Release 0.2.1 - including barcode,face,and image 70/47370/1 accepted/tizen/mobile/20150904.104716 accepted/tizen/tv/20150904.104951 accepted/tizen/wearable/20150904.105531 submit/tizen/20150904.074427
authorTae-Young Chung <ty83.chung@samsung.com>
Wed, 2 Sep 2015 02:15:49 +0000 (11:15 +0900)
committerTae-Young Chung <ty83.chung@samsung.com>
Wed, 2 Sep 2015 02:16:38 +0000 (11:16 +0900)
Change-Id: If6f9ed9a48376d9a179c5c1fa865b1630a701830
Signed-off-by: Tae-Young Chung <ty83.chung@samsung.com>
116 files changed:
AUTHORS [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
LICENSE.APLv2 [new file with mode: 0644]
NOTICE [new file with mode: 0644]
README [new file with mode: 0644]
capi-media-vision.manifest [new file with mode: 0644]
capi-media-vision.pc.in [new file with mode: 0644]
doc/mediavision_doc.h [new file with mode: 0644]
include/mv_barcode.h [new file with mode: 0644]
include/mv_barcode_detect.h [new file with mode: 0644]
include/mv_barcode_generate.h [new file with mode: 0644]
include/mv_barcode_type.h [new file with mode: 0644]
include/mv_common.h [new file with mode: 0644]
include/mv_face.h [new file with mode: 0644]
include/mv_face_type.h [new file with mode: 0644]
include/mv_image.h [new file with mode: 0644]
include/mv_image_type.h [new file with mode: 0644]
include/mv_private.h [new file with mode: 0644]
media-vision-config-example.json [new file with mode: 0644]
media-vision-config.json [new file with mode: 0644]
mv_barcode/CMakeLists.txt [new file with mode: 0644]
mv_barcode/barcode_detector/CMakeLists.txt [new file with mode: 0644]
mv_barcode/barcode_detector/include/Barcode.h [new file with mode: 0644]
mv_barcode/barcode_detector/include/BarcodeUtils.h [new file with mode: 0644]
mv_barcode/barcode_detector/include/mv_barcode_detect_open.h [new file with mode: 0644]
mv_barcode/barcode_detector/src/Barcode.cpp [new file with mode: 0644]
mv_barcode/barcode_detector/src/BarcodeUtils.cpp [new file with mode: 0644]
mv_barcode/barcode_detector/src/mv_barcode_detect_open.cpp [new file with mode: 0644]
mv_barcode/barcode_detector_lic/CMakeLists.txt [new file with mode: 0644]
mv_barcode/barcode_detector_lic/include/mv_barcode_detect_lic.h [new file with mode: 0644]
mv_barcode/barcode_detector_lic/src/mv_barcode_detect_lic.c [new file with mode: 0644]
mv_barcode/barcode_generator/CMakeLists.txt [new file with mode: 0644]
mv_barcode/barcode_generator/include/BarcodeGenerator.h [new file with mode: 0644]
mv_barcode/barcode_generator/include/BarcodeOptions.h [new file with mode: 0644]
mv_barcode/barcode_generator/include/mv_barcode_generate_open.h [new file with mode: 0644]
mv_barcode/barcode_generator/src/BarcodeGenerator.cpp [new file with mode: 0644]
mv_barcode/barcode_generator/src/mv_barcode_generate_open.cpp [new file with mode: 0644]
mv_barcode/barcode_generator_lic/CMakeLists.txt [new file with mode: 0644]
mv_barcode/barcode_generator_lic/include/mv_barcode_generate_lic.h [new file with mode: 0644]
mv_barcode/barcode_generator_lic/src/mv_barcode_generate_lic.c [new file with mode: 0644]
mv_common/CMakeLists.txt [new file with mode: 0644]
mv_common/include/EngineConfig.h [new file with mode: 0644]
mv_common/include/MediaSource.h [new file with mode: 0644]
mv_common/include/mv_common_c.h [new file with mode: 0644]
mv_common/src/EngineConfig.cpp [new file with mode: 0644]
mv_common/src/MediaSource.cpp [new file with mode: 0644]
mv_common/src/mv_common_c.cpp [new file with mode: 0644]
mv_face/CMakeLists.txt [new file with mode: 0644]
mv_face/face/CMakeLists.txt [new file with mode: 0644]
mv_face/face/include/FaceDetector.h [new file with mode: 0644]
mv_face/face/include/FaceExpressionRecognizer.h [new file with mode: 0644]
mv_face/face/include/FaceEyeCondition.h [new file with mode: 0644]
mv_face/face/include/FaceRecognitionModel.h [new file with mode: 0644]
mv_face/face/include/FaceTrackingModel.h [new file with mode: 0644]
mv_face/face/include/FaceUtil.h [new file with mode: 0644]
mv_face/face/include/TrackerMedianFlow.h [new file with mode: 0644]
mv_face/face/include/mv_face_open.h [new file with mode: 0644]
mv_face/face/src/FaceDetector.cpp [new file with mode: 0644]
mv_face/face/src/FaceExpressionRecognizer.cpp [new file with mode: 0644]
mv_face/face/src/FaceEyeCondition.cpp [new file with mode: 0644]
mv_face/face/src/FaceRecognitionModel.cpp [new file with mode: 0644]
mv_face/face/src/FaceTrackingModel.cpp [new file with mode: 0644]
mv_face/face/src/FaceUtil.cpp [new file with mode: 0644]
mv_face/face/src/TrackerMedianFlow.cpp [new file with mode: 0644]
mv_face/face/src/mv_face_open.cpp [new file with mode: 0644]
mv_face/face_lic/CMakeLists.txt [new file with mode: 0644]
mv_face/face_lic/include/mv_face_lic.h [new file with mode: 0644]
mv_face/face_lic/src/mv_face_lic.c [new file with mode: 0644]
mv_image/CMakeLists.txt [new file with mode: 0644]
mv_image/image/CMakeLists.txt [new file with mode: 0644]
mv_image/image/include/ImageConfig.h [new file with mode: 0644]
mv_image/image/include/ImageContourStabilizator.h [new file with mode: 0644]
mv_image/image/include/ImageMathUtil.h [new file with mode: 0644]
mv_image/image/include/ImageObject.h [new file with mode: 0644]
mv_image/image/include/ImageRecognizer.h [new file with mode: 0644]
mv_image/image/include/ImageTracker.h [new file with mode: 0644]
mv_image/image/include/ImageTrackingModel.h [new file with mode: 0644]
mv_image/image/include/mv_image_open.h [new file with mode: 0644]
mv_image/image/src/ImageConfig.cpp [new file with mode: 0644]
mv_image/image/src/ImageContourStabilizator.cpp [new file with mode: 0644]
mv_image/image/src/ImageMathUtil.cpp [new file with mode: 0644]
mv_image/image/src/ImageObject.cpp [new file with mode: 0644]
mv_image/image/src/ImageRecognizer.cpp [new file with mode: 0644]
mv_image/image/src/ImageTracker.cpp [new file with mode: 0644]
mv_image/image/src/ImageTrackingModel.cpp [new file with mode: 0644]
mv_image/image/src/mv_image_open.cpp [new file with mode: 0644]
mv_image/image_lic/CMakeLists.txt [new file with mode: 0644]
mv_image/image_lic/include/mv_image_lic.h [new file with mode: 0644]
mv_image/image_lic/src/mv_image_lic.c [new file with mode: 0644]
packaging/capi-media-vision.spec [new file with mode: 0644]
src/mv_barcode.c [new file with mode: 0644]
src/mv_common.c [new file with mode: 0644]
src/mv_face.c [new file with mode: 0644]
src/mv_image.c [new file with mode: 0644]
src/mv_private.c [new file with mode: 0644]
test/CMakeLists.txt [new file with mode: 0644]
test/testsuites/CMakeLists.txt [new file with mode: 0644]
test/testsuites/barcode/CMakeLists.txt [new file with mode: 0644]
test/testsuites/barcode/barcode_test_suite.c [new file with mode: 0644]
test/testsuites/common/CMakeLists.txt [new file with mode: 0644]
test/testsuites/common/image_helper/CMakeLists.txt [new file with mode: 0644]
test/testsuites/common/image_helper/include/ImageHelper.h [new file with mode: 0644]
test/testsuites/common/image_helper/include/image_helper.h [new file with mode: 0644]
test/testsuites/common/image_helper/src/ImageHelper.cpp [new file with mode: 0644]
test/testsuites/common/image_helper/src/image_helper.cpp [new file with mode: 0644]
test/testsuites/common/testsuite_common/CMakeLists.txt [new file with mode: 0644]
test/testsuites/common/testsuite_common/mv_testsuite_common.c [new file with mode: 0644]
test/testsuites/common/testsuite_common/mv_testsuite_common.h [new file with mode: 0644]
test/testsuites/common/video_helper/CMakeLists.txt [new file with mode: 0644]
test/testsuites/common/video_helper/mv_log_cfg.h [new file with mode: 0644]
test/testsuites/common/video_helper/mv_video_helper.c [new file with mode: 0644]
test/testsuites/common/video_helper/mv_video_helper.h [new file with mode: 0644]
test/testsuites/face/CMakeLists.txt [new file with mode: 0644]
test/testsuites/face/face_test_suite.c [new file with mode: 0644]
test/testsuites/image/CMakeLists.txt [new file with mode: 0644]
test/testsuites/image/image_test_suite.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..14ccbda
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,8 @@
+ByungWook Jang <bw.jang at samsung dot com>
+Tae-Young Chung <ty83.chung at samsung dot com>
+Oleg Kopysov <o.kopysov at samsung dot com>
+Ievgen Vagin <i.vagin at samsung dot com>
+Anton Artyukh <a.artyukh at samsung dot com>
+Yaroslav Zatsikha <y.zatsikha at samsung dot com>
+Sergii Rudenko <s.rudenko at samsung dot com>
+SeokHoon Lee <andy.shlee at samsung dot com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..16f4b13
--- /dev/null
@@ -0,0 +1,170 @@
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_name "capi-media-vision")
+
+PROJECT(${fw_name})
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+# Configure for porting layer:
+
+# Configure for porting layer:
+
+option(MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT
+       "Turn on building of licensed port of the barcode detecting module (if OFF - open port will be built)." OFF)
+option(MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT
+       "Turn on building of licensed port of the barcode generating module (if OFF - open port will be built)." OFF)
+option(MEDIA_VISION_IMAGE_LICENSE_PORT
+       "Turn on building of licensed port of the image module (if OFF - open port will be built)." OFF)
+option(MEDIA_VISION_FACE_LICENSE_PORT
+       "Turn on building of licensed port of the face module (if OFF - open port will be built)." OFF)
+
+set(MV_COMMON_LIB_NAME "mv_common")
+set(MV_BARCODE_DETECTOR_LIB_NAME "mv_barcode_detector" CACHE STRING
+       "Name of the library will be built for barcode detecting module (without extension).")
+set(MV_BARCODE_GENERATOR_LIB_NAME "mv_barcode_generator" CACHE STRING
+       "Name of the library will be built for barcode generating module (without extension).")
+set(MV_IMAGE_LIB_NAME "mv_image" CACHE STRING
+       "Name of the library will be built for image module (without extension).")
+set(MV_FACE_LIB_NAME "mv_face" CACHE STRING
+       "Name of the library will be built for barcode generating module (without extension).")
+
+
+SET(INC_DIR "${PROJECT_SOURCE_DIR}/include")
+SET(INC_COMMON "${PROJECT_SOURCE_DIR}/mv_common/include")
+
+message(STATUS "In_dir ${INC_DIR}")
+
+if(MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT)
+    add_definitions(-DMEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT)
+    SET(INC_BARCODE_DETECTOR "${PROJECT_SOURCE_DIR}/mv_barcode/barcode_detector_lic/include")
+else()
+    SET(INC_BARCODE_DETECTOR "${PROJECT_SOURCE_DIR}/mv_barcode/barcode_detector/include")
+endif()
+
+if(MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT)
+    add_definitions(-DMEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT)
+    SET(INC_BARCODE_GENERATOR "${PROJECT_SOURCE_DIR}/mv_barcode/barcode_generator_lic/include")
+else()
+    SET(INC_BARCODE_GENERATOR "${PROJECT_SOURCE_DIR}/mv_barcode/barcode_generator/include")
+endif()
+
+if(MEDIA_VISION_IMAGE_LICENSE_PORT)
+    add_definitions(-DMEDIA_VISION_IMAGE_LICENSE_PORT)
+    SET(INC_IMAGE "${PROJECT_SOURCE_DIR}/mv_image/image_lic/include")
+else()
+    SET(INC_IMAGE "${PROJECT_SOURCE_DIR}/mv_image/image/include")
+endif()
+
+INCLUDE_DIRECTORIES(${INC_DIR} ${INC_COMMON} ${INC_BARCODE_DETECTOR} ${INC_BARCODE_GENERATOR} ${INC_IMAGE})
+
+if(MEDIA_VISION_FACE_LICENSE_PORT)
+    add_definitions(-DMEDIA_VISION_FACE_LICENSE_PORT)
+    SET(INC_FACE "${PROJECT_SOURCE_DIR}/mv_face/face_lic/include")
+else()
+    SET(INC_FACE "${PROJECT_SOURCE_DIR}/mv_face/face/include")
+endif()
+
+INCLUDE_DIRECTORIES(${INC_DIR} ${INC_COMMON} ${INC_BARCODE_DETECTOR} ${INC_BARCODE_GENERATOR} ${INC_FACE})
+
+SET(dependents "dlog capi-media-tool capi-system-info capi-appfw-application")
+SET(pc_dependents "dlog")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_name} REQUIRED ${dependents})
+FOREACH(flag ${${fw_name}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+    SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -w")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+SET(CMAKE_CXX_FLAGS "-I./include -I./include/headers ${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -fPIC")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g --w")
+
+IF("${ARCH}" STREQUAL "arm")
+    ADD_DEFINITIONS("-DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
+
+ADD_SUBDIRECTORY(mv_common)
+ADD_SUBDIRECTORY(mv_barcode)
+ADD_SUBDIRECTORY(mv_image)
+ADD_SUBDIRECTORY(mv_face)
+
+aux_source_directory(src SOURCES)
+ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
+
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}
+                                 ${MV_COMMON_LIB_NAME}
+                                 ${MV_BARCODE_DETECTOR_LIB_NAME}
+                                 ${MV_BARCODE_GENERATOR_LIB_NAME}
+                                 ${MV_IMAGE_LIB_NAME}
+                                 ${MV_FACE_LIB_NAME})
+
+SET_TARGET_PROPERTIES(${fw_name}
+     PROPERTIES
+     VERSION ${FULLVER}
+     SOVERSION ${MAJORVER}
+     CLEAN_DIRECT_OUTPUT 1
+)
+
+INSTALL(TARGETS ${fw_name} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(
+        DIRECTORY ${INC_DIR}/ DESTINATION include/media
+        FILES_MATCHING
+        PATTERN "*_private.h" EXCLUDE
+        PATTERN "*.h"
+        )
+
+SET(PC_NAME ${fw_name})
+SET(PC_REQUIRED ${pc_dependents})
+SET(PC_LDFLAGS -l${fw_name})
+SET(PC_CFLAGS -I\${includedir}/media)
+
+CONFIGURE_FILE(
+    ${fw_name}.pc.in
+    ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc
+    @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+ADD_SUBDIRECTORY(test)
+
+IF(UNIX)
+
+ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
+ADD_CUSTOM_COMMAND(
+        DEPENDS clean
+        COMMENT "distribution clean"
+        COMMAND find
+        ARGS    .
+        -not -name config.cmake -and \(
+        -name tester.c -or
+        -name Testing -or
+        -name CMakeFiles -or
+        -name cmake.depends -or
+        -name cmake.check_depends -or
+        -name CMakeCache.txt -or
+        -name cmake.check_cache -or
+        -name *.cmake -or
+        -name Makefile -or
+        -name core -or
+        -name core.* -or
+        -name gmon.out -or
+        -name install_manifest.txt -or
+        -name *.pc -or
+        -name *~ \)
+        | grep -v TC | xargs rm -rf
+        TARGET  distclean
+        VERBATIM
+)
+
+ENDIF(UNIX)
+
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..54b213e
--- /dev/null
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..ccdad52
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE file for Apache License terms and conditions.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..415ddeb
--- /dev/null
+++ b/README
@@ -0,0 +1,161 @@
+CONTENT
+
+1. GENERAL DESCRIPTION OF THE MEDIA VISION PACKAGE
+2. USAGE OF PORTING LAYER FOR CHANGING MEDIA VISION ENGINE MODULES
+3. OPEN PORT REQUIRED PACKAGES
+4. TEST SUITE
+
+
+
+
+1. GENERAL DESCRIPTION OF THE MEDIA VISION PACKAGE
+
+Media Vision package includes following modules: Common, Media Vision Barcode,
+Media Vision Face and Media Vision Image. Common module provides two handles
+(mv_source_h and mv_engine_config_h) and related fuctionality. It used by
+barcode detector and generator submodules. mv_source_h is used for wrapping raw
+image data buffers. mv_engine_config_h is optional. It can be used for fine
+tuning of internal libraries which are used by API. mv_engine_config_h handle
+usually can be used by barcode detector and/or generator modules (these modules
+provide mv_barcode_detector and mv_barcode_generator internal libraries) in the
+case when Native API doesn't cover all features supported by internal libraries.
+Using NULL instead of real mv_engine_h handle as functions parameter has to be
+taken into account. In most cases API user prefer to ignore detailed
+configuration of the modules.
+
+Barcode detector submodule API provides tools to analyze the image buffers using
+mv_barcode_detect() function. This analysis strives to detect barcodes at the
+image, determine the type and extract the message. Results can be processed
+using mv_barcode_detected_cb callback.
+
+Barcode generator submodule API provides tools to generate image buffer (or
+image file) with barcode. Barcodes generation can be configured by type,
+message, size, encoding mode, ECC (error correction level), version (three last
+setting are allowed only for QR Codes). One of two functions can be used:
+mv_barcode_generate_source() to generate the mv_source_h handle and
+mv_barcode_generate_image() to generate the file with barcode image.
+
+Media Vision Face module aggregates functionality for detecting, recognition and
+tracking the faces on images. More detailed description can be found in doxygen
+documentation.
+
+Media Vision Image module aggregates functionality for recognition and
+tracking the Flat Image objects. More detailed description can be found in
+doxygen documentation.
+
+
+2. USAGE OF PORTING LAYER FOR CHANGING MEDIA VISION ENGINE MODULES
+
+By default open source engine libraries are used to provide modules
+functionality. But it is possible to substitute them by licensed or other custom
+libraries. To enable building of custom library for the Media Vision package,
+follow these steps:
+
+a. Find CMakeLists.txt in the root of the package directory and change
+   MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT (for enabling build of a custom
+   barcode detector library) and/or
+   MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT (for enabling build of a custom
+   barcode generator library) and/or
+   MEDIA_VISION_FACE_LICENSE_PORT (for enabling build of a custom Media Vision
+   Face library) and/or MEDIA_VISION_IMAGE_LICENSE_PORT (for enabling build of
+   a custom Media Vision Image library) options to ON. Example:
+
+   # only barcode detector module will be customized
+   option(MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT "..." ON)
+   # barcode generator module will be default
+   option(MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT "..." OFF)
+   # face module will be default
+   option(MEDIA_VISION_FACE_LICENSE_PORT "..." OFF)
+   # image module will be default
+   option(MEDIA_VISION_IMAGE_LICENSE_PORT "..." OFF)
+
+b. Options change will cause CMake to build from different subdirectories of
+   mv_barcode/mv_face/mv_image directories. mv_barcode/barcode_detector,
+   mv_barcode/barcode_generator, mv_face/face, mv_image/image subdirectories are
+   used by default. mv_barcode/barcode_detector_lic,
+   mv_barcode/mv_barcode_generator_lic, mv_face/face_lic, mv_image/image_lic
+   subdirectories will be used during build if the corresponding option in ON.
+   *_lic subdirectories already include base structure of the porting layer
+   projects, and files will be used by main capi-media-vision library. Use this
+   files to call functions from custom libraries. For example, you can change
+   mv_barcode_detect_lic.c file in such a way:
+
+   #include "mv_barcode_detect_lic.h"
+   #include "custom_library_header.h"
+
+   int mv_barcode_detect_lic(
+       mv_source_h source,
+       mv_engine_config_h engine_cfg,
+       mv_rectangle_s roi,
+       mv_barcode_on_detected_cb detect_cb,
+       void *user_data)
+   {
+       mv_quadrangle_s *locations = NULL;
+       const char *messages = NULL;
+       mv_barcode_type_e *types = NULL;
+
+       // Here the call of the custom barcode detection function from
+       // custom_library_header.h:
+       int barcodes_number = custom_library_function(
+                                 source, roi, &locations, &messages, &types);
+
+       if (barcodes_number > 0)
+       {
+           detect_cb(
+               source, engine_cfg, locations, messages, types, barcodes_number,
+               user_data);
+           delete[] locations;
+           delete[] messages;
+           delete[] types;
+       }
+
+       return TIZEN_ERROR_NONE;
+   }
+
+c. Change the packaging/capi-media-vision.spec to support any packages required
+   to be found into the system for success build of the custom libraries.
+   You also can remove requirements on open packages that are required by
+   disabled barcode generator/detector, face, image ports. See list of the
+   dependencies in the section 3 of this README file.
+
+d. Modify mv_barcode/<name_of_the_(sub)module>_lic/CMakeLists.txt file for
+   linking required libraries and/or including additional headers. Don't modify
+   the project name or reset ${MV_BARCODE_DETECTOR_LIB_NAME},
+   ${MV_BARCODE_GENERATOR_LIB_NAME}, ${MV_FACE_LIB_NAME}, ${MV_IMAGE_LIB_NAME}
+   variables, because porting layer use these ones during the build. If it is
+   required to change projects/libraries names, best solution is to change
+   MV_BARCODE_DETECTOR_LIB_NAME, MV_BARCODE_GENERATOR_LIB_NAME,
+   MV_FACE_LIB_NAME, MV_IMAGE_LIB_NAME options in the CMakeLists.txt file that
+   is located in the root of the package sources.
+
+
+
+3. OPEN PORT REQUIRED PACKAGES
+
+Building default barcode detector and generator libraries requires following
+dependencies:
+
+Barcode detector: zbar
+Barcode generator: zint
+Media Vision Face: opencv_core, opencv_objdetect, opencv_contrib
+Media Vision Image: opencv_core, opencv_highgui, opencv_imgproc,
+                    opencv_objdetect, opencv_features2d, opencv_nonfree,
+                    opencv_calib3d
+
+You can remove BuildRequires sections for these libraries from
+packaging/capi-media-vision.spec file if corresponding module/modules is/are
+disabled with options mentioned in 2.a.
+
+
+
+3. TEST SUITE
+
+capi-media-vision package includes test suites which allow to check API
+functionality. The test suite applications provide console interface that allows
+to select options for barcode generation and detection, face detection,
+recognition and tracking, image recognition and tracking. Source codes of the
+testsuites are located in corresponding subdirectories of the test directory in
+the capi-media-vision project root:
+test/testsuites/barcode
+test/testsuites/face
+test/testsuites/image
diff --git a/capi-media-vision.manifest b/capi-media-vision.manifest
new file mode 100644 (file)
index 0000000..86dbb26
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_" />
+    </request>
+</manifest>
diff --git a/capi-media-vision.pc.in b/capi-media-vision.pc.in
new file mode 100644 (file)
index 0000000..cde0c80
--- /dev/null
@@ -0,0 +1,14 @@
+
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=@LIB_INSTALL_DIR@
+includedir=/usr/include/media
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
diff --git a/doc/mediavision_doc.h b/doc/mediavision_doc.h
new file mode 100644 (file)
index 0000000..b7ab18d
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_DOC_H__
+#define __TIZEN_MEDIAVISION_DOC_H__
+
+/**
+ * @ingroup CAPI_MEDIA_FRAMEWORK
+ * @defgroup    CAPI_MEDIA_VISION_MODULE Media Vision
+ * @brief Media Vision library providing following functionality:\n
+ * * Face detection, recognition, and tracking;\n
+ * * Barcode detection and generation;\n
+ * * Flat Image detection, recognition and tracking;\n
+ * * Flat Image features extraction.
+ *
+ * @defgroup    CAPI_MEDIA_VISION_COMMON_MODULE Media Vision Common
+ * @ingroup     CAPI_MEDIA_VISION_MODULE
+ * @brief  Common functions and enumerations used in
+ *         @ref CAPI_MEDIA_VISION_FACE_MODULE,
+ *         @ref CAPI_MEDIA_VISION_IMAGE_MODULE and
+ *         @ref CAPI_MEDIA_VISION_BARCODE_MODULE submodules.
+ * @section CAPI_MEDIA_VISION_COMMON_MODULE_HEADER Required Header
+ *      \#include <mv_common.h>
+ *
+ * @section CAPI_MEDIA_VISION_COMMON_MODULE_OVERVIEW Overview
+ * @ref CAPI_MEDIA_VISION_COMMON_MODULE provides a set of functions that
+ * are used in Media Vision API to correctly prepare and use included modules.
+ * @ref mv_source_h is the handler that has to be created to keep information
+ * on image or video frame data as row buffer. It can be created based on
+ * the media data stored in memory or using the @ref media_packet_h handler.
+ * @ref mv_source_h supported by the set of getters which allow to retrieve
+ * such image parameters as its size or colorspace (see @ref mv_colorspace_e
+ * enumeration). The handler is usually used as parameter for functions
+ * performing computer vision tasks on the image data.\n
+ * @ref mv_engine_config_h is the handler which provides dictionary
+ * functionality. It means that it is possible to set (key, value) pairs to
+ * the @ref mv_engine_config_h handlers and use them to transfer these values
+ * to the engine part underlying Media Vision API. Information on which
+ * attributes can be set is provided together with particular engines.
+ *
+ * @section CAPI_MEDIA_VISION_COMMON_MODULE_FEATURE Related Features
+ * This API is related with the following features:\n
+ *  - http://tizen.org/feature/vision.barcode_detection\n
+ *  - http://tizen.org/feature/vision.barcode_generation\n
+ *  - http://tizen.org/feature/vision.face_recognition\n
+ *  - http://tizen.org/feature/vision.image_recognition\n
+ *
+ * It is recommended to design feature related codes in your application for
+ * reliability.\n
+ * You can check if a device supports the related features for this API by using
+ * @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of
+ * your application.\n
+ * To ensure your application is only running on the device with specific
+ * features, please define the features in your manifest file using the manifest
+ * editor in the SDK.\n
+ * More details on featuring your application can be found from
+ * <a href="../org.tizen.mobile.native.appprogramming/html/ide_sdk_tools/feature_element.htm">
+ *    <b>Feature Element</b>.
+ * </a>
+ *
+ * @defgroup    CAPI_MEDIA_VISION_FACE_MODULE Media Vision Face
+ * @ingroup     CAPI_MEDIA_VISION_MODULE
+ * @brief Face detection, recognition, and tracking.
+ * @section CAPI_MEDIA_VISION_FACE_MODULE_HEADER Required Header
+ *      \#include <mv_face.h>
+ *
+ * @section CAPI_MEDIA_VISION_FACE_MODULE_OVERVIEW Overview
+ *
+ * @section CAPI_MEDIA_VISION_FACE_MODULE_FEATURE Related Features
+ * This API is related with the following features:\n
+ *  - http://tizen.org/feature/vision.face_recognition\n
+ *
+ * It is recommended to design feature related codes in your application for
+ * reliability.\n
+ * You can check if a device supports the related features for this API by using
+ * @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of
+ * your application.\n
+ * To ensure your application is only running on the device with specific
+ * features, please define the features in your manifest file using the manifest
+ * editor in the SDK.\n
+ * More details on featuring your application can be found from
+ * <a href="../org.tizen.mobile.native.appprogramming/html/ide_sdk_tools/feature_element.htm">
+ *   <b>Feature Element</b>.
+ * </a>
+ *
+ * @ref CAPI_MEDIA_VISION_FACE_MODULE contains @ref mv_face_detect() function
+ * to detect faces on @ref mv_source_h, and @ref mv_face_detected_cb callback
+ * to process detected faces. Also it contains @ref mv_face_recognize() function
+ * which performs face recognition on @ref mv_source_h for recognition model
+ * @ref mv_face_recognition_model_h handle. Results of the recognition will be
+ * passed to the @ref mv_face_recognized_cb. Results of the recognition consist
+ * of unique face label and confidence of the recognition model that face was
+ * recognized correctly. Unique face label is the integer identifier should be
+ * introduced to the model before starting recognition, when learning examples
+ * are added (see @ref mv_face_recognition_model_add() function
+ * documentation for details about unique face labels).\n
+ * Recognition model should be created with
+ * @ref mv_face_recognition_model_create() and destroyed with
+ * @ref mv_face_recognition_model_destroy(). Model can be cloned with
+ * @ref mv_face_recognition_model_clone(), saved to the file with
+ * @ref mv_face_recognition_model_save(), loaded with
+ * @ref mv_face_recognition_model_load(). Model learning can be provided with
+ * @ref mv_face_recognition_model_add(), and
+ * @ref mv_face_recognition_model_learn() functions. These two methods has to be
+ * called in the direct order: first, labeled face examples should be added to
+ * the model using @ref mv_face_recognition_model_add(). It is
+ * expected that images of the same face will be added specifying the same face
+ * label. When examples were added, model has to be learned based on the collected
+ * set of labeled face images. @ref mv_face_recognition_model_learn() function
+ * will perform learning. If it is required to get the list of unique face
+ * labels learned by the model, @ref mv_face_recognition_model_query_labels()
+ * function can be used.\n
+ * Module contains function
+ * @ref mv_face_track() which performs tracking on @ref mv_source_h for
+ * @ref mv_face_tracking_model_h and  @ref mv_face_on_tracked_cb which process
+ * tracked face. Tracking model should be created with
+ * @ref mv_face_tracking_model_create() and destroyed with
+ * @ref mv_face_tracking_model_destroy(). Tracking model should be prepared
+ * with @ref mv_face_tracking_model_prepare() before each session of tracking.
+ * Model can be cloned with @ref mv_face_tracking_model_clone(), saved to the
+ * file with @ref mv_face_tracking_model_save(), loaded with
+ * @ref mv_face_tracking_model_load().\n
+ * Module provides function for detecting eye-blink status -
+ * @ref mv_face_eye_condition_recognize(), which provides detection on
+ * @ref mv_source_h and face location - @ref mv_rectangle_s. Callback
+ * @ref mv_face_eye_condition_recognized_cb handles result.\n
+ * Also module contains @ref mv_face_facial_expression_recognize() function which
+ * detects face expression on @ref mv_source_h, face location is determined by
+ * @ref mv_rectangle_s. Result is handled with
+ * @ref mv_face_facial_expression_recognized_cb.
+ *
+ * @defgroup    CAPI_MEDIA_VISION_IMAGE_MODULE Media Vision Image
+ * @ingroup     CAPI_MEDIA_VISION_MODULE
+ * @brief Flat Image recognition and tracking;\n
+ * Flat image features extraction.
+ * @section CCAPI_MEDIA_VISION_IMAGE_MODULE_HEADER Required Header
+ *      \#include <mv_image.h>
+ *
+ * @section CAPI_MEDIA_VISION_IMAGE_MODULE_OVERVIEW Overview
+ *
+ * @section CAPI_MEDIA_VISION_IMAGE_MODULE_FEATURE Related Features
+ * This API is related with the following features:\n
+ *  - http://tizen.org/feature/vision.image_recognition\n
+ *
+ * It is recommended to design feature related codes in your application for
+ * reliability.\n
+ * You can check if a device supports the related features for this API by using
+ * @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of
+ * your application.\n
+ * To ensure your application is only running on the device with specific
+ * features, please define the features in your manifest file using the manifest
+ * editor in the SDK.\n
+ * More details on featuring your application can be found from
+ * <a href="../org.tizen.mobile.native.appprogramming/html/ide_sdk_tools/feature_element.htm">
+ *   <b>Feature Element</b>.
+ * </a>
+ *
+ * @ref CAPI_MEDIA_VISION_IMAGE_MODULE contains @ref mv_image_recognize()
+ * function to recognize images on @ref mv_source_h, and @ref
+ * mv_image_recognized_cb callback to process recognition result. Module
+ * also contains @ref mv_image_track() which performs tracking of image on
+ * sequence of @ref mv_source_h handles (by using method for each @ref
+ * mv_source_h) and callback @ref mv_image_tracked_cb to process tracking result.
+ * In order to perform general functionality, module contains @ref
+ * mv_image_object_h and @ref mv_image_tracking_model_h handles.
+ * Image object should be created with @ref mv_image_object_create() and
+ * destroyed with @ref mv_image_object_destroy(). @ref mv_image_object_h can be
+ * constructed by calling @ref mv_image_object_fill() using image wrapped with
+ * @ref mv_source_h. Object can be cloned with @ref mv_image_object_clone(),
+ * saved to the file with @ref mv_image_object_save() and loaded from file with
+ * @ref mv_image_object_load(). Image object can be evaluated with
+ * @ref mv_image_object_get_recognition_rate().
+ * Tracking model should be created with @ref mv_image_tracking_model_create()
+ * and destroyed with @ref mv_image_tracking_model_destroy(). Tracking model
+ * should be based on image object which will be tracked. Use
+ * @ref mv_image_tracking_model_set_target() to assign @ref mv_image_object_h
+ * to the corresponding @ref mv_image_tracking_model_h. It can be cloned with
+ * @ref mv_image_tracking_model_clone(), saved to the file with @ref
+ * mv_image_tracking_model_save() and loaded from file with @ref
+ * mv_image_tracking_model_load().
+ *
+ * @defgroup    CAPI_MEDIA_VISION_BARCODE_MODULE Media Vision BarCode
+ * @ingroup     CAPI_MEDIA_VISION_MODULE
+ * @brief  Barcode module consists of barcode detection and barcode generation
+ *         submodules.
+ * @section CAPI_MEDIA_VISION_BARCODE_MODULE_HEADER Required Header
+ *      \#include <mv_barcode.h>
+ *
+ * @section CAPI_MEDIA_VISION_BARCODE_MODULE_OVERVIEW Overview
+ *
+ * @section CAPI_MEDIA_VISION_BARCODE_MODULE_FEATURE Related Features
+ * This API is related with the following features:\n
+ *  - http://tizen.org/feature/vision.barcode_detection\n
+ *  - http://tizen.org/feature/vision.barcode_generation\n
+ *
+ * It is recommended to design feature related codes in your application for
+ * reliability.\n
+ * You can check if a device supports the related features for this API by using
+ * @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of
+ * your application.\n
+ * To ensure your application is only running on the device with specific
+ * features, please define the features in your manifest file using the manifest
+ * editor in the SDK.\n
+ * More details on featuring your application can be found from
+ * <a href="../org.tizen.mobile.native.appprogramming/html/ide_sdk_tools/feature_element.htm">
+ *   <b>Feature Element</b>.
+ * </a>
+ *
+ * @ref CAPI_MEDIA_VISION_BARCODE_MODULE contains two submodules:\n
+ * * Detection submodule,
+ * * Generation submodule.\n
+ *
+ * Detection submodule can be used for detecting barcodes on image sources,
+ * reading encoded messages, getting barcode types.\n
+ * This module contains
+ * @ref mv_barcode_detect() function and @ref mv_barcode_detected_cb
+ * callback. @ref mv_barcode_detect() function can be called for the image
+ * determined by @ref mv_source_h handler to detect barcodes. If barcodes
+ * were detected, then @ref mv_barcode_detected_cb callback is called.
+ * Each detected barcode type, message and location can be processed by
+ * this callback. @ref mv_barcode_detect() supports ROI (rectangular region of
+ * interest) specification to allow barcode detection only for the region on
+ * the image.
+ *
+ * Generation submodule can be used for generating the barcodes and QR codes.
+ * Different encoding types (see @ref mv_barcode_qr_mode_e), error correction
+ * codes (see @ref mv_barcode_qr_ecc_e) and code versions are supported for
+ * QRCodes.\n This submodule contains @ref mv_barcode_generate_source() function
+ * to generate handler to the buffer with row image of barcode, and
+ * @ref mv_barcode_generate_image() function to generate image file with
+ * barcode. Both functions support the set of parameters which allow API user to
+ * configure output barcode. QR codes as well as Barcodes are supported
+ * (see @ref mv_barcode_type_e enumeration for full list of supported barcodes).
+ * For QR codes it is possible to specify error correction code and encoding
+ * mode (see @ref mv_barcode_qr_mode_e). Generation to file supports several
+ * formats (see @ref mv_barcode_image_format_e).
+ */
+
+#endif  /* __TIZEN_MEDIAVISION_DOC_H__ */
diff --git a/include/mv_barcode.h b/include/mv_barcode.h
new file mode 100644 (file)
index 0000000..00ec447
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_H__
+#define __TIZEN_MEDIAVISION_BARCODE_H__
+
+#include <mv_common.h>
+#include <mv_barcode_detect.h>
+#include <mv_barcode_generate.h>
+
+/**
+ * @file  mv_barcode.h
+ * @brief Representative Media Vision Barcode API header file that includes
+ *        Media Vision Barcode detection and generation functionalities.
+ */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_H__ */
diff --git a/include/mv_barcode_detect.h b/include/mv_barcode_detect.h
new file mode 100644 (file)
index 0000000..77be222
--- /dev/null
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_DETECT_H__
+#define __TIZEN_MEDIAVISION_BARCODE_DETECT_H__
+
+#include <mv_common.h>
+#include <mv_barcode_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_barcode_detect.h
+ * @brief This file contains the Media Vision barcode detect API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_BARCODE_MODULE
+ * @{
+ */
+
+/**
+ * @brief Define MV_BARCODE_DETECT_ATTR_MODE to set mode attribute of the engine
+ *        configuration.
+ *
+ * @since_tizen 2.4
+ *
+ * @see mv_barcode_detect_attr_mode_e
+ */
+#define MV_BARCODE_DETECT_ATTR_MODE   "MV_BARCODE_DETECT_ATTR_MODE"    /**< Mode: 0-image, 1-video*/
+
+/**
+ * @brief Define MV_BARCODE_DETECT_ATTR_TARGET to set target attribute of the
+ *        engine configuration.
+ *
+ * @since_tizen 2.4
+ *
+ * @see mv_barcode_detect_attr_target_e
+ */
+#define MV_BARCODE_DETECT_ATTR_TARGET "MV_BARCODE_DETECT_ATTR_TARGET"  /**< Target: 0-all, 1-1D, 2-2D*/
+
+/**
+ * @brief Enumeration to mode attribute.
+ *
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+    MV_BARCODE_DETECT_ATTR_MODE_IMAGE,    /**< Still image */
+    MV_BARCODE_DETECT_ATTR_MODE_VIDEO     /**< Continuous video */
+} mv_barcode_detect_attr_mode_e;
+
+/**
+ * @brief Enumeration to target attribute.
+ *
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+    MV_BARCODE_DETECT_ATTR_TARGET_ALL,          /**< 1D and 2D */
+    MV_BARCODE_DETECT_ATTR_TARGET_1D_BARCODE,   /**< 1D barcode only */
+    MV_BARCODE_DETECT_ATTR_TARGET_2D_BARCODE,   /**< 2D barcode only */
+} mv_barcode_detect_attr_target_e;
+
+/**
+ * @brief Called when barcode detection is completed.
+ * @details If no barcode is detected then the method will be called, barcodes
+ *          and states will be equal to NULL, and @a number_of_barcodes - 0.
+ *
+ * @since_tizen 2.4
+ * @param [in] source               The handle to the media source
+ * @param [in] engine_cfg           The handle to the configuration of the engine
+ * @param [in] barcode_locations    The quadrangle locations of detected barcodes
+ * @param [in] messages             The decoded messages of barcodes
+ * @param [in] types                The types of detected barcodes
+ * @param [in] number_of_barcodes   The number of detected barcodes
+ * @param [in] user_data            The user data passed from
+ *                                  the mv_barcode_detect() function
+ *
+ * @pre mv_barcode_detect() invokes this callback
+ *
+ * @see mv_barcode_detect()
+ */
+typedef void (*mv_barcode_detected_cb)(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        const mv_quadrangle_s *barcode_locations,
+        const char* messages[],
+        const mv_barcode_type_e *types,
+        int number_of_barcodes,
+        void *user_data);
+
+/**
+ * @brief Detects barcode(s) on source and reads message from it.
+ *
+ * @since_tizen 2.4
+ * @param [in] source            The media source handle
+ * @param [in] engine_cfg        The handle to the configuration of the engine
+ * @param [in] roi               Region of interest - rectangular area on the
+ *                               @a source which will be used for barcode detection
+ *                               Note that @a roi should be inside area on the
+ *                               @a source.
+ * @param [in] detect_cb         The callback for result handling
+ * @param [in] user_data    The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ * @retval #MEDIA_VISION_ERROR_INTERNAL Internal error
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create an engine configuration handle by calling
+ *      @ref mv_create_engine_config(), otherwise use NULL
+ *
+ * @see mv_barcode_detected_cb()
+ */
+int mv_barcode_detect(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s roi,
+        mv_barcode_detected_cb detect_cb,
+        void *user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_DETECT_H__ */
diff --git a/include/mv_barcode_generate.h b/include/mv_barcode_generate.h
new file mode 100644 (file)
index 0000000..6d82709
--- /dev/null
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_GENERATE_H__
+#define __TIZEN_MEDIAVISION_BARCODE_GENERATE_H__
+
+#include <mv_common.h>
+#include <mv_barcode_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_barcode_generate.h
+ * @brief This file contains the Media Vision barcode generate API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_BARCODE_MODULE
+ * @{
+ */
+
+/**
+ * @brief Generates @ref mv_source_h with barcode image.
+ * @details Pay attention that for EAN-8 and EAN-13 barcode types the barcode
+ * type may be selected automatically and this selection depends on the input
+ * message length. Also for QR codes the version may be selected as minimum
+ * required to generate QR code with the input message length.
+ *
+ * @since_tizen 2.4
+ * @param [in]  engine_cfg      The handle to the configuration of the engine
+ * @param [in]  message         The message to be encoded in the barcode
+ * @param [in]  type            Type of the barcode to be generated
+ * @param [in]  qr_enc_mode     Encoding mode for the message (only for QR codes;
+ *                              for 1D barcodes set this parameter to
+ *                              @a MV_BARCODE_QR_MODE_UNAVAILABLE)
+ * @param [in]  qr_ecc          Error correction level (only for QR codes; for
+ *                              1D barcodes set this parameter to
+ *                              @a MV_BARCODE_QR_ECC_UNAVAILABLE)
+ * @param [in]  qr_version      QR code version (for 1D barcodes set this
+ *                              parameter to 0)
+ * @param [in, out] image       The media source handle which will be used to
+ *                              fill by the buffer with generated image
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_MSG_TOO_LONG Too long or short message
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_DATA Invalid data
+ * @retval #MEDIA_VISION_ERROR_INTERNAL Internal error
+ *
+ * @pre Create an engine configuration handle by calling
+ *      @ref mv_create_engine_config(), otherwise use NULL
+ *
+ * @see mv_barcode_generate_image()
+ */
+int mv_barcode_generate_source(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        mv_source_h image);
+
+/**
+ * @brief Generates image file with barcode.
+ * @details Pay attention that for EAN-8 and EAN-13 barcode types the barcode
+ * type may be selected automatically and this selection depends on the input
+ * message length. Also for QR codes the version may be selected as minimum
+ * required to generate QR code with the input message length.
+ *
+ * @since_tizen 2.4
+ * @remarks The mediastorage privilege http://tizen.org/privilege/mediastorage is needed \n
+            if @a image_path is relevant to media storage.\n
+            The externalstorage privilege http://tizen.org/privilege/externalstorage is needed \n
+            if @a image_path is relevant to external storage.
+ * @param [in] engine_cfg      The handle to the configuration of the engine
+ * @param [in] message         The message to be encoded in the barcode
+ * @param [in] image_width     The width of the generated image
+ * @param [in] image_height    The height of the generated image
+ * @param [in] type            Type of the barcode to be generated
+ * @param [in] qr_enc_mode     Encoding mode for the message (only for QR codes;
+ *                             for 1D barcodes set this parameter to
+ *                             @a MV_BARCODE_QR_MODE_UNAVAILABLE)
+ * @param [in] qr_ecc          Error correction level (only for QR codes; for
+ *                             1D barcodes set this parameter to
+ *                             @a MV_BARCODE_QR_ECC_UNAVAILABLE)
+ * @param [in] qr_version      QR code version (for 1D barcodes set this
+ *                             parameter to 0)
+ * @param [in] image_path      The path to the file that has to be generated
+ * @param [in] image_format    The format of the output image
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_MSG_TOO_LONG Too long or short message
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_DATA Invalid data
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_INTERNAL Internal error
+ *
+ * @pre Create an engine configuration handle by calling
+ *      @ref mv_create_engine_config(), otherwise use NULL
+ *
+ * @see mv_barcode_generate_source()
+ */
+int mv_barcode_generate_image(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        int image_width,
+        int image_height,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        const char *image_path,
+        mv_barcode_image_format_e image_format);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_GENERATE_H__ */
diff --git a/include/mv_barcode_type.h b/include/mv_barcode_type.h
new file mode 100644 (file)
index 0000000..d8b2e74
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_TYPE_H__
+#define __TIZEN_MEDIAVISION_BARCODE_TYPE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_barcode_type.h
+ * @brief This file contains enumerations required by barcode detect/generate API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_BARCODE_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for supported barcode types.
+ * @details QR codes (versions 1 to 40) and set of 1D barcodes are supported
+ *
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+    MV_BARCODE_QR,          /**< 2D barcode - Quick Response code */
+    MV_BARCODE_UPC_A,       /**< 1D barcode - Universal Product Code with 12-digit */
+    MV_BARCODE_UPC_E,       /**< 1D barcode - Universal Product Code with 6-digit */
+    MV_BARCODE_EAN_8,       /**< 1D barcode - International Article Number with 8-digit */
+    MV_BARCODE_EAN_13,      /**< 1D barcode - International Article Number with 13-digit */
+    MV_BARCODE_CODE128,     /**< 1D barcode - Code 128 */
+    MV_BARCODE_CODE39,      /**< 1D barcode - Code 39 */
+    MV_BARCODE_I2_5,        /**< 1D barcode - Interleaved Two of Five */
+    MV_BARCODE_UNDEFINED    /**< Undefined */
+} mv_barcode_type_e;
+
+/**
+ * @brief Enumeration for supported QR code error correction level.
+ *
+ * @since_tizen 2.4
+ * @remarks This is unavailable for 1D barcodes
+ */
+typedef enum
+{
+    MV_BARCODE_QR_ECC_LOW,           /**< Recovery up to  7% losses */
+    MV_BARCODE_QR_ECC_MEDIUM,        /**< Recovery up to 15% losses */
+    MV_BARCODE_QR_ECC_QUARTILE,      /**< Recovery up to 25% losses */
+    MV_BARCODE_QR_ECC_HIGH,          /**< Recovery up to 30% losses */
+    MV_BARCODE_QR_ECC_UNAVAILABLE    /**< Unavailable  */
+} mv_barcode_qr_ecc_e;
+
+/**
+ * @brief Enumeration for supported QR code encoding mode.
+ *
+ * @since_tizen 2.4
+ * @remarks This is unavailable for 1D barcodes
+ */
+typedef enum
+{
+    MV_BARCODE_QR_MODE_NUMERIC,         /**< Numeric digits */
+    MV_BARCODE_QR_MODE_ALPHANUMERIC,    /**< Alphanumeric characters */
+    MV_BARCODE_QR_MODE_BYTE,            /**< Raw 8-bit bytes */
+    MV_BARCODE_QR_MODE_UTF8,            /**< UTF-8 character encoding */
+    MV_BARCODE_QR_MODE_UNAVAILABLE      /**< Unavailable */
+} mv_barcode_qr_mode_e;
+
+/**
+ * @brief Enumeration for supported image formats for the barcode generating.
+ *
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+    MV_BARCODE_IMAGE_FORMAT_UNAVAILABLE = -1, /** Unavailable image format */
+    MV_BARCODE_IMAGE_FORMAT_BMP,    /**< BMP image format */
+    MV_BARCODE_IMAGE_FORMAT_JPG,    /**< JPEG image format */
+    MV_BARCODE_IMAGE_FORMAT_PNG,    /**< PNG image format */
+    MV_BARCODE_IMAGE_FORMAT_NUM,    /**< The number of supported image format */
+} mv_barcode_image_format_e;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_TYPE_H__ */
diff --git a/include/mv_common.h b/include/mv_common.h
new file mode 100644 (file)
index 0000000..ff3a5e5
--- /dev/null
@@ -0,0 +1,684 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_COMMON_H__
+#define __TIZEN_MEDIAVISION_COMMON_H__
+
+#include <media_packet.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_common.h
+ * @brief This file contains the Media Vision Common API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_COMMON_MODULE
+ * @{
+ */
+
+/**
+ * @brief Point in 2D space.
+ *
+ * @since_tizen 2.4
+ */
+typedef struct
+{
+    int x; /**< X-axis coordinate of the point in 2D space */
+    int y; /**< Y-axis coordinate of the point in 2D space */
+} mv_point_s;
+
+/**
+ * @brief Location of the object bounded by quadrangle defined by four 2D points.
+ *
+ * @since_tizen 2.4
+ */
+typedef struct
+{
+    mv_point_s points[4];    /**< Four points that define object bounding
+                                  quadrangle */
+} mv_quadrangle_s;
+
+/**
+ * @brief Location of the object bounded by rectangle defined by
+ *        coordinates of top left corner, width and height.
+ *
+ * @since_tizen 2.4
+ */
+typedef struct
+{
+    mv_point_s point;     /**< Top left corner of rectangle coordinates */
+    int width;            /**< Width of the bounding rectangle */
+    int height;           /**< Height of the bounding rectangle */
+} mv_rectangle_s;
+
+/**
+ * @brief Enumeration for Media Vision error.
+ *
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+    MEDIA_VISION_ERROR_NONE
+            = TIZEN_ERROR_NONE,                /**< Successful */
+    MEDIA_VISION_ERROR_NOT_SUPPORTED
+            = TIZEN_ERROR_NOT_SUPPORTED,       /**< Not supported */
+    MEDIA_VISION_ERROR_MSG_TOO_LONG
+            = TIZEN_ERROR_MSG_TOO_LONG,        /**< Message too long */
+    MEDIA_VISION_ERROR_NO_DATA
+            = TIZEN_ERROR_NO_DATA,             /**< No data */
+    MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE
+            = TIZEN_ERROR_KEY_NOT_AVAILABLE,   /**< Key not available */
+    MEDIA_VISION_ERROR_OUT_OF_MEMORY
+            = TIZEN_ERROR_OUT_OF_MEMORY,       /**< Out of memory */
+    MEDIA_VISION_ERROR_INVALID_PARAMETER
+            = TIZEN_ERROR_INVALID_PARAMETER,   /**< Invalid parameter */
+    MEDIA_VISION_ERROR_INVALID_OPERATION
+            = TIZEN_ERROR_INVALID_OPERATION,   /**< Invalid operation */
+    MEDIA_VISION_ERROR_PERMISSION_DENIED
+            = TIZEN_ERROR_NOT_PERMITTED,       /**< Not permitted */
+    MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT
+            = TIZEN_ERROR_MEDIA_VISION | 0x01, /**< Not supported format */
+    MEDIA_VISION_ERROR_INTERNAL
+            = TIZEN_ERROR_MEDIA_VISION | 0x02, /**< Internal error */
+    MEDIA_VISION_ERROR_INVALID_DATA
+            = TIZEN_ERROR_MEDIA_VISION | 0x03, /**< Invalid data */
+    MEDIA_VISION_ERROR_INVALID_PATH
+            = TIZEN_ERROR_MEDIA_VISION | 0x04, /**< Invalid path (Since 3.0) */
+} mv_error_e;
+
+/**
+ * @brief Enumeration for Media Vision @ref mv_engine_config_h handle attribute
+ *        type.
+ *
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+    MV_ENGINE_CONFIG_ATTR_TYPE_DOUBLE,     /**< Double attribute type */
+    MV_ENGINE_CONFIG_ATTR_TYPE_INTEGER,    /**< Integer attribute type */
+    MV_ENGINE_CONFIG_ATTR_TYPE_BOOLEAN,    /**< Boolean attribute type */
+    MV_ENGINE_CONFIG_ATTR_TYPE_STRING      /**< String attribute type */
+} mv_config_attribute_type_e;
+
+/**
+ * @brief Enumeration for Media Vision colorspace.
+ *
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+    MEDIA_VISION_COLORSPACE_INVALID, /**< The colorspace type is invalid */
+    MEDIA_VISION_COLORSPACE_Y800,    /**< The colorspace type is Y800 */
+    MEDIA_VISION_COLORSPACE_I420,    /**< The colorspace type is I420 */
+    MEDIA_VISION_COLORSPACE_NV12,    /**< The colorspace type is NV12 */
+    MEDIA_VISION_COLORSPACE_YV12,    /**< The colorspace type is YV12 */
+    MEDIA_VISION_COLORSPACE_NV21,    /**< The colorspace type is NV21 */
+    MEDIA_VISION_COLORSPACE_YUYV,    /**< The colorspace type is YUYV */
+    MEDIA_VISION_COLORSPACE_UYVY,    /**< The colorspace type is UYVY */
+    MEDIA_VISION_COLORSPACE_422P,    /**< The colorspace type is 422P */
+    MEDIA_VISION_COLORSPACE_RGB565,  /**< The colorspace type is RGB565 */
+    MEDIA_VISION_COLORSPACE_RGB888,  /**< The colorspace type is RGB888 */
+    MEDIA_VISION_COLORSPACE_RGBA,    /**< The colorspace type is RGBA */
+} mv_colorspace_e;
+
+/**
+ * @brief The handle to the Media Vision API engine algorithms configuration.
+ * @details Configuration is a dictionary consists of key and value pairs to
+ *          collect engine-specific settings and allow Media Vision module to
+ *          access them internally. Engine configuration provides developer by
+ *          the possibility to make computer vision algorithms work better
+ *          in particular conditions of API usage. To create engine
+ *          configuration handle @ref mv_create_engine_config() function has to
+ *          be used. When configuration is not needed any more, it is required to
+ *          destroy it and release resources by @ref mv_destroy_engine_config()
+ *          function.
+ *
+ * @since_tizen 2.4
+ *
+ * @see mv_create_engine_config()
+ * @see mv_destroy_engine_config()
+ */
+typedef void *mv_engine_config_h;
+
+/**
+ * @brief The handle to the source.
+ *
+ * @since_tizen 2.4
+ */
+typedef void *mv_source_h;
+
+/**
+ * @brief Creates a source handle.
+ *
+ * @since_tizen 2.4
+ * @remarks You must release @a source by using @ref mv_destroy_source().
+ * @param [out] source    A new handle to the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_destroy_source()
+ */
+int mv_create_source(
+        mv_source_h *source);
+
+/**
+ * @brief Destroys the source handle and releases all its resources.
+ *
+ * @since_tizen 2.4
+ * @param [in] source    The handle to the source to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_create_source()
+ */
+int mv_destroy_source(
+        mv_source_h source);
+
+/**
+ * @brief Fills the media source based on the media packet.
+ *
+ * @since_tizen 2.4
+ * @param [in,out] source          The handle to the source
+ * @param [in]     media_packet    The handle to the media packet from which
+ *                                 will be filled the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ *
+ * @see mv_create_source()
+ * @see mv_destroy_source()
+ */
+int mv_source_fill_by_media_packet(
+        mv_source_h source,
+        media_packet_h media_packet);
+
+/**
+ * @brief Fills the media source based on the buffer and metadata.
+ *
+ * @since_tizen 2.4
+ * @param [in,out] source             The handle to the source
+ * @param [in]     data_buffer        The buffer of image data
+ * @param [in]     buffer_size        The buffer size
+ * @param [in]     image_width        The width of image data
+ * @param [in]     image_height       The height of image data
+ * @param [in]     image_colorspace   The image colorspace
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ *
+ * @see mv_source_clear()
+ */
+int mv_source_fill_by_buffer(
+        mv_source_h source,
+        unsigned char *data_buffer,
+        unsigned int buffer_size,
+        unsigned int image_width,
+        unsigned int image_height,
+        mv_colorspace_e image_colorspace);
+
+/**
+ * @brief Clears the buffer of the media source.
+ *
+ * @since_tizen 2.4
+ * @param [in,out] source    The handle to the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_source_fill_by_buffer()
+ */
+int mv_source_clear(
+        mv_source_h source);
+
+/**
+ * @brief Gets buffer of the media source.
+ *
+ * @since_tizen 2.4
+ * @remarks Note that the retrieved buffer will be destroyed when
+ *          @ref mv_destroy_source() or @ref mv_source_clear() function
+ *          is called for the @a source.
+ *
+ * @param [in]    source        The handle to the source
+ * @param [out]   data_buffer   The buffer of the source
+ * @param [out]   buffer_size   The size of buffer
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_source_get_width()
+ * @see mv_source_get_height()
+ * @see mv_source_get_colorspace()
+ */
+int mv_source_get_buffer(
+        mv_source_h source,
+        unsigned char **data_buffer,
+        unsigned int *buffer_size);
+
+/**
+ * @brief Gets height of the media source.
+ *
+ * @since_tizen 2.4
+ * @param [in]    source         The handle to the source
+ * @param [out]   image_height   The height of an image in the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_source_get_width()
+ * @see mv_source_get_colorspace()
+ * @see mv_source_get_buffer()
+ */
+int mv_source_get_height(
+        mv_source_h source,
+        unsigned int *image_height);
+
+/**
+ * @brief Gets width of the media source.
+ *
+ * @since_tizen 2.4
+ * @param [in]    source        The handle to the source
+ * @param [out]   image_width   The width of an image in the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_source_get_height()
+ * @see mv_source_get_colorspace()
+ * @see mv_source_get_buffer()
+ */
+int mv_source_get_width(
+        mv_source_h source,
+        unsigned int *image_width);
+
+/**
+ * @brief Gets colorspace of the media source.
+ *
+ * @since_tizen 2.4
+ * @param [in]    source             The handle to the source
+ * @param [out]   image_colorspace   The colorspace of an image in the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_source_get_width()
+ * @see mv_source_get_height()
+ * @see mv_source_get_buffer()
+ */
+int mv_source_get_colorspace(
+        mv_source_h source,
+        mv_colorspace_e *image_colorspace);
+
+/**
+ * @brief Creates the handle to the configuration of engine.
+ *
+ * @since_tizen 2.4
+ * @remarks Available engine configuration attributes can be get by using
+ *          @ref mv_engine_config_foreach_supported_attribute().
+ *          The attributes can be changed by @ref mv_engine_config_h
+ *          related setters. Default values are used if the attributes
+ *          are not changed.
+ * @param [out] engine_cfg    The handle to the engine to be created
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_h
+ * @see mv_destroy_engine_config()
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_set_bool_attribute()
+ * @see mv_engine_config_set_string_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ * @see mv_engine_config_get_bool_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ */
+int mv_create_engine_config(
+        mv_engine_config_h *engine_cfg);
+
+/**
+ * @brief Destroys the engine configuration handle and releases all its
+ *        resources.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg    The handle to the engine configuration
+ *                           to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_h
+ * @see mv_create_engine_config()
+ */
+int mv_destroy_engine_config(
+        mv_engine_config_h engine_cfg);
+
+/**
+ * @brief Sets the double attribute to the configuration.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration for which @a value has
+ *                               to be set
+ * @param [in] name              String key of the attribute will be used for
+ *                               storing the @a value into configuration
+ *                               dictionary
+ * @param [in] value             The double value of the attribute
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Attribute key isn't available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_get_double_attribute()
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_set_bool_attribute()
+ * @see mv_engine_config_set_string_attribute()
+ */
+int mv_engine_config_set_double_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        double value);
+
+/**
+ * @brief Sets the integer attribute to the configuration.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration for which @a value has
+ *                               to be set
+ * @param [in] name              String key of the attribute will be used for
+ *                               storing the @a value into configuration
+ *                               dictionary
+ * @param [in] value             The integer value of the attribute
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Attribute key isn't available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_get_int_attribute()
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_set_bool_attribute()
+ * @see mv_engine_config_set_string_attribute()
+ * @see mv_barcode_detect_attr_mode_e
+ * @see mv_barcode_detect_attr_target_e
+ */
+int mv_engine_config_set_int_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        int value);
+
+/**
+ * @brief Sets the boolean attribute to the configuration.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration for which @a value has
+ *                               to be set
+ * @param [in] name              String key of the attribute will be used for
+ *                               storing the @a value into configuration
+ *                               dictionary
+ * @param [in] value             The boolean value of the attribute
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Attribute key isn't available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_get_bool_attribute()
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_set_string_attribute()
+ */
+int mv_engine_config_set_bool_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        bool value);
+
+/**
+ * @brief Sets the string attribute to the configuration.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration for which @a value has
+ *                               to be set
+ * @param [in] name              String key of the attribute will be used for
+ *                               storing the @a value into configuration
+ *                               dictionary
+ * @param [in] value             The string value of the attribute
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Attribute key isn't available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_get_string_attribute()
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_set_bool_attribute()
+ */
+int mv_engine_config_set_string_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        const char *value);
+
+/**
+ * @brief Gets the double attribute from the configuration dictionary.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration from which @a value
+ *                               has to be gotten
+ * @param [in] name              String key of the attribute will be used for
+ *                               getting the @a value from the
+ *                               configuration dictionary
+ * @param [out] value            The attribute to be filled with double value
+ *                               from dictionary
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Attribute key isn't available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ * @see mv_engine_config_get_bool_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ */
+int mv_engine_config_get_double_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        double *value);
+
+/**
+ * @brief Gets the integer attribute from the configuration dictionary.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration from which @a value
+ *                               has to be gotten
+ * @param [in] name              String key of the attribute will be used for
+ *                               getting the @a value from the
+ *                               configuration dictionary
+ * @param [out] value            The attribute to be filled with integer value
+ *                               from dictionary
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Attribute key isn't available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ * @see mv_engine_config_get_bool_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ * @see mv_barcode_detect_attr_mode_e
+ * @see mv_barcode_detect_attr_target_e
+ */
+int mv_engine_config_get_int_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        int *value);
+
+/**
+ * @brief Gets the boolean attribute from the configuration dictionary.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration from which @a value
+ *                               has to be gotten
+ * @param [in] name              String key of the attribute will be used for
+ *                               getting the @a value from the
+ *                               configuration dictionary
+ * @param [out] value            The attribute to be filled with boolean value
+ *                               from dictionary
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Attribute key isn't available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_set_bool_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ */
+int mv_engine_config_get_bool_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        bool *value);
+
+/**
+ * @brief Gets the string attribute from the configuration dictionary.
+ *
+ * @since_tizen 2.4
+ * @remarks Function allocates memory required for output @a value, so
+ *          it has to be removed by the user himself.
+ * @param [in] engine_cfg        Engine configuration from which @a value
+ *                               has to be gotten
+ * @param [in] name              String key of the attribute will be used for
+ *                               getting the @a value from the
+ *                               configuration dictionary
+ * @param [out] value            The attribute to be filled with string value
+ *                               from dictionary
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Attribute key isn't available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_set_string_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ * @see mv_engine_config_get_bool_attribute()
+ */
+int mv_engine_config_get_string_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        char **value);
+
+/**
+ * @brief Called to get information (type and name) once for each supported
+ *        attribute.
+ *
+ * @since_tizen 2.4
+ * @param [in] attribute_type    The supported attribute type
+ * @param [in] attribute_name    The supported attribute name
+ * @param [in] user_data         The user data passed from the
+ *                               @ref mv_engine_config_foreach_supported_attribute()
+ *                               function
+ * @return @c true to continue with the next iteration of the loop, \n
+ *         otherwise @c false to break out of the loop
+ *
+ * @pre mv_engine_config_foreach_supported_attribute() will invoke this callback
+ * @see mv_engine_config_foreach_supported_attribute()
+ */
+typedef bool (*mv_supported_attribute_cb)(
+        mv_config_attribute_type_e attribute_type,
+        const char *attribute_name,
+        void *user_data);
+
+/**
+ * @brief Traverses the list of supported attribute names and types.
+ * @details Using this function names of supported attributes can be obtained.
+ *          Names of the attributes can be used with @ref mv_engine_config_h
+ *          related getters and setters to get/set appropriate attribute values.
+ *
+ * @since_tizen 2.4
+ * @remarks If @a callback is called zero times after
+ *          @ref mv_engine_config_foreach_supported_attribute() call, then
+ *          engine configuration is not supported and setting of attributes will
+ *          cause no effect. In this case for all Media Vision functions which
+ *          require @ref mv_engine_config_h handle as in parameter this
+ *          parameter can be set NULL.
+ * @remarks If @a callback is called at least once, then attribute names and
+ *          types obtained in the @ref mv_supported_attribute_cb callback can be
+ *          changed after mv_engine_config_h handle creation (with
+ *          @ref mv_create_engine_config() function) by corresponding setters.
+ *          Although, if attributes aren't changed by setters, then default
+ *          values will be used.\n
+ *          Changing of attribute values will affect internal functionality
+ *          provided by concrete library underlying Media Vision API.
+ * @param [in] callback     The iteration callback function
+ * @param [in] user_data    The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NO_DATA Can't determine list of supported attributes
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_set_bool_attribute()
+ * @see mv_engine_config_set_string_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ * @see mv_engine_config_get_bool_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ */
+int mv_engine_config_foreach_supported_attribute(
+        mv_supported_attribute_cb callback,
+        void *user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_COMMON_H__ */
diff --git a/include/mv_face.h b/include/mv_face.h
new file mode 100644 (file)
index 0000000..2b6d235
--- /dev/null
@@ -0,0 +1,1105 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_FACE_H__
+#define __TIZEN_MEDIAVISION_FACE_H__
+
+#include <mv_common.h>
+#include <mv_face_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_face.h
+ * @brief  This file contains the Media Vision Face API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_FACE_MODULE
+ * @{
+ */
+
+/**
+ * @brief Defines MV_FACE_DETECTION_MODEL_FILE_PATH to set face detection
+ *        haarcascade xml file attribute of the engine configuration.
+ * @details Face detection haarcascade model can be changed to specify the path to the file
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_string_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ */
+#define MV_FACE_DETECTION_MODEL_FILE_PATH "MV_FACE_DETECTION_MODEL_FILE_PATH"
+
+/**
+ * @brief Defines MV_FACE_RECOGNITION_MODEL_TYPE to set the method used
+ *        for face recognition model learning attribute of the engine
+ *        configuration.
+ * @details Switches between three types of methods used for
+ *          face recognition model learning. Possible values of the
+ *          attribute are:
+ *          1 - Eigenfaces,
+ *          2 - Fisherfaces,
+ *          3 - Local Binary Patterns Histograms (LBPH)
+ *          Default type is LBPH
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_FACE_RECOGNITION_MODEL_TYPE "MV_FACE_RECOGNITION_MODEL_TYPE"
+
+/**
+ * @brief Define MV_FACE_DETECTION_ROI_X to set X coordinate of face detection
+ *        roi as attribute of the engine configuration.
+ * @details Default value is -1 (the roi will be a full image) can be changed
+ *        to specify the roi for face detection
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_FACE_DETECTION_ROI_X "MV_FACE_DETECTION_ROI_X"
+
+/**
+ * @brief Define MV_FACE_DETECTION_ROI_Y to set Y coordinate of face detection
+ *        roi as attribute of the engine configuration.
+ * @details Default value is -1 (the roi will be a full image) can be changed
+ *        to specify the roi for face detection
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_FACE_DETECTION_ROI_Y "MV_FACE_DETECTION_ROI_Y"
+
+/**
+ * @brief Define MV_FACE_DETECTION_ROI_WIDTH to set width of face detection
+ *        roi as attribute of the engine configuration.
+ * @details Default value is -1 (the roi will be a full image) can be changed
+ *        to specify the roi for face detection
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_FACE_DETECTION_ROI_WIDTH "MV_FACE_DETECTION_ROI_WIDTH"
+
+/**
+ * @brief Define MV_FACE_DETECTION_ROI_HEIGHT to set height of face detection
+ *        roi as attribute of the engine configuration.
+ * @details Default value is -1 (the roi will be a full image) can be changed
+ *        to specify the roi for face detection
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_FACE_DETECTION_ROI_HEIGHT "MV_FACE_DETECTION_ROI_HEIGHT"
+
+/**
+ * @brief Define MV_FACE_DETECTION_MIN_SIZE_WIDTH to set minimum width of face
+ *        which will be detected as attribute of the engine configuration.
+ * @details Default value is -1 (all detected faces will be applied) can be
+ *        changed to specify the minimum face width
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_FACE_DETECTION_MIN_SIZE_WIDTH "MV_FACE_DETECTION_MIN_SIZE_WIDTH"
+
+/**
+ * @brief Define MV_FACE_DETECTION_MIN_SIZE_HEIGHT to set minimum height of face
+ *        which will be detected as attribute of the engine configuration.
+ * @details Default value is -1 (all detected faces will be applied) can be changed
+ *        to specify the minimum face height
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_FACE_DETECTION_MIN_SIZE_HEIGHT "MV_FACE_DETECTION_MIN_SIZE_HEIGHT"
+
+/******************/
+/* Face detection */
+/******************/
+
+/**
+ * @brief Called when faces are detected for the @a source.
+ * @details This type callback can be invoked each time when
+ *          @ref mv_face_detect() is called to process the results of face
+ *          detecting.
+ *
+ * @since_tizen 3.0
+ * @remarks If no face is detected then the callback will be invoked, but
+ *          @a faces_locations array will be NULL, and @a number_of_faces will
+ *          be equal to 0.
+ * @param [in] source             The handle to the source of the media where
+ *                                faces were detected
+ * @param [in] engine_cfg         The handle to the configuration of engine was
+ *                                used for face detecting, or NULL if default
+ *                                settings were applied
+ * @param [in] faces_locations    Rectangular locations of detected faces
+ * @param [in] number_of_faces    Number of detected faces
+ * @param [in] user_data          The user data passed from callback invoking code
+ *
+ * @pre Call @ref mv_face_detect() function to perform detection of the face for
+ *      the face image and invoke this callback as a result
+ *
+ * @see mv_face_detect()
+ */
+typedef void (*mv_face_detected_cb)(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *faces_locations,
+        int number_of_faces,
+        void *user_data);
+
+/**
+ * @brief Performs face detection on the @a source for the @a engine_conf.
+ * @details Use this function to launch face detection algorithm configured by
+ *          @a engine_conf configuration. Each time when mv_face_detect is
+ *          called, @a detected_cb will receive a set of the detected
+ *          faces at the media source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source         The handle to the source of the media where faces
+ *                            will be detected
+ * @param [in] engine_cfg     The handle to the configuration of engine will be
+ *                            used for detecting. If NULL, then default settings
+ *                            will be used.
+ * @param [in] detected_cb    The callback which will be called for all face
+ *                            locations detected on media source. This callback
+ *                            will receive detecting results
+ * @param [in] user_data      The user data passed from the code where
+ *                            @ref mv_face_detect() is invoked. This data will
+ *                            be accessible from @a detected_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @post @a detected_cb will be called to process detection results
+ *
+ * @see mv_face_detected_cb
+ */
+int mv_face_detect(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_face_detected_cb detected_cb,
+        void *user_data);
+
+
+/********************/
+/* Face recognition */
+/********************/
+
+/**
+ * @brief Called each time when face is recognized by @ref mv_face_recognize()
+ *        function.
+ *
+ * @since_tizen 3.0
+ * @param [in] source              The handle to the image source for which
+ *                                 face has been recognized/not recognized
+ * @param [in] recognition_model   The handle to the recognition model has been
+ *                                 used for recognition
+ * @param [in] engine_cfg          The handle to the configuration of engine was
+ *                                 used for recognition, or NULL if default
+ *                                 settings were applied
+ * @param [in] face_location       The pointer to the location of the face
+ *                                 recognized on @a source. If face wasn't
+ *                                 recognized, then pointer is NULL
+ * @param [in] face_label          The label that identifies face which was
+ *                                 recognized in the @a source. NULL if
+ *                                 recognition was performed, but no faces
+ *                                 were recognized in the @a source
+ * @param [in] confidence          The confidence of the @a recognition_model
+ *                                 that face has been recognized correctly
+ *                                 (value from 0.0 to 1.0). No faces were
+ *                                 recognized if @a confidence was 0.0.
+ *                                 When model has been learned on large amount
+ *                                 of examples, threshold for this value
+ *                                 can be high (0.85-0.95). If model
+ *                                 was learned for small amount of examples,
+ *                                 then threshold can be reduced (0.5-0.85)
+ * @param [in] user_data           The user data passed from callback invoking
+ *                                 code
+ *
+ * @pre Call @ref mv_face_recognize() function to perform recognition of the
+ *      face for the face image and invoke this callback as a result
+ *
+ * @see mv_face_recognize()
+ */
+typedef void (*mv_face_recognized_cb)(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        const int *face_label,
+        double confidence,
+        void *user_data);
+
+/**
+ * @brief Performs face recognition on the @a source image.
+ * @details Use this function to launch face recognition algorithm configured by
+ *          @a engine_conf configuration using @a recognition_model recognition
+ *          model. Each time when @ref mv_face_recognize() is called,
+ *          @a recognized_cb will receive recognition results:\n
+ *          - Location in the @a source of the face has been recognized;
+ *          - Label of the face has been recognized;
+ *          - Confidence of the @a recognition_model that face has been
+ *            recognized correctly (value from 0.0 to 1.0).
+ *
+ * @since_tizen 3.0
+ * @remarks Using of untrained or weakly trained recognition models will cause
+ *          not accurate results even if resulting confidence will be high.
+ *          Use @ref mv_face_recognition_model_learn() function before
+ *          @ref mv_face_recognize() call. Best results can be achieved when big
+ *          set of face image examples were added by
+ *          @ref mv_face_recognition_model_add() before
+ *          @ref mv_face_recognition_model_learn() call.
+ * @param [in] source              The handle to the source of the media to
+ *                                 recognize face(s) for
+ * @param [in] recognition_model   The handle to the model will be used for
+ *                                 recognition
+ * @param [in] engine_cfg          The handle to the configuration of engine
+ *                                 will be used for recognition. If NULL, then
+ *                                 default settings will be used
+ * @param [in] face_location       Rectangular box bounding face image on the
+ *                                 @a source. If NULL, then full source will be
+ *                                 analyzed
+ * @param [in] recognized_cb       The callback which will be called for the
+ *                                 face recognition results on the @a source.
+ * @param [in] user_data           The user data passed from the code where
+ *                                 @ref mv_face_recognize() is invoked. This
+ *                                 data will be accessible from @a recognized_cb
+ *                                 callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create a face recognition model handle by calling
+ *      @ref mv_face_recognition_model_create()
+ * @post @a recognized_cb will be called to process recognition results
+ *
+ * @see mv_face_recognized_cb
+ */
+int mv_face_recognize(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        mv_face_recognized_cb recognized_cb,
+        void *user_data);
+
+
+/*****************/
+/* Face tracking */
+/*****************/
+
+/**
+ * @brief Called when face determined by @a tracking_model is tracked.
+ * @details This type callback can be invoked each time when
+ *          @ref mv_face_track() is called to process the results of face
+ *          tracking.
+ *
+ * @since_tizen 3.0
+ * @param [in] source           The handle to the video frame or image from
+ *                              sequence for which face was tracked
+ * @param [in] tracking_model   The handle to the model that was used for
+ *                              tracking
+ * @param [in] engine_cfg       The handle to the configuration of engine was
+ *                              used for tracking, or NULL if default settings
+ *                              were applied.
+ * @param [in] location         The pointer to the quadrangle-shaped location
+ *                              which determines new position of the tracked
+ *                              face on the @a source. If NULL, then face was
+ *                              lost by tracking algorithm during last iteration
+ * @param [in] confidence       The confidence of the @a tracking_model
+ *                              that new location of the face was determined
+ *                              correctly (value from 0.0 to 1.0).
+ *                              If no location was determined during last track
+ *                              iteration, then value is 0.0
+ * @param [in] user_data        The user data passed from callback invoking code
+ *
+ * @pre Call @ref mv_face_track() function to perform track iteration for
+ *      the video frame or the image from sequence and invoke this callback as
+ *      a result
+ *
+ * @see mv_face_track()
+ */
+typedef void (*mv_face_tracked_cb)(
+        mv_source_h source,
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_quadrangle_s *location,
+        double confidence,
+        void *user_data);
+
+/**
+ * @brief Performs face tracking on the @a source for the @a tracking_model.
+ * @details Use this function to launch face tracking algorithm configured by
+ *          @a engine_conf configuration using @a tracking_model tracking
+ *          model. Each time when this function is called, @a tracked_cb
+ *          will receive updated @a tracking_model, new location determined for
+ *          the tracked face and model confidence that location is determined
+ *          correctly.
+ *
+ * @since_tizen 3.0
+ * @remarks To allow correct tracking @a tracking_model has to be already used
+ *          in previous tracking process(es) or prepared with
+ *          @ref mv_face_tracking_model_prepare(). Preparation requires
+ *          specifying the face location for the @a source on which tracking was
+ *          started. I.e. @ref mv_face_tracking_model_prepare() function has to
+ *          be called at least once before this method call.
+ * @param [in] source           The handle to the source of the media to
+ *                              recognize face for
+ * @param [in] tracking_model   The handle to the model will be used for
+ *                              tracking
+ * @param [in] engine_cfg       The handle to the configuration of engine will
+ *                              be used for tracking. If NULL, the default
+ *                              configuration will be used.
+ * @param [in] tracked_cb       The callback which will be called for tracking
+ *                              event on the @a source where face would be
+ *                              tracked. This callback will receive tracking
+ *                              results
+ * @param [in] do_learn         The model learning flag. If it is set @c true
+ *                              then model will try to learn (if it supports
+ *                              learning feature), otherwise model will be not
+ *                              learned during the invoking tracking iteration.
+ *                              Learning process improves tracking correctness,
+ *                              but can decrease tracking performance
+ * @param [in] user_data        The user data passed from the code where
+ *                              @ref mv_face_track() is invoked. This data will
+ *                              be accessible from @a tracked_cb callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create a face tracking model handle by calling
+ *      @ref mv_face_tracking_model_create()
+ * @post @a tracked_cb will be called to process tracking results
+ *
+ * @see mv_face_tracked_cb
+ */
+int mv_face_track(
+        mv_source_h source,
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_face_tracked_cb tracked_cb,
+        bool do_learn,
+        void *user_data);
+
+
+/********************************/
+/* Recognition of eye condition */
+/********************************/
+
+/**
+ * @brief Called when eye blink condition is recognized.
+ * @details This type callback can be invoked each time when
+ *          mv_face_eye_condition_recognize() is called for @a face_location to
+ *          recognize eye-blink condition for the face at the @a source.\n
+ *          Usage example for this callback can be found in
+ *          mv_face_eye_condition_recognize() documentation.
+ *
+ * @since_tizen 3.0
+ * @param [in] source           The handle to the source of the media for which
+ *                              eye-blink condition was recognized
+ * @param [in] engine_cfg       The handle to the configuration of engine was
+ *                              used for eye-blink condition recognition, or
+ *                              NULL if default settings were applied.
+ * @param [in] face_location    The location bounding the face at the @a source
+ * @param [in] eye_condition    The type of eye-blink condition recognized for
+ *                              face bounded by @a face_location
+ * @param [in] user_data        The user data passed from callback invoking code
+ *
+ *
+ * @pre Call @ref mv_face_eye_condition_recognize() function to perform
+ *      eye-blink condition recognition and invoke this callback as a result
+ *
+ * @see mv_face_eye_condition_recognize()
+ */
+typedef void (*mv_face_eye_condition_recognized_cb)(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_eye_condition_e eye_condition,
+        void *user_data);
+
+/**
+ * @brief Determines eye-blink condition for @a face_location on media @a source.
+ * @details Use this function to recognize eye-blink condition for the face
+ *          bounded by @a face_location at @a source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source           The handle to the source of the media to
+ *                              recognize eye-blink condition for
+ * @param [in] engine_cfg       The handle to the configuration of engine
+ *                              will be used for eye-blink condition
+ *                              recognition. If NULL, the default configuration
+ *                              will be used.
+ * @param [in] face_location    The location bounding the face at the @a source
+ * @param [in] eye_condition_recognized_cb    The callback for processing result
+ *                              of eye-blink condition recognition
+ * @param [in] user_data        The user data passed from the code where
+ *                              mv_face_eye_condition_recognize() is invoked.
+ *                              This data will be accessible from
+ *                              @a eye_condition_recognized_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ *
+ * @see mv_face_eye_condition_recognized_cb
+ */
+int mv_face_eye_condition_recognize(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_eye_condition_recognized_cb eye_condition_recognized_cb,
+        void *user_data);
+
+
+/************************************/
+/* Recognition of facial expression */
+/************************************/
+
+/**
+ * @brief Called when facial expression is recognized
+ * @details This type callback can be invoked each time when
+ *          mv_face_facial_expression_recognize() is called for @a face_location to
+ *          recognize facial expression for the face at the @a source.\n
+ *          Usage example for this callback can be found in
+ *          mv_face_facial_expression_recognize() documentation.
+ *
+ * @since_tizen 3.0
+ * @param [in] source               The handle to the source of the media for
+ *                                  which facial expression was recognized
+ * @param [in] engine_cfg           The handle to the configuration of engine was
+ *                                  used for expression recognition
+ * @param [in] face_location        The location bounding the face at the @a source
+ * @param [in] facial_expression    The type of facial expression recognized
+ *                                  for face bounded by @a face_location
+ * @param [in] user_data            The user data passed from callback invoking code
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create a face engine configuration handle by calling mv_create_engine_config()
+ *
+ * @see mv_face_facial_expression_recognize()
+ */
+typedef void (*mv_face_facial_expression_recognized_cb)(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_facial_expression_e facial_expression,
+        void *user_data);
+
+/**
+ * @brief Determines facial expression for @a face_location on media @a source.
+ * @details Use this function to determine facial expression for the face
+ *          bounded by @a face_location at @a source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source           The handle to the source of the media
+ *                              to recognize facial expression for
+ * @param [in] engine_cfg       The handle to the configuration of
+ *                              engine will be used for expression recognition
+ * @param [in] face_location    The location bounding the face at the @a source
+ * @param [in] expression_recognized_cb   The callback for processing result
+ *                              of facial expression determining
+ * @param [in] user_data        The user data passed from the code where
+ *                              mv_face_facial_expression_recognize() is invoked.
+ *                              This data will be accessible from
+ *                              @a expression_recognized_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create a face engine configuration handle by calling @ref mv_create_engine_config()
+ *
+ * @see mv_face_facial_expression_recognized_cb
+ */
+int mv_face_facial_expression_recognize(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_facial_expression_recognized_cb expression_recognized_cb,
+        void *user_data);
+
+/*******************************/
+/* Recognition model behavior */
+/*******************************/
+
+/**
+ * @brief Creates a face recognition model handle.
+ * @details Use this function to create default face recognition model. Creating
+ *          process is defined by concrete face engine library. After creation
+ *          recognition model has to be learned with
+ *          @ref mv_face_recognition_model_learn() function to provide
+ *          appropriate results of face recognition functionality. Or learned
+ *          earlier model can be loaded by @ref mv_face_recognition_model_load()
+ *          function.
+ *
+ * @since_tizen 3.0
+ * @remarks It can cause incompatibility issues when saved models (see
+ *          @ref mv_face_recognition_model_save(),
+ *          @ref mv_face_recognition_model_load()
+ *          functions documentation) are used in applications for different
+ *          platforms which use different computer vision libraries underlying
+ *          this API.
+ * @remarks You must release @a recognition_model by using
+ *          @ref mv_face_recognition_model_destroy() function.
+ * @param [out] recognition_model    The handle to the recognition model to be
+ *                                   created
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post Model can be loaded from the file after creation. Use
+ *       @ref mv_face_recognition_model_load() function to load it from file
+ * @post Release @a recognition_model by using
+ *       @ref mv_face_recognition_model_destroy() function when it is not needed
+ *       anymore
+ *
+ * @see mv_face_recognition_model_destroy()
+ */
+int mv_face_recognition_model_create(
+        mv_face_recognition_model_h *recognition_model);
+
+/**
+ * @brief Destroys the face recognition model handle and releases all its
+ *        resources.
+ *
+ * @since_tizen 3.0
+ * @param [in] recognition_model    The handle to the face recognition model to
+ *                                  be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create recognition model by using @ref mv_face_recognition_model_create()
+ *
+ * @see mv_face_recognition_model_create()
+ */
+int mv_face_recognition_model_destroy(
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Creates a copy of existed recognition model handle and clones all its
+ *        resources.
+ *
+ * @since_tizen 3.0
+ * @remarks Cloning perform not only handle copy, but also copies all internal
+ *          resources of the model. @a dst must be released using
+ *          @ref mv_face_recognition_model_destroy().
+ * @param [in]     src    The handle to the recognition model to be copied
+ * @param [out]    dst    The handle to the copy of existed recognition model
+ *                        specified as @a src
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create face recognition handles by calling
+ *      @ref mv_face_recognition_model_create()
+ *
+ * @see mv_face_recognition_model_create()
+ */
+int mv_face_recognition_model_clone(
+        mv_face_recognition_model_h src,
+        mv_face_recognition_model_h *dst);
+
+/**
+ * @brief Saves recognition model to the file.
+ *
+ * @since_tizen 3.0
+ * @remarks This function doesn't save face image examples (image itself) added by
+ *          @ref mv_face_recognition_model_add() function.
+ *          This examples can be removed by
+ *          @ref mv_face_recognition_model_reset() function if
+ *          it is needed to clear the memory.
+ * @remarks @a recognition_model is saved to the application's data directory.
+ *          After model is saved to the file, it can be loaded from this file
+ *          by @ref mv_face_recognition_model_load() function.
+ * @param [in] file_name            Name of the file to save the model
+ * @param [in] recognition_model    The handle to the recognition model to be
+ *                                  saved to the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported model format
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face recognition handle by calling
+ *      @ref mv_face_recognition_model_create() function
+ * @post Saved model can be loaded later by calling
+ *      @ref mv_face_recognition_model_load() function
+ *
+ * @see mv_face_recognition_model_load()
+ * @see mv_face_recognition_model_create()
+ */
+int mv_face_recognition_model_save(
+        const char *file_name,
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Loads recognition model from file.
+ *
+ * @since_tizen 3.0
+ * @remarks This function doesn't modify the set of face image examples added
+ *          with @ref mv_face_recognition_model_add() function.
+ *          Model will be loaded from file without loss of collected examples.
+ *          If you want to free memory from examples, use
+ *          @ref mv_face_recognition_model_reset() function. It
+ *          is recommended to clear the memory if learning algorithm doesn't
+ *          support reinforcement learning.
+ * @remarks @a recognition_model is loaded from the application's data directory.
+ *          @a recognition_model must be destroyed using
+ *          @ref mv_face_recognition_model_destroy().
+ * @param [in]  file_name            Name of file to load the model
+ * @param [out] recognition_model    The handle to the recognition model
+ *                                   to be loaded from the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported model format
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Recognition model can be preliminary saved with
+ *      @ref mv_face_recognition_model_save() function
+ *
+ * @see mv_face_recognition_model_save()
+ * @see mv_face_recognition_model_destroy()
+ */
+int mv_face_recognition_model_load(
+        const char *file_name,
+        mv_face_recognition_model_h *recognition_model);
+
+/**
+ * @brief Adds face image example to be used for face recognition model learning
+ *        with @ref mv_face_recognition_model_learn().
+ *
+ * @since_tizen 3.0
+ * @remarks It is possible to destroy @a source after calling this method.
+ *          Source isn't used for learning directly.
+ * @remarks Face image @a example_location location can be determined using
+ *          @ref mv_face_detect function.
+ * @param [in] source               The handle to @a source that contains face
+ *                                  image
+ * @param [in] recognition_model    The handle to the recognition model which
+ *                                  could be learned based on example
+ * @param [in] example_location     The pointer to the rectangular location of
+ *                                  the face image at the source image. If NULL,
+ *                                  then full image will be analyzed as the face
+ *                                  image
+ * @param [in] face_label           The label that identifies face for which
+ *                                  example is adding. Specify the same labels
+ *                                  for the face images of a single person when
+ *                                  calling this method. Has to be unique for
+ *                                  each face
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face recognition handle by calling
+ *      @ref mv_face_recognition_model_create() function
+ * @post When appropriate amount of face image examples is added to the
+ *       @a recognition_model, this model has to be learned by
+ *       @ref mv_face_recognition_model_learn() function call. Only after
+ *       learning of the model it can be used for face recognition with
+ *       @ref mv_face_recognize() function
+ *
+ * @see mv_face_recognition_model_reset()
+ * @see mv_face_recognition_model_learn()
+ */
+int mv_face_recognition_model_add(
+        const mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        const mv_rectangle_s *example_location,
+        int face_label);
+
+/**
+ * @brief Removes from @a recognition_model all collected with
+ *        @ref mv_face_recognition_model_add() function
+ *        face examples labeled with @a face_label.
+ *
+ * @since_tizen 3.0
+ * @remarks Be aware that if this function is called before
+ *          @ref mv_face_recognition_model_learn() function call, all or part of
+ *          the required for learning data will be lost. It means that face
+ *          image examples determined by the @a face_label label will be removed
+ *          from the model and not taken into account when
+ *          @ref mv_face_recognition_model_learn() will be called next time.
+ * @remarks Call of this function will free all the memory has been allocated
+ *          during previous @ref mv_face_recognition_model_add()
+ *          calls for the corresponding @a face_label label.
+ * @param [in] recognition_model    The handle to the recognition model for
+ *                                  which face image examples will be reset.
+ * @param [in] face_label           The label that identifies face for which
+ *                                  examples will be removed from the
+ *                                  @a recognition_model. If NULL, then all
+ *                                  known by @a recognition_model face image
+ *                                  examples will be removed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Key not available
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_face_recognition_model_add()
+ * @see mv_face_recognition_model_learn()
+ */
+int mv_face_recognition_model_reset(
+        mv_face_recognition_model_h recognition_model,
+        int *face_label);
+
+/**
+ * @brief Learns face recognition model.
+ * @details Before you start learning process, face recognition models has to be
+ *          filled with training data - face image examples. These examples has
+ *          to be provided by
+ *          @ref mv_face_recognition_model_add() function.
+ *          Usually, recognition accuracy is increased when number of not
+ *          identical examples is large. But it depends on the used learning
+ *          algorithm.
+ *
+ * @since_tizen 3.0
+ * @remarks Common flow is to collect face examples as much as possible, add
+ *          them to the recognition model with
+ *          @ref mv_face_recognition_model_add(), then call
+ *          @ref mv_face_recognition_model_learn() for this recognition model to
+ *          learn it (or update the model if updating is supported by the used
+ *          algorithm).
+ * @remarks Selection of the learning algorithm can be performed by setting
+ *          corresponding attributes for the @a engine_cfg. You can check
+ *          supported by @a engine_cfg attributes using
+ *          @ref mv_engine_config_foreach_supported_attribute() function call.
+ *          By default, Local Binary Patterns Histograms (LBPH) based
+ *          recognition algorithm will be used.
+ * @param [in]     engine_cfg           The handle to the configuration of
+ *                                      engine will be used for learning of the
+ *                                      recognition models. If NULL, then
+ *                                      default settings will be used
+ * @param [in,out] recognition_model    The model which will be learned. After
+ *                                      learning process these model may be
+ *                                      changed, so @ref mv_face_recognize()
+ *                                      results may differ before and after
+ *                                      method call respectively to the face
+ *                                      examples collected for the
+ *                                      @a recognition_model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NO_DATA No data
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face engine configuration handle by calling
+ *      @ref mv_create_engine_config() and set supported parameters if
+ *      needed. Or just set @a engine_cfg as NULL to learn with default settings
+ * @pre Create a face recognition model handles by calling
+ *      @ref mv_face_recognition_model_create() function
+ * @pre Add face image examples to the @a recognition_model by calling
+ *      @ref mv_face_recognition_model_add() function
+ * @post If it is not planned to learn the model again, clear memory by
+ *       @ref mv_face_recognition_model_reset() function
+ * @post When model has been learned, it can be used for face recognition with
+ *       @ref mv_face_recognize() function
+ *
+ * @see mv_face_recognition_model_add()
+ * @see mv_face_recognition_model_reset()
+ * @see mv_face_recognize()
+ */
+int mv_face_recognition_model_learn(
+        mv_engine_config_h engine_cfg,
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Queries labels list and number of labels had been learned by the model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a labels array has to be released using free().
+ * @param [in]  recognition_model    The handle to the recognition model for
+ *                                   which set of the learned labels will be
+ *                                   queried
+ * @param [out] labels               The array which will be filled with labels
+ *                                   had been learned by the model
+ * @param [out] number_of_labels     The number of labels in @a labels array
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Add face image examples with labels to the @a recognition_model by
+ *      calling the @ref mv_face_recognition_model_add() function
+ * @pre Learn the @a recognition_model by labeled examples using
+ *      @ref mv_face_recognition_model_learn() function
+ * @post @a labels array has to be freed in the function invoking code
+ *
+ * @see mv_face_recognition_model_add()
+ * @see mv_face_recognition_model_reset()
+ * @see mv_face_recognition_model_learn()
+ */
+int mv_face_recognition_model_query_labels(
+        mv_face_recognition_model_h recognition_model,
+        int **labels,
+        unsigned int *number_of_labels);
+
+/***************************/
+/* Tracking model behavior */
+/***************************/
+
+/**
+ * @brief Calls this function to create a face tracking model handle.
+ * @details Use this function to create default face tracking model handle.
+ *          After creation this handle has to be initialized with
+ *          @ref mv_face_tracking_model_prepare() function to provide
+ *          appropriate results of face tracking functionality. When handle is
+ *          prepared, it is possible to use it for tracking on continuous
+ *          sequence of the sources. Call @ref mv_face_tracking_model_prepare()
+ *          function each time before starting tracking on the new sequence.
+ *          The exception is situation when the new sequence is continuation
+ *          of the previous sequence for which model has been tracked.
+ *
+ * @since_tizen 3.0
+ * @param [out] tracking_model    The pointer to the handle to the tracking
+ *                                model that will be created
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post Model can be loaded from the file after creation. Use
+ *       @ref mv_face_tracking_model_load() function to load it from file
+ * @post Use @ref mv_face_tracking_model_prepare() function before tracking on
+ *       the new video or continuous images sequence
+ * @post Release @a tracking_model by using
+ *       @ref mv_face_tracking_model_destroy() function when it is not needed
+ *       anymore
+ *
+ * @see mv_face_tracking_model_destroy()
+ * @see mv_face_tracking_model_prepare()
+ * @see mv_face_tracking_model_load()
+ */
+int mv_face_tracking_model_create(
+        mv_face_tracking_model_h *tracking_model);
+
+/**
+ * @brief Calls this function to destroy the face tracking model handle and
+ *        release all its resources.
+ *
+ * @since_tizen 3.0
+ * @param [in] tracking_model    The handle to the face tracking model that
+ *                               will be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create tracking model by using @ref mv_face_tracking_model_create()
+ *
+ * @see mv_face_tracking_model_create()
+ */
+int mv_face_tracking_model_destroy(
+        mv_face_tracking_model_h tracking_model);
+
+/**
+ * @brief Calls this function to initialize tracking model by the location of the
+ *        face to be tracked.
+ * @details This function is usually called once after tracking model is created
+ *          and each time before tracking is started for the new sequence of
+ *          sources which is not the direct continuation of the sequence for
+ *          which tracking has been performed before. But it is allowed to call
+ *          it between tracking sessions to allow Media Vision start to track
+ *          more accurately.
+ *
+ * @since_tizen 3.0
+ * @param [in] tracking_model    The handle to the tracking model that will be
+ *                               prepared for tracking on new video or image
+ *                               sequence
+ * @param [in] engine_cfg        The handle to the configuration of engine
+ *                               will be used for model preparing. If NULL, then
+ *                               default settings will be used.
+ * @param [in] source            The handle to the source where face @a location
+ *                               is specified. Usually it is the first frame of
+ *                               the video or the first image in the continuous
+ *                               image sequence planned to be used for tracking
+ * @param [in] location          The quadrangle-shaped location (actually,
+ *                               rectangle can be used) determining position
+ *                               of the face to be tracked on the @a source. If
+ *                               @c NULL, then tracking model will try to find
+ *                               previously tracked face by itself. Don't set
+ *                               NULL when called first time for the tracking
+ *                               model.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face tracking model handle by calling
+ *      @ref mv_face_tracking_model_create() function
+ * @pre Create a source handle by calling @ref mv_create_source() function
+ * @post When model is prepared, @ref mv_face_track() function can be used to
+ *       track on the video or continuous image sequence
+ *
+ * @see mv_face_tracking_model_create()
+ * @see mv_face_track()
+ */
+int mv_face_tracking_model_prepare(
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_quadrangle_s *location);
+
+/**
+ * @brief Calls this function to make a copy of existed tracking model handle and
+ *        clone all its resources to the copy.
+ *
+ * @since_tizen 3.0
+ * @remarks Cloning performs not only handle copy, but also copies all internal
+ *          resources of the model. @a dst must be released using
+ *          mv_face_tracking_model_destroy().
+ * @param [in]     src    The handle to the tracking model to be copied
+ * @param [out]    dst    The handle to the copy of existed tracking model
+ *                        specified as @a src
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create face tracking @a src handle by calling
+ *      @ref mv_face_tracking_model_create()
+ *
+ * @see mv_face_tracking_model_create()
+ */
+int mv_face_tracking_model_clone(
+        mv_face_tracking_model_h src,
+        mv_face_tracking_model_h *dst);
+
+/**
+ * @brief Calls this method to save tracking model to the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @ tracking_model is saved to the application's data directory.
+ *          After model is saved to the file, it can be loaded from this file
+ *          with @ref mv_face_tracking_model_load() function.
+ * @param [in] file_name         Name of the file to save the model
+ * @param [in] tracking_model    The handle to the tracking model to be
+ *                               saved to the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported model format
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face tracking handle by calling
+ *      @ref mv_face_tracking_model_create()
+ * @post Saved model can be loaded from file using
+ *       @ref mv_face_tracking_model_load() function
+ *
+ * @see mv_face_tracking_model_load()
+ * @see mv_face_tracking_model_create()
+ */
+int mv_face_tracking_model_save(
+        const char *file_name,
+        mv_face_tracking_model_h tracking_model);
+
+/**
+ * @brief Calls this method to load a tracking model from file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a tracking_model is loaded from the application's data directory.
+ *          @a tracking_model must be destroyed using
+ *          @ref mv_face_tracking_model_destroy.
+ * @param [in] file_name         Name of file to load the model
+ * @param [out] tracking_model   The handle to the tracking model to be
+ *                               loaded from file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported model format
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Models has been saved by @ref mv_face_tracking_model_save() function
+ *      can be loaded with this function
+ * @post After model has been loaded and if further tracking will be performed
+ *       on the video which is not continuation of the last tracking performed
+ *       for the model, it is recommended to call
+ *       @ref mv_face_tracking_model_prepare() function
+ *
+ * @see mv_face_tracking_model_save()
+ * @see mv_face_tracking_model_destroy()
+ */
+int mv_face_tracking_model_load(
+        const char *file_name,
+        mv_face_tracking_model_h *tracking_model);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_FACE_H__ */
diff --git a/include/mv_face_type.h b/include/mv_face_type.h
new file mode 100644 (file)
index 0000000..2164e94
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_FACE_TYPE_H__
+#define __TIZEN_MEDIAVISION_FACE_TYPE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_face_type.h
+ * @brief This file contains enumerations and handles definition required by
+ *        face detect/recognize/track API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_FACE_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for eyes state type.
+ *
+ * @since_tizen 3.0
+ *
+ * @see mv_face_eye_condition_recognize()
+ */
+typedef enum
+{
+    MV_FACE_EYES_OPEN,      /**< Eyes are open */
+    MV_FACE_EYES_CLOSED,    /**< Eyes are closed */
+    MV_FACE_EYES_NOT_FOUND  /**< The eyes condition wasn't determined */
+} mv_face_eye_condition_e;
+
+/**
+ * @brief Enumeration for expression types can be determined for faces.
+ *
+ * @since_tizen 3.0
+ *
+ * @see mv_face_facial_expression_recognize()
+ */
+typedef enum
+{
+    MV_FACE_UNKNOWN,    /**< Unknown face expression */
+    MV_FACE_NEUTRAL,    /**< Face expression is neutral */
+    MV_FACE_SMILE,      /**< Face expression is smiling */
+    MV_FACE_SADNESS,    /**< Face expression is sadness */
+    MV_FACE_SURPRISE,   /**< Face expression is surprise */
+    MV_FACE_ANGER,      /**< Face expression is anger */
+    MV_FACE_FEAR,       /**< Face expression is fear */
+    MV_FACE_DISGUST,    /**< Face expression is disgust */
+} mv_face_facial_expression_e;
+
+/**
+ * @brief The handle to the model aggregating recognition face features.
+ * @details This handle can be used for faces recognizing with
+ *          @ref mv_face_recognize() function. Handle has to be created by
+ *          @ref mv_face_recognition_model_create() and destroyed by
+ *          @ref mv_face_recognition_model_destroy() functions. To use
+ *          recognition models effectively learning process has to be performed
+ *          before recognition. In other words, appropriate set of the face
+ *          image examples has to be collected with
+ *          @ref mv_face_recognition_model_add() function before
+ *          @ref mv_face_recognition_model_learn() function call, then
+ *          recognition can be performed with @ref mv_face_recognize().
+ *
+ * @since_tizen 3.0
+ *
+ * @see mv_face_recognition_model_create()
+ * @see mv_face_recognition_model_destroy()
+ * @see mv_face_recognition_model_learn()
+ */
+typedef void *mv_face_recognition_model_h;
+
+/**
+ * @brief The handle to the model aggregating tracking face features.
+ * @details This model can be used for face tracking with @ref mv_face_track()
+ *          function. Handle has to be created by
+ *          @ref mv_face_tracking_model_create() and destroyed by
+ *          @ref mv_face_tracking_model_destroy() function. Tracking model can
+ *          be improved during tracking task and allows to track face more
+ *          accurately. So, you can create several tracking models independently
+ *          by default, then apply tracking task for each of them. After some
+ *          tracking these models will be different and each of them will be
+ *          more efficient for tracking of face for which was created.
+ *
+ * @since_tizen 3.0
+ * @remarks Create each tracking model for single face.
+ *
+ * @see mv_face_tracking_model_create()
+ * @see mv_face_tracking_model_destroy()
+ */
+typedef void *mv_face_tracking_model_h;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_FACE_TYPE_H__ */
diff --git a/include/mv_image.h b/include/mv_image.h
new file mode 100644 (file)
index 0000000..5fa9cf6
--- /dev/null
@@ -0,0 +1,857 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_IMAGE_H__
+#define __TIZEN_MEDIAVISION_IMAGE_H__
+
+#include <mv_common.h>
+#include <mv_image_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_image.h
+ * @brief This file contains the Media Vision Image API.
+ *        Working with images (like planar objects): recognition and tracking.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_IMAGE_MODULE
+ * @{
+ */
+
+/**
+ * @brief Defines MV_IMAGE_RECOGNITION_OBJECT_SCALE_FACTOR to set the image to
+ *        be recognized scale factor attribute of the engine configuration.
+ * @details The value of the factor will be used for resizing of
+ *          the images (objects) for recognition. Scale factor is the double value
+ *          and the defalut is 1.2
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_RECOGNITION_OBJECT_SCALE_FACTOR "MV_IMAGE_RECOGNITION_OBJECT_SCALE_FACTOR"
+
+/**
+ * @brief Defines MV_IMAGE_RECOGNITION_OBJECT_MAX_KEYPOINTS_NUM to set the maximum
+ *        keypoints should be detected on the image attribute of the
+ *        engine configuration.
+ * @details The maximal number of keypoints can be selected on the image
+ *          object to calculate descriptors. This keypoints will be used
+ *          for image (object) recognition and has to be specified as integer number
+ *          and the defalut is 1000
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_IMAGE_RECOGNITION_OBJECT_MAX_KEYPOINTS_NUM "MV_IMAGE_RECOGNITION_OBJECT_MAX_KEYPOINTS_NUM"
+
+/**
+ * @brief Defines MV_IMAGE_RECOGNITION_SCENE_SCALE_FACTOR to set the scene scale
+ *        factor attribute of the engine configuration.
+ * @details The value of the factor will be used for resizing of
+ *          the scene including the images (objects) for recognition.
+ *          Scale factor is the double value and the defalut is 1.2
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_RECOGNITION_SCENE_SCALE_FACTOR "MV_IMAGE_RECOGNITION_SCENE_SCALE_FACTOR"
+
+/**
+ * @brief Defines MV_IMAGE_RECOGNITION_SCENE_MAX_KEYPOINTS_NUM to set the maximum
+ *        keypoints should be detected on the scene attribute of the engine
+ *        configuration.
+ * @details The maximal number of keypoints can be selected on the scene including
+ *          the images (objects) to calculate descriptors.
+ *          This keypoints will be used for image recognition and has to be specified
+ *          as unsigned integer and the defalut is 5000
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_RECOGNITION_SCENE_MAX_KEYPOINTS_NUM "MV_IMAGE_RECOGNITION_SCENE_MAX_KEYPOINTS_NUM"
+
+/**
+ * @brief Defines MV_IMAGE_RECOGNITION_MIN_MATCH_NUM to set the minimum number
+ *        of keypoints matches required for recognition attribute of the engine
+ *        configuration.
+ * @details The minimal number of keypoints should be matched between an image and a scene.
+ *          It will be taken into account for image objects recognition.
+ *          Value is unsigned integer and the defalut is 30
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_IMAGE_RECOGNITION_MIN_MATCH_NUM "MV_IMAGE_RECOGNITION_MIN_MATCH_NUM"
+
+/**
+ * @brief Defines MV_IMAGE_RECOGNITION_REQ_MATCH_PART to set the required
+ *        matching part for the image recognition attribute of the engine
+ *        configuration.
+ * @details To recognize occluded or hidden an image by other images,
+ *          required relative part of the matches in respect to the total
+ *          amount of matching keypoints required for image recognition.
+ *          Too low value will result in unsustainable behavior, but
+ *          effect of object overlapping will be reduced. Value can be from 0 to 1
+ *          and the defalut is 0.05
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_RECOGNITION_REQ_MATCH_PART "MV_IMAGE_RECOGNITION_REQ_MATCH_PART"
+
+/**
+ * @brief Defines MV_IMAGE_RECOGNITION_TOLERANT_MATCH_PART_ERR to set the part
+ *        matching error for the image recognition attribute of the engine
+ *        configuration.
+ * @details Allowable error of matches number. Value can be from 0 to 1
+ *          and the defalut is 0.1
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_RECOGNITION_TOLERANT_MATCH_PART_ERR "MV_IMAGE_RECOGNITION_TOLERANT_MATCH_PART_ERR"
+
+/**
+ * @brief Defines MV_IMAGE_TRACKING_HISTORY_AMOUNT to set the number of
+ *        recognition results in the tracking history attribute of the engine
+ *        configuration.
+ * @details Number of previous recognition results, which will influence
+ *         the stabilization. Value is unsigned integer and the defalut is 3
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_int_attribute()
+ * @see mv_engine_config_get_int_attribute()
+ */
+#define MV_IMAGE_TRACKING_HISTORY_AMOUNT "MV_IMAGE_TRACKING_HISTORY_AMOUNT"
+
+/**
+ * @brief Defines MV_IMAGE_TRACKING_EXPECTED_OFFSET to set the expected tracking
+ *        offset attribute of the engine configuration.
+ * @detials Relative offset value, for which the object offset is
+ *          expected (relative to the object size in the current frame).
+ *          Value is a double and the defalut is 0
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_TRACKING_EXPECTED_OFFSET "MV_IMAGE_TRACKING_EXPECTED_OFFSET"
+
+/**
+ * @brief Defines MV_IMAGE_TRACKING_USE_STABLIZATION to enable the contour
+ *        stabilization during tracking process.
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_bool_attribute()
+ * @see mv_engine_config_get_bool_attribute()
+ */
+#define MV_IMAGE_TRACKING_USE_STABLIZATION "MV_IMAGE_TRACKING_USE_STABLIZATION"
+
+/**
+ * @brief Defines MV_IMAGE_TRACKING_STABLIZATION_TOLERANT_SHIFT to set the
+ *        tolerant shift for the tracking stabilization attribute of the engine
+ *        configuration.
+ * @details Relative value of maximum shift per one frame which will be ignored by
+ *             stabilization (relative to the object size in the current frame).
+ *            Value is a double and the defalut is 0.006
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_TRACKING_STABLIZATION_TOLERANT_SHIFT "MV_IMAGE_TRACKING_STABLIZATION_TOLERANT_SHIFT"
+
+/**
+ * @brief Defines MV_IMAGE_TRACKING_STABLIZATION_SPEED to set the
+ *        speed of the tracking stabilization attribute of the engine
+ *        configuration.
+ * @details Start speed will be used for image stabilization. Value is a double
+ *          and the defalut is 2
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_TRACKING_STABLIZATION_SPEED "MV_IMAGE_TRACKING_STABLIZATION_SPEED"
+
+/**
+ * @brief Defines MV_IMAGE_TRACKING_STABLIZATION_ACCELERATION to set the
+ *        acceleration of the tracking stabilization attribute of the engine
+ *        configuration.
+ * @details Acceleration will be used for image stabilization (relative to
+ *          the distance from current location to stabilized location).
+ *          Value is double from 0 to 1 and the defalut is 0.001
+ *
+ * @since_tizen 3.0
+ * @see mv_engine_config_set_double_attribute()
+ * @see mv_engine_config_get_double_attribute()
+ */
+#define MV_IMAGE_TRACKING_STABLIZATION_ACCELERATION "MV_IMAGE_TRACKING_STABLIZATION_ACCELERATION"
+
+/****************************/
+/* Image object recognition */
+/****************************/
+
+/**
+ * @brief Called when image recognition results are received from @ref mv_image_recognize()
+ * @details This type of callback will be called after @ref mv_image_recognize()
+ *          in order to process recognition result.
+ *
+ * @since_tizen 3.0
+ * @remarks Values @a source, @a engine_cfg, @a image_objects, and @a number_of_objects
+ *          are the same as values of input parameters of @ref mv_image_recognize().
+ * @remarks @locations are valid only inside callback.
+ * @param [in] source              The handle to the source image on which the
+ *                                 recognition was carried out
+ * @param [in] engine_cfg          The handle to the configuration of engine
+ *                                 that was used for image recognition, or NULL
+ *                                 if default settings were applied
+ * @param [in] image_objects       The set of handles to the image objects which
+ *                                 have been processed as targets of recognition
+ * @param [in] locations           The locations of image objects on the source
+ *                                 image. This array corresponding to an array
+ *                                 of image objects and each element contains a
+ *                                 location of corresponding object on the
+ *                                 @a source image or NULL if object is not
+ *                                 recognized
+ * @param [in] number_of_objects   The number of image objects and corresponding
+ *                                 locations
+ * @param [in] user_data           The user data passed from the
+ *                                 @ref mv_image_recognize() function
+ *
+ * @pre Call @ref mv_image_recognize() function to perform recognition of the
+ *      image objects on the source image and invoke this callback as a result
+ *
+ * @see mv_image_recognize()
+ * @see mv_source_h
+ * @see mv_image_object_h
+ * @see mv_engine_config_h
+ * @see mv_quadrangle_s
+ */
+typedef void (*mv_image_recognized_cb)(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        const mv_image_object_h *image_objects,
+        mv_quadrangle_s **locations,
+        unsigned int number_of_objects,
+        void *user_data);
+
+/**
+ * @brief Recognizes the given image objects on the source image.
+ * @details Use this function to launch image recognition algorithm configured
+ *          by @a engine_conf configuration.
+ *
+ * @since_tizen 3.0
+ * @param [in] source              The handle to the source image on which image
+ *                                 objects will be recognized
+ * @param [in] image_objects       The set of handles to the image objects which
+ *                                 will be processed as targets of recognition
+ * @param [in] number_of_objects   The number of image objects
+ * @param [in] engine_cfg          The handle to the configuration of engine
+ *                                 which will be used for recognition. If NULL,
+ *                                 then default settings will be used.
+ * @param [in] recognized_cb       The callback which will be called in order to
+ *                                 process recognition result
+ * @param [in] user_data           The user data to be passed to the
+ *                                 @a recognized_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a set of image objects using @ref mv_image_object_create() for
+ *      each of them and construct (fill / load / clone) them on images that
+ *      will be recognized
+ * @pre Create a source handle by calling @ref mv_create_source() and fill
+ *      by the image for which recognition will be performed
+ * @post @a mv_image_recognized_cb will be called to process recognition result
+ * @post Release source image by using @ref mv_destroy_source()
+ * @post Release image objects by using @ref mv_image_object_destroy() for each
+ *       handle from @a image_objects set
+ *
+ * @see mv_image_recognized_cb
+ * @see mv_source_h
+ * @see mv_create_source()
+ * @see mv_destroy_source()
+ * @see mv_image_object_h
+ * @see mv_image_object_create()
+ * @see mv_image_object_destroy()
+ * @see mv_engine_config_h
+ */
+int mv_image_recognize(
+        mv_source_h source,
+        const mv_image_object_h *image_objects,
+        int number_of_objects,
+        mv_engine_config_h engine_cfg,
+        mv_image_recognized_cb recognized_cb,
+        void *user_data);
+
+/*************************/
+/* Image object tracking */
+/*************************/
+
+/**
+ * @brief Called when image tracking result received from @ref mv_image_track()
+ * @details Image tracking on a sequence of frames assumes calling
+ *          @ref mv_image_track() function for each frame in the correct order.
+ *          This type of callback will be called after each @ref mv_image_track()
+ *          call for processing result data.
+ *
+ * @since_tizen 3.0
+ * @remarks If image object is not tracked then the callback will be invoked,
+ *          but @a location will be NULL.
+ * @remarks Handles @a image_tracking_model, @a source and @a engine_cfg the
+ *          same as input parameters of @ref mv_image_track().
+ * @remarks @location pointer is valid only inside callback
+ * @param [in] source                 The handle to the source image on which
+ *                                    the tracking was carried out
+ * @param [in] image_tracking_model   The handle to the image tracking model
+ *                                    which processed as target of tracking
+ * @param [in] engine_cfg             The handle to the configuration of engine
+ *                                    that was used to image tracking, or
+ *                                    NULL if default settings were applied
+ * @param [in] location               The image object location on the source
+ *                                    image or NULL if objects is not tracked
+ * @param [in] user_data              The user data passed from the
+ *                                    @ref mv_image_track() function
+ *
+ * @pre Call @ref mv_image_track() function to perform tracking of the image
+ *      object on the current image from the sequence and invoke this callback
+ *      as a result
+ *
+ * @see mv_image_track()
+ * @see mv_source_h
+ * @see image_tracking_model_h
+ * @see mv_engine_config_h
+ * @see mv_quadrangle_s
+ */
+typedef void (*mv_image_tracked_cb)(
+        mv_source_h source,
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_quadrangle_s *location,
+        void *user_data);
+
+/**
+ * @brief Tracks the given image tracking model on the current frame
+ * @details Image tracking on a sequence of frames assumes calling this
+ *          function for each frame in the correct order.
+ *          @a tracked_cb will be called  for result processing.
+ *
+ * @since_tizen 3.0
+ * @remarks Tracking algorithm is usually using for recognition of image object
+ *          on the sequence of images that are organized by time. For example,
+ *          it may be the sequence of frames from a video stream.
+ * @remarks If object is lost during the tracking, system tries to find it
+ *          further for the following frames. Therefore, tracking will be
+ *          recovered when object appears again.
+ * @remarks Previous calls of @ref mv_image_track() for this
+ *          @a image_tracking_model will affect on current call
+ * @param [in]     source                 The handle to the current image of
+ *                                        sequence where image tracking model
+ *                                        will be tracked
+ * @param [in,out] image_tracking_model   The handle to the image tracking model
+ *                                        which processed as target of tracking
+ * @param [in]     engine_cfg             The handle to the configuration of
+ *                                        engine which will be used for tracking.
+ *                                        If NULL, then default settings will be
+ *                                        used.
+ * @param [in]     tracked_cb             The callback which will receive
+ *                                        tracking results
+ * @param [in]     user_data              The user data to be passed to the
+ *                                        @a tracked_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create() and set target by calling
+ *      @ref mv_image_tracking_model_set_target()
+ * @pre Create a source images by calling @ref mv_create_source() for each of
+ *      them and construct them based on sequence of images for which will be
+ *      held image tracking
+ * @post @a tracked_cb will be called to process tracking result
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy()
+ *
+ * @see mv_image_tracked_cb
+ * @see mv_source_h
+ * @see image_tracking_model_h
+ * @see mv_image_tracking_model_create()
+ * @see mv_image_tracking_model_set_target()
+ * @see mv_image_tracking_model_destroy()
+ */
+int mv_image_track(
+        mv_source_h source,
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_image_tracked_cb tracked_cb,
+        void *user_data);
+
+/**************************/
+/* Image object behaviour */
+/**************************/
+
+/**
+ * @brief Creates an image object.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_object    A new handle to the image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @post Release image object by using @ref mv_image_object_destroy()
+ *
+ * @see mv_image_object_destroy()
+ * @see mv_image_object_h
+ */
+int mv_image_object_create(
+        mv_image_object_h *image_object);
+
+/**
+ * @brief Destroys the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object    The handle to the image object to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create()
+ *
+ * @see mv_image_object_create()
+ * @see mv_image_object_h
+ */
+int mv_image_object_destroy(
+        mv_image_object_h image_object);
+
+/**
+ * @brief Fills the image object.
+ * @details Extracts data from @a source image which will be needed for
+ *          recognition of depicted object in @a location.
+ *
+ * @since_tizen 3.0
+ * @remarks After filling the image object it can be evaluated by
+ *          @ref mv_image_object_get_recognition_rate(). If recognition rate
+ *          is too low, try to use another image of object or change
+ *          configuration parameters (see @ref mv_engine_config_h) and construct
+ *          the image object again.
+ * @param [in,out] image_object    The handle to the image object which will be
+ *                                 filled and can be recognized in future
+ * @param [in]     engine_cfg      The handle to the configuration of engine
+ *                                 which will be used for extract recognition
+ *                                 data from @a source. If NULL, then default
+ *                                 settings will be used.
+ * @param [in]     source          The source image where image object is depicted
+ * @param [in]     location        The pointer to location of the image object
+ *                                 on the source image, or NULL if the object is
+ *                                 shown in full
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create()
+ * @post Release image object by using @ref mv_image_object_destroy()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create()
+ * @see mv_image_object_get_recognition_rate()
+ * @see mv_image_recognize()
+ * @see mv_image_object_destroy()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_fill(
+        mv_image_object_h image_object,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_rectangle_s *location);
+
+/**
+ * @brief Gets a value that determines how well an image object can be recognized.
+ * @details Recognition rate determines how well an image object can be
+ *          recognized. This value can be from 0 to 1. If the recognition rate
+ *          is 0 object can not be recognized and the bigger it is the more
+ *          likely to recognize the object.
+ *
+ * @since_tizen 3.0
+ * @remarks If recognition rate is too low, try to use another image of object
+ *          or change some configuration parameters (see @ref mv_engine_config_h)
+ *          and fill the image object again (see @ref mv_image_object_fill()).
+ * @param [in]  image_object        The handle to the image object which will be
+ *                                  evaluated by this function
+ * @param [out] recognition_rate    A value that determines how well an image
+ *                                  object can be recognized, if 0 then object
+ *                                  can not be recognized
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create()
+ * @post Release image object by using @ref mv_image_object_destroy()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create()
+ * @see mv_image_object_fill()
+ * @see mv_image_object_destroy()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_get_recognition_rate(
+        mv_image_object_h image_object,
+        double *recognition_rate);
+
+/**
+ * @brief Sets a label for the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object   The handle to the image object for which the label
+ *                            will be assigned
+ * @param [in] label          The label which will be assigned to the image
+ *                            object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create()
+ * @post Label could be received by using @ref mv_image_object_get_label()
+ * @post Release image object by using @ref mv_image_object_destroy()
+ *
+ * @see mv_image_object_get_label()
+ * @see mv_image_object_h
+ * @see mv_image_object_create()
+ * @see mv_image_object_destroy()
+ */
+int mv_image_object_set_label(
+        mv_image_object_h image_object,
+        int label);
+
+/**
+ * @brief Gets a label of image object.
+ *
+ * @since_tizen 3.0
+ * @remarks If @a image_object have not a label, this function return
+ *          MEDIA_VISION_ERROR_NO_DATA value.
+ * @param [in]  image_object   The handle to the image object from which a
+ *                             label will be received
+ * @param [out] label          The label of image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NO_DATA Image object hasn't label
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create()
+ * @pre Set label for the image object by using @ref mv_image_object_set_label()
+ * @post Release image object by using @ref mv_image_object_destroy()
+ *
+ * @see mv_image_object_set_label()
+ * @see mv_image_object_h
+ * @see mv_image_object_create()
+ * @see mv_image_object_destroy()
+ */
+int mv_image_object_get_label(
+        mv_image_object_h image_object,
+        int *label);
+
+/**
+ * @brief Clones the image object.
+ *
+ * @since_tizen 3.0
+ * @remarks @a dst must be released using mv_image_object_destroy().
+ * @param [in]  src    The handle to the source image object
+ * @param [out] dst    The handle to the destination image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Create image object handles by calling mv_image_object_create()
+ *
+ * @see mv_image_object_create()
+ * @see mv_image_object_destroy()
+ */
+int mv_image_object_clone(
+        mv_image_object_h src,
+        mv_image_object_h *dst);
+
+/**
+ * @brief Saves the image object.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is saved to the application's data directory.
+ * @param [in] file_name       Name of the file to save the image object
+ * @param [in] image_object    The handle to the image object which will be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object handle by calling mv_image_object_create()
+ * @post Saved model can be loaded later by calling
+ *       mv_image_object_load() function
+ *
+ * @see mv_image_object_create()
+ * @see mv_image_object_load()
+ * @see mv_image_object_destroy()
+ */
+int mv_image_object_save(
+        const char *file_name, mv_image_object_h image_object);
+
+/**
+ * @brief Loads an image object from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is loaded from the application's data directory.
+ *          @a image_object must be destroyed using
+ *          @ref mv_image_object_destroy().
+ * @param [in]  file_name       Name of file to load the image object
+ * @param [out] image_object    The handle to the image object which will be
+ *                              filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Image object can be preliminary saved with mv_image_object_save()
+ *      function
+ *
+ * @see mv_image_object_save()
+ * @see mv_image_object_destroy()
+ */
+int mv_image_object_load(
+        const char *file_name, mv_image_object_h *image_object);
+
+/**********************************/
+/* Image tracking model behaviour */
+/**********************************/
+
+/**
+ * @brief Creates an image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_tracking_model    A new handle to the image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post Release image tracking model by using mv_image_tracking_model_destroy()
+ *
+ * @see mv_image_tracking_model_destroy()
+ */
+int mv_image_tracking_model_create(
+        mv_image_tracking_model_h *image_tracking_model);
+
+/**
+ * @brief Sets target of image tracking model.
+ * @details Sets image object which will be tracked by using tracking
+ *          functionality with @a image_tracking_model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object            Image object which will be set
+ *                                     as target for tracking
+ * @param [in] image_tracking_model    Handle to the image tracking model
+ *                                     for which will be set a new target
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create()
+ * @pre Create an image object using @ref mv_image_object_create() and construct
+ *      (fill / load / clone) it on image that will be tracking
+ * @post Release image object by using @ref mv_image_object_destroy()
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_tracking_model_h
+ * @see mv_image_object_create()
+ * @see mv_image_object_destroy()
+ * @see mv_image_tracking_model_create()
+ * @see mv_image_track()
+ * @see mv_image_tracking_model_destroy()
+ */
+int mv_image_tracking_model_set_target(
+        mv_image_object_h image_object,
+        mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Destroys the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model    The handle to the image tracking model
+ *                                     to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by using mv_image_tracking_model_create()
+ *
+ * @see mv_image_tracking_model_create()
+ */
+int mv_image_tracking_model_destroy(
+        mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Refreshes the state of image tracking model.
+ * @details Clears moving history and change state to undetected. This function
+ *          is usually called each time before tracking is started for the new
+ *          sequence of sources which is not the direct continuation of the
+ *          sequence for which tracking has been performed before. Tracking
+ *          algorithm will try to find image by itself.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model   The handle to the image tracking model
+ *                                    which will be refreshed
+ * @param [in] engine_cfg             The handle to the configuration of
+ *                                    engine which will be used. If NULL,
+ *                                    then default settings will be used.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create()
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy()
+ *
+ * @see mv_image_tracking_model_h
+ * @see mv_image_tracking_model_create()
+ * @see mv_image_track()
+ * @see mv_image_tracking_model_destroy()
+ */
+int mv_image_tracking_model_refresh(
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg);
+
+/**
+ * @brief Clones the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a dst must be released using mv_image_tracking_model_destroy().
+ * @param [in]  src    The handle to the source image tracking model
+ * @param [out] dst    The handle to the destination image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Create image tracking model handles by calling
+ *      mv_image_tracking_model_create()
+ *
+ * @see mv_image_tracking_model_create()
+ * @see mv_image_tracking_model_destroy()
+ */
+int mv_image_tracking_model_clone(
+        mv_image_tracking_model_h src,
+        mv_image_tracking_model_h *dst);
+
+/**
+ * @brief Saves the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is saved to the application's data directory.
+ * @param [in] file_name               Name of file to save the model
+ * @param [in] image_tracking_model    The handle to the image tracking model
+ *                                     to be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model handle by calling
+ *      mv_image_tracking_model_create()
+ * @post Saved model can be loaded later by calling
+ *       mv_image_tracking_model_load() function
+ *
+ * @see mv_image_tracking_model_create()
+ * @see mv_image_tracking_model_load()
+ * @see mv_image_tracking_model_destroy()
+ */
+int mv_image_tracking_model_save(
+        const char *file_name, mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Loads an image tracking model from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is loaded from the application's data directory.
+ *          @a image_tracking_model must be destroyed using
+ *          @ref mv_image_tracking_model_destroy.
+ * @param [in]  file_name               Name of file to load model
+ * @param [out] image_tracking_model    The handle to the image tracking
+ *                                      model to be filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Image tracking model handle can be preliminary saved with
+ *      mv_image_tracking_model_save() function
+ *
+ * @see mv_image_tracking_model_save()
+ * @see mv_image_tracking_model_destroy()
+ */
+int mv_image_tracking_model_load(
+        const char *file_name, mv_image_tracking_model_h *image_tracking_model);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_IMAGE_H__ */
diff --git a/include/mv_image_type.h b/include/mv_image_type.h
new file mode 100644 (file)
index 0000000..9875685
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_IMAGE_TYPE_H__
+#define __TIZEN_MEDIAVISION_IMAGE_TYPE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_image_type.h
+ * @brief This file contains enumerations and handles definition required by
+ *        image recognize/track API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_IMAGE_MODULE
+ * @{
+ */
+
+/* Provided data types */
+
+/**
+ * @brief The image object's type handle.
+ *
+ * @since_tizen 3.0
+ */
+typedef void *mv_image_object_h;
+
+/**
+ * @brief The image tracking model's type handle.
+ *
+ * @since_tizen 3.0
+ */
+typedef void *mv_image_tracking_model_h;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_IMAGE_TYPE_H__ */
diff --git a/include/mv_private.h b/include/mv_private.h
new file mode 100644 (file)
index 0000000..7877a2b
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIA_VISION_PRIVATE_H__
+#define __TIZEN_MEDIA_VISION_PRIVATE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdbool.h>
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "TIZEN_MEDIA_VISION"
+
+#define MEDIA_VISION_FUNCTION_ENTER() \
+        LOGI("[%s] <ENTER>", __FUNCTION__)
+
+#define MEDIA_VISION_FUNCTION_LEAVE() \
+        LOGI("[%s] <LEAVE>", __FUNCTION__)
+
+#define MEDIA_VISION_ASSERT(function, msg) \
+        do \
+        { \
+            int error_code = function; \
+            if(error_code != MEDIA_VISION_ERROR_NONE) \
+            { \
+                LOGE("%s(0x%08x)", msg, error_code); \
+                return error_code; \
+            } \
+        } \
+        while(0)
+
+#define MEDIA_VISION_CHECK_CONDITION(condition,error,msg) \
+        do \
+        { \
+            if(!(condition)) \
+            { \
+                LOGE("[%s] %s(0x%08x)", __FUNCTION__, msg, error); \
+                return error; \
+            } \
+        } \
+        while(0)
+
+#define MEDIA_VISION_INSTANCE_CHECK(arg) \
+        MEDIA_VISION_CHECK_CONDITION(arg != NULL, \
+                                     MEDIA_VISION_ERROR_INVALID_PARAMETER, \
+                                     "MEDIA_VISION_ERROR_INVALID_PARAMETER")
+
+#define MEDIA_VISION_NULL_ARG_CHECK(arg) \
+        MEDIA_VISION_CHECK_CONDITION(arg != NULL, \
+                                     MEDIA_VISION_ERROR_INVALID_PARAMETER, \
+                                     "MEDIA_VISION_ERROR_INVALID_PARAMETER")
+
+#define MEDIA_VISION_SUPPORT_CHECK(arg) \
+        MEDIA_VISION_CHECK_CONDITION(arg != false, MEDIA_VISION_ERROR_NOT_SUPPORTED, \
+                                     "MEDIA_VISION_ERROR_NOT_SUPPORTED")
+
+bool __mv_check_system_info_feature_supported();
+bool __mv_barcode_detect_check_system_info_feature_supported();
+bool __mv_barcode_generate_check_system_info_feature_supported();
+bool __mv_face_check_system_info_feature_supported();
+bool __mv_image_check_system_info_feature_supported();
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIA_VISION_PRIVATE_H__ */
diff --git a/media-vision-config-example.json b/media-vision-config-example.json
new file mode 100644 (file)
index 0000000..2de8fed
--- /dev/null
@@ -0,0 +1,21 @@
+{
+    "attributes":
+    [
+        {   "name"  : "sample_double_attribute",
+            "type"  : "double",
+            "value" : 0.82,
+        },
+        {   "name"  : "sample_integer_attribute",
+            "type"  : "integer",
+            "value" : 50,
+        },
+        {   "name"  : "sample_boolean_attribute",
+            "type"  : "boolean",
+            "value" : true,
+        },
+        {   "name"  : "sample_string attribute",
+            "type"  : "string",
+            "value" : "test string",
+        },
+    ]
+}
diff --git a/media-vision-config.json b/media-vision-config.json
new file mode 100644 (file)
index 0000000..902567e
--- /dev/null
@@ -0,0 +1,120 @@
+{
+    "attributes":
+    [
+        {
+            "name"  : "MV_FACE_DETECTION_MODEL_FILE_PATH",
+            "type"  : "string",
+            "value" : "/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml",
+        },
+        {
+            "name"  : "MV_FACE_DETECTION_ROI_X",
+            "type"  : "integer",
+            "value" : -1,
+        },
+        {
+            "name"  : "MV_FACE_DETECTION_ROI_Y",
+            "type"  : "integer",
+            "value" : -1,
+        },
+        {
+            "name"  : "MV_FACE_DETECTION_ROI_WIDTH",
+            "type"  : "integer",
+            "value" : -1,
+        },
+        {
+            "name"  : "MV_FACE_DETECTION_ROI_HEIGHT",
+            "type"  : "integer",
+            "value" : -1,
+        },
+        {
+            "name"  : "MV_FACE_DETECTION_MIN_SIZE_WIDTH",
+            "type"  : "integer",
+            "value" : -1,
+        },
+        {
+            "name"  : "MV_FACE_DETECTION_MIN_SIZE_HEIGHT",
+            "type"  : "integer",
+            "value" : -1,
+        },
+        {
+            "name" : "MV_BARCODE_DETECT_ATTR_MODE",
+            "type" : "integer",
+            "value" : 1,
+        },
+        {
+            "name" : "MV_BARCODE_DETECT_ATTR_TARGET",
+            "type" : "integer",
+            "value" : 0,
+        },
+        {
+            "name"  : "MV_IMAGE_RECOGNITION_OBJECT_SCALE_FACTOR",
+            "type"  : "double",
+            "value" : 1.2,
+        },
+        {
+            "name"  : "MV_IMAGE_RECOGNITION_OBJECT_MAX_KEYPOINTS_NUM",
+            "type"  : "integer",
+            "value" : 1000,
+        },
+        {
+            "name"  : "MV_IMAGE_RECOGNITION_SCENE_SCALE_FACTOR",
+            "type"  : "double",
+            "value" : 1.2,
+        },
+        {
+            "name"  : "MV_IMAGE_RECOGNITION_SCENE_MAX_KEYPOINTS_NUM",
+            "type"  : "integer",
+            "value" : 5000,
+        },
+        {
+            "name"  : "MV_IMAGE_RECOGNITION_MIN_MATCH_NUM",
+            "type"  : "integer",
+            "value" : 30,
+        },
+        {
+            "name"  : "MV_IMAGE_RECOGNITION_REQ_MATCH_PART",
+            "type"  : "double",
+            "value" : 0.05,
+        },
+        {
+            "name"  : "MV_IMAGE_RECOGNITION_TOLERANT_MATCH_PART_ERR",
+            "type"  : "double",
+            "value" : 0.1,
+        },
+        {
+            "name"  : "MV_IMAGE_TRACKING_HISTORY_AMOUNT",
+            "type"  : "integer",
+            "value" : 3,
+        },
+        {
+            "name"  : "MV_IMAGE_TRACKING_EXPECTED_OFFSET",
+            "type"  : "double",
+            "value" : 0,
+        },
+        {
+            "name"  : "MV_IMAGE_TRACKING_USE_STABLIZATION",
+            "type"  : "boolean",
+            "value" : false,
+        },
+        {
+            "name"  : "MV_IMAGE_TRACKING_STABLIZATION_TOLERANT_SHIFT",
+            "type"  : "double",
+            "value" : 0.006,
+        },
+        {
+            "name"  : "MV_IMAGE_TRACKING_STABLIZATION_SPEED",
+            "type"  : "double",
+            "value" : 2,
+        },
+        {
+            "name"  : "MV_IMAGE_TRACKING_STABLIZATION_ACCELERATION",
+            "type"  : "double",
+            "value" : 0.001,
+        },
+        {
+            "name"  : "MV_FACE_RECOGNITION_MODEL_TYPE",
+            "type"  : "integer",
+            "value" : 3,
+        }
+    ]
+}
diff --git a/mv_barcode/CMakeLists.txt b/mv_barcode/CMakeLists.txt
new file mode 100644 (file)
index 0000000..88da8a9
--- /dev/null
@@ -0,0 +1,14 @@
+project(mv_barcode)
+cmake_minimum_required(VERSION 2.6)
+
+if(MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT)
+    add_subdirectory(${PROJECT_SOURCE_DIR}/barcode_detector_lic) # Licensed port
+else()
+    add_subdirectory(${PROJECT_SOURCE_DIR}/barcode_detector) # Open port
+endif()
+
+if(MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT)
+    add_subdirectory(${PROJECT_SOURCE_DIR}/barcode_generator_lic) # Licened port
+else()
+    add_subdirectory(${PROJECT_SOURCE_DIR}/barcode_generator) # Open port
+endif()
diff --git a/mv_barcode/barcode_detector/CMakeLists.txt b/mv_barcode/barcode_detector/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4a85be3
--- /dev/null
@@ -0,0 +1,29 @@
+project(${MV_BARCODE_DETECTOR_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+if(NOT SKIP_WARNINGS)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_BARCODE_DET_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_BARCODE_DET_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp")
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_BARCODE_DET_INC_LIST} ${MV_BARCODE_DET_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_BARCODE_DET_INC_LIST} ${MV_BARCODE_DET_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME} zbar dlog)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_barcode/barcode_detector/include/Barcode.h b/mv_barcode/barcode_detector/include/Barcode.h
new file mode 100644 (file)
index 0000000..6003fb1
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BARCODE_H__
+#define __BARCODE_H__
+
+#include "mv_barcode.h"
+
+#include <stddef.h>
+#include <zbar.h>
+
+namespace MediaVision
+{
+namespace Barcode
+{
+
+/**
+ * @class    Barcode
+ * @brief    Handle to barcode object.
+ */
+class Barcode
+{
+public:
+    /**
+     * @brief   Barcode constructor.
+     *
+     * @since_tizen 2.4
+     * @remarks create copy of bar_obj
+     * @param   [in] barObj zbar barcode handle
+     *
+     */
+    Barcode(const zbar::Symbol& barObj);
+
+    /**
+     * @brief  Barcode destructor.
+     *
+     * @since_tizen 2.4
+     */
+    ~Barcode();
+
+    /**
+     * @brief  Gets encoded message from barcode object.
+     *
+     * @since_tizen 2.4
+     * @return Encoded message
+     */
+    std::string getMessage(void) const;
+
+    /**
+     * @brief Gets the type of the barcode.
+     *
+     * @since_tizen 2.4
+     * @return Enumeration value corresponding to the barcode type
+     */
+    mv_barcode_type_e getType(void) const;
+
+    /**
+     * @brief  Calculates location of barcode handle from zbar.
+     *         location polygon.
+     *
+     * @since_tizen 2.4
+     * @param  [out] location    Quadrangle that contains barcode on image
+     * @return @c MEDIA_VISION_ERROR_NONE on success,
+     *         otherwise a negative error value
+     */
+    int calculateLocation(mv_quadrangle_s& location) const;
+
+private:
+    const zbar::Symbol *m_pBarcodeObj; ///< Pointer to zbar barcode handle
+};
+
+} /* Barcode */
+} /* MediaVision */
+
+#endif /* __BARCODE_H__ */
diff --git a/mv_barcode/barcode_detector/include/BarcodeUtils.h b/mv_barcode/barcode_detector/include/BarcodeUtils.h
new file mode 100644 (file)
index 0000000..4dea365
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_UTILS_H__
+#define __TIZEN_MEDIAVISION_BARCODE_UTILS_H__
+
+#include "mv_common.h"
+
+namespace zbar
+{
+    class Image;
+}
+
+namespace MediaVision
+{
+namespace Barcode
+{
+
+/**
+ * @brief    This function converts media vision image handle to zbar image handle.
+ *
+ * @since_tizen 2.4
+ * @param [in]  mvSource      Media vision image handle
+ * @param [out] zbarSource    Zbar image handle
+ * @return @c MEDIA_VISION_ERROR_NONE on success,
+           otherwise a negative error value
+ */
+int convertSourceMV2Zbar(mv_source_h mvSource, zbar::Image& zbarSource);
+
+} /* Barcode */
+} /* MediaVision */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_UTILS_H__ */
diff --git a/mv_barcode/barcode_detector/include/mv_barcode_detect_open.h b/mv_barcode/barcode_detector/include/mv_barcode_detect_open.h
new file mode 100644 (file)
index 0000000..e13d8e7
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_DETECT_OPEN_H__
+#define __TIZEN_MEDIAVISION_BARCODE_DETECT_OPEN_H__
+
+#include "mv_barcode_detect.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_barcode_detect_open.h
+ * @brief This file contains the Media Vision barcode detect module API for the
+ *        open module.
+ */
+
+/**
+ * @brief Detects barcode(s) on source and reads message from it.
+ *
+ * @since_tizen 2.4
+ * @param [in] source            The media source handle
+ * @param [in] engine_cfg        The handle to the configuration of the engine
+ * @param [in] roi               Region of interest - rectangular area on the
+ *                               @a source which will be used for barcode detection
+ *                               Note that @a roi should be inside area on the
+ *                               @a source.
+ * @param [in] detect_cb         The callback for result handling
+ * @param [in] user_data    The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ * @retval #MEDIA_VISION_ERROR_INTERNAL Internal error
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create an engine configuration handle by calling
+ *      @ref mv_create_engine_config() if necessary, otherwise use NULL
+ *
+ * @see mv_barcode_detected_cb()
+ */
+int mv_barcode_detect_open(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s roi,
+        mv_barcode_detected_cb detect_cb,
+        void *user_data);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_DETECT_OPEN_H__ */
diff --git a/mv_barcode/barcode_detector/src/Barcode.cpp b/mv_barcode/barcode_detector/src/Barcode.cpp
new file mode 100644 (file)
index 0000000..a35f8bd
--- /dev/null
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Barcode.h"
+
+#include <mv_private.h>
+
+namespace MediaVision
+{
+namespace Barcode
+{
+
+Barcode::Barcode(const zbar::Symbol& barObj):
+                 m_pBarcodeObj(new zbar::Symbol(barObj))
+{
+    ; /* NULL */
+}
+
+Barcode::~Barcode()
+{
+    LOGI("Delete ZBar object");
+    delete m_pBarcodeObj;
+}
+
+std::string Barcode::getMessage(void) const
+{
+    LOGI("Retrieve message data from ZBar object");
+    return m_pBarcodeObj->get_data();
+}
+
+mv_barcode_type_e Barcode::getType(void) const
+{
+    zbar::zbar_symbol_type_t barcodeType = m_pBarcodeObj->get_type();
+
+    switch (barcodeType)
+    {
+        case zbar::ZBAR_QRCODE:
+            return MV_BARCODE_QR;
+
+        case zbar::ZBAR_UPCA:
+            return MV_BARCODE_UPC_A;
+
+        case zbar::ZBAR_UPCE:
+            return MV_BARCODE_UPC_E;
+
+        case zbar::ZBAR_EAN8:
+            return MV_BARCODE_EAN_8;
+
+        case zbar::ZBAR_EAN13:
+            return MV_BARCODE_EAN_13;
+
+        case zbar::ZBAR_CODE128:
+            return MV_BARCODE_CODE128;
+
+        case zbar::ZBAR_CODE39:
+            return MV_BARCODE_CODE39;
+
+        case zbar::ZBAR_I25:
+            return MV_BARCODE_I2_5;
+
+        default:
+            LOGE("ZBar symbol colorspace is not supported by media vision");
+            return MV_BARCODE_UNDEFINED;
+    }
+}
+
+int Barcode::calculateLocation(mv_quadrangle_s& location) const
+{
+    const int numberOfVertexes = 4;
+
+    const int locationPolygonSize = m_pBarcodeObj->get_location_size();
+
+    //polygon location should contain at least 4 points
+    if (locationPolygonSize < numberOfVertexes)
+    {
+        LOGW("Can't compute location of the barcode by %i points (less then %i).", locationPolygonSize, numberOfVertexes);
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    if (locationPolygonSize == numberOfVertexes)
+    {
+        for (int i = 0; i < numberOfVertexes; ++i)
+        {
+            location.points[i].x = m_pBarcodeObj->get_location_x(i);
+            location.points[i].y = m_pBarcodeObj->get_location_y(i);
+        }
+
+        return MEDIA_VISION_ERROR_NONE;
+    }
+
+    //bounding quadrangle is computing by 4 marginal points
+    mv_point_s first = {m_pBarcodeObj->get_location_x(0), m_pBarcodeObj->get_location_y(0)};
+
+    int minX = first.x;
+    int maxX = first.x;
+    int minY = first.y;
+    int maxY = first.y;
+
+    for (int i = 0; i < locationPolygonSize; ++i)
+    {
+        mv_point_s current = {m_pBarcodeObj->get_location_x(i), m_pBarcodeObj->get_location_y(i)};
+        if (current.x < minX)
+        {
+            minX = current.x;
+        }
+        else if (current.x > maxX)
+        {
+            maxX = current.x;
+        }
+
+        if (current.y < minY)
+        {
+            minY = current.y;
+        }
+        else if (current.y > maxY)
+        {
+            maxY = current.y;
+        }
+    }
+
+    mv_point_s bottomLeft = {minX, maxY};
+    mv_point_s bottomRight = {maxX, maxY};
+    mv_point_s topRight = {maxX, minY};
+    mv_point_s topLeft = {minX, minY};
+
+    location.points[0] = topLeft;
+    location.points[1] = topRight;
+    location.points[2] = bottomRight;
+    location.points[3] = bottomLeft;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* Barcode */
+} /* MediaVision */
diff --git a/mv_barcode/barcode_detector/src/BarcodeUtils.cpp b/mv_barcode/barcode_detector/src/BarcodeUtils.cpp
new file mode 100644 (file)
index 0000000..57219eb
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BarcodeUtils.h"
+#include "mv_common_c.h"
+
+#include <mv_private.h>
+
+#include <zbar.h>
+
+namespace MediaVision
+{
+namespace Barcode
+{
+
+int convertSourceMV2Zbar(mv_source_h mvSource, zbar::Image& zbarSource)
+{
+    int err = MEDIA_VISION_ERROR_NONE;
+    unsigned char *buffer = NULL;
+    unsigned int height = 0;
+    unsigned int width = 0;
+    unsigned int size = 0;
+    mv_colorspace_e colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+
+    err = mv_source_get_colorspace_c(mvSource, &colorspace);
+    if (err != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGW("Can't determine mv_source_h colorspace to convert to ZBar colorspace. Conversion failed");
+        return err;
+    }
+
+    switch(colorspace)
+    {
+        case MEDIA_VISION_COLORSPACE_Y800:
+            zbarSource.set_format("Y800");
+            break;
+        case MEDIA_VISION_COLORSPACE_I420:
+            zbarSource.set_format("I420");
+            break;
+        case MEDIA_VISION_COLORSPACE_NV12:
+            zbarSource.set_format("NV12");
+            break;
+        case MEDIA_VISION_COLORSPACE_YV12:
+            zbarSource.set_format("YV12");
+            break;
+        case MEDIA_VISION_COLORSPACE_NV21:
+            zbarSource.set_format("NV21");
+            break;
+        case MEDIA_VISION_COLORSPACE_YUYV:
+            zbarSource.set_format("YUYV");
+            break;
+        case MEDIA_VISION_COLORSPACE_UYVY:
+            zbarSource.set_format("UYVY");
+            break;
+        case MEDIA_VISION_COLORSPACE_422P:
+            zbarSource.set_format("422P");
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB565:
+            zbarSource.set_format("RGBP");
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB888:
+            zbarSource.set_format("RGB3");
+            break;
+        case MEDIA_VISION_COLORSPACE_RGBA:
+            zbarSource.set_format("RGB4");
+            break;
+        default:
+            LOGE("Media vision colorspace is not supported by ZBar symbol");
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    err = mv_source_get_buffer_c(mvSource, &buffer, &size);
+    if (err != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGW("Can't get mv_source_h buffer to convert to ZBar image. Conversion failed");
+        return err;
+    }
+
+    err = mv_source_get_height_c(mvSource, &height);
+    if (err != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGW("Can't get mv_source_h height for conversion. Conversion failed");
+        return err;
+    }
+
+    err = mv_source_get_width_c(mvSource, &width);
+    if (err != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGW("Can't get mv_source_h width for conversion. Conversion failed");
+        return err;
+    }
+
+    zbarSource.set_size(width, height);
+    zbarSource.set_data(buffer, size);
+
+    return err;
+}
+
+} /* Barcode */
+} /* MediaVision */
diff --git a/mv_barcode/barcode_detector/src/mv_barcode_detect_open.cpp b/mv_barcode/barcode_detector/src/mv_barcode_detect_open.cpp
new file mode 100644 (file)
index 0000000..dd5e557
--- /dev/null
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_barcode_detect_open.h"
+
+#include "Barcode.h"
+#include "BarcodeUtils.h"
+
+#include <mv_private.h>
+
+#include <zbar.h>
+
+using namespace MediaVision::Barcode;
+
+int mv_barcode_detect_open(
+    mv_source_h source,
+    mv_engine_config_h engine_cfg,
+    mv_rectangle_s roi,
+    mv_barcode_detected_cb detect_cb,
+    void *user_data)
+{
+    if (!source || !detect_cb)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    zbar::Image image;
+    int err = convertSourceMV2Zbar(source, image);
+    if (err != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGW("convertSourceMV2Zbar failed");
+        return err;
+    }
+
+    zbar::Image greyImage = image.convert("Y800");
+    greyImage.set_crop(roi.point.x, roi.point.y, roi.width, roi.height);
+    zbar::ImageScanner scanner;
+
+    int target_val;
+    err = mv_engine_config_get_int_attribute(engine_cfg, "MV_BARCODE_DETECT_ATTR_TARGET", &target_val);
+    if (err != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGW("mv_engine_config_get_int_attribute failed");
+        return err;
+    }
+
+    /**
+     * 0 - linear barcodes and QR codes
+     * 1 - only linear barcodes
+     * 2 - only QR codes
+     */
+    switch (target_val)
+    {
+        case 0:
+            scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
+            break;
+        case 1:
+            scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 0);
+            scanner.set_config(zbar::ZBAR_UPCA, zbar::ZBAR_CFG_ENABLE, 1);
+            scanner.set_config(zbar::ZBAR_UPCE, zbar::ZBAR_CFG_ENABLE, 1);
+            scanner.set_config(zbar::ZBAR_EAN8, zbar::ZBAR_CFG_ENABLE, 1);
+            scanner.set_config(zbar::ZBAR_EAN13, zbar::ZBAR_CFG_ENABLE, 1);
+            scanner.set_config(zbar::ZBAR_CODE128, zbar::ZBAR_CFG_ENABLE, 1);
+            scanner.set_config(zbar::ZBAR_CODE39, zbar::ZBAR_CFG_ENABLE, 1);
+            scanner.set_config(zbar::ZBAR_I25, zbar::ZBAR_CFG_ENABLE, 1);
+            break;
+        case 2:
+            scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 0);
+            scanner.set_config(zbar::ZBAR_QRCODE, zbar::ZBAR_CFG_ENABLE, 1);
+            break;
+        default:
+            LOGW("Unavailabe target value %d", target_val);
+    }
+
+    int numberOfBarcodes = scanner.scan(greyImage);
+    LOGI("ZBar scanner has found %i barcodes on the mv_source_h", numberOfBarcodes);
+    mv_quadrangle_s *barcodeLocations = NULL;
+    mv_barcode_type_e *types = NULL;
+
+    if (numberOfBarcodes == 0)
+    {
+        LOGI("Call the detect callback for 0 detected barcodes");
+        detect_cb(source, engine_cfg, barcodeLocations, NULL, types, numberOfBarcodes, user_data);
+        return MEDIA_VISION_ERROR_NONE;
+    }
+    else if (numberOfBarcodes < 0)
+    {
+        LOGW("Incorrect number of barcodes (%i), detection is terminated", numberOfBarcodes);
+        return MEDIA_VISION_ERROR_INTERNAL;
+    }
+
+    const char **messagesArray = new const char*[numberOfBarcodes];
+    barcodeLocations = new mv_quadrangle_s[numberOfBarcodes];
+    types = new mv_barcode_type_e[numberOfBarcodes];
+
+    int i = 0;
+    //extract results and prepare them for callback passing
+    for (zbar::SymbolIterator symbol = greyImage.symbol_begin();
+         symbol != greyImage.symbol_end();
+         ++symbol, ++i)
+    {
+        Barcode curBarcode(*symbol);
+
+        size_t messageLength = curBarcode.getMessage().size();
+        char *curMessage = new char[messageLength + 1];
+        curBarcode.getMessage().copy(curMessage, messageLength);
+        curMessage[messageLength] = '\0';
+        messagesArray[i] = curMessage;
+
+        types[i] = curBarcode.getType();
+
+        int err = curBarcode.calculateLocation(barcodeLocations[i]);
+        if (err != MEDIA_VISION_ERROR_NONE)
+        {
+            LOGW("Can't determine location for barcode, detection is terminated");
+            for (int j = 0; j <= i; ++j)
+            {
+                delete[] messagesArray[j];
+            }
+            delete[] messagesArray;
+            delete[] barcodeLocations;
+            delete[] types;
+            return err;
+        }
+    }
+
+    LOGI("Call the detect callback for %i detected barcodes", numberOfBarcodes);
+    detect_cb(source, engine_cfg, barcodeLocations, messagesArray, types, numberOfBarcodes, user_data);
+
+    LOGI("Clean the memory from barcodes messages, locations and types");
+    for (int j = 0; j < numberOfBarcodes; ++j)
+    {
+        delete[] messagesArray[j];
+    }
+    delete[] messagesArray;
+    delete[] barcodeLocations;
+    delete[] types;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
diff --git a/mv_barcode/barcode_detector_lic/CMakeLists.txt b/mv_barcode/barcode_detector_lic/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c4e6af0
--- /dev/null
@@ -0,0 +1,25 @@
+project(${MV_BARCODE_DETECTOR_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_BARCODE_DET_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_BARCODE_DET_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.c")
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_BARCODE_DET_INC_LIST} ${MV_BARCODE_DET_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_BARCODE_DET_INC_LIST} ${MV_BARCODE_DET_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_barcode/barcode_detector_lic/include/mv_barcode_detect_lic.h b/mv_barcode/barcode_detector_lic/include/mv_barcode_detect_lic.h
new file mode 100644 (file)
index 0000000..b119723
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_DETECT_LIC_H__
+#define __TIZEN_MEDIAVISION_BARCODE_DETECT_LIC_H__
+
+#include "mv_barcode_detect.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_barcode_detect_lic.h
+ * @brief This file contains the Media Vision barcode detect module API for the
+ *        licensed module.
+ */
+
+/**
+ * @brief Detects barcode(s) on source and reads message from it.
+ *
+ * @since_tizen 2.4
+ * @param [in] source        The media source handle
+ * @param [in] engine_cfg    The handle to the configuration of the engine
+ * @param [in] roi           Region of interest - rectangular area on the
+ *                           @a source which will be used for barcode detection
+ * @param [in] detect_cb     The callback for result handling
+ * @param [in] user_data     The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create an engine configuration handle by calling
+ *      @ref mv_create_engine_config() if necessary, otherwise use NULL
+ *
+ * @see mv_barcode_detected_cb()
+ */
+int mv_barcode_detect_lic(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s roi,
+        mv_barcode_detected_cb detect_cb,
+        void *user_data);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_DETECT_LIC_H__ */
diff --git a/mv_barcode/barcode_detector_lic/src/mv_barcode_detect_lic.c b/mv_barcode/barcode_detector_lic/src/mv_barcode_detect_lic.c
new file mode 100644 (file)
index 0000000..5dc9fc0
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_barcode_detect_lic.h"
+
+int mv_barcode_detect_lic(
+    mv_source_h source,
+    mv_engine_config_h engine_cfg,
+    mv_rectangle_s roi,
+    mv_barcode_detected_cb detect_cb,
+    void *user_data)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
diff --git a/mv_barcode/barcode_generator/CMakeLists.txt b/mv_barcode/barcode_generator/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f3b16b9
--- /dev/null
@@ -0,0 +1,32 @@
+project(${MV_BARCODE_GENERATOR_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+if(NOT SKIP_WARNINGS)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_BARCODE_GEN_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_BARCODE_GEN_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp")
+
+find_package(OpenCV REQUIRED)
+include_directories(${OpenCV_INCLUDE_DIRS})
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_BARCODE_GEN_INC_LIST} ${MV_BARCODE_GEN_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_BARCODE_GEN_INC_LIST} ${MV_BARCODE_GEN_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} zint ${MV_COMMON_LIB_NAME} ${OpenCV_LIBS} dlog)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_barcode/barcode_generator/include/BarcodeGenerator.h b/mv_barcode/barcode_generator/include/BarcodeGenerator.h
new file mode 100644 (file)
index 0000000..8640683
--- /dev/null
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BARCODEGENERATOR_H__
+#define __BARCODEGENERATOR_H__
+
+#include "BarcodeOptions.h"
+
+#include <string>
+
+/**
+ * @file BarcodeGenerator.h
+ * @brief This file contains the BarcodeGenerator class.
+ */
+
+namespace MediaVision
+{
+namespace Barcode
+{
+
+/**
+ * @brief This class implements barcode generation.
+ * @details 1D Barcodes and 2D QR codes are supported.
+ *
+ * @since_tizen 2.4
+ */
+class BarcodeGenerator
+{
+public:
+
+    /**
+     * @brief This method generates Barcodes image according to options.
+     *
+     * @since_tizen 2.4
+     * @param [in] imageFileName    Image file name which will be generated
+     * @param [in] imageFormat      Image file format which will be generated
+     * @param [in] imageWidth       Image file width which will be generated
+     * @param [in] imageHeight      Image file height which will be generated
+     * @param [in] message          Input message to be encoded
+     * @param [in] type             Barcode type (1D barcode or 2D QR code)
+     * @param [in] encodingMode     Encoding mode (for QR codes only)
+     * @param [in] correctionLevel  Error correction level (for QR codes only)
+     * @param [in] qrVersion        QR code version (1 ~ 40, 0 for 1D barcodes)
+     * @return BARCODE_ERROR_NONE from BarcodeError which is 0 if success,
+     *         BarcodeError value otherwise
+     */
+    static int generateBarcodeToImage(
+        const std::string& imageFileName,
+        BarcodeImageFormat imageFormat,
+        const int imageWidth,
+        const int imageHeight,
+        const std::string& message,
+        BarcodeType type,
+        BarcodeQREncodingMode encodingMode = BARCODE_QR_MODE_UNAVAILABLE,
+        BarcodeQRErrorCorrectionLevel correctionLevel = BARCODE_QR_ECC_UNAVAILABLE,
+        int qrVersion = 0);
+
+    /**
+     * @brief This method generates Barcodes image buffer according to options.
+     *
+     * @since_tizen 2.4
+     * @param [out] imageBuffer        Image buffer with image to be generated
+     * @param [out] imageWidth         Image buffer width which will be generated
+     * @param [out] imageHeight        Image buffer height which will be generated
+     * @param [out] imageChannels      Image buffer channels number which will be generated
+     * @param [in] message             Input message to be encoded
+     * @param [in] type                Barcode type (1D barcode or 2D QR code)
+     * @param [in] encodingMode        Encoding mode (for QR codes only)
+     * @param [in] correctionLevel     Error correction level (for QR codes only)
+     * @param [in] qrVersion           QR code version (1 ~ 40, 0 for 1D barcodes)
+     * @return BARCODE_ERROR_NONE from BarcodeError which is 0 if success,
+     *         BarcodeError value otherwise
+     */
+    static int generateBarcodeToBuffer(
+        unsigned char **imageBuffer,
+        unsigned int *imageWidth,
+        unsigned int *imageHeight,
+        unsigned int *imageChannels,
+        const std::string& message,
+        BarcodeType type,
+        BarcodeQREncodingMode encodingMode = BARCODE_QR_MODE_UNAVAILABLE,
+        BarcodeQRErrorCorrectionLevel correctionLevel = BARCODE_QR_ECC_UNAVAILABLE,
+        int qrVersion = 0);
+};
+
+} /* Barcode */
+} /* MediaVision */
+
+#endif /* __BARCODEGENERATOR_H__ */
+
diff --git a/mv_barcode/barcode_generator/include/BarcodeOptions.h b/mv_barcode/barcode_generator/include/BarcodeOptions.h
new file mode 100644 (file)
index 0000000..4da3b90
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BARCODEOPTIONS_H__
+#define __BARCODEOPTIONS_H__
+
+/**
+ * @file BarcodeOptions.h
+ * @brief This file contains the Barcode options.
+ */
+
+namespace MediaVision
+{
+namespace Barcode
+{
+
+/**
+ * @brief The Barcode type enumeration.
+ *
+ * @since_tizen 2.4
+ */
+enum BarcodeType
+{
+    BARCODE_QR = 58,
+    BARCODE_UPCA = 34,
+    BARCODE_UPCE = 37,
+    BARCODE_EAN8 = 13,
+    BARCODE_EAN13 = BARCODE_EAN8,
+    BARCODE_CODE39 = 8,
+    BARCODE_CODE128 = 20,
+    BARCODE_INTERLEAVE_2_5 = 3
+};
+
+/**
+ * @brief The Barcode error correction level enumeration.
+ *
+ * @since_tizen 2.4
+ * @remarks This is unavailable for 1D barcodes.
+ */
+enum BarcodeQRErrorCorrectionLevel
+{
+    BARCODE_QR_ECC_UNAVAILABLE = 0,
+    BARCODE_QR_ECC_LOW = 1,
+    BARCODE_QR_ECC_MEDIUM = 2,
+    BARCODE_QR_ECC_QUARTILE = 3,
+    BARCODE_QR_ECC_HIGH = 4
+};
+
+
+/**
+ * @brief The Barcode encoding mode enumeration.
+ *
+ * @since_tizen 2.4
+ * @remarks This is unavailable for 1D barcodes.
+ */
+enum BarcodeQREncodingMode
+{
+    BARCODE_QR_MODE_NUMERIC = 1,
+    BARCODE_QR_MODE_ALPHANUMERIC = 1,
+    BARCODE_QR_MODE_BYTE = 0,
+    BARCODE_QR_MODE_UTF8 = 1,
+    BARCODE_QR_MODE_KANJI = 3,
+    BARCODE_QR_MODE_UNAVAILABLE
+};
+
+/**
+ * @brief The Barcode image format enumeration.
+ *
+ * @since_tizen 2.4
+ */
+enum BarcodeImageFormat
+{
+    BARCODE_IMAGE_JPG,
+    BARCODE_IMAGE_PNG,
+    BARCODE_IMAGE_BMP
+};
+
+/**
+ * @brief The Barcode error enumeration.
+ *
+ * @since_tizen 2.4
+ */
+enum BarcodeError
+{
+    BARCODE_ERROR_NONE = 0,
+    BARCODE_WARNING_INVALID_OPTION = 2,
+    BARCODE_ERROR_TOO_LONG = 5,
+    BARCODE_ERROR_INVALID_DATA = 6,
+    BARCODE_ERROR_INVALID_CHECK = 7,
+    BARCODE_ERROR_INVALID_OPTION = 8,
+    BARCODE_ERROR_ENCODING_PROBLEM = 9,
+    BARCODE_ERROR_FILE_ACCESS = 10,
+    BARCODE_ERROR_MEMORY = 11,
+    BARCODE_ERROR_INVALID_PATH =12,
+};
+
+} /* Barcode */
+} /* MediaVision */
+
+#endif /* __BARCODEOPTIONS_H__ */
+
diff --git a/mv_barcode/barcode_generator/include/mv_barcode_generate_open.h b/mv_barcode/barcode_generator/include/mv_barcode_generate_open.h
new file mode 100644 (file)
index 0000000..d3134ac
--- /dev/null
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_GENERATE_OPEN_H__
+#define __TIZEN_MEDIAVISION_BARCODE_GENERATE_OPEN_H__
+
+#include "mv_barcode_generate.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_barcode_generate_open.h
+ * @brief This file contains the Media Vision barcode generate module API for
+ *        the open module.
+ */
+
+/**
+ * @brief Generates @ref mv_source_h with barcode image.
+ *
+ * @since_tizen 2.4
+ * @param [in]  engine_cfg      The handle to the configuration of the engine
+ * @param [in]  message         The message to be encoded in the barcode
+ * @param [in]  type            Type of the barcode to be generated
+ * @param [in]  qr_enc_mode     Encoding mode for the message (only for QR codes;
+ *                              for 1D barcodes set this parameter to
+ *                              @ref MV_BARCODE_QR_MODE_UNAVAILABLE)
+ * @param [in]  qr_ecc          Error correction level (only for QR codes; for
+ *                              1D barcodes set this parameter to
+ *                              @ref MV_BARCODE_QR_ECC_UNAVAILABLE)
+ * @param [in]  qr_version      QR code version (for 1D barcodes set this
+ *                              parameter to 0)
+ * @param [in, out] image       The media source handle which will be used to
+ *                              fill by the buffer with generated image
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_MSG_TOO_LONG Too long or short message
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Permission denied
+ *
+ * @see mv_barcode_generate_image_open()
+ */
+int mv_barcode_generate_source_open(mv_engine_config_h engine_cfg,
+        const char *message,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        mv_source_h image);
+
+/**
+ * @brief Generates image file with barcode.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg      The handle to the configuration of the engine
+ * @param [in] message         The message to be encoded in the barcode
+ * @param [in] image_width     The width of the generated image
+ * @param [in] image_height    The height of the generated image
+ * @param [in] type            Type of the barcode to be generated
+ * @param [in] qr_enc_mode     Encoding mode for the message (only for QR codes;
+ *                             for 1D barcodes set this parameter to
+ *                             @ref MV_BARCODE_QR_MODE_UNAVAILABLE)
+ * @param [in] qr_ecc          Error correction level (only for QR codes; for
+ *                             1D barcodes set this parameter to
+ *                             @ref MV_BARCODE_QR_ECC_UNAVAILABLE)
+ * @param [in] qr_version      QR code version (for 1D barcodes set this
+ *                             parameter to 0)
+ * @param [in] image_path      The path to the file that has to be generated
+ * @param [in] image_format    The format of the output image
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_MSG_TOO_LONG Too long or short message
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ *
+ * @see mv_barcode_generate_source_open()
+ */
+int mv_barcode_generate_image_open(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        int image_width,
+        int image_height,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        const char *image_path,
+        mv_barcode_image_format_e image_format);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_GENERATE_OPEN_H__ */
diff --git a/mv_barcode/barcode_generator/src/BarcodeGenerator.cpp b/mv_barcode/barcode_generator/src/BarcodeGenerator.cpp
new file mode 100644 (file)
index 0000000..8e1d85d
--- /dev/null
@@ -0,0 +1,280 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BarcodeGenerator.h"
+
+#include <mv_private.h>
+
+#include <zint.h>
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/highgui/highgui.hpp>
+
+#include <cstring>
+#include <vector>
+#include <unistd.h>
+
+namespace MediaVision
+{
+namespace Barcode
+{
+
+namespace
+{
+
+int getFormatEncodingInfo(
+        BarcodeImageFormat imageFormat,
+        std::vector<std::string>& extensions,
+        std::vector<int>& compressionParams)
+{
+    static const int PNGCompressionLevel = 3;
+
+    compressionParams.clear();
+    extensions.clear();
+
+    switch (imageFormat)
+    {
+        case BARCODE_IMAGE_PNG:
+            compressionParams.push_back(CV_IMWRITE_PNG_COMPRESSION);
+            compressionParams.push_back(PNGCompressionLevel);
+            extensions.push_back(".png");
+            break;
+        case BARCODE_IMAGE_JPG:
+            extensions.push_back(".jpg");
+            extensions.push_back(".jpeg");
+            extensions.push_back(".jpe");
+            break;
+        case BARCODE_IMAGE_BMP:
+            extensions.push_back(".bmp");
+            extensions.push_back(".dib");
+            break;
+        default:
+            return BARCODE_ERROR_INVALID_OPTION;
+    }
+    return BARCODE_ERROR_NONE;
+}
+
+int createBarcode(
+        const std::string& message,
+        BarcodeType type,
+        BarcodeQREncodingMode encodingMode,
+        BarcodeQRErrorCorrectionLevel correctionLevel,
+        int qrVersion,
+        zint_symbol *symbol)
+{
+    // set input values
+    symbol->symbology = type;
+    symbol->input_mode = encodingMode;
+    symbol->option_1 = correctionLevel;
+    symbol->option_2 = qrVersion;
+    symbol->scale = 1;
+
+    // set default values
+    std::strcpy(symbol->fgcolour, "000000");
+    std::strcpy(symbol->bgcolour, "ffffff");
+    symbol->border_width = 1;
+    symbol->whitespace_width = 0;
+    symbol->height = 50;
+
+    // create barcode
+    const int rotationAngle = 0;
+    int error = ZBarcode_Encode_and_Buffer(
+                    symbol,
+                    (unsigned char*)(message.c_str()),
+                    message.length(),
+                    rotationAngle);
+
+    return error;
+}
+
+int writeBufferToImageFile(
+        zint_symbol *symbol,
+        const std::string& imageFileName,
+        BarcodeImageFormat imageFormat,
+        const int imageWidth,
+        const int imageHeight)
+{
+    if (imageWidth <= 0 || imageHeight <= 0)
+    {
+        LOGE("Barcode image size is invalid: %i x %i. Terminate write to "
+                "the image operation", imageWidth, imageHeight);
+        return BARCODE_ERROR_INVALID_DATA;
+    }
+
+     /* find directory */
+    std::string prefix_imageFileName = imageFileName.substr(0, imageFileName.find_last_of('/'));
+    LOGD("prefix_path: %s", prefix_imageFileName.c_str());
+
+    /* check the directory is available */
+    if (access(prefix_imageFileName.c_str(),F_OK))
+    {
+        LOGE("Can't save barcode image to the path. The path[%s] doesn't existed.", prefix_imageFileName.c_str());
+        return BARCODE_ERROR_INVALID_PATH;
+    }
+
+    // check current extension
+    std::vector<std::string> expectedExtensions;
+    std::vector<int> compressionParams;
+
+    int error = getFormatEncodingInfo(imageFormat,
+            expectedExtensions, compressionParams);
+
+    if (BARCODE_ERROR_NONE != error || expectedExtensions.empty())
+    {
+        LOGE("Image format is incorrectly specified or not supported");
+        return error;
+    }
+
+    bool rightExtensionFlag = false;
+
+    std::string resultFilePath(imageFileName);
+
+    for (size_t extNum = 0; extNum < expectedExtensions.size(); ++extNum)
+    {
+        if (resultFilePath.size() >= expectedExtensions[extNum].size())
+        {
+            std::string givenExtension = resultFilePath.substr(
+                    resultFilePath.length() - expectedExtensions[extNum].size(),
+                    expectedExtensions[extNum].size());
+
+            std::transform(
+                    givenExtension.begin(), givenExtension.end(),
+                    givenExtension.begin(), ::tolower);
+
+            if (givenExtension == expectedExtensions[extNum])
+            {
+                rightExtensionFlag = true;
+                break;
+            }
+        }
+    }
+
+    if (!rightExtensionFlag)
+    {
+        resultFilePath += expectedExtensions[0];
+    }
+
+    cv::Mat image(symbol->bitmap_height, symbol->bitmap_width, CV_8UC3, symbol->bitmap);
+    cv::resize(image, image, cv::Size(imageWidth, imageHeight), 0, 0, cv::INTER_AREA);
+
+    error = cv::imwrite(resultFilePath, image, compressionParams) ?
+           BARCODE_ERROR_NONE : BARCODE_ERROR_INVALID_DATA;
+
+    if (BARCODE_ERROR_NONE != error)
+    {
+        LOGE("Write barcode image to file %s operation failed.",
+                resultFilePath.c_str());
+        return error;
+    }
+
+    return error;
+}
+
+} /* anonymous namespace */
+
+int BarcodeGenerator::generateBarcodeToImage(
+        const std::string& imageFileName,
+        BarcodeImageFormat imageFormat,
+        const int imageWidth,
+        const int imageHeight,
+        const std::string& message,
+        BarcodeType type,
+        BarcodeQREncodingMode encodingMode,
+        BarcodeQRErrorCorrectionLevel correctionLevel,
+        int qrVersion)
+{
+    zint_symbol *symbol = ZBarcode_Create();
+
+    int error = createBarcode(
+                    message,
+                    type,
+                    encodingMode,
+                    correctionLevel,
+                    qrVersion,
+                    symbol);
+
+    if (error != BARCODE_ERROR_NONE)
+    {
+        LOGE("Barcode creation failed, clean memory");
+        ZBarcode_Delete(symbol);
+        return error;
+    }
+
+    error = writeBufferToImageFile(
+                symbol,
+                imageFileName,
+                imageFormat,
+                imageWidth,
+                imageHeight);
+    if (error != BARCODE_ERROR_NONE)
+    {
+        LOGE("Barcode [%s] file write fail, clean memory", imageFileName.c_str());
+    }
+    else
+    {
+        LOGI("Barcode image [%s] is successfully generated, clean memory", imageFileName.c_str());
+    }
+
+    ZBarcode_Delete(symbol);
+
+    return error;
+}
+
+int BarcodeGenerator::generateBarcodeToBuffer(
+        unsigned char **imageBuffer,
+        unsigned int *imageWidth,
+        unsigned int *imageHeight,
+        unsigned int *imageChannels,
+        const std::string& message,
+        BarcodeType type,
+        BarcodeQREncodingMode encodingMode,
+        BarcodeQRErrorCorrectionLevel correctionLevel,
+        int qrVersion)
+{
+    zint_symbol *symbol = ZBarcode_Create();
+
+    int error = createBarcode(
+                    message,
+                    type,
+                    encodingMode,
+                    correctionLevel,
+                    qrVersion,
+                    symbol);
+
+    if (error != BARCODE_ERROR_NONE)
+    {
+        LOGE("Barcode creation failed, clean memory");
+        ZBarcode_Delete(symbol);
+        return error;
+    }
+
+    // fill output buffer
+    *imageWidth = symbol->bitmap_width;
+    *imageHeight = symbol->bitmap_height;
+    *imageChannels = 3;
+    const unsigned int imageBufferSize = (*imageWidth) * (*imageHeight) * (*imageChannels);
+    *imageBuffer = new unsigned char [imageBufferSize];
+    memmove(*imageBuffer, symbol->bitmap, imageBufferSize);
+
+    LOGI("Barcode buffer has been successfully generated, clean memory");
+    ZBarcode_Delete(symbol);
+
+    return BARCODE_ERROR_NONE;
+}
+
+} /* Barcode */
+} /* MediaVision */
diff --git a/mv_barcode/barcode_generator/src/mv_barcode_generate_open.cpp b/mv_barcode/barcode_generator/src/mv_barcode_generate_open.cpp
new file mode 100644 (file)
index 0000000..1aa3034
--- /dev/null
@@ -0,0 +1,348 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_barcode_generate_open.h"
+
+#include "mv_common_c.h"
+#include "BarcodeGenerator.h"
+
+#include <mv_private.h>
+
+#include <algorithm>
+#include <cstring>
+
+using namespace MediaVision::Barcode;
+
+namespace
+{
+
+int alphanumToUpper(std::string& strToTransform)
+{
+    std::string tempString = strToTransform;
+    std::transform(tempString.begin(), tempString.end(),
+                   tempString.begin(), ::toupper);
+
+    if (std::string::npos != tempString.find_first_not_of("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"))
+    {
+        LOGE("Barcode message can't be converted according to support "
+             "alphanumeric (0..9, A..Z, space, $, %, *, +, -, ., /, :) "
+             "mode: %s", strToTransform.c_str());
+        return BARCODE_ERROR_INVALID_DATA;
+    }
+
+    LOGI("Barcode message was converted according to support alphanumeric "
+         "mode: %s -> %s", strToTransform.c_str(), tempString.c_str());
+    strToTransform = tempString;
+    return BARCODE_ERROR_NONE;
+}
+
+BarcodeType convertBarcodeType(mv_barcode_type_e type)
+{
+    BarcodeType barcodeType = BARCODE_QR;
+    switch (type)
+    {
+        case MV_BARCODE_UPC_A:
+            barcodeType = BARCODE_UPCA;
+            break;
+        case MV_BARCODE_UPC_E:
+            barcodeType = BARCODE_UPCE;
+            break;
+        case MV_BARCODE_EAN_8:
+            barcodeType = BARCODE_EAN8;
+            break;
+        case MV_BARCODE_EAN_13:
+            barcodeType = BARCODE_EAN13;
+            break;
+        case MV_BARCODE_CODE128:
+            barcodeType = BARCODE_CODE128;
+            break;
+        case MV_BARCODE_CODE39:
+            barcodeType = BARCODE_CODE39;
+            break;
+        case MV_BARCODE_I2_5:
+            barcodeType = BARCODE_INTERLEAVE_2_5;
+            break;
+        default:
+            break;
+    }
+
+    LOGI("Media vision barcode type has been converted to ZInt barcode type "
+            "(%i -> %i)", type, barcodeType);
+    return barcodeType;
+}
+
+BarcodeQREncodingMode convertEncodingMode(mv_barcode_qr_mode_e mode)
+{
+    BarcodeQREncodingMode encodingMode = BARCODE_QR_MODE_ALPHANUMERIC;
+
+    switch (mode)
+    {
+        case MV_BARCODE_QR_MODE_NUMERIC:
+            encodingMode = BARCODE_QR_MODE_NUMERIC;
+            break;
+        case MV_BARCODE_QR_MODE_BYTE:
+            encodingMode = BARCODE_QR_MODE_BYTE;
+            break;
+        case MV_BARCODE_QR_MODE_UTF8:
+            encodingMode = BARCODE_QR_MODE_UTF8;
+            break;
+        default:
+            break;
+    }
+
+    LOGI("Media vision QRCode encoding mode has been converted to "
+            "ZInt encoding mode (%i -> %i)", mode, encodingMode);
+    return encodingMode;
+}
+
+BarcodeQRErrorCorrectionLevel convertECC(mv_barcode_qr_ecc_e ecc)
+{
+    BarcodeQRErrorCorrectionLevel ecclevel = BARCODE_QR_ECC_LOW;
+
+    switch (ecc)
+    {
+        case MV_BARCODE_QR_ECC_MEDIUM:
+            ecclevel = BARCODE_QR_ECC_MEDIUM;
+            break;
+        case MV_BARCODE_QR_ECC_QUARTILE:
+            ecclevel = BARCODE_QR_ECC_QUARTILE;
+            break;
+        case MV_BARCODE_QR_ECC_HIGH:
+            ecclevel = BARCODE_QR_ECC_HIGH;
+            break;
+        default:
+            break;
+    }
+
+    LOGI("Media vision ECC level has been converted to "
+            "ZInt ECC level (%i -> %i)", ecc, ecclevel);
+    return ecclevel;
+}
+
+int convertBarcodeError(int barcodeError)
+{
+    int mvError = MEDIA_VISION_ERROR_NONE;
+
+    switch (barcodeError)
+    {
+        case BARCODE_WARNING_INVALID_OPTION:
+            mvError = MEDIA_VISION_ERROR_INVALID_PARAMETER;
+            break;
+        case BARCODE_ERROR_TOO_LONG:
+            mvError = MEDIA_VISION_ERROR_MSG_TOO_LONG;
+            break;
+        case BARCODE_ERROR_INVALID_DATA:
+            mvError = MEDIA_VISION_ERROR_INVALID_DATA;
+            break;
+        case BARCODE_ERROR_INVALID_CHECK:
+            mvError = MEDIA_VISION_ERROR_INVALID_PARAMETER;
+            break;
+        case BARCODE_ERROR_INVALID_OPTION:
+            mvError = MEDIA_VISION_ERROR_INVALID_PARAMETER;
+            break;
+        case BARCODE_ERROR_ENCODING_PROBLEM:
+            mvError = MEDIA_VISION_ERROR_INTERNAL;
+            break;
+        case BARCODE_ERROR_FILE_ACCESS:
+            mvError = MEDIA_VISION_ERROR_PERMISSION_DENIED;
+            break;
+        case BARCODE_ERROR_MEMORY:
+            mvError = MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+            break;
+        case BARCODE_ERROR_INVALID_PATH:
+            mvError = MEDIA_VISION_ERROR_INVALID_PATH;
+        default:
+            break;
+    }
+
+    LOGI("ZInt error code has been converted to the media vision error code "
+            "(%i -> (0x%08x))", barcodeError, mvError);
+    return mvError;
+}
+
+BarcodeImageFormat convertImageFormat(mv_barcode_image_format_e format)
+{
+    BarcodeImageFormat imageFormat = BARCODE_IMAGE_PNG;
+
+    switch (format)
+    {
+        case MV_BARCODE_IMAGE_FORMAT_JPG:
+            imageFormat = BARCODE_IMAGE_JPG;
+            break;
+        case MV_BARCODE_IMAGE_FORMAT_BMP:
+            imageFormat = BARCODE_IMAGE_BMP;
+            break;
+        default:
+            break;
+    }
+
+    LOGI("Media vision image format has been converted to "
+            "internal image format (%i -> %i)", format, imageFormat);
+    return imageFormat;
+}
+
+} /* anonymous namespace */
+
+int mv_barcode_generate_source_open(
+        mv_engine_config_h /*engine_cfg*/,
+        const char *message,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        mv_source_h image)
+{
+    std::string messageStr = std::string(message);
+
+    if (qr_enc_mode == MV_BARCODE_QR_MODE_NUMERIC &&
+        messageStr.find_first_not_of("0123456789") != std::string::npos)
+    {
+        LOGE("Barcode message can't be used according to support "
+             "numeric (0..9) mode: %s", messageStr.c_str());
+        return MEDIA_VISION_ERROR_INVALID_DATA;
+    }
+
+    int error = BARCODE_ERROR_NONE;
+    if (MV_BARCODE_QR == type &&
+        MV_BARCODE_QR_MODE_ALPHANUMERIC == qr_enc_mode)
+    {
+        error = alphanumToUpper(messageStr);
+        if (BARCODE_ERROR_NONE != error)
+        {
+            return convertBarcodeError(error);
+        }
+    }
+
+    unsigned char *imageBuffer = NULL;
+    unsigned int imageWidth = 0u;
+    unsigned int imageHeight = 0u;
+    unsigned int imageChannels = 0u;
+
+    error = BarcodeGenerator::generateBarcodeToBuffer(
+                    &imageBuffer,
+                    &imageWidth,
+                    &imageHeight,
+                    &imageChannels,
+                    messageStr,
+                    convertBarcodeType(type),
+                    convertEncodingMode(qr_enc_mode),
+                    convertECC(qr_ecc),
+                    qr_version);
+
+    if (error != BARCODE_ERROR_NONE)
+    {
+        LOGE("Barcode generation to the buffer failed");
+        if (NULL != imageBuffer)
+        {
+            LOGI("Delete temporal buffer");
+            delete[] imageBuffer;
+        }
+        return convertBarcodeError(error);
+    }
+
+    const unsigned int imageBufferSize = imageWidth * imageHeight * imageChannels;
+
+    LOGI("Barcode has been generated to the buffer: "
+            "Buffer size = %ui x %ui; Channels = %ui; Message = %s",
+            imageWidth, imageHeight, imageChannels, messageStr.c_str());
+
+    error = mv_source_fill_by_buffer_c(
+                image,
+                imageBuffer,
+                imageBufferSize,
+                imageWidth,
+                imageHeight,
+                MEDIA_VISION_COLORSPACE_RGB888);
+
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Meidiavision source fill by generated buffer failed");
+    }
+
+    if (NULL != imageBuffer)
+    {
+        LOGI("Delete temporal buffer");
+        delete[] imageBuffer;
+    }
+
+    return error;
+}
+
+
+int mv_barcode_generate_image_open(
+        mv_engine_config_h /*engine_cfg*/,
+        const char *message,
+        int image_width,
+        int image_height,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        const char *image_path,
+        mv_barcode_image_format_e image_format)
+{
+    std::string messageStr = std::string(message);
+
+    if (qr_enc_mode == MV_BARCODE_QR_MODE_NUMERIC &&
+        messageStr.find_first_not_of("0123456789") != std::string::npos)
+    {
+        LOGE("Barcode message can't be used according to support "
+             "numeric (0..9) mode: %s", messageStr.c_str());
+        return MEDIA_VISION_ERROR_INVALID_DATA;
+    }
+
+    if (NULL == image_path)
+    {
+        LOGE("Can't save barcode image to the path[%p]. The path has to be specified", image_path);
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    int error = BARCODE_ERROR_NONE;
+    if (MV_BARCODE_QR == type &&
+        MV_BARCODE_QR_MODE_ALPHANUMERIC == qr_enc_mode)
+    {
+        error = alphanumToUpper(messageStr);
+        if (BARCODE_ERROR_NONE != error)
+        {
+            return convertBarcodeError(error);
+        }
+    }
+
+    error = BarcodeGenerator::generateBarcodeToImage(
+                          std::string(image_path),
+                          convertImageFormat(image_format),
+                          image_width,
+                          image_height,
+                          messageStr,
+                          convertBarcodeType(type),
+                          convertEncodingMode(qr_enc_mode),
+                          convertECC(qr_ecc),
+                          qr_version);
+
+    if (error != BARCODE_ERROR_NONE)
+    {
+        LOGE("Barcode generation to the image file failed");
+    }
+    else
+    {
+        LOGI("Barcode has been generated to the image: "
+                "Image size = %ui x %ui; Message = %s",
+                image_width, image_height, messageStr.c_str());
+    }
+
+    return convertBarcodeError(error);
+}
+
diff --git a/mv_barcode/barcode_generator_lic/CMakeLists.txt b/mv_barcode/barcode_generator_lic/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f037975
--- /dev/null
@@ -0,0 +1,25 @@
+project(${MV_BARCODE_GENERATOR_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_BARCODE_GEN_INCLUDE_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_BARCODE_GEN_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.c")
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_BARCODE_GEN_INCLUDE_LIST} ${MV_BARCODE_GEN_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_BARCODE_GEN_INCLUDE_LIST} ${MV_BARCODE_GEN_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_barcode/barcode_generator_lic/include/mv_barcode_generate_lic.h b/mv_barcode/barcode_generator_lic/include/mv_barcode_generate_lic.h
new file mode 100644 (file)
index 0000000..2076b0c
--- /dev/null
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_BARCODE_GENERATE_LIC_H__
+#define __TIZEN_MEDIAVISION_BARCODE_GENERATE_LIC_H__
+
+#include "mv_barcode_generate.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_barcode_generate_lic.h
+ * @brief This file contains the Media Vision barcode generate module API for
+ *        the licensed module.
+ */
+
+/**
+ * @brief Generates @ref mv_source_h with barcode image.
+ *
+ * @since_tizen 2.4
+ * @param [in]  engine_cfg      The handle to the configuration of the engine
+ * @param [in]  message         The message to be encoded in the barcode
+ * @param [in]  image_width     The width of the generated image
+ * @param [in]  image_height    The height of the generated image
+ * @param [in]  type            Type of the barcode to be generated
+ * @param [in]  qr_enc_mode     Encoding mode for the message (only for QR codes;
+ *                              for 1D barcodes set this parameter to
+ *                              @ref MV_BARCODE_QR_MODE_UNAVAILABLE)
+ * @param [in]  qr_ecc          Error correction level (only for QR codes; for
+ *                              1D barcodes set this parameter to
+ *                              @ref MV_BARCODE_QR_ECC_UNAVAILABLE)
+ * @param [in]  qr_version      QR code version (for 1D barcodes set this
+ *                              parameter to 0)
+ * @param [in] image            The media source handle which will be used to
+ *                              fill by the buffer with generated image
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_barcode_generate_image_lic()
+ */
+int mv_barcode_generate_source_lic(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        mv_source_h image);
+
+/**
+ * @brief Generates image file with barcode.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg      The handle to the configuration of the engine
+ * @param [in] message         The message to be encoded in the barcode
+ * @param [in] image_width     The width of the generated image
+ * @param [in] image_height    The height of the generated image
+ * @param [in] type            Type of the barcode to be generated
+ * @param [in] qr_enc_mode     Encoding mode for the message (only for QR codes;
+ *                             for 1D barcodes set this parameter to
+ *                             @ref MV_BARCODE_QR_MODE_UNAVAILABLE)
+ * @param [in] qr_ecc          Error correction level (only for QR codes; for
+ *                             1D barcodes set this parameter to
+ *                             @ref MV_BARCODE_QR_ECC_UNAVAILABLE)
+ * @param [in] qr_version      QR code version (for 1D barcodes set this
+ *                             parameter to 0)
+ * @param [in] image_path      The path to the file that has to be generated
+ * @param [in] image_format    The format of the output image
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_barcode_generate_source_lic()
+ */
+int mv_barcode_generate_image_lic(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        int image_width,
+        int image_height,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        const char *image_path,
+        mv_barcode_image_format_e image_format);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_BARCODE_GENERATE_LIC_H__ */
diff --git a/mv_barcode/barcode_generator_lic/src/mv_barcode_generate_lic.c b/mv_barcode/barcode_generator_lic/src/mv_barcode_generate_lic.c
new file mode 100644 (file)
index 0000000..d57621f
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_barcode_generate_lic.h"
+
+int mv_barcode_generate_source_lic(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        mv_source_h image)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;;
+}
+
+int mv_barcode_generate_image_lic(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        int image_width,
+        int image_height,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        const char *image_path,
+        mv_barcode_image_format_e image_format)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
diff --git a/mv_common/CMakeLists.txt b/mv_common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..64fa19a
--- /dev/null
@@ -0,0 +1,36 @@
+project(${MV_COMMON_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+if(NOT SKIP_WARNINGS)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${PROJECT_SOURCE_DIR}/include")
+
+file(GLOB MV_COMMON_INCLUDE_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_COMMON_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp")
+
+find_package(OpenCV REQUIRED core highgui imgproc)
+
+if(NOT OpenCV_FOUND)
+    message(SEND_ERROR "Failed to find OpenCV")
+    return()
+else()
+    include_directories(${OpenCV_INCLUDE_DIRS})
+endif()
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_COMMON_INCLUDE_LIST} ${MV_COMMON_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_COMMON_INCLUDE_LIST} ${MV_COMMON_SRC_LIST})
+endif()
+
+TARGET_LINK_LIBRARIES(${MV_COMMON_LIB_NAME} jpeg ${OpenCV_LIBS} capi-media-tool tbm json-c)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_common/include/EngineConfig.h b/mv_common/include/EngineConfig.h
new file mode 100644 (file)
index 0000000..ac580c9
--- /dev/null
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ENGINECONFIG_H__
+#define __ENGINECONFIG_H__
+
+#include <string>
+#include <map>
+
+#include "mv_common.h"
+
+/**
+ * @file   EngineConfig.h
+ * @brief  Engine Configuration class definition.
+ */
+
+namespace MediaVision
+{
+namespace Common
+{
+
+typedef std::map<std::string, double>::const_iterator DictDblConstIter;
+typedef std::map<std::string, int>::const_iterator DictIntConstIter;
+typedef std::map<std::string, bool>::const_iterator DictBoolConstIter;
+typedef std::map<std::string, std::string>::const_iterator DictStrConstIter;
+
+class EngineConfig
+{
+public:
+    /**
+     * @brief Engine configuration constructor.
+     * @details Create new engine configuration dictionary and set default
+     *          attributes values.
+     *
+     * @since_tizen 2.4
+     */
+    EngineConfig();
+
+    /**
+     * @brief Engine configuration destructor.
+     */
+    virtual ~EngineConfig();
+
+    /**
+     * @brief Sets attribute with double value.
+     *
+     * @since_tizen 2.4
+     * @param [in] key          The string name of the attribute
+     * @param [in] value        The double attribute value to be set
+     * @return @c MEDIA_VISION_ERROR_NONE on success,\n
+     *         otherwise a negative error value
+     */
+    int setAttribute(const std::string& key, const double value);
+
+    /**
+     * @brief Sets attribute with integer value.
+     *
+     * @since_tizen 2.4
+     * @param [in] key          The string name of the attribute
+     * @param [in] value        The integer attribute value to be set
+     * @return @c MEDIA_VISION_ERROR_NONE on success,\n
+     *         otherwise a negative error value
+     */
+    int setAttribute(const std::string& key, const int value);
+
+    /**
+     * @brief Sets attribute with boolean value.
+     *
+     * @since_tizen 2.4
+     * @param [in] key          The string name of the attribute
+     * @param [in] value        The boolean attribute value to be set
+     * @return @c MEDIA_VISION_ERROR_NONE on success,\n
+     *         otherwise a negative error value
+     */
+    int setAttribute(const std::string& key, const bool value);
+
+    /**
+     * @brief Sets attribute with string value.
+     *
+     * @since_tizen 2.4
+     * @param [in] key          The string name of the attribute
+     * @param [in] value        The string attribute value to be set
+     * @return @c MEDIA_VISION_ERROR_NONE on success,\n
+     *         otherwise a negative error value
+     */
+    int setAttribute(const std::string& key, const std::string& value);
+
+    /**
+     * @brief Gets double attribute value by attribute name.
+     *
+     * @since_tizen 2.4
+     * @param [in]  key          The string name of the attribute
+     * @param [out] value   r    The double attribute value to be obtained
+     * @return @c MEDIA_VISION_ERROR_NONE on success,\n
+     *         otherwise a negative error value
+     * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE If attribute with name @a key
+     *         doesn't exist in the engine configuration dictionary
+     */
+    int getDoubleAttribute(const std::string& key, double *value) const;
+
+    /**
+     * @brief Gets integer attribute value by attribute name.
+     *
+     * @since_tizen 2.4
+     * @param [in]  key          The string name of the attribute
+     * @param [out] value        The integer attribute value to be obtained
+     * @return @c MEDIA_VISION_ERROR_NONE on success,\n
+     *         otherwise a negative error value
+     * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE If attribute with name @a key
+     *         doesn't exist in the engine configuration dictionary
+     */
+    int getIntegerAttribute(const std::string& key, int *value) const;
+
+    /**
+     * @brief Gets boolean attribute value by attribute name.
+     *
+     * @since_tizen 2.4
+     * @param [in]  key          The string name of the attribute
+     * @param [out] value        The boolean attribute value to be obtained
+     * @return @c MEDIA_VISION_ERROR_NONE on success,\n
+     *         otherwise a negative error value
+     * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE If attribute with name @a key
+     *         doesn't exist in the engine configuration dictionary
+     */
+    int getBooleanAttribute(const std::string& key, bool *value) const;
+
+    /**
+     * @brief Gets string attribute value by attribute name.
+     *
+     * @since_tizen 2.4
+     * @param [in]  key          The string name of the attribute
+     * @param [out] value        The string attribute value to be obtained
+     * @return @c MEDIA_VISION_ERROR_NONE on success,\n
+     *         otherwise a negative error value
+     * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE If attribute with name @a key
+     *         doesn't exist in the engine configuration dictionary
+     */
+    int getStringAttribute(const std::string& key, std::string *value) const;
+
+public:
+    static bool setDefaultConfigFilePath(const std::string& confFilePath);
+
+    static const std::map<std::string, double>& getDefaultDblDict();
+    static const std::map<std::string, int>& getDefaultIntDict();
+    static const std::map<std::string, bool>& getDefaultBoolDict();
+    static const std::map<std::string, std::string>& getDefaultStrDict();
+    static int cacheDictionaries(
+            bool isLazyCache = true,
+            std::string configFilePath = DefConfigFilePath);
+
+private:
+    std::map<std::string, double> m_dblDict;
+    std::map<std::string, int> m_intDict;
+    std::map<std::string, bool> m_boolDict;
+    std::map<std::string, std::string> m_strDict;
+
+private:
+    static std::string DefConfigFilePath;
+
+    static std::map<std::string, double> DefDblDict;
+    static std::map<std::string, int> DefIntDict;
+    static std::map<std::string, bool> DefBoolDict;
+    static std::map<std::string, std::string> DefStrDict;
+
+};
+
+} /* Common */
+} /* MediaVision */
+
+#endif /* __ENGINECONFIG_H__ */
diff --git a/mv_common/include/MediaSource.h b/mv_common/include/MediaSource.h
new file mode 100644 (file)
index 0000000..454f69f
--- /dev/null
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEDIASOURCE_H__
+#define __MEDIASOURCE_H__
+
+// Need for a colorspace
+#include <mv_common.h>
+
+/**
+ * @file MediaSource.h
+ * @brief This file contains the MediaSource class.
+ */
+
+namespace MediaVision
+{
+namespace Common
+{
+
+/**
+ * @class   MediaSource
+ * @brief   The Media Source container
+ * @details It is class which contains Media Source information. This class
+ *          will be use in the Media Vision as simple image.
+ */
+class MediaSource
+{
+public:
+
+    /**
+     * @brief   Creates a MediaSource.
+     * @details Default parameters values of the MediaSource will be: zero for
+     *          width, height and buffer size; NULL for buffer;
+     *          MEDIA_VISION_COLORSPACE_INVALID for colorspace.
+     *
+     * @since_tizen 2.4
+     *
+     * @see MediaSource::~MediaSource()
+     */
+    MediaSource();
+
+    /**
+     * @brief   Destroys the MediaSource and releases all its resources.
+     *
+     * @since_tizen 2.4
+     *
+     * @see MediaSource::MediaSource()
+     */
+    virtual ~MediaSource();
+
+    /**
+     * @brief   Clears the MediaSource.
+     * @details Releases all internal resources and set parameters to default values.
+     *
+     * @since_tizen 2.4
+     *
+     * @see MediaSource::MediaSource()
+     * @see MediaSource::fill()
+     */
+    void clear(void);
+
+    /**
+     * @brief Fills the MediaSource based on the buffer and metadata.
+     *
+     * @since_tizen 2.4
+     * @param [in] buffer       The buffer of image data
+     * @param [in] bufferSize   The buffer size
+     * @param [in] width        The image width
+     * @param [in] height       The image height
+     * @param [in] colorspace   The image colorspace
+     * @return true if filled process is ok. Otherwise return false.
+     *
+     * @see MediaSource::MediaSource()
+     * @see MediaSource::clear()
+     */
+    bool fill(const unsigned char *buffer, unsigned int bufferSize, unsigned int
+            width, unsigned int height, mv_colorspace_e colorspace);
+
+    /**
+     * @brief Gets data buffer of the MediaSource.
+     *
+     * @since_tizen 2.4
+     * @return Pointer to the data buffer.
+     */
+    unsigned char *getBuffer(void) const;
+
+    /**
+     * @brief Gets buffer size of the MediaSource.
+     *
+     * @since_tizen 2.4
+     * @return Size of data buffer.
+     */
+    unsigned int getBufferSize(void) const;
+
+    /**
+     * @brief Gets image width of the MediaSource.
+     *
+     * @since_tizen 2.4
+     * @return Width of image.
+     */
+    unsigned int getWidth(void) const;
+
+    /**
+     * @brief Gets image height of the MediaSource.
+     *
+     * @since_tizen 2.4
+     * @return Height of image.
+     */
+    unsigned int getHeight(void) const;
+
+    /**
+     * @brief Gets image colorspace of the MediaSource.
+     *
+     * @since_tizen 2.4
+     * @return Colorspace of image.
+     */
+    mv_colorspace_e getColorspace(void) const;
+
+private:
+
+    unsigned char *m_pBuffer;        /**< The data buffer */
+
+    unsigned int m_bufferSize;       /**< The buffer size */
+
+    unsigned int m_width;            /**< The image width */
+
+    unsigned int m_height;           /**< The image height */
+
+    mv_colorspace_e m_colorspace;    /**< The image colorspace */
+};
+
+} /* Common */
+} /* MediaVision */
+
+#endif /* __MEDIASOURCE_H__ */
diff --git a/mv_common/include/mv_common_c.h b/mv_common/include/mv_common_c.h
new file mode 100644 (file)
index 0000000..a7fa1bb
--- /dev/null
@@ -0,0 +1,492 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_COMMON_C_H__
+#define __TIZEN_MEDIAVISION_COMMON_C_H__
+
+#include "mv_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_common_c.h
+ * @brief This file contains the Media Vision Common module API.
+ */
+
+/**
+ * @brief Creates a source handle.
+ *
+ * @since_tizen 2.4
+ * @remarks You must release @a source by using @ref mv_destroy_source_c().
+ * @param [out] source    A new handle to the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see mv_destroy_source_c()
+ */
+int mv_create_source_c(
+        mv_source_h *source);
+
+/**
+ * @brief Destroys the source handle and releases all its resources.
+ *
+ * @since_tizen 2.4
+ * @param [in] source    The handle to the source to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_create_source_c()
+ */
+int mv_destroy_source_c(
+        mv_source_h source);
+
+/**
+ * @brief Fills the media source based on the media packet.
+ *
+ * @since_tizen 2.4
+ * @param [in,out] source          The handle to the source
+ * @param [in]     media_packet    The handle to the media packet from which
+ *                                 will be filled the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported media format
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Create a source handle by calling @ref mv_create_source_c()
+ *
+ * @see mv_create_source_c()
+ * @see mv_destroy_source_c()
+ */
+int mv_source_fill_by_media_packet_c(
+        mv_source_h source,
+        media_packet_h media_packet);
+
+/**
+ * @brief Fills the media source based on the buffer and metadata.
+ *
+ * @since_tizen 2.4
+ * @param [in,out] source             The handle to the source
+ * @param [in]     data_buffer        The buffer of image data
+ * @param [in]     buffer_size        The buffer size
+ * @param [in]     image_width        The image width
+ * @param [in]     image_height       The image height
+ * @param [in]     image_colorspace   The image colorspace
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Create a source handle by calling @ref mv_create_source_c()
+ *
+ * @see mv_source_clear_c()
+ */
+int mv_source_fill_by_buffer_c(
+        mv_source_h source,
+        unsigned char *data_buffer,
+        unsigned int buffer_size,
+        unsigned int image_width,
+        unsigned int image_height,
+        mv_colorspace_e image_colorspace);
+
+/**
+ * @brief Clears the buffer of the media source.
+ *
+ * @since_tizen 2.4
+ * @param [in] source    The handle to the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_source_fill_by_buffer_c()
+ */
+int mv_source_clear_c(
+        mv_source_h source);
+
+/**
+ * @brief Gets buffer of the media source.
+ *
+ * @since_tizen 2.4
+ * @remarks Note that the retrieved buffer will be destroyed when
+ *          @ref mv_destroy_source_c() or @ref mv_source_clear_c() function
+ *          is called for the @a source.
+ *
+ * @param [in]    source        The handle to the source
+ * @param [out]   data_buffer   The buffer of the source
+ * @param [out]   buffer_size   The size of buffer
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_source_get_width_c()
+ * @see mv_source_get_height_c()
+ * @see mv_source_get_colorspace_c()
+ */
+int mv_source_get_buffer_c(
+        mv_source_h source,
+        unsigned char **data_buffer,
+        unsigned int *buffer_size);
+
+/**
+ * @brief Gets height of the media source.
+ *
+ * @since_tizen 2.4
+ * @param [in]    source         The handle to the source
+ * @param [out]   image_height   The height of the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_source_get_width_c()
+ * @see mv_source_get_colorspace_c()
+ * @see mv_source_get_buffer_c()
+ */
+int mv_source_get_height_c(
+        mv_source_h source,
+        unsigned int *image_height);
+
+/**
+ * @brief Gets width of the media source.
+ *
+ * @since_tizen 2.4
+ * @param [in]    source        The handle to the source
+ * @param [out]   image_width   The width of the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_source_get_height_c()
+ * @see mv_source_get_colorspace_c()
+ * @see mv_source_get_buffer_c()
+ */
+int mv_source_get_width_c(
+        mv_source_h source,
+        unsigned int *image_width);
+
+/**
+ * @brief Gets colorspace of the media source.
+ *
+ * @since_tizen 2.4
+ * @param [in]    source             The handle to the source
+ * @param [out]   image_colorspace   The colorspace of the source
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_source_get_width_c()
+ * @see mv_source_get_height_c()
+ * @see mv_source_get_buffer_c()
+ */
+int mv_source_get_colorspace_c(
+        mv_source_h source,
+        mv_colorspace_e *image_colorspace);
+
+/**
+ * @brief Creates the handle to the configuration of engine.
+ *
+ * @since_tizen 2.4
+ * @param [out] engine_cfg    The handle to the engine to be created
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see mv_engine_config_h
+ * @see mv_destroy_engine_config_c()
+ * @see mv_engine_config_set_double_attribute_c()
+ * @see mv_engine_config_set_int_attribute_c()
+ * @see mv_engine_config_set_bool_attribute_c()
+ * @see mv_engine_config_set_string_attribute_c()
+ * @see mv_engine_config_get_double_attribute_c()
+ * @see mv_engine_config_get_int_attribute_c()
+ * @see mv_engine_config_get_bool_attribute_c()
+ * @see mv_engine_config_get_string_attribute_c()
+ */
+int mv_create_engine_config_c(
+        mv_engine_config_h *engine_cfg);
+
+/**
+ * @brief Destroys the engine configuration handle and releases all its
+ *        resources.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg    The handle to the engine configuration
+ *                           to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_engine_config_h
+ * @see mv_create_engine_config_c()
+ */
+int mv_destroy_engine_config_c(
+        mv_engine_config_h engine_cfg);
+
+/**
+ * @brief Sets the double attribute to the configuration.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration for which @a value has
+ *                               to be set
+ * @param [in] name              String key of the attribute will be used for
+ *                               storing the @a value into configuration
+ *                               dictionary
+ * @param [in] value             The double value of the attribute
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_engine_config_get_double_attribute_c()
+ * @see mv_engine_config_set_int_attribute_c()
+ * @see mv_engine_config_set_bool_attribute_c()
+ * @see mv_engine_config_set_string_attribute_c()
+ */
+int mv_engine_config_set_double_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        double value);
+
+/**
+ * @brief Sets the integer attribute to the configuration.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration for which @a value has
+ *                               to be set
+ * @param [in] name              String key of the attribute will be used for
+ *                               storing the @a value into configuration
+ *                               dictionary
+ * @param [in] value             The integer value of the attribute
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_engine_config_get_int_attribute_c()
+ * @see mv_engine_config_set_double_attribute_c()
+ * @see mv_engine_config_set_bool_attribute_c()
+ * @see mv_engine_config_set_string_attribute_c()
+ */
+int mv_engine_config_set_int_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        int value);
+
+/**
+ * @brief Sets the boolean attribute to the configuration.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration for which @a value has
+ *                               to be set
+ * @param [in] name              String key of the attribute will be used for
+ *                               storing the @a value into configuration
+ *                               dictionary
+ * @param [in] value             The boolean value of the attribute
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_engine_config_get_bool_attribute_c()
+ * @see mv_engine_config_set_double_attribute_c()
+ * @see mv_engine_config_set_int_attribute_c()
+ * @see mv_engine_config_set_string_attribute_c()
+ */
+int mv_engine_config_set_bool_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        bool attribute);
+
+/**
+ * @brief Sets the string attribute to the configuration.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration for which @a value has
+ *                               to be set
+ * @param [in] name              String key of the attribute will be used for
+ *                               storing the @a value into configuration
+ *                               dictionary
+ * @param [in] value             The string value of the attribute
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_engine_config_get_string_attribute_c()
+ * @see mv_engine_config_set_double_attribute_c()
+ * @see mv_engine_config_set_int_attribute_c()
+ * @see mv_engine_config_set_bool_attribute_c()
+ */
+int mv_engine_config_set_string_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        const char *value);
+
+/**
+ * @brief Gets the double attribute from the configuration dictionary.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration from which @a value
+ *                               has to be gotten
+ * @param [in] name              String key of the attribute will be used for
+ *                               getting the @a value from the
+ *                               configuration dictionary
+ * @param [out] value            The attribute to be filled with double value
+ *                               from dictionary
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Parameter key isn't available
+ *
+ * @see mv_engine_config_set_double_attribute_c()
+ * @see mv_engine_config_get_int_attribute_c()
+ * @see mv_engine_config_get_bool_attribute_c()
+ * @see mv_engine_config_get_string_attribute_c()
+ */
+int mv_engine_config_get_double_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        double *value);
+
+/**
+ * @brief Gets the integer attribute from the configuration dictionary.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration from which @a value
+ *                               has to be gotten
+ * @param [in] name              String key of the attribute will be used for
+ *                               getting the @a value from the
+ *                               configuration dictionary
+ * @param [out] value            The attribute to be filled with integer value
+ *                               from dictionary
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Parameter key isn't available
+ *
+ * @see mv_engine_config_set_int_attribute_c()
+ * @see mv_engine_config_get_double_attribute_c()
+ * @see mv_engine_config_get_bool_attribute_c()
+ * @see mv_engine_config_get_string_attribute_c()
+ */
+int mv_engine_config_get_int_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        int *value);
+
+/**
+ * @brief Gets the boolean attribute from the configuration dictionary.
+ *
+ * @since_tizen 2.4
+ * @param [in] engine_cfg        Engine configuration from which @a value
+ *                               has to be gotten
+ * @param [in] name              String key of the attribute will be used for
+ *                               getting the @a value from the
+ *                               configuration dictionary
+ * @param [out] value            The attribute to be filled with boolean value
+ *                               from dictionary
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Parameter key isn't available
+ *
+ * @see mv_engine_config_set_bool_attribute_c()
+ * @see mv_engine_config_get_double_attribute_c()
+ * @see mv_engine_config_get_int_attribute_c()
+ * @see mv_engine_config_get_string_attribute_c()
+ */
+int mv_engine_config_get_bool_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        bool *value);
+
+/**
+ * @brief Gets the string attribute from the configuration dictionary.
+ *
+ * @since_tizen 2.4
+ * @remarks Function allocates memory required for output @a value, so
+ *          it has to be removed by the user himself.
+ * @param [in] engine_cfg        Engine configuration from which @a value
+ *                               has to be gotten
+ * @param [in] name              String key of the attribute will be used for
+ *                               getting the @a value from the
+ *                               configuration dictionary
+ * @param [out] value            The attribute to be filled with string value
+ *                               from dictionary
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Parameter key isn't available
+ *
+ * @see mv_engine_config_set_string_attribute_c()
+ * @see mv_engine_config_get_double_attribute_c()
+ * @see mv_engine_config_get_int_attribute_c()
+ * @see mv_engine_config_get_bool_attribute_c()
+ */
+int mv_engine_config_get_string_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        char **value);
+
+/**
+ * @brief Traverses the list of supported attribute names and types.
+ * @details Using this function names of supported attributes can be obtained.
+ *          Names of the attributes can be used with @ref mv_engine_config_h
+ *          related getters and setters to get/set appropriate attribute values.
+ *
+ * @since_tizen 2.4
+ * @remarks If @a callback is called zero times after
+ *          @ref mv_engine_config_foreach_supported_attribute() call, then
+ *          engine configuration is not supported and setting of attributes will
+ *          cause no effect. In this case for all Media Vision functions which
+ *          require @ref mv_engine_config_h handle as in parameter this
+ *          parameter can be set NULL.
+ * @remarks If @a callback is called at least once, then attribute names and
+ *          types obtained in the @ref mv_supported_attribute_cb callback can be
+ *          changed after mv_engine_config_h handle creation (with
+ *          @ref mv_create_engine_config_c() function) by corresponding setters.
+ *          Although, if attributes aren't changed by setters, then default
+ *          values will be used.\n
+ *          Changing of attribute values will affect internal functionality
+ *          provided by concrete library underlying Media Vision API.
+ * @param [in] callback     The iteration callback function
+ * @param [in] user_data    The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *                                               (@a callback can't be NULL)
+ * @retval #MEDIA_VISION_ERROR_NO_DATA Can't determine list of supported attributes
+ *
+ * @see mv_engine_config_set_double_attribute_c()
+ * @see mv_engine_config_set_int_attribute_c()
+ * @see mv_engine_config_set_bool_attribute_c()
+ * @see mv_engine_config_set_string_attribute_c()
+ * @see mv_engine_config_get_double_attribute_c()
+ * @see mv_engine_config_get_int_attribute_c()
+ * @see mv_engine_config_get_bool_attribute_c()
+ * @see mv_engine_config_get_string_attribute_c()
+ */
+int mv_engine_config_foreach_supported_attribute_c(
+        mv_supported_attribute_cb callback,
+        void *user_data);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_COMMON_C_H__ */
diff --git a/mv_common/src/EngineConfig.cpp b/mv_common/src/EngineConfig.cpp
new file mode 100644 (file)
index 0000000..3faedf1
--- /dev/null
@@ -0,0 +1,327 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EngineConfig.h"
+
+#include <mv_private.h>
+
+#include <json/json.h>
+
+/**
+ * @file   EngineConfig.cpp
+ * @brief  Engine Configuration class methods implementation.
+ */
+
+namespace MediaVision
+{
+namespace Common
+{
+
+std::string EngineConfig::DefConfigFilePath =
+    std::string("/usr/share/config/capi-media-vision/media-vision-config.json");
+
+std::map<std::string, double> EngineConfig::DefDblDict;
+std::map<std::string, int> EngineConfig::DefIntDict;
+std::map<std::string, bool> EngineConfig::DefBoolDict;
+std::map<std::string, std::string> EngineConfig::DefStrDict;
+
+EngineConfig::EngineConfig()
+{
+    // Force load default attributes from configuration file
+    cacheDictionaries(false);
+
+    // Insert default attribute values into creating engine configuration
+    m_dblDict.insert(getDefaultDblDict().begin(), getDefaultDblDict().end());
+    m_intDict.insert(getDefaultIntDict().begin(), getDefaultIntDict().end());
+    m_boolDict.insert(getDefaultBoolDict().begin(), getDefaultBoolDict().end());
+    m_strDict.insert(getDefaultStrDict().begin(), getDefaultStrDict().end());
+}
+
+EngineConfig::~EngineConfig()
+{
+    ; /* NULL */
+}
+
+int EngineConfig::setAttribute(const std::string& key, const double value)
+{
+    LOGI("Set double attribute for the engine config %p. [%s] = %f",
+            this, key.c_str(), value);
+
+    if (m_dblDict.find(key) == m_dblDict.end())
+    {
+        LOGE("Double attribute [%s] can't be set because isn't supported", key.c_str());
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    m_dblDict[key] = value;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int EngineConfig::setAttribute(const std::string& key, const int value)
+{
+    LOGI("Set integer attribute for the engine config %p. [%s] = %i",
+            this, key.c_str(), value);
+
+    if (m_intDict.find(key) == m_intDict.end())
+    {
+        LOGE("Integer attribute [%s] can't be set because isn't supported", key.c_str());
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    m_intDict[key] = value;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int EngineConfig::setAttribute(const std::string& key, const bool value)
+{
+    LOGI("Set boolean attribute for the engine config %p. [%s] = %s",
+            this, key.c_str(), value ? "TRUE" : "FALSE");
+
+    if (m_boolDict.find(key) == m_boolDict.end())
+    {
+        LOGE("Boolean attribute [%s] can't be set because isn't supported", key.c_str());
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    m_boolDict[key] = value;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int EngineConfig::setAttribute(const std::string& key, const std::string& value)
+{
+    LOGI("Set string attribute for the engine config %p. [%s] = %s",
+            this, key.c_str(), value.c_str());
+
+    if (m_strDict.find(key) == m_strDict.end())
+    {
+        LOGE("String attribute [%s] can't be set because isn't supported", key.c_str());
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    m_strDict[key] = value;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int EngineConfig::getDoubleAttribute(const std::string& key, double *value) const
+{
+    DictDblConstIter dictIter = m_dblDict.find(key);
+    if (dictIter == m_dblDict.end())
+    {
+        LOGE("Attempt to access to the unsupported double attribute [%s] "
+                "of the engine config %p", key.c_str(), this);
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    LOGD("Get double attribute from the engine config %p. [%s] = %f",
+            this, dictIter->first.c_str(), dictIter->second);
+
+    *value = dictIter->second;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int EngineConfig::getIntegerAttribute(const std::string& key, int *value) const
+{
+    DictIntConstIter dictIter = m_intDict.find(key);
+    if (dictIter == m_intDict.end())
+    {
+        LOGE("Attempt to access to the unsupported integer attribute [%s] "
+                "of the engine config %p", key.c_str(), this);
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    LOGD("Get integer attribute from the engine config %p. [%s] = %i",
+            this, dictIter->first.c_str(), dictIter->second);
+
+    *value = dictIter->second;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int EngineConfig::getBooleanAttribute(const std::string& key, bool *value) const
+{
+    DictBoolConstIter dictIter = m_boolDict.find(key);
+    if (dictIter == m_boolDict.end())
+    {
+        LOGE("Attempt to access to the unsupported boolean attribute [%s] "
+                "of the engine config %p", key.c_str(), this);
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    LOGD("Get boolean attribute from the engine config %p. [%s] = %s",
+            this, dictIter->first.c_str(), dictIter->second ? "TRUE" : "FALSE");
+
+    *value = dictIter->second;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int EngineConfig::getStringAttribute(const std::string& key, std::string *value) const
+{
+    DictStrConstIter dictIter = m_strDict.find(key);
+    if (dictIter == m_strDict.end())
+    {
+        LOGE("Attempt to access to the unsupported string attribute [%s] "
+                "of the engine config %p", key.c_str(), this);
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    LOGD("Get string attribute from the engine config %p. [%s] = %s",
+            this, dictIter->first.c_str(), dictIter->second.c_str());
+
+    *value = dictIter->second;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+// static
+
+bool EngineConfig::setDefaultConfigFilePath(const std::string& confFilePath)
+{
+    if (0 != DefConfigFilePath.compare(confFilePath))
+    {
+        DefConfigFilePath = confFilePath;
+        return true;
+    }
+
+    return false;
+}
+
+const std::map<std::string, double>& EngineConfig::getDefaultDblDict()
+{
+    cacheDictionaries();
+
+    return DefDblDict;
+}
+
+const std::map<std::string, int>& EngineConfig::getDefaultIntDict()
+{
+    cacheDictionaries();
+
+    return DefIntDict;
+}
+
+const std::map<std::string, bool>& EngineConfig::getDefaultBoolDict()
+{
+    cacheDictionaries();
+
+    return DefBoolDict;
+}
+
+const std::map<std::string, std::string>& EngineConfig::getDefaultStrDict()
+{
+    cacheDictionaries();
+
+    return DefStrDict;
+}
+
+int EngineConfig::cacheDictionaries(bool isLazyCache, std::string configFilePath)
+{
+    static bool isCached = false;
+    if (!isLazyCache || !isCached)
+    {
+        LOGI("Start to cache default attributes from engine configuration file.");
+
+        DefDblDict.clear();
+        DefIntDict.clear();
+        DefBoolDict.clear();
+        DefStrDict.clear();
+
+        json_object *jobj = json_object_from_file(configFilePath.c_str());
+
+        enum json_type type = json_object_get_type(jobj);
+        if (json_type_object != type)
+        {
+            LOGE("Can't parse engine config file. Incorrect json markup. "
+                    "Supported attributes can't be determined.");
+            json_object_put(jobj);
+            return MEDIA_VISION_ERROR_NO_DATA;
+        }
+
+        json_object *pAttributesObj = json_object_object_get(jobj, "attributes");
+        type = json_object_get_type(pAttributesObj);
+        if (json_type_array != type)
+        {
+            LOGE("Can't parse engine config file. Incorrect json markup. "
+                    "Supported attributes can't be determined.");
+            json_object_put(jobj);
+            return MEDIA_VISION_ERROR_NO_DATA;
+        }
+
+        const int attrNum = json_object_array_length(pAttributesObj);
+
+        for (int attrInd = 0; attrInd < attrNum; ++attrInd)
+        {
+            json_object *pAttrObj =
+                    json_object_array_get_idx(pAttributesObj, attrInd);
+            type = json_object_get_type(pAttrObj);
+
+            json_object *pAttrNameObj = NULL;
+            json_object *pAttrTypeObj = NULL;
+            json_object *pAttrValueObj = NULL;
+
+            if (json_type_object != type ||
+                !json_object_object_get_ex(pAttrObj, "name", &pAttrNameObj) ||
+                !json_object_object_get_ex(pAttrObj, "type", &pAttrTypeObj) ||
+                !json_object_object_get_ex(pAttrObj, "value", &pAttrValueObj))
+            {
+                LOGW("Attribute %i wasn't parsed from json file.", attrInd);
+                continue;
+            }
+
+            const char *nameStr = json_object_get_string(pAttrNameObj);
+            const char *typeStr = json_object_get_string(pAttrTypeObj);
+
+            if (0 == strcmp("double", typeStr))
+            {
+                DefDblDict[std::string(nameStr)] =
+                        json_object_get_double(pAttrValueObj);
+            }
+            else if (0 == strcmp("integer", typeStr))
+            {
+                DefIntDict[std::string(nameStr)] =
+                        json_object_get_int(pAttrValueObj);
+            }
+            else if (0 == strcmp("boolean", typeStr))
+            {
+                DefBoolDict[std::string(nameStr)] =
+                        json_object_get_boolean(pAttrValueObj) ? true : false;
+            }
+            else if (0 == strcmp("string", typeStr))
+            {
+                DefStrDict[std::string(nameStr)] =
+                        json_object_get_string(pAttrValueObj);
+            }
+            else
+            {
+                LOGW("Attribute %i:%s wasn't parsed from json file. Type isn't supported.", attrInd, nameStr);
+                continue;
+            }
+        }
+
+        json_object_put(jobj);
+        isCached = true;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* namespace Common */
+} /* namespace MediaVision */
diff --git a/mv_common/src/MediaSource.cpp b/mv_common/src/MediaSource.cpp
new file mode 100644 (file)
index 0000000..1288625
--- /dev/null
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MediaSource.h"
+
+#include <mv_private.h>
+
+#include <cstring>
+
+namespace MediaVision
+{
+namespace Common
+{
+
+MediaSource::MediaSource() : m_pBuffer (NULL), m_bufferSize (0), m_width (0),
+        m_height (0), m_colorspace (MEDIA_VISION_COLORSPACE_INVALID)
+{
+}
+
+MediaSource::~MediaSource()
+{
+    clear();
+}
+
+void MediaSource::clear(void)
+{
+    if (m_pBuffer != NULL)
+    {
+        LOGD("Delete internal buffer for media source %p", this);
+        delete[] m_pBuffer;
+    }
+    LOGD("Set defaults for media source %p : buffer = NULL; "
+            "bufferSize = 0; width = 0; height = 0; "
+            "colorspace = MEDIA_VISION_COLORSPACE_INVALID", this);
+    m_pBuffer = NULL;
+    m_bufferSize = 0;
+    m_width = 0;
+    m_height = 0;
+    m_colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+}
+
+bool MediaSource::fill(const unsigned char *buffer, unsigned int bufferSize,
+        unsigned int width, unsigned int height, mv_colorspace_e colorspace)
+{
+    if (bufferSize == 0 || buffer == NULL)
+    {
+        return false;
+    }
+
+    LOGD("Call clear() first for media source %p", this);
+    clear();
+
+    try
+    {
+        LOGD("Allocate memory for buffer in media source %p", this);
+        m_pBuffer = new unsigned char[bufferSize];
+    }
+    catch(...)
+    {
+        LOGE("Memory allocating for buffer in media source %p failed!", this);
+        m_pBuffer = NULL;
+        return false;
+    }
+
+    LOGD("Copy data from external buffer (%p) to the internal buffer (%p) of "
+            "media source %p", buffer, m_pBuffer, this);
+    std::memcpy(m_pBuffer, buffer, bufferSize);
+
+    LOGD("Assign new size of the internal buffer of media source %p. "
+            "New size is %ui.", this, bufferSize);
+    m_bufferSize = bufferSize;
+
+    LOGD("Assign new size (%ui x %ui) of the internal buffer image for "
+            "the media source %p", width, height, this);
+    m_width = width;
+    m_height = height;
+
+    LOGD("Assign new colorspace (%i) of the internal buffer image for "
+                "the media source %p", colorspace, this);
+    m_colorspace = colorspace;
+
+    return true;
+}
+
+unsigned char *MediaSource::getBuffer(void) const
+{
+    return m_pBuffer;
+}
+
+unsigned int MediaSource::getBufferSize(void) const
+{
+    return m_bufferSize;
+}
+
+unsigned int MediaSource::getWidth(void) const
+{
+    return m_width;
+}
+
+unsigned int MediaSource::getHeight(void) const
+{
+    return m_height;
+}
+
+mv_colorspace_e MediaSource::getColorspace(void) const
+{
+    return m_colorspace;
+}
+
+} /* Common */
+} /* MediaVision */
diff --git a/mv_common/src/mv_common_c.cpp b/mv_common/src/mv_common_c.cpp
new file mode 100644 (file)
index 0000000..ececf20
--- /dev/null
@@ -0,0 +1,644 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_common_c.h"
+
+#include "MediaSource.h"
+#include "EngineConfig.h"
+
+#include <mv_private.h>
+
+#include <string.h>
+#include <media_packet.h>
+
+int mv_create_source_c(
+    mv_source_h *source_ptr)
+{
+    if (source_ptr == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Creating media vision source");
+    (*source_ptr) = ((mv_source_h)new MediaVision::Common::MediaSource());
+
+    if (*source_ptr == NULL)
+    {
+        LOGE("Failed to create media vision source");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+    LOGD("Media vision source [%p] has been created", *source_ptr);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_destroy_source_c(
+    mv_source_h source)
+{
+    if (!source)
+    {
+        LOGE("Media source can't be destroyed because handle is NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Destroying media vision source [%p]", source);
+    delete ((MediaVision::Common::MediaSource*)source);
+    LOGD("Media vision source has been destroyed");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_source_fill_by_media_packet_c(
+    mv_source_h source,
+    media_packet_h media_packet)
+{
+    if (!source || !media_packet)
+    {
+        LOGE("Media source can't be filled by media_packet handle because "
+                "one of the source or media_packet handles is NULL. "
+                "source = %p; media_packet = %p", source, media_packet);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    bool is_video = false;
+    int image_width = 0;
+    int image_height = 0;
+    media_format_h format = NULL;
+    media_format_mimetype_e mimetype = MEDIA_FORMAT_I420;
+    unsigned char *data_buffer = NULL;
+    uint64_t buffer_size = 0;
+    mv_colorspace_e image_colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+
+    int ret = media_packet_is_video(media_packet, &is_video);
+    if (ret != MEDIA_PACKET_ERROR_NONE)
+    {
+        LOGE("media_packet_is_video() failed, mv_source_h fill skipped");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!is_video)
+    {
+        LOGE("Media packet isn't video, mv_source_h fill skipped");
+        return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    ret = media_packet_get_format(media_packet, &format);
+    if (ret != MEDIA_PACKET_ERROR_NONE)
+    {
+        LOGE("media_packet_get_format() failed, mv_source_h fill skipped");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    ret = media_format_get_video_info(
+            format, &mimetype, &image_width, &image_height, NULL, NULL);
+    if (ret != MEDIA_PACKET_ERROR_NONE)
+    {
+        LOGE("media_format_get_video_info() failed, mv_source_h fill skipped");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (mimetype > MEDIA_FORMAT_H261 && mimetype <= MEDIA_FORMAT_MPEG4_ASP)
+    {
+        LOGE("Media format mimetype is not the raw video, mv_source_h fill skipped");
+        return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    switch (mimetype)
+    {
+        case MEDIA_FORMAT_I420:
+            image_colorspace = MEDIA_VISION_COLORSPACE_I420;
+            break;
+        case MEDIA_FORMAT_NV12:
+            image_colorspace = MEDIA_VISION_COLORSPACE_NV12;
+            break;
+        case MEDIA_FORMAT_YV12:
+            image_colorspace = MEDIA_VISION_COLORSPACE_YV12;
+            break;
+        case MEDIA_FORMAT_NV21:
+            image_colorspace = MEDIA_VISION_COLORSPACE_NV21;
+            break;
+        case MEDIA_FORMAT_YUYV:
+            image_colorspace = MEDIA_VISION_COLORSPACE_YUYV;
+            break;
+        case MEDIA_FORMAT_UYVY:
+            image_colorspace = MEDIA_VISION_COLORSPACE_UYVY;
+            break;
+        case MEDIA_FORMAT_422P:
+            image_colorspace = MEDIA_VISION_COLORSPACE_422P;
+            break;
+        case MEDIA_FORMAT_RGB565:
+            image_colorspace = MEDIA_VISION_COLORSPACE_RGB565;
+            break;
+        case MEDIA_FORMAT_RGB888:
+            image_colorspace = MEDIA_VISION_COLORSPACE_RGB888;
+            break;
+        case MEDIA_FORMAT_RGBA:
+            image_colorspace = MEDIA_VISION_COLORSPACE_RGBA;
+            break;
+        default:
+            LOGE("Format of the media packet buffer is not supported by media "
+                    "vision source (media_format_h mimetype=%i)", mimetype);
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    ret = media_packet_get_buffer_data_ptr(media_packet, (void**)&data_buffer);
+    if (ret != MEDIA_PACKET_ERROR_NONE)
+    {
+        LOGE("media_packet_get_buffer_data_ptr() failed, mv_source_h fill skipped");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    ret = media_packet_get_buffer_size(media_packet, &buffer_size);
+    if (ret != MEDIA_PACKET_ERROR_NONE)
+    {
+        LOGE("media_packet_get_buffer_size() failed, mv_source_h fill skipped");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!((MediaVision::Common::MediaSource*)source)->fill(data_buffer,
+        buffer_size, (unsigned int)image_width, (unsigned int)image_height, image_colorspace))
+    {
+        LOGE("mv_source_h filling from media_packet_h failed");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    LOGD("Media source has been filled from media packet");
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_source_fill_by_buffer_c(
+    mv_source_h source,
+    unsigned char *data_buffer,
+    unsigned int buffer_size,
+    unsigned int image_width,
+    unsigned int image_height,
+    mv_colorspace_e image_colorspace)
+{
+    if (!source || buffer_size == 0 || data_buffer == NULL)
+    {
+        LOGE("Media source can't be filled by buffer because "
+                "one of the source or data_buffer is NULL or buffer_size = 0. "
+                "source = %p; data_buffer = %p; buffer_size = %u",
+                source, data_buffer, buffer_size);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!((MediaVision::Common::MediaSource*)source)->fill(data_buffer,
+            buffer_size, image_width, image_height, image_colorspace))
+    {
+        LOGE("mv_source_h filling from buffer failed");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    LOGD("Media source has been filled from buffer");
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_source_clear_c(
+    mv_source_h source)
+{
+    if (!source)
+    {
+        LOGE("Media source can't be cleared because source handle is NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Clear media vision source [%p]", source);
+    ((MediaVision::Common::MediaSource*)source)->clear();
+    LOGD("Media vision source [%p] has been cleared", source);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_source_get_buffer_c(
+    mv_source_h source,
+    unsigned char **buffer,
+    unsigned int *size)
+{
+    if (!source)
+    {
+        LOGE("Impossible to get buffer for NULL mv_source_h handle");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Get media vision source [%p] buffer and buffer size to be returned", source);
+    *buffer = ((MediaVision::Common::MediaSource*)source)->getBuffer();
+    *size = ((MediaVision::Common::MediaSource*)source)->getBufferSize();
+    LOGD("Media vision source [%p] buffer (%p) and buffer size (%ui) has been returned", source, buffer, *size);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_source_get_height_c(
+    mv_source_h source,
+    unsigned int *height)
+{
+    if (!source)
+    {
+        LOGE("Impossible to get height for NULL mv_source_h handle");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Get media vision source [%p] height to be returned", source);
+    *height = ((MediaVision::Common::MediaSource*)source)->getHeight();
+    LOGD("Media vision source [%p] height (%ui) has been returned", source, *height);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_source_get_width_c(
+    mv_source_h source,
+    unsigned int *width)
+{
+    if (!source)
+    {
+        LOGE("Impossible to get width for NULL mv_source_h handle");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Get media vision source [%p] width to be returned", source);
+    *width = ((MediaVision::Common::MediaSource*)source)->getWidth();
+    LOGD("Media vision source [%p] width (%ui) has been returned", source, *width);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_source_get_colorspace_c(
+    mv_source_h source,
+    mv_colorspace_e *colorspace)
+{
+    if (!source)
+    {
+        LOGE("Impossible to get colorspace for NULL mv_source_h handle");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Get media vision source [%p] colorspace to be returned", source);
+    *colorspace = ((MediaVision::Common::MediaSource*)source)->getColorspace();
+    LOGD("Media vision source [%p] colorspace (%i) has been returned", source, *colorspace);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_create_engine_config_c(
+        mv_engine_config_h *engine_cfg)
+{
+    if (engine_cfg == NULL)
+    {
+        LOGE("Impossible to create mv_engine_config_h handle");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+
+    LOGD("Creating media vision engine config");
+    (*engine_cfg) = ((mv_engine_config_h)new MediaVision::Common::EngineConfig());
+    LOGD("Media vision engine config [%p] has been created", *engine_cfg);
+
+    if (*engine_cfg == NULL)
+    {
+        LOGE("Failed to create mv_engine_config_h handle");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_destroy_engine_config_c(
+        mv_engine_config_h engine_cfg)
+{
+    if (!engine_cfg)
+    {
+        LOGE("Impossible to destroy NULL mv_engine_config_h handle");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Destroying media vision engine config [%p]", engine_cfg);
+    delete ((MediaVision::Common::EngineConfig*)engine_cfg);
+    LOGD("Media vision engine config has been destroyed");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_engine_config_set_double_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        double value)
+{
+    if (!engine_cfg || name == NULL)
+    {
+        LOGE("Impossible to set attribute. One of the required parameters is "
+                "NULL. engine_cfg = %p; name = %p;",
+                engine_cfg, name);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = ((MediaVision::Common::EngineConfig*)engine_cfg)->setAttribute(
+            std::string(name), value);
+
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to set attribute [%s] with value %f. Error code (0x%08x)",
+                name, value, ret);
+        return ret;
+    }
+
+    LOGD("Attribute [%s] (value %f) has been set", name, value);
+    return ret;
+}
+
+int mv_engine_config_set_int_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        int value)
+{
+    if (!engine_cfg || name == NULL)
+    {
+        LOGE("Impossible to set attribute. One of the required parameters is "
+                "NULL. engine_cfg = %p; name = %p;",
+                engine_cfg, name);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = ((MediaVision::Common::EngineConfig*)engine_cfg)->setAttribute(
+            std::string(name), value);
+
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to set attribute [%s] with value %i. Error code (0x%08x)",
+                name, value, ret);
+        return ret;
+    }
+
+    LOGD("Attribute [%s] (value %i) has been set", name, value);
+
+    return ret;
+}
+
+int mv_engine_config_set_bool_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        bool value)
+{
+    if (!engine_cfg || name == NULL)
+    {
+        LOGE("Impossible to set attribute. One of the required parameters is "
+                "NULL. engine_cfg = %p; name = %p;",
+                engine_cfg, name);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = ((MediaVision::Common::EngineConfig*)engine_cfg)->setAttribute(
+            std::string(name), value);
+
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to set attribute [%s] with value %s. Error code (0x%08x)",
+                name, value ? "TRUE" : "FALSE", ret);
+        return ret;
+    }
+
+    LOGD("Attribute [%s] (value %s) has been set",
+            name, value ? "TRUE" : "FALSE");
+    return ret;
+}
+
+int mv_engine_config_set_string_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        const char *value)
+{
+    if (!engine_cfg || name == NULL || value == NULL)
+    {
+        LOGE("Impossible to set attribute. One of the required parameters is "
+                "NULL. engine_cfg = %p; name = %p; value = %p;",
+                engine_cfg, name, value);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = ((MediaVision::Common::EngineConfig*)engine_cfg)->setAttribute(
+            std::string(name), std::string(value));
+
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to set attribute [%s] with value %s. Error code (0x%08x)",
+                name, value, ret);
+        return ret;
+    }
+
+    LOGD("Attribute [%s] (value %s) has been set", name, value);
+    return ret;
+}
+
+int mv_engine_config_get_double_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        double *value)
+{
+    if (!engine_cfg || name == NULL || value == NULL)
+    {
+        LOGE("Impossible to get attribute. One of the required parameters is "
+                "NULL. engine_cfg = %p; name = %p; value = %p;",
+                engine_cfg, name, value);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = ((MediaVision::Common::EngineConfig*)engine_cfg)->getDoubleAttribute(
+            std::string(name), value);
+
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to get attribute [%s]. Error code (0x%08x)",
+                name, ret);
+        return ret;
+    }
+
+    LOGD("Attribute [%s] (value %f) has been gotten",
+            name, *value);
+    return ret;
+}
+
+int mv_engine_config_get_int_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        int *value)
+{
+    if (!engine_cfg || name == NULL || value == NULL)
+    {
+        LOGE("Impossible to get attribute. One of the required parameters is "
+                "NULL. engine_cfg = %p; name = %p; value = %p;",
+                engine_cfg, name, value);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = ((MediaVision::Common::EngineConfig*)engine_cfg)->getIntegerAttribute(
+            std::string(name), value);
+
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to get attribute [%s]. Error code (0x%08x)",
+                name, ret);
+        return ret;
+    }
+
+    LOGD("Attribute [%s] (value %i) has been gotten",
+            name, *value);
+    return ret;
+}
+
+int mv_engine_config_get_bool_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        bool *value)
+{
+    if (!engine_cfg || name == NULL || value == NULL)
+    {
+        LOGE("Impossible to get attribute. One of the required parameters is "
+                "NULL. engine_cfg = %p; name = %p; value = %p;",
+                engine_cfg, name, value);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = ((MediaVision::Common::EngineConfig*)engine_cfg)->getBooleanAttribute(
+            std::string(name), value);
+
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to get attribute [%s]. Error code (0x%08x)",
+                name, ret);
+        return ret;
+    }
+
+    LOGD("Attribute [%s] (value %s) has been gotten",
+            name, *value ? "TRUE" : "FALSE");
+    return ret;
+}
+
+int mv_engine_config_get_string_attribute_c(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        char **value)
+{
+    if (!engine_cfg || name == NULL || value == NULL)
+    {
+        LOGE("Impossible to get attribute. One of the required parameters is "
+                "NULL. engine_cfg = %p; name = %p; value = %p;",
+                engine_cfg, name, value);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    std::string attributeValue;
+    int ret = ((MediaVision::Common::EngineConfig*)engine_cfg)->getStringAttribute(
+            std::string(name), &attributeValue);
+
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to get attribute [%s]. Error code (0x%08x)",
+                    name, ret);
+        return ret;
+    }
+
+    LOGD("Convert string to char*");
+    int stringSize = attributeValue.size();
+    (*value) = new char[stringSize + 1];
+
+    if (attributeValue.copy(*value, stringSize) != attributeValue.size())
+    {
+        LOGE("Conversion from string to char* failed");
+        delete[] (*value);
+        (*value) = NULL;
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+    (*value)[stringSize] = '\0';
+
+    LOGD("Attribute [%s] (value %s) has been gotten",
+            name, *value);
+    return ret;
+}
+
+int mv_engine_config_foreach_supported_attribute_c(
+        mv_supported_attribute_cb callback,
+        void *user_data)
+{
+    if (NULL == callback)
+    {
+        LOGE("Impossible to traverse supported by Media Vision engine "
+                "configuration attributes. Callback is NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    using namespace MediaVision::Common;
+
+    int err = EngineConfig::cacheDictionaries();
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        LOGE("Failed to get attribute names/types. "
+                "Failed to cache attributes from file");
+        return err;
+    }
+
+    DictDblConstIter dblDictIter = EngineConfig::getDefaultDblDict().begin();
+    DictIntConstIter intDictIter = EngineConfig::getDefaultIntDict().begin();
+    DictBoolConstIter boolDictIter = EngineConfig::getDefaultBoolDict().begin();
+    DictStrConstIter strDictIter = EngineConfig::getDefaultStrDict().begin();
+
+    while (dblDictIter != EngineConfig::getDefaultDblDict().end())
+    {
+        if (!callback(MV_ENGINE_CONFIG_ATTR_TYPE_DOUBLE,
+                      dblDictIter->first.c_str(), user_data))
+        {
+            LOGD("Attribute names/types traverse has been stopped by the user");
+            return MEDIA_VISION_ERROR_NONE;
+        }
+        ++dblDictIter;
+    }
+
+    while (intDictIter != EngineConfig::getDefaultIntDict().end())
+    {
+        if (!callback(MV_ENGINE_CONFIG_ATTR_TYPE_INTEGER,
+                      intDictIter->first.c_str(), user_data))
+        {
+            LOGD("Attribute names/types traverse has been stopped by the user");
+            return MEDIA_VISION_ERROR_NONE;
+        }
+        ++intDictIter;
+    }
+
+    while (boolDictIter != EngineConfig::getDefaultBoolDict().end())
+    {
+        if (!callback(MV_ENGINE_CONFIG_ATTR_TYPE_BOOLEAN,
+                      boolDictIter->first.c_str(), user_data))
+        {
+            LOGD("Attribute names/types traverse has been stopped by the user");
+            return MEDIA_VISION_ERROR_NONE;
+        }
+        ++boolDictIter;
+    }
+
+    while (strDictIter != EngineConfig::getDefaultStrDict().end())
+    {
+        if (!callback(MV_ENGINE_CONFIG_ATTR_TYPE_STRING,
+                      strDictIter->first.c_str(), user_data))
+        {
+            LOGD("Attribute names/types traverse has been stopped by the user");
+            return MEDIA_VISION_ERROR_NONE;
+        }
+        ++strDictIter;
+    }
+
+    LOGD("Attribute names/types has been gotten");
+    return MEDIA_VISION_ERROR_NONE;
+}
diff --git a/mv_face/CMakeLists.txt b/mv_face/CMakeLists.txt
new file mode 100644 (file)
index 0000000..248d927
--- /dev/null
@@ -0,0 +1,8 @@
+project(mv_face_port)
+cmake_minimum_required(VERSION 2.6)
+
+if(MEDIA_VISION_FACE_LICENSE_PORT)
+    add_subdirectory(${PROJECT_SOURCE_DIR}/face_lic) # Licensed port
+else()
+    add_subdirectory(${PROJECT_SOURCE_DIR}/face) # Open port
+endif()
diff --git a/mv_face/face/CMakeLists.txt b/mv_face/face/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6cc1199
--- /dev/null
@@ -0,0 +1,36 @@
+project(${MV_FACE_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+if(NOT SKIP_WARNINGS)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_FACE_INCLUDE_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_FACE_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp")
+
+find_package(OpenCV REQUIRED core objdetect contrib)
+if(NOT OpenCV_FOUND)
+    message(SEND_ERROR "Failed to find OpenCV")
+    return()
+else()
+    include_directories(${OpenCV_INCLUDE_DIRS})
+endif()
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_FACE_INCLUDE_LIST} ${MV_FACE_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_FACE_INCLUDE_LIST} ${MV_FACE_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} ${MV_COMMON_LIB_NAME} dlog)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_face/face/include/FaceDetector.h b/mv_face/face/include/FaceDetector.h
new file mode 100644 (file)
index 0000000..f014a54
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACEDETECTOR_H__
+#define __FACEDETECTOR_H__
+
+#include <opencv/cv.h>
+#include <vector>
+#include <string>
+
+/**
+ * @file FaceDetector.h
+ * @brief This file contains the FaceDetector class which implement the face
+ *        detection functionality.
+ */
+
+namespace MediaVision
+{
+namespace Face
+{
+
+/**
+ * @class   FaceDetector
+ * @brief   The Face Detector container.
+ * @details It is class which contains face detection functionality.
+ *
+ * @since_tizen 3.0
+ */
+class FaceDetector
+{
+public:
+
+    /**
+     * @brief   Creates a FaceDetector.
+     *
+     * @since_tizen 3.0
+     */
+    FaceDetector();
+
+    /**
+     * @brief   Destroys the FaceDetector and releases all its resources.
+     *
+     * @since_tizen 3.0
+     */
+    virtual ~FaceDetector();
+
+    /**
+     * @brief Performs face detection functionality.
+     * @details Use this function to launch face detection algorithm which
+     *          used the haarcascade set by setHaarcascadeFilepath().
+     *
+     * @since_tizen 3.0
+     * @param [in]  image           The image where faces will be detected
+     * @param [in]  roi             Region of image where faces will be detected
+     * @param [in]  minSize         Minimum size of faces which will be detected
+     * @param [out] faceLocations   The result locations of detected faces.
+     * @return true if detect process is completely finished. Otherwise return false.
+     *
+     * @pre Set a face haarcascade by calling setHaarcascadeFilepath()
+     *
+     * @see setHaarcascadeFilepath()
+     */
+    bool detectFaces(
+            const cv::Mat& image,
+            const cv::Rect& roi,
+            const cv::Size& minSize,
+            std::vector<cv::Rect>& faceLocations);
+
+    /**
+     * @brief Loads haar cascade classifier for detection process.
+     * @details This method is mandatory for normally detecting process.
+     *
+     * @since_tizen 3.0
+     * @param [in] haarcascadeFilepath The path to the file, which contains haar
+     *                                 cascade classifier information for
+     *                                 detection process.
+     * @return true if cascade is loaded from file and ready for detecting
+     *         process. Otherwise is false.
+     */
+    bool loadHaarcascade(const std::string& haarcascadeFilepath);
+
+private:
+
+    cv::CascadeClassifier m_faceCascade; /**< Cascade classifier of the face
+                                              detecting process. */
+
+    std::string m_haarcascadeFilepath;   /**< Path to the file, which contains
+                                              cascade classifier information. */
+
+    bool m_faceCascadeIsLoaded; /**< Flag to determine the state of the
+                                     m_faceCascade class. true if cascade is loaded
+                                     from file and is ready to detecting process.
+                                     Otherwise is false. */
+};
+
+} /* Face */
+} /* MediaVision */
+
+#endif /* __FACEDETECTOR_H__ */
diff --git a/mv_face/face/include/FaceExpressionRecognizer.h b/mv_face/face/include/FaceExpressionRecognizer.h
new file mode 100644 (file)
index 0000000..fb445a4
--- /dev/null
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACEEXPRESSIONRECOGNIZER_H__
+#define __FACEEXPRESSIONRECOGNIZER_H__
+
+#include "mv_common_c.h"
+#include "mv_face_open.h"
+
+#include <string>
+
+namespace cv
+{
+    class Mat;
+}
+
+/**
+ * @file FaceExpressionRecognizer.h
+ * @brief This file contains the FaceExpressionRecognizer class which implements
+ *        the facial expressions recognition functionality.
+ */
+
+namespace MediaVision
+{
+namespace Face
+{
+
+/**
+ * @brief Face expression recognition configuration.
+ *
+ * @since_tizen 3.0
+ */
+struct FaceRecognizerConfig
+{
+    FaceRecognizerConfig();
+    std::string mHaarcascadeFilepath;
+};
+
+/**
+ * @class FaceExpressionRecognizer
+ * @brief The FaceExpressionRecognizer implements the facial expressions
+ *        recognition functionality.
+ *
+ * @since_tizen 3.0
+ */
+class FaceExpressionRecognizer
+{
+public:
+    /**
+     * @brief Recognizes facial expression on the image with known face location.
+     *
+     * @since_tizen 3.0
+     * @param [in]     grayImage         The grayscale image with face
+     * @param [in]     faceLocation      The location of the face on the @a image
+     * @param [out]    faceExpression    Expression recognized for the face at
+     *                                   @a faceLocation
+     * @param [in]     config            The configuration will be used for
+     *                                   facial expression recognition
+     *
+     * @see MediaVision::Face::FaceRecognizerConfig
+     */
+    static int recognizeFaceExpression(
+                   const cv::Mat& grayImage,
+                   const mv_rectangle_s& faceLocation,
+                   mv_face_facial_expression_e *faceExpression,
+                   const FaceRecognizerConfig& config = FaceRecognizerConfig());
+};
+
+} /* Face */
+} /* MediaVision */
+
+#endif /* __FACEEXPRESSIONRECOGNIZER_H__ */
diff --git a/mv_face/face/include/FaceEyeCondition.h b/mv_face/face/include/FaceEyeCondition.h
new file mode 100644 (file)
index 0000000..56e1038
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACEEYECONDITION_H__
+#define __FACEEYECONDITION_H__
+
+#include <mv_common_c.h>
+#include <mv_face.h>
+
+#include <opencv/cv.h>
+
+/**
+ * @file FaceEyeCondition.h
+ * @brief This file contains the FaceEyeCondition class which implements the face
+ *        eye condition recognition functionality.
+ */
+
+namespace MediaVision
+{
+namespace Face
+{
+
+/**
+ * @class FaceEyeCondition
+ * @brief The FaceEyeCondition implements the face
+ *        eye condition recognition functionality.
+ *
+ * @since_tizen 3.0
+ */
+class FaceEyeCondition
+{
+public:
+
+    /**
+     * @brief Recognizes eye condition on the image with face location.
+     *
+     * @since_tizen 3.0
+     * @param [in] grayImage        The image  in gray scale with face where
+     *                              eye condition will be recognized
+     * @param [in] faceLocation     The rectangle with face location
+     * @param [out] eyeCondition    The eye condition which was recognized
+     * @return @c 0 on success, otherwise a negative error value
+     */
+    static int recognizeEyeCondition(
+                   const cv::Mat& grayImage,
+                   mv_rectangle_s faceLocation,
+                   mv_face_eye_condition_e *eyeCondition);
+
+private:
+
+    static void splitEyes(
+                    /*[in]*/ const cv::Mat& grayImage,
+                    /*[in]*/ mv_rectangle_s faceLocation,
+                    /*[out]*/ cv::Mat& leftEye,
+                    /*[out]*/ cv::Mat& rightEye);
+
+    static int isEyeOpen(/*[in]*/const cv::Mat& eye);
+};
+
+} /* Face */
+} /* MediaVision */
+
+#endif /* __FACEEYECONDITION_H__ */
diff --git a/mv_face/face/include/FaceRecognitionModel.h b/mv_face/face/include/FaceRecognitionModel.h
new file mode 100644 (file)
index 0000000..b4888f2
--- /dev/null
@@ -0,0 +1,290 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACERECOGNITIONMODEL_H__
+#define __FACERECOGNITIONMODEL_H__
+
+#include "FaceUtil.h"
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/contrib/contrib.hpp>
+
+#include <cstring>
+#include <vector>
+
+/**
+ * @file FaceRecognitionModel.h
+ * @brief This file contains the FaceRecognitionModel class definition which
+ *        provides face recognition model interface.
+ */
+
+namespace MediaVision
+{
+namespace Face
+{
+
+/**
+ * @brief Structure containing supported recognition algorithms settings.
+ *
+ * @since_tizen 3.0
+ */
+struct FaceRecognitionModelConfig
+{
+    /**
+     * @brief Default constructor for the @ref FaceRecognitionModelConfig
+     *
+     * @since_tizen 3.0
+     */
+    FaceRecognitionModelConfig();
+
+    bool operator!=(
+            const FaceRecognitionModelConfig& other) const;
+
+    FaceRecognitionModelType mModelType; /**<
+                                Type of the recognition algorithm */
+
+    int mNumComponents;    /**< How many principal components will be included
+                                to the Eigenvectors */
+
+    double mThreshold;     /**< Minimal distance between principal components of
+                                the model allowed */
+
+    int mRadius;           /**< Radius of the local features for LBHP algorithm */
+
+    int mNeighbors;        /**< How many neighboring pixels has to be analyzed
+                                when LBHP learning applied. Usually set as
+                                8*radius */
+
+    int mGridX;            /**< X size of the spatial histogram (LBPH) */
+
+    int mGridY;            /**< Y size of the spatial histogram (LBPH) */
+
+    int mImgWidth;         /**< Width of the image to resize the samples for
+                                algorithms working on the samples of the same
+                                size (Eigenfaces, Fisherfaces) */
+
+    int mImgHeight;        /**< Height of the image to resize the samples for
+                                algorithms working on the samples of the same
+                                size (Eigenfaces, Fisherfaces) */
+};
+
+/**
+ * @brief Structure where results of
+ *        @ref MediaVision::Face::FaceRecognitionModel::recognize() call is
+ *        stored.
+ *
+ * @since_tizen 3.0
+ */
+struct FaceRecognitionResults
+{
+    /**
+     * @brief Default constructor for the @ref FaceRecognitionResults
+     *
+     * @since_tizen 3.0
+     */
+    FaceRecognitionResults();
+
+    bool mIsRecognized;               /**< The flag indication success of the
+                                           recognition */
+    cv::Rect_<int> mFaceLocation;     /**< Location of the face where face has
+                                           been recognized */
+    int mFaceLabel;                   /**< Unique label of the face */
+    double mConfidence;               /**< Recognition confidence level */
+};
+
+/**
+ * @class FaceRecognitionModel
+ * @brief Class providing interface for management of face recognition model.
+ *
+ * @since_tizen 3.0
+ */
+class FaceRecognitionModel
+{
+public:
+
+    /**
+     * @brief    Creates a FaceRecognitionModel class instance.
+     *
+     * @since_tizen 3.0
+     */
+    FaceRecognitionModel();
+
+    /**
+     * @brief    Creates a FaceRecognitionModel class instance based on existed
+     *           instance.
+     *
+     * @since_tizen 3.0
+     * @param [in] origin    The FaceRecognitionModel object that will be used
+     *                       for creation of new one
+     */
+    FaceRecognitionModel(const FaceRecognitionModel& origin);
+
+    /**
+     * @brief @ref FaceRecognitionModel copy assignment operator.
+     * @details Fills the information based on the @a copy
+     *
+     * @since_tizen 3.0
+     * @param [in] copy      @ref FaceRecognitionModel object which will be
+     *                       copied
+     */
+    FaceRecognitionModel& operator=(const FaceRecognitionModel& copy);
+
+    /**
+     * @brief    Destroys the FaceRecognitionModel class instance including all
+     *           its resources.
+     *
+     * @since_tizen 3.0
+     */
+    ~FaceRecognitionModel();
+
+    /**
+     * @brief Serializes FaceRecognitionModel object to the file.
+     *
+     * @since_tizen 3.0
+     * @param [in] fileName    The name of the file to which serialized
+     *                         FaceRecognitionModel object will be saved
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceRecognitionModel::load()
+     */
+    int save(const std::string& fileName);
+
+    /**
+     * @brief Deserializes FaceRecognitionModel object from the file.
+     *
+     * @since_tizen 3.0
+     * @param [in] fileName    The name to the file from which serialized
+     *                         FaceRecognitionModel object will be deserialized
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceRecognitionModel::save()
+     */
+    int load(const std::string& fileName);
+
+    /**
+     * @brief Adds face image example for face labeled by @a faceLabel
+     *
+     * @since_tizen 3.0
+     * @param [in] faceImage    Face image to be added to the training set
+     * @param [in] faceLabel    Label that defines class of the face
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceRecognitionModel::resetFaceExamples()
+     */
+    int addFaceExample(const cv::Mat& faceImage, int faceLabel);
+
+    /**
+     * @brief Clears the internal set of face image examples.
+     *
+     * @since_tizen 3.0
+     * @remarks Internal set of face image examples contains all samples
+     *          collected with @ref FaceRecognitionModel::addPositiveExample()
+     *          method.
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceRecognitionModel::addFaceExample()
+     */
+    int resetFaceExamples(void);
+
+    /**
+     * @brief Clears the internal set of face image examples labeled with
+     *        @a faceLabel.
+     *
+     * @since_tizen 3.0
+     * @remarks Internal set of face image examples contains all samples
+     *          collected with @ref FaceRecognitionModel::addPositiveExample()
+     *          method.
+     * @param faceLabel Unique for the model face label
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceRecognitionModel::addFaceExample()
+     */
+    int resetFaceExamples(int faceLabel);
+
+    /**
+     * @brief Getter for the face labels learned by the model.
+     *
+     * @since_tizen 3.0
+     * @remarks Returning vector will contain only labels had been learned by
+     *          FaceRecognitionModel::learn() method.
+     * @return Vector of the face labels known by the model
+     *
+     * @see FaceRecognitionModel::addFaceExample()
+     * @see FaceRecognitionModel::learn()
+     */
+    const std::set<int>& getFaceLabels(void) const;
+
+    /**
+     * @brief Learns recognition model based on the set of collected face image
+     *        examples.
+     *
+     * @since_tizen 3.0
+     * @param [in] config    Configuration of the algorithm to be used for
+     *                       learning the model
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceRecognitionModel::addFaceExample()
+     */
+    int learn(const FaceRecognitionModelConfig& config = FaceRecognitionModelConfig());
+
+    /**
+     * @brief Recognizes faces in the image and outputs recognition results to
+     *        the @a results structure.
+     *
+     * @since_tizen 3.0
+     * @param [in] config      Configuration of the algorithm to be used for
+     *                         face recognition
+     * @param [out] results    Structure that will contain recognition results
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceRecognitionModel::learn()
+     */
+    int recognize(const cv::Mat& image, FaceRecognitionResults& results);
+
+private:
+
+    /**
+     * Factory method for creating of the recognition algorithm based on input
+     * configuration:
+     */
+    static cv::Ptr<cv::FaceRecognizer> CreateRecognitionAlgorithm(
+            const FaceRecognitionModelConfig& config =
+                    FaceRecognitionModelConfig());
+
+private:
+
+    bool m_canRecognize; /**< The flag showing possibility to recognize with
+                              the face recognition model */
+
+    std::map<int, std::vector<cv::Mat> > m_faceSamples; /**< Samples of the
+                                                             images which
+                                                             will be used for
+                                                             the learning */
+
+    FaceRecognitionModelConfig m_learnAlgorithmConfig; /**< Configuration of the
+                                                            learning method */
+
+    cv::Ptr<cv::FaceRecognizer> m_recognizer; /**< Recognizer associated with
+                                                   the current model */
+
+    std::set<int> m_learnedLabels; /**< Vector of the labels had been learned
+                                           by the model */
+};
+
+} /* Face */
+} /* MediaVision */
+
+#endif /* __FACERECOGNITIONMODEL_H__ */
diff --git a/mv_face/face/include/FaceTrackingModel.h b/mv_face/face/include/FaceTrackingModel.h
new file mode 100644 (file)
index 0000000..daa56c7
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACETRACKINGMODEL_H__
+#define __FACETRACKINGMODEL_H__
+
+#include "TrackerMedianFlow.h"
+
+/**
+ * @file FaceTrackingModel.h
+ * @brief This file contains the FaceTrackingModel class definition which
+ *        provides face tracking model interface.
+ */
+
+namespace MediaVision
+{
+namespace Face
+{
+
+/**
+ * @brief Structure where results of
+ *        @ref MediaVision::Face::FaceTrackingModel::track() call are stored.
+ *
+ * @since_tizen 3.0
+ */
+struct FaceTrackingResults
+{
+    /**
+     * @brief Default constructor for the @ref FaceTrackingResults
+     *
+     * @since_tizen 3.0
+     */
+    FaceTrackingResults();
+
+    bool mIsTracked;                  /**< The flag indication success of the
+                                           tracking */
+    cv::Rect_<float> mFaceLocation;   /**< Location of the face at the current
+                                           track iteration where face position
+                                           is predicted */
+    float mConfidence;                /**< Tracking confidence level
+                                           (0.0 .. 1.0) */
+};
+
+/**
+ * @class FaceTrackingModel
+ * @brief Class providing interface for management of face tracking model.
+ *
+ * @since_tizen 3.0
+ */
+class FaceTrackingModel
+{
+public:
+    /**
+     * @brief    Creates a FaceTrackingModel class instance.
+     *
+     * @since_tizen 3.0
+     */
+    FaceTrackingModel();
+
+    /**
+     * @brief    Creates a FaceTrackingModel class instance based on existed
+     *           instance.
+     *
+     * @since_tizen 3.0
+     * @param [in] origin    The FaceTrackingModel object that will be used
+     *                       for creation of new one
+     */
+    FaceTrackingModel(const FaceTrackingModel& origin);
+
+    /**
+     * @brief @ref FaceTrackingModel copy assignment operator.
+     * @details Fills the information based on the @a copy
+     *
+     * @since_tizen 3.0
+     * @param [in] copy      @ref FaceTrackingModel object which will be
+     *                       copied
+     */
+    FaceTrackingModel& operator=(const FaceTrackingModel& copy);
+
+    /**
+     * @brief    Destroys the FaceTrackingModel class instance including all
+     *           its resources.
+     *
+     * @since_tizen 3.0
+     */
+    ~FaceTrackingModel();
+
+    /**
+     * @brief Serializes FaceTrackingModel object to the file.
+     *
+     * @since_tizen 3.0
+     * @param [in] fileName    The name to the file to which serialized
+     *                         FaceTrackingModel object will be saved
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceTrackingModel::load()
+     */
+    int save(const std::string& fileName);
+
+    /**
+     * @brief Deserializes FaceTrackingModel object from the file.
+     *
+     * @since_tizen 3.0
+     * @param [in] fileName    The name of the file from which serialized
+     *                         FaceTrackingModel object will be deserialized
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceTrackingModel::save()
+     */
+    int load(const std::string& fileName);
+
+    /**
+     * @brief Prepares FaceTrackingModel object to the next tracking session.
+     *
+     * @since_tizen 3.0
+     * @param [in] image          First frame of the video or image sequence for
+     *                            which tracking will be started
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceTrackingModel::save()
+     */
+    int prepare(const cv::Mat& image);
+
+    /**
+     * @brief Prepares FaceTrackingModel object to the next tracking session.
+     *
+     * @since_tizen 3.0
+     * @param [in] image          First frame of the video or image sequence for
+     *                            which tracking will be started
+     * @param [in] boundingBox    Rectangular location of the face on the @a
+     *                            image
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see FaceTrackingModel::save()
+     */
+    int prepare(const cv::Mat& image, const cv::Rect_<float>& boundingBox);
+
+    /**
+     * @brief Performs one tracking iteration for the video frame or image
+     *        from the continuous sequence of images.
+     *
+     * @since_tizen 3.0
+     * @param [in]  image
+     * @param [out] boundingBox
+     */
+    int track(const cv::Mat& image, FaceTrackingResults& results);
+
+private:
+
+    bool m_canTrack;                          /**< The flag showing possibility
+                                                   of the tracking model to
+                                                   perform track */
+
+    cv::Ptr<cv::TrackerMedianFlow> m_tracker; /**< Underlying OpenCV tracking
+                                                   model */
+
+};
+
+} /* Face */
+} /* MediaVision */
+
+#endif /* __FACETRACKINGMODEL_H__ */
diff --git a/mv_face/face/include/FaceUtil.h b/mv_face/face/include/FaceUtil.h
new file mode 100644 (file)
index 0000000..d79757d
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACEUTIL_H__
+#define __FACEUTIL_H__
+
+#include <opencv/cv.h>
+
+#include "mv_common_c.h"
+
+/**
+ * @file FaceUtil.h
+ * @brief This file contains the useful functionality for Face module.
+ */
+namespace MediaVision
+{
+namespace Face
+{
+
+/**
+ * @brief Enumeration of supported learning algorithms.
+ *
+ * @since_tizen 3.0
+ */
+enum FaceRecognitionModelType
+{
+    MEDIA_VISION_FACE_MODEL_TYPE_UNKNOWN = 0,     /**< Unknown algorithm type */
+    MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES = 1,  /**< Eigenfaces algorithm */
+    MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES = 2, /**< Fisherfaces algorithm */
+    MEDIA_VISION_FACE_MODEL_TYPE_LBPH = 3         /**< Local Binary Patterns
+                                                       Histograms algorithm */
+};
+
+/**
+ * @brief Contains parameters for face recognition.
+ *
+ * @since_tizen 3.0
+ */
+struct RecognitionParams
+{
+    RecognitionParams(FaceRecognitionModelType algType);
+
+    RecognitionParams();
+
+    FaceRecognitionModelType mRecognitionAlgType;
+                                 /**< The type of the learning algorithm. */
+};
+
+/**
+ * @brief Converts mv_source_h to cv::Mat class with grayscale type.
+ *
+ * @since_tizen 3.0
+ * @param [in] mvSource    The handle to the image from Media Vision API.
+ * @param [out] cvSource   The cv::Mat class, which will be filled.
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int convertSourceMV2GrayCV(mv_source_h mvSource, cv::Mat& cvSource);
+
+} /* Face */
+} /* MediaVision */
+
+#endif /* __FACEUTIL_H__ */
diff --git a/mv_face/face/include/TrackerMedianFlow.h b/mv_face/face/include/TrackerMedianFlow.h
new file mode 100644 (file)
index 0000000..7112a14
--- /dev/null
@@ -0,0 +1,155 @@
+/*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) 2013, OpenCV Foundation, all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // Redistribution and use in source and binary forms, with or without modification,
+ // are permitted provided that the following conditions are met:
+ //
+ //   * Redistribution's of source code must retain the above copyright notice,
+ //     this list of conditions and the following disclaimer.
+ //
+ //   * Redistribution's in binary form must reproduce the above copyright notice,
+ //     this list of conditions and the following disclaimer in the documentation
+ //     and/or other materials provided with the distribution.
+ //
+ //   * The name of the copyright holders may not be used to endorse or promote products
+ //     derived from this software without specific prior written permission.
+ //
+ // This software is provided by the copyright holders and contributors "as is" and
+ // any express or implied warranties, including, but not limited to, the implied
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
+ // indirect, incidental, special, exemplary, or consequential damages
+ // (including, but not limited to, procurement of substitute goods or services;
+ // loss of use, data, or profits; or business interruption) however caused
+ // and on any theory of liability, whether in contract, strict liability,
+ // or tort (including negligence or otherwise) arising in any way out of
+ // the use of this software, even if advised of the possibility of such damage.
+ //
+ //M*/
+
+#ifndef __TRACKERMEDIANFLOW_H__
+#define __TRACKERMEDIANFLOW_H__
+
+#include "opencv2/core/core.hpp"
+
+namespace cv
+{
+
+class TrackerMedianFlowModel;
+
+/** @brief Median Flow tracker implementation.
+
+Implementation of a paper @cite MedianFlow .
+
+The tracker is suitable for very smooth and predictable movements when object is visible throughout
+the whole sequence. It's quite and accurate for this type of problems (in particular, it was shown
+by authors to outperform MIL). During the implementation period the code at
+<http://www.aonsquared.co.uk/node/5>, the courtesy of the author Arthur Amarra, was used for the
+reference purpose.
+ */
+class TrackerMedianFlow : public virtual Algorithm
+{
+public:
+
+    struct Params
+    {
+        /**
+         * @brief TrackerMedianFlow algorithm parameters constructor
+         */
+        Params();
+        void read(const FileNode& fn);
+        void write(FileStorage& fs) const;
+
+        int mPointsInGrid; /**< Square root of number of keypoints used.
+                                Increase it to trade accurateness for speed.
+                                Default value is sensible and recommended */
+
+        Size mWindowSize; /**< Size of the search window at each pyramid level
+                               for Lucas-Kanade optical flow search used for
+                               tracking */
+
+        int mPyrMaxLevel; /**< Number of pyramid levels for Lucas-Kanade optical
+                               flow search used for tracking */
+    };
+
+    TrackerMedianFlow(Params paramsIn = Params());
+
+    bool copyTo(TrackerMedianFlow& copy) const;
+
+    bool init(const Mat& image, const Rect_<float>& boundingBox);
+    bool update(const Mat& image, Rect_<float>& boundingBox);
+
+    bool isInited() const;
+
+    float getLastConfidence() const;
+    Rect_<float> getLastBoundingBox() const;
+
+    void read(FileStorage& fn);
+    void write(FileStorage& fs) const;
+
+private:
+
+    bool isInit;
+
+    bool medianFlowImpl(Mat oldImage, Mat newImage, Rect_<float>& oldBox);
+
+    Rect_<float> vote(
+            const std::vector<Point2f>& oldPoints,
+            const std::vector<Point2f>& newPoints,
+            const Rect_<float>& oldRect,
+            Point2f& mD);
+
+    template<typename T>
+    T getMedian(
+            std::vector<T>& values, int size = -1);
+
+    void check_FB(
+            std::vector<Mat> newPyramid,
+            const std::vector<Point2f>& oldPoints,
+            const std::vector<Point2f>& newPoints,
+            std::vector<bool>& status);
+
+    void check_NCC(
+            const Mat& oldImage,
+            const Mat& newImage,
+            const std::vector<Point2f>& oldPoints,
+            const std::vector<Point2f>& newPoints,
+            std::vector<bool>& status);
+
+    inline float l2distance(Point2f p1, Point2f p2);
+
+    Params params;               /**< Parameters used during tracking, see
+                                      @ref TrackerMedianFlow::Params */
+
+    TermCriteria termcrit;       /**< Terminating criteria for OpenCV
+                                      Lucas–Kanade optical flow algorithm used
+                                      during tracking */
+
+    Rect_<float> m_boundingBox;  /**< Tracking object bounding box */
+
+    float m_confidence;          /**< Confidence that face was tracked correctly
+                                      at the last tracking iteration */
+
+    Mat m_image;                 /**< Last image for which tracking was
+                                      performed */
+
+    std::vector<Mat> m_pyramid;  /**< The pyramid had been calculated for
+                                      the previous frame (or when
+                                      initialize the model) */
+};
+
+} /* namespace cv */
+
+#endif /* __TRACKERMEDIANFLOW_H__ */
diff --git a/mv_face/face/include/mv_face_open.h b/mv_face/face/include/mv_face_open.h
new file mode 100644 (file)
index 0000000..a127d5a
--- /dev/null
@@ -0,0 +1,791 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_FACE_OPEN_H__
+#define __TIZEN_MEDIAVISION_FACE_OPEN_H__
+
+#include "mv_face.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_face_open.h
+ * @brief  This file contains the Media Vision Face Open API.
+ */
+
+/******************/
+/* Face detection */
+/******************/
+
+/**
+ * @brief Performs face detection on the @a source for the @a engine_conf.
+ * @details Use this function to launch face detection algorithm configured by
+ *          @a engine_conf configuration. Each time when mv_face_detect_open is
+ *          called, @a detected_cb will receive a set of the detected
+ *          faces at the media source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source         The handle to the source of the media where faces
+ *                            will be detected
+ * @param [in] engine_cfg     The handle to the configuration of engine will be
+ *                            used for detecting. If NULL, then default settings
+ *                            will be used.
+ * @param [in] detected_cb    The callback which will be called for all face
+ *                            locations detected on media source. This callback
+ *                            will receive detecting results
+ * @param [in] user_data      The user data passed from the code where
+ *                            @ref mv_face_detect_open() is invoked. This data will be
+ *                            accessible from @a detected_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @post @a detected_cb will be called to process detection results
+ *
+ * @see mv_face_detected_cb
+ */
+int mv_face_detect_open(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_face_detected_cb detected_cb,
+        void *user_data);
+
+
+/********************/
+/* Face recognition */
+/********************/
+
+/**
+ * @brief Performs face recognition on the @a source image.
+ * @details Use this function to launch face recognition algorithm configured by
+ *          @a engine_conf configuration using @a recognition_model recognition
+ *          model. Each time when @ref mv_face_recognize_open() is called,
+ *          @a recognized_cb will receive recognition results:\n
+ *          - Location in the @a source of the face has been recognized;
+ *          - Label of the face has been recognized;
+ *          - Confidence of the @a recognition_model that face has been
+ *            recognized correctly (value from 0.0 to 1.0).
+ *
+ * @since_tizen 3.0
+ * @remarks Using of untrained or weakly trained recognition models will cause
+ *          not accurate results even if resulting confidence will be high.
+ *          Use @ref mv_face_recognition_model_learn_open() function before
+ *          @ref mv_face_recognize_open() call. Best results can be achieved
+ *          when big set of face image examples were added by
+ *          @ref mv_face_recognition_model_add_open() before
+ *          @ref mv_face_recognition_model_learn_open() call.
+ * @param [in] source              The handle to the source of the media to
+ *                                 recognize face(s) for
+ * @param [in] recognition_model   The handle to the model will be used for
+ *                                 recognition
+ * @param [in] engine_cfg          The handle to the configuration of engine
+ *                                 will be used for recognition. If NULL, then
+ *                                 default settings will be used
+ * @param [in] face_location       Rectangular box bounding face image on the
+ *                                 @a source. If NULL, then full source will be
+ *                                 analyzed
+ * @param [in] recognized_cb       The callback which will be called for the
+ *                                 face recognition results on the @a source.
+ * @param [in] user_data           The user data passed from the code where
+ *                                 @ref mv_face_recognize_open() is invoked.
+ *                                 This data will be accessible from
+ *                                 @a recognized_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create a face recognition model handle by calling
+ *      @ref mv_face_recognition_model_create_open()
+ * @post @a recognized_cb will be called to process recognition results
+ *
+ * @see mv_face_recognized_cb
+ */
+int mv_face_recognize_open(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        mv_face_recognized_cb recognized_cb,
+        void *user_data);
+
+
+/*****************/
+/* Face tracking */
+/*****************/
+
+/**
+ * @brief Performs face tracking on the @a source for the @a tracking_model.
+ * @details Use this function to launch face tracking algorithm configured by
+ *          @a engine_conf configuration using @a tracking_model tracking
+ *          model. Each time when this function is called, @a tracked_cb
+ *          will receive updated @a tracking_model, new location determined for
+ *          the tracked face and model confidence that location is determined
+ *          correctly.
+ *
+ * @since_tizen 3.0
+ * @remarks To allow correct tracking @a tracking_model has to be already used
+ *          in previous tracking process(es) or prepared with
+ *          @ref mv_face_tracking_model_prepare_open(). Preparation requires
+ *          specifying the face location for the @a source on which tracking was
+ *          started. I.e. @ref mv_face_tracking_model_prepare_open() function
+ *          has to be called at least once before this method call.
+ * @param [in] source           The handle to the source of the media to
+ *                              recognize face for
+ * @param [in] tracking_model   The handle to the model will be used for
+ *                              tracking
+ * @param [in] engine_cfg       The handle to the configuration of engine will
+ *                              be used for tracking. If NULL, the default
+ *                              configuration will be used.
+ * @param [in] tracked_cb       The callback which will be called for tracking
+ *                              event on the @a source where face would be
+ *                              tracked. This callback will receive tracking
+ *                              results
+ * @param [in] do_learn         The model learning flag. If it is set @c true
+ *                              then model will try to learn (if it supports
+ *                              learning feature), otherwise model will be not
+ *                              learned during the invoking tracking iteration.
+ *                              Learning process improves tracking correctness,
+ *                              but can decrease tracking performance
+ * @param [in] user_data        The user data passed from the code where
+ *                              @ref mv_face_track_open() is invoked. This data
+ *                              will be accessible from @a tracked_cb callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create a face tracking model handle by calling
+ *      @ref mv_face_tracking_model_create_open()
+ * @post @a tracked_cb will be called to process tracking results
+ *
+ * @see mv_face_tracked_cb
+ */
+int mv_face_track_open(
+        mv_source_h source,
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_face_tracked_cb tracked_cb,
+        bool do_learn,
+        void *user_data);
+
+
+/********************************/
+/* Recognition of eye condition */
+/********************************/
+
+/**
+ * @brief Determines eye-blink condition for @a face_location on media @a source.
+ * @details Use this function to recognize eye-blink condition for the face
+ *          bounded by @a face_location at @a source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source           The handle to the source of the media to
+ *                              recognize eye-blink condition for
+ * @param [in] engine_cfg       The handle to the configuration of engine
+ *                              will be used for eye-blink condition
+ *                              recognition. If NULL, the default configuration
+ *                              will be used.
+ * @param [in] face_location    The location bounding the face at the @a source
+ * @param [in] eye_condition_recognized_cb    The callback for processing result
+ *                              of eye-blink condition recognition
+ * @param [in] user_data        The user data passed from the code where
+ *                              @ref mv_face_eye_condition_recognize_open() is
+ *                              invoked. This data will be accessible from
+ *                              @a eye_condition_recognized_cb callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source_open()
+ *
+ * @see mv_face_eye_condition_recognized_cb
+ */
+int mv_face_eye_condition_recognize_open(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_eye_condition_recognized_cb eye_condition_recognized_cb,
+        void *user_data);
+
+
+/************************************/
+/* Recognition of facial expression */
+/************************************/
+
+/**
+ * @brief Determines facial expression for @a face_location on media @a source.
+ * @details Use this function to determine facial expression for the face
+ *          bounded by @a face_location at @a source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source           The handle to the source of the media
+ *                              to recognize facial expression for
+ * @param [in] engine_cfg       The handle to the configuration of
+ *                              engine will be used for expression recognition
+ * @param [in] face_location    The location bounding the face at the @a source
+ * @param [in] expression_recognized_cb   The callback for processing result
+ *                              of facial expression determining
+ * @param [in] user_data        The user data passed from the code where
+ *                              @ref mv_face_facial_expression_recognize_open() is
+ *                              invoked. This data will be accessible from
+ *                              @a expression_recognized_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source_open()
+ * @pre Create a face engine configuration handle by calling @ref mv_create_engine_config()
+ *
+ * @see mv_face_facial_expression_recognized_cb
+ */
+int mv_face_facial_expression_recognize_open(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_facial_expression_recognized_cb expression_recognized_cb,
+        void *user_data);
+
+/*******************************/
+/* Recognition model behavior */
+/*******************************/
+
+/**
+ * @brief Creates a face recognition model handle.
+ * @details Use this function to create default face recognition model. Creating
+ *          process is defined by concrete face engine library. After creation
+ *          recognition model has to be learned with
+ *          @ref mv_face_recognition_model_learn_open() function to provide
+ *          appropriate results of face recognition functionality. Or learned
+ *          earlier model can be loaded by
+ *          @ref mv_face_recognition_model_load_open() function.
+ *
+ * @since_tizen 3.0
+ * @remarks It can cause incompatibility issues when saved models (see
+ *          @ref mv_face_recognition_model_save_open(),
+ *          @ref mv_face_recognition_model_load_open() functions documentation)
+ *          are used in applications for different platforms which use different
+ *          computer vision libraries underlying this API.
+ * @remarks You must release @a recognition_model by using
+ *          @ref mv_face_recognition_model_destroy_open() function.
+ * @param [out] recognition_model    The handle to the recognition model to be
+ *                                   created
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see mv_face_recognition_model_destroy_open()
+ */
+int mv_face_recognition_model_create_open(
+        mv_face_recognition_model_h *recognition_model);
+
+/**
+ * @brief Destroys the face recognition model handle and releases all its
+ *        resources.
+ *
+ * @since_tizen 3.0
+ * @param [in] recognition_model    The handle to the face recognition model to
+ *                                  be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_face_recognition_model_create_open()
+ */
+int mv_face_recognition_model_destroy_open(
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Creates a copy of existed recognition model handle and clones all its
+ *        resources.
+ *
+ * @since_tizen 3.0
+ * @remarks Cloning perform not only handle copy, but also copies all internal
+ *          resources of the model. @a dst must be released using
+ *          @a mv_face_recognition_model_destroy_open().
+ * @param [in]     src    The handle to the recognition model to be copied
+ * @param [out]    dst    The handle to the copy of existed recognition model
+ *                        specified as @a src
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Create face recognition handles by calling
+ *      @ref mv_face_recognition_model_create_open()
+ *
+ * @see mv_face_recognition_model_create_open()
+ */
+int mv_face_recognition_model_clone_open(
+        mv_face_recognition_model_h src,
+        mv_face_recognition_model_h *dst);
+
+/**
+ * @brief Saves recognition model to the file.
+ *
+ * @since_tizen 3.0
+ * @remarks This function doesn't save added by
+ *          @ref mv_face_recognition_model_add_open() function face
+ *          image examples. This examples can be removed by
+ *          @ref mv_face_recognition_model_reset_open() function
+ *          if it is needed to clear the memory.
+ * @remarks After model is saved to the file, it can be loaded from this file
+ *          by @ref mv_face_recognition_model_load_open() function.
+ * @param [in] file_name            Name of the file to save the model
+ * @param [in] recognition_model    The handle to the recognition model to be
+ *                                  saved to the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a face recognition handle by calling
+ *      @ref mv_face_recognition_model_create_open() function
+ * @post Saved model can be loaded later by calling
+ *      @ref mv_face_recognition_model_load_open() function
+ *
+ * @see mv_face_recognition_model_load_open()
+ * @see mv_face_recognition_model_create_open()
+ */
+int mv_face_recognition_model_save_open(
+        const char *file_name,
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Loads recognition model from file.
+ *
+ * @since_tizen 3.0
+ * @remarks This function doesn't modify the set of face image examples added
+ *          with @ref mv_face_recognition_model_add_open() function.
+ *          Model will be loaded from file without loss of collected examples.
+ *          If you want to free memory from examples, use
+ *          @ref mv_face_recognition_model_reset_open() function.
+ *          It is recommended to clear the memory if learning algorithm doesn't
+ *          support reinforcement learning.
+ * @remarks Recognition models can be load from files saved with
+ *          mv_face_recognition_model_save_open() function.
+ * @remarks Recognition model must be destroyed using
+ *          @ref mv_face_recognition_model_destroy.
+ * @param [in]  file_name            Name of the file to load the model from
+ * @param [out] recognition_model    The handle to the recognition model
+ *                                      to be loaded from the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see mv_face_recognition_model_save_open()
+ * @see mv_face_recognition_model_destroy_open()
+ */
+int mv_face_recognition_model_load_open(
+        const char *file_name,
+        mv_face_recognition_model_h *recognition_model);
+
+/**
+ * @brief Adds face image example to be used for face recognition model learning
+ *        with @ref mv_face_recognition_model_learn_open().
+ *
+ * @since_tizen 3.0
+ * @remarks It is possible to destroy @a source after calling this method.
+ *          Source isn't used for learning directly.
+ * @remarks Face image @a example_location location can be determined using
+ *          @ref mv_face_detect_open() function.
+ * @param [in] source               The handle to @a source that contains face
+ *                                  image
+ * @param [in] recognition_model    The handle to the recognition model which
+ *                                  could be learned based on example
+ * @param [in] example_location     The pointer to the rectangular location of
+ *                                  the face image at the source image. If NULL,
+ *                                  then full image will be analyzed as the face
+ *                                  image
+ * @param [in] face_label           The label that identifies face for which
+ *                                  example is adding. Specify the same labels
+ *                                  for the face images of a single person when
+ *                                  calling this method. Can't be NULL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create a face recognition handle by calling
+ *      @ref mv_face_recognition_model_create_open() function
+ * @post When appropriate amount of face image examples is added to the
+ *       @a recognition_model, this model has to be learned by
+ *       @ref mv_face_recognition_model_learn_open() function call. Only after
+ *       learning of the model it can be used for face recognition with
+ *       @a mv_face_recognize_open() function
+ *
+ * @see mv_face_recognition_model_reset_open()
+ * @see mv_face_recognition_model_learn_open()
+ */
+int mv_face_recognition_model_add_open(
+        const mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        const mv_rectangle_s *example_location,
+        int face_label);
+
+/**
+ * @brief Remove from @a recognition_model all collected with
+ *        @ref mv_face_recognition_model_add_open() function
+ *        face examples labeled with @a face_label.
+ *
+ * @since_tizen 3.0
+ * @remarks Be aware that if this function is called before
+ *          @ref mv_face_recognition_model_learn_open() function call, all or
+ *          part of the required for learning data will be lost. It means that
+ *          face image examples determined by the @a face_label label will be
+ *          removed from the model and not taken taken into account when
+ *          @ref mv_face_recognition_model_learn_open() will be called next
+ *          time.
+ * @remarks Call of this function will free all the memory has been allocated
+ *          during previous
+ *          @ref mv_face_recognition_model_add_open() calls for
+ *          the corresponding @a face_label label.
+ * @param [in] recognition_model    The handle to the recognition model for
+ *                                  which face image examples will be reset.
+ * @param [in] face_label           The label that identifies face for which
+ *                                  examples will be removed from the
+ *                                  @a recognition_model. If NULL, then all
+ *                                  known by @a recognition_model face image
+ *                                  examples will be removed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE Key not available
+ *
+ * @see mv_face_recognition_model_add_open()
+ * @see mv_face_recognition_model_learn_open()
+ */
+int mv_face_recognition_model_reset_open(
+        mv_face_recognition_model_h recognition_model,
+        const int *face_label);
+
+/**
+ * @brief Learns face recognition model.
+ * @details Before you start learning process, face recognition models has to be
+ *          filled with training data - face image examples. These examples has
+ *          to be provided by
+ *          mv_face_recognition_model_add_open() function. Usually,
+ *          recognition accuracy is increased when number of not identical
+ *          examples is large. But it depends of the used learning algorithm.
+ *
+ * @since_tizen 3.0
+ * @remarks Common flow is to collect face examples as much as possible, add
+ *          them to the recognition model with
+ *          @ref mv_face_recognition_model_add_open(), then call
+ *          @ref mv_face_recognition_model_learn_open() for this recognition
+ *          model to learn it (or reinforce the model if reinforcement learning
+ *          is supported by the used algorithm).
+ * @remarks Selection of the learning algorithm can be performed by setting
+ *          corresponding attributes for the @a engine_cfg. You can check
+ *          supported by @a engine_cfg attributes using
+ *          @ref mv_engine_config_foreach_supported_attribute() function call.
+ * @param [in]     engine_cfg           The handle to the configuration of
+ *                                      engine will be used for learning of the
+ *                                      recognition models. If NULL, then
+ *                                      default settings will be used
+ * @param [in,out] recognition_model    The model which will be learned. After
+ *                                      learning process these model may be
+ *                                      changed, so
+ *                                      @ref mv_face_recognize_open() results
+ *                                      may differ before and after method call
+ *                                      respectively to the face examples
+ *                                      collected for the @a recognition_model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_NO_DATA No data
+ *
+ * @pre Create a face engine configuration handle by calling
+ *      @ref mv_create_engine_config() and set supported parameters if
+ *      needed. Or just set @a engine_cfg as NULL to learn with default settings
+ * @pre Create a face recognition model handles by calling
+ *      @ref mv_face_recognition_model_create_open() function
+ * @pre Add face image examples to the @a recognition_model by calling
+ *      @ref mv_face_recognition_model_add_open() function
+ * @post If it is not planned to learn the model again, clear memory by
+ *       @ref mv_face_recognition_model_reset_open() function
+ * @post When model has been learned, it can be used for face recognition with
+ *       @ref mv_face_recognize_open() function
+ *
+ * @see mv_face_recognition_model_add_open()
+ * @see mv_face_recognition_model_reset_open()
+ * @see mv_face_recognize_open()
+ */
+int mv_face_recognition_model_learn_open(
+        mv_engine_config_h engine_cfg,
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Queries labels list and number of labels had been learned by the model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a labels array has to be released using free().
+ * @param [in]  recognition_model    The handle to the recognition model for
+ *                                   which set of the learned labels will be
+ *                                   queried
+ * @param [out] labels               The array which will be filled with labels
+ *                                   had been learned by the model
+ * @param [out] number_of_labels     The number of labels in @a labels array
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Add face image examples with labels to the @a recognition_model by
+ *      calling the @ref mv_face_recognition_model_add_open()
+ *      function
+ * @pre Learn the @a recognition_model by labeled examples using
+ *      @ref mv_face_recognition_model_learn_open() function
+ * @post @a labels array has to be freed in the function invoking code
+ *
+ * @see mv_face_recognition_model_add_open()
+ * @see mv_face_recognition_model_reset_open()
+ * @see mv_face_recognition_model_learn_open()
+ */
+int mv_face_recognition_model_query_labels_open(
+        mv_face_recognition_model_h recognition_model,
+        int **labels,
+        unsigned int *number_of_labels);
+
+/***************************/
+/* Tracking model behavior */
+/***************************/
+
+/**
+ * @brief Call this function to create a face tracking model handle.
+ * @details Use this function to create default face tracking model handle.
+ *          After creation this handle has to be initialized with
+ *          @ref mv_face_tracking_model_prepare_open() function to provide
+ *          appropriate results of face tracking functionality. When handle is
+ *          prepared, it is possible to use it for tracking on continuous
+ *          sequence of the sources. Call
+ *          @ref mv_face_tracking_model_prepare_open() function each time before
+ *          starting tracking on the new sequence. The exception is situation
+ *          when the new sequence is continuation of the previous sequence for
+ *          which model has been tracked.
+ *
+ * @since_tizen 3.0
+ * @param [out] tracking_model    The pointer to the handle to the tracking
+ *                                model that will be created
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post Model can be loaded from the file after creation. Use
+ *       @ref mv_face_tracking_model_load_open() function to load it from file
+ * @post Use @ref mv_face_tracking_model_prepare_open() function before tracking
+ *       on the new video or continuous images sequence
+ * @post You must release @a tracking_model by using
+ *       mv_face_tracking_model_destroy_open() function when it is not needed
+ *       anymore
+ *
+ * @see mv_face_tracking_model_destroy_open()
+ * @see mv_face_tracking_model_prepare_open()
+ * @see mv_face_tracking_model_load_open()
+ */
+int mv_face_tracking_model_create_open(
+        mv_face_tracking_model_h *tracking_model);
+
+/**
+ * @brief Call this function to destroy the face tracking model handle and
+ *        release all its resources.
+ *
+ * @since_tizen 3.0
+ * @param [in] tracking_model    The handle to the face tracking model that
+ *                               will be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_face_tracking_model_create_open()
+ */
+int mv_face_tracking_model_destroy_open(
+        mv_face_tracking_model_h tracking_model);
+
+/**
+ * @brief Call this function to initialize tracking model by the location of the
+ *        face to be tracked.
+ * @details This function is usually called once after tracking model is created
+ *          and each time before tracking is started for the new sequence of
+ *          sources which is not the direct continuation of the sequence for
+ *          which tracking has been performed before. But it is allowed to call
+ *          it between tracking sessions to allow Media Vision start to track
+ *          more accurately.
+ *
+ * @since_tizen 3.0
+ * @param [in] tracking_model    The handle to the tracking model that will be
+ *                               prepared for tracking on new video or image
+ *                               sequence
+ * @param [in] engine_cfg        The handle to the configuration of engine
+ *                               will be used for model preparing. If NULL, then
+ *                               default settings will be used.
+ * @param [in] source            The handle to the source where face @a location
+ *                               is specified. Usually it is the first frame of
+ *                               the video or the first image in the continuous
+ *                               image sequence planned to be used for tracking
+ * @param [in] location          The quadrangle-shaped location (actually,
+ *                               rectangle can be used) determining position
+ *                               of the face to be tracked on the @a source. If
+ *                               @c NULL, then last location determined by the
+ *                               tracking model for the tracked face will be
+ *                               used for preparation
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face tracking model handle by calling
+ *      @ref mv_face_tracking_model_create_open() function
+ * @pre Create a source handle by calling @ref mv_create_source() function
+ * @post When model is prepared, @ref mv_face_track_open() function can be used
+ *       to track on the video or continuous image sequence
+ *
+ * @see mv_face_tracking_model_create_open()
+ * @see mv_face_track_open()
+ */
+int mv_face_tracking_model_prepare_open(
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_quadrangle_s */*location*/);
+
+/**
+ * @brief Call this function to make a copy of existed tracking model handle and
+ *        clone all its resources to the copy.
+ *
+ * @since_tizen 3.0
+ * @remarks Cloning performs not only handle copy, but also copies all internal
+ *          resources of the model. @a dst must be released using
+ *          mv_face_tracking_model_destroy_open().
+ * @param [in]     src    The handle to the tracking model to be copied
+ * @param [out] dst    The handle to the copy of existed tracking model
+ *                        specified as @a src
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create face tracking @a src handle by calling
+ *      @ref mv_face_tracking_model_create_open()
+ *
+ * @see mv_face_tracking_model_create_open()
+ */
+int mv_face_tracking_model_clone_open(
+        mv_face_tracking_model_h src,
+        mv_face_tracking_model_h *dst);
+
+/**
+ * @brief Call this method to save tracking model to the file.
+ *
+ * @since_tizen 3.0
+ * @remarks After model is saved to the file, it can be loaded from this file
+ *          with @ref mv_face_tracking_model_load_open() function.
+ * @param [in] file_name         The name of the file where model will be saved
+ * @param [in] tracking_model    The handle to the tracking model to be
+ *                               saved to the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face tracking handle by calling
+ *      @ref mv_face_tracking_model_create_open()
+ * @post Saved model can be loaded from file using
+ *       @ref mv_face_tracking_model_load_open() function
+ *
+ * @see mv_face_tracking_model_load_open()
+ * @see mv_face_tracking_model_create_open()
+ */
+int mv_face_tracking_model_save_open(
+        const char *file_name,
+        mv_face_tracking_model_h tracking_model);
+
+/**
+ * @brief Call this method to load a tracking model from file.
+ *
+ * @since_tizen 3.0
+ * @remarks Tracking models can be load from files saved with
+ *          mv_face_tracking_model_save_open() function.
+ * @param [in] file_name         Path to the file from which model will be
+ *                                loaded
+ * @param [in] tracking_model    The handle to the tracking model to be
+ *                                 loaded from file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Models has been saved by @ref mv_face_tracking_model_save_open()
+ *      function can be loaded with this function
+ * @post After model has been loaded and if further tracking will be performed
+ *       on the video which is not continuation of the last tracking performed
+ *       for the model, it is recommended to call
+ *       @ref mv_face_tracking_model_prepare_open() function
+ *
+ * @see mv_face_tracking_model_save_open()
+ * @see mv_face_tracking_model_destroy_open()
+ */
+int mv_face_tracking_model_load_open(
+        const char *file_name,
+        mv_face_tracking_model_h *tracking_model);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_FACE_OPEN_H__ */
diff --git a/mv_face/face/src/FaceDetector.cpp b/mv_face/face/src/FaceDetector.cpp
new file mode 100644 (file)
index 0000000..21d8195
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FaceDetector.h"
+
+namespace MediaVision
+{
+namespace Face
+{
+
+FaceDetector::FaceDetector() :
+        m_faceCascade(),
+        m_haarcascadeFilepath(),
+        m_faceCascadeIsLoaded(false)
+{
+    ; /* NULL */
+}
+
+FaceDetector::~FaceDetector()
+{
+    ; /* NULL */
+}
+
+bool FaceDetector::detectFaces(
+        const cv::Mat& image,
+        const cv::Rect& roi,
+        const cv::Size& minSize,
+        std::vector<cv::Rect>& faceLocations)
+{
+    if (!m_faceCascadeIsLoaded)
+    {
+        return false;
+    }
+
+    faceLocations.clear();
+
+    cv::Mat intrestingRegion = image;
+
+    bool roiIsUsed = false;
+    if (roi.x >= 0 && roi.y >= 0 && roi.width > 0 && roi.height > 0 &&
+        (roi.x + roi.width) <= image.cols && (roi.y + roi.height) <= image.rows)
+    {
+        intrestingRegion = intrestingRegion(roi);
+        roiIsUsed = true;
+    }
+
+    if (minSize.width > 0 && minSize.height > 0 &&
+        minSize.width <= image.cols && minSize.height <= image.rows)
+    {
+        m_faceCascade.detectMultiScale(
+                intrestingRegion,
+                faceLocations,
+                1.1,
+                3,
+                0,
+                minSize);
+    }
+    else
+    {
+        m_faceCascade.detectMultiScale(intrestingRegion, faceLocations);
+    }
+
+    if (roiIsUsed)
+    {
+        const size_t numberOfLocations = faceLocations.size();
+        for (size_t i = 0u; i < numberOfLocations; ++i)
+        {
+            faceLocations[i].x += roi.x;
+            faceLocations[i].y += roi.y;
+        }
+    }
+
+    return true;
+}
+
+bool FaceDetector::loadHaarcascade(const std::string& haarcascadeFilepath)
+{
+
+    if (!m_faceCascadeIsLoaded || m_haarcascadeFilepath != haarcascadeFilepath)
+    {
+        if (!(m_faceCascadeIsLoaded = m_faceCascade.load(haarcascadeFilepath)))
+        {
+            return false;
+        }
+        m_haarcascadeFilepath = haarcascadeFilepath;
+    }
+
+    return true;
+}
+
+} /* Face */
+} /* MediaVision */
diff --git a/mv_face/face/src/FaceExpressionRecognizer.cpp b/mv_face/face/src/FaceExpressionRecognizer.cpp
new file mode 100644 (file)
index 0000000..51d9d05
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FaceExpressionRecognizer.h"
+
+#include "mv_private.h"
+
+#include <vector>
+
+#include <opencv/cv.h>
+
+namespace MediaVision
+{
+namespace Face
+{
+
+static const int MinDetectionWidth = 30;
+static const int MinDetectionHeight = 30;
+
+FaceRecognizerConfig::FaceRecognizerConfig() :
+        mHaarcascadeFilepath(
+                "/usr/share/OpenCV/haarcascades/haarcascade_smile.xml")
+{
+    ; /* NULL */
+}
+
+int FaceExpressionRecognizer::recognizeFaceExpression(
+                   const cv::Mat& grayImage,
+                   const mv_rectangle_s& faceLocation,
+                   mv_face_facial_expression_e *faceExpression,
+                   const FaceRecognizerConfig& config)
+{
+    if (NULL == faceExpression)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    const int smileRectHeight = cvRound((float)faceLocation.height / 2);
+
+    const cv::Rect roi(
+                  faceLocation.point.x,
+                  faceLocation.point.y + faceLocation.height - smileRectHeight,
+                  faceLocation.width,
+                  smileRectHeight);
+
+    if (roi.width < MinDetectionWidth ||
+        roi.height < MinDetectionHeight)
+    {
+        (*faceExpression) = MV_FACE_UNKNOWN;
+        return MEDIA_VISION_ERROR_NONE;
+    }
+
+    if (0 > roi.x ||
+        0 > roi.y ||
+        roi.x + roi.width > grayImage.cols ||
+        roi.y + roi.height > grayImage.rows)
+    {
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    const cv::Mat mouthImg(grayImage, roi);
+
+    std::vector<cv::Rect> areas;
+
+    cv::CascadeClassifier smileClassifier;
+    smileClassifier.load(config.mHaarcascadeFilepath);
+    smileClassifier.detectMultiScale(
+                            mouthImg,
+                            areas,
+                            1.1,
+                            80,
+                            cv::CASCADE_FIND_BIGGEST_OBJECT |
+                            cv::CASCADE_DO_CANNY_PRUNING    |
+                            cv::CASCADE_SCALE_IMAGE,
+                            cv::Size(MinDetectionWidth, MinDetectionHeight));
+
+    (*faceExpression) = MV_FACE_UNKNOWN;
+    const size_t smilesFoundSize = areas.size();
+    if (smilesFoundSize == 0)
+    {
+        (*faceExpression) = MV_FACE_NEUTRAL;
+    }
+    else if (smilesFoundSize == 1)
+    {
+        (*faceExpression) = MV_FACE_SMILE;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* Face */
+} /* MediaVision */
diff --git a/mv_face/face/src/FaceEyeCondition.cpp b/mv_face/face/src/FaceEyeCondition.cpp
new file mode 100644 (file)
index 0000000..9432d1e
--- /dev/null
@@ -0,0 +1,229 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FaceEyeCondition.h"
+
+#include <mv_private.h>
+
+#include <vector>
+
+namespace MediaVision
+{
+namespace Face
+{
+
+void FaceEyeCondition::splitEyes(
+                           const cv::Mat& grayImage,
+                           mv_rectangle_s faceLocation,
+                           cv::Mat& leftEye,
+                           cv::Mat& rightEye)
+{
+    leftEye = grayImage.rowRange(0, grayImage.rows / 2 - grayImage.rows / 10)
+                       .colRange(grayImage.cols / 2 + grayImage.cols / 10,
+                                 grayImage.cols)
+                       .clone();
+
+    rightEye = grayImage.rowRange(grayImage.rows / 2 + grayImage.rows / 10,
+                                  grayImage.rows)
+                        .colRange(grayImage.cols / 2 + grayImage.cols / 10,
+                                  grayImage.cols)
+                        .clone();
+
+    const cv::Rect faceRect(
+                       faceLocation.point.x,
+                       faceLocation.point.y,
+                       faceLocation.width,
+                       faceLocation.height);
+
+    const cv::Rect eyeAreaRight(
+                      faceRect.x + faceRect.width / 16,
+                      (int) (faceRect.y + (faceRect.height / 4.5)),
+                      (faceRect.width - 2 * faceRect.width / 16) / 2,
+                      (int) (faceRect.height / 3.0));
+
+    const cv::Rect eyeAreaLeft(
+                       faceRect.x + faceRect.width / 16
+                       + (faceRect.width - 2 * faceRect.width / 16) / 2,
+                       (int) (faceRect.y + (faceRect.height / 4.5)),
+                       (faceRect.width - 2 * faceRect.width / 16) / 2,
+                       (int) (faceRect.height / 3.0));
+
+    const double xLeftEyeCenter = (2 * eyeAreaLeft.x + eyeAreaLeft.width) / 2.;
+    const double yLeftEyeCenter = (2 * eyeAreaLeft.y + eyeAreaLeft.height) / 2.;
+
+    const double xRightEyeCenter = (2 * eyeAreaRight.x + eyeAreaRight.width) / 2.;
+    const double yRightEyeCenter = (2 * eyeAreaRight.y + eyeAreaRight.height) / 2.;
+
+    const cv::Rect leftEyeRect(xLeftEyeCenter - eyeAreaLeft.width / 4,
+                               yLeftEyeCenter - eyeAreaLeft.height / 4,
+                               eyeAreaLeft.width / 2,
+                               eyeAreaLeft.height / 2);
+
+    const cv::Rect rightEyeRect(xRightEyeCenter - eyeAreaRight.width / 4,
+                                yRightEyeCenter - eyeAreaRight.height / 4,
+                                eyeAreaRight.width / 2,
+                                eyeAreaRight.height / 2);
+
+    cv::resize(
+            grayImage(leftEyeRect),
+            leftEye,
+            leftEye.size());
+    cv::resize(
+            grayImage(rightEyeRect),
+            rightEye,
+            rightEye.size());
+}
+
+int FaceEyeCondition::isEyeOpen(const cv::Mat& eye)
+{
+    int isOpen = MV_FACE_EYES_CLOSED;
+
+    cv::Mat eyeEqualized;
+    cv::equalizeHist(eye, eyeEqualized);
+
+    const int thresold = 8;
+    eyeEqualized = eyeEqualized < thresold;
+
+    std::vector<std::vector<cv::Point> > contours;
+    std::vector<cv::Vec4i> hierarchy;
+
+    cv::findContours(
+            eyeEqualized,
+            contours,
+            hierarchy,
+            CV_RETR_CCOMP,
+            CV_CHAIN_APPROX_SIMPLE);
+
+    const size_t contoursSize = contours.size();
+
+    if (!contoursSize)
+    {
+        return MV_FACE_EYES_NOT_FOUND;
+    }
+
+    const int xCenter = eyeEqualized.cols / 2;
+    const int yCenter = eyeEqualized.rows / 2;
+    const int width = eyeEqualized.cols / 2.5;
+    const int height = eyeEqualized.rows / 2.5;
+
+    const cv::Rect boundThresold(xCenter - width, yCenter - height, 2 * width, 2 * height);
+
+    const int widthHeightRatio = 3;
+    const double areaRatio = 0.005;
+    const double areaSmallRatio = 0.0005;
+    size_t rectanglesInsideCount = 0u;
+
+    for (size_t i = 0; i < contoursSize; ++i)
+    {
+        const cv::Rect currentRect = cv::boundingRect(contours[i]);
+        const double currentArea = cv::contourArea(contours[i]);
+
+        if (boundThresold.contains(currentRect.br()) &&
+            boundThresold.contains(currentRect.tl()) &&
+            currentArea > areaRatio * boundThresold.area() &&
+            currentRect.width < widthHeightRatio * currentRect.height)
+        {
+            isOpen = MV_FACE_EYES_OPEN;
+        }
+        else if (boundThresold.contains(currentRect.br()) &&
+                 boundThresold.contains(currentRect.tl()) &&
+                 currentArea > areaSmallRatio * boundThresold.area())
+        {
+            ++rectanglesInsideCount;
+        }
+    }
+
+    if (rectanglesInsideCount > 8u)
+    {
+        isOpen = MV_FACE_EYES_CLOSED;
+    }
+
+    return isOpen;
+}
+
+int FaceEyeCondition::recognizeEyeCondition(
+        const cv::Mat& grayImage,
+        mv_rectangle_s faceLocation,
+        mv_face_eye_condition_e *eyeCondition)
+{
+    if (grayImage.empty())
+    {
+        *eyeCondition = MV_FACE_EYES_NOT_FOUND;
+
+        LOGE("Input image is empty. Eye condition recognition failed.");
+        return MEDIA_VISION_ERROR_NO_DATA;
+    }
+
+    if (faceLocation.height <= 0 || faceLocation.width <= 0 ||
+        faceLocation.point.x < 0 || faceLocation.point.y < 0 ||
+        (faceLocation.point.x + faceLocation.width) > grayImage.cols ||
+        (faceLocation.point.y + faceLocation.height) > grayImage.rows)
+    {
+        *eyeCondition = MV_FACE_EYES_NOT_FOUND;
+
+        LOGE("Input face location is wrong. Eye condition recognition failed.");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (NULL == eyeCondition)
+    {
+        *eyeCondition = MV_FACE_EYES_NOT_FOUND;
+
+        LOGE("Output eye condition is NULL. Eye condition recognition failed.");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    // split left and right eyes
+    cv::Mat leftEye;
+    cv::Mat rightEye;
+    splitEyes(grayImage, faceLocation, leftEye, rightEye);
+
+    // recognize eyes conditions
+    const int isOpenLeft = isEyeOpen(leftEye);
+
+    if (isOpenLeft == MV_FACE_EYES_CLOSED)
+    {
+        *eyeCondition = MV_FACE_EYES_CLOSED;
+
+        return MEDIA_VISION_ERROR_NONE;
+    }
+    else if (isOpenLeft == MV_FACE_EYES_NOT_FOUND)
+    {
+        *eyeCondition = MV_FACE_EYES_NOT_FOUND;
+
+        return MEDIA_VISION_ERROR_NONE;
+    }
+
+    const int isOpenRight = isEyeOpen(rightEye);
+
+    if (isOpenRight == MV_FACE_EYES_OPEN)
+    {
+        *eyeCondition = MV_FACE_EYES_OPEN;
+    }
+    else if (isOpenRight == MV_FACE_EYES_CLOSED)
+    {
+        *eyeCondition = MV_FACE_EYES_CLOSED;
+    }
+    else
+    {
+        *eyeCondition = MV_FACE_EYES_NOT_FOUND;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* Face */
+} /* MediaVision */
diff --git a/mv_face/face/src/FaceRecognitionModel.cpp b/mv_face/face/src/FaceRecognitionModel.cpp
new file mode 100644 (file)
index 0000000..1887cea
--- /dev/null
@@ -0,0 +1,546 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FaceRecognitionModel.h"
+
+#include <app_common.h>
+
+#include "mv_private.h"
+#include "mv_common.h"
+
+#include <map>
+
+#include <stdio.h>
+#include <unistd.h>
+
+namespace MediaVision
+{
+namespace Face
+{
+
+namespace
+{
+
+int CopyOpenCVAlgorithmParameters(const cv::Ptr<cv::FaceRecognizer>& srcAlg,
+        cv::Ptr<cv::FaceRecognizer>& dstAlg)
+{
+    char tempPath[1024];
+
+    sprintf(tempPath, "/tmp/alg_copy_%p_%p", srcAlg.obj, dstAlg.obj);
+
+    srcAlg->save(tempPath);
+    dstAlg->load(tempPath);
+
+    if (0 != remove(tempPath))
+    {
+        LOGW("Error removing serialized FaceRecognizer in %s", tempPath);
+    }
+
+    // todo: consider to uncomment this lines if OpenCV will support deep
+    // copy of AlgorithmInfo objects:
+
+    /*std::vector<std::string> paramNames;
+    srcAlg->getParams(paramNames);
+    size_t paramSize = paramNames.size();
+    for (size_t i = 0; i < paramSize; ++i)
+    {
+        int pType = srcAlg->paramType(paramNames[i]);
+
+        switch(pType)
+        {
+        case cv::Param::INT:
+        case cv::Param::UNSIGNED_INT:
+        case cv::Param::UINT64:
+        case cv::Param::SHORT:
+        case cv::Param::UCHAR:
+            dstAlg->set(paramNames[i], srcAlg->getInt(paramNames[i]));
+            break;
+        case cv::Param::BOOLEAN:
+            dstAlg->set(paramNames[i], srcAlg->getBool(paramNames[i]));
+            break;
+        case cv::Param::REAL:
+        case cv::Param::FLOAT:
+            dstAlg->set(paramNames[i], srcAlg->getDouble(paramNames[i]));
+            break;
+        case cv::Param::STRING:
+            dstAlg->set(paramNames[i], srcAlg->getString(paramNames[i]));
+            break;
+        case cv::Param::MAT:
+            dstAlg->set(paramNames[i], srcAlg->getMat(paramNames[i]));
+            break;
+        case cv::Param::MAT_VECTOR:
+        {
+            //std::vector<cv::Mat> value = srcAlg->getMatVector(paramNames[i]);
+            //dstAlg->info()->addParam(*(dstAlg.obj), paramNames[i].c_str(), value);
+            dstAlg->set(paramNames[i], srcAlg->getMatVector(paramNames[i]));
+            break;
+        }
+        case cv::Param::ALGORITHM:
+            dstAlg->set(paramNames[i], srcAlg->getAlgorithm(paramNames[i]));
+            break;
+        default:
+            LOGE("While copying algorothm parameters unsupported parameter "
+                 "%s was found.", paramNames[i].c_str());
+
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+            break;
+        }
+    }*/
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+void ParseOpenCVLabels(
+        const cv::Ptr<cv::FaceRecognizer>& recognizer,
+        std::set<int>& outLabels)
+{
+    if (!recognizer.empty())
+    {
+        cv::Mat labels = recognizer->getMat("labels");
+        for(int i = 0; i < labels.rows; ++i)
+        {
+            outLabels.insert(labels.at<int>(i, 0));
+        }
+    }
+}
+
+} /* anonymous namespace */
+
+FaceRecognitionModelConfig::FaceRecognitionModelConfig() :
+        mModelType(MEDIA_VISION_FACE_MODEL_TYPE_UNKNOWN),
+        mNumComponents(0),
+        mThreshold(DBL_MAX),
+        mRadius(1),
+        mNeighbors(8),
+        mGridX(8),
+        mGridY(8),
+        mImgWidth(150),
+        mImgHeight(150)
+{
+    ; /* NULL */
+}
+
+FaceRecognitionResults::FaceRecognitionResults() :
+        mIsRecognized(false),
+        mFaceLabel(-1),
+        mConfidence(0.0)
+{
+    ; /* NULL */
+}
+
+bool FaceRecognitionModelConfig::operator!=(
+        const FaceRecognitionModelConfig& other) const
+{
+    return mModelType     != other.mModelType     ||
+           mNumComponents != other.mNumComponents ||
+           mThreshold     != other.mThreshold     ||
+           mRadius        != other.mRadius        ||
+           mNeighbors     != other.mNeighbors     ||
+           mGridX         != other.mGridX         ||
+           mGridY         != other.mGridY         ||
+           mImgWidth      != other.mImgWidth      ||
+           mImgHeight     != other.mImgHeight;
+}
+
+FaceRecognitionModel::FaceRecognitionModel() :
+        m_canRecognize(false),
+        m_recognizer(NULL)
+{
+    ; /* NULL */
+}
+
+FaceRecognitionModel::FaceRecognitionModel(const FaceRecognitionModel& origin) :
+        m_canRecognize(origin.m_canRecognize),
+        m_faceSamples(origin.m_faceSamples),
+        m_learnAlgorithmConfig(origin.m_learnAlgorithmConfig),
+        m_recognizer(CreateRecognitionAlgorithm(origin.m_learnAlgorithmConfig)),
+        m_learnedLabels(origin.m_learnedLabels)
+{
+    if (!m_recognizer.empty())
+    {
+        CopyOpenCVAlgorithmParameters(origin.m_recognizer, m_recognizer);
+    }
+}
+
+FaceRecognitionModel& FaceRecognitionModel::operator=(
+        const FaceRecognitionModel& copy)
+{
+    if (this != &copy)
+    {
+        m_canRecognize = copy.m_canRecognize;
+        m_faceSamples = copy.m_faceSamples;
+        m_learnAlgorithmConfig = copy.m_learnAlgorithmConfig;
+        m_recognizer = CreateRecognitionAlgorithm(m_learnAlgorithmConfig);
+        m_learnedLabels = copy.m_learnedLabels;
+
+        if (!m_recognizer.empty())
+        {
+            CopyOpenCVAlgorithmParameters(copy.m_recognizer, m_recognizer);
+        }
+    }
+
+    return *this;
+}
+
+FaceRecognitionModel::~FaceRecognitionModel()
+{
+    ; /* NULL */
+}
+
+int FaceRecognitionModel::save(const std::string& fileName)
+{
+    if (!m_recognizer.empty())
+    {
+        /* find directory */
+        std::string prefix_path = std::string(app_get_data_path());
+        LOGD("prefix_path: %s", prefix_path.c_str());
+
+        std::string filePath;
+        filePath += prefix_path;
+        filePath += fileName;
+
+        /* check the directory is available */
+        std::string prefix_path_check = filePath.substr(0, filePath.find_last_of('/'));
+        if (access(prefix_path_check.c_str(),F_OK))
+        {
+            LOGE("Can't save recognition model. Path[%s] doesn't existed.", prefix_path_check.c_str());
+
+            return MEDIA_VISION_ERROR_INVALID_PATH;
+        }
+
+        cv::FileStorage storage(filePath, cv::FileStorage::WRITE);
+        if (!storage.isOpened())
+        {
+            LOGE("Can't save recognition model. Write to file permission denied.");
+            return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+        }
+
+        switch (m_learnAlgorithmConfig.mModelType)
+        {
+            case MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES:
+                storage << "algorithm" << "Eigenfaces";
+                break;
+            case MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES:
+                storage << "algorithm" << "Fisherfaces";
+                break;
+            case MEDIA_VISION_FACE_MODEL_TYPE_LBPH:
+                storage << "algorithm" << "LBPH";
+                break;
+            default:
+                storage.release();
+                return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+        }
+
+        storage << "can_recognize" << m_canRecognize;
+        m_recognizer->save(storage);
+
+        storage.release();
+    }
+    else
+    {
+        LOGE("Attempt to save recognition model before learn");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceRecognitionModel::load(const std::string& fileName)
+{
+    /* find directory */
+    std::string prefix_path = std::string(app_get_data_path());
+    LOGD("prefix_path: %s", prefix_path.c_str());
+
+    std::string filePath;
+    filePath += prefix_path;
+    filePath += fileName;
+
+    if (access(filePath.c_str(),F_OK))
+    {
+        LOGE("Can't load face recognition model. File[%s] doesn't exist.", filePath.c_str());
+
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    cv::FileStorage storage(filePath, cv::FileStorage::READ);
+    if (!storage.isOpened())
+    {
+        LOGE("Can't load recognition model. Read from file permission denied.");
+
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    LOGD("Loading recognition model from file.");
+
+    std::string algName;
+    int canRecognize = 0;
+    storage["algorithm"] >> algName;
+    storage["can_recognize"] >> canRecognize;
+
+    cv::Ptr<cv::FaceRecognizer> tempRecognizer;
+    FaceRecognitionModelConfig tempConfig;
+    std::set<int> tempLearnedLabels;
+
+    if (algName == "Eigenfaces")
+    {
+        tempRecognizer = cv::createEigenFaceRecognizer();
+        tempRecognizer->load(storage);
+        tempConfig.mModelType =
+                MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES;
+        tempConfig.mNumComponents =
+                tempRecognizer->getInt("ncomponents");
+        ParseOpenCVLabels(tempRecognizer, tempLearnedLabels);
+    }
+    else if (algName == "Fisherfaces")
+    {
+        tempRecognizer = cv::createFisherFaceRecognizer();
+        tempRecognizer->load(storage);
+        tempConfig.mModelType =
+                MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES;
+        tempConfig.mNumComponents =
+                tempRecognizer->getInt("ncomponents");
+        ParseOpenCVLabels(tempRecognizer, tempLearnedLabels);
+    }
+    else if (algName == "LBPH")
+    {
+        tempRecognizer = cv::createLBPHFaceRecognizer();
+        tempRecognizer->load(storage);
+        tempConfig.mModelType =
+                MEDIA_VISION_FACE_MODEL_TYPE_LBPH;
+        tempConfig.mGridX = tempRecognizer->getInt("grid_x");
+        tempConfig.mGridY = tempRecognizer->getInt("grid_y");
+        tempConfig.mNeighbors = tempRecognizer->getInt("neighbors");
+        tempConfig.mRadius = tempRecognizer->getInt("radius");
+        ParseOpenCVLabels(tempRecognizer, tempLearnedLabels);
+    }
+    else
+    {
+        tempConfig = FaceRecognitionModelConfig();
+        LOGE("Failed to load face recognition model from file. File is in "
+             "unsupported format");
+
+        storage.release();
+
+        return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    tempConfig.mThreshold = tempRecognizer->getDouble("threshold");
+
+    LOGD("Recognition model of [%s] type has been loaded from file",
+            algName.c_str());
+
+    storage.release();
+
+    m_recognizer = tempRecognizer;
+    m_learnAlgorithmConfig = tempConfig;
+    m_canRecognize = (canRecognize == 1);
+    m_learnedLabels.clear();
+    m_learnedLabels = tempLearnedLabels;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceRecognitionModel::addFaceExample(
+        const cv::Mat& faceImage,
+        int faceLabel)
+{
+    m_faceSamples[faceLabel].push_back(faceImage);
+
+    LOGD("Added face image example for label %i for recognition model",
+            faceLabel);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceRecognitionModel::resetFaceExamples(void)
+{
+    m_faceSamples.clear();
+
+    LOGD("All face image examples have been removed from recognition model");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceRecognitionModel::resetFaceExamples(int faceLabel)
+{
+    if (1 > m_faceSamples.erase(faceLabel))
+    {
+        LOGD("Failed to remove face image examples for label %i. "
+             "No such examples", faceLabel);
+
+        return MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE;
+    }
+
+    LOGD("Face image examples for label %i have been removed from "
+         "recognition model", faceLabel);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+const std::set<int>& FaceRecognitionModel::getFaceLabels(void) const
+{
+    return m_learnedLabels;
+}
+
+int FaceRecognitionModel::learn(const FaceRecognitionModelConfig& config)
+{
+    bool isIncremental = false;
+    bool isUnisize = false;
+
+    if (MEDIA_VISION_FACE_MODEL_TYPE_LBPH == config.mModelType)
+    {
+        isIncremental = true;
+    }
+
+    if (MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES == config.mModelType ||
+            MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES == config.mModelType)
+    {
+        isUnisize = true;
+    }
+
+    std::vector<cv::Mat> samples;
+    std::vector<int> labels;
+    std::set<int> learnedLabels;
+
+    if (isIncremental)
+    {
+        learnedLabels.insert(m_learnedLabels.begin(), m_learnedLabels.end());
+    }
+
+    std::map<int, std::vector<cv::Mat> >::const_iterator it =
+            m_faceSamples.begin();
+    for (; it != m_faceSamples.end(); ++it)
+    {
+        const size_t faceClassSamplesSize = it->second.size();
+        labels.insert(labels.end(), faceClassSamplesSize, it->first);
+        learnedLabels.insert(it->first);
+
+        if (!isUnisize)
+        {
+            LOGD("%u examples has been added with label %i",
+                    it->second.size(), it->first);
+            samples.insert(samples.end(), it->second.begin(), it->second.end());
+        }
+        else
+        {
+            for (size_t sampleInd = 0; sampleInd < faceClassSamplesSize; ++sampleInd)
+            {
+                cv::Mat resizedSample;
+                cv::resize(it->second[sampleInd],
+                           resizedSample,
+                           cv::Size(config.mImgWidth, config.mImgHeight),
+                           1.0, 1.0, cv::INTER_CUBIC);
+                samples.push_back(resizedSample);
+            }
+        }
+    }
+
+    const size_t samplesSize = samples.size();
+    const size_t labelsSize = labels.size();
+
+    if (0 != samplesSize && samplesSize == labelsSize)
+    {
+        LOGD("Start to learn the model for %u samples and %u labels",
+             samplesSize, labelsSize);
+
+        if (m_learnAlgorithmConfig != config || m_recognizer.empty())
+        {
+            m_recognizer = CreateRecognitionAlgorithm(config);
+        }
+
+        if (m_recognizer.empty())
+        {
+            LOGE("Can't create recognition algorithm for recognition model. "
+                 "Configuration is not supported by any of known algorithms.");
+
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+        }
+
+        isIncremental ? m_recognizer->update(samples, labels) :
+                        m_recognizer->train(samples, labels);
+        m_canRecognize = true;
+        m_learnedLabels.clear();
+        m_learnedLabels = learnedLabels;
+    }
+    else
+    {
+        LOGE("Can't create recognition algorithm for no examples. Try to add "
+                "some face examples before learning");
+
+        return MEDIA_VISION_ERROR_NO_DATA;
+    }
+
+    m_learnAlgorithmConfig = config;
+
+    LOGD("Recognition model has been learned");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceRecognitionModel::recognize(const cv::Mat& image, FaceRecognitionResults& results)
+{
+    if (!m_recognizer.empty() && m_canRecognize)
+    {
+        double absConf = 0.0;
+        m_recognizer->predict(image, results.mFaceLabel, absConf);
+        // Normalize the absolute value of the confidence
+        absConf = exp(7.5 - (0.05 * absConf));
+        results.mConfidence = absConf / (1 + absConf);
+        results.mIsRecognized = true;
+        results.mFaceLocation = cv::Rect(0, 0, image.cols, image.rows);
+    }
+    else
+    {
+        LOGE("Attempt to recognize faces with untrained model");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+cv::Ptr<cv::FaceRecognizer> FaceRecognitionModel::CreateRecognitionAlgorithm(
+        const FaceRecognitionModelConfig& config)
+{
+    cv::Ptr<cv::FaceRecognizer> tempRecognizer;
+    switch (config.mModelType)
+    {
+        case MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES:
+            tempRecognizer = cv::createEigenFaceRecognizer(
+                                     config.mNumComponents,
+                                     config.mThreshold);
+            break;
+        case MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES:
+            tempRecognizer = cv::createFisherFaceRecognizer(
+                                     config.mNumComponents,
+                                     config.mThreshold);
+            break;
+        case MEDIA_VISION_FACE_MODEL_TYPE_LBPH:
+            tempRecognizer = cv::createLBPHFaceRecognizer(
+                                     config.mRadius,
+                                     config.mNeighbors,
+                                     config.mGridX,
+                                     config.mGridY,
+                                     config.mThreshold);
+            break;
+        default:
+            return NULL;
+    }
+
+    return tempRecognizer;
+}
+
+} /* Face */
+} /* MediaVision */
diff --git a/mv_face/face/src/FaceTrackingModel.cpp b/mv_face/face/src/FaceTrackingModel.cpp
new file mode 100644 (file)
index 0000000..2c4fdd6
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FaceTrackingModel.h"
+
+#include <app_common.h>
+
+#include "mv_private.h"
+#include "mv_common.h"
+
+#include <unistd.h>
+
+namespace MediaVision
+{
+namespace Face
+{
+
+FaceTrackingResults::FaceTrackingResults() :
+        mIsTracked(false),
+        mConfidence(0.f)
+{
+    ; /* NULL */
+}
+
+FaceTrackingModel::FaceTrackingModel() :
+        m_canTrack(false),
+        m_tracker(new cv::TrackerMedianFlow())
+{
+    ; /* NULL */
+}
+
+FaceTrackingModel::FaceTrackingModel(const FaceTrackingModel& origin) :
+        m_canTrack(origin.m_canTrack),
+        m_tracker(new cv::TrackerMedianFlow())
+{
+    if (!origin.m_tracker.empty())
+    {
+        origin.m_tracker->copyTo(*(m_tracker.obj));
+    }
+}
+
+FaceTrackingModel& FaceTrackingModel::operator=(const FaceTrackingModel& copy)
+{
+    if (this != &copy)
+    {
+        m_canTrack = copy.m_canTrack;
+        m_tracker = cv::Ptr<cv::TrackerMedianFlow>(new cv::TrackerMedianFlow());
+        if (!copy.m_tracker.empty())
+        {
+            copy.m_tracker->copyTo(*(m_tracker.obj));
+        }
+    }
+
+    return *this;
+}
+
+FaceTrackingModel::~FaceTrackingModel()
+{
+    ; /* NULL */
+}
+
+int FaceTrackingModel::save(const std::string& fileName)
+{
+    if (m_tracker.empty())
+    {
+        LOGE("Can't save tracking model. No tracking algorithm is used");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    std::string prefix_path = std::string(app_get_data_path());
+    LOGD("prefix_path: %s", prefix_path.c_str());
+
+    std::string filePath;
+    filePath += prefix_path;
+    filePath += fileName;
+
+    /* check the directory is available */
+    std::string prefix_path_check = filePath.substr(0, filePath.find_last_of('/'));
+    if (access(prefix_path_check.c_str(),F_OK))
+    {
+        LOGE("Can't save tracking model. Path[%s] doesn't existed.", prefix_path_check.c_str());
+
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    cv::FileStorage storage(filePath, cv::FileStorage::WRITE);
+    if (!storage.isOpened())
+    {
+        LOGE("Can't save tracking model. Write to file permission denied.");
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    LOGD("Storing tracking model to the file started.");
+
+    storage << "canTrack" << (m_canTrack ? 1 : 0);
+    m_tracker->write(storage);
+
+    LOGD("Storing tracking model to the file finished.");
+
+    storage.release();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceTrackingModel::load(const std::string& fileName)
+{
+   /* find directory */
+    std::string prefix_path = std::string(app_get_data_path());
+    LOGD("prefix_path: %s", prefix_path.c_str());
+
+    std::string filePath;
+    filePath += prefix_path;
+    filePath += fileName;
+
+    if (access(filePath.c_str(), F_OK))
+    {
+        LOGE("Can't load face tracking model. File[%s] doesn't exist.", filePath.c_str());
+
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    cv::FileStorage storage(filePath, cv::FileStorage::READ);
+    if (!storage.isOpened())
+    {
+        LOGE("Can't load tracking model. Read from file permission denied.");
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    int canTrack = 0;
+    storage["canTrack"] >> canTrack;
+    m_canTrack = (0 != canTrack);
+    m_tracker->read(storage);
+
+    LOGD("Loading tracking model from file.");
+
+    storage.release();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceTrackingModel::prepare(const cv::Mat& image)
+{
+    if (m_tracker.empty())
+    {
+        LOGE("Failed to prepare tracking model. No tracking algorithm "
+             "is available.");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    cv::Rect_<float> lastBoundingBox;
+    if (!m_tracker->isInited())
+    {
+        lastBoundingBox.x = 0;
+        lastBoundingBox.y = 0;
+        lastBoundingBox.width = image.cols;
+        lastBoundingBox.height = image.rows;
+    }
+    else
+    {
+        lastBoundingBox = m_tracker->getLastBoundingBox();
+    }
+
+    return prepare(image, lastBoundingBox);
+}
+
+int FaceTrackingModel::prepare(
+        const cv::Mat& image,
+        const cv::Rect_<float>& boundingBox)
+{
+    if (m_tracker.empty())
+    {
+        LOGE("Failed to prepare tracking model. No tracking algorithm "
+             "is available.");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    if (!m_tracker->init(image, boundingBox))
+    {
+        LOGE("Failed to prepare tracking model.");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    m_canTrack = true;
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceTrackingModel::track(const cv::Mat& image, FaceTrackingResults& results)
+{
+    if (!m_tracker.empty() && m_canTrack)
+    {
+        results.mIsTracked = m_tracker->update(image, results.mFaceLocation);
+        results.mConfidence = m_tracker->getLastConfidence();
+    }
+    else
+    {
+        LOGE("Attempt to track face with not prepared model");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* Face */
+} /* MediaVision */
diff --git a/mv_face/face/src/FaceUtil.cpp b/mv_face/face/src/FaceUtil.cpp
new file mode 100644 (file)
index 0000000..7d49dd3
--- /dev/null
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FaceUtil.h"
+
+#include "mv_private.h"
+
+#include <opencv2/imgproc/types_c.h>
+#include <opencv2/highgui/highgui.hpp>
+
+namespace MediaVision
+{
+namespace Face
+{
+
+RecognitionParams::RecognitionParams(FaceRecognitionModelType algType) :
+        mRecognitionAlgType(algType)
+{
+    ; /* NULL */
+}
+
+RecognitionParams::RecognitionParams() :
+        mRecognitionAlgType(MEDIA_VISION_FACE_MODEL_TYPE_LBPH)
+{
+    ; /* NULL */
+}
+
+int convertSourceMV2GrayCV(mv_source_h mvSource, cv::Mat& cvSource)
+{
+    MEDIA_VISION_INSTANCE_CHECK(mvSource);
+
+    int depth = CV_8U; // Default depth. 1 byte for channel.
+    unsigned int channelsNumber = 0;
+    unsigned int width = 0, height = 0;
+    unsigned int bufferSize = 0;
+    unsigned char *buffer = NULL;
+
+    mv_colorspace_e colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+
+    MEDIA_VISION_ASSERT(mv_source_get_width(mvSource, &width),
+            "Failed to get the width.");
+    MEDIA_VISION_ASSERT(mv_source_get_height(mvSource, &height),
+            "Failed to get the height.");
+    MEDIA_VISION_ASSERT(mv_source_get_colorspace(mvSource, &colorspace),
+            "Failed to get the colorspace.");
+    MEDIA_VISION_ASSERT(mv_source_get_buffer(mvSource, &buffer, &bufferSize),
+            "Failed to get the buffer size.");
+
+    int conversionType = -1; // Type of conversion from given colorspace to gray
+    switch(colorspace)
+    {
+        case MEDIA_VISION_COLORSPACE_INVALID:
+            LOGE("Error: mv_source has invalid colorspace.");
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        case MEDIA_VISION_COLORSPACE_Y800:
+            channelsNumber = 1;
+            // Without convertion
+            break;
+        case MEDIA_VISION_COLORSPACE_I420:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2GRAY_I420;
+            break;
+        case MEDIA_VISION_COLORSPACE_NV12:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2GRAY_NV12;
+            break;
+        case MEDIA_VISION_COLORSPACE_YV12:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2GRAY_YV12;
+            break;
+        case MEDIA_VISION_COLORSPACE_NV21:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2GRAY_NV21;
+            break;
+        case MEDIA_VISION_COLORSPACE_YUYV:
+            channelsNumber = 2;
+            conversionType = CV_YUV2GRAY_YUYV;
+            break;
+        case MEDIA_VISION_COLORSPACE_UYVY:
+            channelsNumber = 2;
+            conversionType = CV_YUV2GRAY_UYVY;
+            break;
+        case MEDIA_VISION_COLORSPACE_422P:
+            channelsNumber = 2;
+            conversionType = CV_YUV2GRAY_Y422;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB565:
+            channelsNumber = 2;
+            conversionType = CV_BGR5652GRAY;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB888:
+            channelsNumber = 3;
+            conversionType = CV_RGB2GRAY;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGBA:
+            channelsNumber = 4;
+            conversionType = CV_RGBA2GRAY;
+            break;
+        default:
+            LOGE("Error: mv_source has unsupported colorspace.");
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    if (conversionType == -1) // Without conversion
+    {
+        cvSource = cv::Mat(cv::Size(width, height),
+                CV_MAKETYPE(depth, channelsNumber), buffer).clone();
+    }
+    else // Conversion
+    {
+        // Class for representation the given image as cv::Mat before conversion
+        cv::Mat origin(cv::Size(width, height),
+                CV_MAKETYPE(depth, channelsNumber), buffer);
+        cv::cvtColor(origin, cvSource, conversionType);
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* Face */
+} /* MediaVision */
diff --git a/mv_face/face/src/TrackerMedianFlow.cpp b/mv_face/face/src/TrackerMedianFlow.cpp
new file mode 100644 (file)
index 0000000..a7a3b4f
--- /dev/null
@@ -0,0 +1,460 @@
+/*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) 2013, OpenCV Foundation, all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // Redistribution and use in source and binary forms, with or without modification,
+ // are permitted provided that the following conditions are met:
+ //
+ //   * Redistribution's of source code must retain the above copyright notice,
+ //     this list of conditions and the following disclaimer.
+ //
+ //   * Redistribution's in binary form must reproduce the above copyright notice,
+ //     this list of conditions and the following disclaimer in the documentation
+ //     and/or other materials provided with the distribution.
+ //
+ //   * The name of the copyright holders may not be used to endorse or promote products
+ //     derived from this software without specific prior written permission.
+ //
+ // This software is provided by the copyright holders and contributors "as is" and
+ // any express or implied warranties, including, but not limited to, the implied
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
+ // indirect, incidental, special, exemplary, or consequential damages
+ // (including, but not limited to, procurement of substitute goods or services;
+ // loss of use, data, or profits; or business interruption) however caused
+ // and on any theory of liability, whether in contract, strict liability,
+ // or tort (including negligence or otherwise) arising in any way out of
+ // the use of this software, even if advised of the possibility of such damage.
+ //
+ //M*/
+
+#include "TrackerMedianFlow.h"
+
+#include "opencv2/video/tracking.hpp"
+#include "opencv2/imgproc/imgproc.hpp"
+
+#include <algorithm>
+#include <cmath>
+
+namespace
+{
+    float FloatEps = 10e-6f;
+} /* anonymous namespace */
+
+namespace cv
+{
+
+TrackerMedianFlow::Params::Params()
+{
+    mPointsInGrid = 10;
+    mWindowSize = Size(3, 3);
+    mPyrMaxLevel = 5;
+}
+
+void TrackerMedianFlow::Params::read( const cv::FileNode& fn )
+{
+    mPointsInGrid = fn["pointsInGrid"];
+    int winSizeHeight = fn["windowSizeHeight"];
+    int winSizeWidth = fn["windowSizeWidth"];
+    mWindowSize = Size(winSizeHeight, winSizeWidth);
+    mPyrMaxLevel = fn["pyrMaxLevel"];
+}
+
+void TrackerMedianFlow::Params::write( cv::FileStorage& fs ) const
+{
+    fs << "pointsInGrid" << mPointsInGrid;
+    fs << "windowSizeHeight" << mWindowSize.height;
+    fs << "windowSizeWidth" << mWindowSize.width;
+    fs << "pyrMaxLevel" << mPyrMaxLevel;
+}
+
+TrackerMedianFlow::TrackerMedianFlow(Params paramsIn) :
+         termcrit(TermCriteria::COUNT | TermCriteria::EPS,20,0.3),
+         m_confidence(0.0)
+{
+    params = paramsIn;
+    isInit = false;
+}
+
+bool TrackerMedianFlow::copyTo(TrackerMedianFlow& copy) const
+{
+    copy.isInit = isInit;
+    copy.params = params;
+    copy.termcrit = termcrit;
+    copy.m_boundingBox = m_boundingBox;
+    copy.m_confidence = m_confidence;
+    m_image.copyTo(copy.m_image);
+    return true;
+}
+
+bool TrackerMedianFlow::init(const Mat& image, const Rect_<float>& boundingBox)
+{
+    if (image.empty())
+    {
+        return false;
+    }
+
+    image.copyTo(m_image);
+    buildOpticalFlowPyramid(
+            m_image, m_pyramid, params.mWindowSize, params.mPyrMaxLevel);
+    m_boundingBox = boundingBox;
+
+    isInit = true;
+    return isInit;
+}
+
+bool TrackerMedianFlow::update(const Mat& image, Rect_<float>& boundingBox)
+{
+    if (!isInit || image.empty()) return false;
+
+    // Handles such behaviour when preparation frame has the size
+    // different to the tracking frame size. In such case, we resize preparation
+    // frame and bounding box. Then, track as usually:
+    if (m_image.rows != image.rows || m_image.cols != image.cols)
+    {
+        const float xFactor = (float) image.cols / m_image.cols;
+        const float yFactor = (float) image.rows / m_image.rows;
+
+        resize(m_image, m_image, Size(), xFactor, yFactor);
+
+        m_boundingBox.x *= xFactor;
+        m_boundingBox.y *= yFactor;
+        m_boundingBox.width *= xFactor;
+        m_boundingBox.height *= yFactor;
+    }
+
+    Mat oldImage = m_image;
+
+    Rect_<float> oldBox = m_boundingBox;
+    if(!medianFlowImpl(oldImage, image, oldBox))
+    {
+        return false;
+    }
+
+    boundingBox = oldBox;
+    image.copyTo(m_image);
+    m_boundingBox = boundingBox;
+    return true;
+}
+
+bool TrackerMedianFlow::isInited() const
+{
+    return isInit;
+}
+
+float TrackerMedianFlow::getLastConfidence() const
+{
+    return m_confidence;
+}
+
+Rect_<float> TrackerMedianFlow::getLastBoundingBox() const
+{
+    return m_boundingBox;
+}
+
+bool TrackerMedianFlow::medianFlowImpl(
+        Mat oldImage_gray, Mat newImage_gray, Rect_<float>& oldBox)
+{
+    std::vector<Point2f> pointsToTrackOld, pointsToTrackNew;
+
+    const float gridXStep = oldBox.width / params.mPointsInGrid;
+    const float gridYStep = oldBox.height / params.mPointsInGrid;
+    for (int i = 0; i < params.mPointsInGrid; i++)
+    {
+        for (int j = 0; j < params.mPointsInGrid; j++)
+        {
+                pointsToTrackOld.push_back(
+                        Point2f(oldBox.x + .5f*gridXStep + 1.f*gridXStep*j,
+                                oldBox.y + .5f*gridYStep + 1.f*gridYStep*i));
+        }
+    }
+
+    std::vector<uchar> status(pointsToTrackOld.size());
+    std::vector<float> errors(pointsToTrackOld.size());
+
+    std::vector<Mat> tempPyramid;
+    buildOpticalFlowPyramid(
+                         newImage_gray,
+                         tempPyramid,
+                         params.mWindowSize,
+                         params.mPyrMaxLevel);
+
+    calcOpticalFlowPyrLK(m_pyramid,
+                         tempPyramid,
+                         pointsToTrackOld,
+                         pointsToTrackNew,
+                         status,
+                         errors,
+                         params.mWindowSize,
+                         params.mPyrMaxLevel,
+                         termcrit);
+
+    std::vector<Point2f> di;
+    for (size_t idx = 0u; idx < pointsToTrackOld.size(); idx++)
+    {
+        if (status[idx] == 1)
+        {
+            di.push_back(pointsToTrackNew[idx] - pointsToTrackOld[idx]);
+        }
+    }
+
+    std::vector<bool> filter_status;
+    check_FB(tempPyramid,
+             pointsToTrackOld,
+             pointsToTrackNew,
+             filter_status);
+    check_NCC(oldImage_gray,
+              newImage_gray,
+              pointsToTrackOld,
+              pointsToTrackNew,
+              filter_status);
+
+    for (size_t idx = 0u; idx < pointsToTrackOld.size(); idx++)
+    {
+        if (!filter_status[idx])
+        {
+            pointsToTrackOld.erase(pointsToTrackOld.begin() + idx);
+            pointsToTrackNew.erase(pointsToTrackNew.begin() + idx);
+            filter_status.erase(filter_status.begin() + idx);
+            idx--;
+        }
+    }
+
+    if (pointsToTrackOld.size() == 0 || di.size() == 0)
+    {
+        return false;
+    }
+
+    Point2f mDisplacement;
+    Rect_<float> boxCandidate =
+            vote(pointsToTrackOld, pointsToTrackNew, oldBox, mDisplacement);
+
+    std::vector<float> displacements;
+    for (size_t idx = 0u; idx < di.size(); idx++)
+    {
+        di[idx] -= mDisplacement;
+        displacements.push_back(sqrt(di[idx].ddot(di[idx])));
+    }
+
+    m_confidence =
+            (10.f - getMedian(displacements,(int)displacements.size())) / 10.f;
+    if (m_confidence <= 0.f)
+    {
+        m_confidence = 0.f;
+        return false;
+    }
+
+    m_pyramid.swap(tempPyramid);
+    oldBox = boxCandidate;
+    return true;
+}
+
+Rect_<float> TrackerMedianFlow::vote(
+        const std::vector<Point2f>& oldPoints,
+        const std::vector<Point2f>& newPoints,
+        const Rect_<float>& oldRect,
+        Point2f& mD)
+{
+    Rect_<float> newRect;
+    Point2d newCenter(oldRect.x + oldRect.width/2.0,
+                      oldRect.y + oldRect.height/2.0);
+
+    int n = (int)oldPoints.size();
+    std::vector<float> buf(std::max( n*(n-1) / 2, 3), 0.f);
+
+    if(oldPoints.size() == 1)
+    {
+        newRect.x = oldRect.x+newPoints[0].x-oldPoints[0].x;
+        newRect.y = oldRect.y+newPoints[0].y-oldPoints[0].y;
+        newRect.width=oldRect.width;
+        newRect.height=oldRect.height;
+        return newRect;
+    }
+
+    float xshift = 0.f;
+    float yshift = 0.f;
+    for(int i = 0; i < n; i++)
+    {
+        buf[i] = newPoints[i].x - oldPoints[i].x;
+    }
+
+    xshift = getMedian(buf, n);
+    newCenter.x += xshift;
+    for(int idx = 0; idx < n; idx++)
+    {
+        buf[idx] = newPoints[idx].y - oldPoints[idx].y;
+    }
+
+    yshift = getMedian(buf, n);
+    newCenter.y += yshift;
+    mD = Point2f(xshift, yshift);
+
+    if(oldPoints.size() == 1)
+    {
+        newRect.x = newCenter.x - oldRect.width / 2.0;
+        newRect.y = newCenter.y - oldRect.height / 2.0;
+        newRect.width = oldRect.width;
+        newRect.height = oldRect.height;
+        return newRect;
+    }
+
+    float nd = 0.f;
+    float od = 0.f;
+    for (int i = 0, ctr = 0; i < n; i++)
+    {
+        for(int j = 0; j < i; j++)
+        {
+            nd = l2distance(newPoints[i], newPoints[j]);
+            od = l2distance(oldPoints[i], oldPoints[j]);
+            buf[ctr] = (od == 0.f ? 0.f : nd / od);
+            ctr++;
+        }
+    }
+
+    float scale = getMedian(buf, n*(n-1) / 2);
+    newRect.x = newCenter.x - scale * oldRect.width / 2.f;
+    newRect.y = newCenter.y-scale * oldRect.height / 2.f;
+    newRect.width = scale * oldRect.width;
+    newRect.height = scale * oldRect.height;
+
+    return newRect;
+}
+
+template<typename T>
+T TrackerMedianFlow::getMedian(std::vector<T>& values, int size)
+{
+    if (size == -1)
+    {
+        size = (int)values.size();
+    }
+
+    std::vector<T> copy(values.begin(), values.begin() + size);
+    std::sort(copy.begin(),copy.end());
+    if(size%2==0)
+    {
+        return (copy[size/2-1]+copy[size/2])/((T)2.0);
+    }
+    else
+    {
+        return copy[(size - 1) / 2];
+    }
+}
+
+float TrackerMedianFlow::l2distance(Point2f p1, Point2f p2)
+{
+    float dx = p1.x - p2.x;
+    float dy = p1.y - p2.y;
+    return sqrt(dx * dx + dy * dy);
+}
+
+void TrackerMedianFlow::check_FB(
+        std::vector<Mat> newPyramid,
+        const std::vector<Point2f>& oldPoints,
+        const std::vector<Point2f>& newPoints,
+        std::vector<bool>& status)
+{
+    if(status.size() == 0)
+    {
+        status = std::vector<bool>(oldPoints.size(), true);
+    }
+
+    std::vector<uchar> LKstatus(oldPoints.size());
+    std::vector<float> errors(oldPoints.size());
+    std::vector<float> FBerror(oldPoints.size());
+    std::vector<Point2f> pointsToTrackReprojection;
+
+    calcOpticalFlowPyrLK(newPyramid,
+                         m_pyramid,
+                         newPoints,
+                         pointsToTrackReprojection,
+                         LKstatus,
+                         errors,
+                         params.mWindowSize,
+                         params.mPyrMaxLevel,
+                         termcrit);
+
+    for (size_t idx = 0u; idx < oldPoints.size(); idx++)
+    {
+        FBerror[idx] = l2distance(oldPoints[idx], pointsToTrackReprojection[idx]);
+    }
+
+    float FBerrorMedian = getMedian(FBerror) + FloatEps;
+    for (size_t idx = 0u; idx < oldPoints.size(); idx++)
+    {
+        status[idx] = (FBerror[idx] < FBerrorMedian);
+    }
+}
+
+void TrackerMedianFlow::check_NCC(
+        const Mat& oldImage,
+        const Mat& newImage,
+        const std::vector<Point2f>& oldPoints,
+        const std::vector<Point2f>& newPoints,
+        std::vector<bool>& status)
+{
+    std::vector<float> NCC(oldPoints.size(), 0.f);
+    Size patch(30, 30);
+    Mat p1;
+    Mat p2;
+
+    for (size_t idx = 0u; idx < oldPoints.size(); idx++)
+    {
+        getRectSubPix(oldImage, patch, oldPoints[idx], p1);
+        getRectSubPix(newImage, patch, newPoints[idx], p2);
+
+        const int N = 900;
+        const float s1 = sum(p1)(0);
+        const float s2 = sum(p2)(0);
+        const float n1 = norm(p1);
+        const float n2 = norm(p2);
+        const float prod = p1.dot(p2);
+        const float sq1 = sqrt(n1 * n1 - s1 * s1 / N);
+        const float sq2 = sqrt(n2 * n2 - s2 * s2 / N);
+        NCC[idx] = (sq2==0 ? sq1 / std::abs(sq1)
+                        : (prod - s1 * s2 / N) / sq1 / sq2);
+    }
+
+    float median = getMedian(NCC) - FloatEps;
+    for(size_t idx = 0u; idx < oldPoints.size(); idx++)
+    {
+        status[idx] = status[idx] && (NCC[idx] > median);
+    }
+}
+
+void TrackerMedianFlow::read( cv::FileStorage& fs )
+{
+    params.read(fs.root());
+    float bbX = 0.f;
+    float bbY = 0.f;
+    float bbW = 0.f;
+    float bbH = 0.f;
+    fs["lastLocationX"] >> bbX;
+    fs["lastLocationY"] >> bbY;
+    fs["lastLocationW"] >> bbW;
+    fs["lastLocationH"] >> bbH;
+    m_boundingBox = Rect_<float>(bbX, bbY, bbW, bbH);
+    fs["lastImage"] >> m_image;
+}
+
+void TrackerMedianFlow::write( cv::FileStorage& fs ) const
+{
+    params.write(fs);
+    fs << "lastLocationX" << m_boundingBox.x;
+    fs << "lastLocationY" << m_boundingBox.y;
+    fs << "lastLocationW" << m_boundingBox.width;
+    fs << "lastLocationH" << m_boundingBox.height;
+    fs << "lastImage" << m_image;
+}
+
+} /* namespace cv */
diff --git a/mv_face/face/src/mv_face_open.cpp b/mv_face/face/src/mv_face_open.cpp
new file mode 100644 (file)
index 0000000..41f2398
--- /dev/null
@@ -0,0 +1,1048 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_face_open.h"
+
+#include "FaceDetector.h"
+#include "FaceUtil.h"
+#include "FaceRecognitionModel.h"
+#include "FaceTrackingModel.h"
+#include "FaceEyeCondition.h"
+#include "FaceExpressionRecognizer.h"
+
+#include "mv_private.h"
+
+#include <vector>
+#include <set>
+#include <cstring>
+
+using namespace ::MediaVision::Face;
+
+static const RecognitionParams defaultRecognitionParams = RecognitionParams();
+
+static void extractRecognitionParams(
+        mv_engine_config_h engine_cfg,
+        RecognitionParams& recognitionParams)
+{
+    mv_engine_config_h working_cfg = NULL;
+
+    if (NULL == engine_cfg)
+    {
+        mv_create_engine_config(&working_cfg);
+    }
+    else
+    {
+        working_cfg = engine_cfg;
+    }
+
+    int algType = 0;
+    mv_engine_config_get_int_attribute_c(
+            working_cfg,
+            "MV_FACE_RECOGNITION_MODEL_TYPE",
+            &algType);
+
+    if (0 < algType && 4 > algType)
+    {
+        recognitionParams.mRecognitionAlgType =
+                              (FaceRecognitionModelType)algType;
+    }
+    else
+    {
+        recognitionParams.mRecognitionAlgType =
+                              defaultRecognitionParams.mRecognitionAlgType;
+    }
+
+    if (NULL == engine_cfg)
+    {
+        mv_destroy_engine_config(working_cfg);
+    }
+}
+
+inline void convertRectCV2MV(const cv::Rect& src, mv_rectangle_s& dst)
+{
+    dst.point.x = src.x;
+    dst.point.y = src.y;
+    dst.width = src.width;
+    dst.height = src.height;
+}
+
+int mv_face_detect_open(
+    mv_source_h source,
+    mv_engine_config_h engine_cfg,
+    mv_face_detected_cb detected_cb,
+    void *user_data)
+{
+    cv::Mat image;
+
+    int error = convertSourceMV2GrayCV(source, image);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Convertion mv_source_h to gray failed");
+        return error;
+    }
+
+    char *haarcascadeFilepath;
+    error = mv_engine_config_get_string_attribute_c(
+                engine_cfg,
+                "MV_FACE_DETECTION_MODEL_FILE_PATH",
+                &haarcascadeFilepath);
+
+    //default path
+    std::string haarcascadeFilePathStr =
+            "/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml";
+
+    if (error == MEDIA_VISION_ERROR_NONE)
+    {
+        LOGI("Haarcascade file was set as default");
+        haarcascadeFilePathStr = std::string(haarcascadeFilepath);
+
+        delete[] haarcascadeFilepath;
+    }
+    else
+    {
+        LOGE("Error occurred during face detection haarcascade file receiving."
+                " (%i)", error);
+    }
+
+    static FaceDetector faceDetector;
+
+    if (!faceDetector.loadHaarcascade(haarcascadeFilePathStr))
+    {
+        LOGE("Loading Haarcascade failed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::Rect roi(-1, -1, -1, -1);
+    error = mv_engine_config_get_int_attribute_c(
+                engine_cfg,
+                MV_FACE_DETECTION_ROI_X,
+                &roi.x);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Error occurred during face detection roi (x) receiving."
+                " (%i)", error);
+    }
+
+    error = mv_engine_config_get_int_attribute_c(
+                engine_cfg,
+                MV_FACE_DETECTION_ROI_Y,
+                &roi.y);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Error occurred during face detection roi (y) receiving."
+                " (%i)", error);
+    }
+
+    error = mv_engine_config_get_int_attribute_c(
+                engine_cfg,
+                MV_FACE_DETECTION_ROI_WIDTH,
+                &roi.width);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Error occurred during face detection roi (width) receiving."
+                " (%i)", error);
+    }
+
+    error = mv_engine_config_get_int_attribute_c(
+                engine_cfg,
+                MV_FACE_DETECTION_ROI_HEIGHT,
+                &roi.height);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Error occurred during face detection roi (height) receiving."
+                " (%i)", error);
+    }
+
+    cv::Size minSize(-1, -1);
+    error = mv_engine_config_get_int_attribute_c(
+                engine_cfg,
+                MV_FACE_DETECTION_MIN_SIZE_WIDTH,
+                &minSize.width);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Error occurred during face detection minimum width receiving."
+                " (%i)", error);
+    }
+
+    error = mv_engine_config_get_int_attribute_c(
+                engine_cfg,
+                MV_FACE_DETECTION_MIN_SIZE_HEIGHT,
+                &minSize.height);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Error occurred during face detection minimum height receiving."
+                " (%i)", error);
+    }
+
+    std::vector<cv::Rect> faceLocations;
+    if (!faceDetector.detectFaces(image, roi, minSize, faceLocations))
+    {
+        LOGE("Face detection in OpenCV failed");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    static const int StartMaxResultsNumber = 50;
+    static std::vector<mv_rectangle_s> results(StartMaxResultsNumber);
+
+    const int numberOfResults = faceLocations.size();
+    if (numberOfResults > StartMaxResultsNumber)
+    {
+        results.resize(numberOfResults);
+    }
+
+    for(int rectNum = 0; rectNum < numberOfResults; ++rectNum)
+    {
+        convertRectCV2MV(faceLocations[rectNum], results[rectNum]);
+    }
+
+    LOGI("Call the detect callback for %i detected faces", numberOfResults);
+    detected_cb(source, engine_cfg, results.data(), numberOfResults, user_data);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_recognize_open(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        mv_face_recognized_cb recognized_cb,
+        void *user_data)
+{
+    if (!source)
+    {
+        LOGE("Can't recognize for the NULL Media Vision source handle");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+    if (!recognized_cb)
+    {
+        LOGE("Recognition failed. Can't output recognition results without "
+             "callback function");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+    if (!recognition_model)
+    {
+        LOGE("Can't recognize for the NULL Media Vision Face recognition model");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    FaceRecognitionModel *pRecModel = static_cast<FaceRecognitionModel*>(recognition_model);
+
+    if (!pRecModel)
+    {
+        LOGE("Face recognition failed. Incorrect Media Vision Face recognition model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::Mat grayImage;
+    int ret = convertSourceMV2GrayCV(source, grayImage);
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Convertion mv_source_h to gray failed");
+        return ret;
+    }
+
+    cv::Mat image;
+    if (NULL == face_location)
+    {
+        image = grayImage;
+    }
+    else
+    {
+        cv::Rect_<int> roi;
+        roi.x = face_location->point.x;
+        roi.y = face_location->point.y;
+        roi.width = face_location->width;
+        roi.height = face_location->height;
+        image = grayImage(roi);
+    }
+
+    FaceRecognitionResults results;
+
+    LOGD("Face recognition is started");
+
+    ret = pRecModel->recognize(image, results);
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred during the recognition. Failed");
+        return ret;
+    }
+
+    if (!results.mIsRecognized)
+    {
+        recognized_cb(
+                source,
+                recognition_model,
+                engine_cfg,
+                NULL,
+                NULL,
+                0.0,
+                user_data);
+    }
+    else
+    {
+        mv_rectangle_s location;
+        location.point.x = results.mFaceLocation.x;
+        location.point.y = results.mFaceLocation.y;
+        location.width = results.mFaceLocation.width;
+        location.height = results.mFaceLocation.height;
+
+        if (face_location != NULL)
+        {
+            location.point.x += face_location->point.x;
+            location.point.y += face_location->point.y;
+        }
+
+        recognized_cb(
+                source,
+                recognition_model,
+                engine_cfg,
+                &location,
+                &(results.mFaceLabel),
+                results.mConfidence,
+                user_data);
+    }
+
+    LOGD("Face recognition is finished");
+
+    return ret;
+}
+
+int mv_face_track_open(
+        mv_source_h source,
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_face_tracked_cb tracked_cb,
+        bool /*do_learn*/,
+        void *user_data)
+{
+    if (!source)
+    {
+        LOGE("Can't track for the NULL Media Vision source handle");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+    if (!tracked_cb)
+    {
+        LOGE("Tracking failed. Can't output tracking results without "
+             "callback function");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+    if (!tracking_model)
+    {
+        LOGE("Can't track for the NULL Media Vision Face tracking model");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    FaceTrackingModel *pTrackModel =
+            static_cast<FaceTrackingModel*>(tracking_model);
+
+    if (!pTrackModel)
+    {
+        LOGE("Face tracking failed. "
+             "Incorrect Media Vision Face tracking model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::Mat grayImage;
+    int ret = convertSourceMV2GrayCV(source, grayImage);
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Convertion mv_source_h to gray failed");
+        return ret;
+    }
+
+    FaceTrackingResults results;
+    ret = pTrackModel->track(grayImage, results);
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Tracking can't be performed. "
+             "Check that tracking model is prepared when tracking starts");
+        return ret;
+    }
+
+    if (results.mIsTracked)
+    {
+        mv_quadrangle_s predictedLocation;
+        predictedLocation.points[0].x = results.mFaceLocation.x;
+        predictedLocation.points[0].y = results.mFaceLocation.y;
+        predictedLocation.points[1].x =
+                results.mFaceLocation.x + results.mFaceLocation.width;
+        predictedLocation.points[1].y = results.mFaceLocation.y;
+        predictedLocation.points[2].x =
+                results.mFaceLocation.x + results.mFaceLocation.width;
+        predictedLocation.points[2].y =
+                results.mFaceLocation.y + results.mFaceLocation.height;
+        predictedLocation.points[3].x = results.mFaceLocation.x;
+        predictedLocation.points[3].y =
+                results.mFaceLocation.y + results.mFaceLocation.height;
+        tracked_cb(
+                source,
+                tracking_model,
+                engine_cfg,
+                &predictedLocation,
+                results.mConfidence,
+                user_data);
+    }
+    else
+    {
+        tracked_cb(
+                source,
+                tracking_model,
+                engine_cfg,
+                NULL,
+                results.mConfidence,
+                user_data);
+    }
+
+    return ret;
+}
+
+int mv_face_eye_condition_recognize_open(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_eye_condition_recognized_cb eye_condition_recognized_cb,
+        void *user_data)
+{
+    cv::Mat image;
+
+    int error = convertSourceMV2GrayCV(source, image);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Convertion mv_source_h to gray failed");
+        return error;
+    }
+
+    mv_face_eye_condition_e eye_condition;
+    error = FaceEyeCondition::recognizeEyeCondition(
+                                  image,
+                                  face_location,
+                                  &eye_condition);
+
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("eye contition recognition failed");
+        return error;
+    }
+
+    eye_condition_recognized_cb(
+                source,
+                engine_cfg,
+                face_location,
+                eye_condition,
+                user_data);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_facial_expression_recognize_open(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_facial_expression_recognized_cb expression_recognized_cb,
+        void *user_data)
+{
+    cv::Mat image;
+
+    int error = convertSourceMV2GrayCV(source, image);
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Convertion mv_source_h to gray failed");
+        return error;
+    }
+
+    mv_face_facial_expression_e expression;
+    error = FaceExpressionRecognizer::recognizeFaceExpression(
+                                          image, face_location, &expression);
+
+    if (error != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("eye contition recognition failed");
+        return error;
+    }
+
+    expression_recognized_cb(
+                source,
+                engine_cfg,
+                face_location,
+                expression,
+                user_data);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_recognition_model_create_open(
+        mv_face_recognition_model_h *recognition_model)
+{
+    if (recognition_model == NULL)
+    {
+        LOGE("Recognition model can't be created because handle pointer is NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    (*recognition_model) =
+            static_cast<mv_face_recognition_model_h>(new (std::nothrow)FaceRecognitionModel());
+
+    if (*recognition_model == NULL)
+    {
+        LOGE("Failed to create media vision recognition model");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    LOGD("Recognition model [%p] has been created", *recognition_model);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_recognition_model_destroy_open(
+        mv_face_recognition_model_h recognition_model)
+{
+    if (!recognition_model)
+    {
+        LOGE("Recognition model can't be destroyed because handle is NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Destroying media vision recognition model [%p]", recognition_model);
+    delete static_cast<FaceRecognitionModel*>(recognition_model);
+    LOGD("Media vision recognition model has been destroyed");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_recognition_model_clone_open(
+        mv_face_recognition_model_h src,
+        mv_face_recognition_model_h *dst)
+{
+    if (!src || !dst)
+    {
+        LOGE("Can't clone recognition model. Both source and destination"
+             "recognition model handles has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    (*dst) = static_cast<mv_face_recognition_model_h>(new (std::nothrow)FaceRecognitionModel());
+
+    if (*dst == NULL)
+    {
+        LOGE("Failed to create media vision recognition model");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    LOGD("Recognition model [%p] has been created", *dst);
+
+    const FaceRecognitionModel *pSrcModel = static_cast<FaceRecognitionModel*>(src);
+    FaceRecognitionModel *pDstModel = static_cast<FaceRecognitionModel*>(*dst);
+
+    *pDstModel = *pSrcModel;
+
+    LOGD("Media vision recognition model has been cloned");
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_recognition_model_save_open(
+        const char *file_name,
+        mv_face_recognition_model_h recognition_model)
+{
+    if (!recognition_model)
+    {
+        LOGE("Can't save recognition model to the file. Handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (NULL == file_name)
+    {
+        LOGE("Can't save recognition model to the file. File name has to be specified");
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    FaceRecognitionModel *pRecModel = static_cast<FaceRecognitionModel*>(recognition_model);
+    const int ret = pRecModel->save(std::string(file_name));
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred when save recognition model to the file");
+        return ret;
+    }
+
+    LOGD("Media vision recognition model has been saved to the file [%s]", file_name);
+    return ret;
+}
+
+int mv_face_recognition_model_load_open(
+        const char *file_name,
+        mv_face_recognition_model_h *recognition_model)
+{
+    if (!recognition_model)
+    {
+        LOGE("Can't load recognition model from the file. "
+             "Handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (NULL == file_name)
+    {
+        LOGE("Can't load recognition model from the file. "
+             "File name has to be specified");
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    (*recognition_model) =
+        static_cast<mv_face_recognition_model_h>(new (std::nothrow)FaceRecognitionModel());
+
+    if (*recognition_model == NULL)
+    {
+        LOGE("Failed to create media vision recognition model");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    FaceRecognitionModel *pRecModel =
+            static_cast<FaceRecognitionModel*>(*recognition_model);
+
+    if (!pRecModel)
+    {
+        LOGE("Loading of the face recognition model from file failed. "
+             "Incorrect Media Vision Face recognition model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    const int ret = pRecModel->load(std::string(file_name));
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred when loading recognition model to the file");
+        return ret;
+    }
+
+    LOGD("Media vision recognition model has been loaded from the file [%s]", file_name);
+    return ret;
+}
+
+int mv_face_recognition_model_add_open(
+        const mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        const mv_rectangle_s *example_location,
+        int face_label)
+{
+    if (!source)
+    {
+        LOGE("Can't add face image example for recognition model. "
+             "Media Vision source handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!recognition_model)
+    {
+        LOGE("Can't add face image example for recognition model. "
+             "Model handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    FaceRecognitionModel *pRecModel =
+            static_cast<FaceRecognitionModel*>(recognition_model);
+
+    if (!pRecModel)
+    {
+        LOGE("Add face image example to the model failed. "
+             "Incorrect Media Vision Face recognition model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::Mat image;
+    int ret = convertSourceMV2GrayCV(source, image);
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Convertion mv_source_h to gray failed");
+        return ret;
+    }
+
+    if (!example_location)
+    {
+        ret = pRecModel->addFaceExample(image, face_label);
+    }
+    else
+    {
+        cv::Rect_<int> roi;
+        roi.x = example_location->point.x;
+        roi.y = example_location->point.y;
+        roi.width = example_location->width;
+        roi.height = example_location->height;
+        ret = pRecModel->addFaceExample(image(roi).clone(), face_label);
+    }
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred when adding face image example to the recognition model");
+        return ret;
+    }
+
+    LOGD("The face image example labeled %i has been added "
+         "to the Media Vision recognition model", face_label);
+    return ret;
+}
+
+int mv_face_recognition_model_reset_open(
+        mv_face_recognition_model_h recognition_model,
+        const int *face_label)
+{
+    if (!recognition_model)
+    {
+        LOGE("Can't reset positive examples for NULL recognition model");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    FaceRecognitionModel *pRecModel =
+            static_cast<FaceRecognitionModel*>(recognition_model);
+
+    if (!pRecModel)
+    {
+        LOGE("Loading of the face recognition model from file failed. "
+             "Incorrect Media Vision Face recognition model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = (NULL != face_label ?
+               pRecModel->resetFaceExamples(*face_label) :
+               pRecModel->resetFaceExamples());
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred when reset positive examples of the recognition model");
+        return ret;
+    }
+
+    LOGD("The positive examples has been removed from recognition model");
+    return ret;
+}
+
+int mv_face_recognition_model_learn_open(
+        mv_engine_config_h engine_cfg,
+        mv_face_recognition_model_h recognition_model)
+{
+    if (!recognition_model)
+    {
+        LOGE("Can't learn recognition model. Model handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    FaceRecognitionModel *pRecModel =
+            static_cast<FaceRecognitionModel*>(recognition_model);
+
+    if (!pRecModel)
+    {
+        LOGE("Learning of the face recognition model failed. "
+             "Incorrect Media Vision Face recognition model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    RecognitionParams recognitionParams;
+    extractRecognitionParams(engine_cfg, recognitionParams);
+    FaceRecognitionModelConfig learnConfig;
+    learnConfig.mModelType = recognitionParams.mRecognitionAlgType;
+
+    const int ret = pRecModel->learn(learnConfig);
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred when learn face recognition model");
+        return ret;
+    }
+
+    LOGD("Face recognition model has been learned");
+    return ret;
+}
+
+int mv_face_recognition_model_query_labels_open(
+        mv_face_recognition_model_h recognition_model,
+        int **labels,
+        unsigned int *number_of_labels)
+{
+    if (!recognition_model)
+    {
+        LOGE("Can't get list of labels for NULL recognition model");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (NULL == labels || NULL == number_of_labels)
+    {
+        LOGE("Can't get list of labels. labels and number_of_labels out "
+             "parameters both has to be not NULL.");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    FaceRecognitionModel *pRecModel =
+                static_cast<FaceRecognitionModel*>(recognition_model);
+
+    if (!pRecModel)
+    {
+        LOGE("Learning of the face recognition model failed. "
+             "Incorrect Media Vision Face recognition model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    const std::set<int>& learnedLabels = pRecModel->getFaceLabels();
+    *number_of_labels = learnedLabels.size();
+    (*labels) = new int[*number_of_labels];
+
+    std::set<int>::const_iterator it = learnedLabels.begin();
+    int i = 0;
+    for (; it != learnedLabels.end(); ++it)
+    {
+        (*labels)[i] = *it;
+        ++i;
+    }
+
+    LOGD("List of the labels learned by the recognition model has been retrieved");
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_tracking_model_create_open(
+        mv_face_tracking_model_h *tracking_model)
+{
+    if (tracking_model == NULL)
+    {
+        LOGE("Tracking model can't be created because handle pointer is NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    (*tracking_model) =
+            static_cast<mv_face_tracking_model_h>(new (std::nothrow)FaceTrackingModel());
+
+    if (*tracking_model == NULL)
+    {
+        LOGE("Failed to create media vision tracking model");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    LOGD("Tracking model [%p] has been created", *tracking_model);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_tracking_model_destroy_open(
+        mv_face_tracking_model_h tracking_model)
+{
+    if (!tracking_model)
+    {
+        LOGE("Tracking model can't be destroyed because handle is NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGD("Destroying media vision tracking model [%p]", tracking_model);
+    delete static_cast<FaceTrackingModel*>(tracking_model);
+    LOGD("Media vision tracking model has been destroyed");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_tracking_model_prepare_open(
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h /*engine_cfg*/,
+        mv_source_h source,
+        mv_quadrangle_s *location)
+{
+    if (!tracking_model)
+    {
+        LOGE("Can't prepare tracking model. Handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!source)
+    {
+        LOGE("Can't prepare tracking model. "
+             "Media Vision source handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    FaceTrackingModel *pTrackModel =
+            static_cast<FaceTrackingModel*>(tracking_model);
+
+    if (!pTrackModel)
+    {
+        LOGE("Preparation of the face tracking model failed. "
+             "Incorrect Media Vision Face tracking model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::Mat image;
+    int ret = convertSourceMV2GrayCV(source, image);
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Convertion mv_source_h to gray failed");
+        return ret;
+    }
+
+    cv::Rect_<double> roi;
+    if (!location)
+    {
+        ret = pTrackModel->prepare(image);
+    }
+    else
+    {
+        int minX = image.cols;
+        int minY = image.rows;
+        int maxX = 0.0;
+        int maxY = 0.0;
+        for (unsigned i = 0; i < 4; ++i)
+        {
+            minX = minX > location->points[i].x ? location->points[i].x : minX;
+            minY = minY > location->points[i].y ? location->points[i].y : minY;
+            maxX = maxX < location->points[i].x ? location->points[i].x : maxX;
+            maxY = maxY < location->points[i].y ? location->points[i].y : maxY;
+        }
+
+        roi.x = minX;
+        roi.y = minY;
+        roi.width = maxX - minX;
+        roi.height = maxY - minY;
+        ret = pTrackModel->prepare(image, roi);
+    }
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred when prepare face tracking model");
+        return ret;
+    }
+
+    LOGD("Face tracking model has been prepared");
+
+    return ret;
+}
+
+int mv_face_tracking_model_clone_open(
+        mv_face_tracking_model_h src,
+        mv_face_tracking_model_h *dst)
+{
+    if (!src || !dst)
+    {
+        LOGE("Can't clone tracking model. Both source and destination"
+             "tracking model handles has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    (*dst) = static_cast<mv_face_tracking_model_h>(new (std::nothrow)FaceTrackingModel());
+
+    if (*dst == NULL)
+    {
+        LOGE("Failed to create media vision tracking model");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    LOGD("Tracking model [%p] has been created", *dst);
+
+    const FaceTrackingModel *pSrcModel = static_cast<FaceTrackingModel*>(src);
+    FaceTrackingModel *pDstModel = static_cast<FaceTrackingModel*>(*dst);
+
+    *pDstModel = *pSrcModel;
+
+    LOGD("Media vision tracking model has been cloned");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_tracking_model_save_open(
+        const char *file_name,
+        mv_face_tracking_model_h tracking_model)
+{
+    if (!tracking_model)
+    {
+        LOGE("Can't save tracking model to the file. "
+             "Handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (NULL == file_name)
+    {
+        LOGE("Can't save tracking model to the file. "
+             "File name has to be specified");
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    FaceTrackingModel *pTrackModel = static_cast<FaceTrackingModel*>(tracking_model);
+
+    if (!pTrackModel)
+    {
+        LOGE("Saving of the face tracking model to file failed. "
+             "Incorrect Media Vision Face tracking model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    const int ret = pTrackModel->save(std::string(file_name));
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred when save tracking model to the file");
+        return ret;
+    }
+
+    LOGD("Media vision tracking model has been saved to the file [%s]", file_name);
+
+    return ret;
+}
+
+int mv_face_tracking_model_load_open(
+        const char *file_name,
+        mv_face_tracking_model_h *tracking_model)
+{
+    if (!tracking_model)
+    {
+        LOGE("Can't load tracking model from the file. "
+             "Handle has to be not NULL");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (NULL == file_name)
+    {
+        LOGE("Can't load tracking model from the file. "
+             "File name has to be specified");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    (*tracking_model) =
+        static_cast<mv_face_tracking_model_h>(new (std::nothrow)FaceTrackingModel());
+
+    if (*tracking_model == NULL)
+    {
+        LOGE("Failed to create media vision tracking model");
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    FaceTrackingModel *pTrackModel =
+            static_cast<FaceTrackingModel*>(*tracking_model);
+
+    if (!pTrackModel)
+    {
+        LOGE("Loading of the face tracking model from file failed. "
+             "Incorrect Media Vision Face tracking model handle is used");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    const int ret = pTrackModel->load(std::string(file_name));
+
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Error occurred when save recognition model to the file");
+        return ret;
+    }
+
+    LOGD("Media vision recognition model has been loaded from the file [%s]", file_name);
+
+    return ret;
+}
diff --git a/mv_face/face_lic/CMakeLists.txt b/mv_face/face_lic/CMakeLists.txt
new file mode 100644 (file)
index 0000000..905f56f
--- /dev/null
@@ -0,0 +1,25 @@
+project(${MV_FACE_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_FACE_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_FACE_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.c")
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_FACE_INC_LIST} ${MV_FACE_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_FACE_INC_LIST} ${MV_FACE_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_face/face_lic/include/mv_face_lic.h b/mv_face/face_lic/include/mv_face_lic.h
new file mode 100644 (file)
index 0000000..dec74b4
--- /dev/null
@@ -0,0 +1,778 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_FACE_LIC_H__
+#define __TIZEN_MEDIAVISION_FACE_LIC_H__
+
+#include "mv_face.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_face_lic.h
+ * @brief This file contains the Media Vision Face licensed API
+ */
+
+/******************/
+/* Face detection */
+/******************/
+
+/**
+ * @brief Performs face detection on the @a source for the @a engine_conf.
+ * @details Use this function to launch face detection algorithm configured by
+ *          @a engine_conf configuration. Each time when mv_face_detect_lic is
+ *          called, @a detected_cb will receive a set of the detected
+ *          faces at the media source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source         The handle to the source of the media where faces
+ *                            will be detected
+ * @param [in] engine_cfg     The handle to the configuration of engine will be
+ *                            used for detecting. If NULL, then default settings
+ *                            will be used.
+ * @param [in] detected_cb    The callback which will be called for all face
+ *                            locations detected on media source. This callback
+ *                            will receive detecting results
+ * @param [in] user_data      The user data passed from the code where
+ *                            @ref mv_face_detect_lic() is invoked. This data will be
+ *                            accessible from @a detected_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @post @a detected_cb will be called to process detection results
+ *
+ * @see mv_face_detected_cb
+ */
+int mv_face_detect_lic(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_face_detected_cb detected_cb,
+        void *user_data);
+
+
+/********************/
+/* Face recognition */
+/********************/
+
+/**
+ * @brief Performs face recognition on the @a source image.
+ * @details Use this function to launch face recognition algorithm configured by
+ *          @a engine_conf configuration using @a recognition_model recognition
+ *          model. Each time when @ref mv_face_recognize_lic() is called,
+ *          @a recognized_cb will receive recognition results:\n
+ *          - Location in the @a source of the face has been recognized;
+ *          - Label of the face has been recognized;
+ *          - Confidence of the @a recognition_model that face has been
+ *            recognized correctly (value from 0.0 to 1.0).
+ *
+ * @since_tizen 3.0
+ * @remarks Using of untrained or weakly trained recognition models will cause
+ *          not accurate results even if resulting confidence will be high.
+ *          Use @ref mv_face_recognition_model_learn_lic() function before
+ *          @ref mv_face_recognize_lic() call. Best results can be achieved
+ *          when big set of face image examples were added by
+ *          @ref mv_face_recognition_model_add_lic() before
+ *          @ref mv_face_recognition_model_learn_lic() call.
+ * @param [in] source              The handle to the source of the media to
+ *                                 recognize face(s) for
+ * @param [in] recognition_model   The handle to the model will be used for
+ *                                 recognition
+ * @param [in] engine_cfg          The handle to the configuration of engine
+ *                                 will be used for recognition. If NULL, then
+ *                                 default settings will be used
+ * @param [in] face_location       Rectangular box bounding face image on the
+ *                                 @a source. If NULL, then full source will be
+ *                                 analyzed
+ * @param [in] recognized_cb       The callback which will be called for the
+ *                                 face recognition results on the @a source.
+ * @param [in] user_data           The user data passed from the code where
+ *                                 @ref mv_face_recognize_lic() is invoked.
+ *                                 This data will be accessible from
+ *                                 @a recognized_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create a face recognition model handle by calling
+ *      @ref mv_face_recognition_model_create_lic()
+ * @post @a recognized_cb will be called to process recognition results
+ *
+ * @see mv_face_recognized_cb
+ */
+int mv_face_recognize_lic(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        mv_face_recognized_cb recognized_cb,
+        void *user_data);
+
+
+/*****************/
+/* Face tracking */
+/*****************/
+
+/**
+ * @brief Performs face tracking on the @a source for the @a tracking_model.
+ * @details Use this function to launch face tracking algorithm configured by
+ *          @a engine_conf configuration using @a tracking_model tracking
+ *          model. Each time when this function is called, @a tracked_cb
+ *          will receive updated @a tracking_model, new location determined for
+ *          the tracked face and model confidence that location is determined
+ *          correctly.
+ *
+ * @since_tizen 3.0
+ * @remarks To allow correct tracking @a tracking_model has to be already used
+ *          in previous tracking process(es) or prepared with
+ *          @ref mv_face_tracking_model_prepare_lic(). Preparation requires
+ *          specifying the face location for the @a source on which tracking was
+ *          started. I.e. @ref mv_face_tracking_model_prepare_lic() function
+ *          has to be called at least once before this method call.
+ * @param [in] source           The handle to the source of the media to
+ *                              recognize face for
+ * @param [in] tracking_model   The handle to the model will be used for
+ *                              tracking
+ * @param [in] engine_cfg       The handle to the configuration of engine will
+ *                              be used for tracking. If NULL, the default
+ *                              configuration will be used.
+ * @param [in] tracked_cb       The callback which will be called for tracking
+ *                              event on the @a source where face would be
+ *                              tracked. This callback will receive tracking
+ *                              results
+ * @param [in] do_learn         The model learning flag. If it is set @c true
+ *                              then model will try to learn (if it supports
+ *                              learning feature), otherwise model will be not
+ *                              learned during the invoking tracking iteration.
+ *                              Learning process improves tracking correctness,
+ *                              but can decrease tracking performance
+ * @param [in] user_data        The user data passed from the code where
+ *                              @ref mv_face_track_lic() is invoked. This data
+ *                              will be accessible from @a tracked_cb callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create a face tracking model handle by calling
+ *      @ref mv_face_tracking_model_create_lic()
+ * @post @a tracked_cb will be called to process tracking results
+ *
+ * @see mv_face_tracked_cb
+ */
+int mv_face_track_lic(
+        mv_source_h source,
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_face_tracked_cb tracked_cb,
+        bool do_learn,
+        void *user_data);
+
+
+/********************************/
+/* Recognition of eye condition */
+/********************************/
+
+/**
+ * @brief Determines eye-blink condition for @a face_location on media @a source.
+ * @details Use this function to recognize eye-blink condition for the face
+ *          bounded by @a face_location at @a source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source           The handle to the source of the media to
+ *                              recognize eye-blink condition for
+ * @param [in] engine_cfg       The handle to the configuration of engine
+ *                              will be used for eye-blink condition
+ *                              recognition. If NULL, the default configuration
+ *                              will be used.
+ * @param [in] face_location    The location bounding the face at the @a source
+ * @param [in] eye_condition_recognized_cb    The callback for processing result
+ *                              of eye-blink condition recognition
+ * @param [in] user_data        The user data passed from the code where
+ *                              @ref mv_face_eye_condition_recognize_lic() is
+ *                              invoked. This data will be accessible from
+ *                              @a eye_condition_recognized_cb callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ *
+ * @see mv_face_eye_condition_recognized_cb
+ */
+int mv_face_eye_condition_recognize_lic(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_eye_condition_recognized_cb eye_condition_recognized_cb,
+        void *user_data);
+
+
+/************************************/
+/* Recognition of facial expression */
+/************************************/
+
+/**
+ * @brief Determines facial expression for @a face_location on media @a source.
+ * @details Use this function to determine facial expression for the face
+ *          bounded by @a face_location at @a source.
+ *
+ * @since_tizen 3.0
+ * @param [in] source           The handle to the source of the media
+ *                              to recognize facial expression for
+ * @param [in] engine_cfg       The handle to the configuration of
+ *                              engine will be used for expression recognition
+ * @param [in] face_location    The location bounding the face at the @a source
+ * @param [in] expression_recognized_cb   The callback for processing result
+ *                              of facial expression determining
+ * @param [in] user_data        The user data passed from the code where
+ *                              @ref mv_face_facial_expression_recognize_lic() is
+ *                              invoked. This data will be accessible from
+ *                              @a expression_recognized_cb callback.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create a face engine configuration handle by calling @ref mv_create_engine_config()
+ *
+ * @see mv_face_facial_expression_recognized_cb
+ */
+int mv_face_facial_expression_recognize_lic(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_facial_expression_recognized_cb expression_recognized_cb,
+        void *user_data);
+
+/*******************************/
+/* Recognition model behavior */
+/*******************************/
+
+/**
+ * @brief Creates a face recognition model handle.
+ * @details Use this function to create default face recognition model. Creating
+ *          process is defined by concrete face engine library. After creation
+ *          recognition model has to be learned with
+ *          @ref mv_face_recognition_model_learn_lic() function to provide
+ *          appropriate results of face recognition functionality. Or learned
+ *          earlier model can be loaded by
+ *          @ref mv_face_recognition_model_load_lic() function.
+ *
+ * @since_tizen 3.0
+ * @remarks It can cause incompatibility issues when saved models (see
+ *          @ref mv_face_recognition_model_save_lic(),
+ *          @ref mv_face_recognition_model_load_lic() functions documentation)
+ *          are used in applications for different platforms which use different
+ *          computer vision libraries underlying this API.
+ * @remarks You must release @a recognition_model by using
+ *          @ref mv_face_recognition_model_destroy_lic() function.
+ * @param [out] recognition_model    The handle to the recognition model to be
+ *                                   created
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post Model can be loaded from the file after creation. Use
+ *       @ref mv_face_recognition_model_load_lic() function to load it from file
+ * @post Release @a recognition_model by using
+ *       @ref mv_face_recognition_model_destroy_lic() function when it is not needed
+ *       anymore
+ *
+ * @see mv_face_recognition_model_destroy_lic()
+ */
+int mv_face_recognition_model_create_lic(
+        mv_face_recognition_model_h *recognition_model);
+
+/**
+ * @brief Destroys the face recognition model handle and releases all its
+ *        resources.
+ *
+ * @since_tizen 3.0
+ * @param [in] recognition_model    The handle to the face recognition model to
+ *                                  be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create recognition model by using @ref mv_face_recognition_model_create_lic()
+ *
+ * @see mv_face_recognition_model_create_lic()
+ */
+int mv_face_recognition_model_destroy_lic(
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Creates a copy of existed recognition model handle and clones all its
+ *        resources.
+ *
+ * @since_tizen 3.0
+ * @remarks Cloning perform not only handle copy, but also copies all internal
+ *          resources of the model. @a dst must be released using
+ *          @a mv_face_recognition_model_destroy_open_lic().
+ * @param [in]     src    The handle to the recognition model to be copied
+ * @param [out]    dst    The handle to the copy of existed recognition model
+ *                        specified as @a src
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create face recognition handles by calling
+ *      @ref mv_face_recognition_model_create_lic()
+ *
+ * @see mv_face_recognition_model_create_lic()
+ */
+int mv_face_recognition_model_clone_lic(
+        mv_face_recognition_model_h src,
+        mv_face_recognition_model_h *dst);
+
+/**
+ * @brief Saves recognition model to the file.
+ *
+ * @since_tizen 3.0
+ * @remarks This function doesn't save added by
+ *          @ref mv_face_recognition_model_add_lic() function face
+ *          image examples. This examples can be removed by
+ *          @ref mv_face_recognition_model_reset_lic() function
+ *          if it is needed to clear the memory.
+ * @remarks After model is saved to the file, it can be loaded from this file
+ *          by @ref mv_face_recognition_model_load_lic() function.
+ * @param [in] file_name            Name of the file to save the model
+ * @param [in] recognition_model    The handle to the recognition model to be
+ *                                  saved to the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face recognition handle by calling
+ *      @ref mv_face_recognition_model_create_lic() function
+ * @post Saved model can be loaded later by calling
+ *      @ref mv_face_recognition_model_load_lic() function
+ *
+ * @see mv_face_recognition_model_load_lic()
+ * @see mv_face_recognition_model_create_lic()
+ */
+int mv_face_recognition_model_save_lic(
+        const char *file_name,
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Loads recognition model from file.
+ *
+ * @since_tizen 3.0
+ * @remarks This function doesn't modify the set of face image examples added
+ *          with @ref mv_face_recognition_model_add_lic() function.
+ *          Model will be loaded from file without loss of collected examples.
+ *          If you want to free memory from examples, use
+ *          @ref mv_face_recognition_model_reset_lic() function.
+ *          It is recommended to clear the memory if learning algorithm doesn't
+ *          support reinforcement learning.
+ * @remarks @a recognition_model is loaded from the application's data directory.
+ *          @a recognition_model must be destroyed using
+ *          @ref mv_face_recognition_model_destroy_open_lic().
+ * @param [in]  file_name            Name of file to load the model
+ * @param [out] recognition_model    The handle to the recognition model
+ *                                   to be loaded from the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face recognition handle by calling
+ *      @ref mv_face_recognition_model_create_lic() function
+ *
+ * @see mv_face_recognition_model_save_lic()
+ * @see mv_face_recognition_model_create_lic()
+ */
+int mv_face_recognition_model_load_lic(
+        const char *file_name,
+        mv_face_recognition_model_h *recognition_model);
+
+/**
+ * @brief Adds face image example to be used for face recognition model learning
+ *        with @ref mv_face_recognition_model_learn_lic().
+ *
+ * @since_tizen 3.0
+ * @remarks It is possible to destroy @a source after calling this method.
+ *          Source isn't used for learning directly.
+ * @remarks Face image @a example_location location can be determined using
+ *          @ref mv_face_detect_lic function.
+ * @param [in] source               The handle to @a source that contains face
+ *                                  image
+ * @param [in] recognition_model    The handle to the recognition model which
+ *                                  could be learned based on example
+ * @param [in] example_location     The pointer to the rectangular location of
+ *                                  the face image at the source image. If NULL,
+ *                                  then full image will be analyzed as the face
+ *                                  image
+ * @param [in] face_label           The label that identifies face for which
+ *                                  example is adding. Specify the same labels
+ *                                  for the face images of a single person when
+ *                                  calling this method. Has to be unique for
+ *                                  each face
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face recognition handle by calling
+ *      @ref mv_face_recognition_model_create_lic() function
+ * @post When appropriate amount of face image examples is added to the
+ *       @a recognition_model, this model has to be learned by
+ *       @ref mv_face_recognition_model_learn_lic() function call. Only after
+ *       learning of the model it can be used for face recognition with
+ *       @a mv_face_recognize_lic() function
+ *
+ * @see mv_face_recognition_model_reset_lic()
+ * @see mv_face_recognition_model_learn_lic()
+ */
+int mv_face_recognition_model_add_lic(
+        const mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        const mv_rectangle_s *example_location,
+        int face_label);
+
+/**
+ * @brief Remove from @a recognition_model all collected with
+ *        @ref mv_face_recognition_model_add_lic() function
+ *        face examples labeled with @a face_label.
+ *
+ * @since_tizen 3.0
+ * @remarks Be aware that if this function is called before
+ *          @ref mv_face_recognition_model_learn_lic() function call, all or
+ *          part of the required for learning data will be lost. It means that
+ *          face image examples determined by the @a face_label label will be
+ *          removed from the model and not taken taken into account when
+ *          @ref mv_face_recognition_model_learn_lic() will be called next
+ *          time.
+ * @remarks Call of this function will free all the memory has been allocated
+ *          during previous
+ *          @ref mv_face_recognition_model_add_lic() calls for
+ *          the corresponding @a face_label label.
+ * @param [in] recognition_model    The handle to the recognition model for
+ *                                  which face image examples will be reset.
+ * @param [in] face_label           The label that identifies face for which
+ *                                  examples will be removed from the
+ *                                  @a recognition_model. If NULL, then all
+ *                                  known by @a recognition_model face image
+ *                                  examples will be removed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_face_recognition_model_add_lic()
+ * @see mv_face_recognition_model_learn_lic()
+ */
+int mv_face_recognition_model_reset_lic(
+        mv_face_recognition_model_h recognition_model,
+        const int *face_label);
+
+/**
+ * @brief Learns face recognition model.
+ * @details Before you start learning process, face recognition models has to be
+ *          filled with training data - face image examples. These examples has
+ *          to be provided by
+ *          mv_face_recognition_model_add_lic() function. Usually,
+ *          recognition accuracy is increased when number of not identical
+ *          examples is large. But it depends of the used learning algorithm.
+ *
+ * @since_tizen 3.0
+ * @remarks Common flow is to collect face examples as much as possible, add
+ *          them to the recognition model with
+ *          @ref mv_face_recognition_model_add_lic(), then call
+ *          @ref mv_face_recognition_model_learn_lic() for this recognition
+ *          model to learn it (or reinforce the model if reinforcement learning
+ *          is supported by the used algorithm).
+ * @remarks Selection of the learning algorithm can be performed by setting
+ *          corresponding attributes for the @a engine_cfg. You can check
+ *          supported by @a engine_cfg attributes using
+ *          @ref mv_engine_config_foreach_supported_attribute() function call.
+ * @param [in]     engine_cfg           The handle to the configuration of
+ *                                      engine will be used for learning of the
+ *                                      recognition models. If NULL, then
+ *                                      default settings will be used
+ * @param [in,out] recognition_model    The model which will be learned. After
+ *                                      learning process these model may be
+ *                                      changed, so
+ *                                      @ref mv_face_recognize_lic() results
+ *                                      may differ before and after method call
+ *                                      respectively to the face examples
+ *                                      collected for the @a recognition_model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face engine configuration handle by calling
+ *      @ref mv_create_engine_config() and set supported parameters if
+ *      needed. Or just set @a engine_cfg as NULL to learn with default settings
+ * @pre Create a face recognition model handles by calling
+ *      @ref mv_face_recognition_model_create_lic() function
+ * @pre Add face image examples to the @a recognition_model by calling
+ *      @ref mv_face_recognition_model_add_lic() function
+ * @post If it is not planned to learn the model again, clear memory by
+ *       @ref mv_face_recognition_model_reset_lic() function
+ * @post When model has been learned, it can be used for face recognition with
+ *       @ref mv_face_recognize_lic() function
+ *
+ * @see mv_face_recognition_model_add_lic()
+ * @see mv_face_recognition_model_reset_lic()
+ * @see mv_face_recognize_lic()
+ */
+int mv_face_recognition_model_learn_lic(
+        mv_engine_config_h engine_cfg,
+        mv_face_recognition_model_h recognition_model);
+
+/**
+ * @brief Queries labels list and number of labels had been learned by the model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a labels array has to be released using free().
+ * @param [in]  recognition_model    The handle to the recognition model for
+ *                                   which set of the learned labels will be
+ *                                   queried
+ * @param [out] labels               The array which will be filled with labels
+ *                                   had been learned by the model
+ * @param [out] number_of_labels     The number of labels in @a labels array
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Add face image examples with labels to the @a recognition_model by
+ *      calling the @ref mv_face_recognition_model_add_lic()
+ *      function
+ * @pre Learn the @a recognition_model by labeled examples using
+ *      @ref mv_face_recognition_model_learn_lic() function
+ * @post @a labels array has to be freed in the function invoking code
+ *
+ * @see mv_face_recognition_model_add_lic()
+ * @see mv_face_recognition_model_reset_lic()
+ * @see mv_face_recognition_model_learn_lic()
+ */
+int mv_face_recognition_model_query_labels_lic(
+        mv_face_recognition_model_h recognition_model,
+        int **labels,
+        unsigned int *number_of_labels);
+
+/***************************/
+/* Tracking model behavior */
+/***************************/
+
+/**
+ * @brief Calls this function to create a face tracking model handle.
+ * @details Use this function to create default face tracking model handle.
+ *          After creation this handle has to be initialized with
+ *          @ref mv_face_tracking_model_prepare_lic() function to provide
+ *          appropriate results of face tracking functionality. When handle is
+ *          prepared, it is possible to use it for tracking on continuous
+ *          sequence of the sources. Call
+ *          @ref mv_face_tracking_model_prepare_lic() function each time before
+ *          starting tracking on the new sequence. The exception is situation
+ *          when the new sequence is continuation of the previous sequence for
+ *          which model has been tracked.
+ *
+ * @since_tizen 3.0
+ * @param [out] tracking_model    The pointer to the handle to the tracking
+ *                                model that will be created
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post Model can be loaded from the file after creation. Use
+ *       @ref mv_face_tracking_model_load_lic() function to load it from file
+ * @post Use @ref mv_face_tracking_model_prepare_lic() function before tracking
+ *       on the new video or continuous images sequence
+ * @post You must release @a tracking_model by using
+ *       mv_face_tracking_model_destroy_lic() function when it is not needed
+ *       anymore
+ *
+ * @see mv_face_tracking_model_destroy_lic()
+ * @see mv_face_tracking_model_prepare_lic()
+ * @see mv_face_tracking_model_load_lic()
+ */
+int mv_face_tracking_model_create_lic(
+        mv_face_tracking_model_h *tracking_model);
+
+/**
+ * @brief Calls this function to destroy the face tracking model handle and
+ *        release all its resources.
+ *
+ * @since_tizen 3.0
+ * @param [in] tracking_model    The handle to the face tracking model that
+ *                               will be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create tracking model by using @ref mv_face_tracking_model_create_lic()
+ *
+ * @see mv_face_tracking_model_create_lic()
+ */
+int mv_face_tracking_model_destroy_lic(
+        mv_face_tracking_model_h tracking_model);
+
+/**
+ * @brief Calls this function to initialize tracking model by the location of the
+ *        face to be tracked.
+ * @details This function is usually called once after tracking model is created
+ *          and each time before tracking is started for the new sequence of
+ *          sources which is not the direct continuation of the sequence for
+ *          which tracking has been performed before. But it is allowed to call
+ *          it between tracking sessions to allow Media Vision start to track
+ *          more accurately.
+ *
+ * @since_tizen 3.0
+ * @param [in] tracking_model    The handle to the tracking model that will be
+ *                               prepared for tracking on new video or image
+ *                               sequence
+ * @param [in] engine_cfg        The handle to the configuration of engine
+ *                               will be used for model preparing. If NULL, then
+ *                               default settings will be used.
+ * @param [in] source            The handle to the source where face @a location
+ *                               is specified. Usually it is the first frame of
+ *                               the video or the first image in the continuous
+ *                               image sequence planned to be used for tracking
+ * @param [in] location          The quadrangle-shaped location (actually,
+ *                               rectangle can be used) determining position
+ *                               of the face to be tracked on the @a source. If
+ *                               @c NULL, then tracking model will try to find
+ *                               previously tracked face by itself. Don't set
+ *                               NULL when called first time for the tracking
+ *                               model.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face tracking model handle by calling
+ *      @ref mv_face_tracking_model_create_lic() function
+ * @pre Create a source handle by calling @ref mv_create_source() function
+ * @post When model is prepared, @ref mv_face_track_lic() function can be used
+ *       to track on the video or continuous image sequence
+ *
+ * @see mv_face_tracking_model_create_lic()
+ * @see mv_face_track_lic()
+ */
+int mv_face_tracking_model_prepare_lic(
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_quadrangle_s *location);
+
+/**
+ * @brief Calls this function to make a copy of existed tracking model handle and
+ *        clone all its resources to the copy.
+ *
+ * @since_tizen 3.0
+ * @remarks Cloning performs not only handle copy, but also copies all internal
+ *          resources of the model.
+ * @param [in]     src    The handle to the tracking model to be copied
+ * @param [out]    dst    The handle to the copy of existed tracking model
+ *                        specified as @a src
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create face tracking @a src and @a dst handles by calling
+ *      @ref mv_face_tracking_model_create_lic()
+ *
+ * @see mv_face_tracking_model_create_lic()
+ */
+int mv_face_tracking_model_clone_lic(
+        mv_face_tracking_model_h src,
+        mv_face_tracking_model_h *dst);
+
+/**
+ * @brief Calls this method to save tracking model to the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @ tracking_model is saved to the application's data directory.
+ *          After model is saved to the file, it can be loaded from this file
+ *          with @ref mv_face_tracking_model_load_lic() function.
+ * @param [in] file_name         Name of the file to save the model
+ * @param [in] tracking_model    The handle to the tracking model to be
+ *                               saved to the file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a face tracking handle by calling
+ *      @ref mv_face_tracking_model_create_lic()
+ * @post Saved model can be loaded from file using
+ *       @ref mv_face_tracking_model_load_lic() function
+ *
+ * @see mv_face_tracking_model_load_lic()
+ * @see mv_face_tracking_model_create_lic()
+ */
+int mv_face_tracking_model_save_lic(
+        const char *file_name,
+        mv_face_tracking_model_h tracking_model);
+
+/**
+ * @brief Calls this method to load a tracking model from file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a tracking_model is loaded from the application's data directory.
+ *          @a tracking_model must be destroyed using
+ *          @ref mv_face_tracking_model_destroy_lic().
+ * @param [in] file_name         Name of file to load the model
+ * @param [out] tracking_model   The handle to the tracking model to be
+ *                               loaded from file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Models has been saved by @ref mv_face_tracking_model_save_lic()
+ *      function can be loaded with this function
+ * @post After model has been loaded and if further tracking will be performed
+ *       on the video which is not continuation of the last tracking performed
+ *       for the model, it is recommended to call
+ *       @ref mv_face_tracking_model_prepare_lic() function
+ *
+ * @see mv_face_tracking_model_save_lic()
+ * @see mv_face_tracking_model_create_lic()
+ */
+int mv_face_tracking_model_load_lic(
+        const char *file_name,
+        mv_face_tracking_model_h *tracking_model);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_FACE_LIC_H__ */
diff --git a/mv_face/face_lic/src/mv_face_lic.c b/mv_face/face_lic/src/mv_face_lic.c
new file mode 100644 (file)
index 0000000..00a516e
--- /dev/null
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_face_lic.h"
+
+/******************/
+/* Face detection */
+/******************/
+
+int mv_face_detect_lic(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_face_detected_cb detected_cb,
+        void *user_data)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+
+/********************/
+/* Face recognition */
+/********************/
+
+int mv_face_recognize_lic(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        mv_face_recognized_cb recognized_cb,
+        void *user_data)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+
+/*****************/
+/* Face tracking */
+/*****************/
+
+int mv_face_track_lic(
+        mv_source_h source,
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_face_tracked_cb tracked_cb,
+        bool do_learn,
+        void *user_data)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+
+/********************************/
+/* Recognition of eye condition */
+/********************************/
+
+int mv_face_eye_condition_recognize_lic(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_eye_condition_recognized_cb eye_condition_recognized_cb,
+        void *user_data)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+
+/************************************/
+/* Recognition of facial expression */
+/************************************/
+
+int mv_face_facial_expression_recognize_lic(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_facial_expression_recognized_cb expression_recognized_cb,
+        void *user_data)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+
+/******************************/
+/* Recognition model behavior */
+/******************************/
+
+int mv_face_recognition_model_create_lic(
+        mv_face_recognition_model_h *recognition_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_recognition_model_destroy_lic(
+        mv_face_recognition_model_h recognition_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_recognition_model_clone_lic(
+        mv_face_recognition_model_h src,
+        mv_face_recognition_model_h *dst)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_recognition_model_save_lic(
+        const char *file_name,
+        mv_face_recognition_model_h recognition_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_recognition_model_load_lic(
+        const char *file_name,
+        mv_face_recognition_model_h recognition_model_h)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_recognition_model_add_lic(
+        const mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        const mv_rectangle_s *example_location,
+        int face_label)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_recognition_model_reset_lic(
+        mv_face_recognition_model_h recognition_model,
+        const int *face_label)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_recognition_model_learn_lic(
+        mv_engine_config_h engine_cfg,
+        mv_face_recognition_model_h recognition_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_recognition_model_query_labels_lic(
+        mv_face_recognition_model_h recognition_model,
+        int **labels,
+        unsigned int *number_of_labels)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+
+/***************************/
+/* Tracking model behavior */
+/***************************/
+
+int mv_face_tracking_model_create_lic(
+        mv_face_tracking_model_h *tracking_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_tracking_model_destroy_lic(
+        mv_face_tracking_model_h tracking_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_tracking_model_prepare_lic(
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_quadrangle_s *location)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_tracking_model_clone_lic(
+        mv_face_tracking_model_h src,
+        mv_face_tracking_model_h *dst)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_tracking_model_save_lic(
+        const char *file_name,
+        mv_face_tracking_model_h tracking_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_face_tracking_model_load_lic(
+        const char *file_name,
+        mv_face_tracking_model_h tracking_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
diff --git a/mv_image/CMakeLists.txt b/mv_image/CMakeLists.txt
new file mode 100644 (file)
index 0000000..36d2037
--- /dev/null
@@ -0,0 +1,8 @@
+project(mv_image_port)
+cmake_minimum_required(VERSION 2.6)
+
+if(MEDIA_VISION_IMAGE_PORT)
+    add_subdirectory(${PROJECT_SOURCE_DIR}/image_lic) # Licensed port
+else()
+    add_subdirectory(${PROJECT_SOURCE_DIR}/image) # Open port
+endif()
diff --git a/mv_image/image/CMakeLists.txt b/mv_image/image/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0269712
--- /dev/null
@@ -0,0 +1,33 @@
+project(${MV_IMAGE_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_IMAGE_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_IMAGE_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp")
+
+find_package(OpenCV REQUIRED core highgui imgproc objdetect features2d calib3d)
+if(NOT OpenCV_FOUND)
+    message(SEND_ERROR "Failed to find OpenCV")
+    return()
+else()
+    include_directories(${OpenCV_INCLUDE_DIRS})
+endif()
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_IMAGE_INC_LIST} ${MV_IMAGE_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_IMAGE_INC_LIST} ${MV_IMAGE_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME} ${OpenCV_LIBS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_image/image/include/ImageConfig.h b/mv_image/image/include/ImageConfig.h
new file mode 100644 (file)
index 0000000..2d43430
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGEUTIL_H__
+#define __IMAGEUTIL_H__
+
+#include <opencv/cv.h>
+
+/**
+ * @file  ImageUtil.h
+ * @brief This file contains Image Module utility.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+/**
+ * @brief Contains parameters for features extracting from image objects.
+ *
+ * @since_tizen 3.0
+ */
+struct FeaturesExtractingParams
+{
+    FeaturesExtractingParams(
+            double scaleFactor,
+            int maximumFeaturesNumber);
+
+    FeaturesExtractingParams();
+
+    double mScaleFactor; /**< Recognition scale factor for the ORB detector. */
+
+    int mMaximumFeaturesNumber; /**< Maximum number of features, which will be
+            extracted from object image. */
+};
+
+/**
+ * @brief Contains parameters for image objects recognition.
+ *
+ * @since_tizen 3.0
+ */
+struct RecognitionParams
+{
+    RecognitionParams(
+            int minMatchesNumber,
+            double requiredMatchesPart,
+            double allowableMatchesPartError);
+
+    RecognitionParams();
+
+    int mMinMatchesNumber; /**< The minimum matches number, which
+            will be taken into account for image objects recognition. */
+
+    double mRequiredMatchesPart; /**< The part of matches, which will be taken
+            into account for image objects recognition. Too low value will
+            result in unsustainable behavior, but effect of object overlapping
+            will be reduced. Value can be from 0 to 1.*/
+
+    double mAllowableMatchesPartError; /**< Allowable error of matches number. */
+};
+
+/**
+ * @brief Contains parameters for contour stabilization during tracking of image
+ *        objects.
+ *
+ * @since_tizen 3.0
+ */
+struct StabilizationParams
+{
+    StabilizationParams(
+            int historyAmount,
+            double allowableShift,
+            double stabilizationSpeed,
+            double stabilizationAcceleration);
+
+    StabilizationParams();
+
+    int mHistoryAmount; /**< Number of previous recognition results, which
+            will influence the stabilization. */
+
+    double mAllowableShift; /**< Relative value of maximum shift per one frame,
+            which will be ignored by stabilization (relative to the object size
+            in the current frame). */
+
+    double mStabilizationSpeed; /**< Start speed with which the object will be
+            stabilized. */
+
+    double mStabilizationAcceleration; /**< Acceleration with which the object
+            will be stabilized. (relative to the distance from current location
+            to stabilized location). Value can be from 0 to 1.*/
+};
+
+/**
+ * @brief Contains parameters for image objects tracking.
+ *
+ * @since_tizen 3.0
+ */
+struct TrackingParams
+{
+    TrackingParams(
+            FeaturesExtractingParams framesFeaturesExtractingParams,
+            RecognitionParams recognitionParams,
+            StabilizationParams stabilizationParams,
+            double expectedOffset);
+
+    TrackingParams();
+
+    FeaturesExtractingParams mFramesFeaturesExtractingParams; /**< Parameters
+            for extracting features from frames. */
+
+    RecognitionParams mRecognitionParams; /**< Parameters for intermediate
+            recognition. */
+
+    StabilizationParams mStabilizationParams; /**< Parameters for contour
+            stabilization during tracking. */
+
+    double mExpectedOffset; /**< Relative offset value, for which expected the
+            object offset. (relative to the object size in the current
+            frame). */
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGEUTIL_H__ */
diff --git a/mv_image/image/include/ImageContourStabilizator.h b/mv_image/image/include/ImageContourStabilizator.h
new file mode 100644 (file)
index 0000000..1fae797
--- /dev/null
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGECONTOURSTABILIZATOR_H__
+#define __IMAGECONTOURSTABILIZATOR_H__
+
+#include "ImageConfig.h"
+
+#include <opencv/cv.h>
+
+/**
+ * @file  ImageContourStabilizator.h
+ * @brief This file contains functionality for image contour stabilization
+ *        during tracking.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+/**
+ * @class    ImageContourStabilizator
+ * @brief    This class contains functionality for image contour stabilization
+ *           during tracking.
+ *
+ * @since_tizen 3.0
+ */
+class ImageContourStabilizator
+{
+public:
+
+    /**
+     * @brief   @ref ImageContourStabilizator default constructor.
+     *
+     * @since_tizen 3.0
+     */
+    ImageContourStabilizator();
+
+    /**
+     * @brief Stabilizes @a contour.
+     *
+     * @since_tizen 3.0
+     * @remarks Call this function alternately for each contour from sequence
+     * @param [in,out] contour   @ref contour, which will be stabilized
+     * @param [in]     params    configuration parameters
+     * @return true if contour is stabilized, otherwise return false
+     */
+    bool stabilize(
+            std::vector<cv::Point2f>& contour,
+            const StabilizationParams& params);
+
+    /**
+     * @brief Resets stabilization process.
+     *
+     * @since_tizen 3.0
+     * @remarks Call it before starting track on the new sequence of contours.
+     */
+    void reset(void);
+
+private:
+
+    std::vector<cv::Point2f> computeStabilizedQuadrangleContour(void);
+
+private:
+
+    static const size_t MovingHistoryAmount = 3u;
+
+    std::vector<float> m_speeds;
+
+    std::vector<size_t> m_currentCornersSpeed;
+
+    std::deque<std::vector<cv::Point2f> > m_movingHistory;
+
+    std::vector<cv::Point2f> m_lastStabilizedContour;
+
+    size_t m_currentHistoryAmount;
+
+    int m_tempContourIndex;
+
+    std::vector<float> m_priorities;
+
+    bool m_isPrepared;
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGECONTOURSTABILIZATOR_H__ */
diff --git a/mv_image/image/include/ImageMathUtil.h b/mv_image/image/include/ImageMathUtil.h
new file mode 100644 (file)
index 0000000..ebc95d7
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MATHUTIL_H__
+#define __MATHUTIL_H__
+
+#include <opencv/cv.h>
+
+/**
+ * @file  MathUtil.h
+ * @brief This file contains math utility for Image Module.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+const size_t MinimumNumberOfFeatures = 4u; /* Minimum number of features
+                                              when perspective transform
+                                              parameters calculation
+                                              have sense */
+
+const size_t NumberOfQuadrangleCorners = 4u; /* Number of quadrangle corneres */
+
+/**
+ * @brief   Calculates Euclidean distance between two points.
+ *
+ * @since_tizen 3.0
+ * @param [in] point1   The first point
+ * @param [in] point2   The second point
+ * @return distance between two points
+ */
+float getDistance(
+        const cv::Point2f& point1,
+        const cv::Point2f& point2);
+
+/**
+ * @brief   Calculates area of triangle.
+ *
+ * @since_tizen 3.0
+ * @param [in] point1   The first corner of triangle
+ * @param [in] point2   The second corner of triangle
+ * @param [in] point3   The third corner of triangle
+ * @return area of triangle
+ */
+float getTriangleArea(
+        const cv::Point2f& point1,
+        const cv::Point2f& point2,
+        const cv::Point2f& point3);
+
+/**
+ * @brief   Calculates area of quadrangle.
+ *
+ * @since_tizen 3.0
+ * @param [in] points   Four corners of quadrangle
+ * @return area of quadrangle
+ */
+float getQuadrangleArea(
+        const cv::Point2f points[NumberOfQuadrangleCorners]);
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __MATHUTIL_H__ */
diff --git a/mv_image/image/include/ImageObject.h b/mv_image/image/include/ImageObject.h
new file mode 100644 (file)
index 0000000..a494554
--- /dev/null
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGEOBJECT_H__
+#define __IMAGEOBJECT_H__
+
+#include "ImageConfig.h"
+
+#include <opencv/cv.h>
+
+/**
+ * @file  ImageObject.h
+ * @brief This file contains the @ref ImageObject class.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+/**
+ * @class    ImageObject
+ * @brief    This class contains the image information, which will
+ *           be used in recognition algorithms.
+ *
+ * @since_tizen 3.0
+ */
+class ImageObject
+{
+
+public:
+
+    /**
+     * @brief   @ref ImageObject default constructor.
+     *
+     * @since_tizen 3.0
+     */
+    ImageObject();
+
+    /**
+     * @brief   @ref ImageObject constructor based on image.
+     *
+     * @since_tizen 3.0
+     * @remarks Detects keypoints and extracts features from image and creates
+     *          new @ref ImageObject
+     * @param [in] image    The image for which instance of @ref ImageObject
+     *                      will be created
+     * @param [in] params   Features extracting parameters
+     */
+    ImageObject(const cv::Mat& image, const FeaturesExtractingParams& params);
+
+    /**
+     * @brief   @ref ImageObject copy constructor.
+     * @details Creates copy of @ref ImageObject
+     *
+     * @since_tizen 3.0
+     * @param   [in] copy @ref ImageObject which will be copied
+     */
+    ImageObject(const ImageObject& copy);
+
+    /**
+     * @brief   @ref ImageObject copy assignment operator.
+     * @details Fills the information based on the @a copy
+     *
+     * @since_tizen 3.0
+     * @param   [in] copy @ref ImageObject which will be copied
+     *
+     */
+    ImageObject& operator=(const ImageObject& copy);
+
+    /**
+     * @brief   @ref ImageObject destructor.
+     *
+     * @since_tizen 3.0
+     */
+    virtual ~ImageObject();
+
+    /**
+     * @brief   Fills @ref ImageObject class based on image.
+     * @details Detects keypoints and extracts features from image and creates
+     *          new @ref ImageObject
+     *
+     * @since_tizen 3.0
+     * @param [in] image    The image for which instance of @ref ImageObject
+     *                      will be created
+     * @param [in] params   Features extracting parameters
+     */
+    void fill(const cv::Mat& image, const FeaturesExtractingParams& params);
+
+    /**
+     * @brief   Fills @ref ImageObject class based on image.
+     * @details Detects keypoints and extracts features from image and creates
+     *          new @ref ImageObject
+     *
+     * @since_tizen 3.0
+     * @param [in] image         The image for which instance of @ref
+     *                           ImageObject will be created
+     * @param [in] boundingBox   Bounding box of the object being analyzed in
+     *                           the @a image
+     * @param [in] params        Features extracting parameters
+     * @return @a true on success, otherwise a @a false value
+     * @retval true  Successful
+     * @retval false Invalid ROI (bounding box)
+     */
+    bool fill(
+            const cv::Mat& image,
+            const cv::Rect& boundingBox,
+            const FeaturesExtractingParams& params);
+
+    /**
+     * @brief Gets a value that determines how well an @ref ImageObject can be recognized.
+     * @details Confidence can be from 0 to 1. If the recognition rate is 0 object can
+     *          not be recognized
+     *
+     * @since_tizen 3.0
+     * @return A value that determines how well an @ref ImageObject can be recognized.
+     */
+    float getRecognitionRate(void) const;
+
+    /**
+     * @brief Check whether the object is filled.
+     * @details Image object is empty if it wasn't filled.
+     *
+     * @since_tizen 3.0
+     * @remarks Empty object can not be recognized or tracked. Fill the object
+     *          by using corresponding constructor or function @ref fill() to
+     *          make image object valid. Also you can load image object which is
+     *          not empty by using @ref load().
+     * @return @c false if object is filled, otherwise return @c true
+     */
+    bool isEmpty() const;
+
+    /**
+     * @brief Sets a label for the image object.
+     *
+     * @since_tizen 3.0
+     * @param [in] label   The label which will be assigned to the image object
+     */
+    void setLabel(int label);
+
+    /**
+     * @brief Gets a label of object.
+     *
+     * @since_tizen 3.0
+     * @param [out] label   The label of image object
+     * @return @c true if object is labeled, otherwise return @c false
+     */
+    bool getLabel(int& label) const;
+
+    /**
+     * @brief  Stores the @ref ImageObject in a file.
+     *
+     * @since_tizen 3.0
+     * @param  [in] fileName  File name which will be generated
+     * @return @a 0 on success, otherwise a negative error value
+     */
+    int save(const char *fileName) const;
+
+    /**
+     * @brief  Loads the @ref ImageObject from the file.
+     *
+     * @since_tizen 3.0
+     * @param  [in] fileName  File name from which will be loaded an @ref ImageObject
+     * @return @a 0 on success, otherwise a negative error value
+     */
+    int load(const char *fileName);
+
+private:
+
+    static const int MinWidth = 5;
+    static const int MinHeight = 5;
+
+private:
+
+    void extractFeatures(
+            const cv::Mat& image,
+            const FeaturesExtractingParams& params);
+
+    void computeRecognitionRate(const cv::Mat& image);
+
+private:
+
+    bool m_isEmpty;
+
+    bool m_isLabeled;
+
+    int m_label;
+
+    std::vector<cv::Point2f> m_boundingContour;
+
+    std::vector<cv::KeyPoint> m_objectKeypoints;
+
+    cv::Mat m_objectDescriptors;
+
+    float m_recognitionRate;
+
+    friend class ImageRecognizer;
+
+    friend std::ostream& operator << (std::ostream& os, const ImageObject& obj);
+
+    friend std::istream& operator >> (std::istream& is, ImageObject& obj);
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGEOBJECT_H__ */
diff --git a/mv_image/image/include/ImageRecognizer.h b/mv_image/image/include/ImageRecognizer.h
new file mode 100644 (file)
index 0000000..8494e3a
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGERECOGNIZER_H__
+#define __IMAGERECOGNIZER_H__
+
+#include "ImageMathUtil.h"
+#include "ImageConfig.h"
+#include "ImageObject.h"
+
+#include <opencv/cv.h>
+
+/**
+ * @file  ImageRecognizer.h
+ * @brief This file contains functionality for image object recognition.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+/**
+ * @class    ImageRecognizer
+ * @brief    This class contains functionality for image object recognition.
+ *
+ * @since_tizen 3.0
+ */
+class ImageRecognizer
+{
+public:
+
+    /**
+     * @brief   @ref ImageRecognizer constructor based on scene image.
+     *
+     * @since_tizen 3.0
+     * @param [in] sceneImage   The scene in which image objects will be recognized
+     * @param [in] params       Scene features extracting parameters
+     */
+    ImageRecognizer(const cv::Mat& sceneImage,
+            const FeaturesExtractingParams& params);
+
+    /**
+     * @brief   @ref ImageRecognizer constructor based on thes scene @ref ImageObject.
+     *
+     * @since_tizen 3.0
+     * @param [in] scene   The scene for which the objects will be recognized by
+     *                     calling method recognize()
+     */
+    ImageRecognizer(const ImageObject& scene);
+
+    /**
+     * @brief   @ref ImageRecognizer destructor.
+     *
+     * @since_tizen 3.0
+     */
+    virtual ~ImageRecognizer();
+
+    /**
+     * @brief Recognizes the @a target on the scene.
+     *
+     * @since_tizen 3.0
+     * @param [in]  target    @ref ImageObject, which will be recognized
+     * @param [in]  params    Recognition parameters
+     * @param [out] contour   The result contour of @a target object on the scene
+     * @return true if object is found on the scene, otherwise return false
+     */
+    bool recognize(
+            const ImageObject& target,
+            const RecognitionParams& params,
+            std::vector<cv::Point2f>& contour) const;
+
+private:
+
+    ImageRecognizer();
+
+    bool findHomophraphyMatrix(
+            const ImageObject& target,
+            const RecognitionParams& params,
+            cv::Mat& homophraphyMatrix) const;
+
+    size_t matchesSelection(
+            std::vector<cv::DMatch>& examples,
+            unsigned int filterAmount, unsigned int allowableError) const;
+
+    float computeLinearSupportElement(
+            const std::vector<cv::DMatch>& examples,
+            int requiredNumber, int leftLimit, int rightLimit) const;
+
+    static bool isPossibleQuadrangleCorners(
+            const cv::Point2f corners[NumberOfQuadrangleCorners]);
+
+private:
+
+    ImageObject m_scene;
+
+    cv::BFMatcher m_matcher;
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGERECOGNIZER_H__ */
diff --git a/mv_image/image/include/ImageTracker.h b/mv_image/image/include/ImageTracker.h
new file mode 100644 (file)
index 0000000..2bfd5b1
--- /dev/null
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGETRACKER_H__
+#define __IMAGETRACKER_H__
+
+#include "ImageConfig.h"
+
+#include <opencv/cv.h>
+
+/**
+ * @file  ImageTracker.h
+ * @brief This file contains functionality for image object tracking.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+class ImageRecognizer;
+class ImageTrackingModel;
+
+/**
+ * @class    ImageTracker
+ * @brief    This class contains functionality for image object tracking.
+ *
+ * @since_tizen 3.0
+ */
+class ImageTracker
+{
+private:
+
+    struct RecognitionInfo
+    {
+        cv::Mat mFrame;
+
+        RecognitionParams mRecognitionParams;
+
+        FeaturesExtractingParams mSceneFeaturesExtractingParams;
+
+        ImageTrackingModel *mpTarget;
+    };
+
+    static void *recognitionThreadFunc(void *recognitionInfo);
+
+public:
+
+    /**
+     * @brief   @ref ImageTracker constructor based on tracking algorithm
+     *          parameters.
+     *
+     * @since_tizen 3.0
+     * @param [in] trackingParams   Parameters for image objects tracking
+     */
+    ImageTracker(const TrackingParams& trackingParams);
+
+    /**
+     * @brief Tracks the @a target for the video stream consisting of frames.
+     *
+     * @since_tizen 3.0
+     * @remarks Call this function alternately for each frame
+     * @param [in]      frame    Current frame of the video stream
+     * @param [in,out]  target   @ref ImageTrackingModel, which will be tracked
+     */
+    void track(const cv::Mat& frame, ImageTrackingModel& target);
+
+private:
+
+    void trackDetectedObject(
+            const cv::Mat& frame,
+            ImageTrackingModel& target);
+
+    void trackUndetectedObject(
+            const cv::Mat& frame,
+            ImageTrackingModel& target);
+
+    cv::Rect computeExpectedArea(
+            const ImageTrackingModel& target,
+            const cv::Size& frameSize);
+
+private:
+
+    TrackingParams m_trackingParams;
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGETRACKER_H__ */
diff --git a/mv_image/image/include/ImageTrackingModel.h b/mv_image/image/include/ImageTrackingModel.h
new file mode 100644 (file)
index 0000000..2f55c2d
--- /dev/null
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGETRACKINGMODEL_H__
+#define __IMAGETRACKINGMODEL_H__
+
+#include "ImageObject.h"
+
+#include "ImageContourStabilizator.h"
+
+#include <opencv/cv.h>
+
+#include <pthread.h>
+
+#include <vector>
+#include <list>
+
+/**
+ * @file  ImageTrackingModel.h
+ * @brief This file contains the @ref ImageTrackingModel class.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+class ImageContourStabilizator;
+
+/**
+ * @class    ImageTrackingModel
+ * @brief    This class contains the tracking functionality for image objects.
+ *
+ * @since_tizen 3.0
+ */
+class ImageTrackingModel
+{
+private:
+    /**
+     * @brief   @ref ImageTrackingModel state enumeration.
+     *
+     * @since_tizen 3.0
+     */
+    enum State
+    {
+        Invalid,     /**< Invalid tracking model can not be tracked. Set not
+                          empty image object as target by using function
+                          @ref setTarget() to make tracking model valid, also
+                          you can load valid tracking model by using @ref load() */
+        Undetected,  /**< The object was not recognized on the last frame. Ready
+                          for further recognition */
+        Appeared,    /**< The object was recognized on one of the last frames
+                          after its absence  */
+        Tracked,    /**< The object was recognized on the last frame. Its
+                         location can be obtained by calling method getLocation() */
+        InProcess    /**< The object is in the recognition process */
+    };
+
+public:
+
+    /**
+     * @brief   @ref ImageTrackingModel default constructor
+     *
+     * @since_tizen 3.0
+     */
+    ImageTrackingModel();
+
+    /**
+     * @brief   @ref ImageTrackingModel constructor based on tracking algorithm
+     *          parameters.
+     *
+     * @since_tizen 3.0
+     * @param[in] recognitionObject  @ref ImageObject which will be tracked
+     */
+    ImageTrackingModel(const ImageObject& recognitionObject);
+
+    /**
+     * @brief   @ref ImageTrackingModel copy constructor.
+     * @details Creates copy of @ref ImageTrackingModel
+     *
+     * @since_tizen 3.0
+     * @param   [in] copy @ref ImageTrackingModel which will be copied
+     */
+    ImageTrackingModel(const ImageTrackingModel& copy);
+
+    /**
+     * @brief   @ref ImageTrackingModel destructor.
+     *
+     * @since_tizen 3.0
+     */
+    ~ImageTrackingModel();
+
+    /**
+     * @brief   Sets @ref ImageObject as target which will be tracked.
+     *
+     * @since_tizen 3.0
+     * @param [in] target @ref ImageObject which will be tracked
+     */
+    void setTarget(const ImageObject& target);
+
+    /**
+     * @brief Checks whether the tracking model is valid for tracking.
+     * @details Image tracking model is valid if its target is set and not empty.
+     *
+     * @since_tizen 3.0
+     * @remarks Invalid tracking model can not be tracked. Set not empty target
+     *          by using corresponding constructor or function @ref setTarget()
+     *          to make tracking model valid. Also you can load valid tracking
+     *          model by using @ref load().
+     * @return @c true if tracking model is valid, otherwise return @c false
+     */
+    bool isValid() const;
+
+    /**
+     * @brief   Refreshes tracking model.
+     *
+     * @since_tizen 3.0
+     * @remarks Call it before starting track on the new video stream.
+     */
+    void refresh(void);
+
+    /**
+     * @brief   @ref ImageTrackingModel copy assignment operator.
+     * @details Fills the information based on the @a copy
+     *
+     * @since_tizen 3.0
+     * @param   [in] copy @ref ImageTrackingModel which will be copied
+     */
+    ImageTrackingModel& operator=(const ImageTrackingModel& copy);
+
+    /**
+     * @brief  Stores the @ref ImageTrackingModel in a file.
+     *
+     * @since_tizen 3.0
+     * @param  [in] filepath  File name which will be generated
+     * @return @a 0 on success, otherwise a negative error value
+     */
+    int save(const char *filepath) const;
+
+    /**
+     * @brief  Loads the @ref ImageTrackingModel from the file.
+     *
+     * @since_tizen 3.0
+     * @param  [in] filepath  File name from which will be loaded a model
+     * @return @a 0 on success, otherwise a negative error value
+     */
+    int load(const char *filepath);
+
+    /**
+     * @brief  Checks state of the @ref ImageTrackingModel.
+     *
+     * @since_tizen 3.0
+     * @return @a true if object was detected on the last processed frame,
+     *         otherwise a @a false value
+     */
+    bool isDetected() const;
+
+    /**
+     * @brief  Gets last location of the @ref ImageTrackingModel.
+     *
+     * @since_tizen 3.0
+     * @return Last detected location
+     */
+    std::vector<cv::Point2f> getLastlocation() const;
+
+private:
+
+    ImageObject m_recognitionObject;
+
+    ImageContourStabilizator m_stabilizator;
+
+    std::vector<cv::Point2f> m_lastLocation;
+
+    State m_state;
+
+    pthread_t m_recognitionThread;
+
+    mutable pthread_mutex_t m_globalGuard;
+
+    mutable pthread_spinlock_t m_lastLocationGuard;
+
+    mutable pthread_spinlock_t m_stateGuard;
+
+    friend std::ostream& operator << (
+            std::ostream& os,
+            const ImageTrackingModel::State& state);
+
+    friend std::istream& operator >> (
+            std::istream& is,
+            ImageTrackingModel::State& state);
+
+    friend std::ostream& operator << (
+            std::ostream& os,
+            const ImageTrackingModel& obj);
+
+    friend std::istream& operator >> (
+            std::istream& is,
+            ImageTrackingModel& obj);
+
+    friend class ImageTracker;
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGETRACKINGMODEL_H__ */
diff --git a/mv_image/image/include/mv_image_open.h b/mv_image/image/include/mv_image_open.h
new file mode 100644 (file)
index 0000000..f6128fd
--- /dev/null
@@ -0,0 +1,561 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_IMAGE_OPEN_H__
+#define __TIZEN_MEDIAVISION_IMAGE_OPEN_H__
+
+#include "mv_image.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_image_open.h
+ * @brief This file contains the Media Vision Image API for the open module.
+ *        Working with images (like planar objects): recognition and tracking.
+ */
+
+/****************************/
+/* Image object recognition */
+/****************************/
+
+/**
+ * @brief Recognizes the given image objects on the source image.
+ * @details Use this function to launch image recognition algorithm configured
+ *          by @a engine_conf configuration.
+ *
+ * @since_tizen 3.0
+ * @param [in] source              The handle to the source image on which image
+ *                                 objects will be recognized
+ * @param [in] image_objects       The set of handles to the image objects which
+ *                                 will be processed as targets of recognition
+ * @param [in] number_of_objects   The number of image objects
+ * @param [in] engine_cfg          The handle to the configuration of engine
+ *                                 which will be used for recognition. If NULL,
+ *                                 then default settings will be used.
+ * @param [in] recognized_cb       The callback which will be called in order to
+ *                                 process recognition result
+ * @param [in] user_data           The user data to be passed to the
+ *                                 @a recognized_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ *
+ * @pre Create a set of image objects using @ref mv_image_object_create_open()
+ *      for each of them and construct (fill / load / clone) them on images that
+ *      will be recognized
+ * @pre Create a source handle by calling @ref mv_create_source() and fill
+ *      by the image for which recognition will be performed
+ * @post @a mv_image_recognized_cb will be called to process recognition result
+ * @post Release source image by using @ref mv_destroy_source()
+ * @post Release image objects by using @ref mv_image_object_destroy_open() for
+ *       each handle from @a image_objects set
+ *
+ * @see mv_image_recognized_cb
+ * @see mv_source_h
+ * @see mv_create_source()
+ * @see mv_destroy_source()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ * @see mv_engine_config_h
+ */
+int mv_image_recognize_open(
+        mv_source_h source,
+        const mv_image_object_h *image_objects,
+        int number_of_objects,
+        mv_engine_config_h engine_cfg,
+        mv_image_recognized_cb recognized_cb,
+        void *user_data);
+
+/*************************/
+/* Image object tracking */
+/*************************/
+
+/**
+ * @brief Tracks the given image tracking model on the current frame
+ * @details Image tracking on a sequence of frames assumes calling this
+ *          function for each frame in the correct order.
+ *          @a tracked_cb will be called  for result processing.
+ *
+ * @since_tizen 3.0
+ * @remarks Tracking algorithm is usually using for recognition of image object
+ *          on the sequence of images that are organized by time. For example,
+ *          it may be the sequence of frames from a video stream.
+ * @remarks If object is lost during the tracking, system tries to find it
+ *          further for the following frames. Therefore, tracking will be
+ *          recovered when object appears again.
+ * @remarks Previous calls of @ref mv_image_track_open() for this
+ *          @a image_tracking_model will affect on current call
+ * @param [in]     source                 The handle to the current image of
+ *                                        sequence where image tracking model
+ *                                        will be tracked
+ * @param [in,out] image_tracking_model   The handle to the image tracking model
+ *                                        which processed as target of tracking
+ * @param [in]     engine_cfg             The handle to the configuration of
+ *                                        engine which will be used for tracking.
+ *                                        If NULL, then default settings will be
+ *                                        used.
+ * @param [in]     tracked_cb             The callback which will receive
+ *                                        tracking results
+ * @param [in]     user_data              The user data to be passed to the
+ *                                        @a tracked_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create_open() and set target by calling
+ *      @ref mv_image_tracking_model_set_target_open()
+ * @pre Create a source images by calling @ref mv_create_source() for each of
+ *      them and construct them based on sequence of images for which will be
+ *      held image tracking
+ * @post @a tracked_cb will be called to process tracking result
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy_open()
+ *
+ * @see mv_image_tracked_cb
+ * @see mv_source_h
+ * @see image_tracking_model_h
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_tracking_model_set_target_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_track_open(
+        mv_source_h source,
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_image_tracked_cb tracked_cb,
+        void *user_data);
+
+/**************************/
+/* Image object behaviour */
+/**************************/
+
+/**
+ * @brief Creates an image object.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_object    A new handle to the image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Release image object by using mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_create_open(
+        mv_image_object_h *image_object);
+
+/**
+ * @brief Destroys the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object    The handle to the image object to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_image_object_create_open()
+ */
+int mv_image_object_destroy_open(
+        mv_image_object_h image_object);
+
+/**
+ * @brief Fills the image object.
+ * @details Extracts data from @a source image which will be needed for
+ *          recognition of depicted object in @a location.
+ *
+ * @since_tizen 3.0
+ * @remarks After filling the image object it can be evaluated by
+ *          @ref mv_image_object_get_recognition_rate_open(). If recognition
+ *          rate is too low, try to use another image of object or change
+ *          configuration parameters (see @ref mv_engine_config_h) and construct
+ *          the image object again.
+ * @param [in,out] image_object    The handle to the image object which will be
+ *                                 filled and can be recognized in future
+ * @param [in]     engine_cfg      The handle to the configuration of engine
+ *                                 which will be used for extract recognition
+ *                                 data from @a source. If NULL, then default
+ *                                 settings will be used.
+ * @param [in]     source          The source image where image object is depicted
+ * @param [in]     location        The pointer to location of the image object
+ *                                 on the source image, or NULL if the object is
+ *                                 shown in full
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_open()
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_get_recognition_rate_open()
+ * @see mv_image_recognize_open()
+ * @see mv_image_object_destroy_open()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_fill_open(
+        mv_image_object_h image_object,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_rectangle_s *location);
+
+/**
+ * @brief Gets a value that determines how well an image object can be recognized.
+ * @details Recognition rate determines how well an image object can be
+ *          recognized. This value can be from 0 to 1. If the recognition rate
+ *          is 0 object can not be recognized and the bigger it is the more
+ *          likely to recognize the object.
+ *
+ * @since_tizen 3.0
+ * @remarks If recognition rate is too low, try to use another image of object
+ *          or change some configuration parameters (see @ref mv_engine_config_h)
+ *          and fill the image object again
+ *          (see @ref mv_image_object_fill_open()).
+ * @param [in]  image_object        The handle to the image object which will be
+ *                                  evaluated by this function
+ * @param [out] recognition_rate    A value that determines how well an image
+ *                                  object can be recognized, if 0 then object
+ *                                  can not be recognized
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image object by using @ref mv_image_object_create_open()
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_fill_open()
+ * @see mv_image_object_destroy_open()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_get_recognition_rate_open(
+        mv_image_object_h image_object,
+        double *recognition_rate);
+
+/**
+ * @brief Sets a label for the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object   The handle to the image object for which the label
+ *                            will be assigned
+ * @param [in] label          The label which will be assigned to the image
+ *                            object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image object by using @ref mv_image_object_create_open()
+ * @post Label could be received by using
+ *       @ref mv_image_object_get_label_open()
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_get_label_open()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_set_label_open(
+        mv_image_object_h image_object,
+        int label);
+
+/**
+ * @brief Gets a label of image object.
+ *
+ * @since_tizen 3.0
+ * @remarks If @a image_object have not a label, this function return
+ *          MEDIA_VISION_ERROR_NO_DATA value.
+ * @param [in]  image_object   The handle to the image object from which a
+ *                             label will be received
+ * @param [out] label          The label of image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NO_DATA Image object hasn't label
+ *
+ * @pre Create image object by using @ref mv_image_object_create_open()
+ * @pre Set label for the image object by using
+ *      @ref mv_image_object_set_label_open()
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_set_label_open()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_get_label_open(
+        mv_image_object_h image_object,
+        int *label);
+
+/**
+ * @brief Clones the image object.
+ *
+ * @since_tizen 3.0
+ * @remarks @a dst must be released using mv_image_object_destroy_open().
+ * @param [in]  src    The handle to the source image object
+ * @param [out] dst    The handle to the destination image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Create image object handles by calling mv_image_object_create_open()
+ *
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_clone_open(
+        mv_image_object_h src,
+        mv_image_object_h *dst);
+
+/**
+ * @brief Saves the image object.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is saved to the application's data directory.
+ * @param [in] file_name       Name of the file to save the image object
+ * @param [in] image_object    The handle to the image object which will be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ *
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_load_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_save_open(
+        const char *file_name, mv_image_object_h image_object);
+
+/**
+ * @brief Loads an image object from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is loaded from the application's data directory.
+ *          @a image_object must be destroyed using
+ *          @ref mv_image_object_destroy().
+ * @param [in]  file_name       Name of file to load the image object
+ * @param [out] image_object    The handle to the image object which will be
+ *                              filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ *
+ * @pre Image object can be preliminary saved with mv_image_object_save()
+ *      function
+ *
+ * @see mv_image_object_save_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_load_open(
+        const char *file_name, mv_image_object_h *image_object);
+
+/**********************************/
+/* Image tracking model behaviour */
+/**********************************/
+
+/**
+ * @brief Creates an image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_tracking_model    A new handle to the image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Release image tracking model by using mv_image_tracking_model_destroy_open()
+ *
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_create_open(
+        mv_image_tracking_model_h *image_tracking_model);
+
+/**
+ * @brief Sets target of image tracking model.
+ * @details Sets image object which will be tracked by using tracking
+ *          functionality with @a image_tracking_model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object            Image object which will be set
+ *                                     as target for tracking
+ * @param [in] image_tracking_model    Handle to the image tracking model
+ *                                     for which will be set a new target
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create_open()
+ * @pre Create an image object using @ref mv_image_object_create_open() and
+ *      construct (fill / load / clone) it on image that will be tracking
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy_open()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_tracking_model_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_track_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_set_target_open(
+        mv_image_object_h image_object,
+        mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Destroys the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model    The handle to the image tracking model
+ *                                     to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image tracking model by using mv_image_tracking_model_create()
+ *
+ * @see mv_image_tracking_model_create_open()
+ */
+int mv_image_tracking_model_destroy_open(
+        mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Refreshes the state of image tracking model.
+ * @details Clears moving history and change state to undetected. This function
+ *          is usually called each time before tracking is started for the new
+ *          sequence of sources which is not the direct continuation of the
+ *          sequence for which tracking has been performed before. Tracking
+ *          algorithm will try to find image by itself.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model   The handle to the image tracking model
+ *                                    which will be refreshed
+ * @param [in] engine_cfg             The handle to the configuration of
+ *                                    engine which will be used. If NULL,
+ *                                    then default settings will be used.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create_open()
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy_open()
+ *
+ * @see mv_image_tracking_model_h
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_track_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_refresh_open(
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg);
+
+/**
+ * @brief Clones the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a dst must be released using mv_image_tracking_model_destroy_open().
+ * @param [in]  src    The handle to the source image tracking model
+ * @param [out] dst    The handle to the destination image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_clone_open(
+        mv_image_tracking_model_h src,
+        mv_image_tracking_model_h *dst);
+
+/**
+ * @brief Saves the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is saved to the application's data directory.
+ * @param [in] file_name               Name of file to save the model
+ * @param [in] image_tracking_model    The handle to the image tracking model
+ *                                     to be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ *
+ * @pre Create image tracking model handle by calling
+ *      mv_image_tracking_model_create()
+ * @post Saved model can be loaded later by calling
+ *       mv_image_tracking_model_load() function
+
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_tracking_model_load_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_save_open(
+        const char *file_name, mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Loads an image tracking model from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is loaded from the application's data directory.
+ *          @a image_tracking_model must be destroyed using
+ *          @ref mv_image_tracking_model_destroy.
+ * @param [in]  file_name               Name of file to load model
+ * @param [out] image_tracking_model    The handle to the image tracking
+ *                                      model to be filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ *
+ * @pre Image tracking model handle can be preliminary saved with
+ *      mv_image_tracking_model_save() function
+ *
+ * @see mv_image_tracking_model_save_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_load_open(
+        const char *file_name, mv_image_tracking_model_h *image_tracking_model);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_IMAGE_OPEN_H__ */
diff --git a/mv_image/image/src/ImageConfig.cpp b/mv_image/image/src/ImageConfig.cpp
new file mode 100644 (file)
index 0000000..47fdaef
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ImageConfig.h"
+
+namespace MediaVision
+{
+namespace Image
+{
+
+FeaturesExtractingParams::FeaturesExtractingParams(
+        double scaleFactor,
+        int maximumFeaturesNumber) :
+                mScaleFactor(scaleFactor),
+                mMaximumFeaturesNumber(maximumFeaturesNumber)
+{
+    ; /* NULL */
+}
+
+FeaturesExtractingParams::FeaturesExtractingParams() :
+        mScaleFactor(1.2),
+        mMaximumFeaturesNumber(800)
+{
+    ; /* NULL */
+}
+
+RecognitionParams::RecognitionParams(
+        int minMatchesNumber,
+        double requiredMatchesPart,
+        double allowableMatchesPartError) :
+                mMinMatchesNumber(minMatchesNumber),
+                mRequiredMatchesPart(requiredMatchesPart),
+                mAllowableMatchesPartError(allowableMatchesPartError)
+{
+    ; /* NULL */
+}
+
+RecognitionParams::RecognitionParams() :
+        mMinMatchesNumber(0),
+        mRequiredMatchesPart(1.0),
+        mAllowableMatchesPartError(0.0)
+{
+    ; /* NULL */
+}
+
+StabilizationParams::StabilizationParams(
+        int historyAmount,
+        double allowableShift,
+        double stabilizationSpeed,
+        double stabilizationAcceleration) :
+                mHistoryAmount(historyAmount),
+                mAllowableShift(allowableShift),
+                mStabilizationSpeed(stabilizationSpeed),
+                mStabilizationAcceleration(stabilizationAcceleration)
+{
+    ; /* NULL */
+}
+
+StabilizationParams::StabilizationParams() :
+        mHistoryAmount(1),
+        mAllowableShift(0.0),
+        mStabilizationSpeed(0.0),
+        mStabilizationAcceleration(1.0)
+{
+    ; /* NULL */
+}
+
+TrackingParams::TrackingParams(
+        FeaturesExtractingParams framesFeaturesExtractingParams,
+        RecognitionParams recognitionParams,
+        StabilizationParams stabilizationParams,
+        double expectedOffset) :
+                mFramesFeaturesExtractingParams(framesFeaturesExtractingParams),
+                mRecognitionParams(recognitionParams),
+                mStabilizationParams(stabilizationParams),
+                mExpectedOffset(expectedOffset)
+{
+    ; /* NULL */
+}
+
+TrackingParams::TrackingParams() :
+        mFramesFeaturesExtractingParams(),
+        mRecognitionParams(),
+        mStabilizationParams(),
+        mExpectedOffset(0.0)
+{
+    ; /* NULL */
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageContourStabilizator.cpp b/mv_image/image/src/ImageContourStabilizator.cpp
new file mode 100644 (file)
index 0000000..1c48659
--- /dev/null
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ImageContourStabilizator.h"
+#include "ImageMathUtil.h"
+
+#include "mv_private.h"
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageContourStabilizator::ImageContourStabilizator() :
+        m_movingHistory(MovingHistoryAmount),
+        m_priorities(MovingHistoryAmount)
+{
+    reset();
+
+    // increasing the stabilization rate
+    m_speeds.push_back(0.3f);
+    m_speeds.push_back(0.4f);
+    m_speeds.push_back(0.5f);
+    m_speeds.push_back(0.6f);
+    m_speeds.push_back(0.8f);
+    m_speeds.push_back(1.f);
+
+    // calculation of priorities for positions in the moving history
+    for (size_t i = 0u; i < MovingHistoryAmount; ++i)
+    {
+        // linear dependence on the elapsed time
+        m_priorities[i] = (i + 1) / ((MovingHistoryAmount + 1) * MovingHistoryAmount / 2.0f);
+    }
+}
+
+void ImageContourStabilizator::reset(void)
+{
+    m_isPrepared = false;
+    m_tempContourIndex = -1;
+    m_currentHistoryAmount = 0;
+
+    LOGI("Outlier is detected.");
+}
+
+bool ImageContourStabilizator::stabilize(
+        std::vector<cv::Point2f>& contour,
+        const StabilizationParams& /*params*/)
+{
+    // current implementation stabilizes quadrangles only
+    if (contour.size() != NumberOfQuadrangleCorners)
+    {
+        LOGW("Not stabilized. Empty contour.");
+
+        return false;
+    }
+
+    m_currentCornersSpeed.resize(contour.size(), 0);
+
+    if (contour[0].x == contour[1].x && contour[0].y == contour[1].y)
+    {
+        LOGW("Not stabilized. Invalid contour.");
+
+        return false;
+    }
+
+    if (m_lastStabilizedContour.empty())
+    {
+        m_lastStabilizedContour = contour;
+    }
+
+    std::vector<cv::Point2f> stabilizedState;
+
+    // history amount < 2 it's no sense
+    if (MovingHistoryAmount >= 2)
+    {
+        // first sample
+        if (m_tempContourIndex == -1)
+        {
+            m_movingHistory[1] = contour;
+            m_tempContourIndex = 1;
+            m_currentHistoryAmount = 1;
+
+            LOGI("Not stabilized. Too small moving history. (the first one)");
+
+            return false;
+        }
+
+        // too short moving history
+        if (m_currentHistoryAmount < MovingHistoryAmount - 1)
+        {
+            ++m_currentHistoryAmount;
+            ++m_tempContourIndex;
+            m_movingHistory[m_tempContourIndex] = contour;
+
+            LOGI("Not stabilized. Too small moving history.");
+
+            return false;
+        }
+
+        // saving into moving history
+        m_movingHistory.pop_front();
+        m_movingHistory.push_back(contour);
+
+        if (!m_isPrepared)
+        {
+            m_lastStabilizedContour = m_movingHistory[MovingHistoryAmount - 2];
+
+            LOGI("Not stabilized. Too small moving history. (the last one)");
+
+            m_isPrepared = true;
+        }
+
+        // stabilization
+        stabilizedState = computeStabilizedQuadrangleContour();
+
+        if (stabilizedState.empty())
+        {
+            stabilizedState = m_lastStabilizedContour;
+        }
+    }
+    else
+    {
+        stabilizedState = m_lastStabilizedContour;
+    }
+
+    const float tolerantShift = getQuadrangleArea(contour.data()) * 0.00006f + 1.3f;
+
+    const size_t contourSize = stabilizedState.size();
+    for (size_t i = 0u; i < contourSize; ++i)
+    {
+        if (fabs(getDistance(stabilizedState[i], contour[i])) > tolerantShift)
+        {
+            const float dirX = m_lastStabilizedContour[i].x - contour[i].x;
+            const float dirY = m_lastStabilizedContour[i].y - contour[i].y;
+
+            const float speedX = dirX * m_speeds[m_currentCornersSpeed[i]];
+            const float speedY = dirY * m_speeds[m_currentCornersSpeed[i]];
+
+            // final moving
+            m_lastStabilizedContour[i].x -= speedX;
+            m_lastStabilizedContour[i].y -= speedY;
+
+            if (m_currentCornersSpeed[i] < m_speeds.size() - 1)
+            {
+                ++m_currentCornersSpeed[i];
+            }
+        }
+        else
+        {
+            m_currentCornersSpeed[i] = 0;
+        }
+    }
+
+    // m_lastStabilizedContour = stabilizedState;
+    contour = m_lastStabilizedContour;
+
+    LOGI("Contour successfully stabilized.");
+
+    return true;
+}
+
+std::vector<cv::Point2f> ImageContourStabilizator::computeStabilizedQuadrangleContour(void)
+{
+    // final contour
+    std::vector<cv::Point2f> stabilizedState(
+            NumberOfQuadrangleCorners, cv::Point2f(0.f, 0.f));
+
+    // calculation the direction of contour corners to a new location
+    std::vector<cv::Point2f> directions(
+            NumberOfQuadrangleCorners, cv::Point2f(0.f, 0.f));
+
+    // computing expected directions and outliers searching
+    bool expressiveTime = false;
+    float summPriorityWithoutToLastPos[NumberOfQuadrangleCorners];
+    float priorityToLastPos[NumberOfQuadrangleCorners];
+    std::vector<cv::Point2f> directionsToLastPos(NumberOfQuadrangleCorners);
+    for (size_t j = 0u; j < NumberOfQuadrangleCorners; ++j)
+    {
+        // calculation the moving directions and computing average direction
+        std::vector<cv::Point2f> trackDirections(MovingHistoryAmount - 1);
+        cv::Point2f averageDirections(0.f, 0.f);
+
+        for (size_t i = 0u; i < MovingHistoryAmount - 1; ++i)
+        {
+            averageDirections.x += (trackDirections[i].x =
+                    m_movingHistory[i+1][j].x - m_movingHistory[i][j].x) /
+                    (MovingHistoryAmount - 1);
+
+            averageDirections.y += (trackDirections[i].y =
+                    m_movingHistory[i+1][j].y - m_movingHistory[i][j].y) /
+                    (MovingHistoryAmount - 1);
+        }
+
+        // calculation a deviations and select outlier
+        std::vector<float> directionDistances(MovingHistoryAmount - 1);
+        float maxDistance = 0.f, prevMaxDistance = 0.f;
+        int idxWithMaxDistance = 0;
+        int numExpressiveDirection = -1;
+        for (size_t i = 0u; i < MovingHistoryAmount - 1; ++i)
+        {
+            directionDistances[i] = getDistance(
+                    trackDirections[i],
+                    averageDirections);
+
+            if (directionDistances[i] > prevMaxDistance)
+            {
+                if (directionDistances[i] > maxDistance)
+                {
+                    prevMaxDistance = maxDistance;
+                    maxDistance = directionDistances[i];
+                    idxWithMaxDistance = i;
+                }
+                else
+                {
+                    prevMaxDistance = directionDistances[i];
+                }
+            }
+        }
+
+        // check outlier
+        if (0.6f * maxDistance > prevMaxDistance)
+        {
+            LOGI("Outlier is detected.");
+
+            numExpressiveDirection = idxWithMaxDistance;
+        }
+
+        // final direction computing
+        float summPriority = 0.f;
+        for (size_t i = 0u; i < MovingHistoryAmount - 1; ++i)
+        {
+            if ((int)i != numExpressiveDirection)
+            {
+                directions[j].x += trackDirections[i].x * m_priorities[i];
+                directions[j].y += trackDirections[i].y * m_priorities[i];
+                summPriority += m_priorities[i];
+            }
+        }
+        if (numExpressiveDirection == MovingHistoryAmount - 1)
+        {
+            expressiveTime = true;
+        }
+
+        summPriorityWithoutToLastPos[j] = summPriority;
+        priorityToLastPos[j] = m_priorities[MovingHistoryAmount - 1];
+
+        directions[j].x -= directionsToLastPos[j].x =
+                (m_lastStabilizedContour[j].x -
+                        m_movingHistory[MovingHistoryAmount - 1][j].x) *
+                priorityToLastPos[j];
+
+        directions[j].y -= directionsToLastPos[j].y =
+                (m_lastStabilizedContour[j].y -
+                        m_movingHistory[MovingHistoryAmount - 1][j].y) *
+                priorityToLastPos[j];
+
+        summPriority += priorityToLastPos[j];
+
+        directions[j].x /= summPriority;
+        directions[j].y /= summPriority;
+    }
+
+    // final corners computing
+    for (size_t j = 0u; j < NumberOfQuadrangleCorners; ++j)
+    {
+        if (expressiveTime)
+        {
+            directions[j].x *= (summPriorityWithoutToLastPos[j] +
+                    priorityToLastPos[j]);
+            directions[j].x -= directionsToLastPos[j].x;
+            directions[j].x /= summPriorityWithoutToLastPos[j];
+
+            directions[j].y *= (summPriorityWithoutToLastPos[j] +
+                    priorityToLastPos[j]);
+            directions[j].y -= directionsToLastPos[j].y;
+            directions[j].y /= summPriorityWithoutToLastPos[j];
+        }
+
+        stabilizedState[j].x = m_lastStabilizedContour[j].x + directions[j].x;
+        stabilizedState[j].y = m_lastStabilizedContour[j].y + directions[j].y;
+    }
+
+    return stabilizedState;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageMathUtil.cpp b/mv_image/image/src/ImageMathUtil.cpp
new file mode 100644 (file)
index 0000000..8bf5ba8
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ImageMathUtil.h"
+
+namespace MediaVision
+{
+namespace Image
+{
+
+float getDistance(
+        const cv::Point2f& point1,
+        const cv::Point2f& point2)
+{
+    return sqrt(
+        (point1.x - point2.x) * (point1.x - point2.x) +
+        (point1.y - point2.y) * (point1.y - point2.y));
+}
+
+float getTriangleArea(
+        const cv::Point2f& point1,
+        const cv::Point2f& point2,
+        const cv::Point2f& point3)
+{
+    float distances[3];
+
+    distances[0] = getDistance(point1, point2);
+    distances[1] = getDistance(point2, point3);
+    distances[2] = getDistance(point3, point1);
+
+    const float semiperimeter = (distances[0] + distances[1] + distances[2]) / 2.0f;
+
+    return sqrt(semiperimeter *
+        (semiperimeter - distances[0]) *
+        (semiperimeter - distances[1]) *
+        (semiperimeter - distances[2]));
+}
+
+float getQuadrangleArea(const cv::Point2f points[NumberOfQuadrangleCorners])
+{
+    return getTriangleArea(points[0], points[1], points[2]) +
+           getTriangleArea(points[0], points[3], points[2]);
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageObject.cpp b/mv_image/image/src/ImageObject.cpp
new file mode 100644 (file)
index 0000000..531ec62
--- /dev/null
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ImageObject.h"
+
+#include "ImageMathUtil.h"
+
+#include <app_common.h>
+
+#include "mv_private.h"
+#include "mv_common.h"
+
+#include <opencv/cv.h>
+#include <opencv2/features2d/features2d.hpp>
+
+#include <fstream>
+#include <unistd.h>
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageObject::ImageObject() :
+        m_isEmpty(true),
+        m_isLabeled(false),
+        m_label(0),
+        m_recognitionRate(0.f)
+{
+    ; /* NULL */
+}
+
+ImageObject::ImageObject(const cv::Mat& image, const FeaturesExtractingParams& params) :
+        m_isEmpty(true),
+        m_isLabeled(false),
+        m_label(0),
+        m_recognitionRate(0.f)
+{
+    fill(image, params);
+}
+
+ImageObject::ImageObject(const ImageObject& copy) :
+        m_isEmpty(copy.m_isEmpty),
+        m_isLabeled(copy.m_isLabeled),
+        m_label(copy.m_label),
+        m_boundingContour(copy.m_boundingContour),
+        m_objectKeypoints(copy.m_objectKeypoints),
+        m_objectDescriptors(copy.m_objectDescriptors.clone()),
+        m_recognitionRate(copy.m_recognitionRate)
+{
+    ; /* NULL */
+}
+
+ImageObject& ImageObject::operator=(const ImageObject& copy)
+{
+    if (this != &copy)
+    {
+        m_isEmpty = copy.m_isEmpty;
+        m_isLabeled = copy.m_isLabeled;
+        m_label = copy.m_label;
+        m_boundingContour = copy.m_boundingContour;
+        m_objectKeypoints = copy.m_objectKeypoints;
+        m_objectDescriptors = copy.m_objectDescriptors.clone();
+        m_recognitionRate = copy.m_recognitionRate;
+    }
+    return *this;
+}
+
+ImageObject::~ImageObject()
+{
+    ; /* NULL */
+}
+
+void ImageObject::fill(const cv::Mat& image, const FeaturesExtractingParams& params)
+{
+    m_isEmpty = false;
+    m_boundingContour.resize(NumberOfQuadrangleCorners);
+
+    m_boundingContour[0].x = 0.f;
+    m_boundingContour[0].y = 0.f;
+
+    m_boundingContour[1].x = image.cols;
+    m_boundingContour[1].y = 0.f;
+
+    m_boundingContour[2].x = image.cols;
+    m_boundingContour[2].y = image.rows;
+
+    m_boundingContour[3].x = 0.f;
+    m_boundingContour[3].y = image.rows;
+
+    extractFeatures(image, params);
+
+    computeRecognitionRate(image);
+
+    LOGI("[%s] Image object is filled.", __FUNCTION__);
+}
+
+bool ImageObject::fill(const cv::Mat& image, const cv::Rect& boundingBox,
+        const FeaturesExtractingParams& params)
+{
+    if ((0 > boundingBox.x) || (0 >= boundingBox.width) ||
+        (0 > boundingBox.y) || (0 >= boundingBox.height) ||
+        (image.cols < (boundingBox.x + boundingBox.width)) ||
+        (image.rows < (boundingBox.y + boundingBox.height)))
+    {
+        LOGE("[%s] Invalid ROI.", __FUNCTION__);
+        return false;
+    }
+
+    m_isEmpty = false;
+    m_boundingContour.resize(NumberOfQuadrangleCorners);
+
+    m_boundingContour[0].x = 0.f;
+    m_boundingContour[0].y = 0.f;
+
+    m_boundingContour[1].x = boundingBox.width;
+    m_boundingContour[1].y = 0.f;
+
+    m_boundingContour[2].x = boundingBox.width;
+    m_boundingContour[2].y = boundingBox.height;
+
+    m_boundingContour[3].x = 0.f;
+    m_boundingContour[3].y = boundingBox.height;
+
+    cv::Mat objectImage(image, boundingBox);
+
+    extractFeatures(objectImage, params);
+
+    computeRecognitionRate(image);
+
+    LOGI("[%s] Image object is filled.", __FUNCTION__);
+
+    return true;
+}
+
+void ImageObject::extractFeatures(const cv::Mat& image,
+        const FeaturesExtractingParams& params)
+{
+    cv::ORB orb(params.mMaximumFeaturesNumber, params.mScaleFactor);
+
+    if (image.cols < MinWidth || image.rows < MinHeight)
+    {
+        LOGW("[%s] Area is too small, recognition rate is 0.", __FUNCTION__);
+        m_objectKeypoints.clear();
+        m_objectDescriptors = cv::Mat();
+    }
+    else
+    {
+        orb.detect(image, m_objectKeypoints);
+        orb.compute(image, m_objectKeypoints, m_objectDescriptors);
+    }
+}
+
+void ImageObject::computeRecognitionRate(const cv::Mat& image)
+{
+    const size_t numberOfKeypoints = m_objectKeypoints.size();
+
+    // it is impossible to calculate the perspective transformation parameters
+    // if number of key points less than MinimumNumberOfFeatures (4)
+    if (numberOfKeypoints < MinimumNumberOfFeatures)
+    {
+        m_recognitionRate = 0.f;
+        return;
+    }
+
+    static const size_t xCellsNumber = 10u;
+    static const size_t yCellsNumber = 10u;
+
+    cv::Mat cells[xCellsNumber][yCellsNumber];
+    size_t accumulationCounter[xCellsNumber][yCellsNumber];
+
+    const size_t cellWidth = image.cols / xCellsNumber;
+    const size_t cellHeight = image.rows / yCellsNumber;
+
+    for (size_t x = 0u; x < xCellsNumber; ++x)
+    {
+        for (size_t y = 0u; y < yCellsNumber; ++y)
+        {
+            cells[x][y] = image(cv::Rect(
+                    x * cellWidth,
+                    y * cellHeight,
+                    cellWidth,
+                    cellHeight));
+
+            accumulationCounter[x][y] = 0;
+        }
+    }
+
+    for (size_t i = 0u; i < numberOfKeypoints; ++i)
+    {
+        size_t xCellIdx = m_objectKeypoints[i].pt.x / cellWidth;
+        if (xCellIdx >= xCellsNumber)
+        {
+            xCellIdx = xCellsNumber - 1;
+        }
+        size_t yCellIdx = m_objectKeypoints[i].pt.y / cellHeight;
+        if (yCellIdx >= yCellsNumber)
+        {
+            yCellIdx = yCellsNumber - 1;
+        }
+        ++(accumulationCounter[xCellIdx][yCellIdx]);
+    }
+
+    const float exceptedNumber = numberOfKeypoints /
+            (float)(xCellsNumber * yCellsNumber);
+
+    float distributedEvaluation = 0.f;
+
+    for (size_t x = 0u; x < xCellsNumber; ++x)
+    {
+        for (size_t y = 0u; y < yCellsNumber; ++y)
+        {
+            distributedEvaluation += (accumulationCounter[x][y] - exceptedNumber) *
+                    (accumulationCounter[x][y] - exceptedNumber) / exceptedNumber;
+        }
+    }
+
+    float maximumDistributedEvaluation = (xCellsNumber * yCellsNumber - 1) *
+            exceptedNumber;
+
+    maximumDistributedEvaluation += (numberOfKeypoints - exceptedNumber) *
+            (numberOfKeypoints - exceptedNumber) / exceptedNumber;
+
+    distributedEvaluation = 1 -
+            (distributedEvaluation / maximumDistributedEvaluation);
+
+    // Exponentiation to find an approximate confidence value based on the
+    // number of key points on the image.
+    const float cardinalityEvaluation = pow(-0.9, numberOfKeypoints - 3) + 1.0f;
+
+    m_recognitionRate =
+            distributedEvaluation *
+            cardinalityEvaluation;
+}
+
+float ImageObject::getRecognitionRate(void) const
+{
+    return m_recognitionRate;
+}
+
+bool ImageObject::isEmpty() const
+{
+    return m_isEmpty;
+}
+
+void ImageObject::setLabel(int label)
+{
+    m_isLabeled = true;
+    m_label = label;
+}
+
+bool ImageObject::getLabel(int& label) const
+{
+    if (!m_isLabeled)
+    {
+        LOGW("[%s] Image hasn't label.", __FUNCTION__);
+        return false;
+    }
+    label = m_label;
+    return true;
+}
+
+int ImageObject::save(const char *fileName) const
+{
+    std::string prefix_path = std::string(app_get_data_path());
+    LOGD("prefix_path: %s", prefix_path.c_str());
+
+    std::string filePath;
+    filePath += prefix_path;
+    filePath += fileName;
+
+    /* check the directory is available */
+    std::string prefix_path_check = filePath.substr(0, filePath.find_last_of('/'));
+    if (access(prefix_path_check.c_str(), F_OK))
+    {
+        LOGE("Can't save image object. Path[%s] doesn't existed.", prefix_path_check.c_str());
+
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    std::ofstream out;
+
+    out.open(filePath.c_str());
+
+    if (!out.is_open())
+    {
+        LOGE("[%s] Can't create/open file.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    out<<(*this);
+
+    out.close();
+    LOGI("[%s] Image object is saved.", __FUNCTION__);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageObject::load(const char *fileName)
+{
+    /* find directory */
+    std::string prefix_path = std::string(app_get_data_path());
+    LOGD("prefix_path: %s", prefix_path.c_str());
+
+    std::string filePath;
+    filePath += prefix_path;
+    filePath += fileName;
+
+    if (access(filePath.c_str(), F_OK))
+    {
+        LOGE("Can't load image object model. Path[%s] doesn't existed.", filePath.c_str());
+
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    std::ifstream in;
+    in.open(filePath.c_str());
+
+    if (!in.is_open())
+    {
+        LOGE("[%s] Can't open file.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    in>>(*this);
+
+    if (!in.good())
+    {
+        LOGE("[%s] Unexpected end of file.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    in.close();
+    LOGI("[%s] Image object is loaded.", __FUNCTION__);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+std::ostream& operator << (std::ostream& os, const ImageObject& obj)
+{
+    os<<std::setprecision(7);
+
+    os<<obj.m_isEmpty<<'\n';
+    os<<obj.m_isLabeled<<'\n';
+    os<<obj.m_label<<'\n';
+
+    os<<obj.m_boundingContour.size()<<'\n';
+    for (size_t pointNum = 0u; pointNum < obj.m_boundingContour.size(); ++pointNum)
+    {
+        os<<obj.m_boundingContour[pointNum].x<<' ';
+        os<<obj.m_boundingContour[pointNum].y<<'\n';
+    }
+
+    os<<obj.m_objectKeypoints.size()<<'\n';
+    for (size_t keypointNum = 0u; keypointNum < obj.m_objectKeypoints.size();++keypointNum)
+    {
+        os<<obj.m_objectKeypoints[keypointNum].pt.x<<' ';
+        os<<obj.m_objectKeypoints[keypointNum].pt.y<<' ';
+        os<<obj.m_objectKeypoints[keypointNum].size<<' ';
+        os<<obj.m_objectKeypoints[keypointNum].response<<' ';
+        os<<obj.m_objectKeypoints[keypointNum].angle<<' ';
+        os<<obj.m_objectKeypoints[keypointNum].octave<<' ';
+        os<<obj.m_objectKeypoints[keypointNum].class_id<<'\n';
+    }
+
+    os<<obj.m_objectDescriptors.rows<<' ';
+    os<<obj.m_objectDescriptors.cols<<' ';
+    os<<obj.m_objectDescriptors.type()<<'\n';
+    for (int descriptorNum = 0; descriptorNum < obj.m_objectDescriptors.rows;
+            ++descriptorNum)
+    {
+        for (int featureNum = 0; featureNum < obj.m_objectDescriptors.cols;
+                ++featureNum, os<<'\n')
+        {
+            os<<(int)obj.m_objectDescriptors.at<uchar>(descriptorNum, featureNum)<<' ';
+        }
+    }
+
+    return os;
+}
+
+std::istream& operator >> (std::istream& is, ImageObject& obj)
+{
+    size_t numberOfContourPoints = 0u;
+    size_t numberOfKeyPoints = 0u;
+    int rows = 0, cols = 0;
+    int descriptorType = 0;
+
+    ImageObject temporal;
+
+#define MEDIA_VISION_CHECK_IFSTREAM \
+    if (!is.good()) \
+    { \
+        return is; \
+    }
+
+    is>>temporal.m_isEmpty;
+    MEDIA_VISION_CHECK_IFSTREAM
+    is>>temporal.m_isLabeled;
+    MEDIA_VISION_CHECK_IFSTREAM
+    is>>temporal.m_label;
+    MEDIA_VISION_CHECK_IFSTREAM
+
+    is>>numberOfContourPoints;
+    MEDIA_VISION_CHECK_IFSTREAM
+
+    temporal.m_boundingContour.resize(numberOfContourPoints);
+    for (size_t pointNum = 0; pointNum < temporal.m_boundingContour.size(); ++pointNum)
+    {
+        is>>temporal.m_boundingContour[pointNum].x;
+        MEDIA_VISION_CHECK_IFSTREAM
+        is>>temporal.m_boundingContour[pointNum].y;
+        MEDIA_VISION_CHECK_IFSTREAM
+    }
+
+    is>>numberOfKeyPoints;
+    temporal.m_objectKeypoints.resize(numberOfKeyPoints);
+    for (size_t keypointNum = 0; keypointNum < temporal.m_objectKeypoints.size(); ++keypointNum)
+    {
+        is>>temporal.m_objectKeypoints[keypointNum].pt.x;
+        MEDIA_VISION_CHECK_IFSTREAM
+        is>>temporal.m_objectKeypoints[keypointNum].pt.y;
+        MEDIA_VISION_CHECK_IFSTREAM
+        is>>temporal.m_objectKeypoints[keypointNum].size;
+        MEDIA_VISION_CHECK_IFSTREAM
+        is>>temporal.m_objectKeypoints[keypointNum].response;
+        MEDIA_VISION_CHECK_IFSTREAM
+        is>>temporal.m_objectKeypoints[keypointNum].angle;
+        MEDIA_VISION_CHECK_IFSTREAM
+        is>>temporal.m_objectKeypoints[keypointNum].octave;
+        MEDIA_VISION_CHECK_IFSTREAM
+        is>>temporal.m_objectKeypoints[keypointNum].class_id;
+        MEDIA_VISION_CHECK_IFSTREAM
+    }
+
+    is>>rows;
+    MEDIA_VISION_CHECK_IFSTREAM
+    is>>cols;
+    MEDIA_VISION_CHECK_IFSTREAM
+    is>>descriptorType;
+    MEDIA_VISION_CHECK_IFSTREAM
+    temporal.m_objectDescriptors = cv::Mat(rows, cols, descriptorType);
+    int value = 0;
+    for (int descriptorNum = 0; descriptorNum < temporal.m_objectDescriptors.rows; ++descriptorNum)
+    {
+        for (int featureNum = 0; featureNum < temporal.m_objectDescriptors.cols; ++featureNum)
+        {
+            is>>value;
+            MEDIA_VISION_CHECK_IFSTREAM
+            temporal.m_objectDescriptors.at<uchar>(descriptorNum, featureNum) = (uchar)value;
+        }
+    }
+
+#undef MEDIA_VISION_CHECK_IFSTREAM
+
+    obj = temporal;
+
+    return is;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageRecognizer.cpp b/mv_image/image/src/ImageRecognizer.cpp
new file mode 100644 (file)
index 0000000..c921555
--- /dev/null
@@ -0,0 +1,312 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ImageRecognizer.h"
+#include "ImageObject.h"
+
+#include "mv_private.h"
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageRecognizer::ImageRecognizer(
+        const cv::Mat& sceneImage,
+        const FeaturesExtractingParams& params) :
+                m_scene(sceneImage, params)
+{
+    ; /* NULL */
+}
+
+ImageRecognizer::ImageRecognizer(const ImageObject& scene) :
+        m_scene(scene)
+{
+    ; /* NULL */
+}
+
+ImageRecognizer::~ImageRecognizer()
+{
+    ; /* NULL */
+}
+
+bool ImageRecognizer::recognize(
+        const ImageObject& target,
+        const RecognitionParams& params,
+        std::vector<cv::Point2f>& contour) const
+{
+    cv::Mat homophraphyMatrix;
+
+    contour.clear();
+
+    if (MinimumNumberOfFeatures > target.m_objectKeypoints.size())
+    {
+        LOGW("[%s] Image object can't be recognized (Recognition rate is too small).", __FUNCTION__);
+        return false;
+    }
+    if (MinimumNumberOfFeatures > m_scene.m_objectKeypoints.size())
+    {
+        LOGW("[%s] Scene image can't be analyzed (Too few features for recognition).", __FUNCTION__);
+        return false;
+    }
+
+    if(!findHomophraphyMatrix(target, params, homophraphyMatrix))
+    {
+        LOGE("[%s] Can't match the features.", __FUNCTION__);
+        return false;
+    }
+
+    cv::perspectiveTransform(target.m_boundingContour, contour, homophraphyMatrix);
+
+    if (target.m_boundingContour.size() == NumberOfQuadrangleCorners)
+    {
+        if (!isPossibleQuadrangleCorners(contour.data()))
+        {
+            LOGI("[%s] Image object isn't recognized.", __FUNCTION__);
+            contour.clear();
+            return false;
+        }
+    }
+
+    LOGI("[%s] Image object is recognized.", __FUNCTION__);
+    return true;
+}
+
+bool ImageRecognizer::findHomophraphyMatrix(
+        const ImageObject& target,
+        const RecognitionParams& params,
+        cv::Mat& homophraphyMatrix) const
+{
+    std::vector<cv::DMatch> matches;
+
+    m_matcher.match(target.m_objectDescriptors, m_scene.m_objectDescriptors, matches);
+
+    size_t matchesNumber = matches.size();
+
+    if (MinimumNumberOfFeatures > matchesNumber)
+    {
+        LOGE("[%s] Can't match the features.", __FUNCTION__);
+        return false;
+    }
+
+    size_t requiredMatchesNumber =
+            params.mRequiredMatchesPart * matchesNumber;
+
+    size_t allowableMatchesNumberError =
+            params.mAllowableMatchesPartError * requiredMatchesNumber;
+
+    if (matchesNumber - allowableMatchesNumberError >
+        (size_t)params.mMinMatchesNumber &&
+        requiredMatchesNumber + allowableMatchesNumberError <
+        matchesNumber)
+    {
+        if (requiredMatchesNumber - allowableMatchesNumberError <
+            (size_t)params.mMinMatchesNumber)
+        {
+            if (requiredMatchesNumber + allowableMatchesNumberError >
+                (size_t)params.mMinMatchesNumber)
+            {
+                requiredMatchesNumber = ((size_t)params.mMinMatchesNumber +
+                        requiredMatchesNumber + allowableMatchesNumberError) / 2;
+
+                allowableMatchesNumberError = requiredMatchesNumber-
+                        (size_t)params.mMinMatchesNumber +
+                        allowableMatchesNumberError;
+            }
+            else
+            {
+                const size_t minimalAllowableMatchesNumberError = 2u;
+
+                requiredMatchesNumber = params.mMinMatchesNumber +
+                        minimalAllowableMatchesNumberError;
+
+                allowableMatchesNumberError = minimalAllowableMatchesNumberError;
+            }
+        }
+
+        const size_t filterAmount = matchesSelection(matches,
+                                                  requiredMatchesNumber,
+                                                  allowableMatchesNumberError);
+
+        if (filterAmount >= MinimumNumberOfFeatures)
+        {
+            matches.resize(filterAmount);
+        }
+        else
+        {
+            LOGW("[%s] Wrong filtration of feature matches.", __FUNCTION__);
+        }
+
+        matchesNumber = matches.size();
+    }
+
+    std::vector<cv::Point2f> objectPoints(matchesNumber);
+    std::vector<cv::Point2f> scenePoints(matchesNumber);
+
+    for (size_t matchIdx = 0; matchIdx < matchesNumber; ++matchIdx)
+    {
+        objectPoints[matchIdx] =
+                target.m_objectKeypoints[matches[matchIdx].queryIdx].pt;
+
+        scenePoints[matchIdx] =
+                m_scene.m_objectKeypoints[matches[matchIdx].trainIdx].pt;
+    }
+
+    homophraphyMatrix = cv::findHomography(objectPoints, scenePoints, CV_RANSAC);
+
+    return true;
+}
+
+size_t ImageRecognizer::matchesSelection(
+        std::vector<cv::DMatch>& examples,
+        unsigned int filterAmount, unsigned int allowableError) const
+{
+    size_t sizeOfExamples = examples.size();
+
+    if ((filterAmount + allowableError) > sizeOfExamples)
+    {
+        return examples.size();
+    }
+
+    int startLeftLimit = 0;
+    int startRightLimit = sizeOfExamples - 1;
+
+    int leftLimit = startLeftLimit;
+    int rightLimit = startRightLimit;
+
+    int requiredNumber = filterAmount;
+
+    float supportElement = 0.f;
+
+    while (true)
+    {
+        if (leftLimit >= rightLimit)
+        {
+            if (leftLimit < (requiredNumber - (int)allowableError))
+            {
+                leftLimit = requiredNumber + (int)allowableError;
+            }
+
+            break;
+        }
+
+        supportElement = computeLinearSupportElement(examples, requiredNumber,
+                leftLimit, rightLimit);
+
+        // Iteration similar quicksort
+        while (true)
+        {
+            // Search the leftmost element which have bigger confidence than support element
+            while (examples[leftLimit].distance <= supportElement &&
+                leftLimit < startRightLimit)
+            {
+                ++leftLimit;
+            }
+
+            // Search the rightmost element which have smaller confidence than support element
+            while (examples[rightLimit].distance >= supportElement &&
+                rightLimit >= startLeftLimit)
+            {
+                --rightLimit;
+            }
+
+            if (leftLimit >= rightLimit)
+            {
+                break;
+            }
+
+            // Swap
+            std::swap(examples[leftLimit], examples[rightLimit]);
+        }
+        if (abs(filterAmount - leftLimit) <= (int)allowableError)
+        {
+            break;
+        }
+        if ((int)filterAmount > leftLimit)
+        {
+            requiredNumber -= leftLimit - startLeftLimit;
+
+            rightLimit = startRightLimit;
+            startLeftLimit = leftLimit;
+        }
+        else
+        {
+            leftLimit = startLeftLimit;
+            startRightLimit = rightLimit;
+        }
+    }
+
+    return (size_t)leftLimit;
+}
+
+float ImageRecognizer::computeLinearSupportElement(const std::vector<cv::DMatch>& examples,
+        int requiredNumber, int leftLimit, int rightLimit) const
+{
+    int sizeOfExamples = rightLimit - leftLimit + 1;
+
+    if (sizeOfExamples <= 1)
+    {
+        return examples[leftLimit].distance;
+    }
+
+    float minValue = examples[leftLimit].distance;
+    float maxValue = examples[leftLimit].distance;
+
+    // Finding the maximum and minimum values
+    for (int i = leftLimit + 1; i <= rightLimit; ++i)
+    {
+        if (minValue > examples[i].distance)
+        {
+            minValue = examples[i].distance;
+        }
+        else if (maxValue < examples[i].distance)
+        {
+            maxValue = examples[i].distance;
+        }
+    }
+
+    // Linear approximation. f(x) = k*x + b
+    // f(sizeOfExamples) = maxValue; f(1) = minValue;
+    const float b = (maxValue - minValue * sizeOfExamples) / (1 - sizeOfExamples);
+    const float k = minValue - b;
+
+    // Calculation of the support element
+    return k * requiredNumber + b;
+}
+
+bool ImageRecognizer::isPossibleQuadrangleCorners(
+        const cv::Point2f corners[NumberOfQuadrangleCorners])
+{
+    static const float Epsilon = cv::TermCriteria::EPS;
+    static const float MinSizeOfDetectedArea = 30.f;
+
+    const float firstSemiArea = getTriangleArea(corners[0], corners[2], corners[1]) +
+            getTriangleArea(corners[0], corners[2], corners[3]);
+
+    const float secondSemiArea = getTriangleArea(corners[1], corners[3], corners[2]) +
+            getTriangleArea(corners[1], corners[3], corners[0]);
+
+    if (Epsilon < fabs(firstSemiArea - secondSemiArea) ||
+        MinSizeOfDetectedArea > (firstSemiArea + secondSemiArea))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageTracker.cpp b/mv_image/image/src/ImageTracker.cpp
new file mode 100644 (file)
index 0000000..9c114f5
--- /dev/null
@@ -0,0 +1,372 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ImageTracker.h"
+
+#include "ImageMathUtil.h"
+#include "ImageRecognizer.h"
+#include "ImageTrackingModel.h"
+#include "ImageContourStabilizator.h"
+
+#include "mv_private.h"
+
+#include <pthread.h>
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageTracker::ImageTracker(const TrackingParams& trackingParams) :
+        m_trackingParams(trackingParams)
+{
+    ; /* NULL */
+}
+
+void ImageTracker::track(const cv::Mat& frame, ImageTrackingModel& target)
+{
+    ImageTrackingModel::State currentState = ImageTrackingModel::Undetected;
+
+    while (pthread_mutex_trylock(&target.m_globalGuard) != 0)
+    {
+        pthread_spin_lock(&target.m_stateGuard);
+        currentState = target.m_state;
+        pthread_spin_unlock(&target.m_stateGuard);
+
+        if (ImageTrackingModel::InProcess == currentState)
+        {
+            LOGI("[%s] Calling is skipped. Object is recognizing.", __FUNCTION__);
+            return;
+        }
+    }
+
+    pthread_spin_lock(&target.m_stateGuard);
+    currentState = target.m_state;
+    pthread_spin_unlock(&target.m_stateGuard);
+
+    if (ImageTrackingModel::Invalid == currentState)
+    {
+        pthread_mutex_unlock(&target.m_globalGuard);
+        LOGE("[%s] Tracking model is invalid.", __FUNCTION__);
+        return;
+    }
+
+    switch (target.m_state)
+    {
+        case ImageTrackingModel::Appeared:
+        case ImageTrackingModel::Tracked:
+        {
+            pthread_spin_lock(&target.m_stateGuard);
+            target.m_state = ImageTrackingModel::InProcess;
+            pthread_spin_unlock(&target.m_stateGuard);
+
+            trackDetectedObject(frame, target);
+            break;
+        }
+        case ImageTrackingModel::Undetected:
+        {
+            pthread_spin_lock(&target.m_stateGuard);
+            target.m_state = ImageTrackingModel::InProcess;
+            pthread_spin_unlock(&target.m_stateGuard);
+
+            trackUndetectedObject(frame, target);
+
+            // Recognition thread is started. Don't use target here, just exit!
+            return;
+        }
+        case ImageTrackingModel::InProcess:
+        default:
+        {
+            // Abnormal behaviour:
+            // tracking model state is InProcess but globalGuard is not locked
+            LOGE("[%s] Abnormal behaviour. Tracking model status is"
+                    "\"InProgress\" but it is not in progress.", __FUNCTION__);
+
+            pthread_spin_lock(&target.m_stateGuard);
+            if (target.m_recognitionObject.isEmpty())
+            {
+                target.m_state = ImageTrackingModel::Invalid;
+                LOGI("[%s] Tracking model status is changed on \"Invalid\"", __FUNCTION__);
+            }
+            else
+            {
+                target.m_state = ImageTrackingModel::Undetected;
+                LOGI("[%s] Tracking model status is changed on \"Undetected\"", __FUNCTION__);
+            }
+            pthread_spin_unlock(&target.m_stateGuard);
+
+            pthread_mutex_unlock(&target.m_globalGuard);
+            break;
+        }
+    }
+}
+
+void ImageTracker::trackDetectedObject(
+        const cv::Mat& frame,
+        ImageTrackingModel& target)
+{
+    cv::Rect expectedArea = computeExpectedArea(target, frame.size());
+
+    std::vector<cv::Point2f> resultContour;
+
+    ImageRecognizer recognizer(
+            frame(expectedArea),
+            m_trackingParams.mFramesFeaturesExtractingParams);
+
+    const bool isRecognized = recognizer.recognize(
+            target.m_recognitionObject,
+            m_trackingParams.mRecognitionParams,
+            resultContour);
+
+    if (isRecognized)
+    {
+        for (size_t pointIdx = 0; pointIdx < resultContour.size(); ++pointIdx)
+        {
+            resultContour[pointIdx].x += expectedArea.x;
+            resultContour[pointIdx].y += expectedArea.y;
+        }
+
+        if (m_trackingParams.mStabilizationParams.mHistoryAmount > 0)
+        {
+            target.m_stabilizator.stabilize(
+                    resultContour,
+                    m_trackingParams.mStabilizationParams);
+        }
+
+        target.m_stabilizator.stabilize(
+                resultContour,
+                m_trackingParams.mStabilizationParams);
+
+        pthread_spin_lock(&target.m_lastLocationGuard);
+        target.m_lastLocation = resultContour;
+        pthread_spin_unlock(&target.m_lastLocationGuard);
+
+        pthread_spin_lock(&target.m_stateGuard);
+        target.m_state = ImageTrackingModel::Tracked;
+        pthread_spin_unlock(&target.m_stateGuard);
+
+        LOGI("[%s] Object is successfully tracked.", __FUNCTION__);
+    }
+    else
+    {
+        target.m_stabilizator.reset();
+
+        pthread_spin_lock(&target.m_stateGuard);
+        target.m_state = ImageTrackingModel::Undetected;
+        pthread_spin_unlock(&target.m_stateGuard);
+
+        LOGI("[%s] Object is lost.", __FUNCTION__);
+    }
+
+    pthread_mutex_unlock(&target.m_globalGuard);
+}
+
+void *ImageTracker::recognitionThreadFunc(void *recognitionInfo)
+{
+    if (NULL == recognitionInfo)
+    {
+        return NULL;
+    }
+
+    RecognitionInfo *recogInfo = (RecognitionInfo*)recognitionInfo;
+
+    std::vector<cv::Point2f> resultContour;
+
+    ImageRecognizer recognizer(
+            recogInfo->mFrame,
+            recogInfo->mSceneFeaturesExtractingParams);
+
+    bool isRecognized = recognizer.recognize(
+            recogInfo->mpTarget->m_recognitionObject,
+            recogInfo->mRecognitionParams,
+            resultContour);
+
+    if (isRecognized)
+    {
+        recogInfo->mpTarget->m_stabilizator.reset();
+
+        pthread_spin_lock(&(recogInfo->mpTarget->m_lastLocationGuard));
+        recogInfo->mpTarget->m_lastLocation = resultContour;
+        pthread_spin_unlock(&(recogInfo->mpTarget->m_lastLocationGuard));
+
+        pthread_spin_lock(&(recogInfo->mpTarget->m_stateGuard));
+        recogInfo->mpTarget->m_state = ImageTrackingModel::Appeared;
+        pthread_spin_unlock(&(recogInfo->mpTarget->m_stateGuard));
+    }
+    else
+    {
+        pthread_spin_lock(&(recogInfo->mpTarget->m_stateGuard));
+        recogInfo->mpTarget->m_state = ImageTrackingModel::Undetected;
+        pthread_spin_unlock(&(recogInfo->mpTarget->m_stateGuard));
+    }
+
+    recogInfo->mpTarget->m_recognitionThread = 0;
+
+    pthread_mutex_unlock(&(recogInfo->mpTarget->m_globalGuard));
+
+    delete recogInfo;
+
+    return NULL;
+}
+
+void ImageTracker::trackUndetectedObject(
+        const cv::Mat& frame,
+        ImageTrackingModel& target)
+{
+    RecognitionInfo *recognitionInfo = new RecognitionInfo;
+
+    recognitionInfo->mFrame = frame.clone();
+    recognitionInfo->mpTarget = &target;
+
+    recognitionInfo->mRecognitionParams =
+            m_trackingParams.mRecognitionParams;
+    recognitionInfo->mSceneFeaturesExtractingParams =
+            m_trackingParams.mFramesFeaturesExtractingParams;
+
+    if (target.m_recognitionThread)
+    {
+        // Abnormal behaviour:
+        // Recognition thread isn't finished but guardian mutex is unlocked
+        LOGE("[%s] Abnormal behaviour. Recognition thread isn't finished but"
+                "guardian mutex is unlocked.", __FUNCTION__);
+
+        LOGI("[%s] Try to wait recognition thread.", __FUNCTION__);
+        pthread_join(target.m_recognitionThread, NULL);
+        target.m_recognitionThread = 0;
+        LOGI("[%s] Recognition thread is finished.", __FUNCTION__);
+    }
+
+    const int err = pthread_create(
+            &target.m_recognitionThread,
+            NULL,
+            recognitionThreadFunc,
+            recognitionInfo);
+
+    if (0 == err)
+    {
+        LOGI("[%s] Recognition thread is started.", __FUNCTION__);
+        // Recognition thread is started. Don't use target here, just exit!
+        return;
+    }
+    LOGE("[%s] Recognition thread creation is failed.", __FUNCTION__);
+
+    pthread_spin_lock(&target.m_stateGuard);
+    if (target.m_recognitionObject.isEmpty())
+    {
+        target.m_state = ImageTrackingModel::Invalid;
+        LOGI("[%s] Tracking model status is changed on \"Invalid\"", __FUNCTION__);
+    }
+    else
+    {
+        target.m_state = ImageTrackingModel::Undetected;
+        LOGI("[%s] Tracking model status is changed on \"Undetected\"", __FUNCTION__);
+    }
+    pthread_spin_unlock(&target.m_stateGuard);
+
+    pthread_mutex_unlock(&target.m_globalGuard);
+}
+
+cv::Rect ImageTracker::computeExpectedArea(
+        const ImageTrackingModel& target,
+        const cv::Size& frameSize)
+{
+    if (target.m_state == ImageTrackingModel::Appeared)
+    {
+        LOGI("[%s] Expected area for appeared object is full frame.", __FUNCTION__);
+        return cv::Rect(0, 0, frameSize.width, frameSize.height);
+    }
+
+    if (target.m_lastLocation.empty())
+    {
+        LOGW("[%s] Can't compute expected area for object without last"
+                "location.",__FUNCTION__);
+        return cv::Rect(0, 0, 0, 0);
+    }
+
+    cv::Point2f ltCorner(target.m_lastLocation[0]);
+    cv::Point2f rbCorner(target.m_lastLocation[0]);
+
+    const size_t contourPointsNumber = target.m_lastLocation.size();
+
+    for (size_t pointNum = 1; pointNum < contourPointsNumber; ++pointNum)
+    {
+        if (ltCorner.x > target.m_lastLocation[pointNum].x)
+        {
+            ltCorner.x = target.m_lastLocation[pointNum].x;
+        }
+        else if (rbCorner.x < target.m_lastLocation[pointNum].x)
+        {
+            rbCorner.x = target.m_lastLocation[pointNum].x;
+        }
+
+        if (ltCorner.y > target.m_lastLocation[pointNum].y)
+        {
+            ltCorner.y = target.m_lastLocation[pointNum].y;
+        }
+        else if (rbCorner.y < target.m_lastLocation[pointNum].y)
+        {
+            rbCorner.y = target.m_lastLocation[pointNum].y;
+        }
+    }
+
+    cv::Point2f center(
+            (ltCorner.x + rbCorner.x) / 2.0f,
+            (ltCorner.y + rbCorner.y) / 2.0f);
+
+    cv::Size2f halfSize(
+            (center.x - ltCorner.x) * (1 + m_trackingParams.mExpectedOffset),
+            (center.y - ltCorner.y) * (1 + m_trackingParams.mExpectedOffset));
+
+
+    cv::Rect expectedArea(
+            center.x - halfSize.width, center.y - halfSize.height,
+            halfSize.width * 2, halfSize.height * 2);
+
+    if (expectedArea.x < 0)
+    {
+        expectedArea.width += expectedArea.x;
+        expectedArea.x = 0;
+    }
+
+    if (expectedArea.y < 0)
+    {
+        expectedArea.height += expectedArea.y;
+        expectedArea.y = 0;
+    }
+
+    if (expectedArea.x + expectedArea.width > frameSize.width)
+    {
+        expectedArea.width = frameSize.width - expectedArea.x;
+    }
+
+    if (expectedArea.y + expectedArea.height > frameSize.height)
+    {
+        expectedArea.height = frameSize.height - expectedArea.y;
+    }
+
+    if (expectedArea.width <= 0 || expectedArea.height <= 0)
+    {
+        expectedArea.x = 0;
+        expectedArea.y = 0;
+        expectedArea.width = 0;
+        expectedArea.height = 0;
+    }
+
+    return expectedArea;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageTrackingModel.cpp b/mv_image/image/src/ImageTrackingModel.cpp
new file mode 100644 (file)
index 0000000..e0a75c9
--- /dev/null
@@ -0,0 +1,365 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ImageTrackingModel.h"
+
+#include <app_common.h>
+
+#include "mv_private.h"
+#include "mv_common.h"
+
+#include <fstream>
+#include <unistd.h>
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageTrackingModel::ImageTrackingModel() :
+        m_recognitionObject(),
+        m_lastLocation(0),
+        m_state(Invalid),
+        m_recognitionThread(0)
+{
+    pthread_mutex_init(&m_globalGuard, NULL);
+    pthread_spin_init(&m_lastLocationGuard, PTHREAD_PROCESS_SHARED);
+    pthread_spin_init(&m_stateGuard, PTHREAD_PROCESS_SHARED);
+}
+
+ImageTrackingModel::ImageTrackingModel(const ImageObject& recognitionObject) :
+        m_recognitionObject(recognitionObject),
+        m_lastLocation(0),
+        m_state(Invalid),
+        m_recognitionThread(0)
+{
+    if (!recognitionObject.isEmpty())
+    {
+        m_state = Undetected;
+    }
+    pthread_mutex_init(&m_globalGuard, NULL);
+    pthread_spin_init(&m_lastLocationGuard, PTHREAD_PROCESS_SHARED);
+    pthread_spin_init(&m_stateGuard, PTHREAD_PROCESS_SHARED);
+}
+
+ImageTrackingModel::ImageTrackingModel(const ImageTrackingModel& copy) :
+        m_recognitionThread(0)
+{
+    pthread_mutex_init(&m_globalGuard, NULL);
+    pthread_spin_init(&m_lastLocationGuard, PTHREAD_PROCESS_SHARED);
+    pthread_spin_init(&m_stateGuard, PTHREAD_PROCESS_SHARED);
+
+    *this = copy;
+}
+
+ImageTrackingModel::~ImageTrackingModel()
+{
+    if (m_recognitionThread)
+    {
+        pthread_join(m_recognitionThread, NULL);
+    }
+
+    pthread_mutex_destroy(&m_globalGuard);
+    pthread_spin_destroy(&m_lastLocationGuard);
+    pthread_spin_destroy(&m_stateGuard);
+}
+
+void ImageTrackingModel::setTarget(const ImageObject& target)
+{
+    pthread_mutex_lock(&m_globalGuard);
+
+    pthread_spin_lock(&m_stateGuard);
+    m_state = target.isEmpty() ? Invalid : Undetected;
+    pthread_spin_unlock(&m_stateGuard);
+
+    pthread_spin_lock(&m_lastLocationGuard);
+    m_lastLocation.clear();
+    pthread_spin_unlock(&m_lastLocationGuard);
+
+    LOGI("[%s] Target is set into tracking model.", __FUNCTION__);
+
+    m_recognitionObject = target;
+
+    pthread_mutex_unlock(&m_globalGuard);
+}
+
+void ImageTrackingModel::refresh(void)
+{
+    pthread_mutex_lock(&m_globalGuard);
+
+    pthread_spin_lock(&m_stateGuard);
+    m_state = m_recognitionObject.isEmpty() ? Invalid : Undetected;
+    pthread_spin_unlock(&m_stateGuard);
+
+    pthread_spin_lock(&m_lastLocationGuard);
+    m_lastLocation.clear();
+    pthread_spin_unlock(&m_lastLocationGuard);
+
+    LOGI("[%s] Image tracking model is refreshed.", __FUNCTION__);
+
+    pthread_mutex_unlock(&m_globalGuard);
+}
+
+bool ImageTrackingModel::isValid() const
+{
+    bool result = false;
+
+    pthread_spin_lock(&m_stateGuard);
+    result = (m_state != Invalid);
+    pthread_spin_unlock(&m_stateGuard);
+
+    return result;
+}
+
+ImageTrackingModel& ImageTrackingModel::operator=(const ImageTrackingModel& copy)
+{
+    if (this != &copy)
+    {
+        pthread_mutex_t *higherMutex = &m_globalGuard;
+        pthread_mutex_t *lowerMutex = &copy.m_globalGuard;
+
+        if (higherMutex < lowerMutex)
+        {
+            std::swap(higherMutex, lowerMutex);
+        }
+
+        pthread_mutex_lock(higherMutex);
+        pthread_mutex_lock(lowerMutex);
+
+        m_recognitionObject = copy.m_recognitionObject;
+
+        pthread_spin_lock(&m_lastLocationGuard);
+        m_lastLocation = copy.m_lastLocation;
+        pthread_spin_unlock(&m_lastLocationGuard);
+
+        if (copy.m_state == InProcess)
+        {
+            pthread_spin_lock(&m_stateGuard);
+            m_state = m_recognitionObject.isEmpty() ? Invalid : Undetected;
+            pthread_spin_unlock(&m_stateGuard);
+        }
+        else
+        {
+            pthread_spin_lock(&m_stateGuard);
+            m_state = copy.m_state;
+            pthread_spin_unlock(&m_stateGuard);
+        }
+
+        pthread_mutex_unlock(lowerMutex);
+        pthread_mutex_unlock(higherMutex);
+    }
+
+    return *this;
+}
+
+int ImageTrackingModel::save(const char *fileName) const
+{
+    std::string prefix_path = std::string(app_get_data_path());
+    LOGD("prefix_path: %s", prefix_path.c_str());
+
+    std::string filePath;
+    filePath += prefix_path;
+    filePath += fileName;
+
+    /* check the directory is available */
+    std::string prefix_path_check = filePath.substr(0, filePath.find_last_of('/'));
+    if (access(prefix_path_check.c_str(),F_OK))
+    {
+        LOGE("Can't save tracking model. Path[%s] doesn't existed.", prefix_path_check.c_str());
+
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    std::ofstream out;
+    out.open(filePath.c_str());
+
+    if (!out.is_open())
+    {
+        LOGE("[%s] Can't create/open file.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    out<<(*this);
+
+    out.close();
+    LOGI("[%s] Image tracking model is saved.", __FUNCTION__);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageTrackingModel::load(const char *fileName)
+{
+    /* find directory */
+    std::string prefix_path = std::string(app_get_data_path());
+    LOGD("prefix_path: %s", prefix_path.c_str());
+
+    std::string filePath;
+    filePath += prefix_path;
+    filePath += fileName;
+
+    if (access(filePath.c_str(),F_OK))
+    {
+        LOGE("Can't load tracking model. Path[%s] doesn't existed.", filePath.c_str());
+
+        return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    std::ifstream in;
+    in.open(filePath.c_str());
+
+    if (!in.is_open())
+    {
+        LOGE("[%s] Can't open file.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    in>>(*this);
+
+    if (!in.good())
+    {
+        LOGE("[%s] Unexpected end of file.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+    }
+
+    in.close();
+    LOGI("[%s] Image tracking model is loaded.", __FUNCTION__);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+bool ImageTrackingModel::isDetected() const
+{
+    bool result = false;
+
+    pthread_spin_lock(&m_stateGuard);
+    result = (m_state == Tracked);
+    pthread_spin_unlock(&m_stateGuard);
+
+    return result;
+}
+
+std::vector<cv::Point2f> ImageTrackingModel::getLastlocation() const
+{
+    std::vector<cv::Point2f> result;
+
+    pthread_spin_lock(&m_lastLocationGuard);
+    result = m_lastLocation;
+    pthread_spin_unlock(&m_lastLocationGuard);
+
+    return result;
+}
+
+#define STATE_UNSEEN_IO_ID 0
+#define STATE_VISIBLE_IO_ID 1
+
+std::ostream& operator << (std::ostream& os, const ImageTrackingModel::State& state)
+{
+    if (ImageTrackingModel::Tracked == state)
+    {
+        os<<STATE_VISIBLE_IO_ID;
+    }
+    else
+    {
+        os<<STATE_UNSEEN_IO_ID;
+    }
+
+    return os;
+}
+
+std::istream& operator >> (std::istream& is, ImageTrackingModel::State& state)
+{
+    int stateId = -1;
+
+    is>>stateId;
+
+    if (STATE_VISIBLE_IO_ID == stateId)
+    {
+        state = ImageTrackingModel::Tracked;
+    }
+    else
+    {
+        state = ImageTrackingModel::Undetected;
+    }
+
+    return is;
+}
+
+#undef STATE_UNSEEN_IO_ID
+#undef STATE_VISIBLE_IO_ID
+
+std::ostream& operator << (std::ostream& os, const ImageTrackingModel& obj)
+{
+    os<<std::setprecision(7);
+
+    pthread_mutex_lock(&obj.m_globalGuard);
+
+    os<<obj.m_recognitionObject;
+
+    os<<obj.m_lastLocation.size();
+    for (size_t pointNum = 0u; pointNum < obj.m_lastLocation.size(); ++pointNum)
+    {
+        os<<' '<<obj.m_lastLocation[pointNum].x<<' '<<obj.m_lastLocation[pointNum].y;
+    }
+    os<<'\n';
+
+    os<<obj.m_state<<'\n';
+
+    pthread_mutex_unlock(&obj.m_globalGuard);
+
+    return os;
+}
+
+std::istream& operator >> (std::istream& is, ImageTrackingModel& obj)
+{
+#define MEDIA_VISION_CHECK_IFSTREAM \
+    if (!is.good()) \
+    { \
+        return is; \
+    }
+
+    ImageTrackingModel temporal;
+
+    is>>obj.m_recognitionObject;
+    MEDIA_VISION_CHECK_IFSTREAM
+
+    size_t lastLocationAmount = 0u;
+    is>>lastLocationAmount;
+    MEDIA_VISION_CHECK_IFSTREAM
+
+    temporal.m_lastLocation.resize(lastLocationAmount);
+    for (size_t pointNum = 0u; pointNum < lastLocationAmount; ++pointNum)
+    {
+        is>>temporal.m_lastLocation[pointNum].x;
+        MEDIA_VISION_CHECK_IFSTREAM
+        is>>temporal.m_lastLocation[pointNum].y;
+        MEDIA_VISION_CHECK_IFSTREAM
+    }
+
+    is>>temporal.m_state;
+    MEDIA_VISION_CHECK_IFSTREAM
+
+    if (temporal.m_recognitionObject.isEmpty())
+    {
+        temporal.m_state = ImageTrackingModel::Invalid;
+    }
+
+    obj = temporal;
+
+    return is;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/mv_image_open.cpp b/mv_image/image/src/mv_image_open.cpp
new file mode 100644 (file)
index 0000000..1d351a4
--- /dev/null
@@ -0,0 +1,784 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_image_open.h"
+
+#include "mv_private.h"
+#include "mv_common_c.h"
+
+#include "ImageObject.h"
+#include "ImageRecognizer.h"
+#include "ImageTrackingModel.h"
+#include "ImageTracker.h"
+
+#include <opencv/cv.h>
+
+namespace
+{
+
+const MediaVision::Image::FeaturesExtractingParams
+        defaultObjectFeaturesExtractingParams(1.2, 1000);
+
+const MediaVision::Image::FeaturesExtractingParams
+        defaultSceneFeaturesExtractingParams(1.2, 5000);
+
+const MediaVision::Image::RecognitionParams
+        defaultRecognitionParams(15, 0.33, 0.1);
+
+const MediaVision::Image::StabilizationParams
+        defaultStabilizationParams(3, 0.006, 2, 0.001);
+
+const MediaVision::Image::TrackingParams
+        defaultTrackingParams(
+                defaultSceneFeaturesExtractingParams,
+                defaultRecognitionParams,
+                defaultStabilizationParams,
+                0.0);
+
+void extractTargetFeaturesExtractingParams(
+        mv_engine_config_h engine_cfg,
+        MediaVision::Image::FeaturesExtractingParams& featuresExtractingParams)
+{
+    mv_engine_config_h working_cfg = NULL;
+
+    if (NULL == engine_cfg)
+    {
+        mv_create_engine_config(&working_cfg);
+    }
+    else
+    {
+        working_cfg = engine_cfg;
+    }
+
+    featuresExtractingParams = defaultObjectFeaturesExtractingParams;
+
+    mv_engine_config_get_double_attribute_c(
+            working_cfg,
+            "MV_IMAGE_RECOGNITION_OBJECT_SCALE_FACTOR",
+            &featuresExtractingParams.mScaleFactor);
+
+    mv_engine_config_get_int_attribute_c(
+            working_cfg,
+            "MV_IMAGE_RECOGNITION_OBJECT_MAX_KEYPOINTS_NUM",
+            &featuresExtractingParams.mMaximumFeaturesNumber);
+
+    if (NULL == engine_cfg)
+    {
+        mv_destroy_engine_config(working_cfg);
+    }
+}
+
+void extractSceneFeaturesExtractingParams(
+        mv_engine_config_h engine_cfg,
+        MediaVision::Image::FeaturesExtractingParams& featuresExtractingParams)
+{
+    mv_engine_config_h working_cfg = NULL;
+
+    if (NULL == engine_cfg)
+    {
+        mv_create_engine_config(&working_cfg);
+    }
+    else
+    {
+        working_cfg = engine_cfg;
+    }
+
+    featuresExtractingParams = defaultSceneFeaturesExtractingParams;
+
+    mv_engine_config_get_double_attribute_c(
+            working_cfg,
+            "MV_IMAGE_RECOGNITION_SCENE_SCALE_FACTOR",
+            &featuresExtractingParams.mScaleFactor);
+
+    mv_engine_config_get_int_attribute_c(
+            working_cfg,
+            "MV_IMAGE_RECOGNITION_SCENE_MAX_KEYPOINTS_NUM",
+            &featuresExtractingParams.mMaximumFeaturesNumber);
+
+    if (NULL == engine_cfg)
+    {
+        mv_destroy_engine_config(working_cfg);
+    }
+}
+
+void extractRecognitionParams(
+        mv_engine_config_h engine_cfg,
+        MediaVision::Image::RecognitionParams& recognitionParams)
+{
+    mv_engine_config_h working_cfg = NULL;
+
+    if (NULL == engine_cfg)
+    {
+        mv_create_engine_config(&working_cfg);
+    }
+    else
+    {
+        working_cfg = engine_cfg;
+    }
+
+    recognitionParams = defaultRecognitionParams;
+
+    mv_engine_config_get_int_attribute_c(
+            working_cfg,
+            "MV_IMAGE_RECOGNITION_MIN_MATCH_NUM",
+            &recognitionParams.mMinMatchesNumber);
+
+    mv_engine_config_get_double_attribute_c(
+            working_cfg,
+            "MV_IMAGE_RECOGNITION_REQ_MATCH_PART",
+            &recognitionParams.mRequiredMatchesPart);
+
+    mv_engine_config_get_double_attribute_c(
+            working_cfg,
+            "MV_IMAGE_RECOGNITION_TOLERANT_MATCH_PART_ERR",
+            &recognitionParams.mAllowableMatchesPartError);
+
+    if (NULL == engine_cfg)
+    {
+        mv_destroy_engine_config(working_cfg);
+    }
+}
+
+void extractStabilizationParams(
+        mv_engine_config_h engine_cfg,
+        MediaVision::Image::StabilizationParams& stabilizationParams)
+{
+    mv_engine_config_h working_cfg = NULL;
+
+    if (NULL == engine_cfg)
+    {
+        mv_create_engine_config(&working_cfg);
+    }
+    else
+    {
+        working_cfg = engine_cfg;
+    }
+
+    stabilizationParams = defaultStabilizationParams;
+
+    bool useStabilization = true;
+    mv_engine_config_get_bool_attribute_c(
+            working_cfg,
+            "MV_IMAGE_TRACKING_USE_STABLIZATION",
+            &useStabilization);
+
+    if (!useStabilization)
+    {
+        stabilizationParams.mHistoryAmount = 0;
+        if (NULL == engine_cfg)
+        {
+            mv_destroy_engine_config(working_cfg);
+        }
+        return;
+    }
+
+    mv_engine_config_get_int_attribute_c(
+            working_cfg,
+            "MV_IMAGE_TRACKING_HISTORY_AMOUNT",
+            &stabilizationParams.mHistoryAmount);
+
+    mv_engine_config_get_double_attribute_c(
+            working_cfg,
+            "MV_IMAGE_TRACKING_STABLIZATION_TOLERANT_SHIFT",
+            &stabilizationParams.mAllowableShift);
+
+    mv_engine_config_get_double_attribute_c(
+            working_cfg,
+            "MV_IMAGE_TRACKING_STABLIZATION_SPEED",
+            &stabilizationParams.mStabilizationSpeed);
+
+    mv_engine_config_get_double_attribute_c(
+            working_cfg,
+            "MV_IMAGE_TRACKING_STABLIZATION_ACCELERATION",
+            &stabilizationParams.mStabilizationAcceleration);
+
+    if (NULL == engine_cfg)
+    {
+        mv_destroy_engine_config(working_cfg);
+    }
+}
+
+void extractTrackingParams(
+        mv_engine_config_h engine_cfg,
+        MediaVision::Image::TrackingParams& trackingParams)
+{
+    mv_engine_config_h working_cfg = NULL;
+
+    if (NULL == engine_cfg)
+    {
+        mv_create_engine_config(&working_cfg);
+    }
+    else
+    {
+        working_cfg = engine_cfg;
+    }
+
+    trackingParams = defaultTrackingParams;
+
+    extractSceneFeaturesExtractingParams(
+            working_cfg,
+            trackingParams.mFramesFeaturesExtractingParams);
+
+    extractRecognitionParams(
+            working_cfg,
+            trackingParams.mRecognitionParams);
+
+    extractStabilizationParams(
+            working_cfg,
+            trackingParams.mStabilizationParams);
+
+    mv_engine_config_get_double_attribute_c(
+            working_cfg,
+            "MV_IMAGE_TRACKING_EXPECTED_OFFSET",
+            &trackingParams.mExpectedOffset);
+
+    if (NULL == engine_cfg)
+    {
+        mv_destroy_engine_config(working_cfg);
+    }
+}
+
+int convertSourceMV2GrayCV(mv_source_h mvSource, cv::Mat& cvSource)
+{
+    MEDIA_VISION_INSTANCE_CHECK(mvSource);
+
+    int depth = CV_8U; // Default depth. 1 byte for channel.
+    unsigned int channelsNumber = 0u;
+    unsigned int width = 0u, height = 0u;
+    unsigned int bufferSize = 0u;
+    unsigned char *buffer = NULL;
+
+    mv_colorspace_e colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+
+    MEDIA_VISION_ASSERT(mv_source_get_width(mvSource, &width),
+            "Failed to get the width.");
+    MEDIA_VISION_ASSERT(mv_source_get_height(mvSource, &height),
+            "Failed to get the height.");
+    MEDIA_VISION_ASSERT(mv_source_get_colorspace(mvSource, &colorspace),
+            "Failed to get the colorspace.");
+    MEDIA_VISION_ASSERT(mv_source_get_buffer(mvSource, &buffer, &bufferSize),
+            "Failed to get the buffer size.");
+
+    int conversionType = -1; // Type of conversion from given colorspace to gray
+    switch(colorspace)
+    {
+        case MEDIA_VISION_COLORSPACE_INVALID:
+            LOGE("Error: mv_source has invalid colorspace.");
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        case MEDIA_VISION_COLORSPACE_Y800:
+            channelsNumber = 1;
+            // Without convertion
+            break;
+        case MEDIA_VISION_COLORSPACE_I420:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2GRAY_I420;
+            break;
+        case MEDIA_VISION_COLORSPACE_NV12:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2GRAY_NV12;
+            break;
+        case MEDIA_VISION_COLORSPACE_YV12:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2GRAY_YV12;
+            break;
+        case MEDIA_VISION_COLORSPACE_NV21:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2GRAY_NV21;
+            break;
+        case MEDIA_VISION_COLORSPACE_YUYV:
+            channelsNumber = 2;
+            conversionType = CV_YUV2GRAY_YUYV;
+            break;
+        case MEDIA_VISION_COLORSPACE_UYVY:
+            channelsNumber = 2;
+            conversionType = CV_YUV2GRAY_UYVY;
+            break;
+        case MEDIA_VISION_COLORSPACE_422P:
+            channelsNumber = 2;
+            conversionType = CV_YUV2GRAY_Y422;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB565:
+            channelsNumber = 2;
+            conversionType = CV_BGR5652GRAY;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB888:
+            channelsNumber = 3;
+            conversionType = CV_RGB2GRAY;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGBA:
+            channelsNumber = 4;
+            conversionType = CV_RGBA2GRAY;
+            break;
+        default:
+            LOGE("Error: mv_source has unsupported colorspace.");
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    if (conversionType == -1) // Without conversion
+    {
+        cvSource = cv::Mat(cv::Size(width, height),
+                CV_MAKETYPE(depth, channelsNumber), buffer).clone();
+    }
+    else // Conversion
+    {
+        // Class for representation the given image as cv::Mat before conversion
+        cv::Mat origin(cv::Size(width, height),
+                CV_MAKETYPE(depth, channelsNumber), buffer);
+        cv::cvtColor(origin, cvSource, conversionType);
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* anonymous namespace */
+
+int mv_image_recognize_open(
+        mv_source_h source,
+        const mv_image_object_h *image_objects,
+        int number_of_objects,
+        mv_engine_config_h engine_cfg,
+        mv_image_recognized_cb recognized_cb,
+        void *user_data)
+{
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(image_objects);
+    for (int objectNum = 0; objectNum < number_of_objects; ++objectNum)
+    {
+        MEDIA_VISION_INSTANCE_CHECK(image_objects[objectNum]);
+    }
+    MEDIA_VISION_NULL_ARG_CHECK(recognized_cb);
+
+    cv::Mat scene;
+    MEDIA_VISION_ASSERT(
+            convertSourceMV2GrayCV(source, scene),
+            "Failed to convert mv_source.");
+
+    MediaVision::Image::FeaturesExtractingParams featuresExtractingParams;
+    extractSceneFeaturesExtractingParams(engine_cfg, featuresExtractingParams);
+
+    MediaVision::Image::RecognitionParams recognitionParams;
+    extractRecognitionParams(engine_cfg, recognitionParams);
+
+    MediaVision::Image::ImageRecognizer recognizer(scene,
+            featuresExtractingParams);
+
+    mv_quadrangle_s *resultLocations[number_of_objects];
+
+    for (int objectNum = 0; objectNum < number_of_objects; ++objectNum)
+    {
+        std::vector<cv::Point2f> resultContour;
+        bool isRecognized = recognizer.recognize(
+                *((MediaVision::Image::ImageObject*)image_objects[objectNum]),
+                recognitionParams, resultContour);
+        if (isRecognized && (resultContour.size() ==
+                MediaVision::Image::NumberOfQuadrangleCorners))
+        {
+            resultLocations[objectNum] = new mv_quadrangle_s;
+            for (size_t pointNum = 0u;
+                    pointNum < MediaVision::Image::NumberOfQuadrangleCorners;
+                    ++pointNum)
+            {
+                resultLocations[objectNum]->points[pointNum].x =
+                        resultContour[pointNum].x;
+                resultLocations[objectNum]->points[pointNum].y =
+                        resultContour[pointNum].y;
+            }
+        }
+        else
+        {
+            resultLocations[objectNum] = NULL;
+        }
+    }
+
+    recognized_cb(
+            source,
+            engine_cfg,
+            image_objects,
+            resultLocations,
+            number_of_objects,
+            user_data);
+
+    for (int objectNum = 0; objectNum < number_of_objects; ++objectNum)
+    {
+        if (resultLocations[objectNum] != NULL)
+        {
+            delete resultLocations[objectNum];
+            resultLocations[objectNum] = NULL;
+        }
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_track_open(
+        mv_source_h source,
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_image_tracked_cb tracked_cb,
+        void *user_data)
+{
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+    MEDIA_VISION_NULL_ARG_CHECK(tracked_cb);
+
+    if (!((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->isValid())
+    {
+        LOGE("[%s] Image tracking model is invalid.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_INVALID_DATA;
+    }
+
+    MediaVision::Image::TrackingParams trackingParams;
+    extractTrackingParams(engine_cfg, trackingParams);
+
+    cv::Mat frame;
+    MEDIA_VISION_ASSERT(
+            convertSourceMV2GrayCV(source, frame),
+            "Failed to convert mv_source.");
+
+    MediaVision::Image::ImageTracker tracker(trackingParams);
+
+    MediaVision::Image::ImageTrackingModel *trackingModel =
+            (MediaVision::Image::ImageTrackingModel*)image_tracking_model;
+
+    tracker.track(frame, *trackingModel);
+
+    std::vector<cv::Point2f> resultContour = trackingModel->getLastlocation();
+
+    if (trackingModel->isDetected() &&
+            MediaVision::Image::NumberOfQuadrangleCorners == resultContour.size())
+    {
+        mv_quadrangle_s result;
+        for (size_t pointNum = 0u;
+                pointNum < MediaVision::Image::NumberOfQuadrangleCorners;
+                ++pointNum)
+        {
+            result.points[pointNum].x = resultContour[pointNum].x;
+            result.points[pointNum].y = resultContour[pointNum].y;
+        }
+        tracked_cb(source, image_tracking_model, engine_cfg, &result, user_data);
+    }
+    else
+    {
+        tracked_cb(source, image_tracking_model, engine_cfg, NULL, user_data);
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_create_open(
+        mv_image_object_h *image_object)
+{
+    MEDIA_VISION_NULL_ARG_CHECK(image_object);
+
+    (*image_object) = (mv_image_object_h)new (std::nothrow)MediaVision::Image::ImageObject();
+    if (*image_object == NULL)
+    {
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_destroy_open(
+        mv_image_object_h image_object)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+    delete (MediaVision::Image::ImageObject*)image_object;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_fill_open(
+        mv_image_object_h image_object,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_rectangle_s *location)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+
+    cv::Mat image;
+    MEDIA_VISION_ASSERT(
+            convertSourceMV2GrayCV(source, image),
+            "Failed to convert mv_source.");
+
+    MediaVision::Image::FeaturesExtractingParams featuresExtractingParams;
+    extractTargetFeaturesExtractingParams(engine_cfg, featuresExtractingParams);
+
+    if (NULL == location)
+    {
+        ((MediaVision::Image::ImageObject*)image_object)->fill(image,
+                featuresExtractingParams);
+    }
+    else
+    {
+        if (!((MediaVision::Image::ImageObject*)image_object)->fill(image,
+                cv::Rect(location->point.x, location->point.y,
+                        location->width, location->height),
+                        featuresExtractingParams))
+        {
+            // Wrong ROI (bounding box)
+            LOGE("[%s] Wrong ROI.", __FUNCTION__);
+            return MEDIA_VISION_ERROR_INVALID_DATA;
+        }
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_get_recognition_rate_open(
+        mv_image_object_h image_object,
+        double *recognition_rate)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+    MEDIA_VISION_NULL_ARG_CHECK(recognition_rate);
+
+    (*recognition_rate) =
+            ((MediaVision::Image::ImageObject*)image_object)->getRecognitionRate();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_set_label_open(
+        mv_image_object_h image_object,
+        int label)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+    ((MediaVision::Image::ImageObject*)image_object)->setLabel(label);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+int mv_image_object_get_label_open(
+        mv_image_object_h image_object,
+        int *label)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+    MEDIA_VISION_NULL_ARG_CHECK(label);
+
+    if (!((MediaVision::Image::ImageObject*)image_object)->getLabel(*label))
+    {
+        LOGW("[%s] Image object haven't a label.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_NO_DATA;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_clone_open(
+        mv_image_object_h src,
+        mv_image_object_h *dst)
+{
+    MEDIA_VISION_INSTANCE_CHECK(src);
+    MEDIA_VISION_NULL_ARG_CHECK(dst);
+
+    (*dst) = (mv_image_object_h)new (std::nothrow)MediaVision::Image::ImageObject();
+    if (*dst == NULL)
+    {
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    *(MediaVision::Image::ImageObject*)(*dst) =
+            *(MediaVision::Image::ImageObject*)src;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_save_open(
+        const char *file_name, mv_image_object_h image_object)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    int ret = ((MediaVision::Image::ImageObject*)image_object)->save(file_name);
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Fail to save image object.");
+        return ret;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_load_open(
+        const char *file_name, mv_image_object_h *image_object)
+{
+    MEDIA_VISION_NULL_ARG_CHECK(image_object);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    (*image_object) = (mv_image_object_h)new (std::nothrow)MediaVision::Image::ImageObject();
+    if (*image_object == NULL)
+    {
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    int ret = ((MediaVision::Image::ImageObject*)(*image_object))->load(file_name);
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Fail to save image object.");
+        return ret;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_create_open(
+        mv_image_tracking_model_h *image_tracking_model)
+{
+    MEDIA_VISION_NULL_ARG_CHECK(image_tracking_model);
+
+    (*image_tracking_model) = (mv_image_tracking_model_h)
+            new (std::nothrow)MediaVision::Image::ImageTrackingModel();
+    if (*image_tracking_model == NULL)
+    {
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_set_target_open(
+        mv_image_object_h image_object,
+        mv_image_tracking_model_h image_tracking_model)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+    if (((MediaVision::Image::ImageObject*)image_object)->isEmpty())
+    {
+        LOGE("[%s] Target is empty and can't be set as target of tracking"
+                "model.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_INVALID_DATA;
+    }
+
+    ((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->setTarget(
+            *(MediaVision::Image::ImageObject*)image_object);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_destroy_open(
+        mv_image_tracking_model_h image_tracking_model)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+    delete (MediaVision::Image::ImageTrackingModel*)image_tracking_model;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_refresh_open(
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h /*engine_cfg*/)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+    if (!((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->isValid())
+    {
+        LOGE("[%s] Image tracking model is invalid.", __FUNCTION__);
+        return MEDIA_VISION_ERROR_INVALID_DATA;
+    }
+
+    ((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->refresh();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_clone_open(
+        mv_image_tracking_model_h src,
+        mv_image_tracking_model_h *dst)
+{
+    MEDIA_VISION_INSTANCE_CHECK(src);
+    MEDIA_VISION_NULL_ARG_CHECK(dst);
+
+    (*dst) = (mv_image_tracking_model_h)new (std::nothrow)MediaVision::Image::ImageTrackingModel();
+    if (*dst == NULL)
+    {
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    *(MediaVision::Image::ImageObject*)(*dst) = *(MediaVision::Image::ImageObject*)src;
+
+    LOGD("Image tracking model has been successfully cloned");
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_save_open(
+        const char *file_name, mv_image_tracking_model_h image_tracking_model)
+{
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    int ret = ((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->save(file_name);
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to save image tracking model");
+        return ret;
+    }
+
+    LOGD("Image tracking model has been successfully saved");
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_load_open(
+        const char *file_name, mv_image_tracking_model_h *image_tracking_model)
+{
+    MEDIA_VISION_NULL_ARG_CHECK(image_tracking_model);
+
+    if (file_name == NULL)
+    {
+         LOGE("File path is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    (*image_tracking_model) =
+        (mv_image_tracking_model_h) new (std::nothrow)MediaVision::Image::ImageTrackingModel();
+
+    if (*image_tracking_model == NULL)
+    {
+        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+    }
+
+    int ret = ((MediaVision::Image::ImageTrackingModel*)(*image_tracking_model))->load(file_name);
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Failed to load image tracking model");
+        return ret;
+    }
+
+    LOGD("Image tracking model has been successfully loaded");
+    return MEDIA_VISION_ERROR_NONE;
+}
diff --git a/mv_image/image_lic/CMakeLists.txt b/mv_image/image_lic/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b38e47b
--- /dev/null
@@ -0,0 +1,25 @@
+project(${MV_IMAGE_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_IMAGE_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_IMAGE_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.c")
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_IMAGE_INC_LIST} ${MV_IMAGE_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_IMAGE_INC_LIST} ${MV_IMAGE_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_image/image_lic/include/mv_image_lic.h b/mv_image/image_lic/include/mv_image_lic.h
new file mode 100644 (file)
index 0000000..29e1c1d
--- /dev/null
@@ -0,0 +1,564 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_IMAGE_LIC_H__
+#define __TIZEN_MEDIAVISION_IMAGE_LIC_H__
+
+#include "mv_image.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file  mv_image_lic.h
+ * @brief This file contains the Media Vision Image API for the licensed module.
+ *        Working with images (like planar objects): recognition and tracking.
+ */
+
+/****************************/
+/* Image object recognition */
+/****************************/
+
+/**
+ * @brief Recognizes the given image objects on the source image.
+ * @details Use this function to launch image recognition algorithm configured
+ *          by @a engine_conf configuration.
+ *
+ * @since_tizen 3.0
+ * @param [in] source              The handle to the source image on which image
+ *                                 objects will be recognized
+ * @param [in] image_objects       The set of handles to the image objects which
+ *                                 will be processed as targets of recognition
+ * @param [in] number_of_objects   The number of image objects
+ * @param [in] engine_cfg          The handle to the configuration of engine
+ *                                 which will be used for recognition. If NULL,
+ *                                 then default settings will be used.
+ * @param [in] recognized_cb       The callback which will be called in order to
+ *                                 process recognition result
+ * @param [in] user_data           The user data to be passed to the
+ *                                 @a recognized_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a set of image objects using @ref mv_image_object_create_lic()
+ *      for each of them and construct (fill / load / clone) them on images that
+ *      will be recognized
+ * @pre Create a source handle by calling @ref mv_create_source() and fill
+ *      by the image for which recognition will be performed
+ * @post @a mv_image_recognized_cb will be called to process recognition result
+ * @post Release source image by using @ref mv_destroy_source()
+ * @post Release image objects by using @ref mv_image_object_destroy_lic() for
+ *       each handle from @a image_objects set
+ *
+ * @see mv_image_recognized_cb
+ * @see mv_source_h
+ * @see mv_create_source()
+ * @see mv_destroy_source()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ * @see mv_engine_config_h
+ */
+int mv_image_recognize_lic(
+        mv_source_h source,
+        const mv_image_object_h *image_objects,
+        int number_of_objects,
+        mv_engine_config_h engine_cfg,
+        mv_image_recognized_cb recognized_cb,
+        void *user_data);
+
+/*************************/
+/* Image object tracking */
+/*************************/
+
+/**
+ * @brief Tracks the given image tracking model on the current frame
+ * @details Image tracking on a sequence of frames assumes calling this
+ *          function for each frame in the correct order.
+ *          @a tracked_cb will be called  for result processing.
+ *
+ * @since_tizen 3.0
+ * @remarks Tracking algorithm is usually using for recognition of image object
+ *          on the sequence of images that are organized by time. For example,
+ *          it may be the sequence of frames from a video stream.
+ * @remarks If object is lost during the tracking, system tries to find it
+ *          further for the following frames. Therefore, tracking will be
+ *          recovered when object appears again.
+ * @remarks Previous calls of @ref mv_image_track_lic() for this
+ *          @a image_tracking_model will affect on current call
+ * @param [in]     source                 The handle to the current image of
+ *                                        sequence where image tracking model
+ *                                        will be tracked
+ * @param [in,out] image_tracking_model   The handle to the image tracking model
+ *                                        which processed as target of tracking
+ * @param [in]     engine_cfg             The handle to the configuration of
+ *                                        engine which will be used for tracking.
+ *                                        If NULL, then default settings will be
+ *                                        used.
+ * @param [in]     tracked_cb             The callback which will receive
+ *                                        tracking results
+ * @param [in]     user_data              The user data to be passed to the
+ *                                        @a tracked_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create_lic() and set target by calling
+ *      @ref mv_image_tracking_model_set_target_lic()
+ * @pre Create a source images by calling @ref mv_create_source() for each of
+ *      them and construct them based on sequence of images for which will be
+ *      held image tracking
+ * @post @a tracked_cb will be called to process tracking result
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy_lic()
+ *
+ * @see mv_image_tracked_cb
+ * @see mv_source_h
+ * @see image_tracking_model_h
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_tracking_model_set_target_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_track_lic(
+        mv_source_h source,
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_image_tracked_cb tracked_cb,
+        void *user_data);
+
+/**************************/
+/* Image object behaviour */
+/**************************/
+
+/**
+ * @brief Creates an image object.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_object    A new handle to the image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Release image object by using mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_create_lic(
+        mv_image_object_h *image_object);
+
+/**
+ * @brief Destroys the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object    The handle to the image object to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_image_object_create_lic()
+ */
+int mv_image_object_destroy_lic(
+        mv_image_object_h image_object);
+
+/**
+ * @brief Fills the image object.
+ * @details Extracts data from @a source image which will be needed for
+ *          recognition of depicted object in @a location.
+ *
+ * @since_tizen 3.0
+ * @remarks After filling the image object it can be evaluated by
+ *          @ref mv_image_object_get_recognition_rate_lic(). If recognition rate
+ *          is too low, try to use another image of object or change
+ *          configuration parameters (see @ref mv_engine_config_h) and construct
+ *          the image object again.
+ * @param [in,out] image_object    The handle to the image object which will be
+ *                                 filled and can be recognized in future
+ * @param [in]     engine_cfg      The handle to the configuration of engine
+ *                                 which will be used for extract recognition
+ *                                 data from @a source. If NULL, then default
+ *                                 settings will be used.
+ * @param [in]     source          The source image where image object is depicted
+ * @param [in]     location        The pointer to location of the image object
+ *                                 on the source image, or NULL if the object is
+ *                                 shown in full
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_lic()
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_get_recognition_rate_lic()
+ * @see mv_image_recognize_lic()
+ * @see mv_image_object_destroy_lic()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_fill_lic(
+        mv_image_object_h image_object,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_rectangle_s *location);
+
+/**
+ * @brief Gets a value that determines how well an image object can be recognized.
+ * @details Recognition rate determines how well an image object can be
+ *          recognized. This value can be from 0 to 1. If the recognition rate
+ *          is 0 object can not be recognized and the bigger it is the more
+ *          likely to recognize the object.
+ *
+ * @since_tizen 3.0
+ * @remarks If recognition rate is too low, try to use another image of object
+ *          or change some configuration parameters (see @ref mv_engine_config_h)
+ *          and fill the image object again
+ *          (see @ref mv_image_object_fill_lic()).
+ * @param [in]  image_object        The handle to the image object which will be
+ *                                  evaluated by this function
+ * @param [out] recognition_rate    A value that determines how well an image
+ *                                  object can be recognized, if 0 then object
+ *                                  can not be recognized
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_lic()
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_fill_lic()
+ * @see mv_image_object_destroy_lic()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_get_recognition_rate_lic(
+        mv_image_object_h image_object,
+        double *recognition_rate);
+
+/**
+ * @brief Sets a label for the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object   The handle to the image object for which the label
+ *                            will be assigned
+ * @param [in] label          The label which will be assigned to the image
+ *                            object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_lic()
+ * @post Label could be received by using
+ *       @ref mv_image_object_get_label_lic()
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_get_label_lic()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_set_label_lic(
+        mv_image_object_h image_object,
+        int label);
+
+/**
+ * @brief Gets a label of image object.
+ *
+ * @since_tizen 3.0
+ * @remarks If @a image_object have not a label, this function return
+ *          MEDIA_VISION_ERROR_NO_DATA value.
+ * @param [in]  image_object   The handle to the image object from which a
+ *                             label will be received
+ * @param [out] label          The label of image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NO_DATA Image object hasn't label
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_lic()
+ * @pre Set label for the image object by using
+ *      @ref mv_image_object_set_label_lic()
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_set_label_lic()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_get_label_lic(
+        mv_image_object_h image_object,
+        int *label);
+
+/**
+ * @brief Clones the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in]  src    The handle to the source image object
+ * @param [out] dst    The handle to the destination image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object handles by calling mv_image_object_create_lic()
+ *
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_clone_lic(
+        mv_image_object_h src,
+        mv_image_object_h *dst);
+
+/**
+ * @brief Saves the image object.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is saved to the application's data directory.
+ * @param [in] file_name       Name of the file to save the image object
+ * @param [in] image_object    The handle to the image object which will be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_load_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_save_lic(
+        const char *file_name, mv_image_object_h image_object);
+
+/**
+ * @brief Loads an image object from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is loaded from the application's data directory.
+ *          @a image_object must be destroyed using
+ *          @ref mv_image_object_destroy().
+ * @param [in]  file_name       Name of file to load the image object
+ * @param [out] image_object    The handle to the image object which will be
+ *                              filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Image object can be preliminary saved with mv_image_object_save()
+ *      function
+ *
+ * @see mv_image_object_save_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_load_lic(
+        const char *file_name, mv_image_object_h image_object);
+
+/**********************************/
+/* Image tracking model behaviour */
+/**********************************/
+
+/**
+ * @brief Creates an image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_tracking_model    A new handle to the image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Release image tracking model by using mv_image_tracking_model_destroy_lic()
+ *
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_create_lic(
+        mv_image_tracking_model_h *image_tracking_model);
+
+/**
+ * @brief Sets target of image tracking model.
+ * @details Sets image object which will be tracked by using tracking
+ *          functionality with @a image_tracking_model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object            Image object which will be set
+ *                                     as target for tracking
+ * @param [in] image_tracking_model    Handle to the image tracking model
+ *                                     for which will be set a new target
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create_lic()
+ * @pre Create an image object using @ref mv_image_object_create_lic() and
+ *      construct (fill / load / clone) it on image that will be tracking
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy_lic()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_tracking_model_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_track_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_set_target_lic(
+        mv_image_object_h image_object,
+        mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Destroys the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model    The handle to the image tracking model
+ *                                     to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by using mv_image_tracking_model_create()
+ *
+ * @see mv_image_tracking_model_create_lic()
+ */
+int mv_image_tracking_model_destroy_lic(
+        mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Refreshes the state of image tracking model.
+ * @details Clears moving history and change state to undetected. This function
+ *          is usually called each time before tracking is started for the new
+ *          sequence of sources which is not the direct continuation of the
+ *          sequence for which tracking has been performed before. Tracking
+ *          algorithm will try to find image by itself.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model   The handle to the image tracking model
+ *                                    which will be refreshed
+ * @param [in] engine_cfg             The handle to the configuration of
+ *                                    engine which will be used. If NULL,
+ *                                    then default settings will be used.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ *      @ref mv_image_tracking_model_create_lic()
+ * @post Release image tracking model by using
+ *       @ref mv_image_tracking_model_destroy_lic()
+ *
+ * @see mv_image_tracking_model_h
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_track_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_refresh_lic(
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg);
+
+/**
+ * @brief Clones the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [in]  src    The handle to the source image tracking model
+ * @param [out] dst    The handle to the destination image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_clone_lic(
+        mv_image_tracking_model_h src,
+        mv_image_tracking_model_h *dst);
+
+/**
+ * @brief Saves the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is saved to the application's data directory.
+ * @param [in] file_name               Name of file to save the model
+ * @param [in] image_tracking_model    The handle to the image tracking model
+ *                                     to be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model handle by calling
+ *      mv_image_tracking_model_create()
+ * @post Saved model can be loaded later by calling
+ *       mv_image_tracking_model_load() function
+
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_tracking_model_load_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_save_lic(
+        const char *file_name, mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Loads an image tracking model from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is loaded from the application's data directory.
+ *          @a image_tracking_model must be destroyed using
+ *          @ref mv_image_tracking_model_destroy.
+ * @param [in]  file_name               Name of file to load model
+ * @param [out] image_tracking_model    The handle to the image tracking
+ *                                      model to be filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Image tracking model handle can be preliminary saved with
+ *      mv_image_tracking_model_save() function
+ *
+ * @see mv_image_tracking_model_save_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_load_lic(
+        const char *file_name, mv_image_tracking_model_h *image_tracking_model);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_IMAGE_LIC_H__ */
diff --git a/mv_image/image_lic/src/mv_image_lic.c b/mv_image/image_lic/src/mv_image_lic.c
new file mode 100644 (file)
index 0000000..356e563
--- /dev/null
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_image_lic.h"
+
+int mv_image_recognize_lic(
+        mv_source_h source,
+        const mv_image_object_h *image_objects,
+        int number_of_objects,
+        mv_engine_config_h engine_cfg,
+        mv_image_recognized_cb recognized_cb,
+        void *user_data)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_track_lic(
+        mv_source_h source,
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_image_tracked_cb tracked_cb,
+        void *user_data)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_create_lic(
+        mv_image_object_h *image_object)
+
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+
+int mv_image_object_destroy_lic(
+        mv_image_object_h image_object)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_fill_lic(
+        mv_image_object_h image_object,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_rectangle_s *location)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_get_recognition_rate_lic(
+        mv_image_object_h image_object,
+        double *recognition_rate)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_set_label_lic(
+        mv_image_object_h image_object,
+        int label)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_get_label_lic(
+        mv_image_object_h image_object,
+        int *label)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_clone_lic(
+        mv_image_object_h src,
+        mv_image_object_h *dst)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_save_lic(
+        mv_image_object_h image_object,
+        const char *file_name)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_load_lic(
+        mv_image_object_h image_object,
+        const char *file_name)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_create_lic(
+        mv_image_tracking_model_h *image_tracking_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_set_target_lic(
+        mv_image_object_h image_object,
+        mv_image_tracking_model_h image_tracking_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_destroy_lic(
+        mv_image_tracking_model_h image_tracking_model)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_refresh_lic(
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_clone_lic(
+        mv_image_tracking_model_h src,
+        mv_image_tracking_model_h *dst)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_save_lic(
+        mv_image_tracking_model_h image_tracking_model,
+        const char *file_name)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_load_lic(
+        mv_image_tracking_model_h image_tracking_model,
+        const char *file_name)
+{
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec
new file mode 100644 (file)
index 0000000..a786d8e
--- /dev/null
@@ -0,0 +1,82 @@
+Name:        capi-media-vision
+Summary:     Media Vision library for Tizen Native API
+Version:     0.2.1
+Release:     0
+Group:       Multimedia/Framework
+License:     Apache-2.0 and BSD-2.0
+Source0:     %{name}-%{version}.tar.gz
+BuildRequires: cmake
+BuildRequires: pkgconfig(capi-media-tool)
+BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(opencv)
+BuildRequires: pkgconfig(zbar)
+BuildRequires: pkgconfig(glib-2.0)
+# Change to the pkgconfig(zint) after zint package refactor
+BuildRequires: zint
+BuildRequires: zint-devel
+BuildRequires: libjson
+BuildRequires: libjson-devel
+BuildRequires: dlogutil
+BuildRequires: libjpeg-turbo
+BuildRequires: libjpeg-turbo-devel
+BuildRequires: pkgconfig(libavcodec)
+BuildRequires: pkgconfig(libavformat)
+BuildRequires: pkgconfig(libswscale)
+BuildRequires: libavutil-devel
+BuildRequires: pkgconfig(gstreamer-1.0)
+BuildRequires: pkgconfig(gstreamer-base-1.0)
+BuildRequires: pkgconfig(gstreamer-app-1.0)
+
+%description
+Media Vision library for Tizen Native API. Includes barcode detecting, barcode generating, face and image modules.
+
+%package devel
+Summary:    Multimedia Vision Library (DEV)
+Group:      Multimedia/Framework
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+Media Vision library for Tizen Native API (DEV). Includes barcode detecting, barcode generating, face and image modules.
+
+%prep
+%setup -q
+
+%build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license/
+mkdir -p %{buildroot}/usr/share/config/%{name}
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
+cp media-vision-config.json %{buildroot}/usr/share/config/%{name}/
+
+%make_install
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+%files
+%manifest capi-media-vision.manifest
+%{_datadir}/license/%{name}
+%{_datadir}/config/%{name}/media-vision-config.json
+%{_libdir}/libcapi-media-vision.so.*
+%{_libdir}/libmv*.so
+
+%files devel
+#%{_datadir}/config/%{name}/media-vision-config.json
+%{_includedir}/media/*.h
+%{_libdir}/pkgconfig/*.pc
+%{_libdir}/lib%{name}.so
+/opt/usr/devel/media/testsuites/*
diff --git a/src/mv_barcode.c b/src/mv_barcode.c
new file mode 100644 (file)
index 0000000..5d323fe
--- /dev/null
@@ -0,0 +1,252 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <system_info.h>
+
+#include "mv_private.h"
+#include "mv_barcode_detect.h"
+#include "mv_barcode_generate.h"
+
+#ifdef MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT
+
+/* Include headers of licensed barcode detect module here. */
+#include "mv_barcode_detect_lic.h"
+
+#else
+
+/* Include headers of open barcode detect module here. */
+#include "mv_barcode_detect_open.h"
+
+#endif /* MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT */
+
+#ifdef MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT
+
+/* Include headers of licensed barcode generate module here. */
+#include "mv_barcode_generate_lic.h"
+
+#else
+
+/* Include headers of open barcode generate module here. */
+#include "mv_barcode_generate_open.h"
+
+#endif /* MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT */
+
+/**
+ * @file  mv_barcode.c
+ * @brief This file contains the porting layer for Media Vision barcode module.
+ */
+
+int mv_barcode_detect(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s roi,
+        mv_barcode_detected_cb detect_cb,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_barcode_detect_check_system_info_feature_supported());
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(detect_cb);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+    unsigned int src_w = 0;
+    unsigned int src_h = 0;
+
+    ret = mv_source_get_width(source, &src_w);
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("mv_source_get_width fail");
+        return ret;
+    }
+
+    ret = mv_source_get_height(source, &src_h);
+    if (ret != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("mv_source_get_height fail");
+        return ret;
+    }
+
+    if (roi.point.x < 0 || roi.point.y < 0 ||
+       (roi.point.x + roi.width) > src_w ||
+       (roi.point.y + roi.height) > src_h)
+    {
+       LOGE("roi is out of area on source");
+       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+#ifdef MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT
+
+    /* Use licensed barcode detect functionality here. */
+    ret = mv_barcode_detect_lic(
+                  source, engine_cfg, roi, detect_cb, user_data);
+
+#else
+
+    /* Use open barcode detect functionality here. */
+    ret = mv_barcode_detect_open(
+                  source, engine_cfg, roi, detect_cb, user_data);
+
+#endif /* MEDIA_VISION_BARCODE_DETECTOR_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_barcode_generate_source(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        mv_source_h image)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_barcode_generate_check_system_info_feature_supported());
+    MEDIA_VISION_NULL_ARG_CHECK(message);
+    MEDIA_VISION_INSTANCE_CHECK(image);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (type < MV_BARCODE_QR ||
+        type >= MV_BARCODE_UNDEFINED)
+    {
+        LOGE("Not supported barcode type [%d]", type);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (type == MV_BARCODE_QR)
+    {
+        if (qr_enc_mode < MV_BARCODE_QR_MODE_NUMERIC ||
+            qr_enc_mode >= MV_BARCODE_QR_MODE_UNAVAILABLE)
+        {
+            LOGE("Not supported QR encoding mode[%d]", qr_enc_mode);
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        }
+
+        if (qr_ecc < MV_BARCODE_QR_ECC_LOW ||
+            qr_ecc >= MV_BARCODE_QR_ECC_UNAVAILABLE)
+        {
+            LOGE("Not supported QR ECC level [%d]", qr_ecc);
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        }
+
+        if (qr_version < 1 || qr_version > 40)
+        {
+            LOGE("Not supported QR version [%d]", qr_version);
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+#ifdef MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT
+
+    /* Use licensed barcode generate functionality here. */
+    int ret = mv_barcode_generate_source_lic(
+                  engine_cfg, message, type, qr_enc_mode, qr_ecc, qr_version,
+                  image);
+
+#else
+
+    /* Use open barcode generate functionality here. */
+    int ret = mv_barcode_generate_source_open(
+                  engine_cfg, message, type, qr_enc_mode, qr_ecc, qr_version,
+                  image);
+
+#endif /* MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_barcode_generate_image(
+        mv_engine_config_h engine_cfg,
+        const char *message,
+        int image_width,
+        int image_height,
+        mv_barcode_type_e type,
+        mv_barcode_qr_mode_e qr_enc_mode,
+        mv_barcode_qr_ecc_e qr_ecc,
+        int qr_version,
+        const char *image_path,
+        mv_barcode_image_format_e image_format)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_barcode_generate_check_system_info_feature_supported());
+    MEDIA_VISION_NULL_ARG_CHECK(message);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (image_path == NULL)
+    {
+         LOGE("image_path is NULL\n");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    if (type < MV_BARCODE_QR ||
+        type >= MV_BARCODE_UNDEFINED)
+    {
+        LOGE("Not supported barcode type [%d]", type);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (type == MV_BARCODE_QR)
+    {
+        if (qr_enc_mode < MV_BARCODE_QR_MODE_NUMERIC ||
+            qr_enc_mode >= MV_BARCODE_QR_MODE_UNAVAILABLE)
+        {
+            LOGE("Not supported QR encoding mode[%d]", qr_enc_mode);
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        }
+
+        if (qr_ecc < MV_BARCODE_QR_ECC_LOW ||
+            qr_ecc >= MV_BARCODE_QR_ECC_UNAVAILABLE)
+        {
+            LOGE("Not supported QR ECC level [%d]", qr_ecc);
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        }
+
+        if (qr_version < 1 || qr_version > 40)
+        {
+            LOGE("Not supported QR version [%d]", qr_version);
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (image_format < MV_BARCODE_IMAGE_FORMAT_BMP ||
+        image_format >= MV_BARCODE_IMAGE_FORMAT_NUM)
+    {
+        LOGE("Not supported image format [%d]", image_format);
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+#ifdef MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT
+
+    /* Use licensed barcode generate functionality here. */
+    int ret = mv_barcode_generate_image_lic(
+                  engine_cfg, message, image_width, image_height, type,
+                  qr_enc_mode, qr_ecc, qr_version, image_path, image_format);
+
+#else
+
+    /* Use open barcode generate functionality here. */
+    int ret = mv_barcode_generate_image_open(
+                  engine_cfg, message, image_width, image_height, type,
+                  qr_enc_mode, qr_ecc, qr_version, image_path, image_format);
+
+#endif /* MEDIA_VISION_BARCODE_GENERATOR_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
diff --git a/src/mv_common.c b/src/mv_common.c
new file mode 100644 (file)
index 0000000..d11ca6b
--- /dev/null
@@ -0,0 +1,338 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_private.h"
+#include "mv_common.h"
+#include "mv_common_c.h"
+
+int mv_create_source(
+        mv_source_h *source)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(source);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_create_source_c(source);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_destroy_source(
+        mv_source_h source)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_destroy_source_c(source);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_source_fill_by_media_packet(
+        mv_source_h source,
+        media_packet_h media_packet)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_INSTANCE_CHECK(media_packet);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_source_fill_by_media_packet_c(source, media_packet);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_source_fill_by_buffer(
+        mv_source_h source,
+        unsigned char *data_buffer,
+        unsigned int buffer_size,
+        unsigned int image_width,
+        unsigned int image_height,
+        mv_colorspace_e image_colorspace)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(data_buffer);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_source_fill_by_buffer_c(
+        source, data_buffer, buffer_size, image_width, image_height,
+        image_colorspace);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_source_clear(
+        mv_source_h source)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_source_clear_c(source);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_source_get_buffer(
+        mv_source_h source,
+        unsigned char **data_buffer,
+        unsigned int *buffer_size)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(data_buffer);
+    MEDIA_VISION_NULL_ARG_CHECK(buffer_size);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_source_get_buffer_c(source, data_buffer, buffer_size);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_source_get_height(
+        mv_source_h source,
+        unsigned int *image_height)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(image_height);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_source_get_height_c(source, image_height);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_source_get_width(
+        mv_source_h source,
+        unsigned int *image_width)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(image_width);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_source_get_width_c(source, image_width);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_source_get_colorspace(
+        mv_source_h source,
+        mv_colorspace_e *image_colorspace)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(image_colorspace);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_source_get_colorspace_c(source, image_colorspace);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_create_engine_config(
+        mv_engine_config_h *engine_cfg)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(engine_cfg);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_create_engine_config_c(engine_cfg);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_destroy_engine_config(
+        mv_engine_config_h engine_cfg)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_destroy_engine_config_c(engine_cfg);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_set_double_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        double value)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+    MEDIA_VISION_NULL_ARG_CHECK(name);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_engine_config_set_double_attribute_c(
+                  engine_cfg, name, value);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_set_int_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        int value)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+    MEDIA_VISION_NULL_ARG_CHECK(name);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_engine_config_set_int_attribute_c(
+                  engine_cfg, name, value);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_set_bool_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        bool value)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+    MEDIA_VISION_NULL_ARG_CHECK(name);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_engine_config_set_bool_attribute_c(
+                  engine_cfg, name, value);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_set_string_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        const char *value)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+    MEDIA_VISION_NULL_ARG_CHECK(name);
+    MEDIA_VISION_NULL_ARG_CHECK(value);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_engine_config_set_string_attribute_c(
+                  engine_cfg, name, value);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_get_double_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        double *value)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+    MEDIA_VISION_NULL_ARG_CHECK(name);
+    MEDIA_VISION_NULL_ARG_CHECK(value);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_engine_config_get_double_attribute_c(
+                  engine_cfg, name, value);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_get_int_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        int *value)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+    MEDIA_VISION_NULL_ARG_CHECK(name);
+    MEDIA_VISION_NULL_ARG_CHECK(value);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_engine_config_get_int_attribute_c(
+        engine_cfg, name, value);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_get_bool_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        bool *value)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+    MEDIA_VISION_NULL_ARG_CHECK(name);
+    MEDIA_VISION_NULL_ARG_CHECK(value);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_engine_config_get_bool_attribute_c(
+                  engine_cfg, name, value);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_get_string_attribute(
+        mv_engine_config_h engine_cfg,
+        const char *name,
+        char **value)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(engine_cfg);
+    MEDIA_VISION_NULL_ARG_CHECK(name);
+    MEDIA_VISION_NULL_ARG_CHECK(value);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret = mv_engine_config_get_string_attribute_c(
+                  engine_cfg, name, value);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int mv_engine_config_foreach_supported_attribute(
+        mv_supported_attribute_cb callback,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(callback);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+    int ret =
+            mv_engine_config_foreach_supported_attribute_c(callback, user_data);
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
diff --git a/src/mv_face.c b/src/mv_face.c
new file mode 100644 (file)
index 0000000..bf229a9
--- /dev/null
@@ -0,0 +1,762 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_private.h"
+#include "mv_face.h"
+
+#ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+/* Include headers of licensed face module here. */
+#include "mv_face_lic.h"
+
+#else
+
+/* Include headers of open face module here. */
+#include "mv_face_open.h"
+
+#endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+/**
+ * @file  mv_face.c
+ * @brief This file contains the porting layer for Media Vision face module.
+ */
+
+static const int check_source_roi_quadrangle(mv_quadrangle_s *roi, mv_source_h source)
+{
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    if (roi)
+    {
+        int src_w = 0;
+        int src_h = 0;
+
+        ret = mv_source_get_width(source, &src_w);
+        if (ret != MEDIA_VISION_ERROR_NONE)
+        {
+            LOGE("mv_source_get_width fail");
+            return ret;
+        }
+
+        ret = mv_source_get_height(source, &src_h);
+        if (ret != MEDIA_VISION_ERROR_NONE)
+        {
+            LOGE("mv_source_get_height fail");
+            return ret;
+        }
+
+        int idx = 0;
+        while (idx < 4)
+        {
+            if (roi->points[idx].x < 0 || roi->points[idx].y < 0 ||
+                roi->points[idx].x > src_w || roi->points[idx].y > src_h)
+            {
+               LOGE("roi is out of area on source");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+            }
+            ++idx;
+        }
+    }
+
+    return ret;
+}
+
+static const int check_source_roi(mv_rectangle_s *roi, mv_source_h source)
+{
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    if (roi)
+    {
+        int src_w = 0;
+        int src_h = 0;
+
+        ret = mv_source_get_width(source, &src_w);
+        if (ret != MEDIA_VISION_ERROR_NONE)
+        {
+            LOGE("mv_source_get_width fail");
+            return ret;
+        }
+
+        ret = mv_source_get_height(source, &src_h);
+        if (ret != MEDIA_VISION_ERROR_NONE)
+        {
+            LOGE("mv_source_get_height fail");
+            return ret;
+        }
+
+        if (roi->width <= 0 || roi->height <= 0)
+        {
+            LOGE("roi has negative width or height");
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        }
+
+        if (roi->point.x < 0 || roi->point.y < 0 ||
+           (roi->point.x + roi->width) > src_w ||
+           (roi->point.y + roi->height) > src_h)
+        {
+           LOGE("roi is out of area on source");
+           return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return ret;
+}
+
+int mv_face_detect(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_face_detected_cb detected_cb,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(detected_cb);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_detect_lic(source, engine_cfg, detected_cb, user_data);
+
+    #else
+
+    ret = mv_face_detect_open(source, engine_cfg, detected_cb, user_data);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognize(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        mv_face_recognized_cb recognized_cb,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_INSTANCE_CHECK(recognition_model);
+    MEDIA_VISION_NULL_ARG_CHECK(recognized_cb);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = check_source_roi(face_location, source);
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Errors occured when check source and ROI");
+        return ret;
+    }
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognize_lic(
+                  source,
+                  recognition_model,
+                  engine_cfg,
+                  face_location,
+                  recognized_cb,
+                  user_data);
+
+    #else
+
+    ret = mv_face_recognize_open(
+                  source,
+                  recognition_model,
+                  engine_cfg,
+                  face_location,
+                  recognized_cb,
+                  user_data);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_track(
+        mv_source_h source,
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_face_tracked_cb tracked_cb,
+        bool do_learn,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_INSTANCE_CHECK(tracking_model);
+    MEDIA_VISION_NULL_ARG_CHECK(tracked_cb);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_track_lic(
+            source,
+            tracking_model,
+            engine_cfg,
+            tracked_cb,
+            do_learn,
+            user_data);
+
+    #else
+
+    ret = mv_face_track_open(
+            source,
+            tracking_model,
+            engine_cfg,
+            tracked_cb,
+            do_learn,
+            user_data);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_eye_condition_recognize(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_eye_condition_recognized_cb eye_condition_recognized_cb,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(eye_condition_recognized_cb);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_eye_condition_recognize_lic(
+              source,
+              engine_cfg,
+              face_location,
+              eye_condition_recognized_cb,
+              user_data);
+
+    #else
+
+    ret = mv_face_eye_condition_recognize_open(
+              source,
+              engine_cfg,
+              face_location,
+              eye_condition_recognized_cb,
+              user_data);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_facial_expression_recognize(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_facial_expression_recognized_cb expression_recognized_cb,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(expression_recognized_cb);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = check_source_roi(&face_location, source);
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Errors occurred when check source and ROI");
+        return ret;
+    }
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_facial_expression_recognize_lic(
+                  source,
+                  engine_cfg,
+                  face_location,
+                  expression_recognized_cb,
+                  user_data);
+
+    #else
+
+    ret = mv_face_facial_expression_recognize_open(
+                  source,
+                  engine_cfg,
+                  face_location,
+                  expression_recognized_cb,
+                  user_data);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_create(
+        mv_face_recognition_model_h *recognition_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(recognition_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_create_lic(recognition_model);
+
+    #else
+
+    ret = mv_face_recognition_model_create_open(recognition_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_destroy(
+        mv_face_recognition_model_h recognition_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(recognition_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_destroy_lic(recognition_model);
+
+    #else
+
+    ret = mv_face_recognition_model_destroy_open(recognition_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_clone(
+        mv_face_recognition_model_h src,
+        mv_face_recognition_model_h *dst)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(src);
+    MEDIA_VISION_NULL_ARG_CHECK(dst);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_clone_lic(src, dst);
+
+    #else
+
+    ret = mv_face_recognition_model_clone_open(src, dst);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_save(
+        const char *file_name,
+        mv_face_recognition_model_h recognition_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(recognition_model);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_save_lic(
+                  file_name,
+                  recognition_model);
+
+    #else
+
+    ret = mv_face_recognition_model_save_open(
+                  file_name,
+                  recognition_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_load(
+        const char *file_name,
+        mv_face_recognition_model_h *recognition_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(recognition_model);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_load_lic(
+                  file_name,
+                  recognition_model);
+
+    #else
+
+    ret = mv_face_recognition_model_load_open(
+                  file_name,
+                  recognition_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_add(
+        const mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        const mv_rectangle_s *example_location,
+        int face_label)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_INSTANCE_CHECK(recognition_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = check_source_roi(example_location, source);
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Errors occured when check source and ROI");
+        return ret;
+    }
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_add_lic(
+                  source,
+                  recognition_model,
+                  example_location,
+                  face_label);
+    #else
+
+    ret = mv_face_recognition_model_add_open(
+                  source,
+                  recognition_model,
+                  example_location,
+                  face_label);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_reset(
+        mv_face_recognition_model_h recognition_model,
+        int *face_label)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(recognition_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_reset_lic(
+                  recognition_model,
+                  face_label);
+
+    #else
+
+    ret = mv_face_recognition_model_reset_open(
+                  recognition_model,
+                  face_label);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_learn(
+        mv_engine_config_h engine_cfg,
+        mv_face_recognition_model_h recognition_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(recognition_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_learn_lic(engine_cfg, recognition_model);
+
+    #else
+
+    ret = mv_face_recognition_model_learn_open(engine_cfg, recognition_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_recognition_model_query_labels(
+        mv_face_recognition_model_h recognition_model,
+        int **labels,
+        unsigned int *number_of_labels)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(recognition_model);
+    MEDIA_VISION_NULL_ARG_CHECK(labels);
+    MEDIA_VISION_NULL_ARG_CHECK(number_of_labels);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_recognition_model_query_labels_lic(recognition_model, labels, number_of_labels);
+
+    #else
+
+    ret = mv_face_recognition_model_query_labels_open(recognition_model, labels, number_of_labels);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_tracking_model_create(
+        mv_face_tracking_model_h *tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(tracking_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_tracking_model_create_lic(tracking_model);
+
+    #else
+
+    ret = mv_face_tracking_model_create_open(tracking_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_tracking_model_destroy(
+        mv_face_tracking_model_h tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(tracking_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_tracking_model_destroy_lic(tracking_model);
+
+    #else
+
+    ret = mv_face_tracking_model_destroy_open(tracking_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_tracking_model_prepare(
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_quadrangle_s *location)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(tracking_model);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = check_source_roi_quadrangle(location, source);
+    if (MEDIA_VISION_ERROR_NONE != ret)
+    {
+        LOGE("Errors occured when check source and tracking start location");
+        return ret;
+    }
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_tracking_model_prepare_lic(
+              tracking_model, engine_cfg, source, location);
+
+    #else
+
+    ret = mv_face_tracking_model_prepare_open(
+              tracking_model, engine_cfg, source, location);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_tracking_model_clone(
+        mv_face_tracking_model_h src,
+        mv_face_tracking_model_h *dst)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(src);
+    MEDIA_VISION_NULL_ARG_CHECK(dst);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_tracking_model_clone_lic(src, dst);
+
+    #else
+
+    ret = mv_face_tracking_model_clone_open(src, dst);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_tracking_model_save(
+        const char *file_name,
+        mv_face_tracking_model_h tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(tracking_model);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_tracking_model_save_lic(
+              file_name,
+              tracking_model);
+
+    #else
+
+    ret = mv_face_tracking_model_save_open(
+              file_name,
+              tracking_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_face_tracking_model_load(
+        const char *file_name,
+        mv_face_tracking_model_h *tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_face_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(tracking_model);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specifiled");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int ret = MEDIA_VISION_ERROR_NONE;
+
+    #ifdef MEDIA_VISION_FACE_LICENSE_PORT
+
+    ret = mv_face_tracking_model_load_lic(
+              file_name,
+              tracking_model);
+
+    #else
+
+    ret = mv_face_tracking_model_load_open(
+              file_name,
+              tracking_model);
+
+    #endif /* MEDIA_VISION_FACE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
diff --git a/src/mv_image.c b/src/mv_image.c
new file mode 100644 (file)
index 0000000..f041924
--- /dev/null
@@ -0,0 +1,529 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_private.h"
+#include "mv_image.h"
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+/* Include headers of licensed image module here. */
+#include "mv_image_lic.h"
+
+#else
+
+/* Include headers of open image module here. */
+#include "mv_image_open.h"
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+/**
+ * @file  mv_image.c
+ * @brief This file contains the porting layer for Media Vision image module.
+ */
+
+int mv_image_recognize(
+        mv_source_h source,
+        const mv_image_object_h *image_objects,
+        int number_of_objects,
+        mv_engine_config_h engine_cfg,
+        mv_image_recognized_cb recognized_cb,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_NULL_ARG_CHECK(image_objects);
+    int object_num = 0;
+    for (; object_num < number_of_objects; ++object_num)
+    {
+        MEDIA_VISION_INSTANCE_CHECK(image_objects[object_num]);
+    }
+    MEDIA_VISION_NULL_ARG_CHECK(recognized_cb);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_recognize_lic(source, image_objects,
+            number_of_objects, engine_cfg, recognized_cb, user_data);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_recognize_open(source, image_objects,
+            number_of_objects, engine_cfg, recognized_cb, user_data);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_track(
+        mv_source_h source,
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_image_tracked_cb tracked_cb,
+        void *user_data)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+    MEDIA_VISION_NULL_ARG_CHECK(tracked_cb);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_track_lic(source, image_tracking_model, engine_cfg, tracked_cb, user_data);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_track_open(source, image_tracking_model, engine_cfg, tracked_cb, user_data);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_create(
+        mv_image_object_h *image_object)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(image_object);
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_create_lic(image_object);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_create_open(image_object);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_destroy(
+        mv_image_object_h image_object)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_destroy_lic(image_object);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_destroy_open(image_object);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_fill(
+        mv_image_object_h image_object,
+        mv_engine_config_h engine_cfg,
+        mv_source_h source,
+        mv_rectangle_s *location)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+    MEDIA_VISION_INSTANCE_CHECK(source);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_fill_lic(image_object, engine_cfg, source, location);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_fill_open(image_object, engine_cfg, source, location);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_get_recognition_rate(
+        mv_image_object_h image_object,
+        double *recognition_rate)
+{
+       MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+    MEDIA_VISION_NULL_ARG_CHECK(recognition_rate);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_get_recognition_rate_lic(image_object, recognition_rate);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_get_recognition_rate_open(image_object, recognition_rate);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_set_label(
+        mv_image_object_h image_object,
+        int label)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_set_label_lic(image_object, label);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_set_label_open(image_object, label);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_get_label(
+        mv_image_object_h image_object,
+        int *label)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+    MEDIA_VISION_NULL_ARG_CHECK(label);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_get_label_lic(image_object, label);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_get_label_open(image_object, label);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_clone(
+        mv_image_object_h src,
+        mv_image_object_h *dst)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(src);
+    MEDIA_VISION_NULL_ARG_CHECK(dst);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_clone_lic(src, dst);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_clone_open(src, dst);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_save(
+        const char *file_name, mv_image_object_h image_object)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_save_lic(file_name, image_object);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_save_open(file_name, image_object);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_object_load(
+        const char *file_name, mv_image_object_h *image_object)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(image_object);
+
+    if (file_name == NULL)
+    {
+         LOGE("file name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_object_load_lic(file_name, image_object);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_object_load_open(file_name, image_object);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_tracking_model_create(
+        mv_image_tracking_model_h *image_tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(image_tracking_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_tracking_model_create_lic(image_tracking_model);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_tracking_model_create_open(image_tracking_model);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_tracking_model_set_target(
+        mv_image_object_h image_object,
+        mv_image_tracking_model_h image_tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+    MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_tracking_model_set_target_lic(image_object, image_tracking_model);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_tracking_model_set_target_open(image_object, image_tracking_model);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_tracking_model_destroy(
+        mv_image_tracking_model_h image_tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_tracking_model_destroy_lic(image_tracking_model);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_tracking_model_destroy_open(image_tracking_model);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_tracking_model_refresh(
+        mv_image_tracking_model_h image_tracking_model,
+        mv_engine_config_h engine_cfg)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_tracking_model_refresh_lic(
+                  image_tracking_model,
+                  engine_cfg);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_tracking_model_refresh_open(
+                  image_tracking_model,
+                  engine_cfg);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_tracking_model_clone(
+        mv_image_tracking_model_h src,
+        mv_image_tracking_model_h *dst)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(src);
+    MEDIA_VISION_NULL_ARG_CHECK(dst);
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_tracking_model_clone_lic(src, dst);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_tracking_model_clone_open(src, dst);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_tracking_model_save(
+        const char *file_name, mv_image_tracking_model_h image_tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_tracking_model_save_lic(file_name, image_tracking_model);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_tracking_model_save_open(file_name, image_tracking_model);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
+
+int mv_image_tracking_model_load(
+        const char *file_name, mv_image_tracking_model_h *image_tracking_model)
+{
+    MEDIA_VISION_SUPPORT_CHECK(__mv_image_check_system_info_feature_supported);
+    MEDIA_VISION_NULL_ARG_CHECK(image_tracking_model);
+
+    if (file_name == NULL)
+    {
+         LOGE("File name is NULL. The file name has to be specified");
+         return MEDIA_VISION_ERROR_INVALID_PATH;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+#ifdef MEDIA_VISION_IMAGE_LICENSE_PORT
+
+    /* Use licensed image functionality here. */
+    int ret = mv_image_tracking_model_load_lic(file_name, image_tracking_model);
+
+#else
+
+    /* Use open image functionality here. */
+    int ret = mv_image_tracking_model_load_open(file_name, image_tracking_model);
+
+#endif /* MEDIA_VISION_IMAGE_LICENSE_PORT */
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return ret;
+}
diff --git a/src/mv_private.c b/src/mv_private.c
new file mode 100644 (file)
index 0000000..af4e7df
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <system_info.h>
+
+#include "mv_private.h"
+
+bool __mv_check_system_info_feature_supported()
+{
+    // return true is temporary added to allow correct flow for UTC
+    // todo: remove when vision.barcode_detection and vision.barcode_generation
+    // will be added
+    return true;
+
+    bool isBarcodeDetectionSupported = false;
+    bool isBarcodeGenerationSupported = false;
+    bool isFaceRecognitionSupported = false;
+    bool isImageRecognitionSupported = false;
+
+    const int nRetVal1 = system_info_get_platform_bool("http://tizen.org/feature/vision.barcode_detection", &isBarcodeDetectionSupported);
+
+    if (nRetVal1 != SYSTEM_INFO_ERROR_NONE)
+    {
+        LOGE("[%s] SYSTEM_INFO_ERROR: __FUNCTION__");
+        return false;
+    }
+
+    const int nRetVal2 = system_info_get_platform_bool("http://tizen.org/feature/vision.barcode_generation", &isBarcodeGenerationSupported);
+
+    if (nRetVal2 != SYSTEM_INFO_ERROR_NONE)
+    {
+        LOGE("[%s] SYSTEM_INFO_ERROR: __FUNCTION__");
+        return false;
+    }
+
+    const int nRetVal3 = system_info_get_platform_bool("http://tizen.org/feature/vision.face_recognition", &isFaceRecognitionSupported);
+
+    if (nRetVal3 != SYSTEM_INFO_ERROR_NONE)
+    {
+        LOGE("[%s] SYSTEM_INFO_ERROR: __FUNCTION__");
+        return false;
+    }
+
+    const int nRetVal4 = system_info_get_platform_bool("http://tizen.org/feature/vision.image_recognition", &isImageRecognitionSupported);
+
+    if (nRetVal2 != SYSTEM_INFO_ERROR_NONE)
+    {
+        LOGE("[%s] SYSTEM_INFO_ERROR: __FUNCTION__");
+        return false;
+    }
+    (isBarcodeDetectionSupported || isBarcodeGenerationSupported ||
+        isFaceRecognitionSupported  || isImageRecognitionSupported) ?
+            LOGI("system_info_get_platform_bool returned"
+                 "Supported one feature among barcode detection, "
+                 "barcode generation, face recognition, "
+                 "and image recognition capability\n") :
+            LOGE("system_info_get_platform_bool returned"
+                 "Unsupported all features of barcode detection, "
+                 "barcode generation, face recognition, "
+                 "and image recognition capability\n") ;
+
+    return (isBarcodeDetectionSupported || isBarcodeGenerationSupported ||
+            isFaceRecognitionSupported  || isImageRecognitionSupported);
+}
+
+bool __mv_barcode_detect_check_system_info_feature_supported()
+{
+    // return true is temporary added to allow correct flow for UTC
+    // todo: remove when vision.barcode_detection feature will be added
+    return true;
+
+    bool isBarcodeDetectionSupported = false;
+
+    const int nRetVal = system_info_get_platform_bool("http://tizen.org/feature/vision.barcode_detection", &isBarcodeDetectionSupported);
+
+    if (nRetVal != SYSTEM_INFO_ERROR_NONE)
+    {
+        LOGE("[%s] SYSTEM_INFO_ERROR: __FUNCTION__");
+        return false;
+    }
+
+    isBarcodeDetectionSupported ?
+            LOGI("system_info_get_platform_bool returned "
+                 "Supported barcode detection feature capability\n") :
+            LOGE("system_info_get_platform_bool returned "
+                 "Unsupported barcode detection feature capability\n");
+
+    return isBarcodeDetectionSupported;
+}
+
+bool __mv_barcode_generate_check_system_info_feature_supported()
+{
+    // return true is temporary added to allow correct flow for UTC
+    // todo: remove when vision.barcode_generation feature will be added
+    return true;
+
+    bool isBarcodeGenerationSupported = false;
+
+    const int nRetVal = system_info_get_platform_bool("http://tizen.org/feature/vision.barcode_generation", &isBarcodeGenerationSupported);
+
+    if (nRetVal != SYSTEM_INFO_ERROR_NONE)
+    {
+        LOGE("[%s] SYSTEM_INFO_ERROR: __FUNCTION__");
+        return false;
+    }
+
+    isBarcodeGenerationSupported ?
+            LOGI("system_info_get_platform_bool returned "
+                 "Supported barcode generation feature capability\n") :
+            LOGE("system_info_get_platform_bool returned "
+                 "Unsupported barcode generation feature capability\n");
+
+    return isBarcodeGenerationSupported;
+}
+
+bool __mv_face_check_system_info_feature_supported()
+{
+       // return true is temporary added to allow correct flow for UTC
+       // todo: remove when vision.face_recognition feature will be added
+       return true;
+
+       bool isFaceRecognitionSupported = false;
+
+       const int nRetVal = system_info_get_platform_bool("http://tizen.org/feature/vision.face_recognition", &isFaceRecognitionSupported);
+
+       if (nRetVal != SYSTEM_INFO_ERROR_NONE) {
+               LOGE("[%s] SYSTEM_INFO_ERROR: __FUNCTION__");
+               return false;
+       }
+
+       isFaceRecognitionSupported ?
+                       LOGI("system_info_get_platform_bool returned "
+                                "Supported face recognition feature capability\n") :
+                       LOGE("system_info_get_platform_bool returned "
+                                "Unsupported face recognition feature capability\n");
+
+       return isFaceRecognitionSupported;
+}
+
+bool __mv_image_check_system_info_feature_supported()
+{
+       // return true is temporary added to allow correct flow for UTC
+       // todo: remove when vision.image_recognition feature will be added
+       return true;
+
+       bool isImageRecognitionSupported = false;
+
+       const int nRetVal = system_info_get_platform_bool("http://tizen.org/feature/vision.image_recognition", &isImageRecognitionSupported);
+
+       if (nRetVal != SYSTEM_INFO_ERROR_NONE) {
+               LOGE("[%s] SYSTEM_INFO_ERROR: __FUNCTION__");
+               return false;
+       }
+
+       isImageRecognitionSupported ?
+                       LOGI("system_info_get_platform_bool returned "
+                                "Supported image recognition feature capability\n") :
+                       LOGE("system_info_get_platform_bool returned "
+                                "Unsupported image recognition feature capability\n");
+
+       return isImageRecognitionSupported;
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b61a2b3
--- /dev/null
@@ -0,0 +1,5 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(testbin_dir /opt/usr/devel/media/)
+
+ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/test/testsuites)
diff --git a/test/testsuites/CMakeLists.txt b/test/testsuites/CMakeLists.txt
new file mode 100644 (file)
index 0000000..16a2eb6
--- /dev/null
@@ -0,0 +1,13 @@
+project(mv_testsuites)
+cmake_minimum_required(VERSION 2.6)
+
+set(testsuites_dir "${testbin_dir}/testsuites")
+
+SET(INC_IMAGE_HELPER "${PROJECT_SOURCE_DIR}/common/image_helper/include")
+SET(INC_VIDEO_HELPER "${PROJECT_SOURCE_DIR}/common/video_helper")
+SET(INC_TS_COMMON "${PROJECT_SOURCE_DIR}/common/testsuite_common")
+
+add_subdirectory(${PROJECT_SOURCE_DIR}/common)
+add_subdirectory(${PROJECT_SOURCE_DIR}/barcode)
+add_subdirectory(${PROJECT_SOURCE_DIR}/face)
+add_subdirectory(${PROJECT_SOURCE_DIR}/image)
diff --git a/test/testsuites/barcode/CMakeLists.txt b/test/testsuites/barcode/CMakeLists.txt
new file mode 100644 (file)
index 0000000..880da5e
--- /dev/null
@@ -0,0 +1,27 @@
+project(mv_barcode_test_suite)
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG    _DEBUG)
+
+if(NOT SKIP_WARNINGS)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories(${PROJECT_SOURCE_DIR})
+include_directories(${MV_CAPI_MEDIA_VISION_INC_DIR})
+include_directories(${INC_IMAGE_HELPER})
+
+file(GLOB MV_TEST_SUITE_INC_LIST "${PROJECT_SOURCE_DIR}/*.h")
+file(GLOB MV_TEST_SUITE_SRC_LIST "${PROJECT_SOURCE_DIR}/*.c")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
+
+add_executable(${PROJECT_NAME} ${MV_TEST_SUITE_SRC_LIST} ${MV_TEST_SUITE_INC_LIST} ${MV_CAPI_MEDIA_VISION_INC_LIST})
+
+target_link_libraries(${PROJECT_NAME} capi-media-vision dlog avcodec avformat avutil swscale mv_image_helper)
+
+install(TARGETS ${PROJECT_NAME} DESTINATION ${testsuites_dir})
diff --git a/test/testsuites/barcode/barcode_test_suite.c b/test/testsuites/barcode/barcode_test_suite.c
new file mode 100644 (file)
index 0000000..c9d2980
--- /dev/null
@@ -0,0 +1,1279 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mv_barcode.h>
+
+#include <image_helper.h>
+#include <mv_private.h>
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libswscale/swscale.h>
+#include <libavcodec/avcodec.h>
+#include <libavutil/pixfmt.h>
+
+typedef struct
+{
+    mv_barcode_type_e type;
+    mv_barcode_qr_ecc_e ecc;
+    mv_barcode_qr_mode_e mode;
+    int version;
+    size_t width;
+    size_t height;
+    mv_barcode_image_format_e out_image_format;
+    mv_colorspace_e colorspace;
+    char *message;
+    char *file_name;
+    char *out_file_name;
+    unsigned char *out_buffer_ptr;
+} barcode_model_s;
+
+typedef enum
+{
+    MV_TS_GENERATE_TO_IMAGE_FCN,
+    MV_TS_GENERATE_TO_SOURCE_FCN
+} generation_fcn_e;
+
+int convert_rgb_to(unsigned char *src_buffer, unsigned char **dst_buffer,
+        image_data_s image_data, mv_colorspace_e dst_colorspace,
+        unsigned long *cvt_buffer_size)
+{
+    enum PixelFormat pixel_format = PIX_FMT_NONE;
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    switch (dst_colorspace)
+    {
+        case MEDIA_VISION_COLORSPACE_Y800:
+            pixel_format = PIX_FMT_GRAY8;
+            break;
+        case MEDIA_VISION_COLORSPACE_I420:
+            pixel_format = PIX_FMT_YUV420P;
+            break;
+        case MEDIA_VISION_COLORSPACE_NV12:
+            pixel_format = PIX_FMT_NV12;
+            break;
+        case MEDIA_VISION_COLORSPACE_YV12:
+            pixel_format = PIX_FMT_YUV420P; // the same as I420 with inversed U and V
+            break;
+        case MEDIA_VISION_COLORSPACE_NV21:
+            pixel_format = PIX_FMT_NV21;
+            break;
+        case MEDIA_VISION_COLORSPACE_YUYV:
+            pixel_format = PIX_FMT_YUYV422;
+            break;
+        case MEDIA_VISION_COLORSPACE_UYVY:
+            pixel_format = PIX_FMT_UYVY422;
+            break;
+        case MEDIA_VISION_COLORSPACE_422P:
+            pixel_format = PIX_FMT_YUV422P;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB565:
+            pixel_format = PIX_FMT_RGB565BE;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGBA:
+            pixel_format = PIX_FMT_RGBA;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB888:
+            *cvt_buffer_size = image_data.image_width * image_data.image_height * 3;
+            (*dst_buffer) = (unsigned char*)malloc(*cvt_buffer_size);
+            memcpy(*dst_buffer, src_buffer, *cvt_buffer_size);
+
+            MEDIA_VISION_FUNCTION_LEAVE();
+            return MEDIA_VISION_ERROR_NONE;
+        default:
+            MEDIA_VISION_FUNCTION_LEAVE();
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+    }
+
+    AVPicture src_picture;
+    AVPicture dst_picture;
+
+    avpicture_fill(&src_picture, (uint8_t*)src_buffer, PIX_FMT_RGB24,
+            image_data.image_width, image_data.image_height);
+
+    avpicture_alloc(&dst_picture, pixel_format,
+            image_data.image_width, image_data.image_height);
+
+    struct SwsContext *context = sws_getContext(
+            image_data.image_width, image_data.image_height, PIX_FMT_RGB24,
+            image_data.image_width, image_data.image_height, pixel_format,
+            SWS_FAST_BILINEAR, 0, 0, 0);
+
+    sws_scale(context, (const uint8_t* const*)src_picture.data,
+            src_picture.linesize, 0, image_data.image_height,
+            dst_picture.data, dst_picture.linesize);
+
+    *cvt_buffer_size = avpicture_get_size(pixel_format,
+            image_data.image_width, image_data.image_height);
+    (*dst_buffer) = (unsigned char*)malloc(*cvt_buffer_size);
+    memcpy(*dst_buffer, dst_picture.data[0], *cvt_buffer_size);
+
+    avpicture_free(&dst_picture);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int find_min_x(const mv_quadrangle_s *quadrangle, int *minX)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (NULL == quadrangle)
+    {
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    *minX = quadrangle->points[0].x;
+    *minX = quadrangle->points[1].x < *minX ? quadrangle->points[1].x : *minX;
+    *minX = quadrangle->points[2].x < *minX ? quadrangle->points[2].x : *minX;
+    *minX = quadrangle->points[3].x < *minX ? quadrangle->points[3].x : *minX;
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int find_min_y(const mv_quadrangle_s *quadrangle, int *minY)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (NULL == quadrangle)
+    {
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    *minY = quadrangle->points[0].y;
+    *minY = quadrangle->points[1].y < *minY ? quadrangle->points[1].y : *minY;
+    *minY = quadrangle->points[2].y < *minY ? quadrangle->points[2].y : *minY;
+    *minY = quadrangle->points[3].y < *minY ? quadrangle->points[3].y : *minY;
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int find_max_x(const mv_quadrangle_s *quadrangle, int *maxX)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (NULL == quadrangle)
+    {
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    *maxX = quadrangle->points[0].x;
+    *maxX = quadrangle->points[1].x > *maxX ? quadrangle->points[1].x : *maxX;
+    *maxX = quadrangle->points[2].x > *maxX ? quadrangle->points[2].x : *maxX;
+    *maxX = quadrangle->points[3].x > *maxX ? quadrangle->points[3].x : *maxX;
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int find_max_y(const mv_quadrangle_s *quadrangle, int *maxY)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (NULL == quadrangle)
+    {
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    *maxY = quadrangle->points[0].y;
+    *maxY = quadrangle->points[1].y > *maxY ? quadrangle->points[1].y : *maxY;
+    *maxY = quadrangle->points[2].y > *maxY ? quadrangle->points[2].y : *maxY;
+    *maxY = quadrangle->points[3].y > *maxY ? quadrangle->points[3].y : *maxY;
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+bool _mv_engine_config_supported_attribute(mv_config_attribute_type_e attribute_type,
+        const char *attribute_name, void *user_data)
+{
+    printf("Callback call for engine configuration attribute\n");
+
+    if (user_data == NULL)
+    {
+        return false;
+    }
+
+    mv_engine_config_h mv_engine_config = (mv_engine_config_h *)user_data;
+
+    int int_value = 0;
+    double double_value = 0.0;
+    bool bool_value = false;
+    char str_value[1024];
+    switch (attribute_type)
+    {
+        case MV_ENGINE_CONFIG_ATTR_TYPE_DOUBLE:
+            if (MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE ==
+                    mv_engine_config_get_double_attribute(
+                        mv_engine_config, attribute_name, &double_value))
+            {
+                printf("Default double attribute %s wasn't set in engine\n",
+                    attribute_name);
+                return false;
+            }
+            printf("Default double attribute %s was set to %f in engine\n",
+                    attribute_name, double_value);
+            break;
+        case MV_ENGINE_CONFIG_ATTR_TYPE_INTEGER:
+            if (MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE ==
+                    mv_engine_config_get_int_attribute(
+                        mv_engine_config, attribute_name, &int_value))
+            {
+                printf("Default integer attribute %s wasn't set in engine\n",
+                    attribute_name);
+                return false;
+            }
+            printf("Default interget attribute %s was set to %d in engine\n",
+                    attribute_name, int_value);
+            break;
+        case MV_ENGINE_CONFIG_ATTR_TYPE_BOOLEAN:
+            if (MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE ==
+                    mv_engine_config_get_bool_attribute(
+                        mv_engine_config, attribute_name, &bool_value))
+            {
+                printf("Default bool attribute %s wasn't set in engine\n",
+                    attribute_name);
+                return false;
+            }
+            printf("Default bool attribute %s was set to %s in engine\n",
+                    attribute_name,  bool_value ? "TRUE" : "FALSE");
+            break;
+        case MV_ENGINE_CONFIG_ATTR_TYPE_STRING:
+            if (MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE ==
+                    mv_engine_config_get_string_attribute(
+                        mv_engine_config, attribute_name, &str_value))
+            {
+                printf("Default string ttribute %s wasn't set in engine\n",
+                    attribute_name);
+                return false;
+            }
+            printf("Default string attribute %s was set to %s in engine\n",
+                    attribute_name, str_value);
+            break;
+        default:
+            printf("Not supported attribute type\n");
+            return false;
+    }
+
+
+    return true;
+}
+
+void barcode_detected_cb(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        const mv_quadrangle_s *barcodes_locations,
+        const char *messages[],
+        const mv_barcode_type_e *types,
+        int number_of_barcodes,
+        void *user_data)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    printf("%i barcodes were detected on the image.\n", number_of_barcodes);
+    if (number_of_barcodes > 0)
+    {
+        int is_source_data_loaded = 0;
+
+        char *file_name = NULL;
+        unsigned char *out_buffer = NULL;
+        unsigned char *draw_buffer = NULL;
+        unsigned int buf_size = 0;
+        image_data_s image_data = { 0, 0, MEDIA_VISION_COLORSPACE_INVALID };
+        // Check Media Vision source:
+        if (MEDIA_VISION_ERROR_NONE != mv_source_get_buffer(source, &out_buffer, &buf_size) ||
+                MEDIA_VISION_ERROR_NONE != mv_source_get_width(source, &(image_data.image_width)) ||
+                MEDIA_VISION_ERROR_NONE != mv_source_get_height(source, &(image_data.image_height)) ||
+                MEDIA_VISION_ERROR_NONE != mv_source_get_colorspace(source, &(image_data.image_colorspace)) ||
+                user_data == NULL)
+        {
+            printf("ERROR: Creating out image is impossible.\n");
+        }
+        else
+        {
+            file_name = ((barcode_model_s *)user_data)->out_file_name;
+            draw_buffer = ((barcode_model_s *)user_data)->out_buffer_ptr;
+            image_data.image_colorspace = MEDIA_VISION_COLORSPACE_RGB888;
+            is_source_data_loaded = 1;
+        }
+
+        int i = 0;
+        for (i = 0; i < number_of_barcodes; ++i)
+        {
+            const char *cur_message = messages[i];
+            mv_barcode_type_e cur_type = types[i];
+            const char *str_type = NULL;
+            switch (cur_type)
+            {
+                case MV_BARCODE_QR:
+                    str_type = "QR";
+                    break;
+                case MV_BARCODE_UPC_A:
+                    str_type = "UPC-A";
+                    break;
+                case MV_BARCODE_UPC_E:
+                    str_type = "UPC-E";
+                    break;
+                case MV_BARCODE_EAN_8:
+                case MV_BARCODE_EAN_13:
+                    str_type = "EAN-8/13";
+                    break;
+                case MV_BARCODE_CODE128:
+                    str_type = "CODE128";
+                    break;
+                case MV_BARCODE_CODE39:
+                    str_type = "CODE39";
+                    break;
+                case MV_BARCODE_I2_5:
+                    str_type = "I25";
+                    break;
+                default:
+                    str_type = "Undetected";
+                    break;
+            }
+            printf("\tBarcode %i : type is %s\n", i, str_type);
+            if (cur_message != NULL)
+            {
+                printf("\t            message is %s\n", cur_message);
+            }
+            else
+            {
+                printf("\t            message wasn't detected\n");
+            }
+
+            if (is_source_data_loaded == 1)
+            {
+                int minX = 0;
+                int minY = 0;
+                int maxX = 0;
+                int maxY = 0;
+                if (MEDIA_VISION_ERROR_NONE != find_min_x(&barcodes_locations[i], &minX) ||
+                    MEDIA_VISION_ERROR_NONE != find_min_y(&barcodes_locations[i], &minY) ||
+                    MEDIA_VISION_ERROR_NONE != find_max_x(&barcodes_locations[i], &maxX) ||
+                    MEDIA_VISION_ERROR_NONE != find_max_y(&barcodes_locations[i], &maxY))
+                {
+                    continue;
+                }
+
+                const int rectangle_thickness = 6;
+                const int drawing_color[] = {255, 0, 0};
+                if (MEDIA_VISION_ERROR_NONE != draw_rectangle_on_buffer(
+                        minX,
+                        minY,
+                        maxX,
+                        maxY,
+                        drawing_color,
+                        rectangle_thickness,
+                        &image_data,
+                        draw_buffer))
+                {
+                    continue;
+                }
+            }
+        }
+
+        if (file_name != NULL &&
+                MEDIA_VISION_ERROR_NONE == save_image_from_buffer(file_name, draw_buffer, &image_data, 100))
+        {
+            printf("Image was generated as %s\n", file_name);
+        }
+        else
+        {
+            printf("ERROR: Failed to generate output file. Check file name and permissions. \n");
+        }
+
+        printf("\n");
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+}
+
+int generate_barcode_to_image(barcode_model_s model)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (model.message   == NULL ||
+        model.file_name == NULL)
+    {
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGI("Call the mv_barcode_generate_image() function");
+
+    const int err = mv_barcode_generate_image(
+                NULL,
+                model.message,
+                model.width,
+                model.height,
+                model.type,
+                model.mode,
+                model.ecc,
+                model.version,
+                model.file_name,
+                model.out_image_format);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int generate_barcode_to_source(barcode_model_s model)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (model.message   == NULL ||
+        model.file_name == NULL)
+    {
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    LOGI("mv_source_h creation started");
+
+    mv_source_h source = NULL;
+    int err = mv_create_source(&source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Error occurred when trying to create Media Vision "
+               "source. Error code: %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    LOGI("mv_source_h creation finished");
+
+    LOGI("Call the mv_barcode_generate_source() function");
+
+    err = mv_barcode_generate_source(
+            NULL,
+            model.message,
+            model.type,
+            model.mode,
+            model.ecc,
+            model.version,
+            source);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Error occurred during generation barcode to the "
+               "Media Vision source. Error code: %i\n", err);
+
+        const int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("ERROR: Error occurred when try to destroy Media Vision source."
+                   "Error code: %i\n", err2);
+        }
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    unsigned char *data_buffer = NULL;
+    unsigned int buffer_size = 0;
+    unsigned int image_width = 0;
+    unsigned int image_height = 0;
+    mv_colorspace_e image_colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+
+    bool is_source_corrupted = false;
+    err = mv_source_get_buffer(source, &data_buffer, &buffer_size);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Error occurred when trying to get buffer from "
+               "Media Vision source. Error code: %i\n", err);
+        is_source_corrupted = true;
+    }
+
+    err = mv_source_get_width(source, &image_width);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Error occurred when trying to get width of "
+               "Media Vision source. Error code: %i\n", err);
+        is_source_corrupted = true;
+    }
+
+    err = mv_source_get_height(source, &image_height);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Error occurred when trying to get height of "
+               "Media Vision source. Error code: %i\n", err);
+        is_source_corrupted = true;
+    }
+
+    err = mv_source_get_colorspace(source, &image_colorspace);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Error occurred when trying to get colorspace of "
+               "Media Vision source. Error code: %i\n", err);
+        is_source_corrupted = true;
+    }
+
+    if (is_source_corrupted)
+    {
+        err = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf("ERROR: Error occurred when trying to destroy Media Vision "
+                   "source. Error code: %i\n", err);
+        }
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return MEDIA_VISION_ERROR_INTERNAL;
+    }
+
+    const image_data_s image_data = { image_width, image_height, image_colorspace };
+
+    char *jpeg_file_name = "";
+    if (0 == strcmp(model.file_name + strlen(model.file_name) - 4, ".jpg") ||
+        0 == strcmp(model.file_name + strlen(model.file_name) - 5, ".jpeg"))
+    {
+        jpeg_file_name = (char*)malloc(strlen(model.file_name) + 1);
+        strcpy(jpeg_file_name, model.file_name);
+        jpeg_file_name[strlen(model.file_name)] = '\0';
+    }
+    else
+    {
+        jpeg_file_name = (char*)malloc(strlen(model.file_name) + 5);
+        strcpy(jpeg_file_name, model.file_name);
+        strcpy(jpeg_file_name + strlen(model.file_name), ".jpg");
+        jpeg_file_name[strlen(model.file_name) + 4] = '\0';
+    }
+
+    save_image_from_buffer(jpeg_file_name, data_buffer, &image_data, 100);
+
+    free(jpeg_file_name);
+
+    const int err2 = mv_destroy_source(source);
+    if (MEDIA_VISION_ERROR_NONE != err2)
+    {
+        printf("ERROR: Error occurred when try to destroy Media Vision source."
+               "Error code: %i\n", err2);
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int detect_barcode(barcode_model_s model, mv_rectangle_s roi)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    unsigned char *data_buffer = NULL;
+    unsigned long buffer_size = 0;
+    image_data_s image_data;
+
+    int err = load_image_to_buffer(
+            model.file_name, &data_buffer, &buffer_size, &image_data);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during opening the file!!! code: %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    unsigned char *converted_buffer = NULL;
+    unsigned long converted_buffer_size = 0;
+    err = convert_rgb_to(data_buffer, &converted_buffer, image_data, model.colorspace, &converted_buffer_size);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Can't convert to the selected colorspace!!! code: %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    model.out_buffer_ptr = data_buffer;
+
+    mv_engine_config_h mv_engine_config;
+    err = mv_create_engine_config(&mv_engine_config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during creating the media engine config: %i\n", err);
+    }
+
+    mv_engine_config_foreach_supported_attribute(_mv_engine_config_supported_attribute, mv_engine_config);
+
+    mv_engine_config_set_int_attribute(mv_engine_config, MV_BARCODE_DETECT_ATTR_TARGET, MV_BARCODE_DETECT_ATTR_TARGET_2D_BARCODE);
+
+    mv_source_h source;
+    err = mv_create_source(&source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during creating the source!!! code: %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    err = mv_source_fill_by_buffer(source, converted_buffer, converted_buffer_size,
+            image_data.image_width, image_data.image_height, model.colorspace);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during filling the source!!! code: %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    if (converted_buffer != NULL)
+    {
+        free(converted_buffer);
+    }
+
+    err = mv_barcode_detect(source, mv_engine_config, roi, barcode_detected_cb, &model);
+
+    if (data_buffer != NULL)
+    {
+        free(data_buffer);
+    }
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during barcode detection!!! code: %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    err = mv_destroy_source(source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during destroying the source!!! code: %i\n", err);
+    }
+
+    err = mv_destroy_engine_config(mv_engine_config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Error were occurred during destroying the source!!! code: %i\n", err);
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int input_string(const char *prompt, size_t max_len, char **string)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    printf("\n");
+    printf("%s ", prompt);
+
+    if (scanf("\n") != 0)
+    {
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return -1;
+    }
+
+    char buffer[max_len];
+    int last_char = 0;
+    buffer[last_char] = '\0';
+    buffer[sizeof(buffer) - 1] = ~'\0';
+    if (fgets(buffer, sizeof(buffer), stdin) == NULL)
+    {
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return -1;
+    }
+    size_t real_string_len = strlen(buffer);
+    buffer[real_string_len - 1] = '\0';
+    *string = (char*)malloc(real_string_len * sizeof(char));
+    strcpy(*string, buffer);
+
+    size_t str_len = strlen(*string);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return str_len;
+}
+
+int input_size(const char *prompt, size_t max_size, size_t *size)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    printf("\n");
+    printf("%s ", prompt);
+
+    if (scanf("%20zu", size) == 0)
+    {
+        if (scanf("%*[^\n]%*c") != 0)
+        {
+            printf("ERROR: Reading the input line error.\n");
+            MEDIA_VISION_FUNCTION_LEAVE();
+            return -1;
+        }
+        printf("ERROR: Incorrect input.\n");
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return -1;
+    }
+
+    int ret = (*size > max_size ? -1 : 0);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int input_int(const char *prompt, int min_value, int max_value, int *value)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    printf("\n");
+    printf("%s ", prompt);
+
+    if (scanf("%20i", value) == 0)
+    {
+        if (scanf("%*[^\n]%*c") != 0)
+        {
+            printf("ERROR: Reading the input line error.\n");
+            MEDIA_VISION_FUNCTION_LEAVE();
+            return -1;
+        }
+        printf("ERROR: Incorrect input.\n");
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return -1;
+    }
+
+    int ret = (*value < min_value || *value > max_value ? -1 : 0);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret;
+}
+
+int show_menu(const char *title, const int *options, const char **names, int cnt)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    printf("***************************\n");
+    printf("* %23s *\n", title);
+    printf("*-------------------------*\n");
+    int i = 0;
+    for (i = 0; i < cnt; ++i)
+    {
+        printf("* %2i. %19s *\n", options[i], names[i]);
+    }
+    printf("***************************\n\n");
+    int selection = 0;
+    printf("Your choise: ");
+    if (scanf("%20i", &selection) == 0)
+    {
+        if (scanf("%*[^\n]%*c") != 0)
+        {
+            printf("ERROR: Reading the input line error.\n");
+            MEDIA_VISION_FUNCTION_LEAVE();
+            return -1;
+        }
+        printf("ERROR: Incorrect input.\n");
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return selection;
+}
+
+mv_barcode_type_e select_type(void)
+{
+    mv_barcode_type_e selected_type = MV_BARCODE_UNDEFINED;
+    int sel_opt = 0;
+    const int options[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+    const char *names[8] = { "qr", "upca", "upce", "ean8", "ean13", "code39", "code128", "interleave25" };
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    while (sel_opt == 0)
+    {
+        sel_opt = show_menu("Select barcode type:", options, names, 8);
+
+        switch (sel_opt)
+        {
+            case 1:
+                selected_type = MV_BARCODE_QR;
+                break;
+            case 2:
+                selected_type = MV_BARCODE_UPC_A;
+                break;
+            case 3:
+                selected_type = MV_BARCODE_UPC_E;
+                break;
+            case 4:
+                selected_type = MV_BARCODE_EAN_8;
+                break;
+            case 5:
+                selected_type = MV_BARCODE_EAN_13;
+                break;
+            case 6:
+                selected_type = MV_BARCODE_CODE39;
+                break;
+            case 7:
+                selected_type = MV_BARCODE_CODE128;
+                break;
+            case 8:
+                selected_type = MV_BARCODE_I2_5;
+                break;
+            default:
+                sel_opt = 0;
+                break;
+        }
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return selected_type;
+}
+
+mv_barcode_qr_mode_e select_mode(void)
+{
+    mv_barcode_qr_mode_e selected_mode = MV_BARCODE_QR_MODE_UNAVAILABLE;
+    int sel_opt = 0;
+    const int options[4] = { 1, 2, 3, 4 };
+    const char *names[4] = { "numeric", "alphanumeric", "byte", "utf8" };
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    while (sel_opt == 0)
+    {
+        sel_opt = show_menu("Select encoding mode:", options, names, 4);
+        switch (sel_opt)
+        {
+            case 1:
+                selected_mode = MV_BARCODE_QR_MODE_NUMERIC;
+                break;
+            case 2:
+                selected_mode = MV_BARCODE_QR_MODE_ALPHANUMERIC;
+                break;
+            case 3:
+                selected_mode = MV_BARCODE_QR_MODE_BYTE;
+                break;
+            case 4:
+                selected_mode = MV_BARCODE_QR_MODE_UTF8;
+                break;
+            default:
+                sel_opt = 0;
+                break;
+        }
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return selected_mode;
+}
+
+mv_barcode_qr_ecc_e select_ecc(void)
+{
+    mv_barcode_qr_ecc_e selected_ecc = MV_BARCODE_QR_ECC_UNAVAILABLE;
+    int sel_opt = 0;
+    const int options[4] = { 1, 2, 3, 4 };
+    const char *names[4] = { "low", "medium", "quartile", "high" };
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    while (sel_opt == 0)
+    {
+        sel_opt = show_menu("Select ECC level:", options, names, 4);
+        switch (sel_opt)
+        {
+            case 1:
+                selected_ecc = MV_BARCODE_QR_ECC_LOW;
+                break;
+            case 2:
+                selected_ecc = MV_BARCODE_QR_ECC_MEDIUM;
+                break;
+            case 3:
+                selected_ecc = MV_BARCODE_QR_ECC_QUARTILE;
+                break;
+            case 4:
+                selected_ecc = MV_BARCODE_QR_ECC_HIGH;
+                break;
+            default:
+                sel_opt = 0;
+                break;
+        }
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return selected_ecc;
+}
+
+int select_version(void)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int sel_opt = 0;
+    while (sel_opt == 0)
+    {
+        const int options[2] = {1, 40};
+        const char *names[2] = { "1..", "..40" };
+        sel_opt = show_menu("Select QR version:", options, names, 2);
+        if (sel_opt < 1 || sel_opt > 40)
+        {
+            sel_opt = 0;
+        }
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return sel_opt;
+}
+
+generation_fcn_e select_gen_function(void)
+{
+    generation_fcn_e ret_fcn_type = MV_TS_GENERATE_TO_IMAGE_FCN;
+    int sel_opt = 0;
+    const int options[2] = { 1, 2 };
+    const char *names[2] = { "Generate to file", "Generate to source" };
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    while (sel_opt == 0)
+    {
+        sel_opt = show_menu("Select API function:", options, names, 2);
+        switch (sel_opt)
+        {
+            case 1:
+                ret_fcn_type = MV_TS_GENERATE_TO_IMAGE_FCN;
+                break;
+            case 2:
+                ret_fcn_type = MV_TS_GENERATE_TO_SOURCE_FCN;
+                break;
+            default:
+                sel_opt = 0;
+                break;
+        }
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return ret_fcn_type;
+}
+
+mv_barcode_image_format_e select_file_format(void)
+{
+    mv_barcode_image_format_e image_format = MV_BARCODE_IMAGE_FORMAT_JPG;
+    int sel_opt = 0;
+    const int options[3] = { 1, 2, 3 };
+    const char *names[3] = { "BMP", "JPG", "PNG" };
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    while (sel_opt == 0)
+    {
+        sel_opt = show_menu("Select file format:", options, names, 3);
+        switch (sel_opt)
+        {
+            case 1:
+                image_format = MV_BARCODE_IMAGE_FORMAT_BMP;
+                break;
+            case 2:
+                image_format = MV_BARCODE_IMAGE_FORMAT_JPG;
+                break;
+            case 3:
+                image_format = MV_BARCODE_IMAGE_FORMAT_PNG;
+                break;
+            default:
+                sel_opt = 0;
+                break;
+        }
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return image_format;
+}
+
+int perform_detect()
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    barcode_model_s detect_model = {
+        MV_BARCODE_UNDEFINED,
+        MV_BARCODE_QR_ECC_UNAVAILABLE,
+        MV_BARCODE_QR_MODE_UNAVAILABLE,
+        0, 0, 0,
+        MV_BARCODE_IMAGE_FORMAT_PNG,
+        MEDIA_VISION_COLORSPACE_INVALID,
+        NULL, NULL, NULL, NULL };
+
+    while (input_string("Input file name to be analyzed:", 1024, &(detect_model.file_name)) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+    LOGI("Barcode input image has been specified");
+
+    mv_rectangle_s roi = { {0, 0}, 0, 0 };
+
+    while (input_int("Input x coordinate for ROI top left vertex:", 0, 10000, &(roi.point.x)) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    while (input_int("Input y coordinate for ROI top left vertex:", 0, 10000, &(roi.point.y)) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    while (input_int("Input ROI width:", 0, 10000, &(roi.width)) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    while (input_int("Input ROI height:", 0, 10000, &(roi.height)) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+    LOGI("Region of interest (ROI) to detect barcode into has been specified");
+
+    while (input_string("Input file name to be generated:", 1024, &(detect_model.out_file_name)) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+    LOGI("Barcode output image has been specified");
+
+    const int options[11] = { MEDIA_VISION_COLORSPACE_Y800,
+                              MEDIA_VISION_COLORSPACE_I420,
+                              MEDIA_VISION_COLORSPACE_NV12,
+                              MEDIA_VISION_COLORSPACE_YV12,
+                              MEDIA_VISION_COLORSPACE_NV21,
+                              MEDIA_VISION_COLORSPACE_YUYV,
+                              MEDIA_VISION_COLORSPACE_UYVY,
+                              MEDIA_VISION_COLORSPACE_422P,
+                              MEDIA_VISION_COLORSPACE_RGB565,
+                              MEDIA_VISION_COLORSPACE_RGB888,
+                              MEDIA_VISION_COLORSPACE_RGBA };
+    const char *names[11] = { "Y800", "I420", "NV12", "YV12", "NV21",
+                              "YUYV", "UYVY", "422P", "RGB565",
+                              "RGB888", "RGBA" };
+
+    while (true)
+    {
+        int sel_opt = show_menu("Select colorspace to test detector on:", options, names, 11);
+        if (sel_opt < MEDIA_VISION_COLORSPACE_Y800 ||
+            sel_opt > MEDIA_VISION_COLORSPACE_RGBA)
+        {
+            continue;
+        }
+        detect_model.colorspace = (mv_colorspace_e)sel_opt;
+        LOGI("User selection is %i", sel_opt);
+        break;
+    }
+
+    int err = detect_barcode(detect_model, roi);
+
+    if (detect_model.file_name != NULL)
+    {
+        free(detect_model.file_name);
+    }
+
+    if (detect_model.out_file_name != NULL)
+    {
+        free(detect_model.out_file_name);
+    }
+
+    if (err != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Barcode detection failed with error code (0x%08x)", err);
+    }
+
+
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_generate(void)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    barcode_model_s generate_model = {
+            MV_BARCODE_UNDEFINED,
+            MV_BARCODE_QR_ECC_UNAVAILABLE,
+            MV_BARCODE_QR_MODE_UNAVAILABLE,
+            0, 0, 0,
+            MV_BARCODE_IMAGE_FORMAT_PNG,
+            MEDIA_VISION_COLORSPACE_INVALID,
+            NULL, NULL, NULL, NULL };
+
+    generation_fcn_e gen_fcn = select_gen_function();
+    generate_model.type = select_type();
+    LOGI("Barcode type has been selected");
+
+    if (generate_model.type == MV_BARCODE_QR)
+    {
+        generate_model.mode = select_mode();
+        LOGI("Barcode encoding mode has been selected");
+        generate_model.ecc = select_ecc();
+        LOGI("Barcode ecc level has been selected");
+        generate_model.version = select_version();
+        LOGI("Barcode version has been selected");
+    }
+
+    if (gen_fcn == MV_TS_GENERATE_TO_IMAGE_FCN)
+    {
+        generate_model.out_image_format = select_file_format();
+        LOGI("Barcode output image format has been selected");
+    }
+
+    while (input_string("Input message:", 7089, &generate_model.message) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+    LOGI("Barcode message has been specified");
+
+    while (input_string("Input file name:", 1024, &generate_model.file_name) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+    LOGI("Barcode output file name has been specified");
+
+    if (gen_fcn == MV_TS_GENERATE_TO_IMAGE_FCN)
+    {
+        while (input_size("Input image width:", 10000, &generate_model.width) == -1)
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+        LOGI("Barcode output file width has been specified");
+
+        while (input_size("Input image height:", 10000, &generate_model.height) == -1)
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+        LOGI("Barcode output file height has been specified");
+    }
+
+    const int err =
+            gen_fcn == MV_TS_GENERATE_TO_IMAGE_FCN ?
+            generate_barcode_to_image(generate_model) :
+            generate_barcode_to_source(generate_model);
+
+    if (generate_model.message != NULL)
+    {
+        free(generate_model.message);
+    }
+
+    if (generate_model.file_name != NULL)
+    {
+        free(generate_model.file_name);
+    }
+
+    if (err != MEDIA_VISION_ERROR_NONE)
+    {
+        LOGE("Barcode generation failed with error code (0x%08x)", err);
+        printf("ERROR: Errors were occurred during barcode generation!!!\n");
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    LOGI("Barcode output file has been generated");
+    printf("\nBarcode image was successfully generated.\n");
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return 0;
+}
+
+int main(void)
+{
+    LOGI("Media Vision Testsuite is launched.");
+
+    int err = MEDIA_VISION_ERROR_NONE;
+
+    int sel_opt = 0;
+    const int options[2] = { 1, 2 };
+    const char *names[2] = { "Generate", "Detect" };
+
+    while (sel_opt == 0)
+    {
+        sel_opt = show_menu("Select action:", options, names, 2);
+        switch (sel_opt)
+        {
+            case 1:
+                LOGI("Start the barcode generation flow");
+                err = perform_generate();
+                break;
+            case 2:
+                LOGI("Start the barcode detection flow");
+                err = perform_detect();
+                break;
+            default:
+                sel_opt = 0;
+                continue;
+        }
+
+        int do_another = 0;
+
+        if (err != MEDIA_VISION_ERROR_NONE)
+        {
+            printf("ERROR: Action is finished with error code: %i\n", err);
+        }
+
+        sel_opt = 0;
+        const int options_last[2] = { 1, 2 };
+        const char *names_last[2] = { "YES", "NO" };
+
+        while (sel_opt == 0)
+        {
+            sel_opt = show_menu("Perform another action?", options_last, names_last, 2);
+            switch (sel_opt)
+            {
+                case 1:
+                    do_another = 1;
+                    break;
+                case 2:
+                    do_another = 0;
+                    break;
+                default:
+                    sel_opt = 0;
+                    break;
+            }
+        }
+        LOGI("User selection is %i", sel_opt);
+
+        sel_opt = (do_another == 1 ? 0 : sel_opt);
+    }
+
+    LOGI("Media Vision Testsuite is closed.");
+
+    return err;
+}
diff --git a/test/testsuites/common/CMakeLists.txt b/test/testsuites/common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e62cc2a
--- /dev/null
@@ -0,0 +1,6 @@
+project(mv_testsuites_common)
+cmake_minimum_required(VERSION 2.6)
+
+add_subdirectory(${PROJECT_SOURCE_DIR}/image_helper)
+add_subdirectory(${PROJECT_SOURCE_DIR}/video_helper)
+add_subdirectory(${PROJECT_SOURCE_DIR}/testsuite_common)
diff --git a/test/testsuites/common/image_helper/CMakeLists.txt b/test/testsuites/common/image_helper/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a89a88a
--- /dev/null
@@ -0,0 +1,37 @@
+project(mv_image_helper)
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+if(NOT SKIP_WARNINGS)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${PROJECT_SOURCE_DIR}/include")
+
+file(GLOB MV_IMAGE_HELPER_INCLUDE_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_IMAGE_HELPER_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.c"
+                                   "${PROJECT_SOURCE_DIR}/src/*.cpp")
+
+find_package(OpenCV REQUIRED core highgui imgproc)
+
+if(NOT OpenCV_FOUND)
+    message(SEND_ERROR "Failed to find OpenCV")
+    return()
+else()
+    include_directories(${OpenCV_INCLUDE_DIRS})
+endif()
+
+if(FORCED_STATIC_BUILD)
+    add_library(${PROJECT_NAME} STATIC ${MV_IMAGE_HELPER_INCLUDE_LIST} ${MV_IMAGE_HELPER_SRC_LIST})
+else()
+    add_library(${PROJECT_NAME} SHARED ${MV_IMAGE_HELPER_INCLUDE_LIST} ${MV_IMAGE_HELPER_SRC_LIST})
+endif()
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} jpeg ${OpenCV_LIBS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/test/testsuites/common/image_helper/include/ImageHelper.h b/test/testsuites/common/image_helper/include/ImageHelper.h
new file mode 100644 (file)
index 0000000..e9eabcc
--- /dev/null
@@ -0,0 +1,247 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGEHELPER_H__
+#define __IMAGEHELPER_H__
+
+#include "mv_common.h"
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include <jpeglib.h>
+
+/**
+ * @file   ImageHelper.h
+ * @brief  ImageHelper class definition.
+ */
+
+namespace cv
+{
+    template<typename _Tp> class Scalar_;
+    typedef Scalar_<double> Scalar;
+
+    class VideoCapture;
+    class VideoWriter;
+}
+
+namespace MediaVision
+{
+namespace Common
+{
+
+/**
+ * @class ImageHelper
+ * @brief Helper class that provides set of useful methods
+ *        for image management.
+ */
+class ImageHelper
+{
+public:
+    /**
+     * @brief Structure to keep information about width, height and colorspace of an image.
+     */
+    struct ImageData
+    {
+        unsigned int imageWidth;                 /**< Image width */
+        unsigned int imageHeight;                /**< Image height */
+        mv_colorspace_e imageColorspace;         /**< Image colorspace */
+    };
+
+   /**
+     * @brief Loads image from file to the buffer of unsigned chars.
+     *
+     * @since_tizen 3.0
+     * @param [in]  filePath       Path to the image file to be loaded to the
+     *                             @a pDataBuffer
+     * @param [out] pDataBuffer    The buffer of unsigned chars where image data
+     *                             will be stored
+     * @param [out] pBufferSize    The size of the @a pDataBuffer
+     * @param [out] pImageData     The image data (structure that keeps
+     *                             information about image width, height,
+     *                             and colorspace)
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see ImageHelper::saveImageFromBuffer()
+     */
+    static int loadImageToBuffer(
+            const char *filePath,
+            unsigned char **pDataBuffer,
+            unsigned long *pBufferSize,
+            ImageData *pImageData);
+
+    /**
+     * @brief Saves image stored into @a pDataBuffer to the file in jpeg format.
+     *
+     * @since_tizen 3.0
+     * @param [in] filePath       The path to the file where image will be saved
+     * @param [in] pDataBuffer    Data buffer that contains image data
+     * @param [in] imageData      The image data (structure that keeps
+     *                            information about image width, height,
+     *                            and colorspace)
+     * @param [in] quality        Quality for the output jpeg file (0..100)
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see ImageHelper::loadImageToBuffer()
+     */
+    static int saveImageFromBuffer(
+            const char *filePath,
+            unsigned char *pDataBuffer,
+            const ImageData& imageData,
+            int quality = 100);
+
+    /**
+     * @brief Draws the rectangle of specified size on the image data buffer.
+     *
+     * @since_tizen 3.0
+     * @param [in]  topLeftVertexX        The rectangle top left corner
+     *                                    x coordinate
+     * @param [in]  topLeftVertexY        The rectangle top left corner
+     *                                    y coordinate
+     * @param [in]  bottomRightVertexX    The rectangle bottom right corner
+     *                                    x coordinate
+     * @param [in]  bottomRightVertexY    The rectangle bottom right corner
+     *                                    y coordinate
+     * @param [in]  thickness             The thickness of the rectangle border
+     *                                    (negative value to draw filled rectangle)
+     * @param [in]  color                 The color of the rectangle border
+     * @param [in]  imageData             The image data (structure that keeps
+     *                                    information about image width, height,
+     *                                    and colorspace). Colorspace has to be
+     *                                    @c MEDIA_VISION_COLORSPACE_RGB888
+     * @param [in, out] pDataBuffer       The pointer to the image data buffer
+     *                                    which will be used for rectangle drawing
+     * @return @c 0 on success, otherwise a negative error value
+     */
+    static int drawRectangleOnBuffer(
+            int topLeftVertexX,
+            int topLeftVertexY,
+            int bottomRightVertexX,
+            int bottomRightVertexY,
+            int thickness,
+            const cv::Scalar& color,
+            const ImageData& imageData,
+            unsigned char *pDataBuffer);
+
+    /**
+     * @brief Draws the quadrangle of specified size on the image data buffer.
+     *
+     * @since_tizen 3.0
+     * @param [in]  location              The quadrangle structure
+     * @param [in]  thickness             The thickness of the quadrangle border
+     * @param [in]  color                 The color of the quadrangle border
+     * @param [in]  imageData             The image data (structure that keeps
+     *                                    information about image width, height,
+     *                                    and colorspace). Colorspace has to be
+     *                                    @c MEDIA_VISION_COLORSPACE_RGB888
+     * @param [in, out] pDataBuffer       The pointer to the image data buffer
+     *                                    which will be used for quadrangle drawing
+     * @return @c 0 on success, otherwise a negative error value
+     */
+    static int drawQuadrangleOnBuffer(
+            mv_quadrangle_s location,
+            int thickness,
+            const cv::Scalar& color,
+            const ImageData& imageData,
+            unsigned char *pDataBuffer);
+
+    /**
+     * @brief Convers libjpeg colorspace to the Tizen 'image util' colorspace.
+     *
+     * @since_tizen 3.0
+     * @param [in]  inColorspace      The libjpeg colorspace to be converted.
+     * @param [out] pOutColorspace    The Tizen 'image util' colorspace that
+     *                                will be obtained after conversion
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see ImageHelper::convertMVColorspaceToJpeglibColorspace()
+     */
+    static int convertJpeglibColorspaceToMVColorspace(
+            J_COLOR_SPACE inColorspace,
+            mv_colorspace_e *pOutColorspace);
+
+    /**
+     * @brief Convers libjpeg colorspace to the Tizen image util colorspace.
+     *
+     * @since_tizen 3.0
+     * @param [in]  inColorspace      The Tizen 'image util' colorspace to be
+     *                                converted
+     * @param [out] pOutColorspace    The libjpeg colorspace that will be
+     *                                obtained after conversion
+     * @return @c 0 on success, otherwise a negative error value
+     *
+     * @see ImageHelper::convertJpeglibColorspaceToMVColorspace()
+     */
+    static int convertMVColorspaceToJpeglibColorspace(
+            mv_colorspace_e inColorspace,
+            J_COLOR_SPACE *pOutColorspace);
+
+    /**
+     * @brief Converts image data to the image data of RGB888 colorspace.
+     *
+     * @since_tizen 3.0
+     * @param [in]  pInBuffer     Buffer with image data to be converted to
+     *                            RGB888 colorspace
+     * @param [in]  imageData     The image data (structure that keeps
+     *                            information about image width, height,
+     *                            and colorspace) for source image
+     * @param [out] pOutBuffer    Buffer with image data to be generated as
+     *                            a result of the conversion
+     * @return @c 0 on success, otherwise a negative error value
+     */
+    static int convertBufferToRGB888(
+            const unsigned char *pInBuffer,
+            const ImageData& imageData,
+            unsigned char **pOutBuffer);
+
+    /**
+     * @brief Determines number of channels (components) for the colorspace.
+     *
+     * @since_tizen 3.0
+     * @param [in]  colorspace           Colorspace for which number of
+     *                                   components will be determined
+     * @param [out] pComponentsNumber    Number of components to be determined
+     * @return @c 0 on success, otherwise a negative error value
+     */
+    static int getNumberOfComponents(
+            mv_colorspace_e colorspace,
+            int *pComponentsNumber);
+
+private:
+    /**
+     * @brief Converts buffer with image data in Y800 colorspace format
+     *        to the buffer with image data in RGB888 colorspace format.
+     *
+     * @since_tizen 3.0
+     * @param [in]  pInBuffer     The buffer with data in Y800 colorspace format
+     * @param [in]  imageData     The image data (structure that keeps
+     *                            information about image width, height, and
+     *                            colorspace) for source buffer
+     * @param [out] pOutBuffer    The buffer that will contain converted image
+     *                            data in RGB888 colorspace format
+     * @return @c 0 on success, otherwise a negative error value
+     */
+    static int convertY800ToRGB(
+            const unsigned char *pInBuffer,
+            const ImageData& imageData,
+            unsigned char **pOutBuffer);
+
+};
+
+} /* namespace Common */
+} /* namespace MediaVision */
+
+#endif /* __IMAGEHELPER_H__ */
diff --git a/test/testsuites/common/image_helper/include/image_helper.h b/test/testsuites/common/image_helper/include/image_helper.h
new file mode 100644 (file)
index 0000000..bef34be
--- /dev/null
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGE_HELPER_H__
+#define __IMAGE_HELPER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "mv_common.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdio>
+#else
+#include <stddef.h>
+#include <stdio.h>
+#endif
+
+#include <jpeglib.h>
+
+/**
+ * @file   image_helper.h
+ * @brief  Helper functions that provides set of useful methods for image management
+ *         (c wrapper of ImageHelper class).
+ */
+
+/**
+ * @brief Structure to keep information about width, height and colorspace of an image.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct
+{
+    unsigned int image_width;                 /**< Image width */
+    unsigned int image_height;                /**< Image height */
+    mv_colorspace_e image_colorspace;         /**< Image colorspace */
+} image_data_s;
+
+/**
+ * @brief Loads image from file to the buffer of unsigned chars.
+ *
+ * @since_tizen 3.0
+ * @param [in]  file_path      Path to the image file to be loaded to the
+ *                             @a pDataBuffer
+ * @param [out] data_buffer    The buffer of unsigned chars where image data
+ *                             will be stored
+ * @param [out] buffer_size    The size of the @a pDataBuffer
+ * @param [out] image_data     The image data (structure that keeps
+ *                             information about image width, height,
+ *                             and colorspace)
+ * @return @c 0 on success, otherwise a negative error value
+ *
+ * @see save_image_from_buffer()
+ */
+int load_image_to_buffer(
+        const char *file_path,
+        unsigned char **data_buffer,
+        unsigned long *buffer_size,
+        image_data_s *image_data);
+
+/**
+ * @brief Saves image stored into @a pDataBuffer to the file in jpeg format.
+ *
+ * @since_tizen 3.0
+ * @param [in] file_path      The path to the file where image will be saved
+ * @param [in] data_buffer    Data buffer that contains image data
+ * @param [in] image_data     The image data (structure that keeps
+ *                            information about image width, height,
+ *                            and colorspace)
+ * @param [in] quality        Quality for the output jpeg file (0..100)
+ * @return @c 0 on success, otherwise a negative error value
+ *
+ * @see load_image_to_buffer()
+ */
+int save_image_from_buffer(
+        const char *file_path,
+        unsigned char *data_buffer,
+        const image_data_s *image_data,
+        int quality);
+
+/**
+ * @brief Draws the rectangle of specified size on the image data buffer.
+ *
+ * @since_tizen 3.0
+ * @param [in]  tl_vertex_x         The rectangle top left corner x coordinate
+ * @param [in]  tl_vertex_y         The rectangle top left corner y coordinate
+ * @param [in]  br_vertex_x         The rectangle bottom right corner x coordinate
+ * @param [in]  br_vertex_y         The rectangle bottom right corner y coordinate
+ * @param [in]  thickness           The thickness of the rectangle border (negative
+ *                                  value to draw filled rectangle)
+ * @param [in]  rgb_color           The color of the rectangle border
+ * @param [in]  image_data          The image data (structure that keeps information
+ *                                  about image width, height, and colorspace).
+ *                                  Colorspace has to be @c MEDIA_VISION_COLORSPACE_RGB888
+ * @param [in, out] data_buffer     The pointer to the image data buffer which will
+ *                             be used for rectangle drawing
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int draw_rectangle_on_buffer(
+        int tl_vertex_x,
+        int tl_vertex_y,
+        int br_vertex_x,
+        int br_vertex_y,
+        int thickness,
+        const int rgb_color[3],
+        const image_data_s *image_data,
+        unsigned char *data_buffer);
+
+/**
+ * @brief Draws the quadrangle of specified size on the image data buffer.
+ *
+ * @since_tizen 3.0
+ * @param [in]  location          The quadrangle structure
+ * @param [in]  thickness         The thickness of the quadrangle border
+ * @param [in]  rgb_color         The color of the quadrangle border
+ * @param [in]  image_data        The image data (structure that keeps information
+ *                                about image width, height, and colorspace).
+ *                                Colorspace has to be @c MEDIA_VISION_COLORSPACE_RGB888
+ * @param [in, out] data_buffer   The pointer to the image data buffer which will
+ *                                be used for quadrangle drawing
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int draw_quadrangle_on_buffer(
+        mv_quadrangle_s location,
+        int thickness,
+        const int rgb_color[3],
+        const image_data_s *image_data,
+        unsigned char *data_buffer);
+
+/**
+ * @brief Converts libjpeg colorspace to the Tizen 'image util' colorspace.
+ *
+ * @since_tizen 3.0
+ * @param [in]  in_colorspace     The libjpeg colorspace to be converted.
+ * @param [out] out_colorspace    The Tizen 'image util' colorspace that
+ *                                will be obtained after conversion
+ * @return @c 0 on success, otherwise a negative error value
+ *
+ * @see convert_mv_colorspace_to_jpeglib_colorspace()
+ */
+int convert_jpeglib_colorspace_to_mv_colorspace(
+        J_COLOR_SPACE in_colorspace,
+        mv_colorspace_e *out_colorspace);
+
+/**
+ * @brief Converts libjpeg colorspace to the Tizen image util colorspace.
+ *
+ * @since_tizen 3.0
+ * @param [in]  in_colorspace     The Tizen 'image util' colorspace to be
+ *                                converted
+ * @param [out] out_colorspace    The libjpeg colorspace that will be
+ *                                obtained after conversion
+ * @return @c 0 on success, otherwise a negative error value
+ *
+ * @see convert_jpeglib_colorspace_to_mv_colorspace()
+ */
+int convert_mv_colorspace_to_jpeglib_colorspace(
+        mv_colorspace_e in_colorspace,
+        J_COLOR_SPACE *out_colorspace);
+
+/**
+ * @brief Converts image data to the image data of RGB888 colorspace.
+ *
+ * @since_tizen 3.0
+ * @param [in]  in_buffer     Buffer with image data to be converted to
+ *                            RGB888 colorspace
+ * @param [in]  image_data    The image data (structure that keeps
+ *                            information about image width, height,
+ *                            and colorspace) for source image
+ * @param [out] out_buffer    Buffer with image data to be generated as
+ *                            a result of the conversion
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int convert_buffer_to_RGB888(
+        const unsigned char *in_buffer,
+        const image_data_s *image_data,
+        unsigned char **out_buffer);
+
+/**
+ * @brief Determines number of channels (components) for the colorspace.
+ *
+ * @since_tizen 3.0
+ * @param [in]  colorspace           Colorspace for which number of
+ *                                   components will be determined
+ * @param [out] components_number    Number of components to be determined
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int get_number_of_components(
+        mv_colorspace_e colorspace,
+        int *components_number);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __IMAGE_HELPER_H__*/
diff --git a/test/testsuites/common/image_helper/src/ImageHelper.cpp b/test/testsuites/common/image_helper/src/ImageHelper.cpp
new file mode 100644 (file)
index 0000000..e6b0a54
--- /dev/null
@@ -0,0 +1,392 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ImageHelper.h"
+#include "mv_private.h"
+
+#include <vector>
+
+#include <cstring>
+
+#include <setjmp.h>
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+
+/**
+ * @file   ImageHelper.cpp
+ * @brief  The ImageHelper class methods implementation.
+ */
+
+namespace MediaVision
+{
+namespace Common
+{
+
+namespace
+{
+
+static const int OpenCVChannels = 3;
+static const mv_colorspace_e OpenCVColor = MEDIA_VISION_COLORSPACE_RGB888;
+static const int QuadrangleVertices = 4;
+
+std::vector<std::string> getJPGExtensions()
+{
+    std::vector<std::string> extensions;
+    extensions.push_back(".jpg");
+    extensions.push_back(".jpe");
+    extensions.push_back(".jpeg");
+    return extensions;
+}
+
+} /* anonymous namespace */
+
+int ImageHelper::loadImageToBuffer(
+        const char *filePath,
+        unsigned char **pDataBuffer,
+        unsigned long *pBufferSize,
+        ImageData *pImageData)
+{
+    if (filePath == NULL || pDataBuffer == NULL ||
+        pBufferSize == NULL || pImageData == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::Mat image;
+    image = cv::imread(filePath);
+
+    if (!image.data)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::cvtColor(image, image, CV_BGR2RGB);
+
+    *pBufferSize = image.total() * image.elemSize();
+    (*pDataBuffer) = new unsigned char[*pBufferSize];
+    std::memcpy(*pDataBuffer, image.data, *pBufferSize);
+
+    pImageData->imageWidth = image.cols;
+    pImageData->imageHeight = image.rows;
+    pImageData->imageColorspace = OpenCVColor;
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageHelper::saveImageFromBuffer(
+        const char *filePath,
+        unsigned char *pDataBuffer,
+        const ImageData& imageData,
+        int quality)
+{
+    if (filePath == NULL || pDataBuffer == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    static const std::string defaultFilePath = "out";
+    static const std::vector<std::string> jpgExtensions = getJPGExtensions();
+
+    bool rightExtensionFlag = false;
+
+    std::string resultFilePath(filePath);
+    if (resultFilePath.empty())
+    {
+        resultFilePath = defaultFilePath;
+    }
+    else
+    {
+        for (size_t extNum = 0; extNum < jpgExtensions.size(); ++extNum)
+        {
+            if (resultFilePath.size() >= jpgExtensions[extNum].size())
+            {
+                std::string givenExtension = resultFilePath.substr(
+                        resultFilePath.length() - jpgExtensions[extNum].size(),
+                        jpgExtensions[extNum].size());
+
+                std::transform(
+                        givenExtension.begin(), givenExtension.end(),
+                        givenExtension.begin(), ::tolower);
+
+                if (givenExtension == jpgExtensions[extNum])
+                {
+                    rightExtensionFlag = true;
+                    break;
+                }
+            }
+        }
+    }
+    if (!rightExtensionFlag)
+    {
+        resultFilePath += jpgExtensions[0];
+    }
+
+    if (quality <= 0 || quality > 100)
+    {
+        quality = 100;
+    }
+
+    unsigned int width = imageData.imageWidth;
+    unsigned int height = imageData.imageHeight;
+
+    int conversionType = -1; // Type of conversion from given colorspace to BGR
+    unsigned int channelsNumber = 0;
+    switch (imageData.imageColorspace)
+    {
+        case MEDIA_VISION_COLORSPACE_INVALID:
+            return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+        case MEDIA_VISION_COLORSPACE_Y800:
+            channelsNumber = 1;
+            conversionType = CV_GRAY2BGR;
+            break;
+        case MEDIA_VISION_COLORSPACE_I420:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2BGR_I420;
+            break;
+        case MEDIA_VISION_COLORSPACE_NV12:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2BGR_NV12;
+            break;
+        case MEDIA_VISION_COLORSPACE_YV12:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2BGR_YV12;
+            break;
+        case MEDIA_VISION_COLORSPACE_NV21:
+            channelsNumber = 1;
+            height *= 1.5;
+            conversionType = CV_YUV2BGR_NV21;
+            break;
+        case MEDIA_VISION_COLORSPACE_YUYV:
+            channelsNumber = 2;
+            conversionType = CV_YUV2BGR_YUYV;
+            break;
+        case MEDIA_VISION_COLORSPACE_UYVY:
+            channelsNumber = 2;
+            conversionType = CV_YUV2BGR_UYVY;
+            break;
+        case MEDIA_VISION_COLORSPACE_422P:
+            channelsNumber = 2;
+            conversionType = CV_YUV2BGR_Y422;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB565:
+            channelsNumber = 2;
+            conversionType = CV_BGR5652BGR;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGB888:
+            channelsNumber = 3;
+            conversionType = CV_RGB2BGR;
+            break;
+        case MEDIA_VISION_COLORSPACE_RGBA:
+            channelsNumber = 4;
+            conversionType = CV_RGBA2BGR;
+            break;
+        default:
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    const int depth = CV_8U;
+    cv::Mat cvImage(cv::Size(width, height),
+                    CV_MAKETYPE(depth, channelsNumber), pDataBuffer);
+    cv::Mat cvBGRImage;
+    cv::cvtColor(cvImage, cvBGRImage, conversionType);
+
+    std::vector<int> compression_params(2);
+    compression_params[0] = CV_IMWRITE_JPEG_QUALITY;
+    compression_params[1] = quality;
+
+    if (!cv::imwrite(resultFilePath, cvBGRImage, compression_params))
+    {
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageHelper::drawRectangleOnBuffer(
+        int topLeftVertexX,
+        int topLeftVertexY,
+        int bottomRightVertexX,
+        int bottomRightVertexY,
+        int thickness,
+        const cv::Scalar& color,
+        const ImageData& imageData,
+        unsigned char *pDataBuffer)
+{
+    if (NULL == pDataBuffer)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::Mat cvImage(imageData.imageHeight, imageData.imageWidth, CV_8UC(OpenCVChannels), pDataBuffer);
+    cv::rectangle(
+            cvImage,
+            cv::Point(topLeftVertexX, topLeftVertexY),
+            cv::Point(bottomRightVertexX, bottomRightVertexY),
+            color,
+            thickness);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageHelper::drawQuadrangleOnBuffer(
+            mv_quadrangle_s location,
+            int thickness,
+            const cv::Scalar& color,
+            const ImageData& imageData,
+            unsigned char *pDataBuffer)
+{
+    if (NULL == pDataBuffer)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    cv::Mat cvImage(imageData.imageHeight, imageData.imageWidth, CV_8UC(OpenCVChannels), pDataBuffer);
+    for (int i = 0; i < QuadrangleVertices; ++i)
+    {
+        cv::line(
+                cvImage,
+                cv::Point(location.points[i].x, location.points[i].y),
+                cv::Point(location.points[(i + 1) % QuadrangleVertices].x,
+                        location.points[(i + 1) % QuadrangleVertices].y),
+                color,
+                thickness);
+    }
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageHelper::convertJpeglibColorspaceToMVColorspace(
+        J_COLOR_SPACE inColorspace,
+        mv_colorspace_e *pOutColorspace)
+{
+    if (pOutColorspace == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    switch(inColorspace)
+    {
+        case JCS_GRAYSCALE:
+            (*pOutColorspace) = MEDIA_VISION_COLORSPACE_Y800;
+            return MEDIA_VISION_ERROR_NONE;
+        case JCS_RGB:
+            (*pOutColorspace) = MEDIA_VISION_COLORSPACE_RGB888;
+            return MEDIA_VISION_ERROR_NONE;
+        default:
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageHelper::convertMVColorspaceToJpeglibColorspace(
+        mv_colorspace_e inColorspace,
+        J_COLOR_SPACE *pOutColorspace)
+{
+    // todo: support more colorspaces:
+    switch (inColorspace)
+    {
+        case MEDIA_VISION_COLORSPACE_Y800:
+            (*pOutColorspace) = JCS_GRAYSCALE;
+            return MEDIA_VISION_ERROR_NONE;
+        case MEDIA_VISION_COLORSPACE_RGB888:
+            (*pOutColorspace) = JCS_RGB;
+            return MEDIA_VISION_ERROR_NONE;
+        default:
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+    }
+
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int ImageHelper::convertBufferToRGB888(
+        const unsigned char *pInBuffer,
+        const ImageData& imageData,
+        unsigned char **pOutBuffer)
+{
+    // todo: support more colorspaces:
+    switch(imageData.imageColorspace)
+    {
+        case MEDIA_VISION_COLORSPACE_Y800:
+            return convertY800ToRGB(pInBuffer, imageData, pOutBuffer);
+        case MEDIA_VISION_COLORSPACE_RGB888:
+        {
+            int numberOfComponents = 0;
+            getNumberOfComponents(
+                    MEDIA_VISION_COLORSPACE_RGB888, &numberOfComponents);
+            const int dataSize =
+                    imageData.imageHeight * imageData.imageWidth * numberOfComponents;
+            (*pOutBuffer) = new unsigned char[dataSize];
+            std::memcpy(*pOutBuffer, pInBuffer, dataSize);
+            return MEDIA_VISION_ERROR_NONE;
+        }
+        default:
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+    }
+
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int ImageHelper::getNumberOfComponents(
+        mv_colorspace_e colorspace,
+        int *pComponentsNumber)
+{
+    // todo: support more colorspaces:
+    switch (colorspace)
+    {
+        case MEDIA_VISION_COLORSPACE_Y800:
+            (*pComponentsNumber) = 1;
+            return MEDIA_VISION_ERROR_NONE;
+        case MEDIA_VISION_COLORSPACE_RGB888:
+            (*pComponentsNumber) = 3;
+            return MEDIA_VISION_ERROR_NONE;
+        default:
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+    }
+
+    return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int ImageHelper::convertY800ToRGB(
+        const unsigned char *pInBuffer,
+        const ImageData& imageData,
+        unsigned char **pOutBuffer)
+{
+    if (imageData.imageColorspace != MEDIA_VISION_COLORSPACE_Y800)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+    const int inDataSize = imageData.imageHeight * imageData.imageWidth;
+    int numberOfComponents = 0;
+    getNumberOfComponents(MEDIA_VISION_COLORSPACE_RGB888, &numberOfComponents);
+    const int dataSize = inDataSize * numberOfComponents;
+    (*pOutBuffer) = new unsigned char[dataSize];
+    for (int i = 0; i < inDataSize; ++i)
+    {
+        int pixelStartIndex = i*numberOfComponents;
+        (*pOutBuffer)[pixelStartIndex]   = pInBuffer[i];
+        (*pOutBuffer)[pixelStartIndex+1] = pInBuffer[i];
+        (*pOutBuffer)[pixelStartIndex+2] = pInBuffer[i];
+    }
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* namespace Common */
+} /* namespace MediaVision */
diff --git a/test/testsuites/common/image_helper/src/image_helper.cpp b/test/testsuites/common/image_helper/src/image_helper.cpp
new file mode 100644 (file)
index 0000000..369f703
--- /dev/null
@@ -0,0 +1,172 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "image_helper.h"
+
+#include "mv_private.h"
+#include "ImageHelper.h"
+
+#include <opencv2/core/core.hpp>
+
+/**
+ * @file   image_helper.cpp
+ * @brief  image_helper.h functions implementation.
+ */
+
+using namespace MediaVision::Common;
+
+image_data_s convertToCData(ImageHelper::ImageData data)
+{
+    image_data_s ret;
+    ret.image_width = data.imageWidth;
+    ret.image_height = data.imageHeight;
+    ret.image_colorspace = data.imageColorspace;
+    return ret;
+}
+
+ImageHelper::ImageData convertToCppData(image_data_s data)
+{
+    ImageHelper::ImageData ret;
+    ret.imageWidth = data.image_width;
+    ret.imageHeight = data.image_height;
+    ret.imageColorspace = data.image_colorspace;
+    return ret;
+}
+
+
+int load_image_to_buffer(
+        const char *file_path,
+        unsigned char **data_buffer,
+        unsigned long *buffer_size,
+        image_data_s *image_data)
+{
+    if (image_data == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int err;
+    ImageHelper::ImageData imageData;
+    err = ImageHelper::loadImageToBuffer(file_path, data_buffer, buffer_size, &imageData);
+
+    if (err == MEDIA_VISION_ERROR_NONE)
+    {
+        *image_data = convertToCData(imageData);
+    }
+
+    return err;
+}
+
+int save_image_from_buffer(
+        const char *file_path,
+        unsigned char *data_buffer,
+        const image_data_s *image_data,
+        int quality)
+{
+    if (image_data == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    ImageHelper::ImageData imageData = convertToCppData(*image_data);
+    return ImageHelper::saveImageFromBuffer(file_path, data_buffer, imageData, quality);
+}
+
+int draw_rectangle_on_buffer(
+        int tl_vertex_x,
+        int tl_vertex_y,
+        int br_vertex_x,
+        int br_vertex_y,
+        int thickness,
+        const int rgb_color[3],
+        const image_data_s *image_data,
+        unsigned char *data_buffer)
+{
+    if (image_data == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    ImageHelper::ImageData imageData = convertToCppData(*image_data);
+
+    cv::Scalar color(rgb_color[2], rgb_color[1], rgb_color[0]);
+
+    return ImageHelper::drawRectangleOnBuffer(
+                            tl_vertex_x, tl_vertex_y,
+                            br_vertex_x, br_vertex_y,
+                            thickness,
+                            color,
+                            imageData, data_buffer);
+}
+
+int draw_quadrangle_on_buffer(
+        mv_quadrangle_s location,
+        int thickness,
+        const int rgb_color[3],
+        const image_data_s *image_data,
+        unsigned char *data_buffer)
+{
+    if (image_data == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    ImageHelper::ImageData imageData = convertToCppData(*image_data);
+
+    cv::Scalar color(rgb_color[2], rgb_color[1], rgb_color[0]);
+
+    return ImageHelper::drawQuadrangleOnBuffer(
+                            location,
+                            thickness,
+                            color,
+                            imageData,
+                            data_buffer);
+}
+
+int convert_jpeglib_colorspace_to_mv_colorspace(
+        J_COLOR_SPACE in_colorspace,
+        mv_colorspace_e *out_colorspace)
+{
+    return ImageHelper::convertJpeglibColorspaceToMVColorspace(in_colorspace, out_colorspace);
+}
+
+int convert_mv_colorspace_to_jpeglib_colorspace(
+        mv_colorspace_e in_colorspace,
+        J_COLOR_SPACE *out_colorspace)
+{
+    return ImageHelper::convertMVColorspaceToJpeglibColorspace(in_colorspace, out_colorspace);
+}
+
+int convert_buffer_to_RGB888(
+        const unsigned char *in_buffer,
+        const image_data_s *image_data,
+        unsigned char **out_buffer)
+{
+    if (image_data == NULL)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    ImageHelper::ImageData imageData = convertToCppData(*image_data);
+    return ImageHelper::convertBufferToRGB888(in_buffer, imageData, out_buffer);
+}
+
+int get_number_of_components(
+        mv_colorspace_e colorspace,
+        int *components_number)
+{
+    return ImageHelper::getNumberOfComponents(colorspace, components_number);
+}
diff --git a/test/testsuites/common/testsuite_common/CMakeLists.txt b/test/testsuites/common/testsuite_common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b111347
--- /dev/null
@@ -0,0 +1,18 @@
+SET (pkgname mv_testsuite_common)
+PROJECT(${pkgname})
+
+cmake_minimum_required(VERSION 2.6)
+
+SET(INC_DIR include)
+INCLUDE_DIRECTORIES(${INC_DIR})
+include_directories(${INC_IMAGE_HELPER})
+include_directories(${INC_VIDEO_HELPER})
+
+SET(CMAKE_C_FLAGS "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+ADD_LIBRARY(${pkgname} SHARED "mv_testsuite_common.c" "mv_testsuite_common.h")
+
+TARGET_LINK_LIBRARIES(${pkgname} ${MV_COMMON_LIB_NAME} mv_image_helper)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/test/testsuites/common/testsuite_common/mv_testsuite_common.c b/test/testsuites/common/testsuite_common/mv_testsuite_common.c
new file mode 100644 (file)
index 0000000..bf02a2a
--- /dev/null
@@ -0,0 +1,323 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_testsuite_common.h"
+
+#include "image_helper.h"
+#include "mv_log_cfg.h"
+
+#include <string.h>
+#include <stdio.h>
+
+
+void print_fail_result(
+        const char *action_name,
+        int action_return_value)
+{
+    printf(TEXT_RED
+           "Error with code %i was occurred during action '%s'"
+           TEXT_RESET "\n",
+           action_return_value,
+           action_name);
+}
+
+void print_done_result(const char *action_name)
+{
+    printf(TEXT_YELLOW
+           "Action '%s' was finished"
+           TEXT_RESET "\n",
+           action_name);
+}
+
+void print_success_result(const char *action_name)
+{
+    printf(TEXT_GREEN
+           "Action '%s' was finished successfully"
+           TEXT_RESET
+           "\n", action_name);
+}
+
+void print_action_result(
+        const char *action_name,
+        int action_return_value,
+        notification_type_e notification_type_e)
+{
+    switch(notification_type_e)
+    {
+        case FAIL_OR_SUCCESSS:
+            if (MEDIA_VISION_ERROR_NONE != action_return_value)
+            {
+                print_fail_result(action_name, action_return_value);
+            }
+            else
+            {
+                print_success_result(action_name);
+            }
+            break;
+        case FAIL_OR_DONE:
+            if (MEDIA_VISION_ERROR_NONE != action_return_value)
+            {
+                print_fail_result(action_name, action_return_value);
+            }
+            else
+            {
+                print_done_result(action_name);
+            }
+            break;
+        default:
+            print_done_result(action_name);
+    }
+}
+
+int input_string(const char *prompt, size_t max_len, char **string)
+{
+    printf("\n");
+    printf("%s ", prompt);
+
+    if (scanf("\n") != 0)
+    {
+        return -1;
+    }
+
+    char buffer[max_len];
+    int last_char = 0;
+    buffer[last_char] = '\0';
+    buffer[sizeof(buffer) - 1] = ~'\0';
+    if (NULL == fgets(buffer, sizeof(buffer), stdin))
+    {
+        return -1;
+    }
+    size_t real_string_len = strlen(buffer);
+    buffer[real_string_len - 1] = '\0';
+    *string = (char*)malloc(real_string_len * sizeof(char));
+    strcpy(*string, buffer);
+
+    return strlen(*string);
+}
+
+int input_size(const char *prompt, size_t max_size, size_t *size)
+{
+    printf("\n");
+    printf("%s ", prompt);
+
+    if (scanf("%20zu", size) == 0)
+    {
+        if (scanf("%*[^\n]%*c") != 0)
+        {
+            printf("ERROR: Reading the input line error.\n");
+            return -1;
+        }
+        printf("ERROR: Incorrect input.\n");
+        return -1;
+    }
+    scanf("%*[^\n]%*c");
+
+    return (*size > max_size ? -1 : 0);
+}
+
+int input_int(const char *prompt, int min_value, int max_value, int *value)
+{
+    printf("\n");
+    printf("%s ", prompt);
+
+    if (scanf("%20i", value) == 0)
+    {
+        if (scanf("%*[^\n]%*c") != 0)
+        {
+            printf("ERROR: Reading the input line error.\n");
+            return -1;
+        }
+        printf("ERROR: Incorrect input.\n");
+        return -1;
+    }
+    scanf("%*[^\n]%*c");
+
+    return (*value < min_value || *value > max_value ? -1 : 0);
+}
+
+int input_double(
+        const char *prompt,
+        double min_value,
+        double max_value,
+        double *value)
+{
+    printf("\n");
+    printf("%s ", prompt);
+
+    if (scanf("%20lf", value) == 0)
+    {
+        if (scanf("%*[^\n]%*c") != 0)
+        {
+            printf("ERROR: Reading the input line error.\n");
+            return -1;
+        }
+        printf("ERROR: Incorrect input.\n");
+        return -1;
+    }
+    scanf("%*[^\n]%*c");
+
+    return (*value < min_value || *value > max_value ? -1 : 0);
+}
+
+bool show_confirm_dialog(const char *title)
+{
+    const int options[2] = {1, 2};
+    const char *names[2] = { "No", "Yes" };
+
+    bool answer = false;
+
+    int sel = -1;
+    while (sel == -1)
+    {
+        sel = show_menu(title, options, names, 2);
+        switch (sel)
+        {
+            case 1:
+                answer = false;
+                break;
+            case 2:
+                answer = true;
+                break;
+            default:
+                sel = -1;
+                printf("ERROR: Incorrect input.\n");
+                continue;
+        }
+    }
+
+    return answer;
+}
+
+int show_menu(
+        const char *title,
+        const int *options,
+        const char **names,
+        int number_of_option)
+{
+    if (NULL == title || NULL == options || NULL == names || 0 >= number_of_option)
+    {
+        return -1;
+    }
+
+    int number_size = 1;
+
+    int tn_counter = number_of_option;
+    while(tn_counter/=10)
+    {
+        ++number_size;
+    }
+
+    int max_len = strlen(title) - number_size - 2;
+
+    int i = 0;
+    for (i = 0; i < number_of_option; ++i)
+    {
+        const int temp_len = strlen(names[i]);
+        if (max_len < temp_len)
+        {
+            max_len = temp_len;
+        }
+    }
+
+    const int full_size = number_size + 2 + max_len;
+
+    printf("\n**");
+    for (i = 0; i < full_size; ++i)
+    {
+        printf("*");
+    }
+    printf("**\n");
+
+    printf("* %-*s *\n", full_size, title);
+
+    printf("*-");
+    for (i = 0; i < full_size; ++i)
+    {
+        printf("-");
+    }
+    printf("-*\n");
+
+    for (i = 0; i < number_of_option; ++i)
+    {
+        printf("* %0*i. %-*s *\n", number_size, options[i], max_len, names[i]);
+    }
+
+    printf("**");
+    for (i = 0; i < full_size; ++i)
+    {
+        printf("*");
+    }
+    printf("**\n\n");
+
+    int selection = 0;
+    printf("Your choice: ");
+    if (scanf("%25i", &selection) == 0)
+    {
+        if (scanf("%*[^\n]%*c") != 0)
+        {
+            printf("ERROR: Reading the input line error.\n");
+        }
+
+        printf("ERROR: Incorrect input.\n");
+        return -1;
+    }
+    scanf("%*[^\n]%*c");
+
+    return selection;
+}
+
+int load_mv_source_from_file(
+        const char *path_to_image,
+        mv_source_h source)
+{
+    unsigned char *data_buffer = NULL;
+    unsigned long buffer_size = 0;
+    image_data_s image_data;
+
+    int err = load_image_to_buffer(path_to_image, &data_buffer,
+                                   &buffer_size, &image_data);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during opening file!!! code: %i\n",
+               err);
+        if (NULL != data_buffer)
+        {
+            free(data_buffer);
+        }
+
+        return err;
+    }
+
+    err = mv_source_fill_by_buffer(
+                source, data_buffer,
+                buffer_size,
+                image_data.image_width,
+                image_data.image_height,
+                image_data.image_colorspace);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during filling source!!! code %i\n",
+               err);
+    }
+
+    if (NULL != data_buffer)
+    {
+        free(data_buffer);
+    }
+
+    return err;
+}
diff --git a/test/testsuites/common/testsuite_common/mv_testsuite_common.h b/test/testsuites/common/testsuite_common/mv_testsuite_common.h
new file mode 100644 (file)
index 0000000..f159dd0
--- /dev/null
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MV_TESTSUITE_COMMON_H__
+#define __MV_TESTSUITE_COMMON_H__
+
+#include "mv_common.h"
+
+#include <stddef.h>
+
+typedef enum
+{
+    FAIL_OR_SUCCESSS,
+    FAIL_OR_DONE
+} notification_type_e;
+
+/**
+ * @brief Prints success result of action.
+ *
+ * @since_tizen 3.0
+ * @param [in] action_name           Name of action which result will be printed
+ * @param [in] action_return_value   Return value of action
+ */
+void print_fail_result(
+        const char *action_name,
+        int action_return_value);
+
+/**
+ * @brief Prints success result of action.
+ *
+ * @since_tizen 3.0
+ * @param [in] action_name           Name of action which result will be printed
+ */
+void print_done_result(const char *action_name);
+
+/**
+ * @brief Prints success result of action.
+ *
+ * @since_tizen 3.0
+ * @param [in] action_name           Name of action which result will be printed
+ */
+void print_success_result(const char *action_name);
+
+/**
+ * @brief Prints action result.
+ *
+ * @since_tizen 3.0
+ * @param [in] action_name           Name of action which result will be printed
+ * @param [in] action_return_value   Return value of action
+ * @param [in] notification_type_e   Type of notification
+ */
+void print_action_result(
+        const char *action_name,
+        int action_return_value,
+        notification_type_e notification_type_e);
+
+/**
+ * @brief Gets srting from console.
+ *
+ * @since_tizen 3.0
+ * @param [in] prompt     The prompt before getting string value
+ * @param [in] max_len    Maximum length of the string which will be got
+ * @param [out] string    Output string which was got from console
+ * @return Length of the output string on success, otherwise a negative error value
+ */
+int input_string(const char *prompt, size_t max_len, char **string);
+
+/**
+ * @brief Gets unsigned integer from console.
+ *
+ * @since_tizen 3.0
+ * @param [in] prompt      The prompt before getting unsigned integer value
+ * @param [in] max_size    The thresold for maximum possible value
+ * @param [out] size       The output unsigned integer which was got from console
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int input_size(const char *prompt, size_t max_size, size_t *size);
+
+/**
+ * @brief Gets integer from console.
+ *
+ * @since_tizen 3.0
+ * @param [in] prompt       The prompt before getting integer value
+ * @param [in] min_value    The thresold for minimum possible value
+ * @param [in] max_value    The thresold for maximum possible value
+ * @param [out] value       The output integer which was got from console
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int input_int(const char *prompt, int min_value, int max_value, int *value);
+
+/**
+ * @brief Gets double from console.
+ *
+ * @since_tizen 3.0
+ * @param [in] prompt       The prompt before getting double value
+ * @param [in] min_value    The thresold for minimum possible value
+ * @param [in] max_value    The thresold for maximum possible value
+ * @param [out] value       The output double which was got from console
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int input_double(const char *prompt, double min_value, double max_value, double *value);
+
+/**
+ * @brief Shows confirm dialog in console and gets answer (Yes/No).
+ *
+ * @since_tizen 3.0
+ * @param [in] title    The title for confirm dialog which will be printed
+ *                      before input of the answer
+ * @return false if answer is "No" and true if answer is "Yes"
+ */
+bool show_confirm_dialog(const char *title);
+
+/**
+ * @brief Shows menu in console and allows to get item from the array of options.
+ *
+ * @since_tizen 3.0
+ * @param [in] title               The title for show menu which will be printed
+ *                                 before options
+ * @param [in] options             The array with integer numbers of options
+ *                                 which will be shown
+ * @param [in] names               The array with names of options which will
+ *                                 be shown
+ * @param [in] number_of_option    The number of options which will be shown
+ * @return The selected item positive number from options array on success,
+ *         otherwise a negative error value
+ */
+int show_menu(
+        const char *title,
+        const int *options,
+        const char **names,
+        int number_of_option);
+
+/**
+ * @brief Loads media source from JPEG image.
+ *
+ * @since_tizen 3.0
+ * @param [in] path_to_image    The path to JPEG image which will be loaded
+ * @param [in/out] source       The hadler to media source which will be filled
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int load_mv_source_from_file(
+        const char *path_to_image,
+        mv_source_h source);
+
+#endif /* __MV_TESTSUITE_COMMON_H__ */
diff --git a/test/testsuites/common/video_helper/CMakeLists.txt b/test/testsuites/common/video_helper/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9eaa1e7
--- /dev/null
@@ -0,0 +1,25 @@
+SET (pkgname mv_video_helper)
+PROJECT(${pkgname})
+
+cmake_minimum_required(VERSION 2.6)
+
+SET(INC_DIR include)
+INCLUDE_DIRECTORIES(${INC_DIR})
+include_directories(${INC_IMAGE_HELPER})
+
+SET(dependents "gstreamer-1.0 gstreamer-app-1.0 dlog")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${pkgname} REQUIRED ${dependents})
+FOREACH(flag ${${pkgname}_CFLAGS})
+  SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+ADD_LIBRARY(${pkgname} SHARED "mv_video_helper.c" "mv_video_helper.h")
+
+TARGET_LINK_LIBRARIES(${pkgname} ${${pkgname}_LDFLAGS} gstvideo-1.0)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/test/testsuites/common/video_helper/mv_log_cfg.h b/test/testsuites/common/video_helper/mv_log_cfg.h
new file mode 100644 (file)
index 0000000..cb6e0a3
--- /dev/null
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MV_LOG_CFG_H__
+#define __MV_LOG_CFG_H__
+
+#include <dlog.h>
+
+//#define ROOTSTRAP_OUT // enables logs to console
+
+#define TEXT_RED     "\x1b[31m"
+#define TEXT_GREEN   "\x1b[32m"
+#define TEXT_YELLOW  "\x1b[33m"
+#define TEXT_BLUE    "\x1b[34m"
+#define TEXT_MAGENTA "\x1b[35m"
+#define TEXT_CYAN    "\x1b[36m"
+#define TEXT_RESET   "\x1b[0m"
+
+#ifdef ROOTSTRAP_OUT
+
+#define LOGD(...)                                 \
+do                                                \
+{                                                 \
+    printf("<%s:%d>", __FUNCTION__, __LINE__);    \
+    printf(TEXT_CYAN);                            \
+    printf(__VA_ARGS__);                          \
+    printf(TEXT_RESET "\n");                      \
+} while(0)
+
+#define LOGI(...)                                 \
+do                                                \
+{                                                 \
+    printf("<%s:%d>", __FUNCTION__, __LINE__);    \
+    printf(TEXT_GREEN);                           \
+    printf(__VA_ARGS__);                          \
+    printf(TEXT_RESET "\n");                      \
+} while(0)
+
+#define LOGW(...)                                 \
+do                                                \
+{                                                 \
+    printf("<%s:%d>", __FUNCTION__, __LINE__);    \
+    printf(TEXT_YELLOW);                          \
+    printf(__VA_ARGS__);                          \
+    printf(TEXT_RESET "\n");                      \
+} while(0)
+
+#define LOGE(...)                                 \
+do                                                \
+{                                                 \
+    printf("<%s:%d>", __FUNCTION__, __LINE__);    \
+    printf(TEXT_RED);                             \
+    printf(__VA_ARGS__);                          \
+    printf(TEXT_RESET "\n");                      \
+} while(0)
+
+#endif
+
+#endif /* __MV_LOG_CFG_H__ */
diff --git a/test/testsuites/common/video_helper/mv_video_helper.c b/test/testsuites/common/video_helper/mv_video_helper.c
new file mode 100644 (file)
index 0000000..7674d91
--- /dev/null
@@ -0,0 +1,926 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_common.h"
+#include "mv_video_helper.h"
+
+#include "mv_log_cfg.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#include <gst/gst.h>
+#include <gst/app/gstappsink.h>
+#include <gst/video/video.h>
+
+#include <pthread.h>
+
+typedef struct _mv_video_reader_s
+{
+    /* Main bin */
+    GstElement *pl;
+
+    /* Pipeline structure */
+    GstElement *filesrc;
+    GstElement *decodebin;
+    GstElement *videoconvert;
+    GstElement *appsink;
+
+    void *new_sample_cb_user_data;
+    void *eos_cb_user_data;
+
+    GstCaps *caps;
+
+    pthread_spinlock_t new_sample_cb_guard;
+    pthread_spinlock_t eos_cb_guard;
+
+    mv_video_reader_new_sample_cb new_sample_cb;
+    mv_video_reader_eos_cb eos_cb;
+} mv_video_reader_s;
+
+typedef struct _mv_video_writer_s
+{
+    /* Main bin */
+    GstElement *pl;
+
+    /* Pipeline structure */
+    GstElement *appsrc;
+    GstElement *capsfilter;
+    GstElement *videoconvert;
+    GstElement *encoder;
+    GstElement *queue;
+    GstElement *muxer;
+    GstElement *filesink;
+
+    image_data_s image_data;
+    unsigned int fps;
+    unsigned int buffer_size;
+} mv_video_writer_s;
+
+/* video reader internal funcitons */
+static int _mv_video_reader_create_internals(mv_video_reader_s *reader);
+static int _mv_video_reader_link_internals(mv_video_reader_s *reader);
+static int _mv_video_reader_state_change(mv_video_reader_s *reader, GstState state);
+
+/* video writer internal funciton */
+static int _mv_video_writer_create_internals(mv_video_writer_s *writer);
+static int _mv_video_writer_link_internals(mv_video_writer_s *writer);
+static int _mv_video_writer_state_change(mv_video_writer_s *writer, GstState state);
+
+static void appsink_eos(GstAppSink *appsink, gpointer user_data);
+static GstFlowReturn appsink_newsample(GstAppSink *appsink, gpointer user_data);
+static void cb_newpad(GstElement *decodebin, GstPad *new_pad, gpointer user_data);
+
+/* video reader */
+int mv_create_video_reader(
+        mv_video_reader_h *reader)
+{
+    mv_video_reader_s *handle = NULL;
+    int err = MEDIA_VISION_ERROR_NONE;
+
+    if (reader == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    gst_init(NULL, NULL);
+
+    handle = (mv_video_reader_s *) malloc(sizeof(mv_video_reader_s));
+    if (!handle)
+    {
+        LOGE("Not enough memory");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+    memset(handle, 0, sizeof(mv_video_reader_s));
+
+    err = _mv_video_reader_create_internals(handle);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        LOGE("Failed to create internals");
+        free(handle);
+        return err;
+    }
+
+    err = _mv_video_reader_link_internals(handle);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        LOGE("Failed to link internals");
+        free(handle);
+        return err;
+    }
+
+    *reader = (mv_video_reader_s *) handle;
+
+    return err;
+}
+
+int mv_destroy_video_reader(
+        mv_video_reader_h reader)
+{
+    mv_video_reader_s *handle = NULL;
+
+    if (reader == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_reader_s *) reader;
+
+    if (handle->caps && GST_OBJECT_REFCOUNT(handle->caps))
+    {
+        gst_caps_unref(handle->caps);
+    }
+
+    if (handle->pl)
+    {
+        gst_object_unref(handle->pl);
+    }
+    handle->pl = NULL;
+
+    pthread_spin_destroy(&(handle->new_sample_cb_guard));
+    pthread_spin_destroy(&(handle->eos_cb_guard));
+
+    LOGD("video reader destroyed %p", handle);
+
+    free(handle);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_video_reader_load(
+        mv_video_reader_h reader,
+        const char *path,
+        image_data_s *image_data,
+        unsigned int *fps)
+{
+    mv_video_reader_s *handle = NULL;
+    GstVideoInfo info;
+
+    if (reader == NULL || path == NULL ||
+        image_data == NULL || fps == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_reader_s *) reader;
+
+    /* Set input file location from path */
+    g_object_set(G_OBJECT(handle->filesrc),
+                 "location", path,
+                 NULL);
+
+    /* Start playback */
+    if (_mv_video_reader_state_change(handle, GST_STATE_PLAYING))
+    {
+        LOGE("Unable to change state");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    if (_mv_video_reader_state_change(handle, GST_STATE_PAUSED))
+    {
+        LOGE("Unable to change state");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    if (handle->caps == NULL)
+    {
+        LOGE("Unable to get caps from decodebin");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    gst_video_info_from_caps(&info, handle->caps);
+    gst_caps_unref(handle->caps);
+
+    *fps = info.fps_n/info.fps_d;
+
+    /* Fill image data */
+    image_data->image_width = info.width;
+    image_data->image_height = info.height;
+
+    /* Look to :
+     * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#GstVideoFormat */
+    switch(GST_VIDEO_FORMAT_INFO_FORMAT(info.finfo))
+    {
+        case(GST_VIDEO_FORMAT_GRAY8):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_Y800;
+            break;
+        case(GST_VIDEO_FORMAT_I420):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_I420;
+            break;
+        case(GST_VIDEO_FORMAT_NV12):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_NV12;
+            break;
+        case(GST_VIDEO_FORMAT_YV12):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_YV12;
+            break;
+        case(GST_VIDEO_FORMAT_NV21):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_NV21;
+            break;
+        case(GST_VIDEO_FORMAT_YUY2):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_YUYV;
+            break;
+        case(GST_VIDEO_FORMAT_UYVY):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_UYVY;
+            break;
+        case(GST_VIDEO_FORMAT_RGB):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_RGB888;
+            break;
+        case(GST_VIDEO_FORMAT_RGBA):
+            image_data->image_colorspace = MEDIA_VISION_COLORSPACE_RGBA;
+            break;
+        default:
+            LOGE("Video pixel format is not supported\n");
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_video_reader_start(
+        mv_video_reader_h reader)
+{
+    mv_video_reader_s *handle = NULL;
+
+    if (reader == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_reader_s *) reader;
+
+    /* Start playback */
+    if (_mv_video_reader_state_change(handle, GST_STATE_PLAYING))
+    {
+        LOGE("Unable to change state");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_video_reader_stop(
+        mv_video_reader_h reader)
+{
+    mv_video_reader_s *handle = NULL;
+
+    if (reader == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_reader_s *) reader;
+
+    /* Stop playback (NULL or READY) */
+    if (_mv_video_reader_state_change(handle, GST_STATE_NULL))
+    {
+        LOGE("Unable to change state");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_video_reader_set_new_sample_cb(
+        mv_video_reader_h reader,
+        mv_video_reader_new_sample_cb callback,
+        void *user_data)
+{
+    mv_video_reader_s *handle = NULL;
+
+    if (reader == NULL || callback == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_reader_s *) reader;
+
+    pthread_spin_lock(&(handle->new_sample_cb_guard));
+    handle->new_sample_cb = callback;
+    handle->new_sample_cb_user_data = user_data;
+    pthread_spin_unlock(&(handle->new_sample_cb_guard));
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_video_reader_set_eos_cb(
+        mv_video_reader_h reader,
+        mv_video_reader_eos_cb callback,
+        void *user_data)
+{
+    mv_video_reader_s *handle = NULL;
+
+    if (reader == NULL || callback == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_reader_s *) reader;
+
+    pthread_spin_lock(&(handle->eos_cb_guard));
+    handle->eos_cb = callback;
+    handle->eos_cb_user_data = user_data;
+    pthread_spin_unlock(&(handle->eos_cb_guard));
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+/* Video Writer */
+int mv_create_video_writer(
+        mv_video_writer_h *writer)
+{
+    mv_video_writer_s *handle = NULL;
+    int err = MEDIA_VISION_ERROR_NONE;
+
+    if (writer == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    gst_init(NULL, NULL);
+
+    handle = (mv_video_writer_s *) malloc(sizeof(mv_video_writer_s));
+    if (!handle)
+    {
+        LOGE("Not enough memory");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+    memset(handle, 0, sizeof(mv_video_writer_s));
+
+    err = _mv_video_writer_create_internals(handle);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        LOGE("Failed to create internals");
+        free(handle);
+        return err;
+    }
+
+    *writer = (mv_video_writer_s *) handle;
+
+    return err;
+}
+
+int mv_destroy_video_writer(
+        mv_video_writer_h writer)
+{
+    mv_video_writer_s *handle = NULL;
+
+    if (writer == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_writer_s *) writer;
+
+    _mv_video_writer_state_change(writer, GST_STATE_NULL);
+
+    if (handle->pl)
+    {
+        gst_object_unref(handle->pl);
+    }
+    handle->pl = NULL;
+
+    LOGD("video writer destroyed %p", handle);
+
+    free(handle);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_video_writer_init(
+        mv_video_writer_h writer,
+        const char *path,
+        image_data_s image_data,
+        unsigned int fps)
+{
+    mv_video_writer_s *handle = NULL;
+    unsigned int err = MEDIA_VISION_ERROR_NONE;
+
+    if (writer == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_writer_s *) writer;
+
+    handle->image_data.image_width = image_data.image_width;
+    handle->image_data.image_height = image_data.image_height;
+    handle->image_data.image_colorspace = image_data.image_colorspace;
+
+    handle->fps = fps;
+
+    g_object_set(G_OBJECT(handle->filesink),
+                     "location", path,
+                     NULL);
+
+    err = _mv_video_writer_link_internals(handle);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        LOGE("Failed to link internals");
+        return err;
+    }
+
+    return err;
+}
+
+int mv_video_writer_write_frame(
+        mv_video_writer_h writer,
+        unsigned char *frame)
+{
+    mv_video_writer_s *handle = NULL;
+    GstMapInfo info;
+    GstBuffer *buffer = NULL;
+
+    if (writer == NULL || frame == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    handle = (mv_video_writer_s *) writer;
+
+    buffer =  gst_buffer_new_allocate(NULL, handle->buffer_size, NULL);
+    if (!buffer)
+    {
+        LOGE("Unable to allocate buffer for frame");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    LOGD("Copying input frame to buffer and pushing to appsrc");
+    gst_buffer_map(buffer, &info, GST_MAP_READWRITE);
+    memcpy(info.data, frame, info.size);
+    gst_buffer_unmap(buffer, &info);
+
+    if (GST_FLOW_OK !=
+        gst_app_src_push_buffer(handle->appsrc, buffer))
+    {
+        LOGE("Failed to push buffer to appsrc");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+/* Internal functions */
+static int _mv_video_reader_create_internals(
+        mv_video_reader_s *reader)
+{
+    pthread_spin_init(&(reader->new_sample_cb_guard), PTHREAD_PROCESS_SHARED);
+    pthread_spin_init(&(reader->eos_cb_guard), PTHREAD_PROCESS_SHARED);
+
+    reader->pl = gst_pipeline_new(NULL);
+
+    reader->filesrc = gst_element_factory_make("filesrc", "filesrc");
+    reader->decodebin = gst_element_factory_make("decodebin", "decoder");
+    reader->videoconvert = gst_element_factory_make("videoconvert", "convert");
+    reader->appsink = gst_element_factory_make("appsink", "appsink");
+
+    if ((!reader->pl) ||
+        (!reader->filesrc) ||
+        (!reader->decodebin) ||
+        (!reader->videoconvert) ||
+        (!reader->appsink))
+    {
+        LOGE("Unable to create video read pipeline elements");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    gst_bin_add_many(GST_BIN(reader->pl),
+                     reader->filesrc,
+                     reader->decodebin,
+                     reader->videoconvert,
+                     reader->appsink,
+                     NULL);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+static int _mv_video_reader_link_internals(
+        mv_video_reader_s *reader)
+{
+    GstCaps *caps = NULL;
+
+    if (!gst_element_link_many(reader->filesrc,
+                               reader->decodebin,
+                               NULL))
+    {
+        LOGE("Unable to link filesrc to decodebin");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    /* Decodebin pad will be linked during state change */
+    g_signal_connect(reader->decodebin,
+                     "pad-added",
+                     G_CALLBACK(cb_newpad),
+                     reader);
+
+    if (!gst_element_link_many(reader->videoconvert,
+            reader->appsink, NULL))
+    {
+        LOGE("Unable to link filesrc to decodebin");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    caps = gst_caps_new_simple("video/x-raw",
+                               "format", G_TYPE_STRING, "RGB",
+                                NULL);
+
+    gst_app_sink_set_caps(GST_APP_SINK(reader->appsink), caps);
+    gst_caps_unref(caps);
+
+    /* Configure appsink */
+    gst_app_sink_set_emit_signals(GST_APP_SINK(reader->appsink), TRUE);
+    g_signal_connect(reader->appsink,
+                     "new-sample",
+                     G_CALLBACK(appsink_newsample),
+                     reader);
+    g_signal_connect(reader->appsink,
+                     "eos",
+                     G_CALLBACK(appsink_eos),
+                     reader);
+    g_object_set(G_OBJECT(reader->appsink),
+                 "drop", TRUE,
+                 "enable-last-sample", TRUE,
+                 "sync", FALSE,
+                 NULL);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+static int _mv_video_reader_state_change(
+        mv_video_reader_s *reader,
+        GstState state)
+{
+    mv_video_reader_s *handle = (mv_video_reader_s *) reader;
+    GstStateChangeReturn state_ret = GST_STATE_CHANGE_FAILURE;
+    GstState pipeline_state = GST_STATE_NULL;
+
+    state_ret = gst_element_set_state(handle->pl,
+                                      state);
+
+    if (GST_STATE_CHANGE_FAILURE == state_ret)
+    {
+        LOGE("Set state failure");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    LOGI("Set state [%d], change return [%d]",
+         state, state_ret);
+
+    state_ret = gst_element_get_state(handle->pl,
+                                      &pipeline_state,
+                                      NULL,
+                                      GST_CLOCK_TIME_NONE);
+
+    if (GST_STATE_CHANGE_FAILURE == state_ret)
+    {
+        LOGE("get state failure");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+static int _mv_video_writer_create_internals(
+        mv_video_writer_s *writer)
+{
+    writer->pl = gst_pipeline_new(NULL);
+
+    writer->appsrc = gst_element_factory_make("appsrc", "appsrc");
+    writer->capsfilter = gst_element_factory_make("capsfilter", NULL);
+    writer->videoconvert = gst_element_factory_make("videoconvert", "videoconvert");
+    writer->encoder = gst_element_factory_make("avenc_mpeg4", "encoder");
+    writer->queue = gst_element_factory_make("queue", "queue");
+    writer->muxer = gst_element_factory_make("avmux_avi", "muxer");
+    writer->filesink = gst_element_factory_make("filesink", "filesink");
+
+    if ((!writer->pl) ||
+        (!writer->appsrc) ||
+        (!writer->capsfilter) ||
+        (!writer->videoconvert) ||
+        (!writer->encoder) ||
+        (!writer->queue) ||
+        (!writer->muxer) ||
+        (!writer->filesink))
+    {
+        LOGE("Unable to create video read pipeline elements\n");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    gst_bin_add_many(GST_BIN(writer->pl),
+                     writer->appsrc,
+                     writer->capsfilter,
+                     writer->videoconvert,
+                     writer->encoder,
+                     writer->queue,
+                     writer->muxer,
+                     writer->filesink,
+                     NULL);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+static int _mv_video_writer_link_internals(
+        mv_video_writer_s *writer)
+{
+    GstVideoInfo vinfo;
+    GstCaps *caps = NULL;
+    char format[6] = {0};
+
+    /* Convert from mv_colorspace to GstVideoFormat */
+    switch(writer->image_data.image_colorspace)
+    {
+        case(MEDIA_VISION_COLORSPACE_Y800):
+            strncpy(format, "GRAY8", 5);
+            break;
+        case(MEDIA_VISION_COLORSPACE_I420):
+            strncpy(format, "I420", 4);
+            break;
+        case(MEDIA_VISION_COLORSPACE_NV12):
+            strncpy(format, "NV12", 4);
+            break;
+        case(MEDIA_VISION_COLORSPACE_YV12):
+            strncpy(format, "YV12", 4);
+            break;
+        case(MEDIA_VISION_COLORSPACE_NV21):
+            strncpy(format, "NV21", 4);
+            break;
+        case(MEDIA_VISION_COLORSPACE_YUYV):
+            strncpy(format, "YUY2", 4);
+            break;
+        case(MEDIA_VISION_COLORSPACE_UYVY):
+            strncpy(format, "UYVY", 4);
+            break;
+        case(MEDIA_VISION_COLORSPACE_RGB888):
+            strncpy(format, "RGB", 3);
+            break;
+        case(MEDIA_VISION_COLORSPACE_RGBA):
+            strncpy(format, "RGBA", 4);
+            break;
+        default:
+            LOGE("Selected format %d is not supported",
+                 writer->image_data.image_colorspace);
+            return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+    }
+
+    caps = gst_caps_new_simple("video/x-raw",
+                               "format", G_TYPE_STRING, format,
+                               "width", G_TYPE_INT, writer->image_data.image_width,
+                               "height", G_TYPE_INT, writer->image_data.image_height,
+                               "framerate", GST_TYPE_FRACTION, writer->fps, 1,
+                               NULL);
+
+    if (NULL == caps)
+    {
+        LOGE("Failed to create new caps");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    /* This is the simpler way to get buffer size */
+    if (!gst_video_info_from_caps(&vinfo, caps))
+    {
+        LOGE("Unable to set buffer size");
+        gst_caps_unref(caps);
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    writer->buffer_size = vinfo.size;
+
+    /* link appsrc and capsfilter */
+    if ((!gst_element_link_filtered(writer->appsrc,
+                                    writer->capsfilter,
+                                    caps)))
+    {
+        LOGE("Failed to link appsrc to capsfilter");
+        gst_caps_unref(caps);
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+    gst_caps_unref(caps);
+
+    if (!gst_element_link_many(writer->capsfilter,
+                               writer->videoconvert,
+                               writer->encoder,
+                               writer->queue,
+                               writer->muxer,
+                               writer->filesink,
+                               NULL))
+    {
+        LOGE("Unable to capsfilter to filesink");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    g_object_set(G_OBJECT(writer->appsrc),
+                 "max-bytes", 0,
+                 "blocksize", writer->buffer_size,
+                 "stream-type", 0,
+                 "format", GST_FORMAT_BYTES,
+                 NULL);
+
+    if (_mv_video_writer_state_change(writer,
+                                      GST_STATE_PLAYING))
+    {
+        LOGE("Unable to change video writer state");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+static int _mv_video_writer_state_change(
+        mv_video_writer_s *writer,
+        GstState state)
+{
+    mv_video_writer_s *handle = (mv_video_writer_s *) writer;
+    GstStateChangeReturn state_ret = GST_STATE_CHANGE_FAILURE;
+    GstState pipeline_state = GST_STATE_NULL;
+
+    state_ret = gst_element_set_state(handle->pl,
+                                      state);
+
+    if (GST_STATE_CHANGE_FAILURE == state_ret)
+    {
+        LOGE("Set state failure");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    LOGI("Set state [%d], change return [%d]",
+         state, state_ret);
+
+    /* AppSrc can't go to PLAYING state before buffer is not pushed */
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+/* Callbacks */
+static GstFlowReturn appsink_newsample(
+        GstAppSink *appsink,
+        gpointer user_data)
+{
+    mv_video_reader_s *handle = NULL;
+    GstSample *sample = gst_app_sink_pull_sample(appsink);
+
+    if (user_data == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    if (sample != NULL)
+    {
+        handle = (mv_video_reader_s *) user_data;
+        GstVideoInfo vinfo;
+        GstMapInfo info = GST_MAP_INFO_INIT;
+        GstBuffer *buf = gst_sample_get_buffer(sample);
+        GstCaps *caps = gst_sample_get_caps(sample);
+        image_data_s im_data;
+        char *buffer = NULL;
+        unsigned int buffer_size = 0;
+
+        LOGD("Received sample from appsink");
+
+        /* map buffer */
+        gst_buffer_map(buf, &info, GST_MAP_READ);
+        buffer = (char *) info.data;
+
+        /* Fill image data */
+        gst_video_info_from_caps(&vinfo, caps);
+        im_data.image_width = vinfo.width;
+        im_data.image_height = vinfo.height;
+
+        /* Look to :
+        * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#GstVideoFormat */
+        switch(GST_VIDEO_FORMAT_INFO_FORMAT(vinfo.finfo))
+        {
+            case(GST_VIDEO_FORMAT_GRAY8):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_Y800;
+                break;
+            case(GST_VIDEO_FORMAT_I420):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_I420;
+                break;
+            case(GST_VIDEO_FORMAT_NV12):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_NV12;
+                break;
+            case(GST_VIDEO_FORMAT_YV12):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_YV12;
+                break;
+            case(GST_VIDEO_FORMAT_NV21):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_NV21;
+                break;
+            case(GST_VIDEO_FORMAT_YUY2):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_YUYV;
+                break;
+            case(GST_VIDEO_FORMAT_UYVY):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_UYVY;
+                break;
+            case(GST_VIDEO_FORMAT_RGB):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_RGB888;
+                break;
+            case(GST_VIDEO_FORMAT_RGBA):
+                im_data.image_colorspace = MEDIA_VISION_COLORSPACE_RGBA;
+                break;
+            default:
+                LOGE("Video pixel format is not supported\n");
+
+                gst_buffer_unmap(buf, &info);
+                gst_sample_unref(sample);
+                return GST_FLOW_ERROR;
+        }
+
+        pthread_spin_lock(&(handle->new_sample_cb_guard));
+        if (handle->new_sample_cb != NULL)
+        {
+            handle->new_sample_cb(
+                    buffer,
+                    info.size,
+                    im_data,
+                    handle->new_sample_cb_user_data);
+        }
+        pthread_spin_unlock(&(handle->new_sample_cb_guard));
+
+        gst_buffer_unmap(buf, &info);
+        gst_sample_unref(sample);
+    }
+    else
+    {
+        LOGE("Failed to pull sample from appsink");
+        return GST_FLOW_ERROR;
+    }
+
+    return GST_FLOW_OK;
+}
+
+static void appsink_eos(
+        GstAppSink *appsink,
+        gpointer user_data)
+{
+    if (user_data == NULL)
+    {
+        LOGE("NULL pointer passed");
+        return;
+    }
+
+    mv_video_reader_s *handle = (mv_video_reader_s *) user_data;
+
+    /* EOS callback to terminate reading */
+    pthread_spin_lock(&(handle->eos_cb_guard));
+    if (handle->eos_cb != NULL)
+    {
+        handle->eos_cb(handle->eos_cb_user_data);
+    }
+    pthread_spin_unlock(&(handle->eos_cb_guard));
+}
+
+static void cb_newpad(
+        GstElement *decodebin,
+        GstPad *pad,
+        gpointer user_data)
+{
+    mv_video_reader_s *reader = (mv_video_reader_s *) user_data;
+    GstStructure *str = NULL;
+    GstCaps *caps = NULL;
+    GstPad *video_pad = NULL;
+
+    LOGI("Received pad from decodebin. Linking");
+    video_pad = gst_element_get_static_pad(reader->videoconvert, "sink");
+    if (GST_PAD_IS_LINKED(video_pad))
+    {
+        LOGI("Already linked");
+        g_object_unref(video_pad);
+        return;
+    }
+
+    /* Check for pad is video */
+    reader->caps = gst_pad_query_caps(pad, NULL);
+    str = gst_caps_get_structure(reader->caps, 0);
+    if (!g_strrstr(gst_structure_get_name(str), "video"))
+    {
+        LOGI("Not a video pad");
+        gst_object_unref(video_pad);
+        return;
+    }
+
+    gst_pad_link(pad, video_pad);
+    g_object_unref(video_pad);
+}
diff --git a/test/testsuites/common/video_helper/mv_video_helper.h b/test/testsuites/common/video_helper/mv_video_helper.h
new file mode 100644 (file)
index 0000000..b22c11e
--- /dev/null
@@ -0,0 +1,277 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MV_VIDEO_HELPER_H__
+#define __MV_VIDEO_HELPER_H__
+
+#include "mv_common.h"
+#include "image_helper.h"
+
+/**
+ * @brief The handle to the video reader.
+ *
+ * @since_tizen 3.0
+ */
+typedef void *mv_video_reader_h;
+
+/**
+ * @brief The handle to the video writer.
+ *
+ * @since_tizen 3.0
+ */
+typedef void *mv_video_writer_h;
+
+/**
+ * @brief Called when new sample is available from video reader.
+ *
+ * @since_tizen 3.0
+ * @remarks You don't need release @a buffer independently
+ * @param [in] buffer            Raw video buffer
+ * @param [in] buffer_size       Size of video buffer
+ * @param [in] image_data        Image data for corresponding video buffer
+ * @param [in] user_data         User data
+ *
+ * @pre Create a reader handle by calling mv_video_reader_create()
+ * @pre Set callback by calling mv_video_reader_set_new_sample_cb()
+ *
+ * @see mv_video_reader_set_new_sample_cb()
+ */
+typedef void (*mv_video_reader_new_sample_cb) (
+        char *buffer,
+        unsigned int buffer_size,
+        image_data_s image_data,
+        void *user_data);
+
+/**
+ * @brief Called when stream from video reader is finished.
+ *
+ * @since_tizen 3.0
+ * @param [in] user_data         User data
+ *
+ * @pre Create a reader handle by calling mv_video_reader_create()
+ * @pre Set callback by calling mv_video_reader_set_eos_cb()
+ *
+ * @see mv_video_reader_set_eos_cb()
+ */
+typedef void (*mv_video_reader_eos_cb) (
+        void *user_data);
+
+/**
+ * @brief Creates a video reader handle.
+ *
+ * @since_tizen 3.0
+ * @remarks You must release @a reader by using @ref mv_destroy_video_reader().
+ * @param [out] reader    A new handle to the video reader
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @see mv_destroy_video_reader()
+ */
+int mv_create_video_reader(
+        mv_video_reader_h *reader);
+
+/**
+ * @brief Destroys the video reader handle and releases all its resources.
+ *
+ * @since_tizen 3.0
+ * @param [in] reader    The handle to the video reader to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_create_video_reader()
+ */
+int mv_destroy_video_reader(
+        mv_video_reader_h reader);
+
+/**
+ * @brief Loads video from file.
+ *
+ * @since_tizen 3.0
+ * @param [in]  reader      The handle to the video reader
+ * @param [in]  path        Path to the video file to be loaded
+ * @param [out] image_data  Image data for corresponding video buffer
+ * @param [out] fps         Frame per second of corresponding video file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported video format
+ *
+ * @pre Create a video reader handle by calling @ref mv_create_video_reader()
+ */
+int mv_video_reader_load(
+        mv_video_reader_h reader,
+        const char *path,
+        image_data_s *image_data,
+        unsigned int *fps);
+
+/**
+ * @brief Starts reader playback.
+ *
+ * @since_tizen 3.0
+ * @param [in] reader       The handle to the video reader
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a video reader handle by calling @ref mv_create_video_reader()
+ *      and call @ref mv_video_reader_load()
+ *
+ * @post Stop reader playback by calling @ref mv_video_reader_stop()
+ */
+int mv_video_reader_start(
+        mv_video_reader_h reader);
+
+/**
+ * @brief Stops reader playback.
+ *
+ * @since_tizen 3.0
+ * @param [in] reader       The handle to the video reader
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a video reader handle by calling @ref mv_create_video_reader()
+ *      and call @ref mv_video_reader_load()
+ */
+int mv_video_reader_stop(
+        mv_video_reader_h reader);
+
+/**
+ * @brief Sets new sample callback to video reader.
+ *
+ * @since_tizen 3.0
+ * @param [in] reader      The handle to the video reader
+ * @param [in] callback    Callback that will be called
+ * @param [in] user_data  User data
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create a video reader handle by calling @ref mv_create_video_reader()
+ *      and load video with @ref mv_video_reader_load()
+ *
+ * @see mv_create_video_reader()
+ * @see mv_video_reader_load()
+ *
+ */
+int mv_video_reader_set_new_sample_cb(
+    mv_video_reader_h reader,
+    mv_video_reader_new_sample_cb callback,
+    void *user_data);
+
+/**
+ * @brief Sets end of stream callback to video reader.
+ *
+ * @since_tizen 3.0
+ * @param [in] reader     The handle to the video reader
+ * @param [in] callback   Callback that will be called
+ * @param [in] user_data  User data
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create a video reader handle by calling @ref mv_create_video_reader()
+ *      and load video with @ref mv_video_reader_load()
+ *
+ * @see mv_create_video_reader()
+ * @see mv_video_reader_load()
+ *
+ */
+int mv_video_reader_set_eos_cb(
+    mv_video_reader_h reader,
+    mv_video_reader_eos_cb callback,
+    void *user_data);
+
+/**
+ * @brief Creates a video writer handle.
+ *
+ * @since_tizen 3.0
+ * @remarks You must release @a writer by using @ref mv_destroy_video_writer().
+ * @param [out] writer    A new handle to the video writer
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @see mv_destroy_video_writer()
+ */
+int mv_create_video_writer(
+        mv_video_writer_h *writer);
+
+/**
+ * @brief Destroys the video writer handle and releases all its resources.
+ *
+ * @since_tizen 3.0
+ * @param [in] writer    The handle to the video writer to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @see mv_create_video_writer()
+ */
+int mv_destroy_video_writer(
+        mv_video_writer_h writer);
+
+/**
+ * @brief Sets path and frame size for video file to be stored.
+ *
+ * @since_tizen 3.0
+ * @param [in] writer      The handle to the video writer
+ * @param [in] path        Path to the video file to be stored
+ * @param [in] image_data  Image data for corresponding video buffer
+ * @param [in] fps         Frame per second of resulted video file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported video format
+ *
+ * @pre Create a video writer handle by calling @ref mv_create_video_writer()
+ */
+int mv_video_writer_init(
+        mv_video_writer_h writer,
+        const char *path,
+        image_data_s image_data,
+        unsigned int fps);
+
+/**
+ * @brief   Writes consequently video frame to the file.
+ * @details After video writer was initialized this function consequently
+ *          writes frames to the file.
+ *
+ * @since_tizen 3.0
+ * @param [in] writer      The handle to the video writer
+ * @param [in] frame       Raw image buffer
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a video writer handle by calling @ref mv_create_video_writer()
+ *      and initialize video with @ref mv_video_writer_init()
+ */
+int mv_video_writer_write_frame(
+    mv_video_writer_h writer,
+    unsigned char *frame);
+
+#endif /* __MV_VIDEO_HELPER_H__ */
diff --git a/test/testsuites/face/CMakeLists.txt b/test/testsuites/face/CMakeLists.txt
new file mode 100644 (file)
index 0000000..aed6de7
--- /dev/null
@@ -0,0 +1,34 @@
+project(mv_face_test_suite)
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG    _DEBUG)
+
+if(NOT SKIP_WARNINGS)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories(${PROJECT_SOURCE_DIR})
+include_directories(${MV_CAPI_MEDIA_VISION_INC_DIR})
+include_directories(${INC_IMAGE_HELPER})
+include_directories(${INC_VIDEO_HELPER})
+include_directories(${INC_TS_COMMON})
+
+file(GLOB MV_FACE_TEST_SUITE_INC_LIST "${PROJECT_SOURCE_DIR}/*.h")
+file(GLOB MV_FACE_TEST_SUITE_SRC_LIST "${PROJECT_SOURCE_DIR}/*.c")
+
+add_executable(${PROJECT_NAME}
+               ${MV_FACE_TEST_SUITE_INC_LIST}
+               ${MV_FACE_TEST_SUITE_SRC_LIST}
+               ${MV_CAPI_MEDIA_VISION_INC_LIST})
+
+target_link_libraries(${PROJECT_NAME} capi-media-vision
+                                      dlog
+                                      mv_image_helper
+                                      mv_video_helper
+                                      mv_testsuite_common)
+
+install(TARGETS ${PROJECT_NAME} DESTINATION ${testsuites_dir})
diff --git a/test/testsuites/face/face_test_suite.c b/test/testsuites/face/face_test_suite.c
new file mode 100644 (file)
index 0000000..c26fce7
--- /dev/null
@@ -0,0 +1,2146 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mv_common.h>
+#include <mv_face.h>
+
+#include <mv_testsuite_common.h>
+
+#include <image_helper.h>
+#include <mv_video_helper.h>
+
+#include <mv_log_cfg.h>
+
+#include "pthread.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <string.h>
+#include <limits.h>
+
+#define MIN_ALLOWED_LABEL 0
+#define MAX_ALLOWED_LABEL 100
+
+static bool Perform_eye_condition_recognize = false;
+static bool Perform_facial_expression_recognize = false;
+
+void eye_condition_cb(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_eye_condition_e eye_condition,
+        void *user_data)
+{
+    switch (eye_condition)
+    {
+        case MV_FACE_EYES_NOT_FOUND:
+            printf("Eyes not found");
+            break;
+        case MV_FACE_EYES_OPEN:
+            printf("Eyes are open");
+            break;
+        case MV_FACE_EYES_CLOSED:
+            printf("Eyes are closed");
+            break;
+    }
+}
+
+void face_expression_cb(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s face_location,
+        mv_face_facial_expression_e facial_expression,
+        void *user_data)
+{
+    switch (facial_expression)
+    {
+        case MV_FACE_NEUTRAL:
+            printf("Face expression is neutral");
+            break;
+        case MV_FACE_SMILE:
+            printf("Face expression is smiling");
+            break;
+        case MV_FACE_UNKNOWN:
+            printf("Face expression isn't recognized");
+            break;
+    }
+}
+
+void on_face_detected_cb(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *faces_locations,
+        int number_of_faces,
+        void *user_data)
+{
+    printf("%i faces were detected on the image.\n", number_of_faces);
+    if (number_of_faces > 0)
+    {
+        int is_source_data_loaded = 0;
+
+        char *file_name = NULL;
+        unsigned char *out_buffer = NULL;
+        unsigned int buf_size = 0;
+        image_data_s image_data = { 0, 0, MEDIA_VISION_COLORSPACE_INVALID };
+        if (MEDIA_VISION_ERROR_NONE != mv_source_get_buffer(source, &out_buffer, &buf_size) ||
+            MEDIA_VISION_ERROR_NONE != mv_source_get_width(source, &(image_data.image_width)) ||
+            MEDIA_VISION_ERROR_NONE != mv_source_get_height(source, &(image_data.image_height)) ||
+            MEDIA_VISION_ERROR_NONE != mv_source_get_colorspace(source, &(image_data.image_colorspace)) ||
+            user_data == NULL)
+        {
+            printf("ERROR: Creating out image is impossible.\n");
+        }
+        else
+        {
+            file_name = (char*)user_data;
+            is_source_data_loaded = 1;
+        }
+
+        int i = 0;
+        for (i = 0; i < number_of_faces; ++i)
+        {
+            printf("\Face %i : x - %i, y - %i, width - %i, height - %i ", i,
+                    faces_locations[i].point.x, faces_locations[i].point.y,
+                    faces_locations[i].width, faces_locations[i].height);
+
+            if (Perform_eye_condition_recognize)
+            {
+                if (MEDIA_VISION_ERROR_NONE != mv_face_eye_condition_recognize(
+                                                   source,
+                                                   engine_cfg,
+                                                   faces_locations[i],
+                                                   eye_condition_cb,
+                                                   user_data))
+                {
+                    printf(TEXT_RED "\nEye condition recognition for %i face failed"
+                           TEXT_RESET "\n", i);
+                }
+            }
+
+            if (Perform_facial_expression_recognize)
+            {
+                if (MEDIA_VISION_ERROR_NONE != mv_face_facial_expression_recognize(
+                                                   source,
+                                                   engine_cfg,
+                                                   faces_locations[i],
+                                                   face_expression_cb,
+                                                   user_data))
+                {
+                    printf(TEXT_RED "\nFacial expression recognition for %i "
+                           "face failed" TEXT_RESET "\n", i);
+                }
+            }
+
+            printf("\n");
+
+            if ((is_source_data_loaded == 1) && !Perform_eye_condition_recognize)
+            {
+                const int rectangle_thickness = 3;
+                const int drawing_color[] = {255, 0, 0};
+                if (MEDIA_VISION_ERROR_NONE != draw_rectangle_on_buffer(
+                        faces_locations[i].point.x,
+                        faces_locations[i].point.y,
+                        faces_locations[i].point.x + faces_locations[i].width,
+                        faces_locations[i].point.y + faces_locations[i].height,
+                        rectangle_thickness,
+                        drawing_color,
+                        &image_data,
+                        out_buffer))
+                {
+                    continue;
+                }
+            }
+        }
+
+        if (!Perform_eye_condition_recognize)
+        {
+            if (file_name != NULL &&
+                MEDIA_VISION_ERROR_NONE == save_image_from_buffer(
+                                               file_name,
+                                               out_buffer,
+                                               &image_data,
+                                               100))
+            {
+                printf("Image was generated as %s\n", file_name);
+            }
+            else
+            {
+                printf("ERROR: Failed to generate output file. Check file name and permissions. \n");
+            }
+        }
+
+        printf("\n");
+    }
+}
+
+void on_face_recognized_cb(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        const int *face_label,
+        double confidence,
+        void *user_data)
+{
+    if (NULL == face_location)
+    {
+        printf(TEXT_YELLOW "No faces were recognized in the source"
+               TEXT_RESET "\n");
+    }
+    else
+    {
+        printf(TEXT_GREEN "Face labeled %i was recognized in the source with "
+                         "recognition confidence of %.2f"
+              TEXT_RESET "\n", *face_label, confidence);
+    }
+}
+
+int perform_detect()
+{
+    char *in_file_name = NULL;
+    char *out_file_name = NULL;
+
+    // 1. Loading media source
+    while (input_string("Input file name to be analyzed:", 1024, &(in_file_name)) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    mv_source_h source;
+    int err = mv_create_source(&source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during creating the source!!! code: %i"
+               TEXT_RESET "\n", err);
+
+        free(in_file_name);
+
+        return err;
+    }
+
+    err = load_mv_source_from_file(in_file_name, source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        const int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during destroying the source!!! code: %i"
+                    TEXT_RESET "\n", err2);
+
+            free(in_file_name);
+
+            return err2;
+        }
+
+        free(in_file_name);
+
+        return err;
+    }
+
+    free(in_file_name);
+
+    // 2. Select output file to be generated
+    while (input_string("Input file name to be generated:", 1024, &(out_file_name)) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    // 3. Select Haar cascade
+    const int options[3] = { 1, 2, 3 };
+    const char *names[3] = { "haarcascade_frontalface_alt.xml",
+                             "haarcascade_frontalface_alt2.xml",
+                             "haarcascade_frontalface_alt_tree.xml"};
+
+    const int haarcascade = show_menu("Select Haarcascade:", options, names, 3);
+
+    mv_engine_config_h eng_config;
+    err = mv_create_engine_config(&eng_config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during creating the engine config!!! code: %i"
+               TEXT_RESET "\n", err);
+
+        free(out_file_name);
+
+        return err;
+    }
+
+    switch (haarcascade)
+    {
+        case 1:
+            mv_engine_config_set_string_attribute(
+                        eng_config,
+                        MV_FACE_DETECTION_MODEL_FILE_PATH,
+                        "/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml");
+            break;
+        case 2:
+            mv_engine_config_set_string_attribute(
+                    eng_config,
+                    MV_FACE_DETECTION_MODEL_FILE_PATH,
+                    "/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml");
+            break;
+        case 3:
+            mv_engine_config_set_string_attribute(
+                    eng_config,
+                    MV_FACE_DETECTION_MODEL_FILE_PATH,
+                    "/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt_tree.xml");
+            break;
+        default:
+            printf(TEXT_YELLOW "Default Haar cascade was set.\n" TEXT_RESET);
+    }
+
+    // 4. Perform detect
+    err = mv_face_detect(source, eng_config, on_face_detected_cb, out_file_name);
+
+    free(out_file_name);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during face detection!!! code: %i"
+               TEXT_RESET "\n", err);
+
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during destroying the source!!! code: %i"
+                   TEXT_RESET "\n", err2);
+            return err2;
+        }
+
+        err2 = mv_destroy_engine_config(eng_config);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during destroying the engine config!!! code: %i"
+                   TEXT_RESET "\n", err2);
+            return err2;
+        }
+
+        return err;
+    }
+
+    err = mv_destroy_source(source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during destroying the source!!! code: %i"
+               TEXT_RESET "\n", err);
+        return err;
+    }
+
+    err = mv_destroy_engine_config(eng_config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during destroying the engine config!!! code: %i"
+               TEXT_RESET "\n", err);
+        return err;
+    }
+
+    return err;
+}
+
+int perform_mv_face_recognize(mv_face_recognition_model_h model)
+{
+    char *in_file_name = NULL;
+
+    mv_source_h source = NULL;
+    int err = mv_create_source(&source);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during creating the source!!! code: %i"
+               TEXT_RESET "\n", err);
+        return err;
+    }
+
+    printf(TEXT_GREEN "HINT:" TEXT_RESET "\n"
+           TEXT_YELLOW "To achieve appropriate accuracy of recognition,\n"
+                       "choose images with only faces. I.e. face has to cover\n"
+                       "approximately 95-100%% of the image (passport photos\n"
+                       "are the best example :)). Note that if this value is\n"
+                       "less than 95%, accuracy can be significantly reduced.\n"
+                       "In real code such images can be achieved by cropping\n"
+                       "faces from images with face detection functionality.\n"
+           TEXT_RESET);
+    while (-1 == input_string(
+                     "Input file name with the face to be recognized:",
+                     1024,
+                     &(in_file_name)))
+    {
+        printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+    }
+
+    err = load_mv_source_from_file(in_file_name, source);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        free(in_file_name);
+
+        const int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during destroying the source!!! code: %i"
+                    TEXT_RESET "\n", err2);
+            return err2;
+        }
+
+        return err;
+    }
+
+    err = mv_face_recognize(source, model, NULL, NULL, on_face_recognized_cb, NULL);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        free(in_file_name);
+
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during face recognition!!! code: %i"
+               TEXT_RESET "\n", err);
+
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during destroying the source!!! code: %i"
+                   TEXT_RESET "\n", err2);
+            return err2;
+        }
+
+        return err;
+    }
+
+    free(in_file_name);
+
+    return err;
+}
+
+int add_single_example(
+        mv_face_recognition_model_h model, const char *in_file_name,
+        mv_rectangle_s *roi, int *face_label)
+{
+    mv_source_h source;
+    int err = mv_create_source(&source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during creating the source!!! code: %i"
+               TEXT_RESET "\n", err);
+
+        return err;
+    }
+
+    err = load_mv_source_from_file(in_file_name, source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        const int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during destroying the source!!! code: %i"
+                   TEXT_RESET "\n", err2);
+            return err2;
+        }
+
+        return err;
+    }
+
+    if (NULL != roi && !show_confirm_dialog("Do you want to use full image?"))
+    {
+        printf(TEXT_YELLOW "Specify the ROI as rectangle where face is located.\n"
+                           "Use negative values if you want to check correctness\n"
+                           "of error handling.\n"
+               TEXT_RESET);
+
+        while (-1 == input_int("Specify top left ROI x coordinate:",
+                INT_MIN, INT_MAX, &(roi->point.x)))
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+
+        while (-1 == input_int("Specify top left ROI y coordinate:",
+                INT_MIN, INT_MAX, &(roi->point.y)))
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+
+        while (-1 == input_int("Specify top left ROI width:",
+                INT_MIN, INT_MAX, &(roi->width)))
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+
+        while (-1 == input_int("Specify top left ROI height:",
+                INT_MIN, INT_MAX, &(roi->height)))
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+    }
+    else
+    {
+        roi = NULL;
+    }
+
+    int real_label = 0;
+    if (NULL == face_label)
+    {
+        printf(TEXT_YELLOW "Also, you has to assign label for the face in the\n"
+                           "image. You has assign the same labels for the same\n"
+                           "persons. For example, always assign label '1' for\n"
+                           "images with Alice's face; label '2' for Bob's faces,\n"
+                           "'3' for Ann's faces and so on...\n"
+               TEXT_RESET);
+
+        face_label = &real_label;
+        while (-1 == input_int("Specify label as integer:",
+                               MIN_ALLOWED_LABEL,
+                               MAX_ALLOWED_LABEL,
+                               face_label))
+        {
+            printf("Incorrect input! You can use %i-%i labels only. Try again.\n",
+                   MIN_ALLOWED_LABEL,
+                   MAX_ALLOWED_LABEL);
+        }
+    }
+
+    err = mv_face_recognition_model_add(source, model, roi, *face_label);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during adding the sample image from "
+               "[%s] to the face recognition model!!! code: %i"
+               TEXT_RESET "\n", in_file_name, err);
+    }
+
+    const int err2 = mv_destroy_source(source);
+    if (MEDIA_VISION_ERROR_NONE != err2)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during destroying the source!!! code: %i"
+                TEXT_RESET "\n", err2);
+    }
+
+    return err;
+}
+
+int perform_mv_face_recognition_model_add_face_example(
+        mv_face_recognition_model_h model,
+        notification_type_e *notification_type)
+{
+    char *in_file_name = NULL;
+
+    printf(TEXT_GREEN "HINT:" TEXT_RESET "\n"
+           TEXT_YELLOW "To achieve appropriate accuracy of recognition,\n"
+                       "choose images with only faces. I.e. face has to cover\n"
+                       "approximately 95-100%% of the image (passport photos\n"
+                       "are the best example :)). Note that if this value is\n"
+                       "less than 95%, accuracy can be significantly reduced.\n"
+                       "In real code such images can be achieved by cropping\n"
+                       "faces from images with face detection functionality.\n"
+           TEXT_RESET);
+
+    const bool from_dir = show_confirm_dialog("Do add images from directory?");
+    const char *input_path_msg =
+            from_dir ? "Input path to the directory with the face images to be "
+                       "loaded to the model:"
+                     : "Input file name with the face to be loaded to the model:";
+
+    while (-1 == input_string(input_path_msg, 1024, &(in_file_name)))
+    {
+        printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+    }
+
+    int err = MEDIA_VISION_ERROR_NONE;
+
+    if (from_dir)
+    {
+        *notification_type = FAIL_OR_DONE;
+        int face_label = 0;
+        while (-1 == input_int("Specify label as integer:",
+                               MIN_ALLOWED_LABEL,
+                               MAX_ALLOWED_LABEL,
+                               &face_label))
+        {
+            printf("Incorrect input! You can use %i-%i labels only. Try again.\n",
+                   MIN_ALLOWED_LABEL,
+                   MAX_ALLOWED_LABEL);
+        }
+
+        DIR *dir;
+        struct dirent *ent;
+        if ((dir = opendir(in_file_name)) != NULL)
+        {
+            char file_path[1024] = "";
+
+            // Traverses all the files and directories within source directory
+            while ((ent = readdir(dir)) != NULL)
+            {
+                // Determine current entry name
+                const char *file_name = ent->d_name;
+
+                // If current entry is directory, or hidden object, skip the step:
+                if (file_name[0] == '.')
+                {
+                    continue;
+                }
+
+                sprintf(file_path, "%s/%s", in_file_name, file_name);
+                err = add_single_example(model, file_path, NULL, &face_label);
+
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf(TEXT_RED "Failed to add example from %s. "
+                                    "Error code: %i\n" TEXT_RESET,
+                                    file_path, err);
+                }
+                else
+                {
+                    printf(TEXT_GREEN "Example labeled [%i] added from " TEXT_RESET
+                           TEXT_YELLOW "%s\n" TEXT_RESET, face_label, file_path);
+                }
+            }
+
+            closedir(dir);
+        }
+        else
+        {
+            printf(TEXT_RED "Can't read from specified directory (%s)\n"
+                   TEXT_RESET, in_file_name);
+        }
+    }
+    else
+    {
+        *notification_type = FAIL_OR_SUCCESSS;
+        mv_rectangle_s roi;
+        err = add_single_example(model, in_file_name, &roi, NULL);
+    }
+
+    free(in_file_name);
+
+    return err;
+}
+
+int perform_mv_face_recognition_model_reset_face_examples(
+        mv_face_recognition_model_h model,
+        bool full_reset)
+{
+    printf(TEXT_GREEN "HINT:" TEXT_RESET "\n"
+           TEXT_YELLOW "Reset of the examples will affect only examples has\n"
+                       "been collected via mv_face_recognition_model_add()\n"
+                       "function calls (i.e. through 'Add image example' menu\n"
+                       "item). Previously learned model will be not affected,\n"
+                       "so it is possible to recognize faces with this model\n"
+                       "after examples reset. Reset of the examples can be\n"
+                       "useful to erase a class of faces (i.e. all examples\n"
+                       "related to this class) before learning the model.\n"
+                       "Or, if it is needed to reset all collected previously\n"
+                       "examples as an alternative to the creating the new\n"
+                       "model.\n"
+           TEXT_RESET);
+
+    int err = MEDIA_VISION_ERROR_NONE;
+
+    if (full_reset)
+    {
+        err = mv_face_recognition_model_reset(model, NULL);
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during reset of all examples!!!"
+                   " code: %i" TEXT_RESET "\n", err);
+            return err;
+        }
+    }
+    else
+    {
+        int reset_label = 0;
+
+        while (-1 == input_int("Specify label for the examples to be reset:",
+                               MIN_ALLOWED_LABEL,
+                               MAX_ALLOWED_LABEL,
+                               &reset_label))
+        {
+            printf("Incorrect input! You can use %i-%i labels only. Try again.\n",
+                   MIN_ALLOWED_LABEL,
+                   MAX_ALLOWED_LABEL);
+        }
+
+        err = mv_face_recognition_model_reset(model, &reset_label);
+
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during reset of examples labeled"
+                   " with  %i!!! code: %i" TEXT_RESET "\n", reset_label, err);
+            return err;
+        }
+    }
+
+    return err;
+}
+
+int perform_mv_face_recognition_model_save(mv_face_recognition_model_h model)
+{
+    char *out_file_name = NULL;
+
+    while (input_string("Input file name to save the model:",
+                        1024, &(out_file_name)) == -1)
+    {
+        printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+    }
+
+    const int err = mv_face_recognition_model_save(out_file_name, model);
+
+    free(out_file_name);
+
+    return err;
+}
+
+int perform_mv_face_recognition_model_load(mv_face_recognition_model_h *model)
+{
+    char *in_file_name = NULL;
+
+    while (input_string("Input file name to load model from:",
+                        1024, &(in_file_name)) == -1)
+    {
+        printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+    }
+
+    const int err = mv_face_recognition_model_load(in_file_name,model);
+
+    free(in_file_name);
+
+    return err;
+}
+
+int perform_mv_face_recognition_model_clone(
+        mv_face_recognition_model_h model_to_clone)
+{
+    int err = MEDIA_VISION_ERROR_NONE;
+
+    mv_face_recognition_model_h cloned_model = NULL;
+
+    printf(TEXT_GREEN "Perform clone of the recognition model..."
+           TEXT_RESET "\n");
+
+    err = mv_face_recognition_model_clone(model_to_clone, &cloned_model);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "Errors were occurred during model clone. Error code %i"
+               TEXT_RESET "\n", err);
+        return err;
+    }
+
+    printf(TEXT_YELLOW "Model cloning is done." TEXT_RESET "\n");
+
+    if (show_confirm_dialog("Save " TEXT_YELLOW "source model" TEXT_RESET
+                            " to file?"))
+    {
+        const int serr = perform_mv_face_recognition_model_save(model_to_clone);
+        if (MEDIA_VISION_ERROR_NONE != serr)
+        {
+            printf(TEXT_RED
+                   "Errors were occurred when trying to save "
+                   "source model to file. Error code %i" TEXT_RESET "\n", serr);
+        }
+    }
+
+    if (show_confirm_dialog("Save " TEXT_YELLOW "destination model" TEXT_RESET
+                            " to file?"))
+    {
+        const int serr = perform_mv_face_recognition_model_save(cloned_model);
+        if (MEDIA_VISION_ERROR_NONE != serr)
+        {
+            printf(TEXT_RED
+                   "Errors were occurred when trying to save destination model "
+                   "to file. Error code %i" TEXT_RESET "\n", serr);
+        }
+    }
+
+    if (cloned_model)
+    {
+        const int dest_err = mv_face_recognition_model_destroy(cloned_model);
+        if (MEDIA_VISION_ERROR_NONE != dest_err)
+        {
+            printf(TEXT_RED
+                   "Errors were occurred when destroying destination model ."
+                   "Error code %i" TEXT_RESET "\n", dest_err);
+        }
+    }
+
+    return err;
+}
+
+int perform_mv_face_recognition_model_learn(mv_face_recognition_model_h model)
+{
+    printf(TEXT_YELLOW "Learning the model has to be performed after\n"
+                       "adding some amount of examples to the model.\n"
+                       "If you learn without examples, you will get useless\n"
+                       "model, which will be unavailable to recognize. Anyway,\n"
+                       "you can add examples and launch this method again to\n"
+                       "get the appropriate recognition model suitable for\n"
+                       "recognition."
+           TEXT_RESET "\n");
+
+    printf(TEXT_GREEN "Start learning process..." TEXT_RESET "\n");
+
+    const int err = mv_face_recognition_model_learn(NULL, model);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "Learning the model failed. Error code: %i. "
+               "But you still can test with this model.\n"
+               TEXT_RESET "\n", err);
+    }
+    else
+    {
+        printf(TEXT_YELLOW "Recognition model has been learned."
+               TEXT_RESET "\n");
+    }
+
+    return err;
+}
+
+int perform_mv_face_recognition_model_query_labels(mv_face_recognition_model_h model)
+{
+    int *learned_labels = NULL;
+    int learned_labels_n = 0;
+
+    const int err = mv_face_recognition_model_query_labels(model, &learned_labels, &learned_labels_n);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        free(learned_labels);
+
+        return err;
+    }
+
+    int i = 0;
+    printf(TEXT_YELLOW "Recognition model had been learned for the following labels: "
+           TEXT_RESET "\n" TEXT_GREEN);
+    for (i = 0; i < learned_labels_n; ++i)
+    {
+        printf("%i, ", learned_labels[i]);
+    }
+    printf(TEXT_RESET "\n");
+
+    free(learned_labels);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+static int TP = 0;
+static int FP = 0;
+static int TN = 0;
+static int FN = 0;
+static double THRESHOLD = 0.75;
+
+void evaluation_cb(
+        mv_source_h source,
+        mv_face_recognition_model_h recognition_model,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *face_location,
+        const int *face_label,
+        double confidence,
+        void *user_data)
+{
+    if (NULL != user_data)
+    {
+        const int real_label = *((int*)user_data);
+        const int rec_label = (NULL != face_label ? *face_label : -1);
+        if (real_label == -1)
+        {
+            confidence >= THRESHOLD ? ++FP : ++TN;
+        }
+        else if (real_label == rec_label)
+        {
+            confidence >= THRESHOLD ? ++TP : ++FN;
+        }
+        else
+        {
+            if (confidence >= THRESHOLD) { ++FP; }
+            ++FN;
+        }
+    }
+}
+
+int perform_model_evaluation(mv_face_recognition_model_h model)
+{
+    int *learned_labels = NULL;
+    int learned_labels_n = 0;
+
+    mv_face_recognition_model_query_labels(model, &learned_labels, &learned_labels_n);
+
+    int i = 0;
+
+    printf(TEXT_YELLOW "Evaluating model had been learned for the following labels: "
+           TEXT_RESET "\n" TEXT_GREEN);
+    for (i = 0; i < learned_labels_n; ++i)
+    {
+        printf("%i, ", learned_labels[i]);
+    }
+    printf(TEXT_RESET "\n");
+
+    // 100 directories are allowed:
+    const int max_dir_allowed = 100;
+    char (*directories)[1024] = malloc(sizeof *directories * max_dir_allowed);
+    int labels[max_dir_allowed];
+    int unique_checks[MAX_ALLOWED_LABEL + 1];
+    for (i = 0; i < MAX_ALLOWED_LABEL + 1; ++i)
+    {
+        unique_checks[i] = 0;
+    }
+
+    int dir_n = 0;
+    int label_count = 0;
+    while (show_confirm_dialog("Add test images directory?") &&
+           dir_n < max_dir_allowed)
+    {
+        char *in_file_name = NULL;
+        while (-1 == input_string("Specify path to the test images directory:", 1024, &(in_file_name)))
+        {
+            printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+        }
+
+        DIR *dir;
+        if ((dir = opendir(in_file_name)) == NULL)
+        {
+            printf(TEXT_RED "Incorrect input! Directory %s can't be read.\n"
+                   TEXT_RESET, in_file_name);
+            free(in_file_name);
+            in_file_name = NULL;
+            continue;
+        }
+        else
+        {
+            closedir(dir);
+        }
+
+        int face_label = 0;
+        if (-1 == input_int("Specify label as integer:",
+                               MIN_ALLOWED_LABEL,
+                               MAX_ALLOWED_LABEL,
+                               &face_label))
+        {
+            printf(TEXT_RED "Incorrect input! You can use %i-%i labels only.\n"
+                   TEXT_RESET,
+                   MIN_ALLOWED_LABEL,
+                   MAX_ALLOWED_LABEL);
+            free(in_file_name);
+            in_file_name = NULL;
+            continue;
+        }
+
+        bool known_label = false;
+        for (i = 0; i < learned_labels_n; ++i)
+        {
+            if (learned_labels[i] == face_label)
+            {
+                known_label = true;
+                break;
+            }
+        }
+
+        if (!known_label)
+        {
+            printf(TEXT_YELLOW "Recognition model didn't learn with specified label.\n"
+                               "Images will be marked as unknown (-1)\n" TEXT_RESET);
+        }
+
+        labels[dir_n] = known_label ? face_label : -1;
+        strcpy(directories[dir_n], in_file_name);
+        label_count += (0 == unique_checks[face_label] ? 1 : 0);
+        if (labels[dir_n] >= 0)
+        {
+            unique_checks[labels[dir_n]] += 1;
+        }
+
+        free(in_file_name);
+
+        ++dir_n;
+
+        printf(TEXT_GREEN "Current test set for %i unique labels:\n" TEXT_RESET, label_count);
+        for (i = 0; i < dir_n; ++i)
+        {
+            printf(TEXT_YELLOW "Label %i: " TEXT_RESET "%s\n", labels[i], directories[i]);
+        }
+    }
+
+    free(learned_labels);
+
+    int rec_threshold = 0;
+    while (-1 == input_int("Specify recognition confidence threshold (0-100%):", 0, 100, &rec_threshold))
+    {
+        printf(TEXT_RED "Incorrect input! You can use 0-100 values only." TEXT_RESET "\n");
+    }
+    THRESHOLD = (double) rec_threshold / 100.0;
+
+    TP = 0;
+    FP = 0;
+    TN = 0;
+    FN = 0;
+
+    mv_source_h source = NULL;
+    int err = mv_create_source(&source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during creating the source!!! code: %i"
+               TEXT_RESET "\n", err);
+        return err;
+    }
+
+    for (i = 0; i < dir_n; ++i)
+    {
+        DIR *dir;
+        struct dirent *ent;
+        printf("Processing %s...\n", directories[i]);
+        if ((dir = opendir(directories[i])) != NULL)
+        {
+            char file_path[1024] = "";
+
+            // Traverses all the files and directories within source directory
+            while ((ent = readdir(dir)) != NULL)
+            {
+                // Determine current entry name
+                const char *file_name = ent->d_name;
+
+                // If current entry is directory, or hidden object, skip the step:
+                if (file_name[0] == '.')
+                {
+                    continue;
+                }
+
+                sprintf(file_path, "%s/%s", directories[i], file_name);
+                err = load_mv_source_from_file(file_path, source);
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf(TEXT_RED "Failed to test on example from %s. "
+                                    "Example will not affect the evaluation. "
+                                    "Error code: %i.\n" TEXT_RESET,
+                                    file_path, err);
+                }
+                else
+                {
+                    err = mv_face_recognize(source, model, NULL, NULL, evaluation_cb, &(labels[i]));
+                    if (MEDIA_VISION_ERROR_NONE != err)
+                    {
+                        printf(TEXT_RED "Failed to recognize on example from %s. "
+                                        "Example will not affect the evaluation. "
+                                        "Error code: %i\n" TEXT_RESET,
+                                        file_path, err);
+                    }
+                }
+            }
+
+            closedir(dir);
+        }
+        else
+        {
+            printf(TEXT_RED "Can't read from directory [%s]\n"
+                   TEXT_RESET, directories[i]);
+        }
+    }
+
+    int err2 = mv_destroy_source(source);
+    if (MEDIA_VISION_ERROR_NONE != err2)
+    {
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during destroying the source!!! code: %i"
+                   TEXT_RESET "\n", err2);
+        }
+    }
+
+    double accuracy = (TP + TN) / (double) (TP + FP + TN + FN);
+    double precision = TP / (double) (TP + FP);
+    double recall = TP / (double) (TP + FN);
+    double f1 = 2 * precision * recall / (precision + recall);
+
+    printf(TEXT_GREEN "Evaluation results:\n" TEXT_RESET);
+    printf(TEXT_YELLOW "\tTRUE POSITIVE  : " TEXT_RESET "%5i\n", TP);
+    printf(TEXT_YELLOW "\tFALSE POSITIVE : " TEXT_RESET "%5i\n", FP);
+    printf(TEXT_YELLOW "\tTRUE NEGATIVE  : " TEXT_RESET "%5i\n", TN);
+    printf(TEXT_YELLOW "\tFALSE NEGATIVE : " TEXT_RESET "%5i\n", FN);
+    printf(TEXT_YELLOW "\tAccuracy       : " TEXT_RESET "%f\n", accuracy);
+    printf(TEXT_YELLOW "\tPrecision      : " TEXT_RESET "%f\n", precision);
+    printf(TEXT_YELLOW "\tRecall         : " TEXT_RESET "%f\n", recall);
+    printf(TEXT_YELLOW "\tF1 score       : " TEXT_RESET "%f\n", f1);
+
+    free(directories);
+
+    return err;
+}
+
+int perform_recognize()
+{
+    printf("\n" TEXT_YELLOW
+           "Recognition model isn't now created.\n"
+           "You may create it to perform positive \n"
+           "testing, or don't create to check the \n"
+           "functionality behaviour for uncreated model."
+           TEXT_RESET
+           "\n");
+
+    int err = MEDIA_VISION_ERROR_NONE;
+    mv_face_recognition_model_h recognition_model = NULL;
+    const bool do_create = show_confirm_dialog("Do Create Recognition Model?");
+    if (do_create)
+    {
+        printf(TEXT_GREEN "Creating recognition model..." TEXT_RESET "\n");
+
+        err = mv_face_recognition_model_create(&recognition_model);
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf(TEXT_RED "Creating the model failed. Error code: %i. "
+                   "But you still can test with uncreated model.\n"
+                   TEXT_RESET "\n", err);
+        }
+        else
+        {
+            printf(TEXT_YELLOW "Recognition model has been created."
+                   TEXT_RESET "\n");
+        }
+    }
+
+    int sel_opt = 0;
+    const int options[11] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+    const char *names[11] = { "Add image example",
+                              "Reset examples by id",
+                              "Reset all examples",
+                              "Clone the model",
+                              "Learn the model",
+                              "Show learned labels",
+                              "Save model to file",
+                              "Load model from file",
+                              "Recognize with model",
+                              "Evaluate the model",
+                              "Destroy model and exit" };
+
+    while(!sel_opt)
+    {
+        sel_opt = show_menu("Select action:", options, names, 11);
+        notification_type_e notification_type = FAIL_OR_SUCCESSS;
+
+        switch (sel_opt)
+        {
+            case 1:
+                err = perform_mv_face_recognition_model_add_face_example(recognition_model, &notification_type);
+                break;
+            case 2:
+                err = perform_mv_face_recognition_model_reset_face_examples(recognition_model, false);
+                break;
+            case 3:
+                err = perform_mv_face_recognition_model_reset_face_examples(recognition_model, true);
+                break;
+            case 4:
+                err = perform_mv_face_recognition_model_clone(recognition_model);
+                break;
+            case 5:
+                err = perform_mv_face_recognition_model_learn(recognition_model);
+                break;
+            case 6:
+                err = perform_mv_face_recognition_model_query_labels(recognition_model);
+                break;
+            case 7:
+                err = perform_mv_face_recognition_model_save(recognition_model);
+                break;
+            case 8:
+                err = perform_mv_face_recognition_model_load(&recognition_model);
+                break;
+            case 9:
+                err = perform_mv_face_recognize(recognition_model);
+                break;
+            case 10:
+                err = perform_model_evaluation(recognition_model);
+                break;
+            case 11:
+                if (do_create)
+                {
+                    err = mv_face_recognition_model_destroy(recognition_model);
+                    if (MEDIA_VISION_ERROR_NONE != err)
+                    {
+                        printf(TEXT_RED
+                               "Error with code %i was occurred during destoy"
+                               TEXT_RESET "\n", err);
+                    }
+
+                    return err;
+                }
+                else
+                {
+                    return MEDIA_VISION_ERROR_NONE;
+                }
+            default:
+                sel_opt = 0;
+                printf("ERROR: Incorrect option was selected.\n");
+                continue;
+        }
+
+        print_action_result(names[sel_opt - 1], err, notification_type);
+
+        sel_opt = 0;
+    }
+}
+
+int perform_mv_face_tracking_model_save(mv_face_tracking_model_h model)
+{
+    char *out_file_name = NULL;
+
+    while (input_string("Input file name to save the model:",
+                        1024, &(out_file_name)) == -1)
+    {
+        printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+    }
+
+    const int err = mv_face_tracking_model_save(out_file_name, model);
+
+    free(out_file_name);
+
+    return err;
+}
+
+int perform_mv_face_tracking_model_load(mv_face_tracking_model_h *model)
+{
+    char *in_file_name = NULL;
+
+    while (input_string("Input file name to load model from:",
+                        1024, &(in_file_name)) == -1)
+    {
+        printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+    }
+
+    const int err = mv_face_tracking_model_load(in_file_name, model);
+
+    free(in_file_name);
+
+    return err;
+}
+
+int perform_mv_face_tracking_model_clone(
+        mv_face_tracking_model_h model_to_clone)
+{
+    int err = MEDIA_VISION_ERROR_NONE;
+
+    mv_face_tracking_model_h cloned_model = NULL;
+
+    printf(TEXT_GREEN "Perform clone of the tracking model..."
+           TEXT_RESET "\n");
+
+    err = mv_face_tracking_model_clone(model_to_clone, &cloned_model);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "Errors were occurred during model clone. Error code %i"
+               TEXT_RESET "\n", err);
+        return err;
+    }
+
+    printf(TEXT_YELLOW "Model cloning is done." TEXT_RESET "\n");
+
+    if (show_confirm_dialog("Save " TEXT_YELLOW "source model" TEXT_RESET
+                            " to file?"))
+    {
+        const int serr = perform_mv_face_tracking_model_save(model_to_clone);
+        if (MEDIA_VISION_ERROR_NONE != serr)
+        {
+            printf(TEXT_RED
+                   "Errors were occurred when trying to save "
+                   "source model to file. Error code %i" TEXT_RESET "\n", serr);
+        }
+    }
+
+    if (show_confirm_dialog("Save " TEXT_YELLOW "destination model" TEXT_RESET
+                            " to file?"))
+    {
+        const int serr = perform_mv_face_tracking_model_save(cloned_model);
+        if (MEDIA_VISION_ERROR_NONE != serr)
+        {
+            printf(TEXT_RED
+                   "Errors were occurred when trying to save destination model "
+                   "to file. Error code %i" TEXT_RESET "\n", serr);
+        }
+    }
+
+    if (cloned_model)
+    {
+        const int dest_err = mv_face_tracking_model_destroy(cloned_model);
+        if (MEDIA_VISION_ERROR_NONE != dest_err)
+        {
+            printf(TEXT_RED
+                   "Errors were occurred when destroying destination model ."
+                   "Error code %i" TEXT_RESET "\n", dest_err);
+        }
+    }
+
+    return err;
+}
+
+static volatile bool frame_read = false;
+
+void video_1_sample_cb(
+        char *buffer,
+        unsigned int buffer_size,
+        image_data_s image_data,
+        void *user_data)
+{
+    if (!frame_read)
+    {
+        mv_source_h source = (mv_source_h)user_data;
+
+        const int err = mv_source_fill_by_buffer(
+                            source,
+                            buffer,
+                            buffer_size,
+                            image_data.image_width,
+                            image_data.image_height,
+                            image_data.image_colorspace);
+
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf(TEXT_RED "ERROR: Errors were occurred during filling the "
+                   "source based on the video frame! Error code: %i"
+                   TEXT_RESET, err);
+        }
+
+        frame_read = true;
+    }
+}
+
+void face_detected_for_tracking_cb(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        mv_rectangle_s *faces_locations,
+        int number_of_faces,
+        void *user_data)
+{
+    if (number_of_faces < 1)
+    {
+        printf(TEXT_RED "Unfortunatly, no faces were detected on the\n"
+                        "preparation frame. You has to specify bounding\n"
+                        "quadrangles for tracking without advices."
+               TEXT_RESET "\n");
+        return;
+    }
+
+    printf(TEXT_YELLOW "%i face(s) were detected at the preparation frame.\n"
+                       "Following list includes information on faces bounding\n"
+                       "boxes coordinates:"
+           TEXT_RESET "\n", number_of_faces);
+
+    int idx = 0;
+    while (idx < number_of_faces)
+    {
+        printf(TEXT_MAGENTA "Face %i bounding box: " TEXT_RESET "\n", ++idx);
+        printf(TEXT_CYAN "\tTop left point:     x1: %4i;  y1: %4i\n" TEXT_RESET,
+               faces_locations[idx - 1].point.x,
+               faces_locations[idx - 1].point.y);
+        printf(TEXT_CYAN "\tTop right point:    x2: %4i;  y2: %4i\n" TEXT_RESET,
+               faces_locations[idx - 1].point.x + faces_locations[idx - 1].width,
+               faces_locations[idx - 1].point.y);
+        printf(TEXT_CYAN "\tBottom right point: x3: %4i;  y3: %4i\n" TEXT_RESET,
+               faces_locations[idx - 1].point.x + faces_locations[idx - 1].width,
+               faces_locations[idx - 1].point.y + faces_locations[idx - 1].height);
+        printf(TEXT_CYAN "\tBottom right point: x4: %4i;  y4: %4i\n" TEXT_RESET,
+               faces_locations[idx - 1].point.x,
+               faces_locations[idx - 1].point.y + faces_locations[idx - 1].height);
+    }
+}
+
+int load_source_from_first_video_frame(const char *video_file, mv_source_h source)
+{
+    mv_video_reader_h reader = NULL;
+    int err = mv_create_video_reader(&reader);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during creating the video "
+               "reader! Error code: %i\n" TEXT_RESET, err);
+        return err;
+    }
+
+    err = mv_video_reader_set_new_sample_cb(
+                  reader,
+                  video_1_sample_cb,
+                  source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during new sample "
+               "callback set! Error code: %i\n" TEXT_RESET, err);
+
+        const int err2 = mv_destroy_video_reader(reader);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED "ERROR: Errors were occurred during video reader "
+                    "destroy! Error code: %i\n" TEXT_RESET, err);
+        }
+
+        return err;
+    }
+
+    frame_read = false;
+    image_data_s video_info;
+    unsigned int fps;
+    err = mv_video_reader_load(reader, video_file, &video_info, &fps);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during loading the video "
+               "by reader! Error code: %i\n" TEXT_RESET, err);
+
+        const int err2 = mv_destroy_video_reader(reader);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED "ERROR: Errors were occurred during video reader "
+                   "destroy! Error code: %i\n" TEXT_RESET, err);
+        }
+
+        return err;
+    }
+
+    //wait for the video reading thread
+    while (true)
+    {
+        if (frame_read)
+        {
+            int err2 = mv_video_reader_stop(reader);
+            if (MEDIA_VISION_ERROR_NONE != err2)
+            {
+                printf(TEXT_RED "ERROR: Errors were occurred during attempt to "
+                       "stop video reader! Error code: %i\n" TEXT_RESET, err2);
+            }
+
+            err2 = mv_destroy_video_reader(reader);
+            if (MEDIA_VISION_ERROR_NONE != err2)
+            {
+                printf(TEXT_RED "ERROR: Errors were occurred during video "
+                       "reader destroy! Error code: %i\n" TEXT_RESET, err2);
+            }
+
+            break;
+        }
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int perform_mv_face_tracking_model_prepare(mv_face_tracking_model_h model)
+{
+    printf(TEXT_YELLOW "Before any tracking session the tracking model\n"
+                       "preparation is required. Exception is the case when\n"
+                       "the next tracking session will be performed with the\n"
+                       "video which is the direct continuation of the video\n"
+                       "has been used at the previous tracking session.\n"
+                       "Preparation has to be done with the first frame of\n"
+                       "the video or first image from continuous image\n"
+                       "sequence for which next tracking session plan to be\n"
+                       "performed.\nTracking model preparation includes\n"
+                       "specifying the location of the face to be tracked on\n"
+                       "the first frame. Face tracking algorithm will try to\n"
+                       "grab the face image significant features and\n"
+                       "optionally will try to determine the background.\n"
+                       "Actually, preparation is model-dependent and may\n"
+                       "differs in respect to used tracking algorithm."
+           TEXT_RESET "\n");
+
+    int sel_opt = 0;
+    const int options[2] = { 1, 2 };
+    const char *names[2] = { "Prepare with the video file",
+                             "Prepare with the image file" };
+
+    bool is_video = false;
+
+    while(!sel_opt)
+    {
+        sel_opt = show_menu("Select action:", options, names, 2);
+        switch (sel_opt)
+        {
+            case 1:
+                is_video = true;
+                break;
+            case 2:
+                is_video = false;
+                break;
+            default:
+                sel_opt = 0;
+                continue;
+        }
+    }
+
+    mv_source_h preparation_frame = NULL;
+    int err = mv_create_source(&preparation_frame);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during creating the source!!! code: %i"
+               TEXT_RESET "\n", err);
+
+        return err;
+    }
+
+    char *init_frame_file_name = NULL;
+    const char *prompt_str =
+            (is_video ? "Input video file name to prepare the model:"
+                      : "Input image file name to prepare the model:");
+
+    while (input_string(prompt_str, 1024, &(init_frame_file_name)) == -1)
+    {
+        printf(TEXT_RED "Incorrect input! Try again.\n" TEXT_RESET);
+    }
+
+    if (is_video)
+    {
+        err = load_source_from_first_video_frame(init_frame_file_name, preparation_frame);
+    }
+    else
+    {
+        err = load_mv_source_from_file(init_frame_file_name, preparation_frame);
+    }
+
+    free(init_frame_file_name);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during preparation "
+               "frame/image load! Error code: %i\n" TEXT_RESET, err);
+
+        int err2 = mv_destroy_source(preparation_frame);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED "ERROR: Errors were occurred during destroying the "
+                   "source! Error code: %i\n" TEXT_RESET, err2);
+        }
+
+        return err;
+    }
+
+    mv_engine_config_h eng_config = NULL;
+    err = mv_create_engine_config(&eng_config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during creating the "
+               "engine config! Error code: %i\n" TEXT_RESET, err);
+    }
+    else
+    {
+        err = mv_engine_config_set_string_attribute(
+                    eng_config,
+                    MV_FACE_DETECTION_MODEL_FILE_PATH,
+                    "/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml");
+
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf(TEXT_RED "ERROR: Errors were occurred during setting of the "
+                   "the 'MV_FACE_DETECTION_MODEL_FILE_PATH' attribute "
+                   "for engine configuration! Check media-vision-config.json "
+                   "file existence. Error code: %i" TEXT_RESET, err);
+        }
+    }
+
+    err = mv_face_detect(
+              preparation_frame,
+              eng_config,
+              face_detected_for_tracking_cb,
+              NULL);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during face detection! "
+               "Error code: %i\n" TEXT_RESET, err);
+
+        int err2 = mv_destroy_engine_config(eng_config);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED "ERROR: Errors were occurred during destroying the "
+                   "engine configuration! Error code: %i\n" TEXT_RESET, err2);
+        }
+
+        return err;
+    }
+
+    mv_quadrangle_s roi;
+
+    if (show_confirm_dialog("Do specify the face location?"))
+    {
+        printf(TEXT_YELLOW "Specify the coordinates of the quadrangle to be used\n"
+                           "for tracking model preparation:" TEXT_RESET "\n");
+        int idx = 0;
+        char str_prompt[100];
+        while (idx < 4)
+        {
+            ++idx;
+            sprintf(str_prompt, "Specify point %i x coordinate: x%i = ",
+                    idx - 1, idx);
+            while (-1 == input_int(str_prompt, INT_MIN, INT_MAX,
+                                   &(roi.points[idx - 1].x)))
+            {
+                printf("Incorrect input! Try again.\n");
+            }
+            sprintf(str_prompt, "Specify point %i y coordinate: y%i = ",
+                                idx - 1, idx);
+            while (-1 == input_int(str_prompt, INT_MIN, INT_MAX,
+                                   &(roi.points[idx - 1].y)))
+            {
+                printf("Incorrect input! Try again.\n");
+            }
+        }
+
+        err = mv_face_tracking_model_prepare(
+                  model, eng_config, preparation_frame, &roi);
+    }
+    else
+    {
+        err = mv_face_tracking_model_prepare(
+                  model, eng_config, preparation_frame, NULL);
+    }
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during the tracking model "
+               "preparation! Error code: %i\n" TEXT_RESET, err);
+    }
+
+    const int err2 = mv_destroy_source(preparation_frame);
+    if (MEDIA_VISION_ERROR_NONE != err2)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during destroying the "
+               "source! Error code: %i\n" TEXT_RESET, err2);
+    }
+
+    return err;
+}
+
+static char *track_output_dir = NULL;
+
+static int track_frame_counter = 0;
+
+void track_cb(
+        mv_source_h source,
+        mv_face_tracking_model_h tracking_model,
+        mv_engine_config_h engine_cfg,
+        mv_quadrangle_s *location,
+        double confidence,
+        void *user_data)
+{
+    static bool track_catch_face = false;
+
+    ++track_frame_counter;
+
+    unsigned char *out_buffer = NULL;
+    unsigned int buf_size = 0;
+    image_data_s image_data = { 0, 0, MEDIA_VISION_COLORSPACE_INVALID };
+    if (MEDIA_VISION_ERROR_NONE !=
+            mv_source_get_buffer(source, &out_buffer, &buf_size) ||
+        MEDIA_VISION_ERROR_NONE !=
+            mv_source_get_width(source, &(image_data.image_width)) ||
+        MEDIA_VISION_ERROR_NONE !=
+            mv_source_get_height(source, &(image_data.image_height)) ||
+        MEDIA_VISION_ERROR_NONE !=
+            mv_source_get_colorspace(source, &(image_data.image_colorspace)))
+    {
+        printf("ERROR: Creating out image is impossible.\n");
+
+        return;
+    }
+
+    if (NULL != location)
+    {
+        if (!track_catch_face)
+        {
+            printf(TEXT_GREEN "Frame %i : Tracked object is appeared" TEXT_RESET "\n",
+                    track_frame_counter);
+            track_catch_face = true;
+        }
+        else
+        {
+            printf(TEXT_YELLOW "Frame %i : Tracked object is tracked" TEXT_RESET "\n",
+                    track_frame_counter);
+        }
+
+        const int rectangle_thickness = 3;
+        const int drawing_color[] = {255, 0, 0};
+
+        printf(TEXT_YELLOW
+               "Location: (%i,%i) -> (%i,%i) -> (%i,%i) -> (%i,%i)\n"
+               TEXT_RESET,
+               location->points[0].x,
+               location->points[0].y,
+               location->points[1].x,
+               location->points[1].y,
+               location->points[2].x,
+               location->points[2].y,
+               location->points[3].x,
+               location->points[3].y);
+        printf(TEXT_YELLOW "Track confidence: %f" TEXT_RESET "\n", confidence);
+
+        const int err = draw_quadrangle_on_buffer(
+                                *location,
+                                rectangle_thickness,
+                                drawing_color,
+                                &image_data,
+                                out_buffer);
+
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf(TEXT_RED "ERROR: Quadrangle wasn't drew on frame buffer! "
+                   "Error code: %i\n" TEXT_RESET, err);
+
+            return;
+        }
+    }
+    else
+    {
+        if (track_catch_face)
+        {
+            printf(TEXT_RED "Frame %i : Tracked object is lost" TEXT_RESET "\n",
+                    track_frame_counter);
+            track_catch_face = false;
+        }
+        else
+        {
+            printf(TEXT_YELLOW "Frame %i : Tracked object isn't detected" TEXT_RESET "\n",
+                    track_frame_counter);
+        }
+    }
+
+    char file_path[1024];
+    sprintf(file_path, "%s/%05d.jpg", track_output_dir, track_frame_counter);
+    if (MEDIA_VISION_ERROR_NONE == save_image_from_buffer(
+                    file_path, out_buffer, &image_data, 100))
+    {
+        printf("Frame %i was outputted as %s\n", track_frame_counter, file_path);
+    }
+    else
+    {
+        printf(TEXT_RED "ERROR: Failed to generate output file %s. "
+               "Check file name and permissions.\n" TEXT_RESET, file_path);
+    }
+}
+
+void track_on_sample_cb(
+        char *buffer,
+        unsigned int buffer_size,
+        image_data_s image_data,
+        void *user_data)
+{
+    mv_source_h source = NULL;
+    int err = mv_create_source(&source);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during creating the source "
+               "based on the video frame! Error code: %i\n" TEXT_RESET, err);
+
+        return;
+    }
+
+    err = mv_source_fill_by_buffer(
+                        source,
+                        buffer,
+                        buffer_size,
+                        image_data.image_width,
+                        image_data.image_height,
+                        image_data.image_colorspace);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during filling the source "
+               "based on the video frame! Error code: %i\n" TEXT_RESET , err);
+
+        return;
+    }
+
+    mv_face_tracking_model_h tracking_model =
+            (mv_face_tracking_model_h)user_data;
+
+    err = mv_face_track(source, tracking_model, NULL, track_cb, false, NULL);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during tracking the face "
+               TEXT_RESET "on the video frame! Error code: %i\n", err);
+
+        return;
+    }
+}
+
+// end of stream callback
+void eos_cb(void *user_data)
+{
+    printf("Video was fully processed\n");
+    if (NULL == user_data)
+    {
+        printf(TEXT_RED
+                "ERROR: eos callback can't stop tracking process."TEXT_RESET);
+        return;
+    }
+
+    pthread_mutex_unlock((pthread_mutex_t*)user_data);
+}
+
+int generate_image_sequence(
+        mv_face_tracking_model_h tracking_model,
+        const char *track_target_file_name)
+{
+    mv_video_reader_h reader = NULL;
+    int err = mv_create_video_reader(&reader);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during creating the video "
+               "reader! Error code: %i" TEXT_RESET "\n", err);
+        return err;
+    }
+
+    image_data_s video_info;
+    unsigned int fps;
+    // init_frame_file_name
+    err = mv_video_reader_load(reader, track_target_file_name, &video_info, &fps);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during loading the video "
+               "by reader! Error code: %i" TEXT_RESET "\n", err);
+
+        const int err2 = mv_destroy_video_reader(reader);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED "ERROR: Errors were occurred during video reader "
+                   "destroy! Error code: %i" TEXT_RESET "\n", err);
+        }
+
+        return err;
+    }
+
+    err = mv_video_reader_set_new_sample_cb(
+                  reader,
+                  track_on_sample_cb,
+                  tracking_model);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during new sample callback set!"
+               " Error code: %i" TEXT_RESET "\n", err);
+
+        const int err2 = mv_destroy_video_reader(reader);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED "ERROR: Errors were occurred during video reader "
+                   "destroy! Error code: %i" TEXT_RESET "\n", err);
+        }
+
+        return err;
+    }
+
+    pthread_mutex_t block_during_tracking_mutex;
+    pthread_mutex_init(&block_during_tracking_mutex, NULL);
+    pthread_mutex_lock(&block_during_tracking_mutex);
+
+    // set end of stream callback
+    err = mv_video_reader_set_eos_cb(reader, eos_cb, &block_during_tracking_mutex);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED
+               "ERROR: Errors were occurred during setting the eos "
+               "callback for reader! Error code: %i" TEXT_RESET "\n", err);
+
+        const int err2 = mv_destroy_video_reader(reader);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during video reader destroy!"
+                   " Error code: %i" TEXT_RESET "\n", err);
+        }
+
+        pthread_mutex_unlock(&block_during_tracking_mutex);
+        pthread_mutex_destroy(&block_during_tracking_mutex);
+
+        return err;
+    }
+
+    err = mv_video_reader_start(reader);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during starting the "
+               "video reader! Error code: %i" TEXT_RESET "\n", err);
+
+        const int err2 = mv_destroy_video_reader(reader);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf(TEXT_RED
+                   "ERROR: Errors were occurred during video reader destroy!"
+                   " Error code: %i" TEXT_RESET "\n", err);
+        }
+
+        pthread_mutex_unlock(&block_during_tracking_mutex);
+        pthread_mutex_destroy(&block_during_tracking_mutex);
+
+        return err;
+    }
+
+    //wait for the video reading thread
+
+    pthread_mutex_lock(&block_during_tracking_mutex);
+    pthread_mutex_unlock(&block_during_tracking_mutex);
+    pthread_mutex_destroy(&block_during_tracking_mutex);
+
+    err = mv_video_reader_stop(reader);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during "
+               "attempt to stop video reader! Error code: %i\n"
+               TEXT_RESET, err);
+    }
+
+    err = mv_destroy_video_reader(reader);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(TEXT_RED "ERROR: Errors were occurred during video "
+               "reader destroy! Error code: %i\n" TEXT_RESET, err);
+    }
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int perform_mv_face_track(mv_face_tracking_model_h tracking_model)
+{
+    printf(TEXT_YELLOW "Before any tracking session the tracking model\n"
+                       "preparation is required. Exception is the case when\n"
+                       "the next tracking session will be performed with the\n"
+                       "video which is the direct continuation of the video\n"
+                       "has been used at the previous tracking session.\n"
+                       "If you want to test correct tracking case, don't\n"
+                       "forget to perform preparation before tracking."
+           TEXT_RESET "\n");
+
+    char *track_target_file_name = NULL;
+
+    while (input_string("Input video file name to track on:",
+           1024, &(track_target_file_name)) == -1)
+    {
+        printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+    }
+
+    while (input_string("Input directory to save tracking results:",
+                        1024, &(track_output_dir)) == -1)
+    {
+        printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n");
+    }
+
+    track_frame_counter = 0;
+
+    return generate_image_sequence(tracking_model, track_target_file_name);
+}
+
+int perform_track()
+{
+    printf("\n" TEXT_YELLOW
+           "Tracking model isn't now created.\n"
+           "You may create it to perform positive \n"
+           "testing, or don't create to check the \n"
+           "functionality behaviour for uncreated model."
+           TEXT_RESET
+           "\n");
+
+    int err = MEDIA_VISION_ERROR_NONE;
+    mv_face_tracking_model_h tracking_model = NULL;
+    const bool do_create = show_confirm_dialog("Do Create Tracking Model?");
+    if (do_create)
+    {
+        printf(TEXT_GREEN "Creating tracking model..." TEXT_RESET "\n");
+
+        err = mv_face_tracking_model_create(&tracking_model);
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf(TEXT_RED "Creating the model failed. Error code: %i. "
+                   "But you still can test with uncreated model.\n"
+                   TEXT_RESET "\n", err);
+        }
+        else
+        {
+            printf(TEXT_YELLOW "Tracking model has been created."
+                   TEXT_RESET "\n");
+        }
+    }
+
+    int sel_opt = 0;
+    const int options[6] = { 1, 2, 3, 4, 5, 6 };
+    const char *names[6] = { "Prepare the model",
+                              "Clone the model",
+                              "Save model to file",
+                              "Load model from file",
+                              "Track with model",
+                              "Destroy model and exit" };
+
+    while(!sel_opt)
+    {
+        sel_opt = show_menu("Select action:", options, names, 6);
+        notification_type_e notification_type = FAIL_OR_SUCCESSS;
+
+        switch (sel_opt)
+        {
+            case 1:
+                err = perform_mv_face_tracking_model_prepare(tracking_model);
+                break;
+            case 2:
+                err = perform_mv_face_tracking_model_clone(tracking_model);
+                break;
+            case 3:
+                err = perform_mv_face_tracking_model_save(tracking_model);
+                break;
+            case 4:
+                err = perform_mv_face_tracking_model_load(&tracking_model);
+                break;
+            case 5:
+                err = perform_mv_face_track(tracking_model);
+                notification_type = FAIL_OR_DONE;
+                break;
+            case 6:
+                if (do_create)
+                {
+                    err = mv_face_tracking_model_destroy(tracking_model);
+                    if (MEDIA_VISION_ERROR_NONE != err)
+                    {
+                        printf(TEXT_RED
+                               "Error with code %i was occurred during destroy"
+                               TEXT_RESET "\n", err);
+                    }
+
+                    return err;
+                }
+                else
+                {
+                    return MEDIA_VISION_ERROR_NONE;
+                }
+            default:
+                sel_opt = 0;
+                printf("ERROR: Incorrect input.\n");
+                continue;
+        }
+
+        print_action_result(names[sel_opt - 1], err, notification_type);
+
+        sel_opt = 0;
+    }
+}
+
+int perform_eye_condition_recognize()
+{
+    Perform_eye_condition_recognize = true;
+
+    const int err = perform_detect();
+
+    Perform_eye_condition_recognize = false;
+
+    return err;
+}
+
+int perform_face_expression_recognize()
+{
+    Perform_facial_expression_recognize = true;
+
+    const int err = perform_detect();
+
+    Perform_facial_expression_recognize = false;
+
+    return err;
+}
+
+int main(void)
+{
+    int err = MEDIA_VISION_ERROR_NONE;
+
+    int sel_opt = 0;
+    const int options[6] = { 1, 2, 3, 4, 5, 6 };
+    const char *names[6] = { "Detect",
+                             "Track",
+                             "Recognize",
+                             "Eye condition",
+                             "Face expression",
+                             "Exit" };
+
+    while (sel_opt == 0)
+    {
+        sel_opt = show_menu("Select action:", options, names, 6);
+        switch (sel_opt)
+        {
+            case 1:
+                err = perform_detect();
+                break;
+            case 2:
+                err = perform_track();
+                break;
+            case 3:
+                err = perform_recognize();
+                break;
+            case 4:
+                err = perform_eye_condition_recognize();
+                break;
+            case 5:
+                err = perform_face_expression_recognize();
+                break;
+            case 6:
+                return 0;
+            default:
+                sel_opt = 0;
+                printf("Invalid option.\n");
+                continue;
+        }
+
+        int do_another = 0;
+
+        if (err != MEDIA_VISION_ERROR_NONE)
+        {
+            printf("ERROR: Action is finished with error code: %i\n", err);
+        }
+
+        sel_opt = 0;
+        const int options_last[2] = { 1, 2 };
+        const char *names_last[2] = { "YES", "NO" };
+
+        while (sel_opt == 0)
+        {
+            sel_opt = show_menu("Perform another action?", options_last, names_last, 2);
+
+            switch (sel_opt)
+            {
+                case 1:
+                    do_another = 1;
+                    break;
+                case 2:
+                    do_another = 0;
+                    break;
+                default:
+                    sel_opt = 0;
+                    printf("Invalid option.\n");
+                    break;
+            }
+        }
+
+        sel_opt = (do_another == 1 ? 0 : sel_opt);
+    }
+
+    return 0;
+}
diff --git a/test/testsuites/image/CMakeLists.txt b/test/testsuites/image/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6c66495
--- /dev/null
@@ -0,0 +1,41 @@
+project(mv_image_test_suite)
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG    _DEBUG)
+
+if(NOT SKIP_WARNINGS)
+    set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror")
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories(${PROJECT_SOURCE_DIR})
+include_directories(${MV_CAPI_MEDIA_VISION_INC_DIR})
+include_directories(${INC_IMAGE_HELPER})
+include_directories(${INC_VIDEO_HELPER})
+include_directories(${INC_TS_COMMON})
+
+file(GLOB MV_TEST_SUITE_INC_LIST "${PROJECT_SOURCE_DIR}/*.h")
+file(GLOB MV_TEST_SUITE_SRC_LIST "${PROJECT_SOURCE_DIR}/*.c")
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GLIB_PKG glib-2.0)
+
+if (NOT GLIB_PKG_FOUND)
+    message(SEND_ERROR "Failed to find glib")
+    return()
+else()
+    include_directories(${GLIB_PKG_INCLUDE_DIRS})
+endif()
+
+add_executable(${PROJECT_NAME} ${MV_TEST_SUITE_SRC_LIST} ${MV_TEST_SUITE_INC_LIST} ${MV_CAPI_MEDIA_VISION_INC_LIST})
+
+target_link_libraries(${PROJECT_NAME} capi-media-vision
+                                      glib-2.0
+                                      mv_image_helper
+                                      mv_video_helper
+                                      mv_testsuite_common)
+
+install(TARGETS ${PROJECT_NAME} DESTINATION ${testsuites_dir})
diff --git a/test/testsuites/image/image_test_suite.c b/test/testsuites/image/image_test_suite.c
new file mode 100644 (file)
index 0000000..a0d1a11
--- /dev/null
@@ -0,0 +1,2076 @@
+/**
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_image.h"
+#include "mv_private.h"
+
+#include "image_helper.h"
+#include "mv_video_helper.h"
+#include "mv_testsuite_common.h"
+
+#include <glib-2.0/glib.h>
+#include <string.h>
+
+#include <pthread.h>
+
+typedef enum
+{
+    SOURCE_TYPE_GENERATION,
+    SOURCE_TYPE_LOADING,
+    SOURCE_TYPE_CLONING,
+    SOURCE_TYPE_EMPTY,
+    SOURCE_TYPE_INVALID
+} source_type_e;
+
+typedef enum
+{
+    OBJECT_TYPE_IMAGE_OBJECT,
+    OBJECT_TYPE_IMAGE_TRACKING_MODEL,
+    OBJECT_TYPE_INVALID
+} testing_object_type_e;
+
+#define testing_object_maximum_label_length 300
+
+typedef struct testing_object_s
+{
+    void *entity;
+
+    char origin_label[testing_object_maximum_label_length];
+
+    char actual_label[testing_object_maximum_label_length];
+
+    testing_object_type_e object_type;
+
+    source_type_e source_type;
+
+    int cloning_counter;
+} testing_object;
+
+typedef testing_object *testing_object_h;
+
+void testing_object_create(testing_object_h *result)
+{
+    (*result) = malloc(sizeof(testing_object));
+
+    (*result)->entity = (void*)NULL;
+    (*result)->object_type = OBJECT_TYPE_INVALID;
+    (*result)->source_type = SOURCE_TYPE_INVALID;
+    (*result)->cloning_counter = 0;
+    (*result)->origin_label[0] = '\0';
+    (*result)->actual_label[0] = '\0';
+}
+
+void testing_object_fill(
+        testing_object_h target,
+        void *entity,
+        testing_object_type_e object_type,
+        source_type_e source_type,
+        void *source)
+{
+    target->entity = entity;
+    target->object_type = object_type;
+    target->source_type = source_type;
+    target->cloning_counter = 0;
+
+    switch (source_type)
+    {
+        case SOURCE_TYPE_GENERATION:
+        {
+            if (OBJECT_TYPE_IMAGE_OBJECT == object_type)
+            {
+                sprintf(
+                        target->origin_label,
+                        "generated from \"%s\"",
+                        (char*)source);
+            }
+            else if (OBJECT_TYPE_IMAGE_TRACKING_MODEL == object_type)
+            {
+                sprintf(
+                        target->origin_label,
+                        "generated from image object which is %s",
+                        ((testing_object_h)source)->actual_label);
+            }
+            else
+            {
+                sprintf(
+                        target->origin_label,
+                        "generated unknown type of testing object");
+            }
+
+            strcpy(target->actual_label, target->origin_label);
+            break;
+        }
+        case SOURCE_TYPE_LOADING:
+        {
+            sprintf(target->origin_label, "loaded from \"%s\"", (char*)source);
+            strcpy(target->actual_label, target->origin_label);
+            break;
+        }
+        case SOURCE_TYPE_CLONING:
+        {
+            testing_object_h source_object = (testing_object_h)source;
+            strcpy(target->origin_label, source_object->origin_label);
+            target->cloning_counter = source_object->cloning_counter + 1;
+
+            char number_of_cloning[10];
+            number_of_cloning[0] = '\0';
+            if (1 < target->cloning_counter)
+            {
+                sprintf(number_of_cloning, "%s%i%s",
+                        "(x", target->cloning_counter, ")");
+            }
+
+            char type_name[20];
+            if (OBJECT_TYPE_IMAGE_OBJECT == object_type)
+            {
+                sprintf(type_name, "image object");
+            }
+            else if (OBJECT_TYPE_IMAGE_TRACKING_MODEL == object_type)
+            {
+                sprintf(type_name, "tracking model");
+            }
+            else
+            {
+                sprintf(type_name, "unknown object");
+            }
+            sprintf(target->actual_label, "%s%s%s%s%s%s",
+                    "cloned ", number_of_cloning,
+                    " from ", type_name,
+                    " which is ", target->origin_label);
+            break;
+        }
+        case SOURCE_TYPE_EMPTY:
+        {
+            strcpy(target->origin_label, "created an empty");
+            strcpy(target->actual_label, target->origin_label);
+            break;
+        }
+        default:
+        {
+            strcpy(target->origin_label, "having unknown source");
+            break;
+        }
+    }
+}
+
+void testing_object_destroy(testing_object_h *target)
+{
+    switch ((*target)->object_type)
+    {
+        case OBJECT_TYPE_IMAGE_OBJECT:
+        {
+            int err = mv_image_object_destroy((mv_image_object_h)((*target)->entity));
+            if (MEDIA_VISION_ERROR_NONE != err)
+            {
+                printf("\nERROR: Errors were occurred during image object "
+                        "destroying; code %i\n", err);
+            }
+            break;
+        }
+        case OBJECT_TYPE_IMAGE_TRACKING_MODEL:
+        {
+            int err = mv_image_tracking_model_destroy(
+                    (mv_image_tracking_model_h)((*target)->entity));
+            if (MEDIA_VISION_ERROR_NONE != err)
+            {
+                printf("\nERROR: Errors were occurred during image tracking "
+                        "model destroying; code %i\n", err);
+            }
+            break;
+        }
+    }
+    free(*target);
+    (*target) = NULL;
+}
+
+typedef struct
+{
+    mv_quadrangle_s **locations;
+    unsigned int locations_size;
+    unsigned int currently_number;
+} recognition_result;
+
+void destroy_recognition_result(recognition_result *result)
+{
+    if (result->locations_size == 0)
+    {
+        return;
+    }
+
+    int i = 0;
+    for (; i < result->locations_size; ++i)
+    {
+        if (NULL != result->locations[i])
+        {
+            free(result->locations[i]);
+        }
+    }
+    free(result->locations);
+}
+
+void recognized_cb(
+        mv_source_h source,
+        mv_engine_config_h engine_cfg,
+        const mv_image_object_h *image_objects,
+        mv_quadrangle_s **locations,
+        unsigned int number_of_objects,
+        void *user_data)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (NULL == user_data)
+    {
+        return;
+    }
+
+    recognition_result *result = (recognition_result*)user_data;
+
+    int object_num = 0;
+    for(; object_num < number_of_objects; ++object_num)
+    {
+        if (result->currently_number >= result->locations_size)
+        {
+            return;
+        }
+
+        if (NULL == locations[object_num])
+        {
+            result->locations[result->currently_number] = NULL;
+        }
+        else
+        {
+            result->locations[result->currently_number] = malloc(sizeof(mv_quadrangle_s));
+            *(result->locations[result->currently_number]) = *(locations[object_num]);
+        }
+
+        ++result->currently_number;
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+}
+
+void handle_recognition_result(
+        const recognition_result *result,
+        int number_of_objects,
+        mv_source_h *source,
+        char *file_name)
+{
+    int is_source_data_loaded = 0;
+
+    unsigned char *out_buffer = NULL;
+    int buffer_size = 0;
+    image_data_s image_data = { 0, 0, MEDIA_VISION_COLORSPACE_INVALID };
+
+    if (MEDIA_VISION_ERROR_NONE != mv_source_get_buffer(source, &(out_buffer), &buffer_size) ||
+        MEDIA_VISION_ERROR_NONE != mv_source_get_width(source, &(image_data.image_width)) ||
+        MEDIA_VISION_ERROR_NONE != mv_source_get_height(source, &(image_data.image_height)) ||
+        MEDIA_VISION_ERROR_NONE != mv_source_get_colorspace(source, &(image_data.image_colorspace)) ||
+        NULL == file_name)
+    {
+        printf("ERROR: Creating out image is impossible.\n");
+    }
+    else
+    {
+        is_source_data_loaded = 1;
+    }
+
+    int object_num = 0;
+
+
+    for (; object_num < number_of_objects; ++object_num)
+    {
+        if (NULL == result->locations[object_num])
+        {
+            printf("\nImage #%i is not recognized\n", object_num);
+            continue;
+        }
+
+        printf("\nImage #%i is recognized\n", object_num);
+        printf("Recognized image coordinates:\n");
+
+        int point_num = 0;
+        for (; point_num < 4; ++point_num)
+        {
+            printf("%d point - x = %d, y = %d\n", point_num + 1,
+                    result->locations[object_num]->points[point_num].x,
+                    result->locations[object_num]->points[point_num].y);
+        }
+
+        if (is_source_data_loaded)
+        {
+            const int thickness = 2;
+            const int color[] = {0, 255, 0};
+
+            const int err = draw_quadrangle_on_buffer(
+                    *(result->locations[object_num]),
+                    thickness,
+                    color,
+                    &image_data,
+                    out_buffer);
+
+            if (MEDIA_VISION_ERROR_NONE != err)
+            {
+                printf("ERROR: Impossible to draw quadrangle\n");
+            }
+        }
+    }
+    if (save_image_from_buffer(file_name, out_buffer,
+            &image_data, 100) != MEDIA_VISION_ERROR_NONE)
+    {
+       printf("\nERROR: Failed to generate output file\n");
+    }
+    else
+    {
+       printf("\nImage was generated as %s\n", file_name);
+    }
+}
+
+int generate_image_object_from_file(const char *path_to_image,
+                      bool roi_selected,
+                      mv_rectangle_s roi,
+                      mv_image_object_h *result)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    mv_source_h source;
+    int err = mv_create_source(&source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during source creating!!! code %i\n", err);
+    }
+
+    err = load_mv_source_from_file(path_to_image, source);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: image is not loaded; code %i\n", err);
+
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during source "
+                    "destroying; code %i\n", err2);
+        }
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    mv_engine_config_h config;
+    err = mv_create_engine_config(&config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: engine configuration is not created; code %i\n", err);
+
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during source "
+                    "destroying; code %i\n", err2);
+        }
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    err = mv_image_object_create(result);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during creating image object; "
+                "code %i\n", err);
+
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during source "
+                    "destroying; code %i\n", err2);
+        }
+
+        err2 = mv_destroy_engine_config(config);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during engine config "
+                    "destroying; code %i\n", err2);
+        }
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    if (roi_selected)
+    {
+        err = mv_image_object_fill(*result, config, source, &roi);
+    }
+    else
+    {
+        err = mv_image_object_fill(*result, config, source, NULL);
+    }
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: Errors were occurred during filling image object; "
+                "code %i\n", err);
+
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during source "
+                    "destroying; code %i\n", err2);
+        }
+
+        err2 = mv_image_object_destroy(*result);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during image object "
+                    "destroying; code %i\n", err2);
+        }
+
+        err2 = mv_destroy_engine_config(config);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during engine config "
+                    "destroying; code %i\n", err2);
+        }
+
+        *result = NULL;
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    err = mv_destroy_source(source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nERROR: Errors were occurred during source "
+                "destroying; code %i\n", err);
+
+        int err2 = mv_destroy_engine_config(config);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during engine config "
+                    "destroying; code %i\n", err2);
+        }
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    err = mv_destroy_engine_config(config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nERROR: Errors were occurred during engine config "
+                "destroying; code %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return err;
+}
+
+int recognize_image(const char *path_to_image,
+        const char *path_to_generated_image,
+        mv_image_object_h *targets,
+        int number_of_targets)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+
+    if (NULL == targets)
+    {
+        printf("\nYou must create at least one model for recognition\n");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    mv_source_h source;
+    int err = mv_create_source(&source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nERROR: Errors were occurred during source creating; code %i\n", err);
+        return err;
+    }
+
+    err = load_mv_source_from_file(path_to_image, source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: image is not loaded; code %i\n", err);
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during source destroying; "
+                    "code %i\n", err2);
+        }
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    recognition_result result;
+    result.currently_number = 0;
+    if (0 < number_of_targets)
+    {
+        result.locations = malloc(sizeof(mv_quadrangle_s*) * number_of_targets);
+        result.locations_size = number_of_targets;
+    }
+    else
+    {
+        result.locations = NULL;
+        result.locations_size = 0;
+    }
+
+    mv_engine_config_h config;
+    err = mv_create_engine_config(&config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: engine configuration is not created; code %i\n", err);
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during source destroying;"
+                    "code %i\n", err2);
+        }
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    err = mv_image_recognize(source, targets, number_of_targets, config,
+                             recognized_cb, &result);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nERROR: Image is not recognized; code %i\n", err);
+
+        destroy_recognition_result(&result);
+
+        int err2 = mv_destroy_source(source);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during source "
+                    "destroying; code %i\n", err2);
+        }
+        err2 = mv_destroy_engine_config(config);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during engine config "
+                    "destroying; code %i\n", err2);
+        }
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    handle_recognition_result(&result, number_of_targets, source,
+            path_to_generated_image);
+
+    destroy_recognition_result(&result);
+
+    err = mv_destroy_source(source);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nERROR: Errors were occurred during source destroying; code %i\n",
+                err);
+
+        int err2 = mv_destroy_engine_config(config);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during engine config "
+                    "destroying; code %i\n", err2);
+        }
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    err = mv_destroy_engine_config(config);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nERROR: Errors were occurred during engine config destroying; "
+                "code %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_get_confidence(mv_image_object_h target)
+{
+    if (NULL == target)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    double confidence = 0;
+    const int err = mv_image_object_get_recognition_rate(target, &confidence);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nError: confidence hasn't been received with error code %i\n", err);
+        return err;
+    }
+
+    printf("\nConfidence has been successfully received. Its value equal %f.\n", confidence);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int perform_set_label(mv_image_object_h target)
+{
+    if (NULL == target)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int label = 0;
+
+    while (input_int("Input label (int):", INT_MIN, INT_MAX,
+            &label) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    const int err = mv_image_object_set_label(target, label);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nError: the label hasn't been set with error code %i\n", err);
+        return err;
+    }
+
+    printf("\nLabel has been successfully set.\n");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int perform_get_label(mv_image_object_h target)
+{
+    if (NULL == target)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    int label = 0;
+    const int err = mv_image_object_get_label(target, &label);
+    if (MEDIA_VISION_ERROR_NO_DATA == err)
+    {
+        printf("\nSelected image object haven't label.\n");
+        return MEDIA_VISION_ERROR_NONE;
+    }
+    else if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nError: label hasn't been received with error code %i\n", err);
+        return err;
+    }
+
+    printf("\nLabel has been successfully received. Its equal %i.\n", label);
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int perform_recognize(mv_image_object_h *targets, int number_of_targets)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    char *path_to_image = NULL;
+    char *path_to_generated_image = NULL;
+
+    while (input_string("Input file name with image for recognizing:",
+                         1024, &path_to_image) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    while (input_string("Input file name for generated image:",
+                         1024, &path_to_generated_image) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    const int err = recognize_image(path_to_image, path_to_generated_image, targets,
+            number_of_targets);
+
+    free(path_to_image);
+    free(path_to_generated_image);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_load_image_object(char **path_to_object, mv_image_object_h *result)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (NULL != (*result))
+    {
+        mv_image_object_destroy(*result);
+        *result = NULL;
+    }
+
+    while (input_string("Input file name with image object to be loaded:",
+                         1024, path_to_object) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    int err = mv_image_object_load(result, *path_to_object);
+
+    if (MEDIA_VISION_ERROR_NONE != err && NULL != (*result))
+    {
+        printf("Error: object isn't loaded with error code %i\n", err);
+        return err;
+    }
+
+    printf("\nObject successfully loaded\n");
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+    return err;
+}
+
+int perform_save_image_object(mv_image_object_h object)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int err = MEDIA_VISION_ERROR_NONE;
+    char *path_to_object = NULL;
+
+    while (input_string("Input file name to be generated for image object storing:",
+                         1024, &path_to_object) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    err = mv_image_object_save(path_to_object, object);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nError during saving the image object. Error code is %i\n", err);
+        free(path_to_object);
+        return err;
+    }
+
+    printf("\nObject successfully saved\n");
+
+    free(path_to_object);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_generate_image_object(mv_image_object_h *result, char **path_to_image)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (NULL == path_to_image || NULL == result)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    while (input_string("Input file name with image to be analyzed:",
+                         1024, path_to_image) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    mv_rectangle_s roi;
+    const bool sel_roi = show_confirm_dialog("Select if you want to set ROI");
+    if (sel_roi)
+    {
+        printf("\nInput ROI coordinates\n");
+        while (input_int("Input x coordinate:", INT_MIN, INT_MAX,
+                &(roi.point.x)) == -1)
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+
+        while (input_int("Input y coordinate:", INT_MIN, INT_MAX,
+                &(roi.point.y)) == -1)
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+
+        while (input_int("Input ROI width:", INT_MIN, INT_MAX,
+                &(roi.width)) == -1)
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+
+        while (input_int("Input ROI height:", INT_MIN, INT_MAX,
+                &(roi.height)) == -1)
+        {
+            printf("Incorrect input! Try again.\n");
+        }
+
+    }
+
+    int err = generate_image_object_from_file(*path_to_image, sel_roi, roi, result);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nError in generation image object. Error code is %i\n", err);
+
+        if (NULL != (*result))
+        {
+            mv_image_object_destroy(*result);
+            (*result) = NULL;
+        }
+
+        return err;
+    }
+
+    printf("\nObject successfully generated\n");
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_clone_image_object(mv_image_object_h src, mv_image_object_h *result)
+{
+    int err = mv_image_object_clone(src, result);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nError: object isn't cloned with error code %i\n", err);
+
+        int err2 = mv_image_object_destroy(*result);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during image object "
+                    "destroying; code %i\n", err);
+        }
+
+        (*result) = NULL;
+
+        return err;
+    }
+
+    printf("\nObject successfully cloned\n");
+
+    return err;
+}
+
+int handle_tracking_result(
+        mv_video_writer_h writer,
+        mv_source_h frame,
+        int frame_number,
+        mv_quadrangle_s *location)
+{
+    unsigned char *data_buffer = NULL;
+    unsigned int buffer_size = 0;
+    image_data_s image_data;
+
+    int err = mv_source_get_buffer(frame, &data_buffer, &buffer_size);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "ERROR: Errors were occurred during getting buffer from the "
+                "source; code %i\n",
+                err);
+        return err;
+    }
+
+    err = mv_source_get_width(frame, &image_data.image_width);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "ERROR: Errors were occurred during getting width from the "
+                "source; code %i\n",
+                err);
+        return err;
+    }
+
+    err = mv_source_get_height(frame, &image_data.image_height);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "ERROR: Errors were occurred during getting height from the "
+                "source; code %i\n",
+                err);
+        return err;
+    }
+
+    if (location)
+    {
+        printf(
+                "Frame #%i: object is found."
+                "Location: {%i, %i}; {%i, %i}; {%i, %i}; {%i, %i}.\n",
+                frame_number,
+                location->points[0].x,
+                location->points[0].y,
+                location->points[1].x,
+                location->points[1].y,
+                location->points[2].x,
+                location->points[2].y,
+                location->points[3].x,
+                location->points[3].y);
+        const int thickness = 2;
+        const int color[] = {0, 255, 0};
+
+        err = draw_quadrangle_on_buffer(
+                *location,
+                thickness,
+                color,
+                &image_data,
+                data_buffer);
+        if (MEDIA_VISION_ERROR_NONE != err)
+        {
+            printf(
+                    "ERROR: Errors were occurred during drawing quadrangle on "
+                    "the frame; code %i\n",
+                    err);
+            return err;
+        }
+    }
+    else
+    {
+        usleep(1000000);
+        printf("Frame #%i: object isn't found.\n", frame_number);
+    }
+
+    err = mv_video_writer_write_frame(writer, data_buffer);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "ERROR: Errors were occurred during writing frame to the "
+                "result video file; code %i\n",
+                err);
+        return err;
+    }
+
+    return err;
+}
+
+typedef struct
+{
+    mv_image_tracking_model_h target;
+    mv_video_writer_h writer;
+    int frame_number;
+} tracking_cb_data;
+
+void tracked_cb(
+        mv_source_h source,
+        mv_image_object_h image_object,
+        mv_engine_config_h engine_cfg,
+        mv_quadrangle_s *location,
+        void *user_data)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    if (NULL == user_data)
+    {
+        return;
+    }
+
+    tracking_cb_data *cb_data = (tracking_cb_data*)user_data;
+
+    handle_tracking_result(cb_data->writer, source, cb_data->frame_number, location);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+}
+
+void new_frame_cb(
+        char *buffer,
+        unsigned int buffer_size,
+        image_data_s image_data,
+        void *user_data)
+{
+    if (NULL == user_data)
+    {
+        return;
+    }
+
+    mv_source_h frame = NULL;
+
+#define release_resources() \
+    if (frame) \
+    { \
+        const int err2 = mv_destroy_source(frame); \
+        if (MEDIA_VISION_ERROR_NONE != err2) \
+        { \
+            printf( \
+                    "\nERROR: Errors were occurred during source destroying; " \
+                    "code %i\n", \
+                    err2); \
+        } \
+    }
+
+    tracking_cb_data *cb_data = (tracking_cb_data*)user_data;
+
+    ++(cb_data->frame_number);
+
+    int err = mv_create_source(&frame);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "\nERROR: Errors were occurred during source creating; "
+                "code %i\n",
+                err);
+        release_resources();
+        return;
+    }
+
+    err = mv_source_fill_by_buffer(
+            frame,
+            buffer,
+            buffer_size,
+            image_data.image_width,
+            image_data.image_height,
+            image_data.image_colorspace);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("ERROR: mv_source_h for frame is not filled; code %i\n", err);
+        release_resources();
+        return;
+    }
+
+    err = mv_image_track(
+            frame,
+            cb_data->target,
+            NULL,
+            tracked_cb,
+            cb_data);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "ERROR: Errors were occurred during tracking object on "
+                "the video; code %i\n",
+                err);
+        release_resources();
+        return;
+    }
+
+    release_resources()
+
+#undef release_resources()
+}
+
+void eos_frame_cb(
+        void *user_data)
+{
+    if (NULL == user_data)
+    {
+        printf("ERROR: eos callback can't stop tracking process.");
+        return;
+    }
+
+    pthread_mutex_unlock((pthread_mutex_t*)user_data);
+}
+
+int perform_track(mv_image_tracking_model_h target)
+{
+    if (NULL == target)
+    {
+        printf("\nTarget is invalid. It is impossible to track of this target.\n");
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    mv_video_reader_h reader = NULL;
+    mv_video_writer_h writer = NULL;
+    char *path_to_video = NULL;
+    char *path_to_generated_video = NULL;
+    image_data_s image_data = {0};
+    unsigned int fps = 0;
+
+#define release_resources() \
+    int err2 = MEDIA_VISION_ERROR_NONE; \
+    if (reader) \
+    { \
+        err2 = mv_destroy_video_reader(reader); \
+        if (MEDIA_VISION_ERROR_NONE != err2) \
+        { \
+            printf( \
+                    "\nERROR: Errors were occurred during video reader destroying; " \
+                    "code %i\n", \
+                    err2); \
+        } \
+    } \
+    if (writer) \
+    { \
+        err2 = mv_destroy_video_writer(writer); \
+        if (MEDIA_VISION_ERROR_NONE != err2) \
+        { \
+            printf( \
+                    "\nERROR: Errors were occurred during video writer destroying; " \
+                    "code %i\n", \
+                    err2); \
+        } \
+    } \
+    if (path_to_video) \
+    { \
+        free(path_to_video); \
+    } \
+    if (path_to_generated_video) \
+    { \
+        free(path_to_generated_video); \
+    }
+
+    while (input_string("Input file name with video for tracking:",
+                         1024, &path_to_video) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    while (input_string("Input file name for generated video:",
+                         1024, &path_to_generated_video) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    int err = mv_create_video_reader(&reader);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nERROR: Errors were occurred during video reader creating; "
+                "code %i\n", err);
+        release_resources();
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    err = mv_create_video_writer(&writer);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "\nERROR: Errors were occurred during video writer creating; "
+                "code %i\n",
+                err);
+        release_resources();
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    err = mv_video_reader_load(
+        reader,
+        path_to_video,
+        &image_data,
+        &fps);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nERROR: Errors were occurred during video loading; code %i\n", err);
+        release_resources();
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    printf("Receive frame metadata: wxh - %ux%u, fps - %u, format - %d\n",
+        image_data.image_width, image_data.image_height, fps, image_data.image_colorspace);
+
+    // Temporary we accept only RGB888
+    image_data.image_colorspace = MEDIA_VISION_COLORSPACE_RGB888;
+
+    err = mv_video_writer_init(
+            writer,
+            path_to_generated_video,
+            image_data,
+            fps);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "\nERROR: Errors were occurred during video writer initializing; "
+                "code %i\n",
+                err);
+        release_resources();
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    tracking_cb_data cb_data;
+    cb_data.target = target;
+    cb_data.writer = writer;
+    cb_data.frame_number = 0;
+    err = mv_video_reader_set_new_sample_cb(reader, new_frame_cb, &cb_data);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "\nERROR: Errors were occurred during set new frame callback; "
+                "code %i\n",
+                err);
+        release_resources();
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    pthread_mutex_t block_during_tracking_mutex;
+    pthread_mutex_init(&block_during_tracking_mutex, NULL);
+    pthread_mutex_lock(&block_during_tracking_mutex);
+    err = mv_video_reader_set_eos_cb(reader, eos_frame_cb, &block_during_tracking_mutex);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "\nERROR: Errors were occurred during set new frame callback; "
+                "code %i\n",
+                err);
+        release_resources();
+        pthread_mutex_unlock(&block_during_tracking_mutex);
+        pthread_mutex_destroy(&block_during_tracking_mutex);
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    err = mv_video_reader_start(reader);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "\nERROR: Errors were occurred during video reading starts; "
+                "code %i\n",
+                err);
+        release_resources();
+        pthread_mutex_unlock(&block_during_tracking_mutex);
+        pthread_mutex_destroy(&block_during_tracking_mutex);
+        MEDIA_VISION_FUNCTION_LEAVE();
+        return err;
+    }
+
+    pthread_mutex_lock(&block_during_tracking_mutex);
+    pthread_mutex_unlock(&block_during_tracking_mutex);
+    pthread_mutex_destroy(&block_during_tracking_mutex);
+    release_resources();
+
+#undef release_resources()
+
+    printf("\nTracking process is finished\n");
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_save_image_tracking_model(mv_image_tracking_model_h model)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int err = MEDIA_VISION_ERROR_NONE;
+    char *path_to_file = NULL;
+
+    while (input_string(
+            "Input file name to be generated for image tracking model storing:",
+            1024,
+            &path_to_file) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    err = mv_image_tracking_model_save(path_to_file, model);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf(
+                "\nError during saving the image tracking model. "
+                "Error code is %i\n",
+                err);
+        free(path_to_file);
+        return err;
+    }
+
+    printf("\nTracking model successfully saved\n");
+
+    free(path_to_file);
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_load_image_tracking_model(
+        char **path_to_file, mv_image_tracking_model_h *result)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    while (input_string(
+            "Input file name with image tracking model to be loaded:",
+            1024,
+            path_to_file) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+
+    int err = mv_image_tracking_model_load(*path_to_file, result);
+
+    if (MEDIA_VISION_ERROR_NONE != err && NULL != (*result))
+    {
+        printf("Error: tracking model isn't loaded with error code %i\n", err);
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    printf("\nTracking model successfully loaded\n");
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_clone_image_tracking_model(
+        mv_image_tracking_model_h src,
+        mv_image_tracking_model_h *result)
+{
+    MEDIA_VISION_FUNCTION_ENTER();
+
+    int err = mv_image_tracking_model_clone(src, result);
+
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nError: tracking model isn't cloned with error code %i\n", err);
+
+        int err2 = mv_image_tracking_model_destroy(*result);
+        if (MEDIA_VISION_ERROR_NONE != err2)
+        {
+            printf("\nERROR: Errors were occurred during tracking model "
+                    "destroying; code %i\n", err);
+        }
+
+        (*result) = NULL;
+
+        MEDIA_VISION_FUNCTION_LEAVE();
+
+        return err;
+    }
+
+    printf("\nTracking model successfully cloned\n");
+
+    MEDIA_VISION_FUNCTION_LEAVE();
+
+    return err;
+}
+
+int perform_refresh_image_tracking_model(mv_image_tracking_model_h target)
+{
+    if (NULL == target)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+
+    const int err = mv_image_tracking_model_refresh(target, NULL);
+    if (MEDIA_VISION_ERROR_NONE != err)
+    {
+        printf("\nError: tracking model isn't refreshed with error code %i\n", err);
+        return err;
+    }
+
+    printf("\nTracking model is successfully refreshed.\n");
+
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+void show_testing_objects(const char *title, GArray *testing_objects)
+{
+    printf("\n");
+    int i = 0;
+    if (1 > testing_objects->len)
+    {
+        printf("There are no created objects.\n");
+    }
+    else
+    {
+        printf("%s:\n", title);
+        printf("-------------------------------------------------------------------------------------\n");
+        for (i = 0; i < testing_objects->len; ++i)
+        {
+            testing_object_h temp = g_array_index (testing_objects, testing_object_h, i);
+            if (OBJECT_TYPE_IMAGE_OBJECT == temp->object_type)
+            {
+                printf("Image object ");
+            }
+            else if (OBJECT_TYPE_IMAGE_TRACKING_MODEL == temp->object_type)
+            {
+                printf("Image tracking model ");
+            }
+            else
+            {
+                printf("Unknown testing object ");
+            }
+            printf("#%i. %s\n", i, temp->actual_label);
+        }
+        printf("-------------------------------------------------------------------------------------\n");
+    }
+}
+
+int select_testing_object(GArray *testing_objects, testing_object_h *result, char *title)
+{
+    if (0 == testing_objects->len)
+    {
+        printf("Firstly you must create at least one testing object.\n");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    show_testing_objects(title, testing_objects);
+    int sel_index = 0;
+    while (input_int("Input number of element:", 0,
+            testing_objects->len - 1, &sel_index) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+    (*result) = g_array_index(testing_objects, testing_object_h, sel_index);
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int select_testing_object_index(GArray *testing_objects, guint *result_index, char *title)
+{
+    if (0 == testing_objects->len)
+    {
+        printf("Firstly you must create at least one testing object.\n");
+        return MEDIA_VISION_ERROR_INVALID_OPERATION;
+    }
+
+    show_testing_objects(title, testing_objects);
+
+    int sel_index = 0;
+    while (input_int("Input number of element:", 0,
+            testing_objects->len - 1, &sel_index) == -1)
+    {
+        printf("Incorrect input! Try again.\n");
+    }
+    (*result_index) = sel_index;
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int add_testing_object(GArray *testing_objects, testing_object_h object)
+{
+    if (NULL == object)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+    g_array_append_val(testing_objects, object);
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+int remove_testing_object(GArray *testing_objects, guint index)
+{
+    if (index >= testing_objects->len)
+    {
+        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+    }
+    g_array_remove_index(testing_objects, index);
+    return MEDIA_VISION_ERROR_NONE;
+}
+
+void perform_recognition_cases(GArray *image_objects)
+{
+    const char *names[] = {
+            "Show created set of image objects",
+            "Generate new image object from source image  (mv_image_object_fill )",
+            "Load existed image object from file          (mv_image_object_load)",
+            "Clone existed image object                   (mv_image_object_clone)",
+            "Create empty image object                    (mv_image_object_create)",
+            "Save existed image object to the file        (mv_image_object_save)",
+            "Remove image object from created set         (mv_image_object_destroy)",
+            "Get confidence from existed image object     (mv_image_object_get_recognition_rate)",
+            "Recognize all image objects on image         (mv_image_recognize)",
+            "Set label for existed image object           (mv_image_set_label_of_object)",
+            "Get label from existed image object          (mv_image_get_label_of_object)",
+            "Back to the main menu"};
+
+    int number_of_options = sizeof(names) / sizeof(names[0]);
+    int options[number_of_options];
+    int index = 0;
+    for (; index < number_of_options; ++index)
+    {
+        options[index] = index + 1;
+    }
+
+    while (1)
+    {
+        int err = MEDIA_VISION_ERROR_NONE;
+
+        int sel_opt = show_menu("Select action:", options, names, number_of_options);
+
+        switch (sel_opt)
+        {
+            case 1: // Show created set of image objects
+            {
+                show_testing_objects("Set of image objects", image_objects);
+                break;
+            }
+            case 2: // Generate new image object from source image (mv_image_object_fill)
+            {
+                mv_image_object_h temporary = NULL;
+                char *path_to_image = NULL;
+
+                err = perform_generate_image_object(&temporary, &path_to_image);
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf("Generation failed (error code - %i)\n", err);
+                    if (NULL != path_to_image)
+                    {
+                        free(path_to_image);
+                    }
+                    break;
+                }
+
+                testing_object_h added_object;
+                testing_object_create(&added_object);
+                testing_object_fill(added_object, temporary,
+                        OBJECT_TYPE_IMAGE_OBJECT, SOURCE_TYPE_GENERATION, path_to_image);
+
+                if (NULL != path_to_image)
+                {
+                    free(path_to_image);
+                }
+
+                add_testing_object(image_objects, added_object);
+                break;
+            }
+            case 3: // Load existed image object from file (mv_image_object_load)
+            {
+                mv_image_object_h temporary_image_object = NULL;
+                char *path_to_object = NULL;
+
+                err = perform_load_image_object(
+                        &path_to_object, &temporary_image_object);
+
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf("Loading failed (error code - %i)\n", err);
+                    break;
+                }
+
+                testing_object_h added_object = NULL;
+                testing_object_create(&added_object);
+                testing_object_fill(
+                        added_object,
+                        temporary_image_object,
+                        OBJECT_TYPE_IMAGE_OBJECT,
+                        SOURCE_TYPE_LOADING,
+                        path_to_object);
+
+                free(path_to_object);
+
+                add_testing_object(image_objects, added_object);
+                break;
+            }
+            case 4: // Clone existed image object (mv_image_object_clone)
+            {
+                if (image_objects->len <= 0)
+                {
+                    printf("\nFirstly you must create at least one image object.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(
+                        image_objects,
+                        &temporary_testing_object,
+                        "Select the object you want to clone");
+
+                mv_image_object_h temporary_image_object = NULL;
+                perform_clone_image_object(
+                        temporary_testing_object->entity,
+                        &temporary_image_object);
+
+                testing_object_h added_object = NULL;
+                testing_object_create(&added_object);
+                testing_object_fill(
+                        added_object,
+                        temporary_image_object,
+                        OBJECT_TYPE_IMAGE_OBJECT,
+                        SOURCE_TYPE_CLONING,
+                        temporary_testing_object);
+
+                add_testing_object(image_objects, added_object);
+                break;
+            }
+            case 5: // Create empty image object (mv_image_object_create)
+            {
+                mv_image_object_h temporary_image_object = NULL;
+                int err = mv_image_object_create(&temporary_image_object);
+
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf("ERROR: image object creation is failed with code %i\n", err);
+                    break;
+                }
+
+                testing_object_h added_object = NULL;
+                testing_object_create(&added_object);
+                testing_object_fill(
+                        added_object,
+                        temporary_image_object,
+                        OBJECT_TYPE_IMAGE_OBJECT,
+                        SOURCE_TYPE_EMPTY,
+                        NULL);
+
+                add_testing_object(image_objects, added_object);
+                printf("\nImage object successfully created\n");
+                break;
+            }
+            case 6: // Save existed image object to the file (mv_image_object_save)
+            {
+                if (image_objects->len <= 0)
+                {
+                    printf("\nFirstly you must create at least one image object.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(image_objects, &temporary_testing_object,
+                        "Select the object you want to save");
+                perform_save_image_object(temporary_testing_object->entity);
+                break;
+            }
+            case 7: // Remove image object from created set (mv_image_object_destroy)
+            {
+                if (image_objects->len <= 0)
+                {
+                    printf("\nFirstly you must create at least one image object.\n");
+                    break;
+                }
+
+                guint selected_index;
+                int err = select_testing_object_index(
+                        image_objects,
+                        &selected_index,
+                        "Select the object you want to remove");
+                if (MEDIA_VISION_ERROR_NONE == err)
+                {
+                    remove_testing_object(image_objects, selected_index);
+                    printf("\nImage object successfully removed\n");
+                }
+                break;
+            }
+            case 8: // Get confidence from existed image object (mv_image_object_get_recognition_rate)
+            {
+                if (image_objects->len <= 0)
+                {
+                    printf("\nFirstly you must create at least one image object.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(image_objects, &temporary_testing_object,
+                        "Select the object from which you want getting confidence");
+                perform_get_confidence(temporary_testing_object->entity);
+                break;
+            }
+            case 9: // Recognize all image objects on image (mv_image_recognize)
+            {
+                if (image_objects->len <= 0)
+                {
+                    printf("\nFirstly you must create at least one image object.\n");
+                    break;
+                }
+
+                mv_image_object_h *objects_pool = malloc(sizeof(mv_image_object_h) * image_objects->len);
+                int index = 0;
+                for (;index < image_objects->len; ++index)
+                {
+                    objects_pool[index] = g_array_index(image_objects, testing_object_h, index)->entity;
+                }
+                perform_recognize(objects_pool, image_objects->len);
+                free(objects_pool);
+                break;
+            }
+            case 10: // Set label for existed image object (mv_image_object_set_label)
+            {
+                if (image_objects->len <= 0)
+                {
+                    printf("\nFirstly you must create at least one image object.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(image_objects, &temporary_testing_object,
+                        "Select the object for which you want setting label");
+                perform_set_label(temporary_testing_object->entity);
+                break;
+            }
+            case 11: // Get label from existed image object (mv_image_object_get_label)
+            {
+                if (image_objects->len <= 0)
+                {
+                    printf("\nFirstly you must create at least one image object.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(image_objects, &temporary_testing_object,
+                        "Select the object from which you want getting label");
+                perform_get_label(temporary_testing_object->entity);
+                break;
+            }
+            case 12: // Back to the main menu
+            {
+                return;
+            }
+            default:
+                printf("Invalid option.\n");
+        }
+    }
+}
+
+void perform_tracking_cases(GArray *image_objects, GArray *image_tracking_models)
+{
+    const char *names[] = {
+            "Show created set of tracking models",
+            "Create empty tracking model              (mv_image_tracking_model_create)",
+            "Generate model based on image object     (mv_image_tracking_model_set_target)",
+            "Load existed tracking model from file    (mv_image_tracking_model_load)",
+            "Clone existed tracking model             (mv_image_tracking_model_clone)",
+            "Save existed tracking model to the file  (mv_image_tracking_model_save)",
+            "Remove tracking model from created set   (mv_image_tracking_model_destroy)",
+            "Refresh tracking model                   (mv_image_tracking_model_refresh)",
+            "Track                                    (mv_image_track)",
+            "Back to the main menu"};
+
+    int number_of_options = sizeof(names) / sizeof(names[0]);
+    int options[number_of_options];
+    int index = 0;
+    for (; index < number_of_options; ++index)
+    {
+        options[index] = index + 1;
+    }
+
+    while (1)
+    {
+        int err = MEDIA_VISION_ERROR_NONE;
+
+        int sel_opt = show_menu("Select action:", options, names, number_of_options);
+
+        switch (sel_opt)
+        {
+            case 1: // Show created set of tracking models
+            {
+                show_testing_objects("Set of image tracking models", image_tracking_models);
+                break;
+            }
+            case 2: // Create empty tracking model (mv_image_tracking_model_create)
+            {
+                mv_image_tracking_model_h temporary_image_tracking_model = NULL;
+
+                int err = mv_image_tracking_model_create(&temporary_image_tracking_model);
+
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf("ERROR: tracking model creation is failed with code %i\n", err);
+                    break;
+                }
+
+                testing_object_h added_object = NULL;
+                testing_object_create(&added_object);
+                testing_object_fill(
+                        added_object,
+                        temporary_image_tracking_model,
+                        OBJECT_TYPE_IMAGE_TRACKING_MODEL,
+                        SOURCE_TYPE_EMPTY,
+                        NULL);
+
+                add_testing_object(image_tracking_models, added_object);
+                printf("\nTracking model successfully created\n");
+                break;
+            }
+            case 3: // Generate model based on image object (mv_image_tracking_model_set_target)
+            {
+                if (image_objects->len <= 0)
+                {
+                    printf("\nFirstly you must create at least one image object.\n");
+                    break;
+                }
+
+                mv_image_tracking_model_h temporary_image_tracking_model = NULL;
+                err = mv_image_tracking_model_create(&temporary_image_tracking_model);
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf("Error: tracking model isn't created with error code %i\n", err);
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(
+                        image_objects,
+                        &temporary_testing_object,
+                        "Select the image object for tracking");
+
+                err = mv_image_tracking_model_set_target(
+                        (mv_image_object_h)(temporary_testing_object->entity),
+                        temporary_image_tracking_model);
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf("Error: target isn't set with error code %i\n", err);
+                    break;
+                }
+
+                testing_object_h added_object = NULL;
+                testing_object_create(&added_object);
+                testing_object_fill(
+                        added_object,
+                        temporary_image_tracking_model,
+                        OBJECT_TYPE_IMAGE_TRACKING_MODEL,
+                        SOURCE_TYPE_GENERATION,
+                        temporary_testing_object);
+
+                add_testing_object(image_tracking_models, added_object);
+                printf("\nTracking model successfully generated\n");
+                break;
+            }
+            case 4: // Load existed tracking model from file (mv_image_tracking_model_load)
+            {
+                mv_image_tracking_model_h temporary_image_tracking_model = NULL;
+                char *path_to_object = NULL;
+
+                err = perform_load_image_tracking_model(
+                        &path_to_object, &temporary_image_tracking_model);
+
+                if (MEDIA_VISION_ERROR_NONE != err)
+                {
+                    printf("Loading failed (error code - %i)\n", err);
+                    break;
+                }
+
+                testing_object_h added_object = NULL;
+                testing_object_create(&added_object);
+                testing_object_fill(
+                        added_object,
+                        temporary_image_tracking_model,
+                        OBJECT_TYPE_IMAGE_TRACKING_MODEL,
+                        SOURCE_TYPE_LOADING,
+                        path_to_object);
+
+                free(path_to_object);
+
+                add_testing_object(image_tracking_models, added_object);
+                break;
+            }
+            case 5: // Clone existed tracking model (mv_image_tracking_model_clone)
+            {
+                if (image_tracking_models->len <= 0)
+                {
+                    printf(
+                            "\nFirstly you must create at least one image "
+                            "tracking model.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(
+                        image_tracking_models,
+                        &temporary_testing_object,
+                        "Select the tracking model you want to clone");
+
+                mv_image_tracking_model_h temporary_image_tracking_model = NULL;
+                perform_clone_image_tracking_model(
+                        temporary_testing_object->entity,
+                        &temporary_image_tracking_model);
+
+                testing_object_h added_object = NULL;
+                testing_object_create(&added_object);
+                testing_object_fill(
+                        added_object,
+                        temporary_image_tracking_model,
+                        OBJECT_TYPE_IMAGE_TRACKING_MODEL,
+                        SOURCE_TYPE_CLONING,
+                        temporary_testing_object);
+
+                add_testing_object(image_tracking_models, added_object);
+                break;
+            }
+            case 6: // Save existed tracking model to the file (mv_image_tracking_model_save)
+            {
+                if (image_tracking_models->len <= 0)
+                {
+                    printf(
+                            "\nFirstly you must create at least one image "
+                            "tracking model.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(
+                        image_tracking_models,
+                        &temporary_testing_object,
+                        "Select the tracking model you want to save");
+
+                perform_save_image_tracking_model(temporary_testing_object->entity);
+                break;
+            }
+            case 7: // Remove tracking model from created set (mv_image_tracking_model_destroy)
+            {
+                if (image_tracking_models->len <= 0)
+                {
+                    printf(
+                            "\nFirstly you must create at least one image "
+                            "tracking model.\n");
+                    break;
+                }
+
+                guint selected_index;
+                err = select_testing_object_index(
+                        image_tracking_models,
+                        &selected_index,
+                        "Select the object you want to remove");
+
+                if (MEDIA_VISION_ERROR_NONE == err)
+                {
+                    remove_testing_object(image_tracking_models, selected_index);
+                    printf("\nTracking model successfully removed\n");
+                }
+                break;
+            }
+            case 8: // Refresh tracking model (mv_image_tracking_model_refresh)
+            {
+                if (image_tracking_models->len <= 0)
+                {
+                    printf(
+                            "\nFirstly you must create at least one image "
+                            "tracking model.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                select_testing_object(
+                        image_tracking_models,
+                        &temporary_testing_object,
+                        "Select the tracking model you want to refresh");
+
+                perform_refresh_image_tracking_model(temporary_testing_object->entity);
+                break;
+            }
+            case 9: // Track (mv_image_track)
+            {
+                if (image_tracking_models->len <= 0)
+                {
+                    printf(
+                            "\nFirstly you must create at least one image "
+                            "tracking model.\n");
+                    break;
+                }
+
+                testing_object_h temporary_testing_object = NULL;
+                err = select_testing_object(
+                        image_tracking_models,
+                        &temporary_testing_object,
+                        "Select the object which you want to track on video");
+
+                if (MEDIA_VISION_ERROR_NONE == err)
+                {
+                    perform_track(temporary_testing_object->entity);
+                }
+                break;
+            }
+            case 10: // Back to the main menu
+            {
+                return;
+            }
+        }
+    }
+}
+
+int main(void)
+{
+    LOGI("Image Media Vision Testsuite is launched.");
+
+    GArray *image_objects = g_array_new(FALSE, FALSE, sizeof(testing_object_h));
+    GArray *image_tracking_models = g_array_new(FALSE, FALSE,sizeof(testing_object_h));
+
+    const int options[3] = { 1, 2, 3 };
+    const char *names[3] = {
+            "Recognition cases",
+            "Tracking cases",
+            "Exit" };
+
+    mv_image_object_h current_object = NULL;
+
+    while(1)
+    {
+        char exit = 'n';
+        int sel_opt = show_menu("Select action:", options, names, 3);
+        switch (sel_opt)
+        {
+            case 1: // Recognition cases
+                perform_recognition_cases(image_objects);
+                break;
+            case 2: // Tracking cases
+                perform_tracking_cases(image_objects, image_tracking_models);
+                break;
+            case 3: // Exit
+                exit = 'y';
+                break;
+            default:
+                printf("Invalid option.\n");
+                sel_opt = 0;
+                continue;
+        }
+        if ('y' == exit)
+        {
+            sel_opt = 0;
+            const int options_last[2] = { 1, 2 };
+            const char *names_last[2] = { "No", "Yes" };
+
+            while (sel_opt == 0)
+            {
+                sel_opt = show_menu("Are you sure?",
+                                     options_last, names_last, 2);
+                switch (sel_opt)
+                {
+                    case 1:
+                        exit = 'n';
+                        break;
+                    case 2:
+                        exit = 'y';
+                        break;
+                    default:
+                        printf("Invalid option. Back to the main menu.");
+                        sel_opt = 0;
+                        break;
+                }
+            }
+
+            if ('y' == exit)
+            {
+                break;
+            }
+        }
+
+    }
+
+    guint i = 0;
+    for (i = 0; i < image_objects->len; ++i)
+    {
+        testing_object_h temp = g_array_index(
+                image_objects,
+                testing_object_h,
+                i);
+        testing_object_destroy(&temp);
+    }
+    g_array_free(image_objects, TRUE);
+
+    for (i = 0; i < image_tracking_models->len; ++i)
+    {
+        testing_object_h temp = g_array_index(
+                image_tracking_models,
+                testing_object_h,
+                i);
+        testing_object_destroy(&temp);
+    }
+    g_array_free(image_tracking_models, TRUE);
+
+    LOGI("Image Media Vision Testsuite is closed");
+
+    return 0;
+}