瀏覽代碼

Merge branch 'master' of dbv.inf-cv.uni-jena.de:nice/nice-core

Erik Rodner 9 年之前
父節點
當前提交
417b6a9920
共有 79 個文件被更改,包括 2852 次插入596 次删除
  1. 113 8
      CMakeLists.txt
  2. 1 1
      Makefile
  3. 38 0
      NOTES
  4. 45 0
      cmake/FindLinAl.cmake
  5. 201 17
      cmake/NiceModules.cmake
  6. 2 2
      core/CMakeLists.txt
  7. 28 0
      core/NOTES
  8. 2 2
      core/algebra/libdepend.inc
  9. 18 1
      core/basics/Config.cpp
  10. 15 0
      core/basics/FileName.cpp
  11. 9 0
      core/basics/FileName.h
  12. 5 4
      core/basics/libdepend.inc
  13. 5 0
      core/basics/progs/testConfig.cpp
  14. 223 216
      core/iceconversion/image_convertice.h
  15. 15 0
      core/ignore/OpaqueT.cpp
  16. 15 0
      core/ignore/OpaqueT.h
  17. 12 0
      core/ignore/OpaqueT.tcc
  18. 1 1
      core/image/BlockImageAccessT.tcc
  19. 8 0
      core/image/FilterT.h
  20. 41 1
      core/image/FilterT.tcc
  21. 1 1
      core/image/GHough.cpp
  22. 2 7
      core/image/GrayColorImageCommonImplementationT.h
  23. 10 0
      core/image/GrayColorImageCommonImplementationT.tcc
  24. 3 0
      core/image/ImageFile.cpp
  25. 30 7
      core/image/MultiChannelImage3DT.h
  26. 129 56
      core/image/MultiChannelImage3DT.tcc
  27. 2 2
      core/image/MultiChannelImageT.h
  28. 7 7
      core/image/libdepend.inc
  29. 6 0
      core/image/tests/TestImageFile.cpp
  30. 6 0
      core/image/tests/TestImageFile.h
  31. 1 1
      core/imagedisplay/ArrayPlot.cpp
  32. 4 5
      core/imagedisplay/CaptureDialog.cpp
  33. 43 109
      core/imagedisplay/CaptureWidget.cpp
  34. 7 12
      core/imagedisplay/CaptureWidget.h
  35. 3 3
      core/imagedisplay/DefaultMainWindow.cpp
  36. 18 28
      core/imagedisplay/ImageDisplay.cpp
  37. 2 3
      core/imagedisplay/ImageDisplay.h
  38. 8 10
      core/imagedisplay/ImageDisplayManagerWidget.cpp
  39. 5 9
      core/imagedisplay/ImageDisplayManagerWidget.h
  40. 12 4
      core/imagedisplay/QtFramework.cpp
  41. 6 6
      core/imagedisplay/SimpleSelector.cpp
  42. 3 3
      core/imagedisplay/SimpleSelector.h
  43. 6 1
      core/imagedisplay/progs/showImage.cpp
  44. 0 1
      core/matlabAccess/MatFileIO.h
  45. 2 2
      core/matlabAccess/libdepend.inc
  46. 1 1
      core/optimization/gradientBased/OptimizationProblemFirst.h
  47. 1 1
      core/optimization/libdepend.inc
  48. 31 0
      core/tutorial/TODO
  49. 59 0
      core/tutorial/doc/00_install.md
  50. 155 0
      core/tutorial/doc/01_imageio.md
  51. 161 0
      core/tutorial/doc/02_grayscale.md
  52. 134 0
      core/tutorial/doc/03_color.md
  53. 96 0
      core/tutorial/doc/04_filter.md
  54. 143 0
      core/tutorial/doc/05_vecmat.md
  55. 91 0
      core/tutorial/doc/06_algebra.md
  56. 161 0
      core/tutorial/doc/07_optimization.md
  57. 39 0
      core/tutorial/doc/samples.md
  58. 45 0
      core/tutorial/progs/01_imageio.cpp
  59. 74 0
      core/tutorial/progs/02_grayscale.cpp
  60. 45 0
      core/tutorial/progs/03_color.cpp
  61. 53 0
      core/tutorial/progs/04_filter.cpp
  62. 125 0
      core/tutorial/progs/05_matio.cpp
  63. 80 0
      core/tutorial/progs/06_optimization.cpp
  64. 二進制
      core/tutorial/samples/peppers_color.ppm
  65. 4 0
      core/tutorial/samples/peppers_gray.pgm
  66. 二進制
      core/tutorial/samples/simple.mat
  67. 二進制
      core/tutorial/screenshots/tut02_eq_hist_new.png
  68. 二進制
      core/tutorial/screenshots/tut02_eq_hist_org.png
  69. 二進制
      core/tutorial/screenshots/tut02_eq_new.png
  70. 二進制
      core/tutorial/screenshots/tut02_eq_org.png
  71. 48 30
      core/vector/SparseVectorT.h
  72. 31 27
      core/vector/SparseVectorT.tcc
  73. 1 0
      core/vector/ippwrapper.tcc
  74. 3 3
      core/vector/libdepend.inc
  75. 4 0
      core/vector/progs/testCholeskySpeed.cpp
  76. 73 0
      core/vector/tests/TestSVD.cpp
  77. 28 0
      core/vector/tests/TestSVD.h
  78. 31 0
      core/vector/tests/TestSparseVector.cpp
  79. 22 4
      templates/Makefile.config.template

+ 113 - 8
CMakeLists.txt

@@ -1,11 +1,13 @@
-#cmake_minimum_required(VERSION 2.8.6) #version 2.8.6 at least required because of command set(CMAKE_AUTOMOC TRUE) for qt moc-ing (see below)
-cmake_minimum_required(VERSION 2.8.12) #version 2.8.12 at least required because of command  get_filename_component(__testname_dir ${__testname_abspath} DIRECTORY) (getting directory path of filename)
+#version 2.8.9 required for position independent code
+cmake_minimum_required(VERSION 2.8.9)
 project (NICELibrary)
 project (NICELibrary)
 
 
 include(CheckSymbolExists)
 include(CheckSymbolExists)
 include(CheckIncludeFiles)
 include(CheckIncludeFiles)
 
 
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 
 
 include(cmake/NiceModules.cmake REQUIRED)
 include(cmake/NiceModules.cmake REQUIRED)
 
 
@@ -29,10 +31,66 @@ endif()
 
 
 set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR})
 set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR})
 
 
-set(NICE_BUILD_LIBS_STATIC_SHARED STATIC)
-
 set(NICE_SOURCEFILES_FIND_GLOBALLYRECURSIVE ON CACHE STRING "Scan a sublibraries directory for source files instead of using an explicit src file list")
 set(NICE_SOURCEFILES_FIND_GLOBALLYRECURSIVE ON CACHE STRING "Scan a sublibraries directory for source files instead of using an explicit src file list")
 
 
+set(external_deps "")
+
+NICE_OPTION(WITH_MEX "Build with MEX support" OFF)
+if(WITH_MEX)
+  if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    cmake_minimum_required(VERSION 2.8.12)
+    set(MATLAB_DEFAULT_ROOT "/Applications/MATLAB_R2013a.app")
+    set(MATLAB_DEFAULT_ARCH "maci64")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include algorithm")
+    set(MEX_ENDING ".mexmaci64")
+    set(CMAKE_MACOSX_RPATH 1)
+  else()
+    set(MATLAB_DEFAULT_ROOT "/home/matlab/8.2/academic")
+    set(MATLAB_DEFAULT_ARCH "glnxa64")
+    set(MEX_ENDING ".mexa64")
+  endif()
+
+  # Look for MATLAB environment variable
+  if(NOT EXISTS "$ENV{MATLAB}")
+    if(NOT EXISTS ${MATLAB_DEFAULT_ROOT})
+      message(FATAL_ERROR "Cannot find MATLAB at ${MATLAB_DEFAULT_ROOT}! Please set \$MATLAB")
+    else()
+      message(WARNING "\$MATLAB not set, using default")
+      set(MATLAB_ROOT ${MATLAB_DEFAULT_ROOT}) 
+    endif()
+  else()
+    set(MATLAB_ROOT $ENV{MATLAB})
+  endif()
+
+  message(STATUS "Using MATLAB from: ${MATLAB_ROOT}")
+
+  # Look for Arch environment variable
+  if(NOT "$ENV{Arch}" MATCHES ".*((32)|(64))$")
+    message(WARNING "\$Arch not set, using default")
+    set(MATLAB_ARCH ${MATLAB_DEFAULT_ARCH})
+  else()
+    set(MATLAB_ARCH $ENV{Arch})
+  endif()
+
+  message(STATUS "Using MATLAB architecture: " ${MATLAB_ARCH})
+
+  # Look for headers
+  if(EXISTS "${MATLAB_ROOT}/extern/include/mex.h")
+    INCLUDE_DIRECTORIES(${MATLAB_ROOT}/extern/include)
+  else()
+    message(FATAL_ERROR "Cannot find mex.h! Have you set \$MATLAB correctly?")
+  endif()
+
+  FIND_LIBRARY(MEX_LIBMX mx PATHS ${MATLAB_ROOT}/bin/${MATLAB_ARCH} NO_DEFAULT_PATH)
+  FIND_LIBRARY(MEX_LIBMEX mex PATHS ${MATLAB_ROOT}/bin/${MATLAB_ARCH})
+  FIND_LIBRARY(MEX_LIBMAT mat PATHS ${MATLAB_ROOT}/bin/${MATLAB_ARCH})
+
+  SET(MEX_LIBRARIES ${MEX_LIBMX} ${MEX_LIBMEX} ${MEX_LIBMAT})
+  ADD_DEFINITIONS("-DNICE_USELIB_MEX")
+  MESSAGE(STATUS "Found mex libraries at ${MEX_LIBRARIES}")
+  set(external_deps ${external_deps} "MEX")
+endif()
+
 NICE_OPTION(WITH_BOOST "Build with Boost support" OFF)
 NICE_OPTION(WITH_BOOST "Build with Boost support" OFF)
 if(WITH_BOOST)
 if(WITH_BOOST)
   set(Boost_USE_STATIC_LIBS ON)
   set(Boost_USE_STATIC_LIBS ON)
@@ -43,6 +101,7 @@ if(WITH_BOOST)
       ADD_DEFINITIONS( "-DNICE_BOOST_FOUND" )
       ADD_DEFINITIONS( "-DNICE_BOOST_FOUND" )
 	  ADD_DEFINITIONS( "-DNICE_USELIB_BOOST" )
 	  ADD_DEFINITIONS( "-DNICE_USELIB_BOOST" )
   ENDIF()
   ENDIF()
+  set(external_deps ${external_deps} "BOOST")
 endif()
 endif()
 
 
 FIND_PACKAGE(CppUnit)
 FIND_PACKAGE(CppUnit)
@@ -55,6 +114,7 @@ else()
   #set(CPPUNIT_INCLUDE_DIR "/usr/include/") #can be found in  /usr/include/cppunit
   #set(CPPUNIT_INCLUDE_DIR "/usr/include/") #can be found in  /usr/include/cppunit
  # ADD_DEFINITIONS( "-DNICE_USELIB_CPPUNIT" )
  # ADD_DEFINITIONS( "-DNICE_USELIB_CPPUNIT" )
   message(STATUS "CppUnit not found")
   message(STATUS "CppUnit not found")
+  set(external_deps ${external_deps} "BOOST")
 ENDIF()
 ENDIF()
 
 
 NICE_OPTION(WITH_DBV_LIBRARIES "Build with DBV extern librares" OFF)
 NICE_OPTION(WITH_DBV_LIBRARIES "Build with DBV extern librares" OFF)
@@ -73,12 +133,28 @@ if(WITH_DBV_LIBRARIES)
         #message(STATUS "ipp link dir: ${IPP_LIBRARY_DIRS}")
         #message(STATUS "ipp link dir: ${IPP_LIBRARY_DIRS}")
         #message(STATUS "ipp link libs: ${IPP_LIBRARIES}")
         #message(STATUS "ipp link libs: ${IPP_LIBRARIES}")
         ADD_DEFINITIONS( "-DNICE_USELIB_IPP=5" )
         ADD_DEFINITIONS( "-DNICE_USELIB_IPP=5" )
+	ADD_DEFINITIONS( "-lpthread" )
         INCLUDE_DIRECTORIES(${IPP_INCLUDE_DIRS})
         INCLUDE_DIRECTORIES(${IPP_INCLUDE_DIRS})
         
         
+        set(external_deps ${external_deps} "IPP")
       else()
       else()
         message(STATUS "IPP library not found")
         message(STATUS "IPP library not found")
       endif()
       endif()
     endif()
     endif()
+
+    NICE_OPTION(WITH_LINAL "Build with dbv LinAl support" OFF)
+    if(WITH_LINAL)
+      FIND_PACKAGE(LinAl)
+      if(LINAL_FOUND)
+	ADD_DEFINITIONS( "-DNICE_USELIB_LINAL" )
+	#ADD_DEFINITIONS("-lgfortran")
+        INCLUDE_DIRECTORIES(${LINAL_INCLUDE_DIR})
+	#message(STATUS "linal link libs: ${LINAL_LIBRARIES}")
+        message(STATUS "Using LinAl include dir: ${LINAL_INCLUDE_DIR}")
+        set(external_deps ${external_deps} "LINAL")
+      endif()
+    endif()
+
   else()
   else()
     message( SEND_ERROR "trying to use DBV extern library dir, but couldn't be found ${NICE_DBV_LIBRARIES_DIR}. Switch off DBV Usage to continue.") #unsetting dbv libraries path
     message( SEND_ERROR "trying to use DBV extern library dir, but couldn't be found ${NICE_DBV_LIBRARIES_DIR}. Switch off DBV Usage to continue.") #unsetting dbv libraries path
     unset(WITH_DBV_LIBRARIES) #unsetting, since dbv dir not found
     unset(WITH_DBV_LIBRARIES) #unsetting, since dbv dir not found
@@ -92,6 +168,7 @@ if(WITH_OPENMP)
       set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
       set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
       set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
       set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
       ADD_DEFINITIONS( "-DNICE_USELIB_OPENMP")
       ADD_DEFINITIONS( "-DNICE_USELIB_OPENMP")
+      set (external_deps ${external_deps} "OPENMP")
   endif()
   endif()
 endif()
 endif()
 
 
@@ -101,6 +178,7 @@ if(WITH_PNG)
     if (PNG_FOUND)
     if (PNG_FOUND)
       INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIRS})
       INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIRS})
       ADD_DEFINITIONS( "-DNICE_USELIB_PNG")
       ADD_DEFINITIONS( "-DNICE_USELIB_PNG")
+      set (external_deps ${external_deps} "PNG")
     endif()
     endif()
 endif()
 endif()
 
 
@@ -109,12 +187,14 @@ if(WITH_MATIO)
   find_package(HDF5)
   find_package(HDF5)
   if(HDF5_FOUND)
   if(HDF5_FOUND)
     message(STATUS "HDF5-dir: ${HDF5_INCLUDE_DIR}")
     message(STATUS "HDF5-dir: ${HDF5_INCLUDE_DIR}")
+    set (external_deps ${external_deps} "HDF5")
   endif()
   endif()
   find_package(MATIO)
   find_package(MATIO)
   if(MATIO_FOUND)
   if(MATIO_FOUND)
     message(STATUS "Matio-dir: ${MATIO_INCLUDE_DIRS}")
     message(STATUS "Matio-dir: ${MATIO_INCLUDE_DIRS}")
     ADD_DEFINITIONS( "-DNICE_USELIB_MATIO")
     ADD_DEFINITIONS( "-DNICE_USELIB_MATIO")
     INCLUDE_DIRECTORIES(${MATIO_INCLUDE_DIRS})
     INCLUDE_DIRECTORIES(${MATIO_INCLUDE_DIRS})
+    set (external_deps ${external_deps} "MATIO")
   endif()
   endif()
 endif()
 endif()
 
 
@@ -132,16 +212,16 @@ endif()
 
 
 NICE_OPTION(WITH_QT "Build with Qt" ON)
 NICE_OPTION(WITH_QT "Build with Qt" ON)
 if(WITH_QT)
 if(WITH_QT)
-  FIND_PACKAGE(Qt4)# COMPONENTS Qt3Support QtOpenGl)
+  FIND_PACKAGE(Qt4 REQUIRED)# COMPONENTS QtOpenGl)
   SET(QT_USE_QTOPENGL TRUE)
   SET(QT_USE_QTOPENGL TRUE)
   SET(QT_USE_QTXML TRUE)
   SET(QT_USE_QTXML TRUE)
-  SET(QT_USE_QT3SUPPORT TRUE)
   if(QT_FOUND)
   if(QT_FOUND)
-    message(STATUS "QTfound ${QT_QT3SUPPORT_INCLUDE_DIR}")
     set(CMAKE_AUTOMOC TRUE) #see doc: http://blogs.kde.org/2011/11/01/cool-new-stuff-cmake-286-automoc
     set(CMAKE_AUTOMOC TRUE) #see doc: http://blogs.kde.org/2011/11/01/cool-new-stuff-cmake-286-automoc
     INCLUDE(${QT_USE_FILE})
     INCLUDE(${QT_USE_FILE})
     ADD_DEFINITIONS(${QT_DEFINITIONS})
     ADD_DEFINITIONS(${QT_DEFINITIONS})
     ADD_DEFINITIONS( "-DNICE_USELIB_QT")
     ADD_DEFINITIONS( "-DNICE_USELIB_QT")
+    set(external_deps ${external_deps} "QT4")
+    set(external_deps ${external_deps} "QT4_XML")
   endif()
   endif()
 endif()
 endif()
 
 
@@ -224,12 +304,37 @@ set(__listSubLibs "")
 foreach(_curSubdir ${__listSubDirs})
 foreach(_curSubdir ${__listSubDirs})
 	nice_get_real_path(__modpath "${NICE_CURR_DIR}/${_curSubdir}/")
 	nice_get_real_path(__modpath "${NICE_CURR_DIR}/${_curSubdir}/")
 	if(EXISTS "${__modpath}/CMakeLists.txt")
 	if(EXISTS "${__modpath}/CMakeLists.txt")
-		#ADD_SUBDIRECTORY(${__modpath})
 	    LIST(APPEND __listSubLibs ${_curSubdir})
 	    LIST(APPEND __listSubLibs ${_curSubdir})
 	  NICE_OPTION(BUILD_LIB_${_curSubdir} "Build library ${_curSubdir}" ON)
 	  NICE_OPTION(BUILD_LIB_${_curSubdir} "Build library ${_curSubdir}" ON)
 	endif()
 	endif()
 endforeach()
 endforeach()
 
 
+set(internal_deps "")
+
+
+foreach(_curSubLib ${__listSubLibs})
+  if(BUILD_LIB_${_curSubLib})
+	nice_get_real_path(__modpath "${NICE_CURR_DIR}/${_curSubLib}")
+	message(STATUS "Scanning ${__modpath}...")
+	SUBDIRREC(__depDirs "${__modpath}")
+	foreach(__depDir ${__depDirs})
+		#message(STATUS "Adding (${_curSubLib}) ${__depDir} to list...")
+		set(internal_deps ${internal_deps} ${_curSubLib}/${__depDir})
+	endforeach()
+	set(internal_deps ${internal_deps} ${_curSubLib})
+  else()
+    message(STATUS "${_curSubLib} is excluded from build")
+  endif()
+endforeach()
+
+message(STATUS "External dependencies found: ${external_deps}")
+
+## Update deps
+NICE_OPTION(USE_LIBDEPEND "Use libdepend.inc files" OFF)
+if(USE_LIBDEPEND)
+	UPDATE_NICE_DEPENDENCIES()
+endif()
+
 foreach(_curSublib ${__listSubLibs})
 foreach(_curSublib ${__listSubLibs})
   if(BUILD_LIB_${_curSublib})
   if(BUILD_LIB_${_curSublib})
     nice_get_real_path(__modpath "${NICE_CURR_DIR}/${_curSublib}/")
     nice_get_real_path(__modpath "${NICE_CURR_DIR}/${_curSublib}/")

+ 1 - 1
Makefile

@@ -1,4 +1,4 @@
-# --------------------------------
+## --------------------------------
 # - initialization in top makefile
 # - initialization in top makefile
 #
 #
 # here all variables used later on will be defined and initialized. also the
 # here all variables used later on will be defined and initialized. also the

+ 38 - 0
NOTES

@@ -0,0 +1,38 @@
+## Wichtigere Sachen
+*Für die generischen Klassen müssen wir uns etwas überlegen*. Die Implementationen müssen mit in die Header, aber wir können die Lib so "von außen" nicht benutzen, weil wir beim Kompilieren der Templates definitiv unser Buildsystem brauchen (die ganzen Makros, Libs...). Das macht eine Distribution von Binaries quasi unmöglich.
+
+```
+$ grep --include={*.h,*.tcc} -rnw ./ -e ".*def.*USELIB.*" | wc -l
+185
+
+```
+
+Daher mein Vorschlag:
+
+1. Wir schränken für jede betroffene Klasse die möglichen Instanzen ein und kompilieren alle davon explizit mit. Ein Beispiel habe ich in den Ordner "ignore" gepackt.
+Vorteile:
+	* Benutzer braucht nur noch die Header einzubinden und mit nice_core zu linken -> er muss nice_core nicht kompilieren, sondern kann einfach Binaries und Header installieren.
+	* Je nach Lizenzen können wir einige Libraries statisch reinlinken, dabei fallen die nicht benutzten Funktionen raus und die Benutzer muss nicht einmal die sos der Abhängigkeiten installieren.
+	* Wenn wir in der Implementierung eine weitere Abhängigkeit einbauen, machen wir dem Benutzer seinen Buildprozess nicht kaputt.
+Nachteile:
+	* Für Containertypen eher unbrauchbar.
+	* Speicher?
+
+## Buildsystem
+-- WITH_QT OFF verhindert nicht das Kompilieren von libimagedisplay, die hängt aber von Qt ab.
+?? NICE_USELIB_QT verwenden, um in ImageDisplay.h die QT-Header auszuschließen
+
+-- Das Verzeichnis von GLUT ist für Windows hardcoded, sollte eigentlich Umgebungsvariable nutzen. 
+?? Rausnehmen
+
+-- WITH... sind Voreinstellungen in CMakeLists
+?? In Abhängigkeit der gefundenen Libs setzen
+
+-- Die Abhängigkeiten werden in nice-core/CMakeLists.txt gesucht, aber in nice-core/core/CMakeLists.txt werden unabhängig davon die Ergebnisse der find_package()-Aufrufe benutzt.
+?? Wenn nice-core ohnehin nur aus "core" besteht, reicht vielleicht auch nur eine CMakeLists.txt. Dann können wir target_link_libraries aufrufen, nachdem wir eine Abhängigkeit gefunden haben. Alternativ: Wenn jedes Projekt seine eigenen Abhängigkeiten hat, dann kann auch jedes Projekt selbst danach suchen.
+
+## Aufräumen
+-- "Filter.h is obsolete" - hängt noch sehr viel davon ab?
+
+## Bugs
+-- Konstruktor von ImageT ruft string::substr mit falschen Parametern auf, wenn der Punkt im Dateinamen fehlt.

+ 45 - 0
cmake/FindLinAl.cmake

@@ -0,0 +1,45 @@
+# Find the DBV library LinAl headers and library.
+#
+#  LINAL_INCLUDE_DIR - where to find Linal/linal.h, etc.
+#  LINAL_LIBRARIES      - List of libraries.
+#  LINAL_FOUND        - True if LinAl found.
+
+
+
+# Look for the library.
+#execute_process(COMMAND /home/dbv/3rdparty64-gcc43/LinAl/bin/linal-config --libs
+#                OUTPUT_VARIABLE LINAL_LIBRARIES)
+
+set(LINAL_LIBRARIES "/home/dbv/3rdparty64-gcc43/LinAl/lib/libLinAl.so;/home/dbv/3rdparty64-gcc43/LinAl/lib/libarpack++.a;/home/dbv/3rdparty64-gcc43/LinAl/lib/libsuperlu.a;/home/dbv/3rdparty64-gcc43/LinAl/lib/libarpack.a;/home/dbv/3rdparty64-gcc43/LinAl/lib/liblapack.a;/home/dbv/3rdparty64-gcc43/LinAl/lib/libblas.so")
+IF(UNIX) #find gfortran
+  # If the faster 'gold' linker is used, to avoid complaints about undefined symbol
+  # '_gfortran_concat_string', '_gfortran_pow_i4_i4', ... , let's link against gfortran libraries.
+  # These errors happen while linking against VTK static built with R support
+  SET(CMAKE_FIND_LIBRARY_SUFFIXES_SAVED ${CMAKE_FIND_LIBRARY_SUFFIXES}) # Backup
+  LIST(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".so.3")
+  FIND_LIBRARY(GFortran_LIBRARY gfortran)
+  SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVED}) # Restore
+  LIST(APPEND LINAL_LIBRARIES ${GFortran_LIBRARY})
+#  message(STATUS "GFortran_LIBRARY: ${GFortran_LIBRARY}")
+ENDIF()
+MARK_AS_ADVANCED(LINAL_LIBRARIES)
+
+# Look for the header file.
+#execute_process(COMMAND /home/dbv/3rdparty64-gcc43/LinAl/bin/linal-config --cxxflags
+#                OUTPUT_VARIABLE LINAL_INCLUDE_DIR)
+set(LINAL_INCLUDE_DIR "/home/dbv/3rdparty64-gcc43/LinAl/include/")
+MARK_AS_ADVANCED(LINAL_INCLUDE_DIR)
+
+
+# handle the QUIETLY and REQUIRED arguments and set LINAL_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LINAL DEFAULT_MSG LINAL_LIBRARIES LINAL_INCLUDE_DIR)
+
+#IF(MATIO_FOUND)
+#  SET(MATIO_LIBRARIES ${MATIO_LIBRARY} ${HDF5_LIBRARIES})
+#  SET(MATIO_INCLUDE_DIRS ${MATIO_INCLUDE_DIR} ${HDF5_INCLUDE_DIR})
+#ELSE(MATIO_FOUND)
+  #SET(MATIO_LIBRARIES)
+  #SET(MATIO_INCLUDE_DIRS)
+#ENDIF(MATIO_FOUND)

+ 201 - 17
cmake/NiceModules.cmake

@@ -20,6 +20,94 @@ MACRO(SUBDIRLIST result curdir)
   SET(${result} ${dirlist})
   SET(${result} ${dirlist})
 ENDMACRO()
 ENDMACRO()
 
 
+# get a list of all sub directories in curdir (recursive)
+# this function lists only the directories that contain relevant files
+MACRO(SUBDIRREC result curdir)
+	FILE(GLOB_RECURSE children RELATIVE ${curdir} ${curdir}/*.c ${curdir}/*.cpp ${curdir}/*.h ${curdir}/*.tcc ${curdir}/Makefile)
+	SET(dirlist "")
+	FOREACH(child ${children})
+		#message(STATUS ${child})
+		GET_FILENAME_COMPONENT(to_add ${curdir}/${child} PATH)
+		FILE(RELATIVE_PATH to_add_rel ${curdir} ${to_add})
+		IF(IS_DIRECTORY ${curdir}/${to_add_rel})
+			SET(dirlist ${dirlist} ${to_add_rel})
+		ENDIF()
+	ENDFOREACH()
+	IF(NOT "${dirlist}" MATCHES "")
+		LIST(REMOVE_DUPLICATES dirlist)
+	ENDIF()
+	SET(${result} ${dirlist})
+ENDMACRO()
+
+
+# update internal and external dependencies
+#
+# ${internal_deps} contains all the folders that are
+# "allowed". files in folders that are not part of this list will
+# _NOT_ be built.
+# the relevant libdepend.inc files are parsed until no more changes
+# are made
+macro(UPDATE_NICE_DEPENDENCIES)
+set(update_dependencies ON)
+while(update_dependencies)
+	message(STATUS "updating dependencies...")
+	set(update_dependencies OFF)
+	set(remove_these "")
+	foreach(_curDep ${internal_deps})
+		nice_get_real_path(_curDepPath ${NICE_CURR_DIR}/${_curDep})
+		if(EXISTS ${_curDepPath}/libdepend.inc)
+			#message(STATUS "Reading dependencies for ${_curDep}...")
+			file(STRINGS ${_curDepPath}/libdepend.inc _dependencies REGEX "^[$][(]call( )+PKG_DEPEND_INT,")
+			file(STRINGS ${_curDepPath}/libdepend.inc _extdependencies REGEX "^[$][(]call( )+PKG_DEPEND_EXT,")
+			#message(STATUS "Deps: ${_dependencies}")
+			#message(STATUS "Deps: ${_extdependencies}")
+
+			list(LENGTH _dependencies _depCount)
+			if(${_depCount} GREATER 0)
+				foreach(_innerDep ${_dependencies})
+					string(REGEX REPLACE "^[$][(]call( )+PKG_DEPEND_INT,(.*)[)].*$" "\\2" _innerDepName "${_innerDep}")
+					string(REGEX REPLACE "(.*)/$" "\\1" _innerDepName ${_innerDepName})
+					#message(STATUS "Inner dep: ${_innerDepName} (command: ${_innerDep})")
+					list(FIND internal_deps "${_innerDepName}" _innerDepFound)
+					if(${_innerDepFound} LESS 0)
+						message(STATUS "Removing ${_curDep} from build because ${_innerDepName} is missing") 
+						set(remove_these ${remove_these} ${_curDep})	
+						set(update_dependencies ON)
+					endif()
+				endforeach()
+			endif()
+
+			list(LENGTH _extdependencies _extdepCount)
+			if(${_extdepCount} GREATER 0)
+				foreach(_extDep ${_extdependencies})
+					string(REGEX REPLACE "^[$][(]call( )+PKG_DEPEND_EXT,(.*)[)].*$" "\\2" _extDepName "${_extDep}")
+					string(REGEX REPLACE "(.*)/$" "\\1" _extDepName ${_extDepName})
+					#message(STATUS "External dep: ${_extDepName} (command: ${_extDep})")
+					list(FIND external_deps "${_extDepName}" _extDepFound)
+					if(${_extDepFound} LESS 0)
+						message(STATUS "Removing ${_curDep} from build because ${_extDepName} (external) is missing")
+						set(remove_these ${remove_these} ${_curDep})
+						set(update_dependencies ON)
+					endif()
+				endforeach()
+			endif()
+
+		endif()
+	endforeach()
+	foreach(_toRemove ${remove_these})
+		message(STATUS "Checking subdirectories for ${_toRemove}")
+		foreach(_checkDep ${internal_deps})
+			if(${_checkDep} MATCHES "^${_toRemove}.*$")
+				message(STATUS "Removing ${_checkDep}...")
+				LIST(REMOVE_ITEM internal_deps ${_checkDep})
+			endif()
+		endforeach()
+	endforeach()
+endwhile()
+message(STATUS "Done.")
+
+endmacro()
+
 # get absolute path with symlinks resolved
 # get absolute path with symlinks resolved
 macro(nice_get_real_path VAR PATHSTR)
 macro(nice_get_real_path VAR PATHSTR)
   if(CMAKE_VERSION VERSION_LESS 2.8)
   if(CMAKE_VERSION VERSION_LESS 2.8)
@@ -72,23 +160,36 @@ macro(nice_get_source_files)
     ### Get all unit test cpp files recursively
     ### Get all unit test cpp files recursively
     set(nice_${the_library}_TESTFILES_SRC "")
     set(nice_${the_library}_TESTFILES_SRC "")
     set(nice_${the_library}_PROGFILES_SRC "")
     set(nice_${the_library}_PROGFILES_SRC "")
+    set(nice_${the_library}_MEXFILES_SRC "")
     set(nice_${the_library}_SRC"")
     set(nice_${the_library}_SRC"")
     
     
 
 
     #message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
     #message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
-    file(GLOB_RECURSE list_tmp1 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.cpp *.tcc *.c)
+    file(GLOB_RECURSE list_tmp1 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.cpp *.tcc *.c *.C)
     #message(STATUS "list_tmp1: ${list_tmp1}")
     #message(STATUS "list_tmp1: ${list_tmp1}")
     foreach( t_SrcFile ${list_tmp1})
     foreach( t_SrcFile ${list_tmp1})
-      if( NOT t_SrcFile MATCHES "moc_" )
-        if( t_SrcFile MATCHES "tests/" )
-          #message(STATUS "test: ${t_SrcFile}")
-          LIST(APPEND nice_${the_library}_TESTFILES_SRC ${t_SrcFile})
-        elseif( t_SrcFile MATCHES "progs/" )
-          #message(STATUS "prog: ${t_SrcFile}")
-          LIST(APPEND nice_${the_library}_PROGFILES_SRC ${t_SrcFile})
-        else()
-          LIST(APPEND nice_${the_library}_SRC ${t_SrcFile})
-        endif()
+      get_filename_component(t_SrcPath ${t_SrcFile} PATH)
+      set(t_SrcPath ${the_library}/${t_SrcPath})
+      string(REGEX REPLACE "(.*)/+$" "\\1" t_SrcPath ${t_SrcPath})
+      list(FIND internal_deps ${t_SrcPath} dep_index)
+      if(NOT ${dep_index} LESS 0)
+
+	      if( NOT t_SrcFile MATCHES "moc_" )
+		if( t_SrcFile MATCHES "tests/" )
+		  #message(STATUS "test: ${t_SrcFile}")
+		  LIST(APPEND nice_${the_library}_TESTFILES_SRC ${t_SrcFile})
+		elseif( t_SrcFile MATCHES "progs/" )
+		  #message(STATUS "prog: ${t_SrcFile}")
+		  LIST(APPEND nice_${the_library}_PROGFILES_SRC ${t_SrcFile})
+		elseif( t_SrcFile MATCHES "Mex[.]" )
+		  message(STATUS "mex: ${t_SrcFile}")
+		  LIST(APPEND nice_${the_library}_MEXFILES_SRC ${t_SrcFile})
+		else()
+		  LIST(APPEND nice_${the_library}_SRC ${t_SrcFile})
+		endif()
+	      endif()
+      else()
+	message(STATUS "Not building ${t_SrcFile} because ${t_SrcPath} is excluded (dependencies)")
       endif()
       endif()
     endforeach()
     endforeach()
 
 
@@ -104,9 +205,43 @@ macro(nice_get_source_files)
     #message(STATUS "globallyrecusive_tests: ${nice_${the_library}_TESTFILES_SRC}")
     #message(STATUS "globallyrecusive_tests: ${nice_${the_library}_TESTFILES_SRC}")
     #message(STATUS "globallyrecusive_progs: ${nice_${the_library}_PROGFILES_SRC}")
     #message(STATUS "globallyrecusive_progs: ${nice_${the_library}_PROGFILES_SRC}")
 
 
-    ### Get all header files recursively
-    file(GLOB_RECURSE nice_${the_library}_HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
-    
+    ### Get all header files recursively...
+    # ... but filter the headers according to their "type", meaning whether they are part of a unit test, a prog, or a mex.
+    # That means for example, that if you DO NOT WANT to build all progs in ./progs/ directories, all header files inside ./progs/ direcories 
+    # should be excluded and not be consided in the build. The same example applies to unit tests (./tests/) and mex filex.
+    # The reason is: The filter mechanism described above was also appied to source code files. So, we need to take care to have 
+    # the source and header files synchronized, so that we avoid using only the header file of a class, but not its source code implementation file
+    # which might lead to "undefined references" error. Especially in case of header file class definitions using Qt and an Q_OBJECT
+    # definition, a header file is moc'ed but but will generate "undefined references" if the source code file is not available.
+    file(GLOB_RECURSE list_tmp2 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
+    set(nice_${the_library}_HDR "")
+    foreach( t_HdrFile ${list_tmp2})
+      get_filename_component(t_HdrPath ${t_HdrFile} PATH)
+      set(t_HdrPath ${the_library}/${t_HdrPath})
+      string(REGEX REPLACE "(.*)/+$" "\\1" t_HdrPath ${t_HdrPath})
+      #list(FIND internal_deps ${t_HdrPath} dep_index)
+      if( NOT t_HdrFile MATCHES "moc_" )
+        if( t_HdrFile MATCHES "tests/" )
+          if(BUILD_UNITTESTS)
+            LIST(APPEND nice_${the_library}_HDR ${t_HdrFile})
+          endif()
+        elseif( t_HdrFile MATCHES "progs/" )
+          if(BUILD_PROGRAMS)
+            #message(STATUS "prog: ${t_HdrFile}")
+            LIST(APPEND nice_${the_library}_HDR ${t_HdrFile})
+          endif()
+        elseif( t_HdrFile MATCHES "Mex[.]" )
+          if(WITH_MEX)
+            #message(STATUS "mex: ${t_HdrFile}")
+            LIST(APPEND nice_${the_library}_HDR ${t_HdrFile})
+          endif()
+        else()
+           LIST(APPEND nice_${the_library}_HDR ${t_HdrFile})
+        endif()
+      endif()
+    endforeach()
+    #message(STATUS "header files found: ${nice_${the_library}_HDR}")
+
   else()
   else()
     message(STATUS "Using source files from file lists (*.cmake)")
     message(STATUS "Using source files from file lists (*.cmake)")
     #define variable nice_<libname>_HDR and nice_<libname>_SRC for library header and source files (don't include progs and test source files here)
     #define variable nice_<libname>_HDR and nice_<libname>_SRC for library header and source files (don't include progs and test source files here)
@@ -121,11 +256,36 @@ macro(nice_get_source_files)
 endmacro()
 endmacro()
 
 
 macro(nice_build_library)
 macro(nice_build_library)
-  ADD_LIBRARY("nice_${the_library}" ${NICE_BUILD_LIBS_STATIC_SHARED} ${nice_${the_library}_HDR} ${nice_${the_library}_SRC})
+  ADD_LIBRARY("nice_${the_library}" ${nice_${the_library}_HDR} ${nice_${the_library}_SRC})
+  LIST(LENGTH nice_${the_library}_LINKING_DEPENDENCIES dependency_count)
+  SET(tmp_dependencies "")
+  IF(dependency_count GREATER 0)
+	FOREACH(tmp_dependency ${nice_${the_library}_LINKING_DEPENDENCIES})
+		IF("${tmp_dependency}" MATCHES "^nice_")
+			STRING(REGEX REPLACE "^nice_(.*)" "\\1" tmp_dependency_nice ${tmp_dependency})
+			LIST(FIND internal_deps ${tmp_dependency_nice} dep_found)
+			IF(NOT ${dep_found} LESS 0)
+				SET(tmp_dependencies ${tmp_dependencies} ${tmp_dependency})
+			ELSE()
+				MESSAGE(STATUS "${the_library} wants to link to NICE module: ${tmp_dependency_nice}, but it is not available.")
+			ENDIF()
+		ELSE()
+			SET(tmp_dependencies ${tmp_dependencies} ${tmp_dependency})
+		ENDIF()
+	ENDFOREACH()
+  ENDIF()
+  SET(nice_${the_library}_LINKING_DEPENDENCIES ${tmp_dependencies})
   TARGET_LINK_LIBRARIES("nice_${the_library}" ${nice_${the_library}_LINKING_DEPENDENCIES})
   TARGET_LINK_LIBRARIES("nice_${the_library}" ${nice_${the_library}_LINKING_DEPENDENCIES})
   #TARGET_LINK_LIBRARIES("nice_${the_library}" ${nice_${the_library}_LINKING_DEPENDENCIES} ${Boost_LIBRARIES} ${OPENGL_LIBRARY} ${GLUT_LIBRARY} ${QT_LIBRARIES})
   #TARGET_LINK_LIBRARIES("nice_${the_library}" ${nice_${the_library}_LINKING_DEPENDENCIES} ${Boost_LIBRARIES} ${OPENGL_LIBRARY} ${GLUT_LIBRARY} ${QT_LIBRARIES})
   SET_PROPERTY(TARGET "nice_${the_library}" PROPERTY FOLDER "library")
   SET_PROPERTY(TARGET "nice_${the_library}" PROPERTY FOLDER "library")
-  INSTALL(TARGETS "nice_${the_library}" DESTINATION lib)
+  INSTALL(TARGETS "nice_${the_library}" DESTINATION lib EXPORT "nice_${the_library}-exports")
+  INSTALL(EXPORT "nice_${the_library}-exports" DESTINATION lib/exports)
+
+  install(DIRECTORY ./ DESTINATION "include/${the_library}"
+          FILES_MATCHING 
+          PATTERN "*.h"
+          PATTERN "*.tcc"
+	  PATTERN ".git" EXCLUDE)
 
 
   configure_file( ../cmake/niceConfig.cmake.in "${PROJECT_BINARY_DIR}/lib/nice_${the_library}Config.cmake" )
   configure_file( ../cmake/niceConfig.cmake.in "${PROJECT_BINARY_DIR}/lib/nice_${the_library}Config.cmake" )
 endmacro()
 endmacro()
@@ -167,6 +327,30 @@ macro(nice_add_progs)
 
 
 endmacro()
 endmacro()
 
 
+# Add mex output
+macro(nice_add_mexes)
+  if(WITH_MEX)
+    message(STATUS "building mexes:")
+    
+    foreach(__mexcpp ${nice_${the_library}_MEXFILES_SRC})
+      get_filename_component(__mexname ${__mexcpp} NAME_WE )
+      message(STATUS "mexname: ${__mexname} ${__mexcpp}")
+    
+      set(mex_target_name "${the_library}_${__mexname}")
+      ADD_LIBRARY("${mex_target_name}" SHARED ${__mexcpp})
+      TARGET_LINK_LIBRARIES(${mex_target_name} "nice_${the_library}")
+      SET_TARGET_PROPERTIES(${mex_target_name} PROPERTIES OUTPUT_NAME "${__mexname}")
+      SET_TARGET_PROPERTIES(${mex_target_name} PROPERTIES SUFFIX "${MEX_ENDING}")
+      SET_TARGET_PROPERTIES(${mex_target_name} PROPERTIES PREFIX "")
+      
+      INSTALL(TARGETS ${mex_target_name} DESTINATION "bin/${the_library}")
+      
+      SET_PROPERTY(TARGET ${mex_target_name} PROPERTY FOLDER "programs/${the_library}")
+    
+    endforeach()
+  endif()
+endmacro()
+
 # Create unit test (using library CppUnitTest) for all cpp files in the subvariable ${nice_${the_library}_TESTFILES_SRC}
 # Create unit test (using library CppUnitTest) for all cpp files in the subvariable ${nice_${the_library}_TESTFILES_SRC}
 # and build them into "bin/${the_library}"
 # and build them into "bin/${the_library}"
 #
 #
@@ -187,7 +371,7 @@ macro(nice_add_unittests)
     foreach(__testcpp ${nice_${the_library}_TESTFILES_SRC})
     foreach(__testcpp ${nice_${the_library}_TESTFILES_SRC})
       get_filename_component(__testname ${__testcpp} NAME_WE )
       get_filename_component(__testname ${__testcpp} NAME_WE )
       nice_get_real_path(__testname_abspath ${__testcpp})
       nice_get_real_path(__testname_abspath ${__testcpp})
-      get_filename_component(__testname_dir ${__testname_abspath} DIRECTORY)
+      get_filename_component(__testname_dir ${__testname_abspath} PATH)
 
 
       message(STATUS "unittest: ${__testname} ${__testcpp}")
       message(STATUS "unittest: ${__testname} ${__testcpp}")
       
       

+ 2 - 2
core/CMakeLists.txt

@@ -5,7 +5,7 @@
 set(the_library "core")
 set(the_library "core")
 
 
 #add linkage dependencies to other libraries here
 #add linkage dependencies to other libraries here
-set("nice_${the_library}_LINKING_DEPENDENCIES"  ${Boost_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${QT_LIBRARIES} ${IPP_LIBRARIES} ${ImageMagick_LIBRARIES})
+set("nice_${the_library}_LINKING_DEPENDENCIES"  ${Boost_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${QT_LIBRARIES} ${IPP_LIBRARIES} ${LINAL_LIBRARIES} ${ImageMagick_LIBRARIES} ${PNG_LIBRARIES})
 if(MATIO_FOUND)
 if(MATIO_FOUND)
   list(APPEND nice_${the_library}_LINKING_DEPENDENCIES ${MATIO_LIBRARIES})
   list(APPEND nice_${the_library}_LINKING_DEPENDENCIES ${MATIO_LIBRARIES})
 endif(MATIO_FOUND)
 endif(MATIO_FOUND)
@@ -64,4 +64,4 @@ nice_add_unittests()
 #         install(FILES ${hdr} DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT main)
 #         install(FILES ${hdr} DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT main)
 #       endif()
 #       endif()
 #     endforeach()
 #     endforeach()
-#   endif()
+#   endif()

+ 28 - 0
core/NOTES

@@ -0,0 +1,28 @@
+## Wichtigere Sachen
+*Für die generischen Klassen müssen wir uns etwas überlegen*. Die Implementationen müssen mit in die Header, aber wir können die Lib so "von außen" nicht benutzen, weil wir beim Kompilieren der Templates die NICE_USELIB.. aus unserem Buildsystem brauchen und damit auch noch beim Benutzer Abhängigkeiten erzeugen, die vermeidbar wären.
+
+```
+$ grep --include={*.h,*.tcc} -rnw ./ -e ".*def.*USELIB.*" | wc -l
+185
+
+```
+In den meisten Fällen können wir wohl die Template-Funktion explizit instantiieren und in den Header nur noch "extern template..." angeben.
+
+## Buildsystem
+-- WITH_QT OFF verhindert nicht das Kompilieren von libimagedisplay, die hängt aber von Qt ab.
+?? NICE_USELIB_QT verwenden, um in ImageDisplay.h die QT-Header auszuschließen
+
+-- Das Verzeichnis von GLUT ist für Windows hardcoded, sollte eigentlich Umgebungsvariable nutzen. 
+?? Rausnehmen
+
+-- WITH... sind Voreinstellungen in CMakeLists
+?? In Abhängigkeit der gefundenen Libs setzen
+
+-- Die Abhängigkeiten werden in nice-core/CMakeLists.txt gesucht, aber in nice-core/core/CMakeLists.txt werden unabhängig davon die Ergebnisse der find_package()-Aufrufe benutzt.
+?? Wenn nice-core ohnehin nur aus "core" besteht, reicht vielleicht auch nur eine CMakeLists.txt. Dann können wir target_link_libraries aufrufen, nachdem wir eine Abhängigkeit gefunden haben. Alternativ: Wenn jedes Projekt seine eigenen Abhängigkeiten hat, dann kann auch jedes Projekt selbst danach suchen.
+
+## Aufräumen
+-- "Filter.h is obsolete" - hängt noch sehr viel davon ab?
+
+## Bugs
+-- Konstruktor von ImageT ruft string::substr mit falschen Parametern auf, wenn der Punkt im Dateinamen fehlt.

+ 2 - 2
core/algebra/libdepend.inc

@@ -3,6 +3,6 @@ $(call PKG_DEPEND_INT,core/vector)
 # we need the optimization library for our linear solvers
 # we need the optimization library for our linear solvers
 $(call PKG_DEPEND_INT,core/optimization)
 $(call PKG_DEPEND_INT,core/optimization)
 # this is just an optional package
 # this is just an optional package
-$(call PKG_DEPEND_INT,cholesky-gpu/niceinterface)
+# $(call PKG_DEPEND_INT,cholesky-gpu/niceinterface)
 # this is an additional external optional package
 # this is an additional external optional package
-$(call PKG_DEPEND_EXT,TRLAN)
+# $(call PKG_DEPEND_EXT,TRLAN)

+ 18 - 1
core/basics/Config.cpp

@@ -6,6 +6,9 @@
 #include <string>
 #include <string>
 #include <set>
 #include <set>
 
 
+#include <unistd.h> //for getpwd() under linux
+#include <sys/param.h> //for MAXPATHLEN - the maximal path length
+
 // nice-core includes
 // nice-core includes
 #include "core/basics/Exception.h"
 #include "core/basics/Exception.h"
 #include "core/basics/Config.h"
 #include "core/basics/Config.h"
@@ -45,7 +48,21 @@ Config::Config ( int argc,
 {
 {
   readFromArguments ( argc, argv );
   readFromArguments ( argc, argv );
   std::string configfile = gS("main", "config", "" );
   std::string configfile = gS("main", "config", "" );
-  
+
+  NICE::FileName t_ConfigFilename( configfile );
+
+  // check for relative path correction:
+  // if dataset is a relative path, then make it absolute using the
+  // currend working directory
+  if( t_ConfigFilename.isRelative() )
+  {
+      char sCWDPath[MAXPATHLEN];
+      getcwd(sCWDPath, MAXPATHLEN);
+      t_ConfigFilename.set( string(sCWDPath) + "/" + configfile );
+      t_ConfigFilename.convertToRealPath();
+      configfile = t_ConfigFilename.str();
+  }
+  m_sConfigFilename = configfile;
   std::cerr << "configfile: " << configfile << std::endl;
   std::cerr << "configfile: " << configfile << std::endl;
   ioUntilEndOfFile = gB("main", "ioUntilEndOfFile", true );
   ioUntilEndOfFile = gB("main", "ioUntilEndOfFile", true );
   if ( configfile.size() > 0 )
   if ( configfile.size() > 0 )

+ 15 - 0
core/basics/FileName.cpp

@@ -3,6 +3,8 @@
 #include <stdlib.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdio.h>
 
 
+#include <sys/param.h> //for MAXPATHLEN - the maximal path length
+
 
 
 using namespace std;
 using namespace std;
 
 
@@ -143,4 +145,17 @@ bool FileName::isRelative() const {
     return  fileName.substr(0,1) != "/";
     return  fileName.substr(0,1) != "/";
 }
 }
 
 
+bool FileName::convertToRealPath()
+{
+    char actualpath [MAXPATHLEN];
+    char *pRet = realpath( fileName.c_str(), actualpath);
+
+    //TODO: how to treat the return value???
+//    if( pRet == NULL)
+//        return false;
+
+    this->fileName = string( actualpath);
+    return true;
+}
+
 } // namespace
 } // namespace

+ 9 - 0
core/basics/FileName.h

@@ -150,6 +150,15 @@ public:
       @return true if the filename is realtive
       @return true if the filename is realtive
   */
   */
   bool isRelative() const;
   bool isRelative() const;
+
+  /** Converts the path into a real path with all relative path elements being resolved.
+   * Example:
+   *    path before: "/home/user/experiment/../config/conf.conf
+   *    path after : "/home/user/config/conf.conf
+   * @return true if resolution was successfull
+   */
+  bool convertToRealPath();
+
 private:
 private:
   //! stores the file name
   //! stores the file name
   std::string fileName;
   std::string fileName;

+ 5 - 4
core/basics/libdepend.inc

@@ -1,5 +1,6 @@
-$(call PKG_DEPEND_EXT,LINAL)
-$(call PKG_DEPEND_EXT,ZLIB)
-$(call PKG_DEPEND_EXT,BZLIB)
-$(call PKG_DEPEND_EXT,OPENMP)
+# $(call PKG_DEPEND_EXT,LINAL)
+# $(call PKG_DEPEND_EXT,ZLIB)
+# $(call PKG_DEPEND_EXT,BZLIB)
+# $(call PKG_DEPEND_EXT,OPENMP)
+
 
 

+ 5 - 0
core/basics/progs/testConfig.cpp

@@ -16,8 +16,13 @@ using namespace std;
 */
 */
 int main (int argc, char **argv)
 int main (int argc, char **argv)
 {   
 {   
+
 #ifndef WIN32
 #ifndef WIN32
+#ifndef __clang__
+#ifndef __llvm__ 
     std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
     std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 #endif
 
 
     Config conf ( argc, argv );
     Config conf ( argc, argv );

+ 223 - 216
core/iceconversion/image_convertice.h

@@ -26,248 +26,255 @@
 namespace NICE
 namespace NICE
 {
 {
 
 
-    /**
-     * For internal use.
-     */
-    inline unsigned char invert255(unsigned char value, bool invert)
+  /**
+   * For internal use.
+   */
+  inline unsigned char invert255(unsigned char value, bool invert)
+                                 {
+    if (invert)
     {
     {
-        if (invert)
-        {
-            return 255 - value;
-        }
-        else
-        {
-            return value;
-        }
+      return 255 - value;
     }
     }
-
-    /**
-     * Create a new \c NICE::Image from an \c ice::Image.
-     * @param source The source image.
-     * @param invertImage Invert the image? Note: ICE works with inverted images.
-     * @param memoryLayout The memory layout for the new \c NICE::Image.
-     * @return The new \c NICE::Image (ownership given away!)
-     */
-    inline NICE::Image*
-    createGrayImage(const ice::Image& source,
-                    bool invertImage = true,
-                    NICE::GrayColorImageCommonImplementation::MemoryLayout memoryLayout
-                    = NICE::GrayColorImageCommonImplementation::ippAlignment)
+    else
     {
     {
-        // auto_ptr for exception safety
-        auto_ptr<Image>
-        result(new Image(source->xsize, source->ysize, memoryLayout));
-
-        for (int y = 0; y < source->ysize; y++)
+      return value;
+    }
+  }
+
+  /**
+   * Create a new \c NICE::Image from an \c ice::Image.
+   * @param source The source image.
+   * @param invertImage Invert the image? Note: ICE works with inverted images.
+   * @param memoryLayout The memory layout for the new \c NICE::Image.
+   * @return The new \c NICE::Image (ownership given away!)
+   */
+  inline NICE::Image*
+  createGrayImage(const ice::Image& source,
+                  bool invertImage = true,
+                  NICE::GrayColorImageCommonImplementation::MemoryLayout memoryLayout
+                  = NICE::GrayColorImageCommonImplementation::ippAlignment)
+                  {
+    // auto_ptr for exception safety
+    auto_ptr< Image >
+    result(new Image(source->xsize, source->ysize, memoryLayout));
+
+    for (int y = 0; y < source->ysize; y++)
         {
         {
-            Image::Pixel* cursor = result->getPixelPointerY(y);
-
-            for (int x = 0; x < source->xsize; x++)
-            {
-                // FIXME GetVal_nocheck ?!
-                *cursor = invert255(GetVal(source, x, y), invertImage);
-                cursor++;
-            }
-        }
-
-        return result.release();
+      Image::Pixel* cursor = result->getPixelPointerY(y);
+
+      for (int x = 0; x < source->xsize; x++)
+          {
+        // FIXME GetVal_nocheck ?!
+        *cursor = invert255(GetVal(source, x, y), invertImage);
+        cursor++;
+      }
     }
     }
 
 
-    /**
-     * Copy an ice::Image to a NICE::Image
-     * @param source The source image
-     * @param dst The destination image
-     * @param invertImage Invert the image? Note: ICE works with inverted images.
-     *
-     */
-    inline void
-    copyGrayImage(const ice::Image& source,
-                  NICE::Image& dst,
-                  bool invertImage = true)
-    {
-        dst.resize(source->xsize, source->ysize);
-        for (int y = 0; y < source->ysize; y++)
+    return result.release();
+  }
+
+  /**
+   * Copy an ice::Image to a NICE::Image
+   * @param source The source image
+   * @param dst The destination image
+   * @param invertImage Invert the image? Note: ICE works with inverted images.
+   *
+   */
+  inline void
+  copyGrayImage(const ice::Image& source,
+                NICE::Image& dst,
+                bool invertImage = true)
+                {
+    dst.resize(source->xsize, source->ysize);
+    for (int y = 0; y < source->ysize; y++)
         {
         {
-            Image::Pixel* cursor = dst.getPixelPointerY(y);
-            for (int x = 0; x < source->xsize; x++)
-            {
-                *cursor = invert255(GetVal(source, x, y), invertImage);
-                cursor++;
-            }
-        }
+      Image::Pixel* cursor = dst.getPixelPointerY(y);
+      for (int x = 0; x < source->xsize; x++)
+          {
+        *cursor = invert255(GetVal(source, x, y), invertImage);
+        cursor++;
+      }
     }
     }
-
-
-    /**
-     * Create a new \c ice::Image from an \c NICE::Image.
-     * @param source The source image.
-     * @param invertImage Invert the image? Note: ICE works with inverted images.
-     * @return The new \c ice::Image (ownership given away!)
-     */
-    inline ice::Image createIceImage(const NICE::Image& source,
-                                     bool invertImage = true)
-    {
-        ice::Image result = ice::NewImg(source.width(), source.height(), 255);
-
-        for (int y = 0; y < source.height(); y++)
+  }
+
+  /**
+   * Create a new \c ice::Image from an \c NICE::Image.
+   * @param source The source image.
+   * @param invertImage Invert the image? Note: ICE works with inverted images.
+   * @return The new \c ice::Image (ownership given away!)
+   */
+  inline ice::Image createIceImage(const NICE::Image& source,
+                                   bool invertImage = true)
+                                   {
+    ice::Image result = ice::NewImg(source.width(), source.height(), 255);
+
+    for (int y = 0; y < source.height(); y++)
         {
         {
-            const Image::Pixel* cursor = source.getPixelPointerY(y);
-
-            for (int x = 0; x < source.width(); x++)
-            {
-                // FIXME PutVal_nocheck ?!
-                PutVal(result, x, y, invert255(*cursor, invertImage));
-                cursor++;
-            }
-        }
-
-        return result;
+      const Image::Pixel* cursor = source.getPixelPointerY(y);
+
+      for (int x = 0; x < source.width(); x++)
+          {
+        // FIXME PutVal_nocheck ?!
+        PutVal(result, x, y, invert255(*cursor, invertImage));
+        cursor++;
+      }
     }
     }
 
 
-    /**
-     * Create a new \c NICE::ColorImage from an \c ice::ImageRGB.
-     * @param source The source image.
-     * @param invertImage Invert the image? Note: ICE works with inverted images.
-     * @param memoryLayout The memory layout for the new \c NICE::ColorImage.
-     * @return The new \c NICE::ColorImage (ownership given away!)
-     */
-    inline NICE::ColorImage*
-    createColorImage(const ice::ImageRGB& source,
-                     bool invertImage = true,
-                     NICE::GrayColorImageCommonImplementation::MemoryLayout memoryLayout
-                     = NICE::GrayColorImageCommonImplementation::ippAlignment)
-    {
-        // auto_ptr for exception safety
-        auto_ptr<ColorImage>
-        //result(new ColorImage(source.xsize(), source.ysize(), memoryLayout));
-        result(new ColorImage(source.RedImage()->xsize,
-                              source.RedImage()->ysize,
-                              memoryLayout));
-
-        for (int y = 0; y < source.RedImage()->ysize; y++)
+    return result;
+  }
+
+  /**
+   * Create a new \c NICE::ColorImage from an \c ice::ImageRGB.
+   * @param source The source image.
+   * @param invertImage Invert the image? Note: ICE works with inverted images.
+   * @param memoryLayout The memory layout for the new \c NICE::ColorImage.
+   * @return The new \c NICE::ColorImage (ownership given away!)
+   */
+  inline NICE::ColorImage*
+  createColorImage(const ice::ColorImage &source,  // const ice::ImageRGB& source,
+                   bool invertImage = true,
+                   NICE::GrayColorImageCommonImplementation::MemoryLayout memoryLayout
+                   = NICE::GrayColorImageCommonImplementation::ippAlignment)
+                   {
+    // auto_ptr for exception safety
+    auto_ptr< ColorImage >
+    //result(new ColorImage(source.xsize(), source.ysize(), memoryLayout));
+    result(new ColorImage(source.redImage()->xsize,
+                          source.redImage()->ysize,
+                          memoryLayout));
+
+    for (int y = 0; y < source.redImage()->ysize; y++)
         {
         {
-            ColorImage::Pixel* cursor = result->getPixelPointerY(y);
-
-            for (int x = 0; x < source.RedImage()->xsize; x++)
-            {
-                // FIXME GetVal_nocheck ?!
-                *cursor = invert255(GetVal(source.RedImage(), x, y), invertImage);
-                cursor++;
-                *cursor = invert255(GetVal(source.GreenImage(), x, y), invertImage);
-                cursor++;
-                *cursor = invert255(GetVal(source.BlueImage(), x, y), invertImage);
-                cursor++;
-            }
-        }
-
-        return result.release();
+      ColorImage::Pixel* cursor = result->getPixelPointerY(y);
+
+      for (int x = 0; x < source.redImage()->xsize; x++)
+          {
+        // FIXME GetVal_nocheck ?!
+        *cursor = invert255(GetVal(source.redImage(), x, y), invertImage);
+        cursor++;
+        *cursor = invert255(GetVal(source.greenImage(), x, y), invertImage);
+        cursor++;
+        *cursor = invert255(GetVal(source.blueImage(), x, y), invertImage);
+        cursor++;
+      }
     }
     }
 
 
-    /**
-     * Create a new \c ice::ImageRGB from an \c NICE::ColorImage.
-     * @param source The source image.
-     * @param invertImage Invert the image? Note: ICE works with inverted images.
-     * @return The new \c ice::ImageRGB (ownership given away!)
-     */
-    inline ice::ImageRGB* createIceImageRGB(const NICE::ColorImage& source,
+    return result.release();
+  }
+
+  /**
+   * Create a new \c ice::ImageRGB from an \c NICE::ColorImage.
+   * @param source The source image.
+   * @param invertImage Invert the image? Note: ICE works with inverted images.
+   * @return The new \c ice::ImageRGB (ownership given away!)
+   */
+  inline ice::ColorImage* createIceImageRGB(const ice::ColorImage &source,  // const NICE::ColorImage& source,
                                             bool invertImage = true)
                                             bool invertImage = true)
-    {
-        ice::ImageRGB* result = new ice::ImageRGB(source.width(), source.height());
+                                            {
+    ice::ColorImage* result = new ice::ColorImage();
+    result->create(source.xsize, source.ysize, source.maxval);
 
 
-        for (int y = 0; y < source.height(); y++)
+    for (int y = 0; y < source.ysize; y++)
         {
         {
-            const Image::Pixel* cursor = source.getPixelPointerY(y);
-
-            for (int x = 0; x < source.width(); x++)
-            {
-                PutVal(result->RedImage(), x, y, invert255(*cursor, invertImage));
-                cursor++;
-                PutVal(result->GreenImage(), x, y, invert255(*cursor, invertImage));
-                cursor++;
-                PutVal(result->BlueImage(), x, y, invert255(*cursor, invertImage));
-                cursor++;
-            }
-        }
-
-        return result;
+//            const Image::Pixel* cursor = source.getPixelPointerY(y);
+
+      for (int x = 0; x < source.xsize; x++)
+          {
+//                PutVal(result->redImage(), x, y, invert255(*cursor, invertImage));
+//                cursor++;
+//                PutVal(result->greenImage(), x, y, invert255(*cursor, invertImage));
+//                cursor++;
+//                PutVal(result->blueImage(), x, y, invert255(*cursor, invertImage));
+//                cursor++;
+
+        ice::ColorValue valSrc = source.getPixel(x, y);
+        ice::ColorValue valDst(invert255(valSrc.red, invertImage),
+                             invert255(valSrc.green, invertImage),
+                             invert255(valSrc.blue, invertImage));
+        source.setPixel(x, y, valDst);
+      }
     }
     }
 
 
-    /**
-     * Create a new \c NICE::FloatImage from an \c ice::ImageD.
-     * @param source The source FloatImage.
-     * @param memoryLayout The memory layout for the new \c NICE::FloatImage.
-     * @return The new \c NICE::FloatImage (ownership given away!)
-     */
-    inline NICE::FloatImage*
-    createFloatImage(const ice::ImageD& source
-                     )
-    {
-        // auto_ptr for exception safety
-        auto_ptr<FloatImage>
-        result(new FloatImage(source->xsize, source->ysize));
-
-        for (int y = 0; y < source->ysize; y++)
+    return result;
+  }
+
+  /**
+   * Create a new \c NICE::FloatImage from an \c ice::ImageD.
+   * @param source The source FloatImage.
+   * @param memoryLayout The memory layout for the new \c NICE::FloatImage.
+   * @return The new \c NICE::FloatImage (ownership given away!)
+   */
+  template<class T>
+  inline NICE::FloatImage*
+  createFloatImage(const ice::ImageF< T >& source)
+                   {
+    // auto_ptr for exception safety
+    auto_ptr< FloatImage >
+    result(new FloatImage(source->xsize, source->ysize));
+
+    for (int y = 0; y < source->ysize; y++)
         {
         {
-            FloatImage::Pixel* cursor = result->getPixelPointerY(y);
-
-            for (int x = 0; x < source->xsize; x++)
-            {
-                // FIXME GetVal_nocheck ?!
-                *cursor = GetValD(source, x, y);
-                cursor++;
-            }
-        }
-
-        return result.release();
+      FloatImage::Pixel* cursor = result->getPixelPointerY(y);
+
+      for (int x = 0; x < source->xsize; x++)
+          {
+        // FIXME GetVal_nocheck ?!
+        *cursor = GetValD(source, x, y);
+        cursor++;
+      }
     }
     }
 
 
-    /**
-     * Copy an ice::ImageD to a NICE::FloatImage
-     * @param source The source FloatImage
-     * @param dst The destination FloatImage
-     */
-    inline void
-    copyFloatImage(const ice::ImageD& source,
-                   NICE::FloatImage& dst)
-    {
-        dst.resize(source->xsize, source->ysize);
-        for (int y = 0; y < source->ysize; y++)
+    return result.release();
+  }
+
+  /**
+   * Copy an ice::ImageD to a NICE::FloatImage
+   * @param source The source FloatImage
+   * @param dst The destination FloatImage
+   */
+  inline void
+  copyFloatImage(const ice::ImageD& source,
+                 NICE::FloatImage& dst)
+                 {
+    dst.resize(source.xsize, source.ysize);
+    for (int y = 0; y < source.ysize; y++)
         {
         {
-            FloatImage::Pixel* cursor = dst.getPixelPointerY(y);
-            for (int x = 0; x < source->xsize; x++)
-            {
-                *cursor = GetValD(source, x, y);
-                cursor++;
-            }
-        }
+      FloatImage::Pixel* cursor = dst.getPixelPointerY(y);
+      for (int x = 0; x < source.xsize; x++)
+          {
+        *cursor = GetValD(source, x, y);
+        cursor++;
+      }
     }
     }
-
-
-    /**
-     * Create a new \c ice::ImageD from an \c NICE::FloatImage.
-     * @param source The source FloatImage.
-     * @return The new \c ice::ImageD (ownership given away!)
-     */
-    inline ice::ImageD createIceImageD(const NICE::FloatImage& source
-                                      )
-    {
-        ice::ImageD result = ice::NewImgD(source.width(), source.height());
-
-        for (int y = 0; y < source.height(); y++)
+  }
+
+  /**
+   * Create a new \c ice::ImageD from an \c NICE::FloatImage.
+   * @param source The source FloatImage.
+   * @return The new \c ice::ImageD (ownership given away!)
+   */
+  inline ice::ImageD createIceImageD(const NICE::FloatImage& source
+                                     )
+                                     {
+    ice::ImageD result = ice::NewImgD(source.width(), source.height());
+
+    for (int y = 0; y < source.height(); y++)
         {
         {
-            const FloatImage::Pixel* cursor = source.getPixelPointerY(y);
-
-            for (int x = 0; x < source.width(); x++)
-            {
-                // FIXME PutVal_nocheck ?!
-                PutValD(result, x, y, *cursor);
-                cursor++;
-            }
-        }
-
-        return result;
+      const FloatImage::Pixel* cursor = source.getPixelPointerY(y);
+
+      for (int x = 0; x < source.width(); x++)
+          {
+        // FIXME PutVal_nocheck ?!
+        PutValD(result, x, y, *cursor);
+        cursor++;
+      }
     }
     }
 
 
-}; // namespace
+    return result;
+  }
+
+}
+;
+// namespace
 
 
 #endif /* _CONVERTICE_IMAGE_H */
 #endif /* _CONVERTICE_IMAGE_H */

+ 15 - 0
core/ignore/OpaqueT.cpp

@@ -0,0 +1,15 @@
+/*
+   Example files for explicit opaque templates
+*/
+
+#include <iostream>
+#include <string>
+
+#include "OpaqueT.h"
+#include "OpaqueT.tcc"
+
+namespace NICE {
+		// Explicit instances
+		template class OpaqueT<std::string>;
+		template class OpaqueT<int>;
+}

+ 15 - 0
core/ignore/OpaqueT.h

@@ -0,0 +1,15 @@
+/*
+   Example files for explicit opaque templates
+*/
+
+#ifndef IGNORE_OPAQUET_H_
+#define IGNORE_OPAQUET_H_
+
+namespace NICE {
+	template <class T> class OpaqueT {
+		public:
+			void CallMe(T arg);
+	};
+}
+
+#endif

+ 12 - 0
core/ignore/OpaqueT.tcc

@@ -0,0 +1,12 @@
+/*
+   Example files for explicit opaque templates
+*/
+
+#include "OpaqueT.h"
+
+namespace NICE {
+	// Implementations
+	template<class T>void OpaqueT<T>::CallMe(T arg) {
+		std::cout << arg;
+	}
+}

+ 1 - 1
core/image/BlockImageAccessT.tcc

@@ -32,7 +32,7 @@ void BlockImageAccessT<P>::set(const P& value) {
   for(int y=0; y<this->height(); ++y) {
   for(int y=0; y<this->height(); ++y) {
     const P* end = this->getPixelPointerYEnd(y);
     const P* end = this->getPixelPointerYEnd(y);
     const int inc = this->columnStepsize();
     const int inc = this->columnStepsize();
-    for (P* p = this->getPixelPointerY(y); p != end; p = (void*)p + inc) {
+    for (P* p = this->getPixelPointerY(y); p != end; p = p + inc) {
       *p = value;
       *p = value;
     }
     }
   }
   }

+ 8 - 0
core/image/FilterT.h

@@ -68,6 +68,14 @@ class FilterT
     */
     */
     static void filterY ( const ImageT<SrcType>& src, const VectorT<CalcType>& kernel, ImageT<DstType> &result, const int& anchor = -1 );
     static void filterY ( const ImageT<SrcType>& src, const VectorT<CalcType>& kernel, ImageT<DstType> &result, const int& anchor = -1 );
 
 
+    /**
+    * Filters (=convolves) Image \c src into the
+    * Image \c dst using filter (=convolution) kernel \c kernel.
+    * @copydoc filter()
+    */
+    static void filter ( const ImageT<SrcType>& src, const MatrixT<CalcType>& kernel, ImageT<DstType>& result,
+            const int& anchorx = -1, const int& anchory = -1 );
+
     /**
     /**
     * Compute horizontal part of the gradient of a Image \c src via Sobel into Image \c dst.
     * Compute horizontal part of the gradient of a Image \c src via Sobel into Image \c dst.
     * The resulting image \c dst is of the same size as \c src.
     * The resulting image \c dst is of the same size as \c src.

+ 41 - 1
core/image/FilterT.tcc

@@ -72,6 +72,46 @@ void FilterT<SrcType, CalcType, DstType>::filterY ( const ImageT<SrcType>& src,
   }
   }
 }
 }
 
 
+template<class SrcType, class CalcType, class DstType>
+void FilterT<SrcType, CalcType, DstType>::filter(const ImageT<SrcType>& src,
+		const MatrixT<CalcType>& kernel, ImageT<DstType>& result,
+		const int& anchorx, const int& anchory) {
+
+	if (result.width() != src.width() || result.height() != src.height()) {
+		result.resize(src.width(), src.height());
+	}
+
+	IppiPoint anchor;
+	anchor.x = (anchorx < 0) ? (kernel.cols() / 2) : anchorx;
+	anchor.y = (anchory < 0) ? (kernel.rows() / 2) : anchory;
+
+	unsigned int kernel_rows = kernel.rows() - 1;
+	unsigned int kernel_cols = kernel.cols() - 1;
+
+	int runs = 0;
+
+	for (unsigned int y = anchor.y; y < src.height() - (kernel_rows - anchor.y);
+			y++) {
+		for (unsigned int x = anchor.x; x < src.width() - (kernel_cols - anchor.x);
+				x++) {
+			CalcType sum = 0;
+
+			for (int j = -anchor.y; j <= ((int)kernel_rows - anchor.y); j++) {
+				for (int i = -anchor.x; i <= ((int)kernel_cols - anchor.x); i++) {
+					sum += static_cast<CalcType>(src(x + i, y + j))
+							* kernel(kernel_cols - (anchor.x + i),
+									kernel_rows - (anchor.y + j));
+				}
+			}
+
+			result(x, y) = static_cast<DstType>(sum);
+
+		}
+	}
+
+	return;
+}
+
 template<class SrcType, class CalcType, class DstType>
 template<class SrcType, class CalcType, class DstType>
 void FilterT<SrcType, CalcType, DstType>::sobelX ( const NICE::ImageT<SrcType> &src, NICE::ImageT<DstType> &dst)
 void FilterT<SrcType, CalcType, DstType>::sobelX ( const NICE::ImageT<SrcType> &src, NICE::ImageT<DstType> &dst)
 {
 {
@@ -248,7 +288,7 @@ ImageT<DstType> * FilterT<SrcType, CalcType, DstType>::filterMeanLargeFS ( const
     sum = 0;
     sum = 0;
 
 
     const CalcType* pSrc = tmp.getPixelPointerXY ( x, 0 );
     const CalcType* pSrc = tmp.getPixelPointerXY ( x, 0 );
-    SrcType *pDst = result->getPixelPointerXY ( x, 0 );
+    DstType *pDst = result->getPixelPointerXY ( x, 0 );
 
 
     for ( unsigned int e = 0; e < size; ++e ) {
     for ( unsigned int e = 0; e < size; ++e ) {
       sum += * ( pSrc );
       sum += * ( pSrc );

+ 1 - 1
core/image/GHough.cpp

@@ -52,7 +52,7 @@ GHough& GHough::operator=(const GHough& ex)
 void GHough::initialize(IppiSize imageSize,IppiSize transformSize, NeighborType addMode)
 void GHough::initialize(IppiSize imageSize,IppiSize transformSize, NeighborType addMode)
 {
 {
     this->imageSize = imageSize;
     this->imageSize = imageSize;
-    transformSize = transformSize;
+    this->transformSize = transformSize;
     this->addMode = addMode;
     this->addMode = addMode;
     
     
     //! Allocates memory for data
     //! Allocates memory for data

+ 2 - 7
core/image/GrayColorImageCommonImplementationT.h

@@ -178,10 +178,7 @@ public:
    * @note   If you want to explicitly select a file format,
    * @note   If you want to explicitly select a file format,
    *         use read(ImageFile, const GrayColorImageCommonImplementation::MemoryLayout)
    *         use read(ImageFile, const GrayColorImageCommonImplementation::MemoryLayout)
    */
    */
-  inline void read(const std::string &filename /*,
-                   const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout = ippAlignment*/) {
-    read(ImageFile(filename)/*, _memoryLayout*/);
-  }
+  void read(const std::string &filename); 
 
 
   /**
   /**
   * Write this image to a file. See also documentation of \c ImageFile.
   * Write this image to a file. See also documentation of \c ImageFile.
@@ -196,9 +193,7 @@ public:
    * @note If you want to explicitly select a file format,
    * @note If you want to explicitly select a file format,
    *       use write(ImageFile)
    *       use write(ImageFile)
    */
    */
-  inline void write(const std::string &filename) const {
-    write(ImageFile(filename));
-  }
+  inline void write(const std::string &filename) const; 
 
 
   /**
   /**
   * Read this image from a PPM or PGM file.
   * Read this image from a PPM or PGM file.

+ 10 - 0
core/image/GrayColorImageCommonImplementationT.tcc

@@ -195,4 +195,14 @@ void GrayColorImageCommonImplementationT<P>::writePXM(const char* pxmFileName) c
   }
   }
 }
 }
 
 
+template <class P>
+void GrayColorImageCommonImplementationT<P>::read(const std::string &filename) {
+    read(ImageFile(filename)/*, _memoryLayout*/);
+}
+
+template <class P>
+void GrayColorImageCommonImplementationT<P>::write(const std::string &filename) const {
+    write(ImageFile(filename));
+}
+
 } // namespace
 } // namespace

+ 3 - 0
core/image/ImageFile.cpp

@@ -240,6 +240,9 @@ ImageFile::Format ImageFile::name2Format(const std::string &filename)
 	#endif
 	#endif
 
 
 		int pos=filename.find_last_of('.');
 		int pos=filename.find_last_of('.');
+		if(pos==std::string::npos)
+			return ImageFile::FormatUnknown;
+
 		magic=filename.substr(pos);
 		magic=filename.substr(pos);
 		if(magic==".pgm" || magic==".PGM")
 		if(magic==".pgm" || magic==".PGM")
 				return ImageFile::PGM_RAW;
 				return ImageFile::PGM_RAW;

+ 30 - 7
core/image/MultiChannelImage3DT.h

@@ -1,10 +1,10 @@
 #ifndef _NICE_CORE_MULTICHANNELIMAGE3DT_H
 #ifndef _NICE_CORE_MULTICHANNELIMAGE3DT_H
 #define _NICE_CORE_MULTICHANNELIMAGE3DT_H
 #define _NICE_CORE_MULTICHANNELIMAGE3DT_H
 
 
-#include <core/image/MultiChannelImageAccess3D.h>
-#include <core/image/ImageT.h>
-#include <core/image/MultiChannelImageT.h>
-#include <core/image/Histogram.h>
+#include "MultiChannelImageAccess3D.h"
+#include "ImageT.h"
+#include "MultiChannelImageT.h"
+#include "Histogram.h"
 
 
 #include <vector>
 #include <vector>
 #include <fstream>
 #include <fstream>
@@ -28,7 +28,8 @@ protected:
   typedef unsigned int uint;
   typedef unsigned int uint;
 
 
   /** image data, use carefully !!! data[channel][pixel_offset] */
   /** image data, use carefully !!! data[channel][pixel_offset] */
-  P **data;
+  std::vector<P*> data;
+//    P **data;
   
   
   /** image width */
   /** image width */
   int xsize;
   int xsize;
@@ -73,6 +74,17 @@ public:
   /** free all memory */
   /** free all memory */
   void freeData();
   void freeData();
 
 
+  /**
+   * @brief free only the pointer to the actual data, but leaves the actual data in the memory.
+   *
+   * Usefull for when the underlying data (e.g data[0] ptrs are passed to an other multi channel
+   * image for further use and memcopy should be avoided.
+   * Detail: Only frees variable 'data', not the memory data[0:numChannels] is pointing to
+   * @author Johannes Ruehle
+   * @date 2014-07-18
+   */
+  void freeShallowData();
+
   /** reinit */
   /** reinit */
   void reInit( int xsize, int ysize, int zsize, int numChannels = 1);
   void reInit( int xsize, int ysize, int zsize, int numChannels = 1);
 
 
@@ -89,12 +101,17 @@ public:
   
   
   template<class SrcP>
   template<class SrcP>
   void addChannel(const NICE::MultiChannelImage3DT<SrcP> &newImg);
   void addChannel(const NICE::MultiChannelImage3DT<SrcP> &newImg);
+
+  /** add channels only as references (no deep memory copy) */
+  template<class SrcP>
+  void addChannelReferences(const NICE::MultiChannelImage3DT<SrcP> &newImg);
   
   
   /** get value */
   /** get value */
   P get( int x, int y, int z, uint channel = 0 ) const;
   P get( int x, int y, int z, uint channel = 0 ) const;
   
   
   /** get data pointer */
   /** get data pointer */
-  P** getDataPointer();
+  std::vector<P*> getDataPointer() const;
+  //P** getDataPointer();
 
 
   /** set value */
   /** set value */
   void set( int x, int y, int z, P val, uint channel = 0 );
   void set( int x, int y, int z, P val, uint channel = 0 );
@@ -141,9 +158,15 @@ public:
 	/** return image for visualization */
 	/** return image for visualization */
   ImageT<P> getChannelT( int z, uint channel = 0 ) const;
   ImageT<P> getChannelT( int z, uint channel = 0 ) const;
 
 
-  /** return rgb image for visualization */
+  /** return x-slice as image */
+  ImageT<P> getXSlice ( int x, uint channel = 0 ) const;
+
+  /** return rgb image (reading channels 0, 1, 2) for visualization */
   ColorImage getColor(int z) const;
   ColorImage getColor(int z) const;
 
 
+  /** return rgb image (reading arbitrary three channels) for visualization */
+  ColorImage getColorImageFromChannels(int z, int channel0, int channel1, int channel2) const;
+
   /** calculate image statistics */
   /** calculate image statistics */
   void statistics( P & min, P & max, uint channel = 0 ) const;
   void statistics( P & min, P & max, uint channel = 0 ) const;
 
 

+ 129 - 56
core/image/MultiChannelImage3DT.tcc

@@ -7,7 +7,7 @@ namespace NICE {
 template<class P>
 template<class P>
 MultiChannelImage3DT<P>::MultiChannelImage3DT( int _xsize, int _ysize, int _zsize, uint _numChannels)
 MultiChannelImage3DT<P>::MultiChannelImage3DT( int _xsize, int _ysize, int _zsize, uint _numChannels)
 {
 {
-  data = NULL;
+//  data = NULL;
   numChannels = 0;
   numChannels = 0;
   xsize = 0;
   xsize = 0;
   ysize = 0;
   ysize = 0;
@@ -22,7 +22,7 @@ MultiChannelImage3DT<P>::MultiChannelImage3DT()
   ysize = 0;
   ysize = 0;
   zsize = 0;
   zsize = 0;
   numChannels = 0;
   numChannels = 0;
-  data = NULL;
+//  data = NULL;
 }
 }
 
 
 template<class P>
 template<class P>
@@ -52,40 +52,32 @@ MultiChannelImageT<P> MultiChannelImage3DT<P>::operator[] (uint z)
 template<class P>
 template<class P>
 MultiChannelImage3DT<P>& MultiChannelImage3DT<P>::operator=(const MultiChannelImage3DT<P>& orig) 
 MultiChannelImage3DT<P>& MultiChannelImage3DT<P>::operator=(const MultiChannelImage3DT<P>& orig) 
 {
 {
-  if(!(xsize == orig.xsize && ysize == orig.ysize && zsize == orig.zsize && numChannels == orig.numChannels))
+  if(  xsize == orig.xsize
+     && ysize == orig.ysize
+     && zsize == orig.zsize
+     && numChannels == orig.numChannels)
+  {
+      int iMemSize = xsize*ysize*zsize;
+      for(int c=0; c < numChannels; ++c)
+      {
+          std::copy(orig.data[c], orig.data[c]+iMemSize, data[c]);
+      }
+  }
+  else
   {
   {
     freeData();
     freeData();
     xsize = orig.xsize;
     xsize = orig.xsize;
     ysize = orig.ysize;
     ysize = orig.ysize;
     zsize = orig.zsize;
     zsize = orig.zsize;
     numChannels = orig.numChannels;
     numChannels = orig.numChannels;
-    if(orig.data != NULL)
-    {
-      data = new P *[numChannels];
-      for ( int c = 0; c < ( int )numChannels; c++ )
-      {
-        if ( orig.data[c] == NULL )
-        {
-          data[c] = NULL;
-        }
-        else
-        {
-          data[c] = new P [xsize*ysize*zsize];
-        }
-      }
-    }
-    else
-      data = NULL;
-  }
 
 
-  for ( int c = 0; c < ( int )numChannels; c++ )
-  {
-    if ( orig.data[c] != NULL )
+    int iMemSize = xsize*ysize*zsize;
+
+    for(int c = 0; c < numChannels; ++c)
     {
     {
-      for ( int x = 0; x < xsize*ysize*zsize; x++ )
-      {
-        data[c][x] = orig.data[c][x];
-      }
+        P *t_newData = new P [iMemSize];
+        std::copy(orig.data[c], orig.data[c]+iMemSize, t_newData);
+        data.push_back( t_newData );
     }
     }
   }
   }
   
   
@@ -95,13 +87,21 @@ MultiChannelImage3DT<P>& MultiChannelImage3DT<P>::operator=(const MultiChannelIm
 template<class P>
 template<class P>
 MultiChannelImage3DT<P>::MultiChannelImage3DT( const MultiChannelImage3DT<P>& p )
 MultiChannelImage3DT<P>::MultiChannelImage3DT( const MultiChannelImage3DT<P>& p )
 {
 {
-  data = NULL;
   xsize = p.xsize;
   xsize = p.xsize;
   ysize = p.ysize;
   ysize = p.ysize;
   zsize = p.zsize;
   zsize = p.zsize;
   numChannels = p.numChannels;
   numChannels = p.numChannels;
-   
-  if(p.data != NULL)
+
+  int iMemSize = xsize*ysize*zsize;
+
+  for(int c=0; c < numChannels; ++c)
+  {
+      P *t_newData = new P [iMemSize];
+      std::copy(p.data[c], p.data[c]+iMemSize, t_newData);
+      data.push_back( t_newData );
+  }
+
+/*  if(p.data != NULL)
     data = new P *[numChannels];
     data = new P *[numChannels];
   else
   else
     data = NULL;
     data = NULL;
@@ -121,13 +121,25 @@ MultiChannelImage3DT<P>::MultiChannelImage3DT( const MultiChannelImage3DT<P>& p
       }
       }
     }
     }
   }
   }
+*/
 }
 }
 
 
 
 
 template<class P>
 template<class P>
 void MultiChannelImage3DT<P>::addChannel( int newChans )
 void MultiChannelImage3DT<P>::addChannel( int newChans )
 {
 {
-  P **tmpData = new P *[numChannels+newChans];
+    assert(xsize > 0);
+    assert(ysize > 0);
+    assert(zsize > 0);
+
+    for (int i = 0; i < newChans; i++ )
+    {
+        this->data.push_back( new P [xsize*ysize*zsize] );
+    }
+
+    numChannels = this->data.size();
+/* old and ugly:
+   P **tmpData = new P *[numChannels+newChans];
 
 
   bool allocMem = false;
   bool allocMem = false;
   int i = 0;
   int i = 0;
@@ -160,6 +172,7 @@ void MultiChannelImage3DT<P>::addChannel( int newChans )
   }
   }
 
 
   delete [] tmpData;
   delete [] tmpData;
+  */
 }
 }
 
 
 template<class P>
 template<class P>
@@ -224,6 +237,37 @@ void MultiChannelImage3DT<P>::addChannel(const NICE::MultiChannelImage3DT<SrcP>
   }
   }
 }
 }
 
 
+template<class P>
+template<class SrcP>
+void MultiChannelImage3DT<P>::addChannelReferences(const NICE::MultiChannelImage3DT<SrcP> &newImg)
+{
+    if(numChannels == 0)
+    {
+        xsize = newImg.width();
+        ysize = newImg.height();
+        zsize = newImg.depth();
+    }
+    else
+    {
+        if( !(       newImg.width() == this->width()
+                     && newImg.height() == this->height()
+                     && newImg.depth() == this->depth() ) )
+        {
+            throw( " channelwise dimensions don't fit! Abort this crazy mixing of channels" );
+            return;
+        }
+    }
+
+    // add channel deep data references
+    // -> wrap this MultiChannelImage3D around the other data
+    const std::vector< P* > vecDataChannelPtrs = newImg.getDataPointer();
+    for( int c=0; c < vecDataChannelPtrs.size() ; ++c)
+        data.push_back( vecDataChannelPtrs[c] );
+
+    numChannels = data.size();
+
+}
+
 template<class P>
 template<class P>
 MultiChannelImage3DT<P>::~MultiChannelImage3DT()
 MultiChannelImage3DT<P>::~MultiChannelImage3DT()
 {
 {
@@ -233,16 +277,20 @@ MultiChannelImage3DT<P>::~MultiChannelImage3DT()
 template<class P>
 template<class P>
 void MultiChannelImage3DT<P>::freeData()
 void MultiChannelImage3DT<P>::freeData()
 {
 {
-  if ( data != NULL )
-  {
-    for ( uint i = 0 ; i < numChannels ; i++ )
-      if ( data[i] != NULL )
-        delete [] data[i];
+    if ( !data.empty())
+    {
+        for ( int i = 0 ; i < (int)data.size() ; i++ )
+            if ( data[i] != NULL )
+                delete [] data[i];
 
 
-    delete [] data;
+        data.clear();
+    }
+}
 
 
-    data = NULL;
-  }
+template<class P>
+void MultiChannelImage3DT<P>::freeShallowData()
+{
+    this->data.clear();
 }
 }
 
 
 template<class P>
 template<class P>
@@ -253,27 +301,14 @@ void MultiChannelImage3DT<P>::reInit( int _xsize, int _ysize, int _zsize, int _n
   ysize = _ysize;
   ysize = _ysize;
   zsize = _zsize;
   zsize = _zsize;
   numChannels = _numChannels;
   numChannels = _numChannels;
-  data = new P *[numChannels];
-
-  for ( uint i = 0 ; i < numChannels; i++ )
-    data[i] = new P [xsize*ysize*zsize];
+  this->addChannel(numChannels);
 }
 }
 
 
 template<class P>
 template<class P>
 template<class SrcP>
 template<class SrcP>
 void MultiChannelImage3DT<P>::reInitFrom( const MultiChannelImage3DT<SrcP> & src )
 void MultiChannelImage3DT<P>::reInitFrom( const MultiChannelImage3DT<SrcP> & src )
 {
 {
-  freeData();
-
-  xsize = src.width();
-  ysize = src.height();
-  zsize = src.depth();
-  numChannels = src.channels();
-
-  data = new P *[numChannels];
-
-  for ( uint i = 0 ; i < numChannels; i++ )
-    data[i] = new P [xsize*ysize*zsize];
+    this->reInit(src.width(),src.height(), src.depth(), src.channels() );
 }
 }
 
 
 template<class P>
 template<class P>
@@ -289,7 +324,7 @@ P MultiChannelImage3DT<P>::get( int x, int y, int z, uint channel ) const
 }
 }
 
 
 template<class P>
 template<class P>
-P ** MultiChannelImage3DT<P>::getDataPointer()
+std::vector<P*> MultiChannelImage3DT<P>::getDataPointer() const
 {
 {
   return data;
   return data;
 }
 }
@@ -448,6 +483,20 @@ ImageT<P> MultiChannelImage3DT<P>::getChannelT( int z, uint channel ) const
   return img;
   return img;
 }
 }
 
 
+template<class P>
+ImageT<P> MultiChannelImage3DT<P>::getXSlice ( int x, uint channel ) const
+{
+    assert( channel < numChannels );
+
+    NICE::ImageT<P> img(zsize, ysize);
+
+    for ( int y = 0; y < ysize; y++ )
+        for ( int z = 0; z < zsize; z++ )
+            img.setPixel( z, y, data[channel][z*xsize*ysize + y*xsize + x]);
+
+    return img;
+}
+
 /** convert to ice image */
 /** convert to ice image */
 template<class P>
 template<class P>
 void MultiChannelImage3DT<P>::convertToGrey( NICE::Image & img, int z, uint channel,  bool normalize ) const
 void MultiChannelImage3DT<P>::convertToGrey( NICE::Image & img, int z, uint channel,  bool normalize ) const
@@ -538,6 +587,30 @@ ColorImage MultiChannelImage3DT<P>::getColor(int z) const
   return img;
   return img;
 }
 }
 
 
+template<class P>
+ColorImage MultiChannelImage3DT<P>::getColorImageFromChannels(int z, int channel0, int channel1, int channel2) const
+{
+  assert( z < zsize );
+  assert( numChannels >= std::max( std::max(channel0,channel1),channel2 ) );
+
+  NICE::ColorImage img( xsize, ysize );
+
+  long k = 0;
+
+  for ( int y = 0 ; y < ysize; y++ )
+  {
+    for ( int x = 0 ; x < xsize ; x++, k++ )
+    {
+      img.setPixel( x, y, 0, ( int )( data[channel0][z*xsize*ysize + k] ) );
+      img.setPixel( x, y, 1, ( int )( data[channel1][z*xsize*ysize + k] ) );
+      img.setPixel( x, y, 2, ( int )( data[channel2][z*xsize*ysize + k] ) );
+    }
+  }
+  //showImage(img);
+  //getchar();
+  return img;
+}
+
 template<class P>
 template<class P>
 void MultiChannelImage3DT<P>::calcIntegral( uint channel )
 void MultiChannelImage3DT<P>::calcIntegral( uint channel )
 {
 {

+ 2 - 2
core/image/MultiChannelImageT.h

@@ -1,8 +1,8 @@
 #ifndef _NICE_CORE_MULTICHANNELIMAGET_H
 #ifndef _NICE_CORE_MULTICHANNELIMAGET_H
 #define _NICE_CORE_MULTICHANNELIMAGET_H
 #define _NICE_CORE_MULTICHANNELIMAGET_H
 
 
-#include <core/image/MultiChannelImageAccess.h>
-#include <core/image/ImageT.h>
+#include "MultiChannelImageAccess.h"
+#include "ImageT.h"
 
 
 namespace NICE {
 namespace NICE {
 
 

+ 7 - 7
core/image/libdepend.inc

@@ -1,9 +1,9 @@
-$(call PKG_DEPEND_EXT,LINAL)
-$(call PKG_DEPEND_EXT,IPP)
-$(call PKG_DEPEND_EXT,JPG)
-$(call PKG_DEPEND_EXT,PNG)
-$(call FILE_DEPEND_EXT,libcore_image.pc,ICE)
-$(call FILE_DEPEND_EXT,Fourier.o,ICE)
-$(call PKG_DEPEND_EXT,LIBMAGICK)
+# $(call PKG_DEPEND_EXT,LINAL)
+# $(call PKG_DEPEND_EXT,IPP)
+# $(call PKG_DEPEND_EXT,JPG)
+# $(call PKG_DEPEND_EXT,PNG)
+# $(call FILE_DEPEND_EXT,libcore_image.pc,ICE)
+# $(call FILE_DEPEND_EXT,Fourier.o,ICE)
+# $(call PKG_DEPEND_EXT,LIBMAGICK)
 $(call PKG_DEPEND_INT,core/basics)
 $(call PKG_DEPEND_INT,core/basics)
 $(call PKG_DEPEND_INT,core/vector)
 $(call PKG_DEPEND_INT,core/vector)

+ 6 - 0
core/image/tests/TestImageFile.cpp

@@ -295,6 +295,12 @@ void TestImageFile::testJPG_IO()
     }
     }
 }
 }
 
 
+void TestImageFile::testInvalidFileName() {
+	ImageFile image_file;
+	ImageFile::Format fileformat = image_file.name2Format("nodothere");
+	CPPUNIT_ASSERT_EQUAL(fileformat,ImageFile::FormatUnknown);
+}
+
 #endif
 #endif
 
 
 
 

+ 6 - 0
core/image/tests/TestImageFile.h

@@ -21,6 +21,7 @@ class TestImageFile : public CppUnit::TestFixture
 	CPPUNIT_TEST( testColorImage );
 	CPPUNIT_TEST( testColorImage );
 	CPPUNIT_TEST( testGrayImage  );
 	CPPUNIT_TEST( testGrayImage  );
 	CPPUNIT_TEST( testJPG_IO     );
 	CPPUNIT_TEST( testJPG_IO     );
+	CPPUNIT_TEST( testInvalidFileName );
 	CPPUNIT_TEST_SUITE_END();
 	CPPUNIT_TEST_SUITE_END();
 
 
    private:
    private:
@@ -51,6 +52,11 @@ class TestImageFile : public CppUnit::TestFixture
 	* Test JPEG Input and Output
 	* Test JPEG Input and Output
 	*/
 	*/
   	void testJPG_IO();
   	void testJPG_IO();
+
+  	/**
+  	* Test for correct detection of file names without appropriate endings
+  	*/
+  	void testInvalidFileName();
 };
 };
 
 
 #endif // _TESTIMAGEFILE_IMAGE_H
 #endif // _TESTIMAGEFILE_IMAGE_H

+ 1 - 1
core/imagedisplay/ArrayPlot.cpp

@@ -33,7 +33,7 @@ ArrayPlot::ArrayPlot ( std::vector<double> probs,
                        QWidget* parent,
                        QWidget* parent,
                        const char* name ,
                        const char* name ,
                        Qt::WFlags flags )
                        Qt::WFlags flags )
-    : QGLWidget ( parent, name, NULL, flags ),
+    : QGLWidget ( parent, NULL, flags ),
     m_width ( width ),
     m_width ( width ),
     m_height ( height ),
     m_height ( height ),
     m_maxProb ( -std::numeric_limits<double>::infinity() ),
     m_maxProb ( -std::numeric_limits<double>::infinity() ),

+ 4 - 5
core/imagedisplay/CaptureDialog.cpp

@@ -1,19 +1,18 @@
 #include "CaptureDialog.h"
 #include "CaptureDialog.h"
 
 
 #include <qlayout.h>
 #include <qlayout.h>
-//Added by qt3to4:
-#include <Q3VBoxLayout>
+#include <QVBoxLayout>
 
 
 namespace NICE {
 namespace NICE {
 
 
 CaptureDialog::CaptureDialog(QWidget* parent, const char* name, 
 CaptureDialog::CaptureDialog(QWidget* parent, const char* name, 
                              bool modal, Qt::WFlags fl)
                              bool modal, Qt::WFlags fl)
-    : QDialog( parent, name, modal, fl ) {
+    : QDialog( parent, fl ) {
   if (name == NULL) {
   if (name == NULL) {
-    setName("CaptureDialog");
+    setWindowTitle("CaptureDialog");
   }
   }
   
   
-  Q3VBoxLayout* layout = new Q3VBoxLayout( this, 11, 6, "layout"); 
+  QVBoxLayout* layout = new QVBoxLayout( this ); 
   
   
   m_capture = new CaptureWidget(this);
   m_capture = new CaptureWidget(this);
   m_capture->showCancelButton();
   m_capture->showCancelButton();

+ 43 - 109
core/imagedisplay/CaptureWidget.cpp

@@ -2,115 +2,63 @@
 
 
 #include <qvariant.h>
 #include <qvariant.h>
 #include <qpushbutton.h>
 #include <qpushbutton.h>
-#include <q3buttongroup.h>
 #include <qradiobutton.h>
 #include <qradiobutton.h>
 #include <qcheckbox.h>
 #include <qcheckbox.h>
 #include <qlabel.h>
 #include <qlabel.h>
 #include <qlineedit.h>
 #include <qlineedit.h>
 #include <qlayout.h>
 #include <qlayout.h>
 #include <qtooltip.h>
 #include <qtooltip.h>
-#include <q3whatsthis.h>
 #include <qcombobox.h>
 #include <qcombobox.h>
-//Added by qt3to4:
-#include <Q3HBoxLayout>
-#include <Q3VBoxLayout>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QFileDialog>
 
 
 namespace NICE {
 namespace NICE {
 
 
 CaptureWidget::CaptureWidget(QWidget* parent, const char* name, Qt::WFlags fl)
 CaptureWidget::CaptureWidget(QWidget* parent, const char* name, Qt::WFlags fl)
-        : QWidget(parent, name, fl) {
-    if (name == NULL) {
-      setName("CaptureWidget");
-    }
-    //setSizeGripEnabled( TRUE );
-    CaptureWidgetLayout = new Q3VBoxLayout( this, 11, 6, "CaptureWidgetLayout");
+        : QWidget(parent, fl) {
+    CaptureWidgetLayout = new QVBoxLayout( this );
 
 
-    layout15 = new Q3HBoxLayout( 0, 0, 6, "layout15");
+    layout15 = new QHBoxLayout( );
 
 
-    textLabel1 = new QLabel( this, "textLabel1" );
+    textLabel1 = new QLabel( this );
     layout15->addWidget( textLabel1 );
     layout15->addWidget( textLabel1 );
 
 
-    editFormat = new QComboBox( true, this, "editFormat" );
-    editFormat->insertItem("ppm");
-    editFormat->insertItem("pgm");
-    editFormat->insertItem("png");
-    editFormat->insertItem("jpg");
-    QToolTip::add(editFormat,
-                  "Format specified by filename extension (without dot)");
+    editFormat = new QComboBox( this );
+    editFormat->addItem("ppm");
+    editFormat->addItem("pgm");
+    editFormat->addItem("png");
+    editFormat->addItem("jpg");
+    editFormat->setToolTip("Format specified by filename extension (without dot)");
     layout15->addWidget( editFormat );
     layout15->addWidget( editFormat );
 
 
-    checkBuffered = new QCheckBox( this, "checkBuffered" );
-    QToolTip::add(checkBuffered,
-                  "Buffer images in memory and write after capturing (stop)");
+    checkBuffered = new QCheckBox( this );
+    checkBuffered->setToolTip( "Buffer images in memory and write after capturing (stop)");
     layout15->addWidget( checkBuffered );
     layout15->addWidget( checkBuffered );
 
 
-    buttonStart = new QPushButton( this, "buttonStart" );
+    buttonStart = new QPushButton( this );
     layout15->addWidget( buttonStart );
     layout15->addWidget( buttonStart );
 
 
-    buttonStop = new QPushButton( this, "buttonStop" );
+    buttonStop = new QPushButton( this );
     buttonStop->setEnabled( FALSE );
     buttonStop->setEnabled( FALSE );
     layout15->addWidget( buttonStop );
     layout15->addWidget( buttonStop );
 
 
-    buttonCancel = new QPushButton( this, "buttonCancel" );
+    buttonCancel = new QPushButton( this );
     buttonCancel->setAutoDefault( TRUE );
     buttonCancel->setAutoDefault( TRUE );
     buttonCancel->hide();
     buttonCancel->hide();
     layout15->addWidget( buttonCancel );
     layout15->addWidget( buttonCancel );
-    //spacer5 = new QSpacerItem( 20, 44, QSizePolicy::Minimum, QSizePolicy::Expanding );
-    //layout15->addItem( spacer5 );
-
-
-
-//     layout15 = new QHBoxLayout( 0, 0, 6, "layout15");
-//
-//     boxFormat = new QButtonGroup( this, "boxFormat" );
-//     //boxFormat->setInsideMargin(0);
-//     //boxFormat->setInsideSpacing(2);
-//
-//     radioPPM = new QRadioButton( boxFormat, "radioPPM" );
-//     radioPPM->setGeometry( QRect( 11, 26, 267, 25 ) );
-//     radioPPM->setChecked( TRUE );
-//
-//     radioJPG = new QRadioButton( boxFormat, "radioJPG" );
-//     radioJPG->setGeometry( QRect( 11, 119, 267, 25 ) );
-//
-//     radioPGM = new QRadioButton( boxFormat, "radioPGM" );
-//     radioPGM->setGeometry( QRect( 11, 57, 267, 25 ) );
-//
-//     radioPNG = new QRadioButton( boxFormat, "radioPNG" );
-//     radioPNG->setGeometry( QRect( 11, 88, 267, 25 ) );
-//     layout15->addWidget( boxFormat );
-//
-//     layout14 = new QVBoxLayout( 0, 0, 6, "layout14");
-//
-//     buttonStart = new QPushButton( this, "buttonStart" );
-//     layout14->addWidget( buttonStart );
-//
-//     buttonStop = new QPushButton( this, "buttonStop" );
-//     buttonStop->setEnabled( FALSE );
-//     layout14->addWidget( buttonStop );
-//
-//     buttonCancel = new QPushButton( this, "buttonCancel" );
-//     buttonCancel->setAutoDefault( TRUE );
-//     buttonCancel->hide();
-//     layout14->addWidget( buttonCancel );
-//     spacer5 = new QSpacerItem( 20, 44, QSizePolicy::Minimum, QSizePolicy::Expanding );
-//     layout14->addItem( spacer5 );
-//
-//     checkBuffered = new QCheckBox( this, "checkBuffered" );
-//     layout14->addWidget( checkBuffered );
-//     layout15->addLayout( layout14 );
-
+    
     CaptureWidgetLayout->addLayout( layout15 );
     CaptureWidgetLayout->addLayout( layout15 );
 
 
-    layout11 = new Q3HBoxLayout( 0, 0, 6, "layout11");
+    layout11 = new QHBoxLayout();
 
 
-    textLabel2 = new QLabel( this, "textLabel2" );
+    textLabel2 = new QLabel( this );
     layout11->addWidget( textLabel2 );
     layout11->addWidget( textLabel2 );
 
 
-    editDirectory = new QLineEdit( this, "editDirectory" );
+    editDirectory = new QLineEdit( this );
     layout11->addWidget( editDirectory );
     layout11->addWidget( editDirectory );
 
 
-    buttonBrowse = new QPushButton( this, "buttonBrowse" );
+    buttonBrowse = new QPushButton( this );
     layout11->addWidget( buttonBrowse );
     layout11->addWidget( buttonBrowse );
     CaptureWidgetLayout->addLayout( layout11 );
     CaptureWidgetLayout->addLayout( layout11 );
 
 
@@ -124,11 +72,7 @@ CaptureWidget::CaptureWidget(QWidget* parent, const char* name, Qt::WFlags fl)
 
 
     languageChange();
     languageChange();
     resize( QSize(542, 253).expandedTo(minimumSizeHint()) );
     resize( QSize(542, 253).expandedTo(minimumSizeHint()) );
-//     clearWState( WState_Polished ); // Qt4
 
 
-    // signals and slots connections
-//     connect(buttonCancel, SIGNAL(clicked()),
-//             this, SLOT(buttonCancelClicked()));
     connect(buttonCancel, SIGNAL(clicked()),
     connect(buttonCancel, SIGNAL(clicked()),
             this, SIGNAL(cancelled()));
             this, SIGNAL(cancelled()));
     connect(buttonBrowse, SIGNAL(clicked()),
     connect(buttonBrowse, SIGNAL(clicked()),
@@ -157,35 +101,31 @@ CaptureWidget::~CaptureWidget()
  */
  */
 void CaptureWidget::languageChange()
 void CaptureWidget::languageChange()
 {
 {
-    setCaption( tr( "Capture Image Sequence" ) );
-//     boxFormat->setTitle( tr( "Image file format" ) );
-//     radioPPM->setText( tr( "PPM" ) );
-//     radioJPG->setText( tr( "JPEG" ) );
-//     radioPGM->setText( tr( "PGM (gray)" ) );
-//     radioPNG->setText( tr( "PNG" ) );
+    setWindowTitle( tr( "Capture Image Sequence" ) );
     buttonStart->setText( tr( "Start" ) );
     buttonStart->setText( tr( "Start" ) );
     buttonStop->setText( tr( "Stop" ) );
     buttonStop->setText( tr( "Stop" ) );
     buttonCancel->setText( tr( "&Cancel" ) );
     buttonCancel->setText( tr( "&Cancel" ) );
-    buttonCancel->setAccel( QKeySequence( QString::null ) );
+    buttonCancel->setShortcut( QKeySequence( QString::null ) );
     checkBuffered->setText( tr( "Buffer" ) );
     checkBuffered->setText( tr( "Buffer" ) );
     textLabel1->setText( tr( "Format" ) );
     textLabel1->setText( tr( "Format" ) );
     textLabel2->setText( tr( "Directory" ) );
     textLabel2->setText( tr( "Directory" ) );
     buttonBrowse->setText( tr( "..." ) );
     buttonBrowse->setText( tr( "..." ) );
 }
 }
 
 
-#include <q3filedialog.h>
-
 void CaptureWidget::buttonBrowseClicked()
 void CaptureWidget::buttonBrowseClicked()
 {
 {
-  Q3FileDialog dialog("",
-                     "",
-                     this,
-                     "Save to directory dialog");
-  dialog.setCaption("Choose an output directory");
-  dialog.setMode(Q3FileDialog::AnyFile); // QFileDialog::DirectoryOnly
+/*
+  QFileDialog dialog( this );
+  dialog.setWindowTitle("Choose an output directory");
+  dialog.setMode(QFileDialog::AnyFile); 
   if (dialog.exec() == QDialog::Accepted) {
   if (dialog.exec() == QDialog::Accepted) {
     editDirectory->setText(dialog.selectedFile());
     editDirectory->setText(dialog.selectedFile());
   }
   }
+*/
+  QString directory = QFileDialog::getExistingDirectory(this);
+  if(!directory.isNull()) {
+    editDirectory->setText(directory);
+  }
 }
 }
 
 
 void CaptureWidget::buttonStartClicked()
 void CaptureWidget::buttonStartClicked()
@@ -215,13 +155,12 @@ void CaptureWidget::enableGUI(bool enable)
   editDirectory->setEnabled(value);
   editDirectory->setEnabled(value);
   buttonBrowse->setEnabled(value);
   buttonBrowse->setEnabled(value);
   checkBuffered->setEnabled(value);
   checkBuffered->setEnabled(value);
-//   boxFormat->setEnabled(value);
   buttonStop->setEnabled(!value);
   buttonStop->setEnabled(!value);
 }
 }
 
 
 std::string CaptureWidget::directoryName()
 std::string CaptureWidget::directoryName()
 {
 {
-  return std::string(editDirectory->text().local8Bit());
+  return std::string(editDirectory->text().toLocal8Bit());
 }
 }
 
 
 bool CaptureWidget::isBuffered() {
 bool CaptureWidget::isBuffered() {
@@ -231,18 +170,7 @@ bool CaptureWidget::isBuffered() {
 
 
 std::string CaptureWidget::extensionName()
 std::string CaptureWidget::extensionName()
 {
 {
-//   if (radioPPM->isChecked()) {
-//     return ".ppm";
-//   } else if (radioPGM->isChecked()) {
-//     return ".pgm";
-//   } else if (radioPNG->isChecked()) {
-//     return ".png";
-//   } else if (radioJPG->isChecked()) {
-//     return ".jpg";
-//   } else {
-//     return ".ppm";
-//   }
-  return "." + std::string(editFormat->currentText().local8Bit());
+  return "." + std::string(editFormat->currentText().toLocal8Bit());
 }
 }
 
 
 bool CaptureWidget::isCapturing() {
 bool CaptureWidget::isCapturing() {
@@ -254,7 +182,13 @@ void CaptureWidget::setDirectoryName(const std::string& dir) {
 }
 }
 
 
 void CaptureWidget::setExtensionName(const std::string& ext) {
 void CaptureWidget::setExtensionName(const std::string& ext) {
-  editFormat->setCurrentText(ext.c_str());
+  std::string extension_end = ext.substr(1);
+  int extension_index = editFormat->findText(extension_end.c_str());
+  if(extension_index > 0) {
+    editFormat->addItem(extension_end.c_str());
+  } 
+
+  editFormat->setCurrentIndex(extension_index);
 }
 }
 
 
 void CaptureWidget::setBuffered(bool buffer) {
 void CaptureWidget::setBuffered(bool buffer) {

+ 7 - 12
core/imagedisplay/CaptureWidget.h

@@ -3,19 +3,14 @@
 
 
 #include <qvariant.h>
 #include <qvariant.h>
 #include <qdialog.h>
 #include <qdialog.h>
-#include <q3filedialog.h>
-//Added by qt3to4:
-#include <Q3VBoxLayout>
-#include <Q3GridLayout>
-#include <Q3HBoxLayout>
+#include <QFileDialog>
 #include <QLabel>
 #include <QLabel>
 #include <memory>
 #include <memory>
 
 
-class Q3VBoxLayout;
-class Q3HBoxLayout;
-class Q3GridLayout;
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
 class QSpacerItem;
 class QSpacerItem;
-class Q3ButtonGroup;
 class QRadioButton;
 class QRadioButton;
 class QPushButton;
 class QPushButton;
 class QCheckBox;
 class QCheckBox;
@@ -53,11 +48,11 @@ public slots:
   virtual void buttonStopClicked();
   virtual void buttonStopClicked();
 
 
 protected:
 protected:
-  Q3VBoxLayout* CaptureWidgetLayout;
-  Q3HBoxLayout* layout15;
+  QVBoxLayout* CaptureWidgetLayout;
+  QHBoxLayout* layout15;
 //   QVBoxLayout* layout14;
 //   QVBoxLayout* layout14;
   QSpacerItem* spacer5;
   QSpacerItem* spacer5;
-  Q3HBoxLayout* layout11;
+  QHBoxLayout* layout11;
 
 
 //   QButtonGroup* boxFormat;
 //   QButtonGroup* boxFormat;
 //   QRadioButton* radioPPM;
 //   QRadioButton* radioPPM;

+ 3 - 3
core/imagedisplay/DefaultMainWindow.cpp

@@ -13,14 +13,14 @@
 namespace NICE {
 namespace NICE {
 
 
 DefaultMainWindow::DefaultMainWindow(const char* title) : QWidget(NULL, NULL) {
 DefaultMainWindow::DefaultMainWindow(const char* title) : QWidget(NULL, NULL) {
-  setCaption(title);
+  setWindowTitle(title);
 
 
   // create a timer waking us regularly
   // create a timer waking us regularly
   timer.reset(new QTimer(this));
   timer.reset(new QTimer(this));
   timer->connect(timer.get(), SIGNAL(timeout()),
   timer->connect(timer.get(), SIGNAL(timeout()),
                  this, SLOT(timerSlot()));
                  this, SLOT(timerSlot()));
   timerIntervalMS = 0;
   timerIntervalMS = 0;
-  timer->start(timerIntervalMS, false);
+  timer->start(timerIntervalMS);
 
 
   //ImageDisplayManagerWidget* manager =
   //ImageDisplayManagerWidget* manager =
       //new ImageDisplayManagerWidget(this, "image manager");
       //new ImageDisplayManagerWidget(this, "image manager");
@@ -43,7 +43,7 @@ void DefaultMainWindow::timerSlot() {
     timer->stop();
     timer->stop();
   } else if (nextSleepMS != timerIntervalMS) {
   } else if (nextSleepMS != timerIntervalMS) {
     timerIntervalMS = nextSleepMS;
     timerIntervalMS = nextSleepMS;
-    timer->start(timerIntervalMS, false);
+    timer->start(timerIntervalMS);
   }
   }
 }
 }
 
 

+ 18 - 28
core/imagedisplay/ImageDisplay.cpp

@@ -17,15 +17,14 @@
 #endif
 #endif
 
 
 #include <qcursor.h>
 #include <qcursor.h>
-#include <q3filedialog.h>
+#include <QFileDialog>
 #include <qapplication.h>
 #include <qapplication.h>
 #include <qpushbutton.h>
 #include <qpushbutton.h>
 #include <qlineedit.h>
 #include <qlineedit.h>
-#include <q3buttongroup.h>
 #include <qcheckbox.h>
 #include <qcheckbox.h>
-//Added by qt3to4:
 #include <QContextMenuEvent>
 #include <QContextMenuEvent>
 #include <QMouseEvent>
 #include <QMouseEvent>
+#include <QMenu>
 
 
 #include <core/basics/Exception.h>
 #include <core/basics/Exception.h>
 #include <core/basics/FileName.h>
 #include <core/basics/FileName.h>
@@ -40,7 +39,7 @@
 namespace NICE {
 namespace NICE {
 
 
 ImageDisplay::ImageDisplay ( QWidget* parent, const char* name, Qt::WFlags flags )
 ImageDisplay::ImageDisplay ( QWidget* parent, const char* name, Qt::WFlags flags )
-    : QGLWidget ( parent, name, NULL, flags ),
+    : QGLWidget ( parent, NULL, flags ),
     image ( NULL ),
     image ( NULL ),
     colorImageBuffer ( NULL ),
     colorImageBuffer ( NULL ),
     grayImageBuffer ( NULL ),
     grayImageBuffer ( NULL ),
@@ -393,30 +392,23 @@ void ImageDisplay::makeDrop ( int x, int y ) {
 
 
 void ImageDisplay::contextMenuEvent ( QContextMenuEvent* event ) {
 void ImageDisplay::contextMenuEvent ( QContextMenuEvent* event ) {
 
 
-  Q3PopupMenu* popupMenu = new Q3PopupMenu ( this );
+  QMenu* popupMenu = new QMenu ( this );
 
 
-  //   CHECK_PTR(popupMenu); // Qt4
-  //popupMenu->insertTearOffHandle();
   addExtraMenuItems ( popupMenu );
   addExtraMenuItems ( popupMenu );
 
 
-  int saveID = popupMenu->insertItem ( "&Save image", this, SLOT ( menuSave() ) );
-  popupMenu->setAccel ( Qt::CTRL + Qt::Key_S, saveID );
+  popupMenu->addAction("&Save Image", this, SLOT ( menuSave() ), Qt::CTRL + Qt::Key_S);
+  popupMenu->addAction("&Restore aspect ratio", this, SLOT ( menuAspectRatio ), Qt::CTRL + Qt::Key_A);
 
 
-  int aspectID = popupMenu->insertItem ( "&Restore aspect ratio",
-                                         this, SLOT ( menuAspectRatio() ) );
-  popupMenu->setAccel ( Qt::CTRL + Qt::Key_A, aspectID );
-
-  popupMenu->insertSeparator();
-  popupMenu->insertItem ( "Start &capturing image sequence",
-                          this, SLOT ( menuStartCapture() ) );
-  popupMenu->insertItem ( "Sto&p capturing", this, SLOT ( menuStopCapture() ) );
+  popupMenu->addSeparator();
 
 
+  popupMenu->addAction ( "Start &capturing image sequence", this, SLOT ( menuStartCapture() ) );
+  popupMenu->addAction ( "Sto&p capturing", this, SLOT ( menuStopCapture() ) );
 
 
   popupMenu->exec ( QCursor::pos() );
   popupMenu->exec ( QCursor::pos() );
   delete popupMenu;
   delete popupMenu;
 }
 }
 
 
-void ImageDisplay::addExtraMenuItems ( Q3PopupMenu *popupMenu )
+void ImageDisplay::addExtraMenuItems ( QMenu *popupMenu )
 {
 {
 }
 }
 
 
@@ -427,17 +419,15 @@ void ImageDisplay::menuAspectRatio() {
 }
 }
 
 
 void ImageDisplay::menuSave() {
 void ImageDisplay::menuSave() {
-  QString s = Q3FileDialog::getSaveFileName (
-                "",
-                "Images (*.ppm *.pgm *.png *.jpg)",
-                this,
-                "Save file dialog",
-                "Choose a filename" );
-  if ( s.local8Bit().size() == 0 ) {
+  QString s = QFileDialog::getSaveFileName(this,
+		"Save file dialog",
+		"",
+		"Images (*.ppm, *.pgm, *.png, *.jpg)");
+  if ( s.isNull() ) {
     return;
     return;
   }
   }
 
 
-  NICE::FileName filename ( s.local8Bit() );
+  NICE::FileName filename ( s.toLocal8Bit() );
   const std::string ext = filename.extractExtension().str();
   const std::string ext = filename.extractExtension().str();
   const bool extensionOk
   const bool extensionOk
   = ( ext == std::string ( ".ppm" ) || ext == std::string ( ".pgm" )
   = ( ext == std::string ( ".ppm" ) || ext == std::string ( ".pgm" )
@@ -455,7 +445,7 @@ void ImageDisplay::menuSave() {
 void ImageDisplay::menuStartCapture() {
 void ImageDisplay::menuStartCapture() {
   if ( dialog.get() == NULL ) {
   if ( dialog.get() == NULL ) {
     dialog.reset ( new CaptureDialog ( this, "Capture Dialog" ) );
     dialog.reset ( new CaptureDialog ( this, "Capture Dialog" ) );
-    dialog->setCaption ( "Capture: " + captionBuffer );
+    dialog->setWindowTitle ( "Capture: " + captionBuffer );
     connect ( ( QObject* ) dialog->capture(), SIGNAL ( started() ),
     connect ( ( QObject* ) dialog->capture(), SIGNAL ( started() ),
               this, SLOT ( dialogStartCapture() ) );
               this, SLOT ( dialogStartCapture() ) );
     connect ( ( QObject* ) dialog->capture(), SIGNAL ( stopped() ),
     connect ( ( QObject* ) dialog->capture(), SIGNAL ( stopped() ),
@@ -492,7 +482,7 @@ void ImageDisplay::doSetCaption() {
   s << std::fixed << captionBuffer.toAscii().constData()
   s << std::fixed << captionBuffer.toAscii().constData()
   << " (FPS: " << frameRateCounter.getFrameRate() << ")";
   << " (FPS: " << frameRateCounter.getFrameRate() << ")";
   //std::cerr << "ImageDisplay::doSetCaption(): " << s.str() << std::endl;
   //std::cerr << "ImageDisplay::doSetCaption(): " << s.str() << std::endl;
-  QWidget::setCaption ( s.str().c_str() );
+  QWidget::setWindowTitle ( s.str().c_str() );
 }
 }
 
 
 
 

+ 2 - 3
core/imagedisplay/ImageDisplay.h

@@ -8,11 +8,10 @@
 
 
 #include <qgl.h>
 #include <qgl.h>
 #include <qevent.h>
 #include <qevent.h>
-#include <q3popupmenu.h>
-//Added by qt3to4:
 #include <QMouseEvent>
 #include <QMouseEvent>
 #include <QContextMenuEvent>
 #include <QContextMenuEvent>
 #include <QGLWidget>
 #include <QGLWidget>
+#include <QMenu>
 
 
 #include <vector>
 #include <vector>
 
 
@@ -258,7 +257,7 @@ protected:
    * called by contextMenuEvent(), use this to include additional
    * called by contextMenuEvent(), use this to include additional
    * menu items
    * menu items
    */
    */
-  virtual void addExtraMenuItems ( Q3PopupMenu *popupMenu );
+  virtual void addExtraMenuItems ( QMenu *popupMenu );
 
 
   //! receive mouse events
   //! receive mouse events
   virtual void mousePressEvent(QMouseEvent* event);
   virtual void mousePressEvent(QMouseEvent* event);

+ 8 - 10
core/imagedisplay/ImageDisplayManagerWidget.cpp

@@ -4,28 +4,26 @@
 #include <qpushbutton.h>
 #include <qpushbutton.h>
 #include <qlayout.h>
 #include <qlayout.h>
 #include <qtooltip.h>
 #include <qtooltip.h>
-#include <q3whatsthis.h>
+
 //Added by qt3to4:
 //Added by qt3to4:
-#include <Q3VBoxLayout>
+#include <QVBoxLayout>
 
 
 /*
 /*
  *  Constructs a ImageDisplayManagerWidget as a child of 'parent', with the
  *  Constructs a ImageDisplayManagerWidget as a child of 'parent', with the
  *  name 'name' and widget flags set to 'f'.
  *  name 'name' and widget flags set to 'f'.
  */
  */
 ImageDisplayManagerWidget::ImageDisplayManagerWidget( QWidget* parent, const char* name, Qt::WFlags fl )
 ImageDisplayManagerWidget::ImageDisplayManagerWidget( QWidget* parent, const char* name, Qt::WFlags fl )
-    : QWidget( parent, name, fl )
+    : QWidget( parent, fl )
 {
 {
-    if ( !name )
-  setName( "ImageDisplayManagerWidget" );
-    ImageDisplayManagerWidgetLayout = new Q3VBoxLayout( this, 11, 6, "ImageDisplayManagerWidgetLayout");
+    ImageDisplayManagerWidgetLayout = new QVBoxLayout( this );
 
 
-    buttonShowAll = new QPushButton( this, "buttonShowAll" );
+    buttonShowAll = new QPushButton( this );
     ImageDisplayManagerWidgetLayout->addWidget( buttonShowAll );
     ImageDisplayManagerWidgetLayout->addWidget( buttonShowAll );
 
 
-    buttonHideAll = new QPushButton( this, "buttonHideAll" );
+    buttonHideAll = new QPushButton( this );
     ImageDisplayManagerWidgetLayout->addWidget( buttonHideAll );
     ImageDisplayManagerWidgetLayout->addWidget( buttonHideAll );
 
 
-    buttonDeleteAll = new QPushButton( this, "buttonDeleteAll" );
+    buttonDeleteAll = new QPushButton( this );
     ImageDisplayManagerWidgetLayout->addWidget( buttonDeleteAll );
     ImageDisplayManagerWidgetLayout->addWidget( buttonDeleteAll );
     languageChange();
     languageChange();
     resize( QSize(205, 133).expandedTo(minimumSizeHint()) );
     resize( QSize(205, 133).expandedTo(minimumSizeHint()) );
@@ -51,7 +49,7 @@ ImageDisplayManagerWidget::~ImageDisplayManagerWidget()
  */
  */
 void ImageDisplayManagerWidget::languageChange()
 void ImageDisplayManagerWidget::languageChange()
 {
 {
-    setCaption( tr( "Image displays" ) );
+    setWindowTitle( tr( "Image displays" ) );
     buttonShowAll->setText( tr( "Show all images" ) );
     buttonShowAll->setText( tr( "Show all images" ) );
     buttonHideAll->setText( tr( "Hide all images" ) );
     buttonHideAll->setText( tr( "Hide all images" ) );
     buttonDeleteAll->setText( tr( "Release (!) all images" ) );
     buttonDeleteAll->setText( tr( "Release (!) all images" ) );

+ 5 - 9
core/imagedisplay/ImageDisplayManagerWidget.h

@@ -3,14 +3,10 @@
 
 
 #include <qvariant.h>
 #include <qvariant.h>
 #include <qwidget.h>
 #include <qwidget.h>
-//Added by qt3to4:
-#include <Q3GridLayout>
-#include <Q3HBoxLayout>
-#include <Q3VBoxLayout>
-
-class Q3VBoxLayout;
-class Q3HBoxLayout;
-class Q3GridLayout;
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+
 class QSpacerItem;
 class QSpacerItem;
 class QPushButton;
 class QPushButton;
 
 
@@ -32,7 +28,7 @@ public slots:
     virtual void buttonDeleteAll_clicked();
     virtual void buttonDeleteAll_clicked();
 
 
 protected:
 protected:
-    Q3VBoxLayout* ImageDisplayManagerWidgetLayout;
+    QVBoxLayout* ImageDisplayManagerWidgetLayout;
 
 
 protected slots:
 protected slots:
     virtual void languageChange();
     virtual void languageChange();

+ 12 - 4
core/imagedisplay/QtFramework.cpp

@@ -35,7 +35,11 @@ QtFramework::QtFramework()
 #endif
 #endif
 
 
 #ifndef WIN32
 #ifndef WIN32
-  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#ifndef __clang__
+#ifndef __llvm__ 
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 #endif
 }
 }
 
 
@@ -47,7 +51,11 @@ QtFramework::QtFramework(int& argc, char** argv)
 #endif
 #endif
 
 
 #ifndef WIN32
 #ifndef WIN32
-  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#ifndef __clang__
+#ifndef __llvm__ 
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 #endif
 }
 }
 
 
@@ -93,8 +101,8 @@ int QtFramework::nonstaticExec(QWidget* _mainWindow, bool showMainWindow) {
 }
 }
 
 
 int QtFramework::doExec(bool showMainWindow) {
 int QtFramework::doExec(bool showMainWindow) {
-  //application->setMainWidget(mainWindow.get());
-  application->setMainWidget(mainWindow);
+  mainWindow->setAttribute(Qt::WA_QuitOnClose, true);
+
   if (showMainWindow) {
   if (showMainWindow) {
     mainWindow->show();
     mainWindow->show();
   }
   }

+ 6 - 6
core/imagedisplay/SimpleSelector.cpp

@@ -39,27 +39,27 @@ void SimpleSelector::rectSelect(float left, float top, float right, float bottom
     updateGL();
     updateGL();
 }
 }
   
   
-void SimpleSelector::addExtraMenuItems ( Q3PopupMenu *popupMenu )
+void SimpleSelector::addExtraMenuItems ( QMenu *popupMenu )
 {
 {
     colorMenuMap.clear();
     colorMenuMap.clear();
     for ( int color = 1 ; color <= m_maxColors ; color++ )
     for ( int color = 1 ; color <= m_maxColors ; color++ )
     {
     {
 		string caption = "Color/Class " + itostr(color);
 		string caption = "Color/Class " + itostr(color);
-		int id = popupMenu->insertItem ( QString(caption.c_str()), this, SLOT(dummy()) );
-		colorMenuMap.insert ( pair<int, int> ( id, color ) );
+		QAction* action = popupMenu->addAction ( QString(caption.c_str()), this, SLOT(dummy()) );
+		colorMenuMap.insert ( pair<QAction*, int> ( action, color ) );
     }
     }
 
 
     connect (popupMenu, SIGNAL(activated(int)), this, SLOT(menuActivated(int)));
     connect (popupMenu, SIGNAL(activated(int)), this, SLOT(menuActivated(int)));
-    popupMenu->insertSeparator();
+    popupMenu->addSeparator();
 }
 }
   
   
 void SimpleSelector::dummy(void)
 void SimpleSelector::dummy(void)
 {
 {
 }
 }
 
 
-void SimpleSelector::menuActivated ( int id ) 
+void SimpleSelector::menuActivated (QAction* action) 
 {
 {
-    map<int, int>::const_iterator i = colorMenuMap.find(id);
+    map<QAction*, int>::const_iterator i = colorMenuMap.find(action);
     if ( i != colorMenuMap.end()  ) 
     if ( i != colorMenuMap.end()  ) 
 		setCurrentColor(i->second);
 		setCurrentColor(i->second);
 }
 }

+ 3 - 3
core/imagedisplay/SimpleSelector.h

@@ -65,7 +65,7 @@ protected:
    * called by contextMenuEvent(), use this to include additional
    * called by contextMenuEvent(), use this to include additional
    * menu items
    * menu items
    */
    */
-  void addExtraMenuItems ( Q3PopupMenu *popupMenu );
+  void addExtraMenuItems ( QMenu *popupMenu );
 
 
   //! set current marker color
   //! set current marker color
   void setCurrentColor ( int color );
   void setCurrentColor ( int color );
@@ -81,7 +81,7 @@ private slots:
   void rectSelect(float left, float top, float right, float bottom);
   void rectSelect(float left, float top, float right, float bottom);
 
 
   //! slot needed for the context menu
   //! slot needed for the context menu
-  void menuActivated ( int id );
+  void menuActivated ( QAction* action );
 
 
   //! dummy slot for menu item insertion
   //! dummy slot for menu item insertion
   void dummy(void);
   void dummy(void);
@@ -106,7 +106,7 @@ private:
   std::vector<int> m_rectanglesColor;
   std::vector<int> m_rectanglesColor;
 
 
   //! this map maps menu item ids to colors
   //! this map maps menu item ids to colors
-  std::map<int, int> colorMenuMap;
+  std::map<QAction*, int> colorMenuMap;
 
 
 };
 };
 
 

+ 6 - 1
core/imagedisplay/progs/showImage.cpp

@@ -18,8 +18,13 @@ using namespace std;
 */
 */
 int main ( int argc, char **argv )
 int main ( int argc, char **argv )
 {
 {
+
 #ifndef WIN32
 #ifndef WIN32
-  std::set_terminate ( __gnu_cxx::__verbose_terminate_handler );
+#ifndef __clang__
+#ifndef __llvm__ 
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 #endif
 
 
   for ( int i = 1 ; i < argc ; i++ )
   for ( int i = 1 ; i < argc ; i++ )

+ 0 - 1
core/matlabAccess/MatFileIO.h

@@ -25,7 +25,6 @@
 #else //#ifdef NICE_USELIB_MATIO
 #else //#ifdef NICE_USELIB_MATIO
 
 
 #include <matio.h>
 #include <matio.h>
-#include <matio_private.h>
 
 
 #ifndef sparse_t
 #ifndef sparse_t
 #define sparse_t mat_sparse_t
 #define sparse_t mat_sparse_t

+ 2 - 2
core/matlabAccess/libdepend.inc

@@ -1,4 +1,4 @@
 $(call PKG_DEPEND_INT,core/basics)
 $(call PKG_DEPEND_INT,core/basics)
 $(call PKG_DEPEND_INT,core/vector)
 $(call PKG_DEPEND_INT,core/vector)
-$(call PKG_DEPEND_EXT_ESSENTIAL,MATIO)
-$(call PKG_DEPEND_EXT_ESSENTIAL,HDF5)
+$(call PKG_DEPEND_EXT,MATIO)
+$(call PKG_DEPEND_EXT,HDF5)

+ 1 - 1
core/optimization/gradientBased/OptimizationProblemFirst.h

@@ -34,7 +34,7 @@ class OptimizationProblemFirst : private NonCopyable {
 public:
 public:
   //! Default constructor
   //! Default constructor
   inline OptimizationProblemFirst(unsigned int dimension)
   inline OptimizationProblemFirst(unsigned int dimension)
-      : m_gradientCache(dimension) {
+      : m_gradientCache(dimension, 0), m_positionCache(dimension,0) {
     init();
     init();
   }
   }
 
 

+ 1 - 1
core/optimization/libdepend.inc

@@ -1,3 +1,3 @@
-$(call PKG_DEPEND_EXT,LINAL)
+# $(call PKG_DEPEND_EXT,LINAL)
 $(call PKG_DEPEND_INT,core/vector)
 $(call PKG_DEPEND_INT,core/vector)
 $(call PKG_DEPEND_INT,core/basics)
 $(call PKG_DEPEND_INT,core/basics)

+ 31 - 0
core/tutorial/TODO

@@ -0,0 +1,31 @@
+# Tutorials TODO
+
+## General
+- Add "tutorial 0", a cheat sheet-like overview of NICE?
+
+## Tutorial 1 - Basic Image I/O Operations
+- Complete list of file formats vs. dependencies
+- Write down what parts of NICE support certain ImageT<> instances
+- Add recommendations on what pixel formats to use because of this
+
+## Tutorial 2 - Grayscale Image Operations
+- Add overview of different gray value transforms
+- Expand section about Image operator overloads
+- Add section on histogram specifications
+
+## Tutorial 3 - Color Image Operations
+- Section about differences and similarities between ImageT<> and ColorImageT<>
+- Section about conversion between color spaces
+
+## Tutorial 4 - Filters
+- Section about mean filters
+- Section about separable linear filters
+- Section about gaussian filters
+- Section about gradient images
+
+# Proposals for tutorials > 4
+- Drawing
+- Gauss pyramids? (Requires IPP)
+- Hough transform? (Lots of questions...)
+- Linear algebra examples?
+

+ 59 - 0
core/tutorial/doc/00_install.md

@@ -0,0 +1,59 @@
+# Tutorial 00 - Building and installing NICE-core
+
+## Dependencies
+
+### Linux
+The following libraries and programs are required in order to build NICE-core.
+
+ - Command line developer tools 
+ - CMake 2.8.6 or later
+ - Qt 4.x
+ - OpenGL
+ - GLUT 2.x
+
+### Mac OS X
+Newer version of Mac OS X ship with clang as the default compiler.
+NICE depends on some libraries that are available from _homebrew_,
+so you need to install it from [brew.sh](http://brew.sh) first.
+
+You also need to install Qt 4.8.5 for Mac.
+If you have Mac OS X 10.9, you also have to remove lines 330-332 from
+_qtglobal.h_:
+
+```c++
+#  if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_8)
+#    warning "This version of Mac OS X is unsupported"
+#  endif
+```
+
+And finally FreeGLUT (using _homebrew_):
+
+```bash
+$ brew install freeglut
+```
+
+## Preparing the file system
+Make a new working directory and clone the repository from GitHub:
+
+```bash
+$ mkdir nice
+$ cd nice
+$ git clone https://github.com/cvjena/nice-core.git
+```
+
+NICE needs to be built out-of-tree (in a separate directory next
+to __nice-core__):
+
+```bash
+$ cd nice
+$ mkdir build
+$ cd build
+```
+
+## Building NICE-core
+Navigate to the __build__ directory and build NICE-core like this:
+
+```bash
+$ cmake ../nice-core
+$ make
+```

+ 155 - 0
core/tutorial/doc/01_imageio.md

@@ -0,0 +1,155 @@
+# Tutorial 01 - Basic Image I/O Operations
+
+In this first tutorial you will learn how to read and write image files and how images are represented in NICE.
+
+## Prerequisites
+If you need support for a specific image file format other than PGM/PPM, you have to compile nice-core yourself and add the necessary libraries and CMake flags.
+
+The sample code for this tutorial does not have any dependencies other than nice-core. You can find it in the tutorial/progs subfolder.
+
+## Images in memory
+NICE provides a common generic interface for grayscale and multi-channel
+images.
+The corresponding classes are _ImageT_ and _ColorImageT_, both subclasses of
+_GrayColorImageCommonImplementationT_ which contains the most basic image
+access methods.
+Those are used by many of the other modules.
+You can find typical use cases in the next tutorials.
+
+Note that NICE does not have generic implementations of every function.
+We recommend using 8-bit images for most applications and also
+provide a shorthand typedef called _Image_.
+
+## Image files
+In NICE, instances of _ImageT_ or _ColorImageT_ do not have to exist on disk. Files are different, completely independent objects. The _ImageFile_ class serves as a pointer to a file in the file system.
+
+An instance of _ImageFile_ can be read from or written to, but it does not modify the file in any way unless you call those methods.
+
+Constructing an _ImageFile_ is simple:
+
+```c++
+ImageFile file("path/to/file.pgm");
+```
+
+This does not touch the file at all and it doesn't need to exist. If it does exist, you can read the image file into memory like this:
+
+```c++
+Image image_in_memory;
+file.reader(&image_in_memory);
+```
+
+After making our changes to the image (in memory), we can write them to the file:
+
+```c++
+file.writer(&image_in_memory);
+```
+
+## Header information
+Sometimes it can be useful to access metadata without reading the whole image into memory. _ImageFile_ provides the __getHeader__ method for this. It reads the file and returns an instance of _Header_ with the fields __width__, __height__, __bitdepth__, __channel__.
+
+## Formats
+Note that _ImageFile_ attemtps to determine the file format by looking at the file name. You can override this behaviour by providing the __type__ parameter using the _Format_ enumeration.
+
+Supported file formats include PGM/PPM out of the box and those provided by libpng, libjpeg and libimagemagick++.
+
+The sample images do not need any additional libraries.
+
+# Sample code
+There is a complete sample program for every tutorial in this series.
+These samples are built along with NICE and can be found in the
+__core__ output directory.
+
+The sample program for this tutorial reads a file from disk to memory,
+displays metadata from the file header and writes the image to another
+file.
+
+You can find PXM sample images to use with the sample code
+in the __tutorial__ folder.
+
+## Includes
+We start of the sample program by including the necessary header files.
+The first few tutorials explain the usage of classes in the __image__
+subdirectory.
+
+Header files are usually named after the classes they declare.
+We need the _ImageT_ and _ImageFile_ classes, so our sample code
+starts like this:
+
+```c++
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ImageFile.h>
+```
+
+## File names
+We then get the file names from the command line.
+NICE will automatically determine the file type from its ending.
+This works for reads and writes, so you can use this sample program
+as a simple converter between image formats.
+
+This next part simply checks if the user specified both source and
+destination file.
+If there are enough arguments, they are stored in a _string_.
+ 
+```c++
+// Check if enough parameters were supplied
+if (argc < 3) {
+	std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+	return -1;
+}	
+
+// These are our file names
+std::string input_path(argv[1]);
+std::string output_path(argv[2]);
+```
+
+## Image metadata
+_ImageFile_ can read the header information without reading the whole image
+into memory.
+We use the __getHeader__ method to obtain a _Header_ instance.
+The fields are written to the standard output.
+
+```c++
+// Read file header and display header information
+NICE::ImageFile source_file(input_path);
+NICE::ImageFile::Header source_header = source_file.getHeader();
+
+std::cout << "Source image dimensions: " << source_header.width << " x " << source_header.height;
+std::cout << " (" << source_header.channel << " channels, " << source_header.bitdepth << " bpp)\n";
+```
+
+## Reading and writing the image
+To read the image, we create an empty instance of _ColorImage_ hand it over
+to the file's __reader__ method.
+
+Writing the image to disk is just as easy: contruct an _ImageFile_ with the
+destination path and call the __writer__ method.
+
+```c++
+// Read image into memory
+NICE::ColorImage source_image;
+source_file.reader(&source_image);
+
+// Write image to disk
+NICE::ImageFile dest_image(output_path);
+dest_image.writer(&source_image);
+return 0;
+```
+
+Remember that _ImageFile_ objects are just containers for a file's location
+and only open the file when you call methods that require reading or writing.
+
+## Running the sample
+
+_Command line:_
+
+```bash
+./01_imageio ../../nice-core/core/tutorial/samples/peppers_color.ppm /tmp/output.ppm
+```
+
+_Output:_
+
+```
+Source image dimensions: 512 x 512 (3 channels, 8 bpp)
+```

+ 161 - 0
core/tutorial/doc/02_grayscale.md

@@ -0,0 +1,161 @@
+# Tutorial 02 - Grayscale Image Operations
+
+After reading your image from a file into memory, you may want to optimize its histogram using gray value transforms. This tutorial will tech you the basics.
+
+## Pattern for gray value transforms
+You can use the following pattern for your gray value transforms.
+
+```c++
+template <class P> void MyTransform(NICE::ImageT<P>& image)
+{
+	for(int x = 0; x < image.width(); x++) {
+		for(int y=0; y < image.height(); y++) {
+			P pixel = image.getPixelQuick(x, y);
+			// Insert transform here	
+			image.setPixelQuick(x, y, pixel);
+		}
+	}
+}
+```
+
+Note that the get/setPixelQuick Methods don't perform boundary checks!
+
+### Optimization
+If you have access to Intel IPP, you can use the overloaded operators provided in ImageOperators.h.
+
+Another easy way to improve performance is adding a "parallel for" OpenMP compilation hint.
+
+## Gamma transforms
+Gamma transforms are a little more complicated, because gray values are not always in the [0,1] range.
+For example, the _Image_ and _GrayImage16s_ use the full positive range of their data types while the _FloatImage_ class can handle arbitrary ranges.
+
+You can use the __max()__ and __min()__ methods on your image to find its specific range. 
+
+## Histogram
+NICE provides a _Histogram_ class for 8-bit grayscale and color images (_Image_ and _ColorImage_).
+To calculate an image's histogram, use the constructor:
+
+``` c++
+NICE::Histogram histogram(image, 0, 256);
+```
+
+# Sample code
+This sample program attempts to equalize an image's histogram by deriving a
+gray value transform from the cumulative histogram.
+
+Take this ![sample image](screenshots/tut02_eq_org.png):
+the ![histogram](screenshots/tut02_eq_hist_org.png) shows that it doesn't make
+use of the whole range of gray values.
+After running the sample program, the image should look like
+![this](screenshot/tut02_eq_new.png).
+We can see in its ![histogram](screenshot/tut02_eq_hist_new.png) that is uses
+the complete range now.
+
+## Includes and file names
+Just like the previous sample, the program needs input and output file names.
+It also uses the _ImageT_ and _ImageFile_ classes, but needs the relevant
+headers for _Histogram_ and _VectorT_ as well.
+
+```c++
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ImageFile.h>
+#include <core/image/Histogram.h>
+#include <core/vector/VectorT.h>
+```
+
+The command line is then checked and stored like in the first sample. Most
+sample programs will use this pattern.
+
+```c++
+// Check if enough parameters were supplied
+if (argc < 3) {
+	std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+	return -1;
+}
+
+// These are our file names
+std::string input_path(argv[1]);
+std::string output_path(argv[2]);
+```
+
+## Calculating the histogram
+We read the image file specified as a command line argument using _ImageFile_
+like we learned in the first tutorial. This time we don't use _ColorImage_,
+because the sample program describes a gray value transform.
+
+When constructing a _Histogram_, we need to specify the range of gray values
+in our image. 8-bit images have values ranging from 0 to 255, but while the
+histogram includes the lower boundary as a bin, it does not include the upper
+boundary because it uses the difference between the boundarys to calculate the
+number of bins. This is why the sample program uses the values 0 and 256.
+
+The cumulative functions doesn't return another _Histogram_, but an _IntVector_.
+
+```c++
+// Read image into memory
+NICE::ImageFile source_file(input_path);
+NICE::Image image;
+source_file.reader(&image);
+
+// Calculate cumulative histogram
+NICE::Histogram histogram(image, 0, 256);
+NICE::IntVector* cumulative_histogram = histogram.cumulative();
+```
+
+## The transform
+In theory, if we use the cumulative histogram as a mapping for our gray value
+transform, the resulting image has a perfectly uniform histogram. We can prove
+this for images that are continuously differentiable functions of real numbers.
+This is not the case for digital images:
+suppose an image is filled with a single color.
+There is no gray value transform that can turn this image into one with a
+uniform distribution of gray values.
+
+We also need to scale the cumulative histogram down to our 8-bit range.
+The largest value will match the total number of pixels in the source image,
+so we use that to calculate a scaling factor.
+
+```c++
+double factor = 255.0/(double)(image.width()*image.height());
+
+// Transform using our pattern
+for(int x = 0; x < image.width(); x++) {
+	for(int y=0; y < image.height(); y++) {
+		// This is the old gray value
+		Ipp8u pixel = image.getPixelQuick(x, y);
+
+		// We use it as and index into the cumulative histogram to
+		// computer the new one. This has to be scaled appropriately
+		// using our precomputed factor.
+		double new_pixel_f =
+				((double)cumulative_histogram->get(pixel))*factor;
+
+		// The pixel format is 8-bit integer, so we have to convert
+		// the result
+		Ipp8u new_pixel = static_cast<Ipp8u>(new_pixel_f + 0.5);
+
+		// ..and save it
+		image.setPixelQuick(x, y, new_pixel);
+
+	}
+}
+```
+
+We can now write the changed image back to disk. We use a new file to preserve
+the original.
+
+```c++
+NICE::ImageFile dest_image(output_path);
+dest_image.writer(&image);
+return 0;
+```
+
+## Running the sample
+
+_Command line:_
+
+```bash
+./02_grayscale ../../nice-core/core/tutorial/samples/peppers_gray.pgm /tmp/output.ppm
+```

+ 134 - 0
core/tutorial/doc/03_color.md

@@ -0,0 +1,134 @@
+# Tutorial 03 - Color Image Operations
+
+## Architecture
+As mentioned in tutorial 01, color images in memory are represented by instances of
+_ColorImageT<>_.
+
+## File input/output
+Because _ImageT<>_ and _ColorImageT<>_ are both subclasses of 
+_GrayColorImageCommonImplementationT<>_, you can use the __reader__ and __writer__ methods
+as explained in tutorial 01.
+
+Note that using a file format that doesn't match the number of channels used by your image
+results in undefined behavior.
+
+## Read/write operations
+For pixel access, the __setPixelQuick__ methods accepts either a matching instance of
+_ColorT<>_ (_Color_ for 8-bit images) or three pixel values:
+
+```c++
+// Using Color
+color_image.setPixelQuick(4, 3, NICE::Color(0, 255, 0));
+
+// Using separate parameters
+color_image.setPixelQuick(4, 3, 0, 255, 0);
+```
+
+To read a pixel, use __getPixelQuick__ with the additional _channel_ parameter:
+
+```c++
+r = color_image.getPixelQuick(4, 3, 0);
+g = color_image.getPixelQuick(4, 3, 1);
+b = color_image.getPixelQuick(4, 3, 2);
+```
+
+## Conversion between color spaces
+NICE can convert between the three-channel color spaces YUV, HSV and RGB.
+The following methods are available:
+
+- __rgbToHSV__
+- __hsvToRGB__
+- __rgbToYUV__
+- __yuvToRGB__
+
+These methods allocate a new _ColorImageT<>_ (you can specify your own if you want to) and
+return a pointer to it:
+
+```c++
+// Use the return value
+NICE::ColorImage my_rgb_image = NICE::hsvToRGB(my_hsv_image);
+
+// Specify your own!
+NICE::ColorImage my_yuv_image(my_hsv_image.width(), my_hsv_image.height());
+NICE::rgbToYUV(my_rgb_image, my_yuv_image);
+```
+
+### Pseudocolors
+While not strictly a conversion, you can enhance a gray image with pseudocolors using the
+built-in function _imageToPseudoColor_. This is a very helpful visualization technique
+if your gray values represent something other than intensity (e.g depth or temperature):
+
+```c++
+// Allocate color image of appropriate dimensions
+NICE::ColorImage color_image(image.width(), image.height());
+
+// Convert to pseudocolor image
+NICE::imageToPseudoColor(image, color_image);
+```
+
+# Sample code
+The sample program for this chapter follows the input-transform-output pattern
+of the previous examples. Because conversions between color spaces are
+very easy to do with NICE-core, but also very hard to visualize, we will
+show you how to work with _ColorImageT<>_ by coloring a grayscale input
+using pseudocolors.
+
+## Includes and file names
+You can find the pseudocolor and conversion functions in __Convert.h_.
+_ColorImageT<>_ has its own header file.
+
+```c++
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ColorImageT.h>
+#include <core/image/ImageFile.h>
+#include <core/image/Convert.h>
+```
+
+We also need to check the command line for arguments and store them
+if there are enough:
+
+```c++
+// Check if enough parameters were supplied
+if (argc < 3) {
+	std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+	return -1;
+}
+
+// These are our file names
+std::string input_path(argv[1]);
+std::string output_path(argv[2]);
+```
+
+## Pseudocolors
+The next step is reading the file into an _Image_ and calling the
+_imageToPseudoColor_ method to perform the colorization. This methods needs
+a destination _ColorImage_ of similar dimensions.
+
+```c++
+// Read image into memory
+NICE::ImageFile source_file(input_path);
+NICE::Image image;
+source_file.reader(&image);
+
+// Calculate pseudocolors
+NICE::ColorImage pseudo_image(image.width(), image.height());
+NICE::imageToPseudoColor(image, pseudo_image);
+```
+
+After this is done, we write __pseudo_image__ to disk so we can look at it:
+
+```c++
+NICE::ImageFile dest_image(output_path);
+dest_image.writer(&pseudo_image);
+return 0;
+```
+
+## Running the sample
+
+_Command line:_
+
+```bash
+./03_color ../../nice-core/core/tutorial/samples/peppers_gray.pgm /tmp/output.ppm
+```

+ 96 - 0
core/tutorial/doc/04_filter.md

@@ -0,0 +1,96 @@
+# Tutorial 04 - Filters
+Linear filters play an important role in image processing.
+They are used for dealing with noise and in many computer vision applications.
+NICE provides generic implementations of several common filter types and
+supports custom kernels.
+
+## Data types
+The class _FilterT<>_ contains static methods for every filter type supported
+by NICE.
+You can specify different data types for your source and destination images and
+also
+for the calculations used during convolution.
+
+We recommend sticking to 8-bit-per-channel images (using the Image typedef as
+recommended throughout this tutorial series) and using _double_ values for
+the filter calculations.
+
+In this case you can use the _Filter_ typedef.
+
+## Source and destination image
+Most filter methods expect a destination image to write their results to.
+This image should have the same dimensions as the source image, otherwise
+it will be resized or an exception will be thrown.
+
+You should always construct a destination image like this:
+
+```c++
+// [...]
+NICE::Image image;
+// [...]
+NICE::Image result(image.width(), image.height());
+```
+
+## Filter types
+This section will give you an overview of the different kinds of filter NICE
+supports.
+
+### Mean filter
+A very simple filter for noise reduction is the mean filter.
+NICE implements this filter two times: for small and for large kernels.
+
+For most applications, the small implementation will suffice:
+
+```c++
+const unsigned int size = 3;
+NICE::Filter::filterMean(image, size, result);
+```
+
+The __size__ parameter describes the radius of the neighborhood
+(not including the center)
+used as a filter kernel. For size = 3, you get a 7x7 mean filter.
+
+### Sobel filter
+For some detection algorithms, you need gradient images.
+To compute the first derivative of your image in X and Y directions,
+use the following methods:
+
+```c++
+NICE::Filter::sobelX(image,gradientImageX);
+NICE::Filter::sobelY(image,gradientImageY);
+```
+
+
+### Using your own filter kernel
+Some applications require a specific filter kernel.
+You can supply an instance of _MatrixT<>_ with your values.
+
+The template argument should match the type used for calculations in
+_FilterT_.
+If you use the _Filter_ typedef, you can use the _Matrix_ typedef as well.
+
+You can then apply the filter like this:
+
+```c++
+NICE::Filter::filter(image, kernel, result);
+```
+
+If your filter kernel is separable, you can get better performance by applying
+two one-dimensional convolutions.
+Instead of _MatrixT<>_, you supply two _VectorT<>_ instances.
+As with _Matrix_, there's a typedef _Vector_ for _VectorT<double>_.
+
+You need to call two methods in this case:
+
+```c++
+NICE::Filter::filterX(image, kernel, result);
+NICE::Filter::filterY(image, kernel, result);
+```
+
+## Running the sample
+
+_Command line:_
+
+```bash
+./04_filter ../../nice-core/core/tutorial/samples/peppers_color.ppm /tmp/output.pgm
+```

+ 143 - 0
core/tutorial/doc/05_vecmat.md

@@ -0,0 +1,143 @@
+# Tutorial 05 - Vectors and Matrices
+## Vectors
+NICE provides the generic _VectorT<>_ class for vector data storage and
+calculations.
+It supports the same, large number of operations for all data types.
+
+There are deep and shallow copy functions for LinAl interoperability.
+
+### Construction
+While _VectorT<>_ provides a default constructor, it is only if you want
+to avoid pointers as member variables.
+
+_VectorT<>_ needs to know the number of elements because resizing a vector is
+extremely inefficient. You can also initialize the elements if you want to:
+
+```c++
+// This line creates an empty vector
+VectorT<double> empty_vector();
+
+// This line creates a three-dimensional vector
+// The elements are not initialized
+VectorT<double> threed_vector(3);
+
+// This line creates a two-dimensional vector
+// We initialize the elements to the value 25.3
+VectorT<double> twod_vector(3, 25.3);
+```
+
+
+### Operators
+For easy and expressive calculations, _VectorT<>_ defines the following
+classes of operators:
+
+* Unary operators:
+    - Unchecked read or reference access to element ([])
+    - Checked read or reference access to element (())
+
+* Binary operators:
+    - Vector addition and subtraction (+,-)
+    - Scalar multiplication (\*)
+
+* Combined assignment operators:
+    - Vector addition and subtraction (+=,-=)
+    - Vector multiplication and division (\*=,/=)
+    - Scalar addition and subtraction (+=,-=)
+    - Scalar multiplication and division (\*=,/=)
+
+### Methods
+In addition to basic algebra, _VectorT<>_ supports more complex operations.
+These include:
+
+* Calculating the scalar product of two _VectorT<>_: __scalarProduct__
+* Determining various statistics: __Sum__, __Mean__, __Median__, __StdDev__,
+  __Min__, __Max__
+* Additional information on these statistics: __MaxIndex__, __MinIndex__
+* Mean in non-euclidean vector spaces: __CircularMean__
+* Several norms: __normInf__, __normL1__, __normL2__
+* ...and normalization routines: __normalizeInf__, __normalizeL1__, __normalizeL2__
+* Basic sorting functions: __sortAscend__, __sortDescend__
+
+## Matrices
+Just like vectors, matrices have a generic representation in NICE.
+The class is called _MatrixT<>_ and is not related to _VectorT<>_ in that it
+is not a construct like _VectorT<VectorT<>>_.
+
+### Construction
+_MatrixT<>_ has a large number of constructors for different use cases.
+The default constructor creates a _MatrixT<>_ of dimensions 0x0 and should
+only be used for RAII purposes because resizing a _MatrixT<>_ is a very
+inefficient operation.
+
+```c++
+// Construction and expansion
+NICE::MatrixT<double> empty_matrix();
+empty_matrix.resize(5,4);
+```
+
+Instead, you can specifiy the dimensions and an optional default element.
+When no default element is given to the constructor, the matrix will not
+be initialized contains unpredictable data.
+
+```c++
+// 4x5 matrix - no initialization
+NICE::MatrixT<double> undefined_matrix(4,5);
+
+// 5x6 matrix - default element: 1
+NICE::MatrixT<double> simple_matrix(5,6,1);
+```
+
+### Data access
+_MatrixT<>_ provides different methods for read and write access to fit as
+many applications as possible.
+See the following snippet for important use cases:
+
+```c++
+// This is our matrix
+NICE::MatrixT<double> matrix(3,3);
+
+// At this point, the elements are unknown, so let's set them all to zero.
+matrix.set(0);
+
+// Now, create a vector
+NICE::VectorT<double> vector(3);
+vector[0]=1, vector[1]=2, vector[2]=3;
+
+// We can use this vector with the setRow method
+matrix.setRow(0, vector);
+
+// Set the center element to 5
+matrix(1,1)=5;
+
+// How can we set a column using a VectorT?
+matrix.getColumnRef(2)=vector;
+```
+
+### Operators
+_MatrixT<>_ exports basic calculations and methods as operators:
+
+* Unary operators:
+    - Unchecked read or reference access to element (())
+
+* Binary operators:
+    - Matrix addition and subtraction (+,-)
+    - Matrix-scalar multiplication (\*)
+    - Matrix-vector multiplication (\*)
+    - Matrix multiplication (\*)
+
+* Combined assignment operators:
+    - Matrix addition and subtraction (+=,-=)
+    - Matrix multiplication and division - element-wise (\*=,/=)
+    - Scalar addition and subtraction (+=,-=)
+    - Scalar multiplication and division (\*=,/=)
+
+### Methods
+More advanced calculations are available as member functions:
+
+* Set the matrix to a multiple of the identity matrix or
+  add to the existing matrix: __setIdentity__, __addIdentity__
+* Add a vector's elements as a diagonal matrix: __addDiagonal__
+* Calculate the tensor product of two vectors and store it
+  or add it to the matrix: __tensorProduct__, __addTensorProduct__
+* Store the result of a matrix multiplication: __multiply__
+* Check if a floating point matrix contains a NaN element: __containsNaN__

+ 91 - 0
core/tutorial/doc/06_algebra.md

@@ -0,0 +1,91 @@
+# Tutorial 06 - Linear Algebra
+
+## Singular value decomposition
+_Note: Currently, calculating the SVD of a matrix requires LinAL_
+
+Use the _SVD_ class for fast singular value decomposition.
+The calculation is performed at initialization and the resulting
+matrices are available from getter functions.
+
+Calculating the SVD is a very straightforward task.
+See this short example on how to use the SVD class:
+
+```c++
+// Create a matrix
+NICE::MatrixT<double> my_matrix(3,3,0);
+my_matrix.addIdentity(1);
+my_matrix(0,2) = 5;
+my_matrix(1,0) = 3;
+
+// Calculate the SVD
+NICE::SVD svd(my_matrix);
+
+// Store the results
+NICE::MatrixT<double> result_vt = svd.getVt();
+NICE::MatrixT<double> result_u = svd.getU();
+
+// This returns the singular values in a diagonal matrix
+// This diagonal matrix is allocated only if you call this function.
+NICE::MatrixT<double> result_s_matrix = svd.getS();
+
+// This returns the singular values as a vector. Use this function for
+// increased efficiency
+NICE::VectorT<double> result_s_vector = svd.getSingularValues();
+```
+
+## Eigenvalues
+_Note: Currently, calculating the eigenvalues of a matrix requires IPP._
+
+Calculating the eigenvalues of a matrix is as simple as single function call.
+The __eigenvalues__ function takes a _MatrixT<>_ and returns a _VectorT<>_ 
+that contains the eigenvalues. It allocates a _VectorT<>_ of matching dimensions
+on the heap.
+This behavior can be overridden be specifying a pointer as the second parameter.
+
+```c++
+// Create a matrix
+NICE::MatrixT<double> matrix(3,3,0);
+matrix.addIdentity(4);
+matrix(0,1) = -2;
+
+// Calculate the eigenvalues
+NICE::VectorT<double> eigenvals = NICE::eigenvalues(matrix);
+
+// ..or use your own vector
+NICE::VectorT<double> my_own_vector(3);
+NICE::eigenvalues(matrix, my_own_vector);
+```
+
+## Running the sample
+
+_Command line:_
+
+```bash
+./05_matio ../../nice-core/core/tutorial/samples/simple.mat MyMatrix
+```
+
+_Output:_
+
+```
+Loading matrix "MyMatrix"...
+Dimensions: 4 x 4
+1       2       3       4
+4       5       6       7
+2       3       4       5
+2       9       8       1
+Vt:
+-0.266556       -0.584949       -0.621772       -0.447418
+-0.188645       0.497147        0.204551        -0.821837
+0.925622        0.0646203       -0.282292       -0.243639
+-0.191273       0.637577        -0.701334       0.255031
+U:
+-0.285172       -0.294773       -0.738967       -0.534522
+-0.607906       -0.440949       0.603809        -0.267261
+-0.39275        -0.343498       -0.291375       0.801784
+-0.62839        0.775037        -0.0666614      -1.08901e-16
+S:
+17.8539 0       0       0
+0       6.33725 0       0
+0       0       1.03735 0
+0       0       0       2.17065e-16
+```

+ 161 - 0
core/tutorial/doc/07_optimization.md

@@ -0,0 +1,161 @@
+# Tutorial 07 - Optimization Problems
+NICE can solve different kinds of optimization problems using different
+algorithms in a modular fashion.
+
+Some standard problems are already defined in NICE-core, including:
+* Solving linear systems
+* Approximating bilinear products
+
+See the relevant doxygen documentation for more information on these.
+
+This tutorial will show you how to implement your own, non-standard
+optimization problems in a way that is compatible with NICE.
+
+The sample problem is a simple one: find the minimum of the quadratic
+function _f(x)=ax^2 +bx+c_.
+The values are read from the command line.
+
+We start by implementing the problem as a subclass of
+_OptimizationProblemFirst_.
+The "first" stands for first-order, meaning that the objective function is
+differentiable.
+
+The class provides us with helper functions and manages the state of the
+optimization.
+The member variable __parameters__ holds the current position in parameter
+space.
+
+Two functions must be implemented: __computeObjective__ and
+__computeGradient__.
+There also has to be a constructor that explicitly calls the
+_OptimizationProblemFirst_ constructor because it needs to know the
+dimensionality of the problem.
+
+## Includes
+The sample program needs some STL includes for I/O and to convert the command
+line parameters to floating-point values.
+We use the integrated _FirstOrderRasmussen_ solver in this example:
+
+```c++
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <core/vector/VectorT.h>
+#include <core/optimization/gradientBased/OptimizationProblemFirst.h>
+#include <core/optimization/gradientBased/FirstOrderRasmussen.h>
+```
+
+## The _QuadraticOptimizationProblem_ class
+Our _QuadraticOptimizationProblem_ class has member variables for each of the
+parameters. Everything else is managed by the base class.
+
+The constructor initializes the member variables and class the base constructor
+with the parameter "1", because this is a one-dimensional problem.
+
+```c++
+class QuadraticOptimizationProblem : public NICE::OptimizationProblemFirst {
+private:
+	double a, b, c;
+
+public:
+	QuadraticOptimizationProblem(double a, double b, double c) :
+		OptimizationProblemFirst(1),
+		a(a), b(b), c(c) { }
+```
+
+Because we want to find the minimum of the quadratic function f(x), the
+objective function is the same.
+The __parameters__ function returs the current state (position) of the
+optimization process.
+
+```c++
+double computeObjective() {
+	double x = parameters()(0);	
+	return a * x * x + b * x + c;
+}
+```
+
+The gradient function is just as simple.
+It gets called with a const reference to a _Vector_ that matches the
+dimensionality of the problem.
+We write the value of the derivative f'(x) = 2ax+b into the _Vector_:
+
+```c++
+void computeGradient(NICE::Vector& newGradient) {
+	double x = parameters()(0);	
+	double dx_dy = 2.0 * a * x + b;
+	newGradient(0) = dx_dy;
+}
+```
+
+## The program
+First, a small utility function to convert the command line arguments:
+
+```c++
+double convert_param(const std::string& s) {
+	double r;
+	if(!(std::istringstream(s) >> r)) {
+		return 0;
+	}
+	return r;
+}
+```
+
+Now, the main function.
+We start by counting the argmuments and converting them if there are enough
+of them.
+They are the displayed for verification:
+
+```c++
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 4) {
+		std::cout << "USAGE: " << argv[0] << " <a> <b> <c>\n";
+		return -1;
+	}
+
+	// Convert the arguments
+	double param_a = convert_param(argv[1]);
+	double param_b = convert_param(argv[2]);
+	double param_c = convert_param(argv[3]);
+	std::cout << "Optimizing function f(x) = " << param_a << " x^2 + ";
+	std::cout << param_b << " x + " << param_c << "\n";
+```
+
+Solving the problem is very simple and done in three lines:
+
+```c++
+QuadraticOptimizationProblem problem(param_a, param_b, param_c);
+NICE::FirstOrderRasmussen solver;
+solver.optimizeFirst(problem);
+```
+
+The solution is part of the problem's state and can be accessed by calling the
+__position__ method:
+
+```c++
+double x_min = problem.position()(0);
+std::cout << "Solution: " << x_min << "\n";
+```
+
+## Running the sample
+
+_Command line:_
+
+```bash
+./06_optimization 4.3 5 2.3
+```
+
+_Output:_
+
+```
+Optimizing function f(x) = 4.3 x^2 + 5 x + 2.3
+FirstOrderRasmussen: initial value of the objective function is 2.3
+Iteration 1 / 100  objective function = 2.3
+FirstOrderRasmussen: new objective value 0.846598
+Iteration 3 / 100  objective function = 0.846598
+FirstOrderRasmussen: new objective value 0.846512
+Iteration 7 / 100  objective function = 0.846512
+FirstOrderRasmussen: low gradient 7.72715e-14 < 1e-05 = epsilonG
+Solution: -0.581395
+```

+ 39 - 0
core/tutorial/doc/samples.md

@@ -0,0 +1,39 @@
+# Sample code
+Some tutorials come with sample code for a more hands-on learning experience.
+The following sample programs are available:
+
+| Tutorial | Sample Program |
+| -: | - |
+| 01 | Simple program that reads a file and writes the image to another|
+| 02 | Program that optimizes the contrast of a grayscale image|
+| 03 | Program that colorizes a grayscale image using pseudocolors|
+| 04 | Program that applies a motion blur effect to an image using a linear filter|
+| 05 / 06 | Program that loads a Matlab file to showcase algebra functions|
+| 07 | Program that minimizes a given quadratic function |
+
+# Sample images for sample code
+NICE-core supports PPM and PGM images out of the box without any additional
+dependencies.
+
+See the __samples__ folder for sample images that work with the sample code
+from the tutorials.
+
+## Grayscale sample images
+The grayscale samples are 8-bit PGM files.
+You can use them with the following sample programs:
+
+* Tutorial 02
+* Tutorial 03
+* Tutorial 04
+
+## Color sample images
+The color samples are 8-bit-per-channel PPM images.
+They work with the sample code from these tutorials:
+
+* Tutorial 01
+
+# Other samples
+We also include some Matlab files for use with the following samples:
+
+* Tutorial 05
+* Tutorial 06

+ 45 - 0
core/tutorial/progs/01_imageio.cpp

@@ -0,0 +1,45 @@
+/*
+ * Tutorial 01 - Basic Image I/O Operations
+ * Sample Implementation
+ *
+ * @file 01_imageio.cpp
+ * @brief Sample implementation for tutorial 01
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ImageFile.h>
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 3) {
+		std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+		return -1;
+	}	
+
+	// These are our file names
+	std::string input_path(argv[1]);
+	std::string output_path(argv[2]);
+
+	// Read file header and display header information
+	NICE::ImageFile source_file(input_path);
+	NICE::ImageFile::Header source_header = source_file.getHeader();
+
+	std::cout << "Source image dimensions: " << source_header.width << " x " << source_header.height;
+	std::cout << " (" << source_header.channel << " channels, " << source_header.bitdepth << " bpp)\n";
+
+	// Read image into memory
+	NICE::ColorImage source_image;
+	source_file.reader(&source_image);
+
+	// Write image to disk
+	NICE::ImageFile dest_image(output_path);
+	dest_image.writer(&source_image);
+	return 0;
+}

+ 74 - 0
core/tutorial/progs/02_grayscale.cpp

@@ -0,0 +1,74 @@
+/*
+ * Tutorial 02 - Grayscale Image Operations
+ * Sample Implementation
+ *
+ * @file 02_grayscale.cpp
+ * @brief Sample implementation for tutorial 02
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ImageFile.h>
+#include <core/image/Histogram.h>
+#include <core/vector/VectorT.h>
+
+/*
+ * Entry point
+ */
+
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 3) {
+		std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+		return -1;
+	}
+
+	// These are our file names
+	std::string input_path(argv[1]);
+	std::string output_path(argv[2]);
+
+	// Read image into memory
+	NICE::ImageFile source_file(input_path);
+	NICE::Image image;
+	source_file.reader(&image);
+
+	// Calculate cumulative histogram
+	NICE::Histogram histogram(image, 0, 256);
+	NICE::IntVector* cumulative_histogram = histogram.cumulative();
+
+	// The largest value in the cumulative histogram is the total pixel count
+	// of the source image. We need to scale this down to 255 to match the pixel
+	// format of the image.
+	double factor = 255.0/(double)(image.width()*image.height());
+
+	// Transform using our pattern
+	for(int x = 0; x < image.width(); x++) {
+		for(int y=0; y < image.height(); y++) {
+			// This is the old gray value
+			Ipp8u pixel = image.getPixelQuick(x, y);
+
+			// We use it as and index into the cumulative histogram to
+			// computer the new one. This has to be scaled appropriately
+			// using our precomputed factor.
+			double new_pixel_f =
+					((double)cumulative_histogram->get(pixel))*factor;
+
+			// The pixel format is 8-bit integer, so we have to convert
+			// the result
+			Ipp8u new_pixel = static_cast<Ipp8u>(new_pixel_f + 0.5);
+
+			// ..and save it
+			image.setPixelQuick(x, y, new_pixel);
+
+		}
+	}
+
+
+	// Write image to disk
+	NICE::ImageFile dest_image(output_path);
+	dest_image.writer(&image);
+	return 0;
+}

+ 45 - 0
core/tutorial/progs/03_color.cpp

@@ -0,0 +1,45 @@
+/*
+ * Tutorial 03 - Color Image Operations
+ * Sample Implementation
+ *
+ * @file 03_color.cpp
+ * @brief Sample implementation for tutorial 03
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+ 
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/image/ColorImageT.h>
+#include <core/image/ImageFile.h>
+#include <core/image/Convert.h>
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 3) {
+		std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+		return -1;
+	}
+
+	// These are our file names
+	std::string input_path(argv[1]);
+	std::string output_path(argv[2]);
+
+	// Read image into memory
+	NICE::ImageFile source_file(input_path);
+	NICE::Image image;
+	source_file.reader(&image);
+
+	// Calculate pseudocolors
+	NICE::ColorImage pseudo_image(image.width(), image.height());
+	NICE::imageToPseudoColor(image, pseudo_image);
+
+	// Write image to disk
+	NICE::ImageFile dest_image(output_path);
+	dest_image.writer(&pseudo_image);
+	return 0;
+}

+ 53 - 0
core/tutorial/progs/04_filter.cpp

@@ -0,0 +1,53 @@
+/*
+ * Tutorial 04 - Filters
+ * Sample Implementation
+ *
+ * @file 04_filter.cpp
+ * @brief Sample implementation for tutorial 04
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <core/image/ImageT.h>
+#include <core/vector/MatrixT.h>
+#include <core/image/FilterT.h>
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+		if (argc < 3) {
+			std::cout << "USAGE: " << argv[0] << " <input image> <output image>\n";
+			return -1;
+		}
+
+		// These are our file names
+		std::string input_path(argv[1]);
+		std::string output_path(argv[2]);
+
+		// Read file header and display header information
+		NICE::ImageFile source_file(input_path);
+
+		// Read image into memory
+		NICE::Image image;
+		source_file.reader(&image);
+
+		// Allocate memory for result image
+		NICE::Image result(image.width(), image.height());
+
+		// Put together a simple convolution kernel for our motion blur effect
+		NICE::Matrix kernel(10,10);
+		kernel.set(0);
+		kernel.addIdentity(0.1);
+
+		// Filter the image
+		NICE::Filter::filter(image, kernel, result);
+
+		// Write image to disk
+		NICE::ImageFile dest_image(output_path);
+		dest_image.writer(&result);
+		return 0;
+}

+ 125 - 0
core/tutorial/progs/05_matio.cpp

@@ -0,0 +1,125 @@
+/*
+ * Tutorials 05/06 - Matlab I/O and Linear Algebra
+ * Sample Implementation
+ *
+ * @file 05_matio.cpp
+ * @brief Sample implementation for tutorials 05/06
+ * @date 09.03.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <exception>
+#include <core/image/ImageT.h>
+#include <core/vector/MatrixT.h>
+#include <core/vector/VectorT.h>
+#include <core/vector/Eigen.h>
+#include <core/vector/SVD.h>
+#include <core/image/FilterT.h>
+
+#ifdef NICE_USELIB_MATIO
+#include <core/matlabAccess/MatFileIO.h>
+
+template<typename T> void printMatrix(NICE::MatrixT<T> matrix);
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 3) {
+		std::cout << "USAGE: " << argv[0] << " <matlab file> <matrix name>\n";
+		return -1;
+	}
+
+	// These are our file names
+	std::string input_path(argv[1]);
+	std::string matrix_name(argv[2]);
+
+	NICE::MatFileIO matlab_file(input_path, MAT_ACC_RDONLY);
+	
+	// Show the number of variables in the file
+	int vars_in_file = matlab_file.getNumberOfVariables();
+	std::cout << vars_in_file << " Variables in " << input_path << "\n";
+
+	// Load the matrix
+	std::cout << "Loading matrix \"" << matrix_name << "\"...\n";
+
+	// Check if the variable is a matrix
+	matvar_t* matrix_variable = matlab_file.getVariableViaName(matrix_name);
+	if(matrix_variable->rank != 2) {
+		std::cout << "Variable is not a matrix. Rank: " << matrix_variable->rank << ".\n";
+		return -1;
+	}
+
+	// Read the dimensions
+	int cols = matrix_variable->dims[1];
+	int rows = matrix_variable->dims[0];
+	std::cout << "Dimensions: " << cols << " x " << rows << "\n";
+
+	// Read the matrix into a vector of vectors
+	std::vector< std::vector<double> > matrix_vecvec(rows, std::vector<double>(cols));
+	matlab_file.getFeatureMatrixViaName(matrix_vecvec, matrix_name);
+
+	// Now, we want a NICE matrix
+	NICE::MatrixT<double> matrix(rows, cols);
+	for(int i = 0; i < rows; i++) {
+		for(int j = 0; j < cols; j++) {
+			matrix(i,j) = matrix_vecvec[i][j];
+		}
+	}
+
+	// Print the NICE matrix
+	printMatrix(matrix);
+
+	// Check if eigenvalues exist
+	if(rows != cols) {
+		std::cout << "Matrix is not square, cannot calculate eigenvalues!\n";
+		return -1;
+	}
+
+	// Calculate eigenvalues
+	try {
+		NICE::VectorT<double>* matrix_eigenvalues = NICE::eigenvalues(matrix);
+	} catch (std::exception& e) {
+		std::cout << "Exception occured during eigenvalue calculation, "
+			<< "is IPP installed?\n";
+	}
+
+#ifdef NICE_USELIB_LINAL
+	// Calculate singular value decomposition
+	NICE::SVD<double> matrix_svd(matrix);
+
+	std::cout << "Vt:\n";
+	printMatrix(matrix_svd.getVt());
+
+	std::cout << "U:\n";
+	printMatrix(matrix_svd.getU());
+
+	std::cout << "S:\n";
+	printMatrix(matrix_svd.getS());
+#else
+	std::cout << "LinAL is not installed, SVD calculation is not possible!\n";
+#endif
+	return 0;
+
+}
+
+template<typename T> void printMatrix(NICE::MatrixT<T> matrix) {
+	for(int i = 0; i < matrix.rows(); i++) {
+		for(int j = 0; j < matrix.cols(); j++) {
+			std::cout << matrix(i,j) << "\t";
+		}
+		std::cout << "\n";
+	}
+}
+#else
+
+/*
+ * Replacement entry point
+ */
+int main(int argc, char** argv) {
+	std::cout << "This sample needs MATIO to work!\n";
+}
+#endif

+ 80 - 0
core/tutorial/progs/06_optimization.cpp

@@ -0,0 +1,80 @@
+/*
+ * Tutorial 07 - Optimization Problmes
+ * Sample Implementation
+ *
+ * @file 06_optimization.cpp
+ * @brief Sample implementation for tutorial 07
+ * @date 28.04.2014
+ * @author Clemens-A. Brust
+ */
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <core/vector/VectorT.h>
+#include <core/optimization/gradientBased/OptimizationProblemFirst.h>
+#include <core/optimization/gradientBased/FirstOrderRasmussen.h>
+
+class QuadraticOptimizationProblem : public NICE::OptimizationProblemFirst {
+private:
+	double a, b, c;
+
+public:
+	QuadraticOptimizationProblem(double a, double b, double c) :
+		OptimizationProblemFirst(1),
+		a(a), b(b), c(c) { }
+
+	double computeObjective() {
+		double x = parameters()(0);	
+		return a * x * x + b * x + c;
+	}
+	
+	void computeGradient(NICE::Vector& newGradient) {
+		double x = parameters()(0);	
+		double dx_dy = 2.0 * a * x + b;
+		newGradient(0) = dx_dy;
+	}
+};
+
+
+/*
+ * Parameter conversion
+ */
+double convert_param(const std::string& s) {
+	double r;
+	if(!(std::istringstream(s) >> r)) {
+		return 0;
+	}
+	return r;
+}
+
+
+/*
+ * Entry point
+ */
+int main(int argc, char** argv) {
+	// Check if enough parameters were supplied
+	if (argc < 4) {
+		std::cout << "USAGE: " << argv[0] << " <a> <b> <c>\n";
+		return -1;
+	}
+
+	// Convert the arguments
+	double param_a = convert_param(argv[1]);
+	double param_b = convert_param(argv[2]);
+	double param_c = convert_param(argv[3]);
+	
+	std::cout << "Optimizing function f(x) = " << param_a << " x^2 + ";
+	std::cout << param_b << " x + " << param_c << "\n";
+
+	// Instantiate and solve the problem
+	QuadraticOptimizationProblem problem(param_a, param_b, param_c);
+	NICE::FirstOrderRasmussen solver;
+	solver.optimizeFirst(problem);
+
+	// Display the solution
+	double x_min = problem.position()(0);
+	std::cout << "Solution: " << x_min << "\n";
+
+	return 0;
+}

二進制
core/tutorial/samples/peppers_color.ppm


文件差異過大導致無法顯示
+ 4 - 0
core/tutorial/samples/peppers_gray.pgm


二進制
core/tutorial/samples/simple.mat


二進制
core/tutorial/screenshots/tut02_eq_hist_new.png


二進制
core/tutorial/screenshots/tut02_eq_hist_org.png


二進制
core/tutorial/screenshots/tut02_eq_new.png


二進制
core/tutorial/screenshots/tut02_eq_org.png


+ 48 - 30
core/vector/SparseVectorT.h

@@ -32,7 +32,7 @@ class SparseVectorT : public std::map<I, V>, public Persistent
 
 
   protected:
   protected:
     //! dimension of the SparseVector, not properly implemented! FIXME
     //! dimension of the SparseVector, not properly implemented! FIXME
-    int dim;
+    uint dim;
     
     
 
 
   public:
   public:
@@ -42,26 +42,30 @@ class SparseVectorT : public std::map<I, V>, public Persistent
      * @param k position of the value
      * @param k position of the value
      * @param v value
      * @param v value
      */
      */
-    SparseVectorT ( I k, V v );
-    SparseVectorT ( const std::map<I, V> & mymap );
+    SparseVectorT ( I _k, 
+                    V _v
+                  );
+    SparseVectorT ( const std::map<I, V> & _mymap );
 
 
     /**
     /**
      * simple constructor -> does nothing
      * simple constructor -> does nothing
      */
      */
-    SparseVectorT ():dim(-1) {}
+    SparseVectorT ():dim(0) {}
 
 
     /**
     /**
      * Constructor with the dimension
      * Constructor with the dimension
      * @param _dim dimension of the SparseVector
      * @param _dim dimension of the SparseVector
      */
      */
-    SparseVectorT ( int _dim );
+    SparseVectorT ( uint _dim );
 
 
     /**
     /**
      * converts a ICE::Vector to a SparseVector with a tolerance factor
      * converts a ICE::Vector to a SparseVector with a tolerance factor
      * @param v input ICE::Vector
      * @param v input ICE::Vector
      * @param tolerance tolerance value
      * @param tolerance tolerance value
      */
      */
-    SparseVectorT ( const NICE::Vector &v, double tolerance = 1e-15 );
+    SparseVectorT ( const NICE::Vector & _v, 
+                    double _tolerance = 1e-15
+                  );
 
 
     /**
     /**
      * simple destructor
      * simple destructor
@@ -72,44 +76,56 @@ class SparseVectorT : public std::map<I, V>, public Persistent
      * add the elements of a SparseVector to this SparseVector
      * add the elements of a SparseVector to this SparseVector
      * @param v input SparseVector
      * @param v input SparseVector
      */
      */
-    void add ( const SparseVectorT<I,V> & v );
+    void add ( const SparseVectorT<I,V> & _v );
 
 
     /**
     /**
      * add the elements of a SparseVector to this NICE::Vector and multiply each element with a constant lambda
      * add the elements of a SparseVector to this NICE::Vector and multiply each element with a constant lambda
      * @param v
      * @param v
      * @param lambda
      * @param lambda
      */
      */
-    void add ( const SparseVectorT<I,V> & v, double lambda );
+    void add ( const SparseVectorT<I,V> & _v, 
+               double _lambda 
+             );
     
     
     /**
     /**
      * add to each element a constant
      * add to each element a constant
      * @param value
      * @param value
      */
      */
-    void add ( V value );
+    void add ( V _value );
     
     
     /**
     /**
      * sub the elements of a SparseVector from this SparseVector
      * sub the elements of a SparseVector from this SparseVector
      * @param v input SparseVector
      * @param v input SparseVector
      */
      */
-    void sub ( const SparseVectorT<I,V> & v );
+    void sub ( const SparseVectorT<I,V> & _v );
 
 
     /** add a sparse vector given as a STL map with integer values multiplied with a scalar to the current vector */
     /** add a sparse vector given as a STL map with integer values multiplied with a scalar to the current vector */
-    void addMap ( const std::map<int, int> & v, double lambda = 1.0 );
+    void addMap ( const std::map<uint, int> & _v, 
+                  double _lambda = 1.0
+                );
 
 
     /** add a sparse vector given as a STL map with double values multiplied with a scalar to the current vector */
     /** add a sparse vector given as a STL map with double values multiplied with a scalar to the current vector */
-    void addMap ( const std::map<int, double> & v, double lambda = 1.0 );
+    void addMap ( const std::map<uint, double> & _v, 
+                  double _lambda = 1.0 
+                );
 
 
     /** normalize, such that all elements sum to one */
     /** normalize, such that all elements sum to one */
     void normalize ();
     void normalize ();
     
     
     /** normalize in given interval between maxv and minv */
     /** normalize in given interval between maxv and minv */
-    void normalize (V minv, V maxv);
+    void normalize (V _minv, 
+                    V _maxv
+                   );
 
 
     /** read from a stream */
     /** read from a stream */
-    void restore ( std::istream & is, int format = 0 );
+    void restore ( std::istream & _is, 
+                   int _format = 0 
+                 );
 
 
     /** write to a stream */
     /** write to a stream */
-    void store ( std::ostream & os, int format = 0 ) const;
+    void store ( std::ostream & _os,
+                 int _format = 0 
+               ) const;
 
 
     /** clear the data of the vector */
     /** clear the data of the vector */
     void clear ();
     void clear ();
@@ -121,32 +137,32 @@ class SparseVectorT : public std::map<I, V>, public Persistent
      * each element of the SparseVector is multiplied by the elements of the input SparseVector
      * each element of the SparseVector is multiplied by the elements of the input SparseVector
      * @param v input SparseVector
      * @param v input SparseVector
      */
      */
-    void multiply ( const SparseVectorT<I,V> & v );
+    void multiply ( const SparseVectorT<I,V> & _v );
 
 
     /**
     /**
      * each element of the SparseVector is multiplied by a constant value
      * each element of the SparseVector is multiplied by a constant value
      * @param val factor
      * @param val factor
      */
      */
-    void multiply ( V val );
+    void multiply ( V _val );
 
 
     /**
     /**
      * each element of the SparseVector is divided by the elements of the input SparseVector
      * each element of the SparseVector is divided by the elements of the input SparseVector
      * @param v input SparseVector
      * @param v input SparseVector
      */
      */
-    void divide ( const SparseVectorT<I,V> & v );
+    void divide ( const SparseVectorT<I,V> & _v );
 
 
     /**
     /**
      * each element of the SparseVector is divided by a constant value
      * each element of the SparseVector is divided by a constant value
      * @param v divisor
      * @param v divisor
      */
      */
-    void divide ( V v );
+    void divide ( V _v );
 
 
     /**
     /**
      * computes the inner product of two SparseVectors
      * computes the inner product of two SparseVectors
      * @param v the second sparse vector
      * @param v the second sparse vector
      * @return inner product
      * @return inner product
      */
      */
-    double innerProduct ( const SparseVectorT<I,V> & v ) const;
+    double innerProduct ( const SparseVectorT<I,V> & _v ) const;
 
 
     /** get the sum of all elements */
     /** get the sum of all elements */
     V sum () const;
     V sum () const;
@@ -164,25 +180,27 @@ class SparseVectorT : public std::map<I, V>, public Persistent
     I maxElementExclusive ( I key ) const;
     I maxElementExclusive ( I key ) const;
 
 
     /** get all indices of elements with non-zero values as a sorted STL vector */
     /** get all indices of elements with non-zero values as a sorted STL vector */
-    void getSortedIndices ( std::vector<I> & indizes ) const;
+    void getSortedIndices ( std::vector<I> & _indizes ) const;
 
 
     /** get an element */
     /** get an element */
-    V get ( I i ) const;
+    V get ( I _i ) const;
 
 
     /** set an element */
     /** set an element */
-    bool set ( I i , V newValue );
+    bool set ( I _i , 
+               V _newValue 
+             );
 
 
     /**
     /**
      * set the dimension of the SparseVector
      * set the dimension of the SparseVector
      * @param _dim
      * @param _dim
      */
      */
-    void setDim ( int _dim );
+    void setDim ( uint _dim );
 
 
     /**
     /**
      * returns the dimension of the SparseVector
      * returns the dimension of the SparseVector
      * @return dimension
      * @return dimension
      */
      */
-    int getDim() const;
+    uint getDim() const;
     
     
     /**
     /**
     * @brief calculate the value of the minimum kernel
     * @brief calculate the value of the minimum kernel
@@ -190,7 +208,7 @@ class SparseVectorT : public std::map<I, V>, public Persistent
     * @param b 2nd argument of the minimum kernel, which is symmetric
     * @param b 2nd argument of the minimum kernel, which is symmetric
     * @return resulting value of the minimum kernel
     * @return resulting value of the minimum kernel
     */
     */
-    double minimumKernel ( const SparseVectorT<I,V> & b ) const;
+    double minimumKernel ( const SparseVectorT<I,V> & _b ) const;
 
 
     /** pick a random index by interpreting the elements of the vector as
     /** pick a random index by interpreting the elements of the vector as
         an unnormalized multinomial distribution */
         an unnormalized multinomial distribution */
@@ -200,12 +218,12 @@ class SparseVectorT : public std::map<I, V>, public Persistent
      * @brief computes a full NICE::VectorT from the current SparseVectorT object. the dimension has to be set properly for this method!
      * @brief computes a full NICE::VectorT from the current SparseVectorT object. the dimension has to be set properly for this method!
      * @param v resulting NICE::VectorT
      * @param v resulting NICE::VectorT
      */
      */
-    void convertToVectorT(NICE::VectorT<V> & v ) const ;     
+    void convertToVectorT(NICE::VectorT<V> & _v ) const ;     
 };
 };
 
 
-typedef SparseVectorT<long, double> SparseVectorLong;
-typedef SparseVectorT<int, double> SparseVectorInt;
-typedef SparseVectorT<short, double> SparseVector;
+typedef SparseVectorT<unsigned long, double> SparseVectorLong;
+typedef SparseVectorT<unsigned int, double> SparseVectorInt;
+typedef SparseVectorT<unsigned short, double> SparseVector;
 
 
 } // namespace
 } // namespace
 
 

+ 31 - 27
core/vector/SparseVectorT.tcc

@@ -27,20 +27,20 @@ SparseVectorT<I,V>::SparseVectorT ( const std::map<I, V> & mymap ):std::map<I, V
 template<typename I, typename V>
 template<typename I, typename V>
 SparseVectorT<I,V>::SparseVectorT ( I k, V v )
 SparseVectorT<I,V>::SparseVectorT ( I k, V v )
 {
 {
-  this->insert ( std::pair<short, double> ( k, v ) );
-  dim = k;
+  this->insert ( std::pair<I, V> ( k, v ) );
+  this->dim = k;
 }
 }
 
 
 template<typename I, typename V>
 template<typename I, typename V>
-SparseVectorT<I,V>::SparseVectorT ( int _dim ) : dim ( _dim )
+SparseVectorT<I,V>::SparseVectorT ( uint _dim ) : dim ( _dim )
 {
 {
 }
 }
 
 
 template<typename I, typename V>
 template<typename I, typename V>
 SparseVectorT<I,V>::SparseVectorT ( const NICE::Vector &v, double tolerance )
 SparseVectorT<I,V>::SparseVectorT ( const NICE::Vector &v, double tolerance )
 {
 {
-  dim = (int)v.size();
-  for ( int i = 0; i < dim; i++ )
+  this->dim = v.size();
+  for ( uint i = 0; i < dim; i++ )
   {
   {
     if ( fabs ( v[i] ) > tolerance )
     if ( fabs ( v[i] ) > tolerance )
       this->insert ( std::pair<I, V> ( i, v[i] ) );
       this->insert ( std::pair<I, V> ( i, v[i] ) );
@@ -57,7 +57,7 @@ void SparseVectorT<I,V>::sub ( const SparseVectorT<I,V> & v )
 template<typename I, typename V>
 template<typename I, typename V>
 void SparseVectorT<I,V>::add ( const SparseVectorT<I,V> & v )
 void SparseVectorT<I,V>::add ( const SparseVectorT<I,V> & v )
 {
 {
-  add ( v, 1.0 );
+  this->add ( v, 1.0 );
 }
 }
 
 
 template<typename I, typename V>
 template<typename I, typename V>
@@ -326,16 +326,16 @@ void SparseVectorT<I,V>::normalize ( V minv, V maxv )
 }
 }
 
 
 template<typename I, typename V>
 template<typename I, typename V>
-void SparseVectorT<I,V>::addMap ( const std::map<int, int> & v, double lambda )
+void SparseVectorT<I,V>::addMap ( const std::map<uint, int> & v, double lambda )
 {
 {
-  for ( std::map<int, int>::const_iterator v_it = v.begin(); v_it != v.end(); v_it++ )
+  for ( std::map<uint, int>::const_iterator v_it = v.begin(); v_it != v.end(); v_it++ )
     ( *this ) [(I)v_it->first] += (V)v_it->second * lambda;
     ( *this ) [(I)v_it->first] += (V)v_it->second * lambda;
 }
 }
 
 
 template<typename I, typename V>
 template<typename I, typename V>
-void SparseVectorT<I,V>::addMap ( const std::map<int, double> & v, double lambda )
+void SparseVectorT<I,V>::addMap ( const std::map<uint, double> & v, double lambda )
 {
 {
-  for ( std::map<int, double>::const_iterator v_it = v.begin(); v_it != v.end(); v_it++ )
+  for ( std::map<uint, double>::const_iterator v_it = v.begin(); v_it != v.end(); v_it++ )
     ( *this ) [(I)v_it->first] += (V)v_it->second * lambda;
     ( *this ) [(I)v_it->first] += (V)v_it->second * lambda;
 }
 }
 
 
@@ -456,15 +456,15 @@ bool SparseVectorT<I,V>::set ( I i , V newValue )
 }
 }
 
 
 template<typename I, typename V>
 template<typename I, typename V>
-void SparseVectorT<I,V>::setDim ( int _dim )
+void SparseVectorT<I,V>::setDim ( uint _dim )
 {
 {
-  dim = _dim;
+  this->dim = _dim;
 }
 }
 
 
 template<typename I, typename V>
 template<typename I, typename V>
-int SparseVectorT<I,V>::getDim() const
+uint SparseVectorT<I,V>::getDim() const
 {
 {
-  return dim;
+  return this->dim;
 }
 }
 
 
 template<typename I, typename V>
 template<typename I, typename V>
@@ -530,19 +530,23 @@ I SparseVectorT<I,V>::pickRandomSample() const
 template<typename I, typename V>
 template<typename I, typename V>
 void SparseVectorT<I,V>::convertToVectorT(NICE::VectorT<V> & v ) const
 void SparseVectorT<I,V>::convertToVectorT(NICE::VectorT<V> & v ) const
 {
 {
-  int dimension (this->getDim());
-  //dimension flag was not set properly
-  if (dimension < 0)
+  uint dimension ( this->getDim() );
+
+  if ( dimension == 0 )
   {
   {
-    typename SparseVectorT<I,V>::const_iterator i = this->end(); i--;
-    int dist (distance(this->begin(), this->end()) );
-    if (dist > 0)
-      dimension = i->first+1; //plus one, since this is the index, but we need the resulting size
+    // if dimension is zero, it could either be the case that the sparse vector is empty, or that the dimension flag was not set properly. 
+    // thus, let's check out the largest dimension
+    // could be removed later... only needed for backwards compatibility
+    typename SparseVectorT<I,V>::const_iterator svIt = this->end(); 
+    svIt--;
+    uint dist (distance(this->begin(), this->end()) );
+    if ( dist > 0 )
+      dimension = svIt->first+1; //plus one, since this is the index, but we need the resulting size
     //we're not allowed here to set the dimension flag, since we want to have this method to be a const one
     //we're not allowed here to set the dimension flag, since we want to have this method to be a const one
   }
   }
 
 
-  //our sparse vector is empty
-  if (dimension <= 0)
+  // is our sparse vector empty?
+  if ( dimension == 0 )
   {
   {
     v.clear();
     v.clear();
     v.resize(0);
     v.resize(0);
@@ -556,12 +560,12 @@ void SparseVectorT<I,V>::convertToVectorT(NICE::VectorT<V> & v ) const
   v.set( (V) 0.0);
   v.set( (V) 0.0);
 
 
   //add the actual content
   //add the actual content
-  typename SparseVectorT<I,V>::const_iterator i = this->begin();
-  for ( ; i != this->end(); i++ )
+  typename SparseVectorT<I,V>::const_iterator svIt = this->begin();
+  for ( ; svIt != this->end(); svIt++ )
   {
   {
     //just to be sure that we do not get some errors due to badly set dimension flags
     //just to be sure that we do not get some errors due to badly set dimension flags
-    if (i->first < dimension)
-      v[i->first] = i->second;
+    if (svIt->first < dimension)
+      v[svIt->first] = svIt->second;
   }
   }
 }
 }
 
 

+ 1 - 0
core/vector/ippwrapper.tcc

@@ -4,6 +4,7 @@
 #include <numeric>
 #include <numeric>
 #include <cmath>
 #include <cmath>
 #include <functional>
 #include <functional>
+#include <cstdlib>
 
 
 template<class P>
 template<class P>
 inline IppStatus ippsCopy( const P* pSrc, P* pDst, int len ) {
 inline IppStatus ippsCopy( const P* pSrc, P* pDst, int len ) {

+ 3 - 3
core/vector/libdepend.inc

@@ -1,4 +1,4 @@
-$(call PKG_DEPEND_EXT,LINAL)
-$(call PKG_DEPEND_EXT,IPP)
+# $(call PKG_DEPEND_EXT,LINAL)
+# $(call PKG_DEPEND_EXT,IPP)
 $(call PKG_DEPEND_INT,core/basics)
 $(call PKG_DEPEND_INT,core/basics)
-$(call PKG_DEPEND_EXT,OPENMP)
+# $(call PKG_DEPEND_EXT,OPENMP)

+ 4 - 0
core/vector/progs/testCholeskySpeed.cpp

@@ -38,7 +38,11 @@ double getInvError ( const Matrix & A, const Matrix & Ainv )
 int main (int argc, char **argv)
 int main (int argc, char **argv)
 {   
 {   
 #ifndef WIN32
 #ifndef WIN32
+#ifndef __clang__
+#ifndef __llvm__ 
     std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
     std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+#endif
 #endif
 #endif
 
 
     int size = 500;
     int size = 500;

+ 73 - 0
core/vector/tests/TestSVD.cpp

@@ -0,0 +1,73 @@
+/*
+ * NICE-Core - efficient algebra and computer vision methods
+ *  - libbasicvector - An core/vector/template for new NICE libraries
+ * See file License for license information.
+ */
+
+#ifdef NICE_USELIB_CPPUNIT
+#include "TestSVD.h"
+#include "core/basics/cppunitex.h"
+#include "core/vector/MatrixT.h"
+#include "core/vector/SVD.h"
+
+#include <string>
+#include <exception>
+
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestSVD );
+
+void TestSVD::setUp() {
+}
+
+void TestSVD::tearDown() {
+}
+
+
+#define sr(tr, tm, t0, t1, t2, t3) tm(tr,0)=t0; tm(tr,1)=t1; tm(tr,2)=t2; tm(tr,3)=t3;
+
+#define ASSERT_MATRIX_EQUAL(m1, m2) for(int i=0; i<m1.rows(); i++) { \
+	for(int j=0; j<m1.cols(); j++) { \
+		CPPUNIT_ASSERT_DOUBLES_EQUAL(m1(i,j),m2(i,j),0.0002); \
+	} \
+}
+
+void TestSVD::testSVD() {
+	NICE::MatrixT<double> matrix(4,4);
+
+	sr(0, matrix, 1, 2, 3, 4);
+	sr(1, matrix, 4, 5, 6, 7);
+	sr(2, matrix, 2, 3, 4, 5);
+	sr(3, matrix, 2, 9, 8, 1);
+
+	NICE::MatrixT<double> exu(4,4,0);
+	sr(0, exu, -0.2852, -0.2948, -0.7390, -0.5345);
+	sr(1, exu, -0.6079, -0.4409,  0.6038, -0.2673);
+	sr(2, exu, -0.3927, -0.3435, -0.2914,  0.8018);
+	sr(3, exu, -0.6284,  0.7750, -0.0667, -0.0000);
+
+	NICE::MatrixT<double> exs(4,4,0);
+	exs(0,0) = 17.8539;
+	exs(1,1) = 6.3372;
+	exs(2,2) = 1.0374;
+	
+	NICE::MatrixT<double> exv(4,4,0);
+	sr(0, exv, -0.2666, -0.1866,  0.9256, -0.1913);
+	sr(1, exv, -0.5849,  0.4971,  0.0646,  0.6376);
+	sr(2, exv, -0.6218,  0.2046, -0.2823, -0.7013);
+	sr(3, exv, -0.4474, -0.8218, -0.2436,  0.2550);
+
+	NICE::MatrixT<double> fail(4,4,999.999);
+
+#ifdef NICE_USELIB_LINAL
+	NICE::SVD<double> test_svd(matrix);
+	ASSERT_MATRIX_EQUAL(exu, test_svd.getU());
+	ASSERT_MATRIX_EQUAL(exs, test_svd.getS());
+	ASSERT_MATRIX_EQUAL(exv, test_svd.getV());
+#else
+	ASSERT_MATRIX_EQUAL(exu, fail);
+#endif
+
+}
+
+#endif

+ 28 - 0
core/vector/tests/TestSVD.h

@@ -0,0 +1,28 @@
+/*
+ * NICE-Core - efficient algebra and computer vision methods
+ *  - libbasicvector - An core/vector/template for new NICE libraries
+ * See file License for license information.
+ */
+#ifndef _TESTSVD_H
+#define _TESTSVD_H
+
+#include <cppunit/extensions/HelperMacros.h>
+/**
+ * CppUnit-Testcase. 
+ * Test template...
+ */
+class TestSVD : public CppUnit::TestFixture {
+  CPPUNIT_TEST_SUITE( TestSVD );
+  CPPUNIT_TEST( testSVD );
+  CPPUNIT_TEST_SUITE_END();
+  
+ private:
+ 
+ public:
+  void setUp();
+  void tearDown();
+
+  void testSVD();
+};
+
+#endif // _TESTSVD_H

+ 31 - 0
core/vector/tests/TestSparseVector.cpp

@@ -19,6 +19,8 @@ CPPUNIT_TEST_SUITE_REGISTRATION( TestSparseVector );
 using namespace NICE;
 using namespace NICE;
 using namespace std;
 using namespace std;
 
 
+const bool b_verbose = false;
+
 void TestSparseVector::testProducts()
 void TestSparseVector::testProducts()
 {
 {
   SparseVector v1;
   SparseVector v1;
@@ -41,7 +43,13 @@ void TestSparseVector::testProducts()
   SparseVector v3;
   SparseVector v3;
   v3.restore ( iss );
   v3.restore ( iss );
   
   
+  if ( b_verbose )
+    std::cerr << "TestSparseVector::testProducts -- check1 v3 == v1 " << std::endl;
+  
   CPPUNIT_ASSERT ( v3 == v1 );
   CPPUNIT_ASSERT ( v3 == v1 );
+  
+  if ( b_verbose )
+    std::cerr << "TestSparseVector::testProducts -- check1 v3 == v1 passed" << std::endl;
 
 
   //cerr << "Testing SparseVector::FORMAT_INDEX_LINE" << endl;
   //cerr << "Testing SparseVector::FORMAT_INDEX_LINE" << endl;
   stringstream ss;
   stringstream ss;
@@ -50,8 +58,14 @@ void TestSparseVector::testProducts()
   v3.clear();
   v3.clear();
   v3.restore ( ss, SparseVector::FORMAT_INDEX_LINE );
   v3.restore ( ss, SparseVector::FORMAT_INDEX_LINE );
 
 
+  if ( b_verbose )
+    std::cerr << "TestSparseVector::testProducts -- check2 v3 == v1 " << std::endl;
+  
   CPPUNIT_ASSERT ( v3 == v1 );
   CPPUNIT_ASSERT ( v3 == v1 );
   
   
+  if ( b_verbose )
+    std::cerr << "TestSparseVector::testProducts -- check2 v3 == v1 passed" << std::endl;
+  
   //cerr << "Testing SparseVector::FORMAT_INDEX" << endl;
   //cerr << "Testing SparseVector::FORMAT_INDEX" << endl;
   stringstream ss2;
   stringstream ss2;
   v1.store( ss2, SparseVector::FORMAT_INDEX );
   v1.store( ss2, SparseVector::FORMAT_INDEX );
@@ -59,7 +73,13 @@ void TestSparseVector::testProducts()
   v3.clear();
   v3.clear();
   v3.restore ( ss2, SparseVector::FORMAT_INDEX );
   v3.restore ( ss2, SparseVector::FORMAT_INDEX );
 
 
+  if ( b_verbose )
+    std::cerr << "TestSparseVector::testProducts -- check3 v3 == v1" << std::endl;
+  
   CPPUNIT_ASSERT ( v3 == v1 );
   CPPUNIT_ASSERT ( v3 == v1 );
+  
+  if ( b_verbose )
+    std::cerr << "TestSparseVector::testProducts -- check3 v3 == v1 passed" << std::endl;
 
 
 }
 }
 
 
@@ -77,7 +97,18 @@ void TestSparseVector::testConversionToVectorT()
   NICE::Vector vGT(5);
   NICE::Vector vGT(5);
   vGT[0] = 0.5;vGT[1] = 1.0;vGT[2] = 0.0;vGT[3] = 0.1;vGT[4] = 2.0;
   vGT[0] = 0.5;vGT[1] = 1.0;vGT[2] = 0.0;vGT[3] = 0.1;vGT[4] = 2.0;
    
    
+  if ( b_verbose )
+  {
+    std::cerr << "TestSparseVector::testConversionToVectorT -- v == vGT" << std::endl;
+  
+    std::cerr << v << std::endl;
+    std::cerr << vGT << std::endl;
+  }
+  
   CPPUNIT_ASSERT ( v == vGT );
   CPPUNIT_ASSERT ( v == vGT );
+  
+  if ( b_verbose )
+    std::cerr << "TestSparseVector::testConversionToVectorT -- v == vGT passed" << std::endl;
 }
 }
 
 
 #endif
 #endif

+ 22 - 4
templates/Makefile.config.template

@@ -151,7 +151,7 @@ ifeq (1,$(shell test -f $(LINALCONFIG) && echo "1"))
 endif
 endif
 
 
 # ---------------------------------- QT4 (first local install -> if not available 
 # ---------------------------------- QT4 (first local install -> if not available 
-QT4_PKGCONFIG=QtGui QtCore QtOpenGL Qt3Support
+QT4_PKGCONFIG=QtGui QtCore QtOpenGL
 QT4_XML_PKGCONFIG=QtXml
 QT4_XML_PKGCONFIG=QtXml
 
 
 ifeq (1,$(shell pkg-config --exists $(QT4_PKGCONFIG) && echo "1"))
 ifeq (1,$(shell pkg-config --exists $(QT4_PKGCONFIG) && echo "1"))
@@ -161,7 +161,7 @@ else
   QTDIR=$(THIRD_BASE)/qt4
   QTDIR=$(THIRD_BASE)/qt4
   ifeq (1,$(shell test -d $(QTDIR)/lib/pkgconfig && echo "1"))
   ifeq (1,$(shell test -d $(QTDIR)/lib/pkgconfig && echo "1"))
     QT4_PKGCONFIG_XXX=$(QTDIR)/lib/pkgconfig
     QT4_PKGCONFIG_XXX=$(QTDIR)/lib/pkgconfig
-    QT4_PKGCONFIG=$(QT4_PKGCONFIG_XXX)/QtGui.pc $(QT4_PKGCONFIG_XXX)/QtCore.pc $(QT4_PKGCONFIG_XXX)/QtOpenGL.pc $(QT4_PKGCONFIG_XXX)/Qt3Support.pc
+    QT4_PKGCONFIG=$(QT4_PKGCONFIG_XXX)/QtGui.pc $(QT4_PKGCONFIG_XXX)/QtCore.pc $(QT4_PKGCONFIG_XXX)/QtOpenGL.pc
     QT4_XML_PKGCONFIG=$(QT4_PKGCONFIG_XXX)/QtXml.pc
     QT4_XML_PKGCONFIG=$(QT4_PKGCONFIG_XXX)/QtXml.pc
     MOC_BINARY=$(QTDIR)/bin/moc
     MOC_BINARY=$(QTDIR)/bin/moc
   	$(call CONFIGINFO,QT4_3rdparty,1)
   	$(call CONFIGINFO,QT4_3rdparty,1)
@@ -169,7 +169,7 @@ else
 endif
 endif
 
 
 ifeq (1,$(shell pkg-config --exists $(QT4_PKGCONFIG) && echo "1"))
 ifeq (1,$(shell pkg-config --exists $(QT4_PKGCONFIG) && echo "1"))
-  QT4_CFLAGS=-DQT3_SUPPORT -DNICE_USELIB_QT
+  QT4_CFLAGS=-DNICE_USELIB_QT
   # The moc precompiler. Make sure it´s the Qt4 version!
   # The moc precompiler. Make sure it´s the Qt4 version!
   MOC=$(MOC_BINARY) $(QT4_CFLAGS)
   MOC=$(MOC_BINARY) $(QT4_CFLAGS)
 else
 else
@@ -331,7 +331,8 @@ endif
 # for Matze Wackers optimization lib
 # for Matze Wackers optimization lib
 DEBUGFLAGS_CFLAGS=-DOPT_DEBUG -DDEBUG
 DEBUGFLAGS_CFLAGS=-DOPT_DEBUG -DDEBUG
 
 
-MATIODIR=matio/
+MATIODIR=$(NICEHOME)/matio/
+# $(info Matio dir: $(MATIODIR))
 ifeq (1,$(shell test -d $(MATIODIR) && echo "1"))
 ifeq (1,$(shell test -d $(MATIODIR) && echo "1"))
   MATIO_CFLAGS=-DNICE_USELIB_MATIO -I$(MATIODIR)
   MATIO_CFLAGS=-DNICE_USELIB_MATIO -I$(MATIODIR)
   MATIO_LDFLAGS=-L$(MATIODIR) -lmatio
   MATIO_LDFLAGS=-L$(MATIODIR) -lmatio
@@ -339,3 +340,20 @@ ifeq (1,$(shell test -d $(MATIODIR) && echo "1"))
 else
 else
   $(call CONFIGINFO,MATIO,0)
   $(call CONFIGINFO,MATIO,0)
 endif
 endif
+
+#HDF5
+ifeq (1,$(shell pkg-config --exists hdf5 && echo "1"))
+  HDF5_CFLAGS= `pkg-config --cflags hdf5 -DNICE_USELIB_HDF5  
+  HDF5_LDFLAGS=`pkg-config --libs hdf5
+  $(call CONFIGINFO,HDF5_LOCAL,1)
+else
+  HDF5_PREFIX=$(NICEHOME)/matio/hdf5/
+  ifeq (1,$(shell test -d $(HDF5_PREFIX) && echo "1"))
+    HDF5_CFLAGS=-I$(HDF5_PREFIX)/include/ -DNICE_USELIB_HDF5
+    HDF5_LDFLAGS=-L$(HDF5_PREFIX)/lib -L$(HDF5_PREFIX)/lib64 -lhdf5
+    $(call CONFIGINFO,HDF5,1)
+  else
+    $(call CONFIGINFO,HDF5,0)
+  endif
+endif
+

部分文件因文件數量過多而無法顯示