diff --git a/CMake/PackageDepends/MITK_Boost_Config.cmake b/CMake/PackageDepends/MITK_Boost_Config.cmake index b152bfa4f5..04243ce630 100644 --- a/CMake/PackageDepends/MITK_Boost_Config.cmake +++ b/CMake/PackageDepends/MITK_Boost_Config.cmake @@ -1,13 +1,15 @@ +set(Boost_ADDITIONAL_VERSIONS "1.78.0" "1.78") + find_package(Boost REQUIRED COMPONENTS ${Boost_REQUIRED_COMPONENTS_BY_MODULE}) if(Boost_REQUIRED_COMPONENTS_BY_MODULE) foreach(boost_component ${Boost_REQUIRED_COMPONENTS_BY_MODULE}) list(APPEND ALL_LIBRARIES "Boost::${boost_component}") endforeach() endif() list(APPEND ALL_LIBRARIES "Boost::boost") if(MSVC) list(APPEND ALL_LIBRARIES "Boost::dynamic_linking" "bcrypt") endif() diff --git a/CMake/Whitelists/ClassificationCmdApps.cmake b/CMake/Whitelists/ClassificationCmdApps.cmake index a8b1d36b67..19011af613 100644 --- a/CMake/Whitelists/ClassificationCmdApps.cmake +++ b/CMake/Whitelists/ClassificationCmdApps.cmake @@ -1,22 +1,20 @@ include(${CMAKE_CURRENT_LIST_DIR}/CoreCmdApps.cmake) list(APPEND enabled_modules Classification CLCore CLVigraRandomForest CLUtilities CLMRUtilities CLImportanceWeighting Segmentation DataCollection - IpSegmentation - IpFunc SurfaceInterpolation GraphAlgorithms ImageStatistics ImageExtraction PlanarFigure QtWidgets QtWidgetsExt ) diff --git a/CMake/Whitelists/FlowBenchSegmentation.cmake b/CMake/Whitelists/FlowBenchSegmentation.cmake index 1f2ac2ac73..da16f6fad7 100644 --- a/CMake/Whitelists/FlowBenchSegmentation.cmake +++ b/CMake/Whitelists/FlowBenchSegmentation.cmake @@ -1,57 +1,55 @@ set(enabled_modules Core CppMicroServices DICOM DICOMPM DataTypesExt AlgorithmsExt DICOMQI Multilabel SceneSerializationBase DICOMPMIO DICOMImageIO ContourModel DICOMSegIO LegacyGL MapperExt SceneSerialization LegacyIO IOExt MultilabelIO AppUtil QtWidgets QtWidgetsExt Segmentation SegmentationUI PlanarFigure Annotation - IpSegmentation - IpFunc SurfaceInterpolation GraphAlgorithms ImageExtraction ImageStatistics ) set(enabled_plugins org.blueberry.core.commands org.blueberry.core.expressions org.blueberry.core.runtime org.blueberry.ui.qt org.blueberry.ui.qt.help org.blueberry.ui.qt.log org.mitk.core.ext org.mitk.core.services org.mitk.gui.common org.mitk.gui.qt.application org.mitk.gui.qt.common org.mitk.gui.qt.datamanager org.mitk.gui.qt.flow.segmentation org.mitk.gui.qt.flowapplication org.mitk.gui.qt.imagenavigator org.mitk.gui.qt.multilabelsegmentation org.mitk.gui.qt.properties org.mitk.gui.qt.segmentation org.mitk.gui.qt.stdmultiwidgeteditor org.mitk.planarfigure ) diff --git a/CMake/mitkFunctionGetMSVCVersion.cmake b/CMake/mitkFunctionGetMSVCVersion.cmake index e12baec1a3..440d316b7d 100644 --- a/CMake/mitkFunctionGetMSVCVersion.cmake +++ b/CMake/mitkFunctionGetMSVCVersion.cmake @@ -1,25 +1,30 @@ function(mitkFunctionGetMSVCVersion ) if(MSVC) if(MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920) set(VISUAL_STUDIO_PRODUCT_NAME "Visual Studio 2017" PARENT_SCOPE) set(VISUAL_STUDIO_VERSION_MAJOR 14 PARENT_SCOPE) string(SUBSTRING ${MSVC_VERSION} 2 -1 version_minor) set(VISUAL_STUDIO_VERSION_MINOR ${version_minor} PARENT_SCOPE) elseif(MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1930) set(VISUAL_STUDIO_PRODUCT_NAME "Visual Studio 2019" PARENT_SCOPE) set(VISUAL_STUDIO_VERSION_MAJOR 14 PARENT_SCOPE) string(SUBSTRING ${MSVC_VERSION} 2 -1 version_minor) set(VISUAL_STUDIO_VERSION_MINOR ${version_minor} PARENT_SCOPE) + elseif(MSVC_VERSION GREATER_EQUAL 1930 AND MSVC_VERSION LESS 1940) + set(VISUAL_STUDIO_PRODUCT_NAME "Visual Studio 2022" PARENT_SCOPE) + set(VISUAL_STUDIO_VERSION_MAJOR 14 PARENT_SCOPE) + string(SUBSTRING ${MSVC_VERSION} 2 -1 version_minor) + set(VISUAL_STUDIO_VERSION_MINOR ${version_minor} PARENT_SCOPE) else() message(WARNING "Unknown Visual Studio version ${MSVC_VERSION} (CMake/mitkFunctionGetMSVCVersion.cmake)") endif() if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) set(CMAKE_LIBRARY_ARCHITECTURE x64 PARENT_SCOPE) else() set(CMAKE_LIBRARY_ARCHITECTURE x86 PARENT_SCOPE) endif() endif() endfunction() diff --git a/CMakeExternals/Boost.cmake b/CMakeExternals/Boost.cmake index 208c32fcc9..2a92b4030c 100644 --- a/CMakeExternals/Boost.cmake +++ b/CMakeExternals/Boost.cmake @@ -1,337 +1,342 @@ #----------------------------------------------------------------------------- # Boost #----------------------------------------------------------------------------- include(mitkFunctionGetMSVCVersion) #[[ Sanity checks ]] if(DEFINED BOOST_ROOT AND NOT EXISTS ${BOOST_ROOT}) message(FATAL_ERROR "BOOST_ROOT variable is defined but corresponds to non-existing directory") endif() string(REPLACE "^^" ";" MITK_USE_Boost_LIBRARIES "${MITK_USE_Boost_LIBRARIES}") set(proj Boost) set(proj_DEPENDENCIES ) set(Boost_DEPENDS ${proj}) if(NOT DEFINED BOOST_ROOT AND NOT MITK_USE_SYSTEM_Boost) #[[ Reset variables. ]] set(patch_cmd "") set(configure_cmd "") set(install_cmd "") set(BOOST_ROOT ${ep_prefix}) if(WIN32) set(BOOST_LIBRARYDIR "${BOOST_ROOT}/lib") endif() #[[ If you update Boost, make sure that the FindBoost module of the minimum required version of CMake supports the new version of Boost. In case you are using a higher version of CMake, download at least the source code of the minimum required version of CMake to look into the right version of the FindBoost module: <CMAKE_INSTALL_DIR>/share/cmake-<VERSION>/Modules/FindBoost.cmake Search for a list called _Boost_KNOWN_VERSIONS. If the new version is not included in this list, you have three options: * Update the minimum required version of CMake. This may require adaptions of other parts of our CMake scripts and has the most impact on other MITK developers. Yet this is the safest and cleanest option. * Set Boost_ADDITIONAL_VERSIONS (see the documentation of the FindBoost module). As Boost libraries and dependencies between them are hard-coded in the FindBoost module only for known versions, this may cause trouble for other MITK developers relying on new components of Boost or components with changed dependencies. * Copy a newer version of the FindBoost module into our CMake directory. Our CMake directory has a higher precedence than the default CMake module directory. Doublecheck if the minimum required version of CMake is able to process the newer version of the FindBoost module. Also, DO NOT FORGET to mention this option right above the call of cmake_minimum_required() in the top-level CMakeLists.txt file AND in this file right above the set(url) command below so if we update the minimum required version of CMake or use another option in the future, we do not forget to remove our copy of the FindBoost module again. ]] - set(url "${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/boost_1_74_0.tar.gz") - set(md5 3c8fb92ce08b9ad5a5f0b35731ac2c8e) + set(url "${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/boost_1_78_0_b1.tar.gz") + set(md5 bbaa634603e3789d7dd0c21d0bdf4f09) if(MITK_USE_Boost_LIBRARIES) #[[ Boost has a two-step build process. In the first step, a bootstrap script is called to build b2, an executable that is used to actually build Boost in the second step. The bootstrap script expects a toolset (compiler) argument that is used to build the b2 executable. The scripts and their expected argument format differ between Windows and Unix. ]] if(WIN32) mitkFunctionGetMSVCVersion() if(VISUAL_STUDIO_VERSION_MINOR EQUAL 0) #[[ Use just the major version in the toolset name. ]] set(bootstrap_args vc${VISUAL_STUDIO_VERSION_MAJOR}) elseif(VISUAL_STUDIO_VERSION_MAJOR EQUAL 14 AND VISUAL_STUDIO_VERSION_MINOR LESS 20) #[[ Assume Visual Studio 2017. ]] set(bootstrap_args vc${VISUAL_STUDIO_VERSION_MAJOR}1) elseif(VISUAL_STUDIO_VERSION_MAJOR EQUAL 14 AND VISUAL_STUDIO_VERSION_MINOR LESS 30) #[[ Assume Visual Studio 2019. ]] set(bootstrap_args vc${VISUAL_STUDIO_VERSION_MAJOR}2) + elseif(VISUAL_STUDIO_VERSION_MAJOR EQUAL 14 AND VISUAL_STUDIO_VERSION_MINOR LESS 40) + + #[[ Assume Visual Studio 2022. ]] + set(bootstrap_args vc${VISUAL_STUDIO_VERSION_MAJOR}3) + else() #[[ Fallback to the generic case. Be prepared to add another elseif branch above for future versions of Visual Studio. ]] set(bootstrap_args vc${VISUAL_STUDIO_VERSION_MAJOR}) endif() else() #[[ We support GCC and Clang on Unix. On macOS, the toolset must be set to clang. The actual compiler for all of these toolkits is set further below, after the bootstrap script but before b2. ]] if(CMAKE_CXX_COMPILER_ID STREQUAL GNU) set(toolset gcc) elseif(CMAKE_CXX_COMPILER_ID STREQUAL Clang OR APPLE) set(toolset clang) endif() if(toolset) set(bootstrap_args --with-toolset=${toolset}) endif() #[[ At least give it a shot if the toolset is something else and let the bootstrap script decide on the toolset by not passing any argument. ]] endif() #[[ The call of b2 is more complex. b2 arguments are grouped into options and properties. Options follow the standard format for arguments while properties are plain key-value pairs. ]] set(b2_options --build-dir=<BINARY_DIR> --stagedir=<INSTALL_DIR> --ignore-site-config #[[ Build independent of any site.config file ]] -q #[[ Stop at first error ]] ) if(APPLE AND CMAKE_OSX_SYSROOT) #[[ Specify the macOS platform SDK to be used. ]] list(APPEND b2_options --sysroot=${CMAKE_OSX_SYSROOT}) endif() foreach(lib ${MITK_USE_Boost_LIBRARIES}) list(APPEND b2_options --with-${lib}) endforeach() set(b2_properties threading=multi runtime-link=shared "cxxflags=${MITK_CXX14_FLAG} ${CMAKE_CXX_FLAGS}" ) if(CMAKE_SIZEOF_VOID_P EQUAL 8) list(APPEND b2_properties address-model=64) else() list(APPEND b2_properties address-model=32) endif() if(BUILD_SHARED_LIBS) list(APPEND b2_properties link=shared) else() list(APPEND b2_properties link=static) endif() list(APPEND b2_properties "\ $<$<CONFIG:Debug>:variant=debug>\ $<$<CONFIG:Release>:variant=release>\ $<$<CONFIG:MinSizeRel>:variant=release>\ $<$<CONFIG:RelWithDebInfo>:variant=release>") if(WIN32) set(bootstrap_cmd if not exist b2.exe \( call bootstrap.bat ${bootstrap_args} \)) set(b2_cmd b2 ${b2_options} ${b2_properties} stage) else() set(bootstrap_cmd #[[ test -e ./b2 || ]] ./bootstrap.sh ${bootstrap_args}) set(b2_cmd ./b2 ${b2_options} ${b2_properties} stage) #[[ We already told Boost if we want to use GCC or Clang but so far we were not able to specify the exact same compiler we set in CMake when configuring the MITK superbuild for the first time. For example, this can be different from the system default when multiple versions of the same compiler are installed at the same time. The bootstrap script creates a configuration file for b2 that should be modified if necessary before b2 is called. We look for a line like using gcc ; and replace it with something more specific like using gcc : : /usr/bin/gcc-7.3 ; We use the stream editor sed for the replacement but since macOS is based on BSD Unix, we use the limited but portable BSD syntax instead of the more powerful GNU syntax. We also use | instead of the more commonly used / separator for sed because the replacement contains slashes. 2021/06/15: The custom project-config.jam does not work well with SDK paths on macOS anymore, so we use a custom project-config.jam only on Linux for now. ]] if(toolset AND NOT APPLE) set(configure_cmd sed -i.backup "\ s|\ using[[:space:]][[:space:]]*${toolset}[[:space:]]*$<SEMICOLON>|\ using ${toolset} : : ${CMAKE_CXX_COMPILER} $<SEMICOLON>|\ g" <SOURCE_DIR>/project-config.jam ) endif() endif() endif() if(WIN32) set(dummy_cmd cd .) else() set(dummy_cmd true) #[[ "cd ." does not work reliably ]] endif() if(NOT patch_cmd) set(patch_cmd ${dummy_cmd}) #[[ Do nothing ]] endif() if(NOT configure_cmd) set(configure_cmd ${dummy_cmd}) #[[ Do nothing ]] endif() if(WIN32) set(install_cmd if not exist $<SHELL_PATH:${ep_prefix}/include/boost/config.hpp> \( ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR>/boost <INSTALL_DIR>/include/boost \) ) else() set(install_cmd # test -e <INSTALL_DIR>/include/boost/config.hpp || ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR>/boost <INSTALL_DIR>/include/boost ) endif() ExternalProject_Add(${proj} URL ${url} URL_MD5 ${md5} PATCH_COMMAND ${patch_cmd} CONFIGURE_COMMAND ${configure_cmd} BUILD_COMMAND "" INSTALL_COMMAND ${install_cmd} ) ExternalProject_Add_Step(${proj} bootstrap COMMAND ${bootstrap_cmd} DEPENDEES patch DEPENDERS configure WORKING_DIRECTORY <SOURCE_DIR> ) ExternalProject_Add_Step(${proj} b2 COMMAND ${b2_cmd} DEPENDEES bootstrap DEPENDERS build WORKING_DIRECTORY <SOURCE_DIR> ) if(WIN32) #[[ Reuse already extracted files. ]] set(stamp_dir ${ep_prefix}/src/Boost-stamp) configure_file( ${CMAKE_CURRENT_LIST_DIR}/extract-Boost.replacement.cmake ${stamp_dir}/extract-Boost.replacement.cmake COPYONLY) ExternalProject_Add_Step(${proj} pre_download COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/Boost-pre_download.cmake DEPENDEES mkdir DEPENDERS download WORKING_DIRECTORY ${stamp_dir} ) endif() set(install_manifest_dependees install) if(MITK_USE_Boost_LIBRARIES) if(WIN32) #[[ Move DLLs from lib to bin directory. ]] ExternalProject_Add_Step(${proj} post_install COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/Boost-post_install-WIN32.cmake DEPENDEES install WORKING_DIRECTORY <INSTALL_DIR>/lib ) set(install_manifest_dependees post_install) elseif(APPLE) #[[ Boost does not follow the common practice of either using rpath or absolute paths for referencing dependencies. We have to use the install_name_tool to fix this. ]] ExternalProject_Add_Step(${proj} post_install COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/Boost-post_install-APPLE.cmake DEPENDEES install WORKING_DIRECTORY <INSTALL_DIR>/lib ) set(install_manifest_dependees post_install) endif() endif() ExternalProject_Add_Step(${proj} install_manifest COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/Boost-install_manifest.cmake DEPENDEES ${install_manifest_dependees} WORKING_DIRECTORY ${ep_prefix} ) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 74ac3443a8..d77d4c55b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,1439 +1,1443 @@ +#[[ When increasing the minimum required version, check if Boost_ADDITIONAL_VERSIONS + in CMake/PackageDepends/MITK_Boost_Config.cmake can be removed. See the first + long comment in CMakeExternals/Boost.cmake for details. ]] + set(MITK_CMAKE_MINIMUM_REQUIRED_VERSION 3.18) cmake_minimum_required(VERSION ${MITK_CMAKE_MINIMUM_REQUIRED_VERSION}) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19 AND CMAKE_VERSION VERSION_LESS 3.19.2) message(FATAL_ERROR "\ CMake v${CMAKE_VERSION} is defective [1]. \ Please either downgrade to v3.18 or upgrade to at least v3.19.2.\n\ [1] https://gitlab.kitware.com/cmake/cmake/-/issues/21529") endif() #----------------------------------------------------------------------------- # Policies #----------------------------------------------------------------------------- #[[ T28060 https://cmake.org/cmake/help/v3.18/policy/CMP0091.html https://cmake.org/cmake/help/v3.18/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html We pass CMP0091 to all external projects as command-line argument: -DCMAKE_POLICY_DEFAULT_CMP0091:STRING=OLD ]] cmake_policy(SET CMP0091 OLD) #----------------------------------------------------------------------------- # Superbuild Option - Enabled by default #----------------------------------------------------------------------------- option(MITK_USE_SUPERBUILD "Build MITK and the projects it depends on via SuperBuild.cmake." ON) if(MITK_USE_SUPERBUILD) project(MITK-superbuild) set(MITK_SOURCE_DIR ${PROJECT_SOURCE_DIR}) set(MITK_BINARY_DIR ${PROJECT_BINARY_DIR}) else() - project(MITK VERSION 2021.02.99) + project(MITK VERSION 2021.10.99) include_directories(SYSTEM ${MITK_SUPERBUILD_BINARY_DIR}) endif() #----------------------------------------------------------------------------- # MITK Extension Feature #----------------------------------------------------------------------------- set(MITK_EXTENSION_DIRS "" CACHE STRING "") unset(MITK_ABSOLUTE_EXTENSION_DIRS) foreach(MITK_EXTENSION_DIR ${MITK_EXTENSION_DIRS}) get_filename_component(MITK_ABSOLUTE_EXTENSION_DIR "${MITK_EXTENSION_DIR}" ABSOLUTE) list(APPEND MITK_ABSOLUTE_EXTENSION_DIRS "${MITK_ABSOLUTE_EXTENSION_DIR}") endforeach() set(MITK_DIR_PLUS_EXTENSION_DIRS "${MITK_SOURCE_DIR}" ${MITK_ABSOLUTE_EXTENSION_DIRS}) #----------------------------------------------------------------------------- # Update CMake module path #----------------------------------------------------------------------------- set(MITK_CMAKE_DIR ${MITK_SOURCE_DIR}/CMake) set(CMAKE_MODULE_PATH ${MITK_CMAKE_DIR}) foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) set(MITK_CMAKE_EXTENSION_DIR "${MITK_EXTENSION_DIR}/CMake") if(EXISTS "${MITK_CMAKE_EXTENSION_DIR}") list(APPEND CMAKE_MODULE_PATH "${MITK_CMAKE_EXTENSION_DIR}") endif() endforeach() #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- # Standard CMake macros include(FeatureSummary) include(CTest) include(CMakeParseArguments) include(FindPackageHandleStandardArgs) # MITK macros include(mitkFunctionGetGccVersion) include(mitkFunctionCheckCompilerFlags) include(mitkFunctionSuppressWarnings) # includes several functions include(mitkMacroEmptyExternalProject) include(mitkFunctionEnableBuildConfiguration) include(mitkFunctionWhitelists) include(mitkFunctionAddExternalProject) include(mitkFunctionAddLibrarySearchPaths) SUPPRESS_VC_DEPRECATED_WARNINGS() #----------------------------------------------------------------------------- # Set a default build type if none was specified #----------------------------------------------------------------------------- if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Debug' as none was specified.") set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() #----------------------------------------------------------------------------- # Check miminum macOS version #----------------------------------------------------------------------------- # The minimum supported macOS version is 10.14. If you use a version less than # 10.14, there is no guarantee that the build still works. if(APPLE) exec_program(sw_vers ARGS -productVersion OUTPUT_VARIABLE macos_version) if (macos_version VERSION_LESS "10.14") message(WARNING "Detected macOS version \"${macos_version}\" is not supported anymore. Minimum required macOS version is at least 10.14.") endif() if (CMAKE_OSX_DEPLOYMENT_TARGET AND CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.14) message(WARNING "Detected macOS deployment target \"${CMAKE_OSX_DEPLOYMENT_TARGET}\" is not supported anymore. Minimum required macOS version is at least 10.14.") endif() endif() #----------------------------------------------------------------------------- # Check miminum compiler versions #----------------------------------------------------------------------------- if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # require at least gcc 4.9 as provided by ppa:ubuntu-toolchain-r/test for Ubuntu 14.04 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) message(FATAL_ERROR "GCC version must be at least 4.9 If you are using Ubuntu 14.04, you can easily install gcc and g++ 4.9 (or any later version available) in addition to your version ${CMAKE_CXX_COMPILER_VERSION}: sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install gcc-4.9 g++-4.9 Make sure to explicitly specify these compilers when configuring MITK: CMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-4.9 CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-4.9 For more information on the proposed PPA see the Toolchain Updates section of https://wiki.ubuntu.com/ToolChain.") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # require at least clang 3.4 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) message(FATAL_ERROR "Clang version must be at least 3.4") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") # require at least clang 5.0 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) message(FATAL_ERROR "Apple Clang version must be at least 5.0") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # require at least Visual Studio 2017 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) message(FATAL_ERROR "Microsoft Visual Studio 2017 or newer required") endif() else() message(WARNING "You are using an unsupported compiler! Compilation has only been tested with Clang (Linux or Apple), GCC and MSVC.") endif() if(CMAKE_COMPILER_IS_GNUCXX) mitkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION) else() set(GCC_VERSION 0) endif() set(MITK_CXX_STANDARD 14) set(CMAKE_CXX_EXTENSIONS 0) set(CMAKE_CXX_STANDARD ${MITK_CXX_STANDARD}) set(CMAKE_CXX_STANDARD_REQUIRED 1) # This is necessary to avoid problems with compile feature checks. # CMAKE_CXX_STANDARD seems to only set the -std=c++14 flag for targets. # However, compile flag checks also need to be done with -std=c++14. # The MITK_CXX14_FLAG variable is also used for external projects # build during the MITK super-build. mitkFunctionCheckCompilerFlags("-std=c++14" MITK_CXX14_FLAG) #----------------------------------------------------------------------------- # Warn if source or build path is too long #----------------------------------------------------------------------------- if(WIN32) set(_src_dir_length_max 50) set(_bin_dir_length_max 50) if(MITK_USE_SUPERBUILD) set(_src_dir_length_max 34) # _src_dir_length_max - strlen(ep/src/ITK-build) set(_bin_dir_length_max 40) # _bin_dir_length_max - strlen(MITK-build) endif() string(LENGTH "${MITK_SOURCE_DIR}" _src_n) string(LENGTH "${MITK_BINARY_DIR}" _bin_n) # The warnings should be converted to errors if(_src_n GREATER _src_dir_length_max) message(WARNING "MITK source code directory path length is too long (${_src_n} > ${_src_dir_length_max})." "Please move the MITK source code directory to a directory with a shorter path." ) endif() if(_bin_n GREATER _bin_dir_length_max) message(WARNING "MITK build directory path length is too long (${_bin_n} > ${_bin_dir_length_max})." "Please move the MITK build directory to a directory with a shorter path." ) endif() endif() #----------------------------------------------------------------------------- # Additional MITK Options (also shown during superbuild) #----------------------------------------------------------------------------- # ----------------------------------------- # General build options option(BUILD_SHARED_LIBS "Build MITK with shared libraries" ON) option(WITH_COVERAGE "Enable/Disable coverage" OFF) option(BUILD_TESTING "Test the project" ON) option(MITK_FAST_TESTING "Disable long-running tests like packaging" OFF) option(MITK_XVFB_TESTING "Execute test drivers through xvfb-run" OFF) option(MITK_BUILD_ALL_APPS "Build all MITK applications" OFF) option(MITK_BUILD_EXAMPLES "Build the MITK Examples" OFF) -option(MITK_ENABLE_PIC_READER "Enable support for reading the DKFZ pic file format." ON) mark_as_advanced( MITK_XVFB_TESTING MITK_FAST_TESTING MITK_BUILD_ALL_APPS - MITK_ENABLE_PIC_READER ) #----------------------------------------------------------------------------- # Set UI testing flags #----------------------------------------------------------------------------- if(MITK_XVFB_TESTING) set(MITK_XVFB_TESTING_COMMAND "xvfb-run" "--auto-servernum" CACHE STRING "Command and options to test through Xvfb") mark_as_advanced(MITK_XVFB_TESTING_COMMAND) endif(MITK_XVFB_TESTING) # ----------------------------------------- # Other options set(MITK_CUSTOM_REVISION_DESC "" CACHE STRING "Override MITK revision description") mark_as_advanced(MITK_CUSTOM_REVISION_DESC) set_property(GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS "") include(CMakeExternals/ExternalProjectList.cmake) foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) set(MITK_CMAKE_EXTERNALS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/CMakeExternals") if(EXISTS "${MITK_CMAKE_EXTERNALS_EXTENSION_DIR}/ExternalProjectList.cmake") include("${MITK_CMAKE_EXTERNALS_EXTENSION_DIR}/ExternalProjectList.cmake") endif() endforeach() # ----------------------------------------- # Other MITK_USE_* options not related to # external projects build via the # MITK superbuild option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ON) option(MITK_USE_OpenCL "Use OpenCL GPU-Computing library" OFF) option(MITK_USE_OpenMP "Use OpenMP" OFF) option(MITK_USE_Python3 "Use Python 3" OFF) #----------------------------------------------------------------------------- # Build configurations #----------------------------------------------------------------------------- set(_buildConfigs "Custom") file(GLOB _buildConfigFiles CMake/BuildConfigurations/*.cmake) foreach(_buildConfigFile ${_buildConfigFiles}) get_filename_component(_buildConfigFile ${_buildConfigFile} NAME_WE) list(APPEND _buildConfigs ${_buildConfigFile}) endforeach() foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) file(GLOB _extBuildConfigFiles "${MITK_EXTENSION_DIR}/CMake/BuildConfigurations/*.cmake") foreach(_extBuildConfigFile ${_extBuildConfigFiles}) get_filename_component(_extBuildConfigFile "${_extBuildConfigFile}" NAME_WE) list(APPEND _buildConfigs "${_extBuildConfigFile}") endforeach() list(REMOVE_DUPLICATES _buildConfigs) endforeach() set(MITK_BUILD_CONFIGURATION "Custom" CACHE STRING "Use pre-defined MITK configurations") set_property(CACHE MITK_BUILD_CONFIGURATION PROPERTY STRINGS ${_buildConfigs}) mitkFunctionEnableBuildConfiguration() mitkFunctionCreateWhitelistPaths(MITK) mitkFunctionFindWhitelists(MITK) # ----------------------------------------- # Qt version related variables option(MITK_USE_Qt5 "Use Qt 5 library" ON) if(MITK_USE_Qt5) if(WIN32) set(MITK_QT5_MINIMUM_VERSION 5.12.9) else() set(MITK_QT5_MINIMUM_VERSION 5.12) endif() set(MITK_QT5_COMPONENTS Concurrent OpenGL PrintSupport Script Sql Svg Widgets Xml XmlPatterns WebEngineWidgets UiTools Help LinguistTools) if(APPLE) list(APPEND MITK_QT5_COMPONENTS DBus) elseif(UNIX) list(APPEND MITK_QT5_COMPONENTS X11Extras) endif() # Hint at default install locations of Qt if(NOT Qt5_DIR) if(MSVC) set(_dir_candidates "C:/Qt") if(CMAKE_GENERATOR MATCHES "^Visual Studio [0-9]+ ([0-9]+)") set(_compilers "msvc${CMAKE_MATCH_1}") elseif(CMAKE_GENERATOR MATCHES "Ninja") include(mitkFunctionGetMSVCVersion) mitkFunctionGetMSVCVersion() if(VISUAL_STUDIO_PRODUCT_NAME MATCHES "^Visual Studio ([0-9]+)") set(_compilers "msvc${CMAKE_MATCH_1}") endif() endif() if(_compilers MATCHES "[0-9]+") - if (CMAKE_MATCH_0 EQUAL 2019) - list(APPEND _compilers "msvc2017") # Binary compatible to 2019 + if (CMAKE_MATCH_0 EQUAL 2022) + list(APPEND _compilers "msvc2019" "msvc2017") # Binary compatible + elseif (CMAKE_MATCH_0 EQUAL 2019) + list(APPEND _compilers "msvc2017") # Binary compatible endif() endif() else() set(_dir_candidates ~/Qt) if(APPLE) set(_compilers clang) else() list(APPEND _dir_candidates /opt/Qt) set(_compilers gcc) endif() endif() if(CMAKE_SIZEOF_VOID_P EQUAL 8) foreach(_compiler ${_compilers}) list(APPEND _compilers64 "${_compiler}_64") endforeach() set(_compilers ${_compilers64}) endif() foreach(_dir_candidate ${_dir_candidates}) get_filename_component(_dir_candidate ${_dir_candidate} REALPATH) foreach(_compiler ${_compilers}) set(_glob_expression "${_dir_candidate}/5.*/${_compiler}") file(GLOB _hints ${_glob_expression}) list(SORT _hints) list(APPEND MITK_QT5_HINTS ${_hints}) endforeach() endforeach() endif() find_package(Qt5 ${MITK_QT5_MINIMUM_VERSION} COMPONENTS ${MITK_QT5_COMPONENTS} REQUIRED HINTS ${MITK_QT5_HINTS}) endif() # ----------------------------------------- # Custom dependency logic if(WIN32 AND Qt5_DIR) set(_dir_candidate "${Qt5_DIR}/../../../../../Tools/OpenSSL/Win_x64") get_filename_component(_dir_candidate ${_dir_candidate} ABSOLUTE) if(EXISTS "${_dir_candidate}") set(OPENSSL_ROOT_DIR "${_dir_candidate}") endif() endif() find_package(OpenSSL) option(MITK_USE_SYSTEM_Boost "Use the system Boost" OFF) set(MITK_USE_Boost_LIBRARIES "" CACHE STRING "A semi-colon separated list of required Boost libraries") if(MITK_USE_cpprestsdk) if(NOT OpenSSL_FOUND) set(openssl_message "Could not find OpenSSL (dependency of C++ REST SDK).\n") if(UNIX) if(APPLE) set(openssl_message "${openssl_message}Please install it using your favorite package management " "system (i.e. Homebrew or MacPorts).\n") else() set(openssl_message "${openssl_message}Please install the dev package of OpenSSL (i.e. libssl-dev).\n") endif() else() set(openssl_message "${openssl_message}Please either install Win32 OpenSSL:\n" " https://slproweb.com/products/Win32OpenSSL.html\n" "Or use the Qt Maintenance tool to install:\n" " Developer and Designer Tools > OpenSSL Toolkit > OpenSSL 64-bit binaries\n") endif() set(openssl_message "${openssl_message}If it still cannot be found, you can hint CMake to find OpenSSL by " "adding/setting the OPENSSL_ROOT_DIR variable to the root directory of an " "OpenSSL installation. Make sure to clear variables of partly found " "versions of OpenSSL before, or they will be mixed up.") message(FATAL_ERROR ${openssl_message}) endif() list(APPEND MITK_USE_Boost_LIBRARIES date_time regex system) if(UNIX) list(APPEND MITK_USE_Boost_LIBRARIES atomic chrono filesystem random thread) endif() list(REMOVE_DUPLICATES MITK_USE_Boost_LIBRARIES) set(MITK_USE_Boost_LIBRARIES ${MITK_USE_Boost_LIBRARIES} CACHE STRING "A semi-colon separated list of required Boost libraries" FORCE) endif() if(MITK_USE_Python3) set(MITK_USE_ZLIB ON CACHE BOOL "" FORCE) if(APPLE AND CMAKE_FRAMEWORK_PATH AND CMAKE_FRAMEWORK_PATH MATCHES "python3\\.?([0-9]+)") find_package(Python3 3.${CMAKE_MATCH_1} EXACT REQUIRED COMPONENTS Interpreter Development NumPy) else() find_package(Python3 REQUIRED COMPONENTS Interpreter Development NumPy) endif() if(WIN32) string(REPLACE "\\" "/" Python3_STDARCH "${Python3_STDARCH}") string(REPLACE "\\" "/" Python3_STDLIB "${Python3_STDLIB}") string(REPLACE "\\" "/" Python3_SITELIB "${Python3_SITELIB}") endif() endif() if(BUILD_TESTING AND NOT MITK_USE_CppUnit) message("> Forcing MITK_USE_CppUnit to ON because BUILD_TESTING=ON") set(MITK_USE_CppUnit ON CACHE BOOL "Use CppUnit for unit tests" FORCE) endif() if(MITK_USE_BLUEBERRY) option(MITK_BUILD_ALL_PLUGINS "Build all MITK plugins" OFF) mark_as_advanced(MITK_BUILD_ALL_PLUGINS) if(NOT MITK_USE_CTK) message("> Forcing MITK_USE_CTK to ON because of MITK_USE_BLUEBERRY") set(MITK_USE_CTK ON CACHE BOOL "Use CTK in MITK" FORCE) endif() endif() #----------------------------------------------------------------------------- # Pixel type multiplexing #----------------------------------------------------------------------------- # Customize the default pixel types for multiplex macros set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES "int, unsigned int, short, unsigned short, char, unsigned char" CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES "double, float" CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES "itk::RGBPixel<unsigned char>, itk::RGBAPixel<unsigned char>" CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") mark_as_advanced(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES MITK_ACCESSBYITK_DIMENSIONS ) # consistency checks if(NOT MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES) set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES "int, unsigned int, short, unsigned short, char, unsigned char" CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES) set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES "double, float" CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES) set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES "itk::RGBPixel<unsigned char>, itk::RGBAPixel<unsigned char>" CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES) string(REPLACE "," ";" _integral_types ${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES}) string(REPLACE "," ";" _floating_types ${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES}) foreach(_scalar_type ${_integral_types} ${_floating_types}) set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}itk::VariableLengthVector<${_scalar_type}>,") endforeach() string(LENGTH "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" _length) math(EXPR _length "${_length} - 1") string(SUBSTRING "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" 0 ${_length} MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES) set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES ${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} CACHE STRING "List of vector pixel types used in AccessByItk and InstantiateAccessFunction macros for itk::VectorImage types" FORCE) endif() if(NOT MITK_ACCESSBYITK_DIMENSIONS) set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") endif() find_package(Git REQUIRED) #----------------------------------------------------------------------------- # Superbuild script #----------------------------------------------------------------------------- if(MITK_USE_SUPERBUILD) include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake") # Print configuration summary message("\n\n") feature_summary( DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------" WHAT ALL) return() endif() #***************************************************************************** #**************************** END OF SUPERBUILD **************************** #***************************************************************************** #----------------------------------------------------------------------------- # Organize MITK targets in folders #----------------------------------------------------------------------------- set_property(GLOBAL PROPERTY USE_FOLDERS ON) set(MITK_ROOT_FOLDER "MITK" CACHE STRING "") mark_as_advanced(MITK_ROOT_FOLDER) #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(WriteBasicConfigVersionFile) include(CheckCXXSourceCompiles) include(GenerateExportHeader) include(mitkFunctionAddCustomModuleTest) include(mitkFunctionCheckModuleDependencies) include(mitkFunctionCompileSnippets) include(mitkFunctionConfigureVisualStudioUserProjectFile) include(mitkFunctionCreateBlueBerryApplication) include(mitkFunctionCreateCommandLineApp) include(mitkFunctionCreateModule) include(mitkFunctionCreatePlugin) include(mitkFunctionCreateProvisioningFile) include(mitkFunctionGetLibrarySearchPaths) include(mitkFunctionGetVersion) include(mitkFunctionGetVersionDescription) include(mitkFunctionInstallAutoLoadModules) include(mitkFunctionInstallCTKPlugin) include(mitkFunctionInstallProvisioningFiles) include(mitkFunctionInstallThirdPartyCTKPlugins) include(mitkFunctionOrganizeSources) include(mitkFunctionUseModules) if( ${MITK_USE_MatchPoint} ) include(mitkFunctionCreateMatchPointDeployedAlgorithm) endif() include(mitkMacroConfigureItkPixelTypes) include(mitkMacroCreateExecutable) include(mitkMacroCreateModuleTests) include(mitkMacroGenerateToolsLibrary) include(mitkMacroGetLinuxDistribution) include(mitkMacroGetPMDPlatformString) include(mitkMacroInstall) include(mitkMacroInstallHelperApp) include(mitkMacroInstallTargets) include(mitkMacroMultiplexPicType) # Deprecated include(mitkMacroCreateCTKPlugin) #----------------------------------------------------------------------------- # Global CMake variables #----------------------------------------------------------------------------- # Required and enabled C++14 features for all MITK code. # These are added as PUBLIC compile features to all MITK modules. set(MITK_CXX_FEATURES cxx_auto_type cxx_decltype cxx_enum_forward_declarations cxx_extended_friend_declarations cxx_extern_templates cxx_final cxx_lambdas cxx_local_type_template_args cxx_long_long_type cxx_nullptr cxx_override cxx_range_for cxx_right_angle_brackets cxx_rvalue_references cxx_static_assert cxx_strong_enums cxx_template_template_parameters cxx_trailing_return_types cxx_variadic_macros ) if(NOT DEFINED CMAKE_DEBUG_POSTFIX) # We can't do this yet because the CTK Plugin Framework # cannot cope with a postfix yet. #set(CMAKE_DEBUG_POSTFIX d) endif() #----------------------------------------------------------------------------- # Output directories. #----------------------------------------------------------------------------- set(_default_LIBRARY_output_dir lib) set(_default_RUNTIME_output_dir bin) set(_default_ARCHIVE_output_dir lib) foreach(type LIBRARY RUNTIME ARCHIVE) # Make sure the directory exists if(MITK_CMAKE_${type}_OUTPUT_DIRECTORY AND NOT EXISTS ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) message("Creating directory MITK_CMAKE_${type}_OUTPUT_DIRECTORY: ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}") file(MAKE_DIRECTORY "${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}") endif() if(MITK_CMAKE_${type}_OUTPUT_DIRECTORY) set(CMAKE_${type}_OUTPUT_DIRECTORY ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) else() set(CMAKE_${type}_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${_default_${type}_output_dir}) set(MITK_CMAKE_${type}_OUTPUT_DIRECTORY ${CMAKE_${type}_OUTPUT_DIRECTORY}) endif() set(CMAKE_${type}_OUTPUT_DIRECTORY ${CMAKE_${type}_OUTPUT_DIRECTORY} CACHE INTERNAL "Output directory for ${type} files.") mark_as_advanced(CMAKE_${type}_OUTPUT_DIRECTORY) endforeach() #----------------------------------------------------------------------------- # Set MITK specific options and variables (NOT available during superbuild) #----------------------------------------------------------------------------- if(OpenSSL_FOUND AND WIN32) set(MITK_OPENSSL_SSL_DLL "" CACHE FILEPATH "") set(MITK_OPENSSL_CRYPTO_DLL "" CACHE FILEPATH "") if(MITK_OPENSSL_SSL_DLL AND EXISTS "${MITK_OPENSSL_SSL_DLL}" AND MITK_OPENSSL_CRYPTO_DLL AND EXISTS "${MITK_OPENSSL_CRYPTO_DLL}") foreach(config_type ${CMAKE_CONFIGURATION_TYPES}) execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${MITK_BINARY_DIR}/bin/${config_type}") configure_file("${MITK_OPENSSL_SSL_DLL}" "${MITK_BINARY_DIR}/bin/${config_type}/" COPYONLY) configure_file("${MITK_OPENSSL_CRYPTO_DLL}" "${MITK_BINARY_DIR}/bin/${config_type}/" COPYONLY) endforeach() MITK_INSTALL(FILES "${MITK_OPENSSL_SSL_DLL}" "${MITK_OPENSSL_CRYPTO_DLL}" ) endif() endif() # Look for optional Doxygen package find_package(Doxygen) option(BLUEBERRY_DEBUG_SMARTPOINTER "Enable code for debugging smart pointers" OFF) mark_as_advanced(BLUEBERRY_DEBUG_SMARTPOINTER) # Ask the user to show the console window for applications option(MITK_SHOW_CONSOLE_WINDOW "Use this to enable or disable the console window when starting MITK GUI Applications" ON) mark_as_advanced(MITK_SHOW_CONSOLE_WINDOW) if(NOT MITK_FAST_TESTING) if(MITK_CTEST_SCRIPT_MODE STREQUAL "Continuous" OR MITK_CTEST_SCRIPT_MODE STREQUAL "Experimental") set(MITK_FAST_TESTING ON) endif() endif() if(NOT UNIX) set(MITK_WIN32_FORCE_STATIC "STATIC" CACHE INTERNAL "Use this variable to always build static libraries on non-unix platforms") endif() if(MITK_BUILD_ALL_PLUGINS) set(MITK_BUILD_ALL_PLUGINS_OPTION "FORCE_BUILD_ALL") endif() # Configure pixel types used for ITK image access multiplexing mitkMacroConfigureItkPixelTypes() # Configure module naming conventions set(MITK_MODULE_NAME_REGEX_MATCH "^[A-Z].*$") set(MITK_MODULE_NAME_REGEX_NOT_MATCH "^[Mm][Ii][Tt][Kk].*$") set(MITK_DEFAULT_MODULE_NAME_PREFIX "Mitk") set(MITK_MODULE_NAME_PREFIX ${MITK_DEFAULT_MODULE_NAME_PREFIX}) set(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME 1) #----------------------------------------------------------------------------- # Get MITK version info #----------------------------------------------------------------------------- mitkFunctionGetVersion(${MITK_SOURCE_DIR} MITK) mitkFunctionGetVersionDescription(${MITK_SOURCE_DIR} MITK) # MITK_VERSION set(MITK_VERSION_STRING "${MITK_VERSION_MAJOR}.${MITK_VERSION_MINOR}.${MITK_VERSION_PATCH}") if(MITK_VERSION_PATCH STREQUAL "99") set(MITK_VERSION_STRING "${MITK_VERSION_STRING}-${MITK_REVISION_SHORTID}") endif() #----------------------------------------------------------------------------- # Installation preparation # # These should be set before any MITK install macros are used #----------------------------------------------------------------------------- # on macOS all BlueBerry plugins get copied into every # application bundle (.app directory) specified here if(MITK_USE_BLUEBERRY AND APPLE) foreach(MITK_EXTENSION_DIR ${MITK_DIR_PLUS_EXTENSION_DIRS}) set(MITK_APPLICATIONS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/Applications") if(EXISTS "${MITK_APPLICATIONS_EXTENSION_DIR}/AppList.cmake") set(MITK_APPS "") include("${MITK_APPLICATIONS_EXTENSION_DIR}/AppList.cmake") foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 1 option_name) list(GET target_info_list 0 app_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) set(MACOSX_BUNDLE_NAMES ${MACOSX_BUNDLE_NAMES} Mitk${app_name}) endif() endforeach() endif() endforeach() endif() #----------------------------------------------------------------------------- # Set coverage Flags #----------------------------------------------------------------------------- if(WITH_COVERAGE) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(coverage_flags "-g -fprofile-arcs -ftest-coverage -O0 -DNDEBUG") set(COVERAGE_CXX_FLAGS ${coverage_flags}) set(COVERAGE_C_FLAGS ${coverage_flags}) endif() endif() #----------------------------------------------------------------------------- # MITK C/CXX Flags #----------------------------------------------------------------------------- set(MITK_C_FLAGS "${COVERAGE_C_FLAGS}") set(MITK_C_FLAGS_DEBUG ) set(MITK_C_FLAGS_RELEASE ) set(MITK_CXX_FLAGS "${COVERAGE_CXX_FLAGS} ${MITK_CXX14_FLAG}") set(MITK_CXX_FLAGS_DEBUG ) set(MITK_CXX_FLAGS_RELEASE ) set(MITK_EXE_LINKER_FLAGS ) set(MITK_SHARED_LINKER_FLAGS ) if(WIN32) set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN -DNOMINMAX") mitkFunctionCheckCompilerFlags("/wd4005" MITK_CXX_FLAGS) # warning C4005: macro redefinition mitkFunctionCheckCompilerFlags("/wd4231" MITK_CXX_FLAGS) # warning C4231: nonstandard extension used : 'extern' before template explicit instantiation # the following line should be removed after fixing bug 17637 mitkFunctionCheckCompilerFlags("/wd4316" MITK_CXX_FLAGS) # warning C4316: object alignment on heap mitkFunctionCheckCompilerFlags("/wd4180" MITK_CXX_FLAGS) # warning C4180: qualifier applied to function type has no meaning mitkFunctionCheckCompilerFlags("/wd4251" MITK_CXX_FLAGS) # warning C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' endif() if(APPLE) set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -DGL_SILENCE_DEPRECATION") # Apple deprecated OpenGL in macOS 10.14 endif() if(NOT MSVC_VERSION) foreach(_flag -Wall -Wextra -Wpointer-arith -Winvalid-pch -Wcast-align -Wwrite-strings -Wno-error=gnu -Wno-error=unknown-pragmas # The strict-overflow warning is generated by ITK template code -Wno-error=strict-overflow -Woverloaded-virtual -Wstrict-null-sentinel #-Wold-style-cast #-Wsign-promo -Wno-error=deprecated-copy -Wno-array-bounds -fdiagnostics-show-option ) mitkFunctionCheckCAndCXXCompilerFlags(${_flag} MITK_C_FLAGS MITK_CXX_FLAGS) endforeach() endif() if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE) mitkFunctionCheckCompilerFlags("-Wl,--no-undefined" MITK_SHARED_LINKER_FLAGS) mitkFunctionCheckCompilerFlags("-Wl,--as-needed" MITK_SHARED_LINKER_FLAGS) endif() if(CMAKE_COMPILER_IS_GNUCXX) mitkFunctionCheckCAndCXXCompilerFlags("-fstack-protector-all" MITK_C_FLAGS MITK_CXX_FLAGS) set(MITK_CXX_FLAGS_RELEASE "-U_FORTIFY_SOURCES -D_FORTIFY_SOURCE=2 ${MITK_CXX_FLAGS_RELEASE}") endif() set(MITK_MODULE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) set(MITK_EXE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) #----------------------------------------------------------------------------- # MITK Packages #----------------------------------------------------------------------------- set(MITK_MODULES_PACKAGE_DEPENDS_DIR ${MITK_SOURCE_DIR}/CMake/PackageDepends) set(MODULES_PACKAGE_DEPENDS_DIRS ${MITK_MODULES_PACKAGE_DEPENDS_DIR}) foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) set(MITK_PACKAGE_DEPENDS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/CMake/PackageDepends") if(EXISTS "${MITK_PACKAGE_DEPENDS_EXTENSION_DIR}") list(APPEND MODULES_PACKAGE_DEPENDS_DIRS "${MITK_PACKAGE_DEPENDS_EXTENSION_DIR}") endif() endforeach() if(NOT MITK_USE_SYSTEM_Boost) set(Boost_NO_SYSTEM_PATHS 1) endif() set(Boost_USE_MULTITHREADED 1) set(Boost_USE_STATIC_LIBS 0) set(Boost_USE_STATIC_RUNTIME 0) set(Boost_ADDITIONAL_VERSIONS 1.74 1.74.0) # We need this later for a DCMTK workaround set(_dcmtk_dir_orig ${DCMTK_DIR}) # This property is populated at the top half of this file get_property(MITK_EXTERNAL_PROJECTS GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS) foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_package GLOBAL PROPERTY MITK_${ep}_PACKAGE) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) if(MITK_USE_${ep} AND _package) if(_components) find_package(${_package} COMPONENTS ${_components} REQUIRED CONFIG) else() # Prefer config mode first because it finds external # <proj>Config.cmake files pointed at by <proj>_DIR variables. # Otherwise, existing Find<proj>.cmake files could fail. if(DEFINED ${_package}_DIR) #we store the information because it will be overwritten by find_package #and would get lost for all EPs that use on Find<proj>.cmake instead of config #files. set(_temp_EP_${_package}_dir ${${_package}_DIR}) endif(DEFINED ${_package}_DIR) find_package(${_package} QUIET CONFIG) string(TOUPPER "${_package}" _package_uc) if(NOT (${_package}_FOUND OR ${_package_uc}_FOUND)) if(DEFINED _temp_EP_${_package}_dir) set(${_package}_DIR ${_temp_EP_${_package}_dir} CACHE PATH "externaly set dir of the package ${_package}" FORCE) endif(DEFINED _temp_EP_${_package}_dir) find_package(${_package} REQUIRED) endif() endif() endif() endforeach() # Ensure that the MITK CMake module path comes first set(CMAKE_MODULE_PATH ${MITK_CMAKE_DIR} ${CMAKE_MODULE_PATH} ) if(MITK_USE_DCMTK) if(${_dcmtk_dir_orig} MATCHES "${MITK_EXTERNAL_PROJECT_PREFIX}.*") # Help our FindDCMTK.cmake script find our super-build DCMTK set(DCMTK_DIR ${MITK_EXTERNAL_PROJECT_PREFIX}) else() # Use the original value set(DCMTK_DIR ${_dcmtk_dir_orig}) endif() endif() if(MITK_USE_DCMQI) # Due to the preferred CONFIG mode in find_package calls above, # the DCMQIConfig.cmake file is read, which does not provide useful # package information. We explictly need MODULE mode to find DCMQI. # Help our FindDCMQI.cmake script find our super-build DCMQI set(DCMQI_DIR ${MITK_EXTERNAL_PROJECT_PREFIX}) find_package(DCMQI REQUIRED) endif() if(MITK_USE_OpenIGTLink) link_directories(${OpenIGTLink_LIBRARY_DIRS}) endif() if(MITK_USE_OpenCL) find_package(OpenCL REQUIRED) endif() if(MITK_USE_OpenMP) find_package(OpenMP REQUIRED COMPONENTS CXX) else() find_package(OpenMP QUIET COMPONENTS CXX) if(OpenMP_FOUND) set(MITK_USE_OpenMP ON CACHE BOOL "" FORCE) elseif(APPLE AND OpenMP_libomp_LIBRARY AND NOT OpenMP_CXX_LIB_NAMES) set(OpenMP_CXX_LIB_NAMES libomp CACHE STRING "" FORCE) get_filename_component(openmp_lib_dir "${OpenMP_libomp_LIBRARY}" DIRECTORY) set(openmp_include_dir "${openmp_lib_dir}/../include") if(EXISTS "${openmp_include_dir}") get_filename_component(openmp_include_dir "${openmp_include_dir}" REALPATH) set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I${openmp_include_dir}" CACHE STRING "" FORCE) find_package(OpenMP QUIET COMPONENTS CXX) if(OpenMP_FOUND) set(MITK_USE_OpenMP ON CACHE BOOL "" FORCE) endif() endif() endif() endif() # Qt support if(MITK_USE_Qt5) find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED) # at least Core required get_target_property(_qmake_exec Qt5::qmake LOCATION) execute_process(COMMAND ${_qmake_exec} -query QT_INSTALL_BINS RESULT_VARIABLE _result OUTPUT_VARIABLE QT_BINARY_DIR ERROR_VARIABLE _error ) string(STRIP "${QT_BINARY_DIR}" QT_BINARY_DIR) if(_result OR NOT EXISTS "${QT_BINARY_DIR}") message(FATAL_ERROR "Could not determine Qt binary directory: ${_result} ${QT_BINARY_DIR} ${_error}") endif() find_program(QT_HELPGENERATOR_EXECUTABLE NAMES qhelpgenerator qhelpgenerator-qt5 qhelpgenerator5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_COLLECTIONGENERATOR_EXECUTABLE NAMES qcollectiongenerator qcollectiongenerator-qt5 qcollectiongenerator5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_ASSISTANT_EXECUTABLE NAMES assistant assistant-qt5 assistant5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_XMLPATTERNS_EXECUTABLE NAMES xmlpatterns PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) mark_as_advanced(QT_HELPGENERATOR_EXECUTABLE QT_COLLECTIONGENERATOR_EXECUTABLE QT_ASSISTANT_EXECUTABLE QT_XMLPATTERNS_EXECUTABLE ) if(MITK_USE_BLUEBERRY) option(BLUEBERRY_USE_QT_HELP "Enable support for integrating plugin documentation into Qt Help" ${DOXYGEN_FOUND}) mark_as_advanced(BLUEBERRY_USE_QT_HELP) # Sanity checks for in-application BlueBerry plug-in help generation if(BLUEBERRY_USE_QT_HELP) set(_force_blueberry_use_qt_help_to_off 0) if(NOT DOXYGEN_FOUND) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen was not found.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(DOXYGEN_FOUND AND DOXYGEN_VERSION VERSION_LESS 1.8.7) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen version 1.8.7 or newer not found.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT QT_HELPGENERATOR_EXECUTABLE) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because QT_HELPGENERATOR_EXECUTABLE is empty.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT MITK_USE_Qt5) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because MITK_USE_Qt5 is OFF.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT QT_XMLPATTERNS_EXECUTABLE) message("You have enabled Qt Help support, but QT_XMLPATTERNS_EXECUTABLE is empty") set(_force_blueberry_use_qt_help_to_off 1) endif() if(_force_blueberry_use_qt_help_to_off) set(BLUEBERRY_USE_QT_HELP OFF CACHE BOOL "Enable support for integrating plugin documentation into Qt Help" FORCE) endif() endif() if(BLUEBERRY_QT_HELP_REQUIRED AND NOT BLUEBERRY_USE_QT_HELP) message(FATAL_ERROR "BLUEBERRY_USE_QT_HELP is required to be set to ON") endif() endif() endif() #----------------------------------------------------------------------------- # Testing #----------------------------------------------------------------------------- if(BUILD_TESTING) #[[ See T27701 # Initial cache for ProjectTemplate and PluginGenerator tests configure_file( CMake/mitkTestInitialCache.txt.in ${MITK_BINARY_DIR}/mitkTestInitialCache.txt @ONLY )]] # Configuration for the CMake-generated test driver set(CMAKE_TESTDRIVER_EXTRA_INCLUDES "#include <stdexcept>") set(CMAKE_TESTDRIVER_BEFORE_TESTMAIN " try {") set(CMAKE_TESTDRIVER_AFTER_TESTMAIN " } catch (const std::exception& e) { fprintf(stderr, \"%s\\n\", e.what()); return EXIT_FAILURE; } catch (...) { printf(\"Exception caught in the test driver\\n\"); return EXIT_FAILURE; }") set(MITK_TEST_OUTPUT_DIR "${MITK_BINARY_DIR}/test_output") if(NOT EXISTS ${MITK_TEST_OUTPUT_DIR}) file(MAKE_DIRECTORY ${MITK_TEST_OUTPUT_DIR}) endif() # Test the package target include(mitkPackageTest) endif() configure_file(mitkTestingConfig.h.in ${MITK_BINARY_DIR}/mitkTestingConfig.h) #----------------------------------------------------------------------------- # MITK_SUPERBUILD_BINARY_DIR #----------------------------------------------------------------------------- # If MITK_SUPERBUILD_BINARY_DIR isn't defined, it means MITK is *NOT* build using Superbuild. # In that specific case, MITK_SUPERBUILD_BINARY_DIR should default to MITK_BINARY_DIR if(NOT DEFINED MITK_SUPERBUILD_BINARY_DIR) set(MITK_SUPERBUILD_BINARY_DIR ${MITK_BINARY_DIR}) endif() #----------------------------------------------------------------------------- # Set C/CXX and linker flags for MITK code #----------------------------------------------------------------------------- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MITK_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MITK_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MITK_CXX_FLAGS_RELEASE}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MITK_C_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MITK_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${MITK_C_FLAGS_RELEASE}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MITK_EXE_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MITK_SHARED_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${MITK_MODULE_LINKER_FLAGS}") #----------------------------------------------------------------------------- # Add subdirectories #----------------------------------------------------------------------------- add_subdirectory(Utilities) add_subdirectory(Modules) include("${CMAKE_CURRENT_SOURCE_DIR}/Modules/ModuleList.cmake") mitkFunctionWhitelistModules(MITK MITK_MODULES) set(MITK_ROOT_FOLDER_BACKUP "${MITK_ROOT_FOLDER}") foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) get_filename_component(MITK_ROOT_FOLDER "${MITK_EXTENSION_DIR}" NAME) set(MITK_MODULES_EXTENSION_DIR "${MITK_EXTENSION_DIR}/Modules") if(EXISTS "${MITK_MODULES_EXTENSION_DIR}/ModuleList.cmake") set(MITK_MODULES "") include("${MITK_MODULES_EXTENSION_DIR}/ModuleList.cmake") foreach(mitk_module ${MITK_MODULES}) add_subdirectory("${MITK_MODULES_EXTENSION_DIR}/${mitk_module}" "Modules/${mitk_module}") endforeach() endif() set(MITK_MODULE_NAME_PREFIX ${MITK_DEFAULT_MODULE_NAME_PREFIX}) endforeach() set(MITK_ROOT_FOLDER "${MITK_ROOT_FOLDER_BACKUP}") add_subdirectory(Wrapping) set(MITK_DOXYGEN_OUTPUT_DIR "${PROJECT_BINARY_DIR}/Documentation/Doxygen" CACHE PATH "Output directory for doxygen generated documentation.") if(MITK_USE_BLUEBERRY) include("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/PluginList.cmake") mitkFunctionWhitelistPlugins(MITK MITK_PLUGINS) set(mitk_plugins_fullpath "") foreach(mitk_plugin ${MITK_PLUGINS}) list(APPEND mitk_plugins_fullpath Plugins/${mitk_plugin}) endforeach() set(MITK_PLUGIN_REGEX_LIST "") foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) set(MITK_PLUGINS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/Plugins") if(EXISTS "${MITK_PLUGINS_EXTENSION_DIR}/PluginList.cmake") set(MITK_PLUGINS "") include("${MITK_PLUGINS_EXTENSION_DIR}/PluginList.cmake") foreach(mitk_plugin ${MITK_PLUGINS}) list(APPEND mitk_plugins_fullpath "${MITK_PLUGINS_EXTENSION_DIR}/${mitk_plugin}") endforeach() endif() endforeach() if(EXISTS ${MITK_PRIVATE_MODULES}/PluginList.cmake) include(${MITK_PRIVATE_MODULES}/PluginList.cmake) foreach(mitk_plugin ${MITK_PRIVATE_PLUGINS}) list(APPEND mitk_plugins_fullpath ${MITK_PRIVATE_MODULES}/${mitk_plugin}) endforeach() endif() if(MITK_BUILD_EXAMPLES) include("${CMAKE_CURRENT_SOURCE_DIR}/Examples/Plugins/PluginList.cmake") set(mitk_example_plugins_fullpath ) foreach(mitk_example_plugin ${MITK_EXAMPLE_PLUGINS}) list(APPEND mitk_example_plugins_fullpath Examples/Plugins/${mitk_example_plugin}) list(APPEND mitk_plugins_fullpath Examples/Plugins/${mitk_example_plugin}) endforeach() endif() # Specify which plug-ins belong to this project macro(GetMyTargetLibraries all_target_libraries varname) set(re_ctkplugin_mitk "^org_mitk_[a-zA-Z0-9_]+$") set(re_ctkplugin_bb "^org_blueberry_[a-zA-Z0-9_]+$") set(_tmp_list) list(APPEND _tmp_list ${all_target_libraries}) ctkMacroListFilter(_tmp_list re_ctkplugin_mitk re_ctkplugin_bb MITK_PLUGIN_REGEX_LIST OUTPUT_VARIABLE ${varname}) endmacro() # Get infos about application directories and build options set(mitk_apps_fullpath "") foreach(MITK_EXTENSION_DIR ${MITK_DIR_PLUS_EXTENSION_DIRS}) set(MITK_APPLICATIONS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/Applications") if(EXISTS "${MITK_APPLICATIONS_EXTENSION_DIR}/AppList.cmake") set(MITK_APPS "") include("${MITK_APPLICATIONS_EXTENSION_DIR}/AppList.cmake") foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 directory_name) list(GET target_info_list 1 option_name) if(${option_name}) list(APPEND mitk_apps_fullpath "${MITK_APPLICATIONS_EXTENSION_DIR}/${directory_name}^^${option_name}") endif() endforeach() endif() endforeach() if (mitk_plugins_fullpath) ctkMacroSetupPlugins(${mitk_plugins_fullpath} BUILD_OPTION_PREFIX MITK_BUILD_ APPS ${mitk_apps_fullpath} BUILD_ALL ${MITK_BUILD_ALL_PLUGINS} COMPACT_OPTIONS) endif() set(MITK_PLUGIN_USE_FILE "${MITK_BINARY_DIR}/MitkPluginUseFile.cmake") if(${PROJECT_NAME}_PLUGIN_LIBRARIES) ctkFunctionGeneratePluginUseFile(${MITK_PLUGIN_USE_FILE}) else() file(REMOVE ${MITK_PLUGIN_USE_FILE}) set(MITK_PLUGIN_USE_FILE ) endif() endif() #----------------------------------------------------------------------------- # Documentation #----------------------------------------------------------------------------- if(DOXYGEN_FOUND) add_subdirectory(Documentation) endif() #----------------------------------------------------------------------------- # Installation #----------------------------------------------------------------------------- # set MITK cpack variables # These are the default variables, which can be overwritten ( see below ) include(mitkSetupCPack) set(use_default_config ON) set(ALL_MITK_APPS "") set(activated_apps_no 0) foreach(MITK_EXTENSION_DIR ${MITK_DIR_PLUS_EXTENSION_DIRS}) set(MITK_APPLICATIONS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/Applications") if(EXISTS "${MITK_APPLICATIONS_EXTENSION_DIR}/AppList.cmake") set(MITK_APPS "") include("${MITK_APPLICATIONS_EXTENSION_DIR}/AppList.cmake") foreach(mitk_app ${MITK_APPS}) string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 directory_name) list(GET target_info_list 1 option_name) list(GET target_info_list 2 executable_name) list(APPEND ALL_MITK_APPS "${MITK_EXTENSION_DIR}/Applications/${directory_name}^^${option_name}^^${executable_name}") if(${option_name} OR MITK_BUILD_ALL_APPS) MATH(EXPR activated_apps_no "${activated_apps_no} + 1") endif() endforeach() endif() endforeach() list(LENGTH ALL_MITK_APPS app_count) if(app_count EQUAL 1 AND (activated_apps_no EQUAL 1 OR MITK_BUILD_ALL_APPS)) # Corner case if there is only one app in total set(use_project_cpack ON) elseif(activated_apps_no EQUAL 1 AND NOT MITK_BUILD_ALL_APPS) # Only one app is enabled (no "build all" flag set) set(use_project_cpack ON) else() # Less or more then one app is enabled set(use_project_cpack OFF) endif() foreach(mitk_app ${ALL_MITK_APPS}) # extract target_dir and option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 target_dir) list(GET target_info_list 1 option_name) list(GET target_info_list 2 executable_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) # check whether application specific configuration files will be used if(use_project_cpack) # use files if they exist if(EXISTS "${target_dir}/CPackOptions.cmake") include("${target_dir}/CPackOptions.cmake") endif() if(EXISTS "${target_dir}/CPackConfig.cmake.in") set(CPACK_PROJECT_CONFIG_FILE "${target_dir}/CPackConfig.cmake") configure_file(${target_dir}/CPackConfig.cmake.in ${CPACK_PROJECT_CONFIG_FILE} @ONLY) set(use_default_config OFF) endif() endif() # add link to the list list(APPEND CPACK_CREATE_DESKTOP_LINKS "${executable_name}") endif() endforeach() # if no application specific configuration file was used, use default if(use_default_config) configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in ${MITK_BINARY_DIR}/MITKCPackOptions.cmake @ONLY) set(CPACK_PROJECT_CONFIG_FILE "${MITK_BINARY_DIR}/MITKCPackOptions.cmake") endif() # include CPack model once all variables are set include(CPack) # Additional installation rules include(mitkInstallRules) #----------------------------------------------------------------------------- # Last configuration steps #----------------------------------------------------------------------------- # ---------------- Export targets ----------------- set(MITK_EXPORTS_FILE "${MITK_BINARY_DIR}/MitkExports.cmake") file(REMOVE ${MITK_EXPORTS_FILE}) set(targets_to_export) get_property(module_targets GLOBAL PROPERTY MITK_MODULE_TARGETS) if(module_targets) list(APPEND targets_to_export ${module_targets}) endif() if(MITK_USE_BLUEBERRY) if(MITK_PLUGIN_LIBRARIES) list(APPEND targets_to_export ${MITK_PLUGIN_LIBRARIES}) endif() endif() export(TARGETS ${targets_to_export} APPEND FILE ${MITK_EXPORTS_FILE}) set(MITK_EXPORTED_TARGET_PROPERTIES ) foreach(target_to_export ${targets_to_export}) get_target_property(autoload_targets ${target_to_export} MITK_AUTOLOAD_TARGETS) if(autoload_targets) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_TARGETS \"${autoload_targets}\")") endif() get_target_property(autoload_dir ${target_to_export} MITK_AUTOLOAD_DIRECTORY) if(autoload_dir) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_DIRECTORY \"${autoload_dir}\")") endif() get_target_property(deprecated_module ${target_to_export} MITK_MODULE_DEPRECATED_SINCE) if(deprecated_module) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_MODULE_DEPRECATED_SINCE \"${deprecated_module}\")") endif() endforeach() # ---------------- External projects ----------------- get_property(MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS_CONFIG GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) set(MITK_CONFIG_EXTERNAL_PROJECTS ) #string(REPLACE "^^" ";" _mitk_external_projects ${MITK_EXTERNAL_PROJECTS}) foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) set(MITK_CONFIG_EXTERNAL_PROJECTS "${MITK_CONFIG_EXTERNAL_PROJECTS} set(MITK_USE_${ep} ${MITK_USE_${ep}}) set(MITK_${ep}_DIR \"${${ep}_DIR}\") set(MITK_${ep}_COMPONENTS ${_components}) ") endforeach() foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_package GLOBAL PROPERTY MITK_${ep}_PACKAGE) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) if(_components) set(_components_arg COMPONENTS \${_components}) else() set(_components_arg) endif() if(_package) set(MITK_CONFIG_EXTERNAL_PROJECTS "${MITK_CONFIG_EXTERNAL_PROJECTS} if(MITK_USE_${ep}) set(${ep}_DIR \${MITK_${ep}_DIR}) if(MITK_${ep}_COMPONENTS) mitkMacroFindDependency(${_package} COMPONENTS \${MITK_${ep}_COMPONENTS}) else() mitkMacroFindDependency(${_package}) endif() endif()") endif() endforeach() # ---------------- Tools ----------------- configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactory.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactoryLoader.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactoryLoader.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolGUIExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolGUIExtensionITKFactory.cpp.in COPYONLY) # ---------------- Configure files ----------------- configure_file(mitkVersion.h.in ${MITK_BINARY_DIR}/mitkVersion.h) configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) set(IPFUNC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/ipFunc) set(UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities) configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) configure_file(MITKConfig.cmake.in ${MITK_BINARY_DIR}/MITKConfig.cmake @ONLY) write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${MITK_VERSION_STRING} COMPATIBILITY AnyNewerVersion) #----------------------------------------------------------------------------- # MITK Applications #----------------------------------------------------------------------------- # This must come after MITKConfig.h was generated, since applications # might do a find_package(MITK REQUIRED). add_subdirectory(Applications) if(MSVC AND TARGET MitkWorkbench) set_directory_properties(PROPERTIES VS_STARTUP_PROJECT MitkWorkbench) endif() foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) set(MITK_APPLICATIONS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/Applications") if(EXISTS "${MITK_APPLICATIONS_EXTENSION_DIR}/CMakeLists.txt") add_subdirectory("${MITK_APPLICATIONS_EXTENSION_DIR}" "Applications") endif() endforeach() #----------------------------------------------------------------------------- # MITK Examples #----------------------------------------------------------------------------- if(MITK_BUILD_EXAMPLES) # This must come after MITKConfig.h was generated, since applications # might do a find_package(MITK REQUIRED). add_subdirectory(Examples) endif() #----------------------------------------------------------------------------- # Print configuration summary #----------------------------------------------------------------------------- message("\n\n") feature_summary( DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------" WHAT ALL ) diff --git a/Documentation/Doxygen/3-DeveloperManual/Concepts/Logging.dox b/Documentation/Doxygen/3-DeveloperManual/Concepts/Logging.dox index c300b9c0a7..b4d0f0172a 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Concepts/Logging.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Concepts/Logging.dox @@ -1,72 +1,72 @@ /** \page LoggingPage Logging Concept \tableofcontents \section LoggingPageSection1 Basic Information on Logging To use logging in MITK you can stream your messages into a logging stream, similar to the "std::cout" stream in standard c++. A simple example is shown next. \code MITK_INFO << "Here comes my message"; \endcode Please only use the MITK_INFO (respectively MITK_WARN, MITK_ERROR, MITK_FATAL, MITK_DEBUG, see \ref LoggingPageSection3 for more details) in MITK, the std::cout stream should not be used. You can also log object information, like shown in the next example. \code MITK_INFO << "I want to log my vector size: " << m_vector.getSize(); \endcode All logged information will be displayed in the console and be written to a logging file in the MITK binary folder. Advanced users may want to know that this behavior is controlled by the logging backend class, which can be adapted if you want to change the behavior. This is everything you need to know about simple logging. Further reading will show you how you can categorize your logging message and what logging levels are. \section LoggingPageSection2 Categorize your Logging Messages You may also want to categorize your logging messages, so you can assign messages to your specific topic. You can simply add classes and subclasses to your MITK logging messages by using brackets, like shown in the next example. \code MITK_INFO << "no class"; MITK_INFO("MyClass") << "single class"; MITK_INFO("MyClass")("MySubClass") << "class with subclass"; \endcode This classes makes it easy to e.g. simply filter all logging messages only for relevant information. \section LoggingPageSection3 Logging Levels MITK offers different logging levels. You may mostly want to use MITK_INFO, but please consider using the other levels, e.g. when logging debug information or errors. <b>Debug (MITK_DEBUG)</b>: These messages are designed for debug output, used to debug your source code. Example: \code MITK_DEBUG << "Result of method LoadPicture(): true." \endcode These messages are only displayed if you turn the CMake-Variable MBILOG_ENABLE_DEBUG_MESSAGES on. You can also use the debug message in release mode, output only depends on the CMake-Variable. If you want to enable the debug messages only for a single class / module / plugin you can also simply define the variable in your source code for the time you want to see the messages. Therefore you add a line "#define MBILOG_ENABLE_DEBUG" in the beginning of your cpp file. But don't forget to remove the definition before commiting the source code. <b>Info (MITK_INFO)</b>: For standard information messages that inform about expected changes/results in the program flow. Info messages should be important and understandable for the users of the program. Example: \code -MITK_INFO << "The picture test.pic has been loaded successfully." +MITK_INFO << "The picture test.nrrd has been loaded successfully." \endcode <b>Warning (MITK_WARN)</b>: Warning messages should inform about unexpected or potentially problematic states in the program flow that do not lead directly to an error. Thus, after a warning the program should be able continue without errors and in a clear state. Example: \code -MITK_WARN << "The picture test.pic was not loaded because access was denied." +MITK_WARN << "The picture test.nrrd was not loaded because access was denied." \endcode <b>Error (MITK_ERROR)</b>: Error messages notify the user about corrupt states in the program flow. Such states may occur after unexpected behavior of source code. Example: \code -MITK_ERROR << "Error while adding test.pic to the data storage, aborting." +MITK_ERROR << "Error while adding test.nrrd to the data storage, aborting." \endcode <b>Fatal (MITK_FATAL)</b>: Fatal messages report corrupt states in the program flow that lead directly to a crash of the program. Example: \code MITK_FATAL << "Memory allocation error during instantiation of image object." \endcode \section LoggingPageSection4 Conditional Logging Another feature of the logging mechanism is that you can directly give conditions for logging your message. These bool values or expressions can be defined in brackets. An example is shown next. \code MITK_INFO(x>1000) << "x is too large"; //logs only if x > 1000 \endcode */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Concepts/RenderingTests.dox b/Documentation/Doxygen/3-DeveloperManual/Concepts/RenderingTests.dox index 2dbe0bd4ec..134aeec00b 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Concepts/RenderingTests.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Concepts/RenderingTests.dox @@ -1,97 +1,97 @@ namespace mitk{ /** \page RenderingTests Automatic Rendering Tests Available sections: -# \ref RenderingTests_WhatIsARenderingTest "What is an automatic rendering test?" -# \ref RenderingTests_HowToCreateATest "How to create a rendering test" \section RenderingTests_WhatIsARenderingTest What is an automatic rendering test? An automatic rendering test is a powerful tool to test rendering results automatically via dashboard. Regarding rendering lots of different sources influence the output on the screen (e.g. different mappers, renderes, camera settings or the algorithm creating the data). Thus, during the rendering process of an image many different classes are involved and can have impact on the output. A minor change in an important class (e.g. mitkVtkPropRenderer) can have major impact on the actual rendering. An automatic rendering test takes an arbitrary object as input (e.g. image, surface, point set), renders this into an mitkRenderWindow, makes a screen shot of that renderwindow and finally compares that screen shot to a given reference. Of course, the reference has to be defined by the user. Internally, a VTK test method is used to compare both screen shots and measure differences. In case of failure, a difference can be generated to show exactly which pixels are rendered incorrectly. Implementing automatic rendering tests for algorithms ensures that algorithms deliver the same output as they used to do in previous version of MITK. \section RenderingTests_HowToCreateATest How to create your own automatic rendering test To create an automatic rendering test you should use an existing test as example (e.g. mitkImageVtkMapper2DTest). \subsection RenderingTests_HowToCreateATest_Sub1 Adding the test to CMake Like adding any test with parameters to CMake, you have to add a custom test to the files.cmake and the corresponding CMakeLists.txt: For instance a test for the mitkImageVtkMapper2D has to be added like this: files.cmake \code set(MODULE_CUSTOM_TESTS ... mitkImageVtkMapper2D.cpp ) \endcode CMakeLists.txt \code mitkAddCustomModuleTest(mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2D #custom name of the test and executable ${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/rgbaImage640x480REF.png #corresponding reference screenshot ) \endcode The first parameter defines a custom name for the test. This is a feature to distinguish between tests with different inputs. In this example the test is named <em>mitkImageVtkMapper2D_rgbaImage640x480</em> to show that this test is using the test image <em>rbgaImage640x480</em> as input. The next parameters sets test executable name (i.e. the name of the test class). Here: <em>mitkImageVtkMapper2D</em>. The next parameter(s) are used to pass the input to the test. For instance, it is possible to set -multiple objects as input for a test (e.g. /path/to/img1.jpg /path/to/img2.pic /path/to/pointset.mps). +multiple objects as input for a test (e.g. /path/to/img1.jpg /path/to/img2.nrrd /path/to/pointset.mps). All test data for core tests should be placed into the MITK-DATA repository inside the folder: ${MITK_DATA_DIR}/RenderingTestData/. It is possible to create other folders for different modules or bundles. The option -V defines the path to the reference screen shot and is internally used by VTK. The reference screen shot is highly important and has to be proven if is correct. The <em>mitkRenderingTestHelper</em> offers means to capture a screen shot of a renderwindow. Capturing a reference screen shot should happen just once and NOT be a permanent part of the test. It is also possible to set the option -T /path/to/directory/. This option is internally used by VTK to save a difference image. This is meant for debugging and should not be used for the final implemenation of a test. \subsection RenderingTests_HowToCreateATest_Sub2 Coding the test Writing the test code is pretty straight forward. In the example of the <em>mitkImageVtkMapper2DTest</em> the input parameters are added to a datastorage and rendered into a render window via the <em>mitkRenderingTestHelper</em>. Last, the vtkTesting macro is called to compare the given reference to the data rendered in the renderwindow: \code int retVal = vtkRegressionTestImage( renderingHelper.GetVtkRenderWindow() ); //retVal meanings: (see VTK/Rendering/vtkTesting.h) //0 = test failed //1 = test passed //2 = test not run //3 = something with vtkInteraction MITK_TEST_CONDITION( retVal == 1, "VTK test result positive" ); \endcode If the content of the previously filled renderwindow does not equal the reference, the test will fail. Feel free to modify the data before rendering. E.g. create a surface from the loaded image and render that surface afterwards or add compute QBalls for an image and render those. Happy testing! */ } diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/BuildInstructions.dox b/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/BuildInstructions.dox index 2b948a8ba5..c8fbcc7f30 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/BuildInstructions.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/BuildInstructions.dox @@ -1,236 +1,236 @@ /** \page BuildInstructionsPage Build Instructions \tableofcontents \section BuildInstructions_Introduction Introduction The CMake-based build system of MITK supports a "superbuild" process, meaning that it will download, configure, and build all required third-party libraries (except Qt) automatically. These instructions will show you how to use the MITK superbuild. \note This page explains explicitly how to build MITK itself. If you want to create your own project based on MITK, the process described below is completely automated. Please see \ref HowToNewProject. For more advanced users, the last sections explains how to inject custom build libraries into the superbuild process. \section BuildInstructions_Prerequisites Prerequisites You need: -# <a href="https://git-scm.com/">Git</a> (there are also numerous third-party graphical clients available). We recommend using Git, but see below for a way how to get the current source code without using it. -# <a href="https://cmake.org/">CMake</a> (version \minimumCMakeVersion or higher) -# <a href="https://www.qt.io/">Qt</a> \minimumQt5Version if you plan to develop Qt-based applications -# If you are using <b>macOS</b> you need an XCode installation and the Command Line Tools as it provides the neccessary compilers and SDKs To build MITK on Linux, install the following packages, e. g. with APT: \code{.unparsed} -sudo apt install build-essential doxygen git graphviz libfreetype6-dev libglu1-mesa-dev libssl-dev libtiff5-dev libwrap0-dev libxcomposite1 libxcursor1 libxi-dev libxkbcommon-x11-0 libxt-dev mesa-common-dev +sudo apt install build-essential doxygen git graphviz libfreetype6-dev libglu1-mesa-dev libssl-dev libtiff5-dev libwrap0-dev libxcomposite1 libxcursor1 libxdamage-dev libxi-dev libxkbcommon-x11-0 libxt-dev mesa-common-dev \endcode For the optional and experimental (!) Python integration, install NumPy and SimpleITK v1.x, e. g.: \code{.unparsed} sudo apt install python3-numpy python3-pip pip3 install SimpleITK==1.* \endcode \section BuildInstructions_Qt A note about Qt As we do not provide Qt in the MITK superbuild you need to install Qt manually. The Qt Company provides <a href="https://www.qt.io/download/">online installers for all supported platforms</a>. We highly recommend to install Qt to the default location of the installer as it will allow MITK to automatically find Qt without any further action needed. Make sure to also select the following <b>required components</b>: - QtWebEngine - QtScript On Windows, the Qt installer offers a welcome and straight forward way to install <b>OpenSSL</b>. You find it under the Tools node. \section BuildInstructions_Get_Source Get a source tree Since MITK is under active development we recommend to use Git to check out the latest stable release from the homepage. If you decide to use the most current nightly release, make sure to get a stable tree: Check the <a href="https://cdash.mitk.org/index.php?project=MITK">MITK dashboard</a> before checking out. If the build tree is not clean, you can specify an older revision for the checkout or get a stable tar ball from <a href="https://www.mitk.org">www.mitk.org</a>. To clone MITK's current Git repository do: \code git clone https://phabricator.mitk.org/source/mitk.git MITK \endcode \section BuildInstructions_Build_With_CMake Build MITK with CMake Create a new directory for the superbuild binary tree, change to it and call CMake: In the shell (assuming your current directory is the same as the one where you issued the git clone command): \code mkdir MITK-superbuild cd MITK-superbuild ccmake ../MITK \endcode If you use <b>Windows</b> or prefer to use the CMake GUI, start the CMake GUI and enter the location of the source tree and binary tree, choose a suitable generator and configure the project. CMake will present you a couple of options, these are the most important ones: - <tt><b>CMAKE_PREFIX_PATH</b></tt> The path to your Qt installation, e.g., <i>C:/Qt/5.12.9/msvc2017_64</i> or <i>/home/user/Qt/5.12.9/gcc_64</i> - <tt><b>MITK_USE_BLUEBERRY</b></tt> Build the BlueBerry application framework - <tt><b>MITK_USE_Boost_LIBRARIES</b></tt> If you need binary Boost libraries, specify them here. - <tt><b>MITK_USE_OpenCV</b></tt> Build MITK code which depends on OpenCV (this will download and build OpenCV 2.4) - <tt><b>MITK_USE_Python3</b></tt> Enables Python wrapping in MITK. This will also configure ITK, VTK, and OpenCV (if enabled) to build Python wrappers. - <tt><b>MITK_USE_Qt5</b></tt> Build MITK code which depends on Qt 5 If you are satisfied with the configuration of your MITK superbuild, generate the project files with CMake by pressing "Generate". <b>Linux</b> and <b>macOS</b> users usually just enter "make" (optionally supplying the number threads to be used for a parallel build): \code make -j6 \endcode <b>Windows</b> users using Visual Studio can open the generated <tt>MITK-superbuild.sln</tt> solution file in the <tt>MITK-superbuild</tt> directory and start the build by building the <tt>BUILD_ALL</tt> project. \section BuildInstructions_Customize Customize your MITK superbuild The MITK superbuild configures MITK as well as all external libraries. The build directories of these libraries, and of MITK itself are located inside the <tt>MITK-superbuild</tt> directory. For example, the directory layout may look like: \code MITK-superbuild |- ep "external projects" |-bin |-lib |-include |-src |- MITK-build \endcode To change the configuration of the MITK build itself, choose the MITK-build directory as the binary directory in the CMake GUI (not the MITK-superbuild directory). After generating the project files, build the MITK project by either issuing "make" in the MITK-build directory (Linux, macOS), or by opening MITK-build/MITK.sln (Windows). You may also change the configuration of any project configured via the superbuild process. Make sure to also build the changed project and also the projects which depend on it. \section BuildInstructions_Running Running Applications On Linux, just execute the application you want to run. MITK executables are located in <tt>MITK-superbuild/MITK-build/bin</tt> On Windows, the <tt>PATH</tt> environment variable must contain the directories containing the third-party libraries. This is automatically done from Visual Studio. For running the applications directly use the generated batch files in the <tt>MITK-superbuild/MITK-build/bin</tt>. \section BuildInstructions_Documentation Documentation If you have the <a href="https://www.doxygen.nl/">Doxygen</a> documentation tool installed, you get a new project (Visual Studio) or "make" target named "doc". You can build this to generate the HTML documentation of MITK in the Documentation/Doxygen directory of your MITK-build binary tree or in the <tt>MITK_DOXYGEN_OUTPUT_DIR</tt> CMake variable (if specified). \section BuildInstructions_Extending Extend MITK on your own (using the application framework BlueBerry) Please see \ref NewPluginPage \section BuildInstructions_As_Toolkit Use MITK in your own project (as a toolkit) To use MITK in your external project, add the CMake command <code>find_package(MITK REQUIRED)</code> to your CMakeLists.txt and make use of the CMake macros <code>mitk_create_module()</code> and <code>mitk_create_executable()</code> provided by MITK. Here is a very basic example CMakeLists.txt including MITK as a project: \code cmake_minimum_required(VERSION 3.10 FATAL_ERROR) project(MyProject) -find_package(MITK 2021.02 REQUIRED) +find_package(MITK 2021.10 REQUIRED) add_executable(MyApp main.cpp) target_link_libraries(MyApp MitkCore) \endcode with the main.ccp being \code #include <iostream> #include <mitkLogMacros.h> int main() { MITK_INFO << "Hello world!"; return 0; } \endcode \section BuildInstructions_Advanced_Customization Superbuild customization You can inject pre-build third-party libraries into the MITK superbuild by setting certain CMake variables before the first configure step. MITK will then use these third-party libraries instead of downloading and building them by itself. Note that you must take care of configuring those libraries with all options MITK requires. The variables listed below are provided for injecting third-party libraries. Their occurrence in the CMake GUI or in ccmake may depend on specific MITK_USE_* options set to ON. You may also use the variable names below without the <tt>EXTERNAL_</tt> prefix, for example when providing their values on a command line call to CMake. - <tt><b>EXTERNAL_BOOST_ROOT</b></tt> Set this variable to your custom Boost installation - <tt><b>EXTERNAL_CTK_DIR</b></tt> Set this variable to your CTK binary tree (the directory containing the CTKConfig.cmake file) - <tt><b>EXTERNAL_CableSwig_DIR</b></tt> Set this variable to your CableSwig binary tree for Python wrapping (the directory containing the CableSwigConfig.cmake file) - <tt><b>EXTERNAL_DCMTK_DIR</b></tt> Set this variable to your DCMTK binary tree (the directory containing the DCMTKConfig.cmake file) - <tt><b>EXTERNAL_GDCM_DIR</b></tt> Set this variable to your GDCM binary tree (the directory containing the GDCMConfig.cmake file) - <tt><b>EXTERNAL_ITK_DIR</b></tt> Set this variable to your ITK binary tree (the directory containing the ITKConfig.cmake file) - <tt><b>EXTERNAL_OpenCV_DIR</b></tt> Set this variable to your OpenCV binary tree (the directory containing the OpenCVConfig.cmake file) - <tt><b>EXTERNAL_VTK_DIR</b></tt> Set this variable to your VTK binary tree (the directory containing the VTKConfig.cmake file) To set CMake options before the first configure step is invoked, supply them on the command line, i.e. \code ccmake -DITK_DIR:PATH=/opt/ITK-release ../MITK \endcode */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/SupportedPlatforms.md b/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/SupportedPlatforms.md index 596dadc9b5..41c0a30b1b 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/SupportedPlatforms.md +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/SupportedPlatforms.md @@ -1,49 +1,55 @@ Supported Platforms {#SupportedPlatformsPage} =================== MITK is a cross-platform framework that is available for the following platforms: - Windows - Linux - macOS Supported Platforms Details --------------------------- The MITK team provides support for the most frequently used platforms and continuously runs testing procedures to ensure compatibility. Due to the large amount of possible combinations of operating systems and compiler versions, we divide platform support into two test categories: Tier 1 and Tier 2. Although MITK may be built on a broader range of platform-compiler combinations, only a subset of these are actively supported by the MITK development team. +In general, only 64-bit builds are supported. + Tier 1 Platforms ---------------- All Tier 1 platforms are continuously tested by our unit test suite and other internal testing procedures. Errors or bugs discovered in these platforms are prioritized and corrected as soon as possible. | Platform | Compilers | ----------------------------------- | -------------------------------------------------- -| Microsoft Windows 10 (x64) | Visual Studio 2019 (latest update) -| Linux Ubuntu 20.04 (x64) | Default GCC version -| Linux Ubuntu 18.04 (x64) | Default GCC version -| Apple macOS 10.14 "Mojave" | Default Apple Clang version +| Microsoft Windows 10 | Visual Studio 2019 (latest update) +| Linux Ubuntu 20.04 | Default GCC version +| Linux Ubuntu 18.04 | Default GCC version Tier 2 Platforms ---------------- Tier 2 platforms may or may not be tested on a regular basis. Some Tier 2 platforms are used by individual members of the MITK development team on a daily basis and some only receive occasional testing. While we strive to support these platforms, MITK users should note that errors may be present in released versions as well as in the current master branch. | Platform | Compilers | ----------------------------------- | -------------------------------------------------- -| Microsoft Windows 10 (x64) | Visual Studio 2017 (latest update) +| Microsoft Windows 10 | Visual Studio 2022 (latest update) +| Apple macOS 11 "Big Sur" | Default Apple Clang version | Apple macOS 10.15 "Catalina" | Default Apple Clang version -| Apple macOS 11.1 "Big Sur" (x64) | Default Apple Clang version All platforms not listed above are not officially supported by the MITK team. However, we will happily accept -contributions to improve support for other platforms. +contributions to improve support for other platforms as long as we have the hardware and capacity for maintenance. + +CI Build Clients +---------------- + +To get an overview of currently tested platforms, see the <a href="https://cdash.mitk.org/index.php?project=MITK">build reports on our CDash site</a>. diff --git a/Documentation/Doxygen/4-API/Pages.dox b/Documentation/Doxygen/4-API/Pages.dox index 3cb9ec9d13..2d69ee13f0 100644 --- a/Documentation/Doxygen/4-API/Pages.dox +++ b/Documentation/Doxygen/4-API/Pages.dox @@ -1,39 +1,42 @@ /** \defgroup MITKDeprecatedAPI Deprecated \page deprecatedSince2012_09 Deprecated as of 2012.09 \ingroup MITKDeprecatedAPI \page deprecatedSince2013_03 Deprecated as of 2013.03 \ingroup MITKDeprecatedAPI \page deprecatedSince2013_06 Deprecated as of 2013.06 \ingroup MITKDeprecatedAPI \page deprecatedSince2013_09 Deprecated as of 2013.09 \ingroup MITKDeprecatedAPI \page deprecatedSince2014_03 Deprecated as of 2014.03 \ingroup MITKDeprecatedAPI \page deprecatedSince2014_10 Deprecated as of 2014.10 \ingroup MITKDeprecatedAPI \page deprecatedSince2015_05 Deprecated as of 2015.05 \ingroup MITKDeprecatedAPI \page deprecatedSince2016_03 Deprecated as of 2016.03 \ingroup MITKDeprecatedAPI \page deprecatedSince2016_11 Deprecated as of 2016.11 \ingroup MITKDeprecatedAPI \page deprecatedSince2018_04 Deprecated as of 2018.04 \ingroup MITKDeprecatedAPI \page deprecatedSince2021_02 Deprecated as of 2021.02 \ingroup MITKDeprecatedAPI +\page deprecatedSince2021_10 Deprecated as of 2021.10 +\ingroup MITKDeprecatedAPI + */ diff --git a/Documentation/doxygen.conf.in b/Documentation/doxygen.conf.in index 8a46babe1b..79bb026e21 100644 --- a/Documentation/doxygen.conf.in +++ b/Documentation/doxygen.conf.in @@ -1,2433 +1,2431 @@ # Doxyfile 1.8.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "Medical Imaging Interaction Toolkit" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = @MITK_VERSION_STRING@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "Medical Imaging Interaction Toolkit" # With the PROJECT_LOGO tag one can specify an logo or icon that is included in # the documentation. The maximum height of the logo should not exceed 55 pixels # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = "@MITK_DOXYGEN_OUTPUT_DIR@" # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = NO # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a # new page for each member. If set to NO, the documentation of a member will be # part of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = "FIXME=\par Fix Me's:\n" \ "BlueBerry=\if BLUEBERRY" \ "endBlueBerry=\endif" \ "bundlemainpage{1}=\page \1" \ "embmainpage{1}=\page \1" \ "github{2}=<a href=\"https://github.com/MITK/MITK/blob/master/\1\">\2</a>" \ "deprecatedSince{1}=\xrefitem deprecatedSince\1 \"\" \"Functions deprecated as of \1\" \deprecated (as of \1) " \ "minimumCMakeVersion=@MITK_CMAKE_MINIMUM_REQUIRED_VERSION@" \ "minimumQt5Version=@MITK_QT5_MINIMUM_VERSION@" \ "imageMacro{3}=\image html \1 \2 \n \image latex \1 \2 width=\3cm" \ "developersguidemainpage{1}=\page \1 " \ "usersguidemainpage{1}=\page \1 " \ "nondependentPluginLink{3}= \ref \1 \"\3\" " # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed # or free formatted code, this is the default for Fortran type files), VHDL. For # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = cmake=c++ # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = YES # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined # locally in source files will be included in the documentation. If set to NO # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = @MITK_DOXYGEN_INTERNAL_DOCS@ # This flag is only useful for Objective-C code. When set to YES local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO these classes will be included in the various overviews. This option has # no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = @MITK_DOXYGEN_HIDE_FRIEND_COMPOUNDS@ # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = @MITK_DOXYGEN_INTERNAL_DOCS@ # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = YES # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the # todo list. This list is created by putting \todo commands in the # documentation. # The default value is: YES. GENERATE_TODOLIST = @MITK_DOXYGEN_GENERATE_TODOLIST@ # The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the # test list. This list is created by putting \test commands in the # documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = @MITK_DOXYGEN_GENERATE_BUGLIST@ # The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= @MITK_DOXYGEN_GENERATE_DEPRECATEDLIST@ # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if <section_label> ... \endif and \cond <section_label> # ... \endcond blocks. ENABLED_SECTIONS = @MITK_DOXYGEN_ENABLED_SECTIONS@ # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 0 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES the list # will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = "@MITK_SOURCE_DIR@/Documentation/MITKDoxygenLayout.xml" # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO doxygen will only warn about wrong or incomplete parameter # documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. # Note: If this tag is empty the current directory is searched. INPUT = @MITK_SOURCE_DIR@ \ @MITK_BINARY_DIR@ \ @MITK_DOXYGEN_ADDITIONAL_INPUT_DIRS@ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank the # following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, # *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. FILE_PATTERNS = *.h \ *.dox \ *.md # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = "@MITK_SOURCE_DIR@/Utilities/IpFunc/" \ - "@MITK_SOURCE_DIR@/Utilities/IpSegmentation/" \ - "@MITK_SOURCE_DIR@/Utilities/qtsingleapplication/" \ +EXCLUDE = "@MITK_SOURCE_DIR@/Utilities/qtsingleapplication/" \ "@MITK_SOURCE_DIR@/Applications/PluginGenerator/" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/core/doc/snippets/" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/core/doc/doxygen/standalone/" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/core/test/" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/core/examples/" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/core/src/util/jsoncpp.cpp" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/third_party" \ "@MITK_SOURCE_DIR@/CMake/PackageDepends" \ "@MITK_SOURCE_DIR@/CMakeExternals" \ "@MITK_SOURCE_DIR@/Licenses" \ "@MITK_BINARY_DIR@/Documentation/Doxygen" \ "@MITK_BINARY_DIR@/bin/" \ "@MITK_BINARY_DIR@/PT/" \ "@MITK_BINARY_DIR@/GP/" \ "@MITK_BINARY_DIR@/_CPack_Packages/" \ @MITK_DOXYGEN_ADDITIONAL_EXCLUDE_DIRS@ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = README* \ moc_* \ ui_* \ qrc_* \ wrap_* \ Register* \ */files.cmake \ */.git/* \ *_p.h \ *Private.* \ */Internal/* \ */internal/* \ */Snippets/* \ */snippets/* \ */testing/* \ */Testing/* \ */test/* \ */resource/* \ "@MITK_BINARY_DIR@/*.cmake" \ @MITK_DOXYGEN_EXCLUDE_PATTERNS@ # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = "@MITK_SOURCE_DIR@/Examples/" \ "@MITK_SOURCE_DIR@/Examples/Tutorial/" \ "@MITK_SOURCE_DIR@/Examples/Plugins/" \ "@MITK_SOURCE_DIR@/Examples/QtFreeRender/" \ "@MITK_SOURCE_DIR@/Modules/Core/" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/core/doc/snippets/" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/core/examples/" \ "@MITK_SOURCE_DIR@/Modules/CppMicroServices/" \ "@MITK_SOURCE_DIR@/Modules/OpenCL/Documentation/doxygen/snippets/" \ "@MITK_SOURCE_DIR@/Modules/IGT/Tutorial/" \ "@MITK_SOURCE_DIR@/Plugins/org.mitk.gui.common/src/" \ "@MITK_SOURCE_DIR@/Plugins/org.mitk.gui.qt.igtexamples/" \ "@MITK_SOURCE_DIR@/Plugins/org.mitk.gui.qt.igttracking/" # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = "@MITK_SOURCE_DIR@/Documentation/Doxygen/" \ "@MITK_SOURCE_DIR@" # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # <filter> <input-file> # # where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = *.cmake=@CMakeDoxygenFilter_EXECUTABLE@ # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER ) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES, then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 3 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra stylesheet files is of importance (e.g. the last # stylesheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @MITK_DOXYGEN_STYLESHEET@ # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = "@MITK_SOURCE_DIR@/Documentation/Doxygen/mitkLogo.jpg" # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the stylesheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to NO can help when comparing the output of multiple runs. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = @MITK_DOXYGEN_HTML_DYNAMIC_SECTIONS@ # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler ( hhc.exe). If non-empty # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated ( # YES) or that it should be included in the master .chm file ( NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated ( # YES) or a normal table of contents ( NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = @MITK_DOXYGEN_GENERATE_QHP@ # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = @MITK_DOXYGEN_QCH_FILE@ # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = "org.mitk" # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = MITK # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = @QT_HELPGENERATOR_EXECUTABLE@ # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 300 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = YES # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use <access key> + S # (what the <access key> is depends on the OS and browser, but it is typically # <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down # key> to jump into the search results window, the results can be navigated # using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel # the search. The filter options can be selected when the cursor is inside the # search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> # to select a filter and <Enter> or <escape> to activate or cancel the filter # option. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing # and searching needs to be provided by external tools. See the section # "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain the # search results. # # Doxygen ships with an example indexer ( doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. # # Doxygen ships with an example indexer ( doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). See the section "External Indexing and # Searching" for details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. # The default file is: searchdata.xml. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. # This tag requires that the tag SEARCHENGINE is set to YES. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of # to a relative location where the documentation can be found. The format is: # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... # This tag requires that the tag SEARCHENGINE is set to YES. EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # # Note that when enabling USE_PDFLATEX this option is only used for generating # bitmaps for formulas in the HTML output, but not in the Makefile that is # written to the output directory. # The default file is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used by the # printer. # Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x # 14 inches) and executive (7.25 x 10.5 inches). # The default value is: a4. # This tag requires that the tag GENERATE_LATEX is set to YES. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names # that should be included in the LaTeX output. To get the times font for # instance you can specify # EXTRA_PACKAGES=times # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. EXTRA_PACKAGES = amssymb # The LATEX_HEADER tag can be used to specify a personal LaTeX header for the # generated LaTeX document. The header should contain everything until the first # chapter. If it is left blank doxygen will generate a standard header. See # section "Doxygen usage" for information on how to let doxygen write the # default header to a separate file. # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, # $datetime, $date, $doxygenversion, $projectname, $projectnumber, # $projectbrief, $projectlogo. Doxygen will replace $title with the empy string, # for the replacement values of the other commands the user is refered to # HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last # chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what # special commands can be used inside the footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output # directory. Note that the files will be copied as-is; there are no commands or # markers available. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will # contain links (just like the HTML output) instead of page references. This # makes the output suitable for online browsing using a PDF viewer. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate # the PDF file directly from the LaTeX files. Set this option to YES to get a # higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode # command to the generated LaTeX files. This will instruct LaTeX to keep running # if errors occur, instead of asking the user for help. This option is also used # when generating formulas in HTML. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BATCHMODE = NO # If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the # index chapters (such as File Index, Compound Index, etc.) in the output. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HIDE_INDICES = NO # If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source # code with syntax highlighting in the LaTeX output. # # Note that which sources are shown also depends on other settings such as # SOURCE_BROWSER. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See # http://en.wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The # RTF output is optimized for Word 97 and may not look too pretty with other RTF # readers/editors. # The default value is: NO. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: rtf. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will # contain hyperlink fields. The RTF file will contain links (just like the HTML # output) instead of page references. This makes the output suitable for online # browsing using Word or some other Word compatible readers that support those # fields. # # Note: WordPad (write) and others do not support links. # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's config # file, i.e. a series of assignments. You only have to provide replacements, # missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is # similar to doxygen's config file. A template extensions file can be generated # using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES doxygen will generate man pages for # classes and files. # The default value is: NO. GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. A directory man3 will be created inside the directory specified by # MAN_OUTPUT. # The default directory is: man. # This tag requires that the tag GENERATE_MAN is set to YES. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to the generated # man pages. In case the manual section does not start with a number, the number # 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is # optional. # The default value is: .3. # This tag requires that the tag GENERATE_MAN is set to YES. MAN_EXTENSION = .3 # The MAN_SUBDIR tag determines the name of the directory created within # MAN_OUTPUT in which the man pages are placed. If defaults to man followed by # MAN_EXTENSION with the initial . removed. # This tag requires that the tag GENERATE_MAN is set to YES. MAN_SUBDIR = # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without # them the man command would be unable to find the correct page. # The default value is: NO. # This tag requires that the tag GENERATE_MAN is set to YES. MAN_LINKS = NO #--------------------------------------------------------------------------- # Configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES doxygen will generate an XML file that # captures the structure of the code including all documentation. # The default value is: NO. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: xml. # This tag requires that the tag GENERATE_XML is set to YES. XML_OUTPUT = xml # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size # of the XML output. # The default value is: YES. # This tag requires that the tag GENERATE_XML is set to YES. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- # If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. GENERATE_DOCBOOK = NO # The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in # front of it. # The default directory is: docbook. # This tag requires that the tag GENERATE_DOCBOOK is set to YES. DOCBOOK_OUTPUT = docbook # If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the # program listings (including syntax highlighting and cross-referencing # information) to the DOCBOOK output. Note that enabling this will significantly # increase the size of the DOCBOOK output. # The default value is: NO. # This tag requires that the tag GENERATE_DOCBOOK is set to YES. DOCBOOK_PROGRAMLISTING = NO #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen # Definitions (see http://autogen.sf.net) file that captures the structure of # the code including all documentation. Note that this feature is still # experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module # file that captures the structure of the code including all documentation. # # Note that this feature is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # output from the Perl module output. # The default value is: NO. # This tag requires that the tag GENERATE_PERLMOD is set to YES. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely # formatted so it can be parsed by a human reader. This is useful if you want to # understand what is going on. On the other hand, if this tag is set to NO the # size of the Perl module output will be much smaller and Perl will parse it # just the same. # The default value is: YES. # This tag requires that the tag GENERATE_PERLMOD is set to YES. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file are # prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful # so different doxyrules.make files included by the same Makefile don't # overwrite each other's variables. # This tag requires that the tag GENERATE_PERLMOD is set to YES. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names # in the source code. If set to NO only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and # EXPAND_AS_DEFINED tags. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES the includes files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will be # used. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. # gcc). The argument of the tag is a list of macros of the form: name or # name=definition (no spaces). If the definition and the "=" are omitted, "=1" # is assumed. To prevent a macro definition from being undefined via #undef or # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. PREDEFINED = itkNotUsed(x)= \ "itkSetMacro(name,type)=virtual void Set##name (type _arg);" \ "itkGetMacro(name,type)=virtual type Get##name ();" \ "itkGetConstMacro(name,type)=virtual type Get##name () const;" \ "itkSetStringMacro(name)=virtual void Set##name (const char* _arg);" \ "itkGetStringMacro(name)=virtual const char* Get##name () const;" \ "itkSetClampMacro(name,type,min,max)=virtual void Set##name (type _arg);" \ "itkSetObjectMacro(name,type)=virtual void Set##name (type* _arg);" \ "itkGetObjectMacro(name,type)=virtual type* Get##name ();" \ "itkSetConstObjectMacro(name,type)=virtual void Set##name ( const type* _arg);" \ "itkGetConstObjectMacro(name,type)=virtual const type* Get##name ();" \ "itkGetConstReferenceMacro(name,type)=virtual const type& Get##name ();" \ "itkGetConstReferenceObjectMacro(name,type)=virtual const type::Pointer& Get##name () const;" \ "itkBooleanMacro(name)=virtual void name##On (); virtual void name##Off ();" \ "itkSetVector2Macro(name,type)=virtual void Set##name (type _arg1, type _arg2) virtual void Set##name (type _arg[2]);" \ "itkGetVector2Macro(name,type)=virtual type* Get##name () const; virtual void Get##name (type& _arg1, type& _arg2) const; virtual void Get##name (type _arg[2]) const;" \ "itkSetVector3Macro(name,type)=virtual void Set##name (type _arg1, type _arg2, type _arg3) virtual void Set##name (type _arg[3]);" \ "itkGetVector3Macro(name,type)=virtual type* Get##name () const; virtual void Get##name (type& _arg1, type& _arg2, type& _arg3) const; virtual void Get##name (type _arg[3]) const;" \ "itkSetVector4Macro(name,type)=virtual void Set##name (type _arg1, type _arg2, type _arg3, type _arg4) virtual void Set##name (type _arg[4]);" \ "itkGetVector4Macro(name,type)=virtual type* Get##name () const; virtual void Get##name (type& _arg1, type& _arg2, type& _arg3, type& _arg4) const; virtual void Get##name (type _arg[4]) const;" \ "itkSetVector6Macro(name,type)=virtual void Set##name (type _arg1, type _arg2, type _arg3, type _arg4, type _arg5, type _arg6) virtual void Set##name (type _arg[6]);" \ "itkGetVector6Macro(name,type)=virtual type* Get##name () const; virtual void Get##name (type& _arg1, type& _arg2, type& _arg3, type& _arg4, type& _arg5, type& _arg6) const; virtual void Get##name (type _arg[6]) const;" \ "itkSetVectorMacro(name,type,count)=virtual void Set##name(type data[]);" \ "itkGetVectorMacro(name,type,count)=virtual type* Get##name () const;" \ "itkNewMacro(type)=static Pointer New();" \ "itkFactorylessNewMacro(type)=static Pointer New();" \ "itkCloneMacro(type)=Pointer Clone() const;" \ "itkTypeMacro(thisClass,superclass)=virtual const char *GetClassName() const;" \ "itkConceptMacro(name,concept)=enum { name = 0 };" \ "ITK_NUMERIC_LIMITS=std::numeric_limits" \ "ITK_TYPENAME=typename" \ "FEM_ABSTRACT_CLASS(thisClass,parentClass)=public: /** Standard Self typedef.*/ typedef thisClass Self; /** Standard Superclass typedef. */ typedef parentClass Superclass; /** Pointer or SmartPointer to an object. */ typedef Self* Pointer; /** Const pointer or SmartPointer to an object. */ typedef const Self* ConstPointer; private:" \ "FEM_CLASS(thisClass,parentClass)=FEM_ABSTRACT_CLASS(thisClass,parentClass) public: /** Create a new object from the existing one */ virtual Baseclass::Pointer Clone() const; /** Class ID for FEM object factory */ static const int CLID; /** Virtual function to access the class ID */ virtual int ClassID() const { return CLID; /** Object creation in an itk compatible way */ static Self::Pointer New() { return new Self(); } private:" \ FREEVERSION \ ERROR_CHECKING \ HAS_TIFF \ HAS_JPEG \ HAS_NETLIB \ HAS_PNG \ HAS_ZLIB \ HAS_GLUT \ HAS_QT \ VCL_USE_NATIVE_STL=1 \ VCL_USE_NATIVE_COMPLEX=1 \ VCL_HAS_BOOL=1 \ VXL_BIG_ENDIAN=1 \ VXL_LITTLE_ENDIAN=0 \ VNL_DLL_DATA= \ size_t=vcl_size_t \ "US_PREPEND_NAMESPACE(x)=us::x" \ "US_BEGIN_NAMESPACE= namespace us {" \ "US_END_NAMESPACE=}" \ "US_BASECLASS_NAME=itk::LightObject" \ US_EXPORT= \ "DEPRECATED(func)=func" \ @US_PLATFORM@ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The # macro definition that is found in the sources will be used. Use the PREDEFINED # tag if you want to use a different macro definition that overrules the # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have # an all uppercase name, and do not end with a semicolon. Such function macros # are typically used for boiler-plate code, and will confuse the parser if not # removed. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration options related to external references #--------------------------------------------------------------------------- # The TAGFILES tag can be used to specify one or more tag files. For each tag # file the location of the external documentation should be added. The format of # a tag file without this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where loc1 and loc2 can be relative or absolute paths or URLs. See the # section "Linking to external documentation" for more information about the use # of tag files. # Note: Each tag file must have a unique name (where the name does NOT include # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. GENERATE_TAGFILE = @MITK_DOXYGEN_TAGFILE_NAME@ # If the ALLEXTERNALS tag is set to YES all external class will be listed in the # class index. If set to NO only the inherited external classes will be listed. # The default value is: NO. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in # the modules index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. EXTERNAL_GROUPS = NO # If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. EXTERNAL_PAGES = YES #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # NO turns the diagrams off. Note that this option also works with HAVE_DOT # disabled, but it is recommended to install and use dot, since it yields more # powerful graphs. # The default value is: YES. CLASS_DIAGRAMS = YES # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. # If left empty dia is assumed to be found in the default search path. DIA_PATH = # If set to YES, the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. HAVE_DOT = @HAVE_DOT@ # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # to run in parallel. When set to 0 doxygen will base this on the number of # processors available in the system. You can set it explicitly to a value # larger than 0 to get control over the balance between CPU load and processing # speed. # Minimum value: 0, maximum value: 32, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. DOT_NUM_THREADS = @MITK_DOXYGEN_DOT_NUM_THREADS@ # When you want a differently looking font in the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by # setting DOT_FONTPATH to the directory containing the font. # The default value is: Helvetica. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size (in points) of the font of # dot graphs. # Minimum value: 4, maximum value: 24, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the default font as specified with # DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set # the path where dot can find it using this tag. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for # each documented class showing the direct and indirect inheritance relations. # Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a # graph for each documented class showing the direct and indirect implementation # dependencies (inheritance, containment, and class references variables) of the # class with other documented classes. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. UML_LOOK = @MITK_DOXYGEN_UML_LOOK@ # If the UML_LOOK tag is enabled, the fields and methods are shown inside the # class node. If there are many fields or methods and many nodes the graph may # become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the # number of items for each type to make the size more manageable. Set this to 0 # for no limit. Note that the threshold may be exceeded by 50% before the limit # is enforced. So when you set the threshold to 10, up to 15 fields may appear, # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. UML_LIMIT_NUM_FIELDS = 10 # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. TEMPLATE_RELATIONS = YES # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then doxygen will generate a graph for each documented file showing the # direct and indirect include dependencies of the file with other documented # files. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing # the direct and indirect include dependencies of the file with other documented # files. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. CALL_GRAPH = NO # If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller # dependency graph for every global function or class method. # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical # hierarchy of all classes instead of a textual one. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GRAPHICAL_HIERARCHY = NO # If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the # dependencies a directory has on other directories in a graphical way. The # dependency relations are determined by the #include relations between the # files in the directories. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). # Possible values are: png, jpg, gif and svg. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # # Note that this requires a modern browser other than Internet Explorer. Tested # and working are Firefox, Chrome, Safari, and Opera. # Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make # the SVG files visible. Older versions of IE do not have SVG support. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. INTERACTIVE_SVG = NO # The DOT_PATH tag can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. # This tag requires that the tag HAVE_DOT is set to YES. DOT_PATH = "@DOXYGEN_DOT_PATH@" # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the \dotfile # command). # This tag requires that the tag HAVE_DOT is set to YES. DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile # command). MSCFILE_DIRS = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile # command). DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the # path where java can find the plantuml.jar file. If left blank, it is assumed # PlantUML is not used or called during a preprocessing step. Doxygen will # generate a warning when it encounters a \startuml command in this case and # will not generate output for the diagram. # This tag requires that the tag HAVE_DOT is set to YES. PLANTUML_JAR_PATH = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized # by representing a node as a red box. Note that doxygen if the number of direct # children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that # the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. # Minimum value: 0, maximum value: 10000, default value: 50. # This tag requires that the tag HAVE_DOT is set to YES. DOT_GRAPH_MAX_NODES = 120 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs # generated by dot. A depth value of 3 means that only nodes reachable from the # root by following a path via at most 3 edges will be shown. Nodes that lay # further from the root node will be omitted. Note that setting this option to 1 # or 2 may greatly reduce the computation time needed for large code bases. Also # note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. # Minimum value: 0, maximum value: 1000, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not seem # to support this out of the box. # # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support # this, this feature is disabled by default. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES diff --git a/Examples/Tutorial/ITKAndVTK/mitkWithITKAndVTK.cpp b/Examples/Tutorial/ITKAndVTK/mitkWithITKAndVTK.cpp index c744b6af7f..acf9c09bd2 100644 --- a/Examples/Tutorial/ITKAndVTK/mitkWithITKAndVTK.cpp +++ b/Examples/Tutorial/ITKAndVTK/mitkWithITKAndVTK.cpp @@ -1,76 +1,76 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <itkDiscreteGaussianImageFilter.h> #include <itkImage.h> #include <itksys/SystemTools.hxx> #include <mitkIOUtil.h> #include <mitkImageAccessByItk.h> #include <mitkImageCast.h> #include <mitkStandaloneDataStorage.h> #include <vtkImageViewer.h> #include <vtkRenderWindowInteractor.h> /// /// Small application for demonstrating the interaction between MITK, /// ITK and VTK (not necessarily useful). /// int main(int /*argc*/, char **argv) { - // MITK: Read a .pic.gz file, e.g. Core/Code/Testing/Data/Pic3D.pic.gz from + // MITK: Read a .nrrd file, e.g. Core/Code/Testing/Data/Pic3D.nrrd from // disk const char *filename = argv[1]; mitk::Image::Pointer mitkImage; try { mitkImage = mitk::IOUtil::Load<mitk::Image>(filename); } catch (const std::exception &e) { MITK_WARN << "Could not open file " << filename; return EXIT_FAILURE; } // ITK: Image smoothing // Create ITK image, cast from MITK image typedef itk::Image<short, 3> ImageType; ImageType::Pointer itkImage = ImageType::New(); mitk::CastToItkImage(mitkImage, itkImage); typedef itk::DiscreteGaussianImageFilter<ImageType, ImageType> FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput(itkImage); filter->SetVariance(2); filter->SetMaximumKernelWidth(5); filter->Update(); // run filter // reimport filtered image data mitk::CastToMitkImage(filter->GetOutput(), mitkImage); // VTK: Show result in renderwindow vtkImageViewer *viewer = vtkImageViewer::New(); vtkRenderWindowInteractor *renderWindowInteractor = vtkRenderWindowInteractor::New(); viewer->SetupInteractor(renderWindowInteractor); viewer->SetInputData(mitkImage->GetVtkImageData()); viewer->Render(); viewer->SetColorWindow(255); viewer->SetColorLevel(128); renderWindowInteractor->Start(); renderWindowInteractor->Delete(); viewer->Delete(); return EXIT_SUCCESS; } diff --git a/Modules/AlgorithmsExt/test/CMakeLists.txt b/Modules/AlgorithmsExt/test/CMakeLists.txt index 4b2f4f5be6..5c76ebf4b6 100644 --- a/Modules/AlgorithmsExt/test/CMakeLists.txt +++ b/Modules/AlgorithmsExt/test/CMakeLists.txt @@ -1,5 +1,5 @@ MITK_CREATE_MODULE_TESTS() if(TARGET ${TESTDRIVER}) - mitkAddCustomModuleTest(mitkLabeledImageToSurfaceFilterTest_BinaryBall mitkLabeledImageToSurfaceFilterTest ${MITK_DATA_DIR}/BallBinary30x30x30.pic.gz) + mitkAddCustomModuleTest(mitkLabeledImageToSurfaceFilterTest_BinaryBall mitkLabeledImageToSurfaceFilterTest ${MITK_DATA_DIR}/BallBinary30x30x30.nrrd) endif() diff --git a/Modules/ContourModel/Algorithms/mitkContourModelUtils.cpp b/Modules/ContourModel/Algorithms/mitkContourModelUtils.cpp index c3ea18a797..134106e179 100755 --- a/Modules/ContourModel/Algorithms/mitkContourModelUtils.cpp +++ b/Modules/ContourModel/Algorithms/mitkContourModelUtils.cpp @@ -1,238 +1,238 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkContourModelUtils.h> #include <mitkContourModelToSurfaceFilter.h> #include <mitkLabelSetImage.h> #include <mitkSurface.h> #include <vtkImageStencil.h> #include <vtkPointData.h> #include <vtkPolyData.h> #include <vtkPolyDataToImageStencil.h> mitk::ContourModelUtils::ContourModelUtils() { } mitk::ContourModelUtils::~ContourModelUtils() { } mitk::ContourModel::Pointer mitk::ContourModelUtils::ProjectContourTo2DSlice( - const Image *slice, const ContourModel *contourIn3D, bool, bool) + const Image *slice, const ContourModel *contourIn3D) { if (nullptr == slice || nullptr == contourIn3D) return nullptr; auto projectedContour = ContourModel::New(); projectedContour->Initialize(*contourIn3D); auto sliceGeometry = slice->GetGeometry(); const auto numberOfTimesteps = static_cast<TimeStepType>(contourIn3D->GetTimeSteps()); for (std::remove_const_t<decltype(numberOfTimesteps)> t = 0; t < numberOfTimesteps; ++t) { auto iter = contourIn3D->Begin(t); auto end = contourIn3D->End(t); while (iter != end) { const auto ¤tPointIn3D = (*iter)->Coordinates; Point3D projectedPointIn2D; projectedPointIn2D.Fill(0.0); sliceGeometry->WorldToIndex(currentPointIn3D, projectedPointIn2D); projectedContour->AddVertex(projectedPointIn2D, t); ++iter; } } return projectedContour; } mitk::ContourModel::Pointer mitk::ContourModelUtils::BackProjectContourFrom2DSlice( - const BaseGeometry *sliceGeometry, const ContourModel *contourIn2D, bool) + const BaseGeometry *sliceGeometry, const ContourModel *contourIn2D) { if (nullptr == sliceGeometry || nullptr == contourIn2D) return nullptr; auto worldContour = ContourModel::New(); worldContour->Initialize(*contourIn2D); const auto numberOfTimesteps = static_cast<TimeStepType>(contourIn2D->GetTimeSteps()); for (std::remove_const_t<decltype(numberOfTimesteps)> t = 0; t < numberOfTimesteps; ++t) { auto iter = contourIn2D->Begin(t); auto end = contourIn2D->End(t); while (iter != end) { const auto ¤tPointIn2D = (*iter)->Coordinates; Point3D worldPointIn3D; worldPointIn3D.Fill(0.0); sliceGeometry->IndexToWorld(currentPointIn2D, worldPointIn3D); worldContour->AddVertex(worldPointIn3D, t); ++iter; } } return worldContour; } void mitk::ContourModelUtils::FillContourInSlice( const ContourModel *projectedContour, Image *sliceImage, const Image* workingImage, int paintingPixelValue) { FillContourInSlice(projectedContour, 0, sliceImage, workingImage, paintingPixelValue); } void mitk::ContourModelUtils::FillContourInSlice( const ContourModel *projectedContour, TimeStepType contourTimeStep, Image *sliceImage, const Image* workingImage, int paintingPixelValue) { if (nullptr == projectedContour) { mitkThrow() << "Cannot fill contour in slice. Passed contour is invalid"; } if (nullptr == sliceImage) { mitkThrow() << "Cannot fill contour in slice. Passed slice is invalid"; } auto contourModelFilter = mitk::ContourModelToSurfaceFilter::New(); contourModelFilter->SetInput(projectedContour); contourModelFilter->Update(); auto surface = mitk::Surface::New(); surface = contourModelFilter->GetOutput(); if (nullptr == surface->GetVtkPolyData(contourTimeStep)) { MITK_WARN << "Could not create surface from contour model."; return; } auto surface2D = vtkSmartPointer<vtkPolyData>::New(); surface2D->SetPoints(surface->GetVtkPolyData(contourTimeStep)->GetPoints()); surface2D->SetLines(surface->GetVtkPolyData(contourTimeStep)->GetLines()); auto image = vtkSmartPointer<vtkImageData>::New(); image->DeepCopy(sliceImage->GetVtkImageData()); const double FOREGROUND_VALUE = 255.0; const double BACKGROUND_VALUE = 0.0; const vtkIdType count = image->GetNumberOfPoints(); for (std::remove_const_t<decltype(count)> i = 0; i < count; ++i) image->GetPointData()->GetScalars()->SetTuple1(i, FOREGROUND_VALUE); auto polyDataToImageStencil = vtkSmartPointer<vtkPolyDataToImageStencil>::New(); // Set a minimal tolerance, so that clipped pixels will be added to contour as well. polyDataToImageStencil->SetTolerance(mitk::eps); polyDataToImageStencil->SetInputData(surface2D); polyDataToImageStencil->Update(); auto imageStencil = vtkSmartPointer<vtkImageStencil>::New(); imageStencil->SetInputData(image); imageStencil->SetStencilConnection(polyDataToImageStencil->GetOutputPort()); imageStencil->ReverseStencilOff(); imageStencil->SetBackgroundValue(BACKGROUND_VALUE); imageStencil->Update(); vtkSmartPointer<vtkImageData> filledImage = imageStencil->GetOutput(); vtkSmartPointer<vtkImageData> resultImage = sliceImage->GetVtkImageData(); FillSliceInSlice(filledImage, resultImage, workingImage, paintingPixelValue); sliceImage->SetVolume(resultImage->GetScalarPointer()); } void mitk::ContourModelUtils::FillSliceInSlice( vtkSmartPointer<vtkImageData> filledImage, vtkSmartPointer<vtkImageData> resultImage, const Image* image, int paintingPixelValue, double fillForegroundThreshold) { auto labelImage = dynamic_cast<const LabelSetImage *>(image); const auto numberOfPoints = filledImage->GetNumberOfPoints(); if (nullptr == labelImage) { for (std::remove_const_t<decltype(numberOfPoints)> i = 0; i < numberOfPoints; ++i) { if (fillForegroundThreshold <= filledImage->GetPointData()->GetScalars()->GetTuple1(i)) resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue); } } else { const auto backgroundValue = labelImage->GetExteriorLabel()->GetValue(); if (paintingPixelValue != backgroundValue) { for (std::remove_const_t<decltype(numberOfPoints)> i = 0; i < numberOfPoints; ++i) { const auto filledValue = filledImage->GetPointData()->GetScalars()->GetTuple1(i); if (fillForegroundThreshold <= filledValue) { const auto existingValue = resultImage->GetPointData()->GetScalars()->GetTuple1(i); if (!labelImage->GetLabel(existingValue, labelImage->GetActiveLayer())->GetLocked()) resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue); } } } else { const auto activePixelValue = labelImage->GetActiveLabel(labelImage->GetActiveLayer())->GetValue(); for (std::remove_const_t<decltype(numberOfPoints)> i = 0; i < numberOfPoints; ++i) { if (fillForegroundThreshold <= filledImage->GetPointData()->GetScalars()->GetTuple1(i)) { if (resultImage->GetPointData()->GetScalars()->GetTuple1(i) == activePixelValue) resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue); } } } } } mitk::ContourModel::Pointer mitk::ContourModelUtils::MoveZerothContourTimeStep(const ContourModel *contour, TimeStepType t) { if (nullptr == contour) return nullptr; auto resultContour = ContourModel::New(); resultContour->Expand(t + 1); std::for_each(contour->Begin(), contour->End(), [&resultContour, t](ContourElement::VertexType *vertex) { resultContour->AddVertex(*vertex, t); }); return resultContour; } int mitk::ContourModelUtils::GetActivePixelValue(const Image* workingImage) { auto labelSetImage = dynamic_cast<const LabelSetImage*>(workingImage); int activePixelValue = 1; if (nullptr != labelSetImage) { activePixelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue(); } return activePixelValue; } diff --git a/Modules/ContourModel/Algorithms/mitkContourModelUtils.h b/Modules/ContourModel/Algorithms/mitkContourModelUtils.h index 7c567a697e..6fe5f072bd 100644 --- a/Modules/ContourModel/Algorithms/mitkContourModelUtils.h +++ b/Modules/ContourModel/Algorithms/mitkContourModelUtils.h @@ -1,124 +1,116 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkContourModelUtils_h #define mitkContourModelUtils_h #include <mitkContourModel.h> #include <mitkImage.h> #include <vtkSmartPointer.h> #include <MitkContourModelExports.h> namespace mitk { /** * \brief Helpful methods for working with contours and images * * */ class MITKCONTOURMODEL_EXPORT ContourModelUtils : public itk::Object { public: mitkClassMacroItkParent(ContourModelUtils, itk::Object); /** \brief Projects a contour onto an image point by point. Converts from world to index coordinates. \param slice \param contourIn3D - \param correctionForIpSegmentation adds 0.5 to x and y index coordinates (difference between ipSegmentation and - MITK contours) - \param constrainToInside */ static ContourModel::Pointer ProjectContourTo2DSlice(const Image *slice, - const ContourModel *contourIn3D, - bool correctionForIpSegmentation, - bool constrainToInside); + const ContourModel *contourIn3D); /** \brief Projects a slice index coordinates of a contour back into world coordinates. \param sliceGeometry \param contourIn2D - \param correctionForIpSegmentation subtracts 0.5 to x and y index coordinates (difference between ipSegmentation - and MITK contours) */ static ContourModel::Pointer BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry, - const ContourModel *contourIn2D, - bool correctionForIpSegmentation = false); + const ContourModel *contourIn2D); /** \brief Fill a contour in a 2D slice with a specified pixel value. This version always uses the contour of time step 0 and fills the image. \pre sliceImage points to a valid instance \pre projectedContour points to a valid instance */ static void FillContourInSlice(const ContourModel *projectedContour, Image *sliceImage, const Image* workingImage, int paintingPixelValue = 1); /** \brief Fill a contour in a 2D slice with a specified pixel value. This overloaded version uses the contour at the passed contourTimeStep to fill the passed image slice. \pre sliceImage points to a valid instance \pre projectedContour points to a valid instance */ static void FillContourInSlice(const ContourModel *projectedContour, TimeStepType contourTimeStep, Image *sliceImage, const Image* workingImage, int paintingPixelValue = 1); /** \brief Fills the paintingPixelValue into every pixel of resultImage as indicated by filledImage. If a LableSet image is specified it also by incorporating the rules of LabelSet images when filling the content. \param filledImage Pointer to the image content that should be checked to decied of a pixel in resultImage should be filled with paintingPixelValue or not. \param resultImage Pointer to the image content that should be overwritten guided by the content of filledImage. \param image Pointer to an mitk image that allows to define the LabelSet image which states steer the filling process. If an LabelSet instance is passed its states (e.g. locked labels etc...) will be used. If nullptr or an normal image is passed, then simply any pixel position indicated by filledImage will be overwritten. \param paintingPixelValue the pixelvalue/label that should be used in the result image when filling. \param fillForegroundThreshold The threshold value that decides if a pixel in the filled image counts as foreground (>=fillForegroundThreshold) or not. */ static void FillSliceInSlice(vtkSmartPointer<vtkImageData> filledImage, vtkSmartPointer<vtkImageData> resultImage, const Image* image, int paintingPixelValue, double fillForegroundThreshold = 1.0); /** \brief Move the contour in time step 0 to to a new contour model at the given time step. */ static ContourModel::Pointer MoveZerothContourTimeStep(const ContourModel *contour, TimeStepType timeStep); /** \brief Retrieves the active pixel value of a (labelset) image. If the image is basic image, the pixel value 1 (one) will be returned. If the image is actually a labelset image, the pixel value of the active label of the active layer will be returned. \param workingImage The (labelset) image to retrieve the active pixel value of. */ static int GetActivePixelValue(const Image* workingImage); protected: ContourModelUtils(); ~ContourModelUtils() override; }; } #endif diff --git a/Modules/ContourModel/DataManagement/mitkContourElement.cpp b/Modules/ContourModel/DataManagement/mitkContourElement.cpp index bd906acb7b..be73ced97b 100644 --- a/Modules/ContourModel/DataManagement/mitkContourElement.cpp +++ b/Modules/ContourModel/DataManagement/mitkContourElement.cpp @@ -1,419 +1,489 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <algorithm> #include <mitkContourElement.h> #include <vtkMath.h> -bool mitk::ContourElement::ContourModelVertex::operator ==(const ContourModelVertex& other) const +bool mitk::ContourElement::ContourModelVertex::operator==(const ContourModelVertex &other) const { return this->Coordinates == other.Coordinates && this->IsControlPoint == other.IsControlPoint; } mitk::ContourElement::ConstVertexIterator mitk::ContourElement::ConstIteratorBegin() const { return this->begin(); } mitk::ContourElement::ConstVertexIterator mitk::ContourElement::ConstIteratorEnd() const { return this->end(); } mitk::ContourElement::VertexIterator mitk::ContourElement::IteratorBegin() { return this->begin(); } mitk::ContourElement::VertexIterator mitk::ContourElement::IteratorEnd() { return this->end(); } mitk::ContourElement::ConstVertexIterator mitk::ContourElement::begin() const { return this->m_Vertices.begin(); } mitk::ContourElement::ConstVertexIterator mitk::ContourElement::end() const { return this->m_Vertices.end(); } mitk::ContourElement::VertexIterator mitk::ContourElement::begin() { return this->m_Vertices.begin(); } mitk::ContourElement::VertexIterator mitk::ContourElement::end() { return this->m_Vertices.end(); } mitk::ContourElement::ContourElement(const mitk::ContourElement &other) : itk::LightObject(), m_IsClosed(other.m_IsClosed) { - for (const auto& v : other.m_Vertices) + for (const auto &v : other.m_Vertices) { m_Vertices.push_back(new ContourModelVertex(*v)); } } -mitk::ContourElement& mitk::ContourElement::operator = (const ContourElement& other) +mitk::ContourElement &mitk::ContourElement::operator=(const ContourElement &other) { if (this != &other) { this->Clear(); - for (const auto& v : other.m_Vertices) + for (const auto &v : other.m_Vertices) { m_Vertices.push_back(new ContourModelVertex(*v)); } } this->m_IsClosed = other.m_IsClosed; return *this; } mitk::ContourElement::~ContourElement() { this->Clear(); } mitk::ContourElement::VertexSizeType mitk::ContourElement::GetSize() const { return this->m_Vertices.size(); } void mitk::ContourElement::AddVertex(const mitk::Point3D &vertex, bool isControlPoint) { this->m_Vertices.push_back(new VertexType(vertex, isControlPoint)); } void mitk::ContourElement::AddVertexAtFront(const mitk::Point3D &vertex, bool isControlPoint) { this->m_Vertices.push_front(new VertexType(vertex, isControlPoint)); } void mitk::ContourElement::InsertVertexAtIndex(const mitk::Point3D &vertex, bool isControlPoint, VertexSizeType index) { if (index >= 0 && this->GetSize() > index) { auto _where = this->m_Vertices.begin(); _where += index; this->m_Vertices.insert(_where, new VertexType(vertex, isControlPoint)); } } void mitk::ContourElement::SetVertexAt(VertexSizeType pointId, const Point3D &point) { if (pointId >= 0 && this->GetSize() > pointId) { this->m_Vertices[pointId]->Coordinates = point; } } void mitk::ContourElement::SetVertexAt(VertexSizeType pointId, const VertexType *vertex) { if (nullptr == vertex) { mitkThrow() << "Cannot set vertex. Passed vertex instance is invalid. Index to set: " << pointId; } if (pointId >= 0 && this->GetSize() > pointId) { this->m_Vertices[pointId]->Coordinates = vertex->Coordinates; this->m_Vertices[pointId]->IsControlPoint = vertex->IsControlPoint; } } mitk::ContourElement::VertexType *mitk::ContourElement::GetVertexAt(VertexSizeType index) { return this->m_Vertices.at(index); } -const mitk::ContourElement::VertexType* mitk::ContourElement::GetVertexAt(VertexSizeType index) const +const mitk::ContourElement::VertexType *mitk::ContourElement::GetVertexAt(VertexSizeType index) const { return this->m_Vertices.at(index); } bool mitk::ContourElement::IsEmpty() const { return this->m_Vertices.empty(); } +mitk::ContourElement::VertexType *mitk::ContourElement::GetControlVertexAt(const mitk::Point3D &point, float eps) +{ + /* current version iterates over the whole deque - should some kind of an octree with spatial query*/ + + if (eps > 0) + { + // currently no method with better performance is available + return BruteForceGetVertexAt(point, eps, true); + } // if eps < 0 + return nullptr; +} + mitk::ContourElement::VertexType *mitk::ContourElement::GetVertexAt(const mitk::Point3D &point, float eps) { /* current version iterates over the whole deque - should some kind of an octree with spatial query*/ if (eps > 0) { // currently no method with better performance is available return BruteForceGetVertexAt(point, eps); } // if eps < 0 return nullptr; } -mitk::ContourElement::VertexType *mitk::ContourElement::BruteForceGetVertexAt(const mitk::Point3D &point, double eps) +mitk::ContourElement::VertexType *mitk::ContourElement::GetNextControlVertexAt(const mitk::Point3D &point, float eps) +{ + /* current version iterates over the whole deque - should some kind of an octree with spatial query*/ + + if (eps > 0) + { + // currently no method with better performance is available + return BruteForceGetVertexAt(point, eps, true, 1); + } // if eps < 0 + return nullptr; +} + +mitk::ContourElement::VertexType *mitk::ContourElement::GetPreviousControlVertexAt(const mitk::Point3D &point, float eps) { + /* current version iterates over the whole deque - should some kind of an octree with spatial query*/ + if (eps > 0) { - std::deque<std::pair<double, VertexType *>> nearestlist; + // currently no method with better performance is available + return BruteForceGetVertexAt(point, eps, true, -1); + } // if eps < 0 + return nullptr; +} + +mitk::ContourElement::VertexType *mitk::ContourElement::BruteForceGetVertexAt(const mitk::Point3D &point, + double eps, + bool isControlPoint, + int offset) +{ + VertexListType verticesList; + + if (isControlPoint) + { + verticesList = this->GetControlVertices(); + } + else + { + verticesList = *this->GetVertexList(); + } - ConstVertexIterator it = this->m_Vertices.begin(); + int vertexIndex = BruteForceGetVertexIndexAt(point, eps, verticesList); - ConstVertexIterator end = this->m_Vertices.end(); + if (vertexIndex!=-1) + { + vertexIndex += offset; - while (it != end) + if (vertexIndex < 0) { - mitk::Point3D currentPoint = (*it)->Coordinates; + // for negative offset + // if the offset exceeds the first vertex, we start from the end of the vertex list backwards + vertexIndex = verticesList.size() + offset; + } + else if (vertexIndex >= (int) verticesList.size()) + { + // if the offset exceeds the last vertex, we start from the beginning of the vertex list + vertexIndex = vertexIndex - verticesList.size(); + } - double distance = currentPoint.EuclideanDistanceTo(point); - if (distance < eps) - { - // if list is emtpy, add point to list - if (nearestlist.size() < 1) - { - nearestlist.push_front(std::pair<double, VertexType *>((*it)->Coordinates.EuclideanDistanceTo(point), (*it))); - } - // found an approximate point - check if current is closer then first in nearestlist - else if (distance < nearestlist.front().first) - { - // found even closer vertex - nearestlist.push_front(std::pair<double, VertexType *>((*it)->Coordinates.EuclideanDistanceTo(point), (*it))); - } - } // if distance > eps + return verticesList[vertexIndex]; + } + return nullptr; +} - it++; - } // while - if (nearestlist.size() > 0) +int mitk::ContourElement::BruteForceGetVertexIndexAt(const mitk::Point3D &point, + double eps, + VertexListType verticesList) +{ + if (eps < 0) + { + mitkThrow() << "Distance cannot be negative"; + } + + ConstVertexIterator nearestPointIterator; + bool nearestPointIsInitialized = false; + double nearestPointDistance = std::numeric_limits<double>::max(); + + ConstVertexIterator it = verticesList.begin(); + ConstVertexIterator end = verticesList.end(); + + while (it != end) + { + mitk::Point3D currentPoint = (*it)->Coordinates; + + double distance = currentPoint.EuclideanDistanceTo(point); + if (distance < eps) { - /*++++++++++++++++++++ return the nearest active point if one was found++++++++++++++++++*/ - auto it = nearestlist.begin(); - auto end = nearestlist.end(); - while (it != end) + if (distance < nearestPointDistance) { - if ((*it).second->IsControlPoint) - { - return (*it).second; - } - it++; + nearestPointIterator = it; + nearestPointIsInitialized = true; + nearestPointDistance = distance; } - /*---------------------------------------------------------------------------------------*/ + } // if distance > eps - // return closest point - return nearestlist.front().second; - } + it++; + } // while + + if (nearestPointIsInitialized) + { + return nearestPointIterator - verticesList.begin(); } - return nullptr; + return -1; } const mitk::ContourElement::VertexListType *mitk::ContourElement::GetVertexList() const { return &(this->m_Vertices); } bool mitk::ContourElement::IsClosed() const { return this->m_IsClosed; } bool mitk::ContourElement::IsNearContour(const mitk::Point3D &point, float eps) const { ConstVertexIterator it1 = this->m_Vertices.begin(); ConstVertexIterator it2 = this->m_Vertices.begin(); it2++; // it2 runs one position ahead ConstVertexIterator end = this->m_Vertices.end(); int counter = 0; for (; it1 != end; it1++, it2++, counter++) { if (it2 == end) it2 = this->m_Vertices.begin(); mitk::Point3D v1 = (*it1)->Coordinates; mitk::Point3D v2 = (*it2)->Coordinates; const float l2 = v1.SquaredEuclideanDistanceTo(v2); mitk::Vector3D p_v1 = point - v1; mitk::Vector3D v2_v1 = v2 - v1; double tc = (p_v1 * v2_v1) / l2; // take into account we have line segments and not (infinite) lines if (tc < 0.0) tc = 0.0; if (tc > 1.0) tc = 1.0; mitk::Point3D crossPoint = v1 + v2_v1 * tc; double distance = point.SquaredEuclideanDistanceTo(crossPoint); if (distance < eps) { return true; } } return false; } void mitk::ContourElement::Close() { this->m_IsClosed = true; } void mitk::ContourElement::Open() { this->m_IsClosed = false; } void mitk::ContourElement::SetClosed(bool isClosed) { isClosed ? this->Close() : this->Open(); } mitk::ContourElement::VertexListType mitk::ContourElement::GetControlVertices() const { VertexListType controlVertices; - std::copy_if(this->m_Vertices.begin(), this->m_Vertices.end(), std::back_inserter(controlVertices), [](const VertexType* v) {return v->IsControlPoint; }); + std::copy_if( + this->m_Vertices.begin(), this->m_Vertices.end(), std::back_inserter(controlVertices), [](const VertexType *v) { + return v->IsControlPoint; + }); return controlVertices; } void mitk::ContourElement::Concatenate(const mitk::ContourElement *other, bool check) { if (other->GetSize() > 0) { - for (const auto& sourceVertex : other->m_Vertices) + for (const auto &sourceVertex : other->m_Vertices) { if (check) { - auto finding = std::find_if(this->m_Vertices.begin(), this->m_Vertices.end(), [sourceVertex](const VertexType* v) {return sourceVertex->Coordinates == v->Coordinates; }); + auto finding = + std::find_if(this->m_Vertices.begin(), this->m_Vertices.end(), [sourceVertex](const VertexType *v) { + return sourceVertex->Coordinates == v->Coordinates; + }); if (finding == this->m_Vertices.end()) { this->m_Vertices.push_back(new ContourModelVertex(*sourceVertex)); } } else { this->m_Vertices.push_back(new ContourModelVertex(*sourceVertex)); } } } } -mitk::ContourElement::VertexSizeType mitk::ContourElement::GetIndex(const VertexType* vertex) const +mitk::ContourElement::VertexSizeType mitk::ContourElement::GetIndex(const VertexType *vertex) const { VertexSizeType result = NPOS; auto finding = std::find(this->m_Vertices.begin(), this->m_Vertices.end(), vertex); if (finding != this->m_Vertices.end()) { result = finding - this->m_Vertices.begin(); } return result; } bool mitk::ContourElement::RemoveVertex(const VertexType *vertex) { auto finding = std::find(this->m_Vertices.begin(), this->m_Vertices.end(), vertex); return RemoveVertexByIterator(finding); } bool mitk::ContourElement::RemoveVertexAt(VertexSizeType index) { if (index >= 0 && index < this->m_Vertices.size()) { auto delIter = this->m_Vertices.begin() + index; return RemoveVertexByIterator(delIter); } return false; } bool mitk::ContourElement::RemoveVertexAt(const mitk::Point3D &point, double eps) { if (eps > 0) { - auto finding = std::find_if(this->m_Vertices.begin(), this->m_Vertices.end(), [point, eps](const VertexType* v) {return v->Coordinates.EuclideanDistanceTo(point) < eps; }); + auto finding = std::find_if(this->m_Vertices.begin(), this->m_Vertices.end(), [point, eps](const VertexType *v) { + return v->Coordinates.EuclideanDistanceTo(point) < eps; + }); return RemoveVertexByIterator(finding); } return false; } -bool mitk::ContourElement::RemoveVertexByIterator(VertexListType::iterator& iter) +bool mitk::ContourElement::RemoveVertexByIterator(VertexListType::iterator &iter) { if (iter != this->m_Vertices.end()) { - delete* iter; + delete *iter; this->m_Vertices.erase(iter); return true; } return false; } void mitk::ContourElement::Clear() { for (auto vertex : m_Vertices) { delete vertex; } this->m_Vertices.clear(); } //---------------------------------------------------------------------- void mitk::ContourElement::RedistributeControlVertices(const VertexType *selected, int period) { int counter = 0; auto _where = this->m_Vertices.begin(); if (selected != nullptr) { auto finding = std::find(this->m_Vertices.begin(), this->m_Vertices.end(), selected); if (finding != this->m_Vertices.end()) { _where = finding; } } auto _iter = _where; while (_iter != this->m_Vertices.end()) { div_t divresult; divresult = div(counter, period); (*_iter)->IsControlPoint = (divresult.rem == 0); counter++; _iter++; } _iter = _where; counter = 0; while (_iter != this->m_Vertices.begin()) { div_t divresult; divresult = div(counter, period); (*_iter)->IsControlPoint = (divresult.rem == 0); counter++; _iter--; } } diff --git a/Modules/ContourModel/DataManagement/mitkContourElement.h b/Modules/ContourModel/DataManagement/mitkContourElement.h index 42be258cc3..9a9f17186e 100644 --- a/Modules/ContourModel/DataManagement/mitkContourElement.h +++ b/Modules/ContourModel/DataManagement/mitkContourElement.h @@ -1,260 +1,289 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef _mitkContourElement_H_ #define _mitkContourElement_H_ #include "mitkCommon.h" #include <MitkContourModelExports.h> #include <mitkNumericTypes.h> #include <deque> namespace mitk { /** \brief Represents a contour in 3D space. A ContourElement is consisting of linked vertices implicitely defining the contour. They are stored in a double ended queue making it possible to add vertices at front and end of the contour and to iterate in both directions. To mark a vertex as a special one it can be set as a control point. \note This class assumes that it manages its vertices. So if a vertex instance is added to this class the ownership of the vertex is transfered to the ContourElement instance. The ContourElement instance takes care of deleting vertex instances if needed. It is highly not recommend to use this class directly as it is designed as a internal class of ContourModel. Therefore it is adviced to use ContourModel if contour representations are needed in MITK. */ class MITKCONTOURMODEL_EXPORT ContourElement : public itk::LightObject { public: mitkClassMacroItkParent(ContourElement, itk::LightObject); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** \brief Represents a single vertex of a contour. */ struct MITKCONTOURMODEL_EXPORT ContourModelVertex { ContourModelVertex(const mitk::Point3D& point, bool active = false) : IsControlPoint(active), Coordinates(point) {}; ContourModelVertex(const ContourModelVertex& other) : IsControlPoint(other.IsControlPoint), Coordinates(other.Coordinates) { }; /** \brief Treat point special. */ bool IsControlPoint; /** \brief Coordinates in 3D space. */ mitk::Point3D Coordinates; bool operator ==(const ContourModelVertex& other) const; }; using VertexType = ContourModelVertex; using VertexListType = std::deque<VertexType*>; using VertexIterator = VertexListType::iterator; using ConstVertexIterator = VertexListType::const_iterator; using VertexSizeType = VertexListType::size_type; /**Indicates an invalid index. * It is always the maximum of the unsigned int type.*/ static const VertexSizeType NPOS = -1; /** \brief Return a const iterator a the front. */ ConstVertexIterator ConstIteratorBegin() const; /** \brief Return a const iterator a the end. */ ConstVertexIterator ConstIteratorEnd() const; /** \brief Return an iterator a the front. */ VertexIterator IteratorBegin(); /** \brief Return an iterator a the end. */ VertexIterator IteratorEnd(); /** \brief Return a const iterator a the front. * For easier support of stl functionality. */ ConstVertexIterator begin() const; /** \brief Return a const iterator a the end. * For easier support of stl functionality. */ ConstVertexIterator end() const; /** \brief Return an iterator a the front. * For easier support of stl functionality. */ VertexIterator begin(); /** \brief Return an iterator a the end. * For easier support of stl functionality. */ VertexIterator end(); /** \brief Returns the number of contained vertices. */ VertexSizeType GetSize() const; /** \brief Add a vertex at the end of the contour \param point - coordinates in 3D space. \param isControlPoint - is the vertex a special control point. */ void AddVertex(const mitk::Point3D &point, bool isControlPoint); /** \brief Add a vertex at the front of the contour \param point - coordinates in 3D space. \param isControlPoint - is the vertex a control point. */ void AddVertexAtFront(const mitk::Point3D &point, bool isControlPoint); /** \brief Add a vertex at a given index of the contour \param point - coordinates in 3D space. \param isControlPoint - is the vertex a special control point. \param index - the index to be inserted at. */ void InsertVertexAtIndex(const mitk::Point3D &point, bool isControlPoint, VertexSizeType index); /** \brief Set coordinates a given index. \param pointId Index of vertex. \param point Coordinates. */ void SetVertexAt(VertexSizeType pointId, const mitk::Point3D &point); /** \brief Set vertex a given index (by copying the values). \param pointId Index of vertex. \param vertex Vertex. \pre Passed vertex is a valid instance */ void SetVertexAt(VertexSizeType pointId, const VertexType* vertex); /** \brief Returns the vertex a given index \param index \pre index must be valid. */ VertexType* GetVertexAt(VertexSizeType index); const VertexType* GetVertexAt(VertexSizeType index) const; - /** \brief Returns the approximate nearest vertex a given posoition in 3D space + /** \brief Returns the approximate nearest vertex a given position in 3D space \param point - query position in 3D space. \param eps - the error bound for search algorithm. */ VertexType *GetVertexAt(const mitk::Point3D &point, float eps); + /** \brief Returns the next vertex to the approximate nearest vertex of a given position in 3D space + \param point - query position in 3D space. + \param eps - the error bound for search algorithm. + */ + VertexType *GetNextControlVertexAt(const mitk::Point3D &point, float eps); + + /** \brief Returns the previous vertex to the approximate nearest vertex of a given position in 3D space + \param point - query position in 3D space. + \param eps - the error bound for search algorithm. + */ + VertexType *GetPreviousControlVertexAt(const mitk::Point3D &point, float eps); + + /** \brief Returns the approximate nearest control vertex a given posoition in 3D space, if the clicked position is within a specific range. + \param point - query position in 3D space. + \param eps - the error bound for search algorithm. + */ + VertexType *GetControlVertexAt(const mitk::Point3D &point, float eps); + /** \brief Returns the index of the given vertex within the contour. \param vertex - the vertex to be searched. \return index of vertex. Returns ContourElement::NPOS if not found. */ VertexSizeType GetIndex(const VertexType *vertex) const; /** \brief Returns the container of the vertices. - */ + */ const VertexListType *GetVertexList() const; /** \brief Returns whether the contour element is empty. */ bool IsEmpty() const; /** \brief Returns if the conour is closed or not. */ bool IsClosed() const; /** \brief Returns whether a given point is near a contour, according to eps. \param point - query position in 3D space. \param eps - the error bound for search algorithm. */ bool IsNearContour(const mitk::Point3D &point, float eps) const; /** \brief Close the contour. Connect first with last element. */ void Close(); /** \brief Open the contour. Disconnect first and last element. */ void Open(); /** \brief Set the contours IsClosed property. \param isClosed - true = closed; false = open; */ void SetClosed(bool isClosed); /** \brief Concatenate the contuor with a another contour. All vertices of the other contour will be cloned and added after last vertex. \param other - the other contour \param check - set it true to avoid adding of vertices that are already in the source contour */ void Concatenate(const mitk::ContourElement *other, bool check); /** \brief Remove the given vertex from the container if exists. \param vertex - the vertex to be removed. */ bool RemoveVertex(const VertexType *vertex); /** \brief Remove a vertex at given index within the container if exists. \param index - the index where the vertex should be removed. */ bool RemoveVertexAt(VertexSizeType index); /** \brief Remove the approximate nearest vertex at given position in 3D space if one exists. \param point - query point in 3D space. \param eps - error bound for search algorithm. */ bool RemoveVertexAt(const mitk::Point3D &point, double eps); /** \brief Clear the storage container. */ void Clear(); - /** \brief Returns the approximate nearest vertex a given posoition in 3D space + /** \brief Returns the approximate nearest vertex a given position in 3D space. With the parameter 'isControlPoint', + one can decide if any vertex should be returned, or just control vertices. \param point - query position in 3D space. - \param eps - the error bound for search algorithm. + \param eps - the error bound for search algorithm. It is an open boundary. + \param offset - a offset to the vertex, e.g. 1 if the next vertex should be returned or -1 for the previous vertex + */ + VertexType *BruteForceGetVertexAt(const mitk::Point3D &point, double eps, bool isControlPoint = false, int offset = 0); + + /** \brief Returns the index of the approximate nearest vertex of a given position in 3D space. + \param point - query position in 3D space. + \param eps - the error bound for search algorithm. It is an open boundary. + \param verticesList - the vertex list to search the index in, either only control vertices or all vertices */ - VertexType *BruteForceGetVertexAt(const mitk::Point3D &point, double eps); + int BruteForceGetVertexIndexAt(const mitk::Point3D &point, + double eps, + VertexListType verticesList); /** Returns a list pointing to all vertices that are indicated to be control points. \remark It is important to note, that the vertex pointers in the returned list directly point to the vertices stored interanlly. So they are still owned by the ContourElement instance that returns the list. If one wants to take over ownership, one has to clone the vertex instances. */ VertexListType GetControlVertices() const; /** \brief Uniformly redistribute control points with a given period (in number of vertices) \param vertex - the vertex around which the redistribution is done. \param period - number of vertices between control points. */ void RedistributeControlVertices(const VertexType *vertex, int period); protected: mitkCloneMacro(Self); ContourElement() = default; ContourElement(const mitk::ContourElement &other); ~ContourElement(); ContourElement& operator = (const ContourElement & other); /** Internal helper function to correctly remove the element indicated by the iterator from the list. After the call the iterator is invalid. Caller of the function must ensure that the iterator is valid!. \result Indicates if the element indicated by the iterator was removed. If iterator points to end it returns false.*/ bool RemoveVertexByIterator(VertexListType::iterator& iter); VertexListType m_Vertices; // double ended queue with vertices bool m_IsClosed = false; }; } // namespace mitk #endif // _mitkContourElement_H_ diff --git a/Modules/ContourModel/DataManagement/mitkContourModel.cpp b/Modules/ContourModel/DataManagement/mitkContourModel.cpp index d6e04cb150..02350613d6 100644 --- a/Modules/ContourModel/DataManagement/mitkContourModel.cpp +++ b/Modules/ContourModel/DataManagement/mitkContourModel.cpp @@ -1,628 +1,679 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkContourModel.h> #include <mitkPlaneGeometry.h> mitk::ContourModel::ContourModel() : m_UpdateBoundingBox(true) { // set to initial state this->InitializeEmpty(); } mitk::ContourModel::ContourModel(const ContourModel &other) : BaseData(other), m_ContourSeries(other.m_ContourSeries), m_lineInterpolation(other.m_lineInterpolation) { m_SelectedVertex = nullptr; } mitk::ContourModel::~ContourModel() { m_SelectedVertex = nullptr; this->m_ContourSeries.clear(); // TODO check destruction } void mitk::ContourModel::AddVertex(const Point3D &vertex, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->AddVertex(vertex, false, timestep); } } void mitk::ContourModel::AddVertex(const Point3D &vertex, bool isControlPoint, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->m_ContourSeries[timestep]->AddVertex(vertex, isControlPoint); this->InvokeEvent(ContourModelSizeChangeEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } } void mitk::ContourModel::AddVertex(const VertexType &vertex, TimeStepType timestep) { this->AddVertex(vertex.Coordinates, vertex.IsControlPoint, timestep); } void mitk::ContourModel::AddVertexAtFront(const Point3D &vertex, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->AddVertexAtFront(vertex, false, timestep); } } void mitk::ContourModel::AddVertexAtFront(const Point3D &vertex, bool isControlPoint, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->m_ContourSeries[timestep]->AddVertexAtFront(vertex, isControlPoint); this->InvokeEvent(ContourModelSizeChangeEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } } void mitk::ContourModel::AddVertexAtFront(const VertexType &vertex, TimeStepType timestep) { this->AddVertexAtFront(vertex.Coordinates, vertex.IsControlPoint, timestep); } bool mitk::ContourModel::SetVertexAt(int pointId, const Point3D &point, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { if (pointId >= 0 && this->m_ContourSeries[timestep]->GetSize() > ContourElement::VertexSizeType(pointId)) { this->m_ContourSeries[timestep]->SetVertexAt(pointId, point); this->Modified(); this->m_UpdateBoundingBox = true; return true; } return false; } return false; } bool mitk::ContourModel::SetVertexAt(int pointId, const VertexType *vertex, TimeStepType timestep) { if (vertex == nullptr) return false; if (!this->IsEmptyTimeStep(timestep)) { if (pointId >= 0 && this->m_ContourSeries[timestep]->GetSize() > ContourElement::VertexSizeType(pointId)) { this->m_ContourSeries[timestep]->SetVertexAt(pointId, vertex); this->Modified(); this->m_UpdateBoundingBox = true; return true; } return false; } return false; } void mitk::ContourModel::InsertVertexAtIndex(const Point3D &vertex, int index, bool isControlPoint, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { if (index >= 0 && this->m_ContourSeries[timestep]->GetSize() > ContourElement::VertexSizeType(index)) { this->m_ContourSeries[timestep]->InsertVertexAtIndex(vertex, isControlPoint, index); this->InvokeEvent(ContourModelSizeChangeEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } } } void mitk::ContourModel::UpdateContour(const ContourModel* sourceModel, TimeStepType destinationTimeStep, TimeStepType sourceTimeStep) { if (nullptr == sourceModel) { mitkThrow() << "Cannot update contour. Passed source model is invalid."; } if (!sourceModel->GetTimeGeometry()->IsValidTimeStep(sourceTimeStep)) { mitkThrow() << "Cannot update contour. Source contour time geometry does not support passed time step. Invalid time step: " << sourceTimeStep; } if (!this->GetTimeGeometry()->IsValidTimeStep(destinationTimeStep)) { MITK_WARN << "Cannot update contour. Contour time geometry does not support passed time step. Invalid time step: " << destinationTimeStep; return; } this->Clear(destinationTimeStep); std::for_each(sourceModel->Begin(sourceTimeStep), sourceModel->End(sourceTimeStep), [this, destinationTimeStep](ContourElement::VertexType* vertex) { this->m_ContourSeries[destinationTimeStep]->AddVertex(vertex->Coordinates, vertex->IsControlPoint); }); this->InvokeEvent(ContourModelSizeChangeEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } bool mitk::ContourModel::IsEmpty(TimeStepType timestep) const { if (!this->IsEmptyTimeStep(timestep)) { return this->m_ContourSeries[timestep]->IsEmpty(); } return true; } bool mitk::ContourModel::IsEmpty() const { return this->IsEmpty(0); } int mitk::ContourModel::GetNumberOfVertices(TimeStepType timestep) const { if (!this->IsEmptyTimeStep(timestep)) { return this->m_ContourSeries[timestep]->GetSize(); } return -1; } const mitk::ContourModel::VertexType *mitk::ContourModel::GetVertexAt(int index, TimeStepType timestep) const { if (!this->IsEmptyTimeStep(timestep) && this->m_ContourSeries[timestep]->GetSize() > mitk::ContourElement::VertexSizeType(index)) { return this->m_ContourSeries[timestep]->GetVertexAt(index); } return nullptr; } +const mitk::ContourModel::VertexType *mitk::ContourModel::GetNextControlVertexAt(mitk::Point3D &point, + float eps, + TimeStepType timestep) const +{ + if (!this->IsEmptyTimeStep(timestep)) + { + return this->m_ContourSeries[timestep]->GetNextControlVertexAt(point, eps); + } + return nullptr; +} + +const mitk::ContourModel::VertexType *mitk::ContourModel::GetPreviousControlVertexAt(mitk::Point3D &point, + float eps, + TimeStepType timestep) const +{ + if (!this->IsEmptyTimeStep(timestep)) + { + return this->m_ContourSeries[timestep]->GetPreviousControlVertexAt(point, eps); + } + return nullptr; +} + int mitk::ContourModel::GetIndex(const VertexType *vertex, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { return this->m_ContourSeries[timestep]->GetIndex(vertex); } return -1; } void mitk::ContourModel::Close(TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->m_ContourSeries[timestep]->Close(); this->InvokeEvent(ContourModelClosedEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } } void mitk::ContourModel::Open(TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->m_ContourSeries[timestep]->Open(); this->InvokeEvent(ContourModelClosedEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } } void mitk::ContourModel::SetClosed(bool isClosed, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->m_ContourSeries[timestep]->SetClosed(isClosed); this->InvokeEvent(ContourModelClosedEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } } bool mitk::ContourModel::IsEmptyTimeStep(unsigned int t) const { return (this->m_ContourSeries.size() <= t); } bool mitk::ContourModel::IsNearContour(Point3D &point, float eps, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { return this->m_ContourSeries[timestep]->IsNearContour(point, eps); } return false; } void mitk::ContourModel::Concatenate(ContourModel *other, TimeStepType timestep, bool check) { if (!this->IsEmptyTimeStep(timestep)) { if (!this->m_ContourSeries[timestep]->IsClosed()) { this->m_ContourSeries[timestep]->Concatenate(other->m_ContourSeries[timestep], check); this->InvokeEvent(ContourModelSizeChangeEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } } } mitk::ContourModel::VertexIterator mitk::ContourModel::Begin(TimeStepType timestep) const { return this->IteratorBegin(timestep); } mitk::ContourModel::VertexIterator mitk::ContourModel::IteratorBegin(TimeStepType timestep) const { if (!this->IsEmptyTimeStep(timestep)) { return this->m_ContourSeries[timestep]->IteratorBegin(); } else { mitkThrow() << "No iterator at invalid timestep " << timestep << ". There are only " << this->GetTimeSteps() << " timesteps available."; } } mitk::ContourModel::VertexIterator mitk::ContourModel::End(TimeStepType timestep) const { return this->IteratorEnd(timestep); } mitk::ContourModel::VertexIterator mitk::ContourModel::IteratorEnd(TimeStepType timestep) const { if (!this->IsEmptyTimeStep(timestep)) { return this->m_ContourSeries[timestep]->IteratorEnd(); } else { mitkThrow() << "No iterator at invalid timestep " << timestep << ". There are only " << this->GetTimeSteps() << " timesteps available."; } } bool mitk::ContourModel::IsClosed(int timestep) const { if (!this->IsEmptyTimeStep(timestep)) { return this->m_ContourSeries[timestep]->IsClosed(); } return false; } +bool mitk::ContourModel::SelectControlVertexAt(Point3D &point, float eps, TimeStepType timestep) +{ + if (!this->IsEmptyTimeStep(timestep)) + { + this->m_SelectedVertex = this->m_ContourSeries[timestep]->GetControlVertexAt(point, eps); + } + return this->m_SelectedVertex != nullptr; +} + bool mitk::ContourModel::SelectVertexAt(Point3D &point, float eps, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->m_SelectedVertex = this->m_ContourSeries[timestep]->GetVertexAt(point, eps); } return this->m_SelectedVertex != nullptr; } bool mitk::ContourModel::SelectVertexAt(int index, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep) && index >= 0) { return (this->m_SelectedVertex = this->m_ContourSeries[timestep]->GetVertexAt(index)); } return false; } bool mitk::ContourModel::SetControlVertexAt(Point3D &point, float eps, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { VertexType *vertex = this->m_ContourSeries[timestep]->GetVertexAt(point, eps); if (vertex != nullptr) { vertex->IsControlPoint = true; return true; } } return false; } bool mitk::ContourModel::SetControlVertexAt(int index, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep) && index >= 0) { VertexType *vertex = this->m_ContourSeries[timestep]->GetVertexAt(index); if (vertex != nullptr) { vertex->IsControlPoint = true; return true; } } return false; } bool mitk::ContourModel::RemoveVertex(const VertexType *vertex, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { if (this->m_ContourSeries[timestep]->RemoveVertex(vertex)) { this->Modified(); this->m_UpdateBoundingBox = true; this->InvokeEvent(ContourModelSizeChangeEvent()); return true; } } return false; } bool mitk::ContourModel::RemoveVertexAt(int index, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { if (this->m_ContourSeries[timestep]->RemoveVertexAt(index)) { this->Modified(); this->m_UpdateBoundingBox = true; this->InvokeEvent(ContourModelSizeChangeEvent()); return true; } } return false; } bool mitk::ContourModel::RemoveVertexAt(Point3D &point, float eps, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { if (this->m_ContourSeries[timestep]->RemoveVertexAt(point, eps)) { this->Modified(); this->m_UpdateBoundingBox = true; this->InvokeEvent(ContourModelSizeChangeEvent()); return true; } } return false; } void mitk::ContourModel::ShiftSelectedVertex(Vector3D &translate) { if (this->m_SelectedVertex) { this->ShiftVertex(this->m_SelectedVertex, translate); this->Modified(); this->m_UpdateBoundingBox = true; } } void mitk::ContourModel::ShiftContour(Vector3D &translate, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { // shift all vertices for (auto vertex : *(this->m_ContourSeries[timestep])) { this->ShiftVertex(vertex, translate); } this->Modified(); this->m_UpdateBoundingBox = true; this->InvokeEvent(ContourModelShiftEvent()); } } void mitk::ContourModel::ShiftVertex(VertexType *vertex, Vector3D &vector) { vertex->Coordinates[0] += vector[0]; vertex->Coordinates[1] += vector[1]; vertex->Coordinates[2] += vector[2]; } void mitk::ContourModel::Clear(TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { // clear data at timestep this->m_ContourSeries[timestep]->Clear(); this->Modified(); this->m_UpdateBoundingBox = true; } } void mitk::ContourModel::Expand(unsigned int timeSteps) { std::size_t oldSize = this->m_ContourSeries.size(); if (static_cast<std::size_t>(timeSteps) > oldSize) { Superclass::Expand(timeSteps); // insert contours for each new timestep for (std::size_t i = oldSize; i < static_cast<std::size_t>(timeSteps); i++) { m_ContourSeries.push_back(ContourElement::New()); } this->InvokeEvent(ContourModelExpandTimeBoundsEvent()); } } void mitk::ContourModel::SetRequestedRegionToLargestPossibleRegion() { // no support for regions } bool mitk::ContourModel::RequestedRegionIsOutsideOfTheBufferedRegion() { // no support for regions return false; } bool mitk::ContourModel::VerifyRequestedRegion() { // no support for regions return true; } void mitk::ContourModel::SetRequestedRegion(const itk::DataObject * /*data*/) { // no support for regions } void mitk::ContourModel::Clear() { // clear data and set to initial state again this->ClearData(); this->InitializeEmpty(); this->Modified(); this->m_UpdateBoundingBox = true; } void mitk::ContourModel::RedistributeControlVertices(int period, TimeStepType timestep) { if (!this->IsEmptyTimeStep(timestep)) { this->m_ContourSeries[timestep]->RedistributeControlVertices(this->GetSelectedVertex(), period); this->InvokeEvent(ContourModelClosedEvent()); this->Modified(); this->m_UpdateBoundingBox = true; } } +mitk::ContourModel::VertexListType mitk::ContourModel::GetControlVertices(TimeStepType timestep) +{ + VertexListType controlVertices; + if (!this->IsEmptyTimeStep(timestep)) + { + controlVertices = this->m_ContourSeries[timestep]->GetControlVertices(); + } + return controlVertices; +} + +mitk::ContourModel::VertexListType mitk::ContourModel::GetVertexList(TimeStepType timestep) +{ + VertexListType controlVertices; + if (!this->IsEmptyTimeStep(timestep)) + { + controlVertices = *this->m_ContourSeries[timestep]->GetVertexList(); + } + return controlVertices; +} + void mitk::ContourModel::ClearData() { // call the superclass, this releases the data of BaseData Superclass::ClearData(); // clear out the time resolved contours this->m_ContourSeries.clear(); } void mitk::ContourModel::Initialize() { this->InitializeEmpty(); this->Modified(); this->m_UpdateBoundingBox = true; } void mitk::ContourModel::Initialize(const ContourModel &other) { TimeStepType numberOfTimesteps = other.GetTimeGeometry()->CountTimeSteps(); this->InitializeTimeGeometry(numberOfTimesteps); for (TimeStepType currentTimestep = 0; currentTimestep < numberOfTimesteps; currentTimestep++) { this->m_ContourSeries.push_back(ContourElement::New()); this->SetClosed(other.IsClosed(currentTimestep), currentTimestep); } m_SelectedVertex = nullptr; this->m_lineInterpolation = other.m_lineInterpolation; this->Modified(); this->m_UpdateBoundingBox = true; } void mitk::ContourModel::InitializeEmpty() { // clear data at timesteps this->m_ContourSeries.resize(0); this->m_ContourSeries.push_back(ContourElement::New()); // set number of timesteps to one this->InitializeTimeGeometry(1); m_SelectedVertex = nullptr; this->m_lineInterpolation = ContourModel::LINEAR; } void mitk::ContourModel::UpdateOutputInformation() { if (this->GetSource()) { this->GetSource()->UpdateOutputInformation(); } if (this->m_UpdateBoundingBox) { // update the bounds of the geometry according to the stored vertices ScalarType mitkBounds[6]; // calculate the boundingbox at each timestep typedef itk::BoundingBox<unsigned long, 3, ScalarType> BoundingBoxType; typedef BoundingBoxType::PointsContainer PointsContainer; int timesteps = this->GetTimeSteps(); // iterate over the timesteps for (int currenTimeStep = 0; currenTimeStep < timesteps; currenTimeStep++) { if (dynamic_cast<PlaneGeometry *>(this->GetGeometry(currenTimeStep))) { // do not update bounds for 2D geometries, as they are unfortunately defined with min bounds 0! return; } else { // we have a 3D geometry -> let's update bounds // only update bounds if the contour was modified if (this->GetMTime() > this->GetGeometry(currenTimeStep)->GetBoundingBox()->GetMTime()) { mitkBounds[0] = 0.0; mitkBounds[1] = 0.0; mitkBounds[2] = 0.0; mitkBounds[3] = 0.0; mitkBounds[4] = 0.0; mitkBounds[5] = 0.0; BoundingBoxType::Pointer boundingBox = BoundingBoxType::New(); PointsContainer::Pointer points = PointsContainer::New(); auto it = this->IteratorBegin(currenTimeStep); auto end = this->IteratorEnd(currenTimeStep); // fill the boundingbox with the points while (it != end) { Point3D currentP = (*it)->Coordinates; BoundingBoxType::PointType p; p.CastFrom(currentP); points->InsertElement(points->Size(), p); it++; } // construct the new boundingBox boundingBox->SetPoints(points); boundingBox->ComputeBoundingBox(); BoundingBoxType::BoundsArrayType tmp = boundingBox->GetBounds(); mitkBounds[0] = tmp[0]; mitkBounds[1] = tmp[1]; mitkBounds[2] = tmp[2]; mitkBounds[3] = tmp[3]; mitkBounds[4] = tmp[4]; mitkBounds[5] = tmp[5]; // set boundingBox at current timestep BaseGeometry *geometry3d = this->GetGeometry(currenTimeStep); geometry3d->SetBounds(mitkBounds); } } } this->m_UpdateBoundingBox = false; } GetTimeGeometry()->Update(); } void mitk::ContourModel::ExecuteOperation(Operation * /*operation*/) { // not supported yet } diff --git a/Modules/ContourModel/DataManagement/mitkContourModel.h b/Modules/ContourModel/DataManagement/mitkContourModel.h index d234d9cefb..f42452d056 100644 --- a/Modules/ContourModel/DataManagement/mitkContourModel.h +++ b/Modules/ContourModel/DataManagement/mitkContourModel.h @@ -1,437 +1,467 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef _MITK_CONTOURMODEL_H_ #define _MITK_CONTOURMODEL_H_ #include "mitkBaseData.h" #include "mitkCommon.h" #include <MitkContourModelExports.h> #include <mitkContourElement.h> namespace mitk { /** \brief ContourModel is a structure of linked vertices defining a contour in 3D space. The vertices are stored in a mitk::ContourElement is stored for each timestep. The contour line segments are implicitly defined by the given linked vertices. By default two control points are are linked by a straight line.It is possible to add vertices at front and end of the contour and to iterate in both directions. Points are specified containing coordinates and additional (data) information, see mitk::ContourElement. For accessing a specific vertex either an index or a position in 3D Space can be used. The vertices are best accessed by using a VertexIterator. Interaction with the contour is thus available without any mitk interactor class using the api of ContourModel. It is possible to shift single vertices also as shifting the whole contour. A contour can be either open like a single curved line segment or closed. A closed contour can for example represent a jordan curve. \section mitkContourModelDisplayOptions Display Options The default mappers for this data structure are mitk::ContourModelGLMapper2D and mitk::ContourModelMapper3D. See these classes for display options which can can be set via properties. */ class MITKCONTOURMODEL_EXPORT ContourModel : public BaseData { public: mitkClassMacro(ContourModel, BaseData); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /*+++++++++++++++ typedefs +++++++++++++++++++++++++++++++*/ typedef ContourElement::VertexType VertexType; typedef ContourElement::VertexListType VertexListType; typedef ContourElement::VertexIterator VertexIterator; typedef ContourElement::ConstVertexIterator ConstVertexIterator; typedef std::vector<ContourElement::Pointer> ContourModelSeries; /*+++++++++++++++ END typedefs ++++++++++++++++++++++++++++*/ /** \brief Possible interpolation of the line segments between control points */ enum LineSegmentInterpolation { LINEAR, B_SPLINE }; /*++++++++++++++++ inline methods +++++++++++++++++++++++*/ /** \brief Get the current selected vertex. */ VertexType *GetSelectedVertex() { return this->m_SelectedVertex; } /** \brief Deselect vertex. */ void Deselect() { this->m_SelectedVertex = nullptr; } /** \brief Set selected vertex as control point */ void SetSelectedVertexAsControlPoint(bool isControlPoint = true) { if (this->m_SelectedVertex) { m_SelectedVertex->IsControlPoint = isControlPoint; this->Modified(); } } /** \brief Set the interpolation of the line segments between control points. */ void SetLineSegmentInterpolation(LineSegmentInterpolation interpolation) { this->m_lineInterpolation = interpolation; this->Modified(); } /** \brief Get the interpolation of the line segments between control points. */ LineSegmentInterpolation GetLineSegmentInterpolation() { return this->m_lineInterpolation; } /*++++++++++++++++ END inline methods +++++++++++++++++++++++*/ /** \brief Add a vertex to the contour at given timestep. The vertex is added at the end of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertex(const Point3D &vertex, TimeStepType timestep = 0); /** \brief Add a vertex to the contour at given timestep. A copy of the passed vertex is added at the end of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertex(const VertexType &vertex, TimeStepType timestep = 0); /** \brief Add a vertex to the contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) \param isControlPoint - specifies the vertex to be handled in a special way (e.g. control points will be rendered). @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertex(const Point3D& vertex, bool isControlPoint, TimeStepType timestep = 0); /** Clears the contour of destinationTimeStep and copies the contour of the passed source model at the sourceTimeStep. @pre soureModel must point to a valid instance @pre sourceTimePoint must be valid @note Updateing a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void UpdateContour(const ContourModel* sourceModel, TimeStepType destinationTimeStep, TimeStepType sourceTimeStep); /** \brief Add a vertex to the contour at given timestep AT THE FRONT of the contour. The vertex is added at the FRONT of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertexAtFront(const Point3D &vertex, TimeStepType timestep = 0); /** \brief Add a vertex to the contour at given timestep AT THE FRONT of the contour. The vertex is added at the FRONT of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertexAtFront(const VertexType &vertex, TimeStepType timestep = 0); /** \brief Add a vertex to the contour at given timestep AT THE FRONT of the contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) \param isControlPoint - specifies the vertex to be handled in a special way (e.g. control points will be rendered). @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertexAtFront(const Point3D &vertex, bool isControlPoint, TimeStepType timestep = 0); /** \brief Insert a vertex at given index. */ void InsertVertexAtIndex(const Point3D &vertex, int index, bool isControlPoint = false, TimeStepType timestep = 0); /** \brief Set a coordinates for point at given index. */ bool SetVertexAt(int pointId, const Point3D &point, TimeStepType timestep = 0); /** \brief Set a coordinates and control state for point at given index. */ bool SetVertexAt(int pointId, const VertexType *vertex, TimeStepType timestep = 0); /** \brief Return if the contour is closed or not. */ bool IsClosed(int timestep = 0) const; /** \brief Concatenate two contours. The starting control point of the other will be added at the end of the contour. \param other \param timestep - the timestep at which the vertex will be add ( default 0) \param check - check for intersections ( default false) */ void Concatenate(ContourModel *other, TimeStepType timestep = 0, bool check = false); /** \brief Returns a const VertexIterator at the start element of the contour. @throw mitk::Exception if the timestep is invalid. */ VertexIterator Begin(TimeStepType timestep = 0) const; /** \brief Returns a const VertexIterator at the start element of the contour. @throw mitk::Exception if the timestep is invalid. */ VertexIterator IteratorBegin(TimeStepType timestep = 0) const; /** \brief Returns a const VertexIterator at the end element of the contour. @throw mitk::Exception if the timestep is invalid. */ VertexIterator End(TimeStepType timestep = 0) const; /** \brief Returns a const VertexIterator at the end element of the contour. @throw mitk::Exception if the timestep is invalid. */ VertexIterator IteratorEnd(TimeStepType timestep = 0) const; /** \brief Close the contour. The last control point will be linked with the first point. */ virtual void Close(TimeStepType timestep = 0); /** \brief Set isClosed to false contour. The link between the last control point the first point will be removed. */ virtual void Open(TimeStepType timestep = 0); /** \brief Set closed property to given boolean. false - The link between the last control point the first point will be removed. true - The last control point will be linked with the first point. */ virtual void SetClosed(bool isClosed, TimeStepType timestep = 0); /** \brief Returns the number of vertices at a given timestep. \param timestep - default = 0 */ int GetNumberOfVertices(TimeStepType timestep = 0) const; /** \brief Returns whether the contour model is empty at a given timestep. \param timestep - default = 0 */ virtual bool IsEmpty(TimeStepType timestep) const; /** \brief Returns whether the contour model is empty. */ bool IsEmpty() const override; /** \brief Returns the vertex at the index position within the container. * If the index or timestep is invalid a nullptr will be returned. */ virtual const VertexType *GetVertexAt(int index, TimeStepType timestep = 0) const; + /** Returns the next control vertex to the approximate nearest vertex of a given position in 3D space + * If the timestep is invalid a nullptr will be returned. + */ + virtual const VertexType *GetNextControlVertexAt(mitk::Point3D &point, float eps, TimeStepType timestep) const; + + /** Returns the previous control vertex to the approximate nearest vertex of a given position in 3D space + * If the timestep is invalid a nullptr will be returned. + */ + virtual const VertexType *GetPreviousControlVertexAt(mitk::Point3D &point, float eps, TimeStepType timestep) const; + /** \brief Remove a vertex at given timestep within the container. \return index of vertex. -1 if not found. */ int GetIndex(const VertexType *vertex, TimeStepType timestep = 0); /** \brief Check if there isn't something at this timestep. */ bool IsEmptyTimeStep(unsigned int t) const override; /** \brief Check if mouse cursor is near the contour. */ virtual bool IsNearContour(Point3D &point, float eps, TimeStepType timestep); + /** \brief Mark a vertex at an index in the container as selected. - */ + */ bool SelectVertexAt(int index, TimeStepType timestep = 0); /** \brief Mark a vertex at an index in the container as control point. */ bool SetControlVertexAt(int index, TimeStepType timestep = 0); + /** \brief Mark a control vertex at a given position in 3D space. + + \param point - query point in 3D space + \param eps - radius for nearest neighbour search (error bound). + \param timestep - search at this timestep + + @return true = vertex found; false = no vertex found + */ + bool SelectControlVertexAt(Point3D &point, float eps, TimeStepType timestep = 0); + /** \brief Mark a vertex at a given position in 3D space. \param point - query point in 3D space \param eps - radius for nearest neighbour search (error bound). \param timestep - search at this timestep @return true = vertex found; false = no vertex found */ bool SelectVertexAt(Point3D &point, float eps, TimeStepType timestep = 0); + /* \pararm point - query point in 3D space \pararm eps - radius for nearest neighbour search (error bound). \pararm timestep - search at this timestep @return true = vertex found; false = no vertex found */ bool SetControlVertexAt(Point3D &point, float eps, TimeStepType timestep = 0); /** \brief Remove a vertex at given index within the container. @return true = the vertex was successfuly removed; false = wrong index. */ bool RemoveVertexAt(int index, TimeStepType timestep = 0); /** \brief Remove a vertex at given timestep within the container. @return true = the vertex was successfuly removed. */ bool RemoveVertex(const VertexType *vertex, TimeStepType timestep = 0); /** \brief Remove a vertex at a query position in 3D space. The vertex to be removed will be search by nearest neighbour search. Note that possibly no vertex at this position and eps is stored inside the contour. @return true = the vertex was successfuly removed; false = no vertex found. */ bool RemoveVertexAt(Point3D &point, float eps, TimeStepType timestep = 0); /** \brief Shift the currently selected vertex by a translation vector. \param translate - the translation vector. */ void ShiftSelectedVertex(Vector3D &translate); /** \brief Shift the whole contour by a translation vector at given timestep. \param translate - the translation vector. \param timestep - at this timestep the contour will be shifted. */ void ShiftContour(Vector3D &translate, TimeStepType timestep = 0); /** \brief Clear the storage container at given timestep. All control points are removed at timestep. */ virtual void Clear(TimeStepType timestep); /** \brief Initialize all data objects */ void Initialize() override; /** \brief Initialize object with specs of other contour. Note: No data will be copied. */ void Initialize(const ContourModel &other); + /** \brief Returns a list pointing to all vertices that are indicated to be control points. + */ + VertexListType GetControlVertices(TimeStepType timestep); + + /** \brief Returns the container of the vertices. + */ + VertexListType GetVertexList(TimeStepType timestep); + /*++++++++++++++++++ method inherit from base data +++++++++++++++++++++++++++*/ /** \brief Inherit from base data - no region support available for contourModel objects. */ void SetRequestedRegionToLargestPossibleRegion() override; /** \brief Inherit from base data - no region support available for contourModel objects. */ bool RequestedRegionIsOutsideOfTheBufferedRegion() override; /** \brief Inherit from base data - no region support available for contourModel objects. */ bool VerifyRequestedRegion() override; /** \brief Inherit from base data - no region support available for contourModel objects. */ void SetRequestedRegion(const itk::DataObject *data) override; /** \brief Expand the contour model and its TimeGeometry to given number of timesteps. */ void Expand(unsigned int timeSteps) override; /** \brief Update the OutputInformation of a ContourModel object The BoundingBox of the contour will be updated, if necessary. */ void UpdateOutputInformation() override; /** \brief Clear the storage container. The object is set to initial state. All control points are removed and the number of timesteps are set to 1. */ void Clear() override; /** \brief overwrite if the Data can be called by an Interactor (StateMachine). */ void ExecuteOperation(Operation *operation) override; /** \brief Redistributes ontrol vertices with a given period (as number of vertices) \param period - the number of vertices between control points. \param timestep - at this timestep all lines will be rebuilt. */ virtual void RedistributeControlVertices(int period, TimeStepType timestep); protected: mitkCloneMacro(Self); ContourModel(); ContourModel(const ContourModel &other); ~ContourModel() override; // inherit from BaseData. called by Clear() void ClearData() override; // inherit from BaseData. Initial state of a contour with no vertices and a single timestep. void InitializeEmpty() override; // Shift a vertex static void ShiftVertex(VertexType *vertex, Vector3D &vector); // Storage with time resolved support. ContourModelSeries m_ContourSeries; // The currently selected vertex. VertexType *m_SelectedVertex; // The interpolation of the line segment between control points. LineSegmentInterpolation m_lineInterpolation; // only update the bounding geometry if necessary bool m_UpdateBoundingBox; }; itkEventMacro(ContourModelEvent, itk::AnyEvent); itkEventMacro(ContourModelShiftEvent, ContourModelEvent); itkEventMacro(ContourModelSizeChangeEvent, ContourModelEvent); itkEventMacro(ContourModelAddEvent, ContourModelSizeChangeEvent); itkEventMacro(ContourModelRemoveEvent, ContourModelSizeChangeEvent); itkEventMacro(ContourModelExpandTimeBoundsEvent, ContourModelEvent); itkEventMacro(ContourModelClosedEvent, ContourModelEvent); } #endif diff --git a/Modules/Core/TestingHelper/src/mitkInteractionTestHelper.cpp b/Modules/Core/TestingHelper/src/mitkInteractionTestHelper.cpp index cd3d5ebcce..e908256b1f 100644 --- a/Modules/Core/TestingHelper/src/mitkInteractionTestHelper.cpp +++ b/Modules/Core/TestingHelper/src/mitkInteractionTestHelper.cpp @@ -1,435 +1,436 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // MITK #include <mitkIOUtil.h> #include <mitkInteractionEventConst.h> #include <mitkInteractionTestHelper.h> #include <mitkPlaneGeometryDataMapper2D.h> #include <mitkStandaloneDataStorage.h> // VTK #include <vtkCamera.h> #include <vtkRenderWindowInteractor.h> // us #include <usGetModuleContext.h> #include <tinyxml2.h> mitk::InteractionTestHelper::InteractionTestHelper(const std::string &interactionXmlFilePath) : m_InteractionFilePath(interactionXmlFilePath) { this->Initialize(interactionXmlFilePath); } void mitk::InteractionTestHelper::Initialize(const std::string &interactionXmlFilePath) { tinyxml2::XMLDocument document; if (tinyxml2::XML_SUCCESS == document.LoadFile(interactionXmlFilePath.c_str())) { // get RenderingManager instance auto rm = mitk::RenderingManager::GetInstance(); // create data storage m_DataStorage = mitk::StandaloneDataStorage::New(); // for each renderer found create a render window and configure for (auto *element = document.FirstChildElement(mitk::InteractionEventConst::xmlTagInteractions().c_str()) ->FirstChildElement(mitk::InteractionEventConst::xmlTagConfigRoot().c_str()) ->FirstChildElement(mitk::InteractionEventConst::xmlTagRenderer().c_str()); element != nullptr; element = element->NextSiblingElement(mitk::InteractionEventConst::xmlTagRenderer().c_str())) { // get name of renderer const char *rendererName = element->Attribute(mitk::InteractionEventConst::xmlEventPropertyRendererName().c_str()); // get view direction mitk::SliceNavigationController::ViewDirection viewDirection = mitk::SliceNavigationController::Axial; if (element->Attribute(mitk::InteractionEventConst::xmlEventPropertyViewDirection().c_str()) != nullptr) { int viewDirectionNum = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyViewDirection().c_str())); viewDirection = static_cast<mitk::SliceNavigationController::ViewDirection>(viewDirectionNum); } // get mapper slot id mitk::BaseRenderer::MapperSlotId mapperID = mitk::BaseRenderer::Standard2D; if (element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID().c_str()) != nullptr) { int mapperIDNum = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID().c_str())); mapperID = static_cast<mitk::BaseRenderer::MapperSlotId>(mapperIDNum); } // Get Size of Render Windows int size[3]; size[0] = size[1] = size[2] = 0; if (element->Attribute(mitk::InteractionEventConst::xmlRenderSizeX().c_str()) != nullptr) { size[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeX().c_str())); } if (element->Attribute(mitk::InteractionEventConst::xmlRenderSizeY().c_str()) != nullptr) { size[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeY().c_str())); } if (element->Attribute(mitk::InteractionEventConst::xmlRenderSizeZ().c_str()) != nullptr) { size[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeZ().c_str())); } // create renderWindow, renderer and dispatcher auto rw = RenderWindow::New(nullptr, rendererName); // VtkRenderWindow is created within constructor if nullptr if (size[0] != 0 && size[1] != 0) { rw->SetSize(size[0], size[1]); rw->GetRenderer()->Resize(size[0], size[1]); } // set storage of renderer rw->GetRenderer()->SetDataStorage(m_DataStorage); // set view direction to axial rw->GetSliceNavigationController()->SetDefaultViewDirection(viewDirection); // set renderer to render 2D rw->GetRenderer()->SetMapperID(mapperID); rw->GetRenderer()->PrepareRender(); // Some more magic for the 3D render window case: // Camera view direction, position and focal point if (mapperID == mitk::BaseRenderer::Standard3D) { if (element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointX().c_str()) != nullptr) { double cameraFocalPoint[3]; cameraFocalPoint[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointX().c_str())); cameraFocalPoint[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointY().c_str())); cameraFocalPoint[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointZ().c_str())); rw->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetFocalPoint(cameraFocalPoint); } if (element->Attribute(mitk::InteractionEventConst::xmlCameraPositionX().c_str()) != nullptr) { double cameraPosition[3]; cameraPosition[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionX().c_str())); cameraPosition[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionY().c_str())); cameraPosition[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionZ().c_str())); rw->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetPosition(cameraPosition); } if (element->Attribute(mitk::InteractionEventConst::xmlViewUpX().c_str()) != nullptr) { double viewUp[3]; viewUp[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpX().c_str())); viewUp[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpY().c_str())); viewUp[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpZ().c_str())); rw->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetViewUp(viewUp); } } rw->GetVtkRenderWindow()->Render(); rw->GetVtkRenderWindow()->WaitForCompletion(); // connect SliceNavigationControllers to timestep changed event of TimeNavigationController rw->GetSliceNavigationController()->ConnectGeometryTimeEvent(rm->GetTimeNavigationController(), false); rm->GetTimeNavigationController()->ConnectGeometryTimeEvent(rw->GetSliceNavigationController(), false); // add to list of known render windows m_RenderWindowList.push_back(rw); } // TODO: check the following lines taken from QmitkStdMultiWidget and adapt them to be executed in our code here. // mitkWidget1->GetSliceNavigationController() // ->ConnectGeometrySendEvent(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); // register interaction event obserer to handle scroll events InitializeDisplayActionEventHandling(); } else { mitkThrow() << "Can not load interaction xml file <" << m_InteractionFilePath << ">"; } // WARNING assumes a 3D window exists !!!! this->AddDisplayPlaneSubTree(); } void mitk::InteractionTestHelper::InitializeDisplayActionEventHandling() { m_DisplayActionEventBroadcast = mitk::DisplayActionEventBroadcast::New(); m_DisplayActionEventBroadcast->LoadStateMachine("DisplayInteraction.xml"); - m_DisplayActionEventBroadcast->SetEventConfig("DisplayConfigMITK.xml"); + m_DisplayActionEventBroadcast->SetEventConfig("DisplayConfigMITKBase.xml"); + m_DisplayActionEventBroadcast->AddEventConfig("DisplayConfigCrosshair.xml"); } mitk::InteractionTestHelper::~InteractionTestHelper() { mitk::RenderingManager *rm = mitk::RenderingManager::GetInstance(); // unregister renderers auto it = m_RenderWindowList.begin(); auto end = m_RenderWindowList.end(); for (; it != end; ++it) { rm->GetTimeNavigationController()->Disconnect((*it)->GetSliceNavigationController()); (*it)->GetSliceNavigationController()->Disconnect(rm->GetTimeNavigationController()); mitk::BaseRenderer::RemoveInstance((*it)->GetVtkRenderWindow()); } rm->RemoveAllObservers(); } mitk::DataStorage::Pointer mitk::InteractionTestHelper::GetDataStorage() { return m_DataStorage; } void mitk::InteractionTestHelper::AddNodeToStorage(mitk::DataNode::Pointer node) { this->m_DataStorage->Add(node); this->Set3dCameraSettings(); } void mitk::InteractionTestHelper::PlaybackInteraction() { mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(m_DataStorage); // load events if not loaded yet if (m_Events.empty()) this->LoadInteraction(); auto it = m_RenderWindowList.begin(); auto end = m_RenderWindowList.end(); for (; it != end; ++it) { (*it)->GetRenderer()->PrepareRender(); (*it)->GetVtkRenderWindow()->Render(); (*it)->GetVtkRenderWindow()->WaitForCompletion(); } mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(m_DataStorage); it = m_RenderWindowList.begin(); for (; it != end; ++it) { (*it)->GetVtkRenderWindow()->Render(); (*it)->GetVtkRenderWindow()->WaitForCompletion(); } // mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); // playback all events in queue for (unsigned long i = 0; i < m_Events.size(); ++i) { // let dispatcher of sending renderer process the event m_Events.at(i)->GetSender()->GetDispatcher()->ProcessEvent(m_Events.at(i)); } if (false) { it--; (*it)->GetVtkRenderWindow()->GetInteractor()->Start(); } } void mitk::InteractionTestHelper::LoadInteraction() { // load interaction pattern from xml file std::ifstream xmlStream(m_InteractionFilePath.c_str()); mitk::XML2EventParser parser(xmlStream); m_Events = parser.GetInteractions(); xmlStream.close(); // Avoid VTK warning: Trying to delete object with non-zero reference count. parser.SetReferenceCount(0); } void mitk::InteractionTestHelper::SetTimeStep(int newTimeStep) { mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(m_DataStorage); bool timeStepIsvalid = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetCreatedWorldGeometry()->IsValidTimeStep( newTimeStep); if (timeStepIsvalid) { mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime()->SetPos(newTimeStep); } } mitk::RenderWindow *mitk::InteractionTestHelper::GetRenderWindowByName(const std::string &name) { auto it = m_RenderWindowList.begin(); auto end = m_RenderWindowList.end(); for (; it != end; ++it) { if (name.compare((*it)->GetRenderer()->GetName()) == 0) return (*it).GetPointer(); } return nullptr; } mitk::RenderWindow *mitk::InteractionTestHelper::GetRenderWindowByDefaultViewDirection( mitk::SliceNavigationController::ViewDirection viewDirection) { auto it = m_RenderWindowList.begin(); auto end = m_RenderWindowList.end(); for (; it != end; ++it) { if (viewDirection == (*it)->GetSliceNavigationController()->GetDefaultViewDirection()) return (*it).GetPointer(); } return nullptr; } mitk::RenderWindow *mitk::InteractionTestHelper::GetRenderWindow(unsigned int index) { if (index < m_RenderWindowList.size()) { return m_RenderWindowList.at(index).GetPointer(); } else { return nullptr; } } void mitk::InteractionTestHelper::AddDisplayPlaneSubTree() { // add the displayed planes of the multiwidget to a node to which the subtree // @a planesSubTree points ... mitk::PlaneGeometryDataMapper2D::Pointer mapper; mitk::IntProperty::Pointer layer = mitk::IntProperty::New(1000); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetProperty("name", mitk::StringProperty::New("Widgets")); node->SetProperty("helper object", mitk::BoolProperty::New(true)); m_DataStorage->Add(node); for (auto it : m_RenderWindowList) { if (it->GetRenderer()->GetMapperID() == BaseRenderer::Standard3D) continue; // ... of widget 1 mitk::DataNode::Pointer planeNode1 = (mitk::BaseRenderer::GetInstance(it->GetVtkRenderWindow()))->GetCurrentWorldPlaneGeometryNode(); planeNode1->SetProperty("visible", mitk::BoolProperty::New(true)); planeNode1->SetProperty("name", mitk::StringProperty::New("widget1Plane")); planeNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); planeNode1->SetProperty("helper object", mitk::BoolProperty::New(true)); planeNode1->SetProperty("layer", layer); planeNode1->SetColor(1.0, 0.0, 0.0); mapper = mitk::PlaneGeometryDataMapper2D::New(); planeNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper); m_DataStorage->Add(planeNode1, node); } } void mitk::InteractionTestHelper::Set3dCameraSettings() { tinyxml2::XMLDocument document; if (tinyxml2::XML_SUCCESS == document.LoadFile(m_InteractionFilePath.c_str())) { // for each renderer found create a render window and configure for (auto *element = document.FirstChildElement(mitk::InteractionEventConst::xmlTagInteractions().c_str()) ->FirstChildElement(mitk::InteractionEventConst::xmlTagConfigRoot().c_str()) ->FirstChildElement(mitk::InteractionEventConst::xmlTagRenderer().c_str()); element != nullptr; element = element->NextSiblingElement(mitk::InteractionEventConst::xmlTagRenderer().c_str())) { // get name of renderer const char *rendererName = element->Attribute(mitk::InteractionEventConst::xmlEventPropertyRendererName().c_str()); // get mapper slot id mitk::BaseRenderer::MapperSlotId mapperID = mitk::BaseRenderer::Standard2D; if (element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID().c_str()) != nullptr) { int mapperIDNum = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID().c_str())); mapperID = static_cast<mitk::BaseRenderer::MapperSlotId>(mapperIDNum); } if (mapperID == mitk::BaseRenderer::Standard3D) { RenderWindow *namedRenderer = nullptr; for (const auto &it : m_RenderWindowList) { if (strcmp(it->GetRenderer()->GetName(), rendererName) == 0) { namedRenderer = it.GetPointer(); break; } } if (namedRenderer == nullptr) { MITK_ERROR << "No match for render window was found."; return; } namedRenderer->GetRenderer()->PrepareRender(); if (element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointX().c_str()) != nullptr) { double cameraFocalPoint[3]; cameraFocalPoint[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointX().c_str())); cameraFocalPoint[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointY().c_str())); cameraFocalPoint[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointZ().c_str())); namedRenderer->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetFocalPoint(cameraFocalPoint); } if (element->Attribute(mitk::InteractionEventConst::xmlCameraPositionX().c_str()) != nullptr) { double cameraPosition[3]; cameraPosition[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionX().c_str())); cameraPosition[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionY().c_str())); cameraPosition[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionZ().c_str())); namedRenderer->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetPosition(cameraPosition); } if (element->Attribute(mitk::InteractionEventConst::xmlViewUpX().c_str()) != nullptr) { double viewUp[3]; viewUp[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpX().c_str())); viewUp[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpY().c_str())); viewUp[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpZ().c_str())); namedRenderer->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetViewUp(viewUp); } namedRenderer->GetVtkRenderWindow()->Render(); } } } } diff --git a/Modules/Core/files.cmake b/Modules/Core/files.cmake index 8faabae848..fd48d9ca2c 100644 --- a/Modules/Core/files.cmake +++ b/Modules/Core/files.cmake @@ -1,327 +1,326 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkCoreActivator.cpp mitkCoreObjectFactoryBase.cpp mitkCoreObjectFactory.cpp mitkCoreServices.cpp mitkException.cpp Algorithms/mitkBaseDataSource.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkCompositePixelValueToString.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkExtractSliceFilter2.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkTemporalJoinImagesFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkAnatomicalStructureColorPresets.cpp DataManagement/mitkArbitraryTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseGeometry.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataStorage.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGeometryTransformHolder.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkGenericIDRelationRule.cpp DataManagement/mitkIdentifiable.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageReadAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageVtkReadAccessor.cpp DataManagement/mitkImageVtkWriteAccessor.cpp DataManagement/mitkImageWriteAccessor.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkIPersistenceService.cpp DataManagement/mitkIPropertyAliases.cpp DataManagement/mitkIPropertyDescriptions.cpp DataManagement/mitkIPropertyExtensions.cpp DataManagement/mitkIPropertyFilters.cpp DataManagement/mitkIPropertyOwner.cpp DataManagement/mitkIPropertyPersistence.cpp DataManagement/mitkIPropertyProvider.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLine.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMaterial.cpp DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModifiedLock.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDataUID.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateFunction.cpp DataManagement/mitkNodePredicateGeometry.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateDataProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkNodePredicateSubGeometry.cpp DataManagement/mitkNumericConstants.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneGeometryData.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkPropertyKeyPath.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyListReplacedObserver.cpp DataManagement/mitkPropertyNameHelper.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkPropertyPersistence.cpp DataManagement/mitkPropertyPersistenceInfo.cpp DataManagement/mitkPropertyRelationRuleBase.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkScaleOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkSourceImageRelationRule.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTemporoSpatialStringProperty.cpp DataManagement/mitkUIDManipulator.cpp DataManagement/mitkVector.cpp DataManagement/mitkVectorProperty.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkIPropertyRelations.cpp DataManagement/mitkPropertyRelations.cpp Interactions/mitkAction.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayActionEventBroadcast.cpp Interactions/mitkDisplayActionEventFunctions.cpp Interactions/mitkDisplayActionEventHandler.cpp Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp Interactions/mitkDisplayActionEventHandlerStd.cpp Interactions/mitkDisplayActionEventHandlerSynchronized.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventFactory.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkInteractionEventObserver.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionSchemeSwitcher.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkSinglePointDataInteractor.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkXML2EventParser.cpp IO/mitkAbstractFileIO.cpp IO/mitkAbstractFileReader.cpp IO/mitkAbstractFileWriter.cpp IO/mitkCustomMimeType.cpp IO/mitkFileReader.cpp IO/mitkFileReaderRegistry.cpp IO/mitkFileReaderSelector.cpp IO/mitkFileReaderWriterBase.cpp IO/mitkFileWriter.cpp IO/mitkFileWriterRegistry.cpp IO/mitkFileWriterSelector.cpp IO/mitkGeometry3DToXML.cpp IO/mitkIFileIO.cpp IO/mitkIFileReader.cpp IO/mitkIFileWriter.cpp IO/mitkGeometryDataReaderService.cpp IO/mitkGeometryDataWriterService.cpp IO/mitkImageGenerator.cpp IO/mitkImageVtkLegacyIO.cpp IO/mitkImageVtkXmlIO.cpp IO/mitkIMimeTypeProvider.cpp IO/mitkIOConstants.cpp IO/mitkIOMimeTypes.cpp IO/mitkIOUtil.cpp IO/mitkItkImageIO.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkLegacyFileReaderService.cpp IO/mitkLegacyFileWriterService.cpp IO/mitkLocaleSwitch.cpp IO/mitkLog.cpp IO/mitkMimeType.cpp IO/mitkMimeTypeProvider.cpp IO/mitkOperation.cpp IO/mitkPixelType.cpp IO/mitkPointSetReaderService.cpp IO/mitkPointSetWriterService.cpp IO/mitkProportionalTimeGeometryToXML.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSurfaceStlIO.cpp IO/mitkSurfaceVtkIO.cpp IO/mitkSurfaceVtkLegacyIO.cpp IO/mitkSurfaceVtkXmlIO.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkPreferenceListReaderOptionsFunctor.cpp IO/mitkIOMetaInformationPropertyConstants.cpp Rendering/mitkAbstractAnnotationRenderer.cpp Rendering/mitkAnnotationUtils.cpp Rendering/mitkBaseRenderer.cpp #Rendering/mitkGLMapper.cpp Moved to deprecated LegacyGL Module Rendering/mitkGradientBackground.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/mitkMapper.cpp Rendering/mitkAnnotation.cpp Rendering/mitkPlaneGeometryDataMapper2D.cpp Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowFrame.cpp #Rendering/mitkSurfaceGLMapper2D.cpp Moved to deprecated LegacyGL Module Rendering/mitkSurfaceVtkMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml -Interactions/DisplayConfigPACS.xml -Interactions/DisplayConfigPACSCrosshair.xml +Interactions/DisplayConfigMITKBase.xml +Interactions/DisplayConfigPACSBase.xml +Interactions/DisplayConfigCrosshair.xml +Interactions/DisplayConfigRotation.xml +Interactions/DisplayConfigActivateCoupling.xml +Interactions/DisplayConfigSwivel.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml -Interactions/DisplayConfigMITK.xml -Interactions/DisplayConfigMITKNoCrosshair.xml -Interactions/DisplayConfigMITKRotation.xml -Interactions/DisplayConfigMITKRotationUnCoupled.xml -Interactions/DisplayConfigMITKSwivel.xml Interactions/DisplayConfigMITKLimited.xml Interactions/DisplayConfigBlockLMB.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml mitkAnatomicalStructureColorPresets.xml ) diff --git a/Modules/Core/include/mitkCommon.h b/Modules/Core/include/mitkCommon.h index be1abe9faa..1fd400dfaf 100644 --- a/Modules/Core/include/mitkCommon.h +++ b/Modules/Core/include/mitkCommon.h @@ -1,200 +1,196 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITK_COMMON_H_DEFINED #define MITK_COMMON_H_DEFINED #ifdef _MSC_VER // This warns about truncation to 255 characters in debug/browse info #pragma warning(disable : 4786) #pragma warning(disable : 4068) /* disable unknown pragma warnings */ #endif // add only those headers here that are really necessary for all classes! #include "itkObject.h" #include "mitkConfig.h" #include "mitkExceptionMacro.h" #include "mitkGetClassHierarchy.h" #include "mitkLogMacros.h" -#ifndef MITK_UNMANGLE_IPPIC -#define mitkIpPicDescriptor mitkIpPicDescriptor -#endif - typedef unsigned int MapperSlotId; /** From ITK 4.7 version, the TypeMacro overrides (by using the explicit attribute) the GetNameOfClass * hence the SuperClass must provide one. * * If not, use the mitkClassMacroNoParent version */ #define mitkClassMacro(className, SuperClassName) \ typedef className Self; \ typedef SuperClassName Superclass; \ typedef itk::SmartPointer<Self> Pointer; \ typedef itk::SmartPointer<const Self> ConstPointer; \ static const char *GetStaticNameOfClass() { return #className; } \ virtual std::vector<std::string> GetClassHierarchy() const override { return mitk::GetClassHierarchy<Self>(); } \ itkTypeMacro(className, SuperClassName); #define mitkClassMacroItkParent(className, SuperClassName) \ typedef className Self; \ typedef SuperClassName Superclass; \ typedef itk::SmartPointer<Self> Pointer; \ typedef itk::SmartPointer<const Self> ConstPointer; \ static const char *GetStaticNameOfClass() { return #className; } \ virtual std::vector<std::string> GetClassHierarchy() const { return mitk::GetClassHierarchy<Self>(); } \ itkTypeMacro(className, SuperClassName); /** At version 4.7 provides two type macros, the normal one expects the Superclass to provide the * GetNameOfClass explicitely, the NoParent deos not expect anything. */ #define mitkClassMacroNoParent(className) \ typedef className Self; \ typedef itk::SmartPointer<Self> Pointer; \ typedef itk::SmartPointer<const Self> ConstPointer; \ static const char *GetStaticNameOfClass() { return #className; } \ virtual std::vector<std::string> GetClassHierarchy() const { return mitk::GetClassHierarchy<Self>(); } \ itkTypeMacroNoParent(className) /** * Macro for Constructors with one parameter for classes derived from itk::Lightobject **/ #define mitkNewMacro1Param(classname, type) \ \ static Pointer New(type _arg) \ \ { \ Pointer smartPtr = new classname(_arg); \ smartPtr->UnRegister(); \ return smartPtr; \ } /** * Macro for Constructors with two parameters for classes derived from itk::Lightobject **/ #define mitkNewMacro2Param(classname, typea, typeb) \ \ static Pointer New(typea _arga, typeb _argb) \ \ { \ Pointer smartPtr = new classname(_arga, _argb); \ smartPtr->UnRegister(); \ return smartPtr; \ } /** * Macro for Constructors with three parameters for classes derived from itk::Lightobject **/ #define mitkNewMacro3Param(classname, typea, typeb, typec) \ \ static Pointer New(typea _arga, typeb _argb, typec _argc) \ \ { \ Pointer smartPtr = new classname(_arga, _argb, _argc); \ smartPtr->UnRegister(); \ return smartPtr; \ } /** * Macro for Constructors with four parameters for classes derived from itk::Lightobject **/ #define mitkNewMacro4Param(classname, typea, typeb, typec, typed) \ \ static Pointer New(typea _arga, typeb _argb, typec _argc, typed _argd) \ \ { \ Pointer smartPtr = new classname(_arga, _argb, _argc, _argd); \ smartPtr->UnRegister(); \ return smartPtr; \ } /** * Macro for Constructors with five parameters for classes derived from itk::Lightobject **/ #define mitkNewMacro5Param(classname, typea, typeb, typec, typed, typee) \ \ static Pointer New(typea _arga, typeb _argb, typec _argc, typed _argd, typee _arge) \ \ { \ Pointer smartPtr = new classname(_arga, _argb, _argc, _argd, _arge); \ smartPtr->UnRegister(); \ return smartPtr; \ } /** * Macro for Constructors with six parameters for classes derived from itk::Lightobject **/ #define mitkNewMacro6Param(classname, typea, typeb, typec, typed, typee, typef) \ \ static Pointer New(typea _arga, typeb _argb, typec _argc, typed _argd, typee _arge, typef _argf) \ \ { \ Pointer smartPtr = new classname(_arga, _argb, _argc, _argd, _arge, _argf); \ smartPtr->UnRegister(); \ return smartPtr; \ } /** Get a smart const pointer to an object. Creates the member * Get"name"() (e.g., GetPoints()). */ #define mitkGetObjectMacroConst(name, type) \ virtual type *Get##name() const \ { \ itkDebugMacro("returning " #name " address " << this->m_##name); \ return this->m_##name.GetPointer(); \ } /** Creates a Clone() method for "Classname". Returns a smartPtr of a clone of the calling object*/ #define mitkCloneMacro(classname) \ virtual itk::LightObject::Pointer InternalClone() const override \ \ { \ Pointer smartPtr = new classname(*this); \ smartPtr->UnRegister(); \ return smartPtr.GetPointer(); \ } /** cross-platform deprecation macro \todo maybe there is something in external toolkits (ITK, VTK,...) that we could reulse -- would be much preferable */ #ifdef MITK_NO_DEPRECATED_WARNINGS #define DEPRECATED(func) func #elif defined(__GNUC__) #define DEPRECATED(...) __VA_ARGS__ __attribute__((deprecated)) #elif defined(_MSC_VER) #define DEPRECATED(...) __declspec(deprecated)##__VA_ARGS__ #else #pragma message("WARNING: You need to implement DEPRECATED for your compiler!") #define DEPRECATED(func) func #endif /** * Mark templates as exported to generate public RTTI symbols which are * needed for GCC and Clang to support e.g. dynamic_cast between DSOs. */ #if defined(__clang__) || defined(__GNUC__) #define MITK_EXPORT __attribute__((visibility("default"))) #define MITK_IMPORT __attribute__((visibility("default"))) #define MITK_LOCAL __attribute__((visibility("hidden"))) #elif defined(WIN32) #define MITK_EXPORT __declspec(dllexport) #define MITK_IMPORT __declspec(dllimport) #define MITK_LOCAL #else #define MITK_EXPORT #define MITK_IMPORT #define MITK_LOCAL #endif #endif // MITK_COMMON_H_DEFINED diff --git a/Modules/Core/include/mitkDisplayActionEvents.h b/Modules/Core/include/mitkDisplayActionEvents.h index ba069e7213..faa5e2288b 100644 --- a/Modules/Core/include/mitkDisplayActionEvents.h +++ b/Modules/Core/include/mitkDisplayActionEvents.h @@ -1,184 +1,179 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKDISPLAYACTIONEVENTS_H #define MITKDISPLAYACTIONEVENTS_H #include <MitkCoreExports.h> // mitk core #include "mitkInteractionEvent.h" // itk #include <itkEventObject.h> #include <mitkVector.h> #include <mitkPoint.h> namespace mitk { class MITKCORE_EXPORT DisplayActionEvent : public itk::AnyEvent { public: typedef DisplayActionEvent Self; typedef itk::AnyEvent Superclass; DisplayActionEvent() : m_InteractionEvent(nullptr) {} DisplayActionEvent(InteractionEvent* interactionEvent) : m_InteractionEvent(interactionEvent) {} ~DisplayActionEvent() override {} const char* GetEventName() const override { return "DisplayActionEvent"; } - bool CheckEvent(const itk::EventObject* e) const override - { return dynamic_cast<const Self*>(e) != nullptr; } + bool CheckEvent(const itk::EventObject* e) const override { return dynamic_cast<const Self *>(e) != nullptr; } itk::EventObject* MakeObject() const override { return new Self(m_InteractionEvent); } InteractionEvent* GetInteractionEvent() const { return m_InteractionEvent; } BaseRenderer* GetSender() const { return m_InteractionEvent != nullptr ? m_InteractionEvent->GetSender() : nullptr; } DisplayActionEvent(const Self& s) : Superclass(s), m_InteractionEvent(s.GetInteractionEvent()) {}; private: InteractionEvent* m_InteractionEvent; void operator=(const Self &); }; class MITKCORE_EXPORT DisplayMoveEvent : public DisplayActionEvent { public: typedef DisplayMoveEvent Self; typedef DisplayActionEvent Superclass; DisplayMoveEvent() : Superclass() {} DisplayMoveEvent(InteractionEvent* interactionEvent, const Vector2D& moveVector) : Superclass(interactionEvent) , m_MoveVector(moveVector) { } ~DisplayMoveEvent() override {} const char* GetEventName() const override { return "DisplayMoveEvent"; } - bool CheckEvent(const itk::EventObject* e) const override - { return dynamic_cast<const Self*>(e) != nullptr; } + bool CheckEvent(const itk::EventObject* e) const override { return dynamic_cast<const Self *>(e) != nullptr; } itk::EventObject* MakeObject() const override { return new Self(GetInteractionEvent(), m_MoveVector); } const Vector2D& GetMoveVector() const { return m_MoveVector; } DisplayMoveEvent(const Self& s) : Superclass(s), m_MoveVector(s.GetMoveVector()) {}; private: Vector2D m_MoveVector; }; class MITKCORE_EXPORT DisplaySetCrosshairEvent : public DisplayActionEvent { public: typedef DisplaySetCrosshairEvent Self; typedef DisplayActionEvent Superclass; DisplaySetCrosshairEvent() : Superclass() {} DisplaySetCrosshairEvent(InteractionEvent* interactionEvent, const Point3D& position) : Superclass(interactionEvent) , m_Position(position) { } ~DisplaySetCrosshairEvent() override {} const char* GetEventName() const override { return "DisplaySetCrosshairEvent"; } - bool CheckEvent(const itk::EventObject* e) const override - { return dynamic_cast<const Self*>(e) != nullptr; } + bool CheckEvent(const itk::EventObject* e) const override { return dynamic_cast<const Self *>(e) != nullptr; } itk::EventObject* MakeObject() const override { return new Self(GetInteractionEvent(), m_Position); } const Point3D& GetPosition() const { return m_Position; } DisplaySetCrosshairEvent(const Self& s) : Superclass(s), m_Position(s.GetPosition()) {}; private: Point3D m_Position; }; class MITKCORE_EXPORT DisplayZoomEvent : public DisplayActionEvent { public: typedef DisplayZoomEvent Self; typedef DisplayActionEvent Superclass; DisplayZoomEvent() : Superclass() {} DisplayZoomEvent(InteractionEvent* interactionEvent, float zoomFactor, const Point2D& startCoordinate) : Superclass(interactionEvent) , m_ZoomFactor(zoomFactor) , m_StartCoordinate(startCoordinate) { } ~DisplayZoomEvent() override {} const char* GetEventName() const override { return "DisplayZoomEvent"; } - bool CheckEvent(const itk::EventObject* e) const override - { return dynamic_cast<const Self*>(e) != nullptr; } + bool CheckEvent(const itk::EventObject* e) const override { return dynamic_cast<const Self *>(e) != nullptr; } itk::EventObject* MakeObject() const override { return new Self(GetInteractionEvent(), m_ZoomFactor, m_StartCoordinate); } float GetZoomFactor() const { return m_ZoomFactor; } const Point2D& GetStartCoordinate() const { return m_StartCoordinate; } DisplayZoomEvent(const Self& s) : Superclass(s), m_ZoomFactor(s.GetZoomFactor()), m_StartCoordinate(s.GetStartCoordinate()) {}; private: float m_ZoomFactor; Point2D m_StartCoordinate; }; class MITKCORE_EXPORT DisplayScrollEvent : public DisplayActionEvent { public: typedef DisplayScrollEvent Self; typedef DisplayActionEvent Superclass; DisplayScrollEvent() : Superclass() {} - DisplayScrollEvent(InteractionEvent* interactionEvent, int sliceDelta) + DisplayScrollEvent(InteractionEvent* interactionEvent, int sliceDelta, bool autoRepeat) : Superclass(interactionEvent) , m_SliceDelta(sliceDelta) + , m_AutoRepeat(autoRepeat) { } ~DisplayScrollEvent() override {} const char* GetEventName() const override { return "DisplayScrollEvent"; } - bool CheckEvent(const itk::EventObject* e) const override - { return dynamic_cast<const Self*>(e) != nullptr; } - itk::EventObject* MakeObject() const override { return new Self(GetInteractionEvent(), m_SliceDelta); } + bool CheckEvent(const itk::EventObject *e) const override { return dynamic_cast<const Self *>(e) != nullptr; } + itk::EventObject* MakeObject() const override { return new Self(GetInteractionEvent(), m_SliceDelta, m_AutoRepeat); } int GetSliceDelta() const { return m_SliceDelta; } - DisplayScrollEvent(const Self& s) : Superclass(s), m_SliceDelta(s.GetSliceDelta()) {}; + bool GetAutoRepeat() const { return m_AutoRepeat; } + DisplayScrollEvent(const Self& s) : Superclass(s), m_SliceDelta(s.GetSliceDelta()), m_AutoRepeat(s.GetAutoRepeat()) {}; private: int m_SliceDelta; + bool m_AutoRepeat; }; class MITKCORE_EXPORT DisplaySetLevelWindowEvent : public DisplayActionEvent { public: typedef DisplaySetLevelWindowEvent Self; typedef DisplayActionEvent Superclass; DisplaySetLevelWindowEvent() : Superclass() {} DisplaySetLevelWindowEvent(InteractionEvent* interactionEvent, ScalarType level, ScalarType window) : Superclass(interactionEvent) , m_Level(level) , m_Window(window) { } ~DisplaySetLevelWindowEvent() override {} const char* GetEventName() const override { return "DisplaySetLevelWindowEvent"; } - bool CheckEvent(const itk::EventObject* e) const override - { - return dynamic_cast<const Self*>(e) != nullptr; - } + bool CheckEvent(const itk::EventObject *e) const override { return dynamic_cast<const Self *>(e) != nullptr; } itk::EventObject* MakeObject() const override { return new Self(GetInteractionEvent(), m_Level, m_Window); } ScalarType GetLevel() const { return m_Level; } ScalarType GetWindow() const { return m_Window; } DisplaySetLevelWindowEvent(const Self& s) : Superclass(s), m_Level(s.GetLevel()), m_Window(s.GetWindow()) {}; private: ScalarType m_Level; ScalarType m_Window; }; } // end namespace #endif // MITKDISPLAYACTIONEVENTS_H diff --git a/Modules/Core/include/mitkImage.h b/Modules/Core/include/mitkImage.h index 359b536d87..c8b6f03464 100644 --- a/Modules/Core/include/mitkImage.h +++ b/Modules/Core/include/mitkImage.h @@ -1,644 +1,643 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 #define MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 #include "mitkBaseData.h" #include "mitkImageAccessorBase.h" #include "mitkImageDataItem.h" #include "mitkImageDescriptor.h" #include "mitkImageVtkAccessor.h" #include "mitkLevelWindow.h" #include "mitkPlaneGeometry.h" #include "mitkSlicedData.h" #include <MitkCoreExports.h> #include <mitkProportionalTimeGeometry.h> #ifndef __itkHistogram_h #include <itkHistogram.h> #endif class vtkImageData; namespace itk { template <class T> class MutexLockHolder; } namespace mitk { class SubImageSelector; class ImageTimeSelector; class ImageStatisticsHolder; /** * @brief Image class for storing images * - * Can be asked for header information, the data vector, - * the mitkIpPicDescriptor struct or vtkImageData objects. If not the complete - * data is required, the appropriate SubImageSelector class should be used - * for access. + * Can be asked for header information, the data vector, or vtkImageData objects. + * If not the complete data is required, the appropriate SubImageSelector class + * should be used for access. * Image organizes sets of slices (s x 2D), volumes (t x 3D) and channels (n * x ND). Channels are for different kind of data, e.g., morphology in * channel 0, velocities in channel 1. All channels must have the same Geometry! In * particular, the dimensions of all channels are the same, only the pixel-type * may differ between channels. * * For importing ITK images use of mitk::ITKImageImport is recommended, see * \ref Adaptor. * * For ITK v3.8 and older: Converting coordinates from the ITK physical * coordinate system (which does not support rotated images) to the MITK world * coordinate system should be performed via the BaseGeometry of the Image, see * BaseGeometry::WorldToItkPhysicalPoint. * * For more information, see \ref MitkImagePage . * @ingroup Data */ class MITKCORE_EXPORT Image : public SlicedData { friend class SubImageSelector; friend class ImageAccessorBase; friend class ImageVtkAccessor; friend class ImageVtkReadAccessor; friend class ImageVtkWriteAccessor; friend class ImageReadAccessor; friend class ImageWriteAccessor; public: mitkClassMacro(Image, SlicedData); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** Smart Pointer type to a ImageDataItem. */ typedef itk::SmartPointer<ImageDataItem> ImageDataItemPointer; typedef itk::Statistics::Histogram<double> HistogramType; typedef mitk::ImageStatisticsHolder *StatisticsHolderPointer; /** This enum is evaluated when setting new data to an image. */ enum ImportMemoryManagementType { CopyMemory, /**< Data to be set is copied and assigned to a new memory block. Data memory block will be freed on deletion of mitk::Image. */ ManageMemory, /**< Data to be set will be referenced, and Data memory block will be freed on deletion of mitk::Image. */ ReferenceMemory, /**< Data to be set will be referenced, but Data memory block will not be freed on deletion of mitk::Image. */ DontManageMemory = ReferenceMemory }; /** * @brief Vector container of SmartPointers to ImageDataItems; * Class is only for internal usage to allow convenient access to all slices over iterators; * See documentation of ImageDataItem for details. */ typedef std::vector<ImageDataItemPointer> ImageDataItemPointerArray; public: /** * @brief Returns the PixelType of channel @a n. */ const mitk::PixelType GetPixelType(int n = 0) const; /** * @brief Get dimension of the image */ unsigned int GetDimension() const; /** * @brief Get the size of dimension @a i (e.g., i=0 results in the number of pixels in x-direction). * * @sa GetDimensions() */ unsigned int GetDimension(int i) const; public: /** * @brief Get a volume at a specific time @a t of channel @a n as a vtkImageData. */ virtual vtkImageData *GetVtkImageData(int t = 0, int n = 0); virtual const vtkImageData *GetVtkImageData(int t = 0, int n = 0) const; /** * @brief Check whether slice @a s at time @a t in channel @a n is set */ bool IsSliceSet(int s = 0, int t = 0, int n = 0) const override; /** * @brief Check whether volume at time @a t in channel @a n is set */ bool IsVolumeSet(int t = 0, int n = 0) const override; /** * @brief Check whether the channel @a n is set */ bool IsChannelSet(int n = 0) const override; /** * @brief Set @a data as slice @a s at time @a t in channel @a n. It is in * the responsibility of the caller to ensure that the data vector @a data * is really a slice (at least is not smaller than a slice), since there is * no chance to check this. * * The data is copied to an array managed by the image. If the image shall * reference the data, use SetImportSlice with ImportMemoryManagementType * set to ReferenceMemory. For importing ITK images use of mitk:: * ITKImageImport is recommended. * @sa SetPicSlice, SetImportSlice, SetImportVolume */ virtual bool SetSlice(const void *data, int s = 0, int t = 0, int n = 0); /** * @brief Set @a data as volume at time @a t in channel @a n. It is in * the responsibility of the caller to ensure that the data vector @a data * is really a volume (at least is not smaller than a volume), since there is * no chance to check this. * * The data is copied to an array managed by the image. If the image shall * reference the data, use SetImportVolume with ImportMemoryManagementType * set to ReferenceMemory. For importing ITK images use of mitk:: * ITKImageImport is recommended. * @sa SetPicVolume, SetImportVolume */ virtual bool SetVolume(const void *data, int t = 0, int n = 0); /** * @brief Set @a data in channel @a n. It is in * the responsibility of the caller to ensure that the data vector @a data * is really a channel (at least is not smaller than a channel), since there is * no chance to check this. * * The data is copied to an array managed by the image. If the image shall * reference the data, use SetImportChannel with ImportMemoryManagementType * set to ReferenceMemory. For importing ITK images use of mitk:: * ITKImageImport is recommended. * @sa SetPicChannel, SetImportChannel */ virtual bool SetChannel(const void *data, int n = 0); /** * @brief Set @a data as slice @a s at time @a t in channel @a n. It is in * the responsibility of the caller to ensure that the data vector @a data * is really a slice (at least is not smaller than a slice), since there is * no chance to check this. * * The data is managed according to the parameter \a importMemoryManagement. * @sa SetPicSlice */ virtual bool SetImportSlice( void *data, int s = 0, int t = 0, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory); /** * @brief Set @a data as volume at time @a t in channel @a n. It is in * the responsibility of the caller to ensure that the data vector @a data * is really a volume (at least is not smaller than a volume), since there is * no chance to check this. * * The data is managed according to the parameter \a importMemoryManagement. * @sa SetPicVolume */ virtual bool SetImportVolume(void *data, int t = 0, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory); virtual bool SetImportVolume(const void *const_data, int t = 0, int n = 0); /** * @brief Set @a data in channel @a n. It is in * the responsibility of the caller to ensure that the data vector @a data * is really a channel (at least is not smaller than a channel), since there is * no chance to check this. * * The data is managed according to the parameter \a importMemoryManagement. * @sa SetPicChannel */ virtual bool SetImportChannel(void *data, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory); /** * initialize new (or re-initialize) image information * @warning Initialize() by pic assumes a plane, evenly spaced geometry starting at (0,0,0). */ virtual void Initialize(const mitk::PixelType &type, unsigned int dimension, const unsigned int *dimensions, unsigned int channels = 1); /** * initialize new (or re-initialize) image information by a BaseGeometry * * \param type * \param geometry * \param channels * @param tDim defines the number of time steps for which the Image should be initialized */ virtual void Initialize(const mitk::PixelType &type, const mitk::BaseGeometry &geometry, unsigned int channels = 1, int tDim = 1); /** * \brief Initialize new (or re-initialize) image information by a TimeGeometry * * \param type * \param geometry * \param channels * \param tDim override time dimension if the value is bigger than 0 (Default -1) */ virtual void Initialize(const mitk::PixelType &type, const mitk::TimeGeometry &geometry, unsigned int channels = 1, int tDim = -1); /** * initialize new (or re-initialize) image information by a PlaneGeometry and number of slices * * Initializes the bounding box according to the width/height of the * PlaneGeometry and @a sDim via SlicedGeometry3D::InitializeEvenlySpaced. * The spacing is calculated from the PlaneGeometry. * \sa SlicedGeometry3D::InitializeEvenlySpaced */ virtual void Initialize(const mitk::PixelType &type, int sDim, const mitk::PlaneGeometry &geometry2d, unsigned int channels = 1, int tDim = 1); /** * initialize new (or re-initialize) image information by another * mitk-image. * Only the header is used, not the data vector! */ virtual void Initialize(const mitk::Image *image); virtual void Initialize(const mitk::ImageDescriptor::Pointer inDesc); /** * initialize new (or re-initialize) image information by @a vtkimagedata, * a vtk-image. * Only the header is used, not the data vector! Use * SetVolume(vtkimage->GetScalarPointer()) to set the data vector. * * @param vtkimagedata * @param channels * @param tDim override time dimension in @a vtkimagedata (if >0 and <) * @param sDim override z-space dimension in @a vtkimagedata (if >0 and <) * @param pDim override y-space dimension in @a vtkimagedata (if >0 and <) */ virtual void Initialize(vtkImageData *vtkimagedata, int channels = 1, int tDim = -1, int sDim = -1, int pDim = -1); /** * initialize new (or re-initialize) image information by @a itkimage, * a templated itk-image. * Only the header is used, not the data vector! Use * SetVolume(itkimage->GetBufferPointer()) to set the data vector. * * @param itkimage * @param channels * @param tDim override time dimension in @a itkimage (if >0 and <) * @param sDim override z-space dimension in @a itkimage (if >0 and <) */ template <typename itkImageType> void InitializeByItk(const itkImageType *itkimage, int channels = 1, int tDim = -1, int sDim = -1) { if (itkimage == nullptr) return; MITK_DEBUG << "Initializing MITK image from ITK image."; // build array with dimensions in each direction with at least 4 entries m_Dimension = itkimage->GetImageDimension(); unsigned int i, *tmpDimensions = new unsigned int[m_Dimension > 4 ? m_Dimension : 4]; for (i = 0; i < m_Dimension; ++i) tmpDimensions[i] = itkimage->GetLargestPossibleRegion().GetSize().GetSize()[i]; if (m_Dimension < 4) { unsigned int *p; for (i = 0, p = tmpDimensions + m_Dimension; i < 4 - m_Dimension; ++i, ++p) *p = 1; } // overwrite number of slices if sDim is set if ((m_Dimension > 2) && (sDim >= 0)) tmpDimensions[2] = sDim; // overwrite number of time points if tDim is set if ((m_Dimension > 3) && (tDim >= 0)) tmpDimensions[3] = tDim; // rough initialization of Image // mitk::PixelType importType = ImportItkPixelType( itkimage::PixelType ); Initialize( MakePixelType<itkImageType>(itkimage->GetNumberOfComponentsPerPixel()), m_Dimension, tmpDimensions, channels); const typename itkImageType::SpacingType &itkspacing = itkimage->GetSpacing(); MITK_DEBUG << "ITK spacing " << itkspacing; // access spacing of itk::Image Vector3D spacing; FillVector3D(spacing, itkspacing[0], 1.0, 1.0); if (m_Dimension >= 2) spacing[1] = itkspacing[1]; if (m_Dimension >= 3) spacing[2] = itkspacing[2]; // access origin of itk::Image Point3D origin; const typename itkImageType::PointType &itkorigin = itkimage->GetOrigin(); MITK_DEBUG << "ITK origin " << itkorigin; FillVector3D(origin, itkorigin[0], 0.0, 0.0); if (m_Dimension >= 2) origin[1] = itkorigin[1]; if (m_Dimension >= 3) origin[2] = itkorigin[2]; // access direction of itk::Imagm_PixelType = new mitk::PixelType(type);e and include spacing const typename itkImageType::DirectionType &itkdirection = itkimage->GetDirection(); MITK_DEBUG << "ITK direction " << itkdirection; mitk::Matrix3D matrix; matrix.SetIdentity(); unsigned int j, itkDimMax3 = (m_Dimension >= 3 ? 3 : m_Dimension); // check if spacing has no zero entry and itkdirection has no zero columns bool itkdirectionOk = true; mitk::ScalarType columnSum; for (j = 0; j < itkDimMax3; ++j) { columnSum = 0.0; for (i = 0; i < itkDimMax3; ++i) { columnSum += fabs(itkdirection[i][j]); } if (columnSum < mitk::eps) { itkdirectionOk = false; } if ((spacing[j] < -mitk::eps) // (normally sized) negative value && (j == 2) && (m_Dimensions[2] == 1)) { // Negative spacings can occur when reading single DICOM slices with ITK via GDCMIO // In these cases spacing is not determind by ITK correctly (because it distinguishes correctly // between slice thickness and inter slice distance -- slice distance is meaningless for // single slices). // I experienced that ITK produced something meaningful nonetheless because is is // evaluating the tag "(0018,0088) Spacing between slices" as a fallback. This tag is not // reliable (http://www.itk.org/pipermail/insight-users/2005-September/014711.html) // but gives at least a hint. // In real world cases I experienced that this tag contained the correct inter slice distance // with a negative sign, so we just invert such negative spacings. MITK_WARN << "Illegal value of itk::Image::GetSpacing()[" << j << "]=" << spacing[j] << ". Using inverted value " << -spacing[j]; spacing[j] = -spacing[j]; } else if (spacing[j] < mitk::eps) // value near zero { MITK_ERROR << "Illegal value of itk::Image::GetSpacing()[" << j << "]=" << spacing[j] << ". Using 1.0 instead."; spacing[j] = 1.0; } } if (itkdirectionOk == false) { MITK_ERROR << "Illegal matrix returned by itk::Image::GetDirection():" << itkdirection << " Using identity instead."; for (i = 0; i < itkDimMax3; ++i) for (j = 0; j < itkDimMax3; ++j) if (i == j) matrix[i][j] = spacing[j]; else matrix[i][j] = 0.0; } else { for (i = 0; i < itkDimMax3; ++i) for (j = 0; j < itkDimMax3; ++j) matrix[i][j] = itkdirection[i][j] * spacing[j]; } // re-initialize PlaneGeometry with origin and direction PlaneGeometry *planeGeometry = static_cast<PlaneGeometry *>(GetSlicedGeometry(0)->GetPlaneGeometry(0)); planeGeometry->SetOrigin(origin); planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix); // re-initialize SlicedGeometry3D SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(0); slicedGeometry->InitializeEvenlySpaced(planeGeometry, m_Dimensions[2]); slicedGeometry->SetSpacing(spacing); // re-initialize TimeGeometry ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]); SetTimeGeometry(timeGeometry); // clean-up delete[] tmpDimensions; this->Initialize(); } /** * @brief Check whether slice @a s at time @a t in channel @a n is valid, i.e., * is (or can be) inside of the image */ virtual bool IsValidSlice(int s = 0, int t = 0, int n = 0) const; /** * @brief Check whether volume at time @a t in channel @a n is valid, i.e., * is (or can be) inside of the image */ virtual bool IsValidVolume(int t = 0, int n = 0) const; /** * @brief Check whether the channel @a n is valid, i.e., * is (or can be) inside of the image */ virtual bool IsValidChannel(int n = 0) const; /** * @brief Returns true if an image is rotated, i.e. its geometry's * transformation matrix has nonzero elements besides the diagonal. * Non-diagonal elements are checked if larger then 1/1000 of the matrix' trace. */ bool IsRotated() const; /** * @brief Get the sizes of all dimensions as an integer-array. * * @sa GetDimension(int i); */ unsigned int *GetDimensions() const; ImageDescriptor::Pointer GetImageDescriptor() const { return m_ImageDescriptor; } ChannelDescriptor GetChannelDescriptor(int id = 0) const { return m_ImageDescriptor->GetChannelDescriptor(id); } /** \brief Sets a geometry to an image. */ void SetGeometry(BaseGeometry *aGeometry3D) override; /** * @warning for internal use only */ virtual ImageDataItemPointer GetSliceData(int s = 0, int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; /** * @warning for internal use only */ virtual ImageDataItemPointer GetVolumeData(int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; /** * @warning for internal use only */ virtual ImageDataItemPointer GetChannelData(int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; /** \brief Returns a pointer to the ImageStatisticsHolder object that holds all statistics information for the image. All Get-methods for statistics properties formerly accessible directly from an Image object are now moved to the new \a ImageStatisticsHolder object. */ StatisticsHolderPointer GetStatistics() const { return m_ImageStatistics; } protected: mitkCloneMacro(Self); typedef itk::MutexLockHolder<itk::SimpleFastMutexLock> MutexHolder; int GetSliceIndex(int s = 0, int t = 0, int n = 0) const; int GetVolumeIndex(int t = 0, int n = 0) const; void ComputeOffsetTable(); virtual bool IsValidTimeStep(int t) const; void Expand(unsigned int timeSteps) override; virtual ImageDataItemPointer AllocateSliceData( int s = 0, int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; virtual ImageDataItemPointer AllocateVolumeData( int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; virtual ImageDataItemPointer AllocateChannelData( int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; Image(); Image(const Image &other); ~Image() override; void Clear() override; /** @warning Has to be called by every Initialize method! */ void Initialize() override; void PrintSelf(std::ostream &os, itk::Indent indent) const override; mutable ImageDataItemPointerArray m_Channels; mutable ImageDataItemPointerArray m_Volumes; mutable ImageDataItemPointerArray m_Slices; mutable itk::SimpleFastMutexLock m_ImageDataArraysLock; unsigned int m_Dimension; unsigned int *m_Dimensions; ImageDescriptor::Pointer m_ImageDescriptor; size_t *m_OffsetTable; ImageDataItemPointer m_CompleteData; // Image statistics Holder replaces the former implementation directly inside this class friend class ImageStatisticsHolder; StatisticsHolderPointer m_ImageStatistics; private: ImageDataItemPointer GetSliceData_unlocked( int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer GetVolumeData_unlocked(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer GetChannelData_unlocked(int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer AllocateSliceData_unlocked( int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer AllocateVolumeData_unlocked(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer AllocateChannelData_unlocked(int n, void *data, ImportMemoryManagementType importMemoryManagement) const; bool IsSliceSet_unlocked(int s, int t, int n) const; bool IsVolumeSet_unlocked(int t, int n) const; bool IsChannelSet_unlocked(int n) const; /** Stores all existing ImageReadAccessors */ mutable std::vector<ImageAccessorBase *> m_Readers; /** Stores all existing ImageWriteAccessors */ mutable std::vector<ImageAccessorBase *> m_Writers; /** Stores all existing ImageVtkAccessors */ mutable std::vector<ImageAccessorBase *> m_VtkReaders; /** A mutex, which needs to be locked to manage m_Readers and m_Writers */ itk::SimpleFastMutexLock m_ReadWriteLock; /** A mutex, which needs to be locked to manage m_VtkReaders */ itk::SimpleFastMutexLock m_VtkReadersLock; }; /** * @brief Equal A function comparing two images for beeing equal in meta- and imagedata * * @ingroup MITKTestingAPI * * Following aspects are tested for equality: * - dimension of the images * - size of the images * - pixel type * - pixel values : pixel values are expected to be identical at each position ( for other options see * mitk::CompareImageFilter ) * * @param rightHandSide An image to be compared * @param leftHandSide An image to be compared * @param eps Tolarence for comparison. You can use mitk::eps in most cases. * @param verbose Flag indicating if the user wants detailed console output or not. * @return true, if all subsequent comparisons are true, false otherwise */ MITKCORE_EXPORT bool Equal(const mitk::Image &leftHandSide, const mitk::Image &rightHandSide, ScalarType eps, bool verbose); } // namespace mitk #endif /* MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 */ diff --git a/Modules/Core/include/mitkImageDataItem.h b/Modules/Core/include/mitkImageDataItem.h index 946879ff55..8c1a00b8be 100644 --- a/Modules/Core/include/mitkImageDataItem.h +++ b/Modules/Core/include/mitkImageDataItem.h @@ -1,166 +1,162 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef IMAGEDATAITEM_H #define IMAGEDATAITEM_H #include "mitkCommon.h" #include <MitkCoreExports.h> -//#include <mitkIpPic.h> -//#include "mitkPixelType.h" #include "mitkImageDescriptor.h" -//#include "mitkImageVtkAccessor.h" class vtkImageData; namespace mitk { class PixelType; class ImageVtkReadAccessor; class ImageVtkWriteAccessor; class Image; //##Documentation //## @brief Internal class for managing references on sub-images //## //## ImageDataItem is a container for image data which is used internal in //## mitk::Image to handle the communication between the different data types for images - //## used in MITK (ipPicDescriptor, mitk::Image, vtkImageData). Common for these image data + //## used in MITK (mitk::Image, vtkImageData). Common for these image data //## types is the actual image data, but they differ in representation of pixel type etc. - //## The class is also used to convert ipPic images to vtkImageData. //## //## The class is mainly used to extract sub-images inside of mitk::Image, like single slices etc. //## It should not be used outside of this. //## //## @param manageMemory Determines if image data is removed while destruction of ImageDataItem or not. //## @ingroup Data class MITKCORE_EXPORT ImageDataItem : public itk::LightObject { friend class ImageAccessorBase; friend class ImageWriteAccessor; friend class ImageReadAccessor; template <class TPixel, unsigned int VDimension> friend class ImagePixelAccessor; friend class Image; // template<class TOutputImage> // friend class ImageToItk; public: typedef itk::SmartPointer<mitk::Image> ImagePointer; typedef itk::SmartPointer<const mitk::Image> ImageConstPointer; mitkClassMacroItkParent(ImageDataItem, itk::LightObject); itkCloneMacro(ImageDataItem); itk::LightObject::Pointer InternalClone() const override; ImageDataItem(const ImageDataItem &aParent, const mitk::ImageDescriptor::Pointer desc, int timestep, unsigned int dimension, void *data = nullptr, bool manageMemory = false, size_t offset = 0); ~ImageDataItem() override; ImageDataItem(const mitk::ImageDescriptor::Pointer desc, int timestep, void *data, bool manageMemory); ImageDataItem(const mitk::PixelType &type, int timestep, unsigned int dimension, unsigned int *dimensions, void *data, bool manageMemory); ImageDataItem(const ImageDataItem &other); bool IsComplete() const { return m_IsComplete; } void SetComplete(bool complete) { m_IsComplete = complete; } int GetOffset() const { return m_Offset; } PixelType GetPixelType() const { return *m_PixelType; } void SetTimestep(int t) { m_Timestep = t; } void SetManageMemory(bool b) { m_ManageMemory = b; } int GetDimension() const { return m_Dimension; } int GetDimension(int i) const { int returnValue = 0; // return the true size if dimension available if (i < (int)m_Dimension) returnValue = m_Dimensions[i]; return returnValue; } ImageDataItem::ConstPointer GetParent() const { return m_Parent; } /** * @brief GetVtkImageAccessor Returns a vtkImageDataItem, if none is present, a new one is constructed by the * ConstructVtkImageData method. * Due to historical development of MITK and VTK, the vtkImage origin is explicitly set * to * (0, 0, 0) for 3D images. * See bug 5050 for detailed information. * @return Pointer of type ImageVtkReadAccessor */ ImageVtkReadAccessor *GetVtkImageAccessor(ImageConstPointer) const; ImageVtkWriteAccessor *GetVtkImageAccessor(ImagePointer); // Returns if image data should be deleted on destruction of ImageDataItem. bool GetManageMemory() const { return m_ManageMemory; } virtual void ConstructVtkImageData(ImageConstPointer) const; size_t GetSize() const { return m_Size; } virtual void Modified() const; protected: /**Helper function to allow friend classes to access m_Data without changing their code. * Moved to protected visibility because only friends are allowed to access m_Data directly. * Other classes should used ImageWriteAccessor::GetData() or ImageReadAccessor::GetData() * to get access.*/ void* GetData() const { return m_Data; } unsigned char *m_Data; PixelType *m_PixelType; bool m_ManageMemory; mutable vtkImageData *m_VtkImageData; mutable ImageVtkReadAccessor *m_VtkImageReadAccessor; ImageVtkWriteAccessor *m_VtkImageWriteAccessor; int m_Offset; bool m_IsComplete; size_t m_Size; private: void ComputeItemSize(const unsigned int *dimensions, unsigned int dimension); ImageDataItem::ConstPointer m_Parent; unsigned int m_Dimension; unsigned int m_Dimensions[MAX_IMAGE_DIMENSIONS]; int m_Timestep; }; } // namespace mitk #endif /* IMAGEDATAITEM_H */ diff --git a/Modules/Core/include/mitkImageDescriptor.h b/Modules/Core/include/mitkImageDescriptor.h index 48986781eb..e9e082a3d7 100644 --- a/Modules/Core/include/mitkImageDescriptor.h +++ b/Modules/Core/include/mitkImageDescriptor.h @@ -1,122 +1,122 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKIMAGEDESCRIPTOR_H #define MITKIMAGEDESCRIPTOR_H #include <itkObjectFactory.h> #include <string> #include <vector> #include "mitkChannelDescriptor.h" #include "mitkCommon.h" -/// Defines the maximum of 8 dimensions per image channel taken from ipPicDescriptor +/// Defines the maximum of 8 dimensions per image channel #define MAX_IMAGE_DIMENSIONS 8 namespace mitk { /** \brief An object to hold all essential information about an Image object The ImageDescriptor holds an std::vector of pointers to ChannelDescriptor together with the information about the image's dimensions. The general assumption ist, that each channel of an image has to have the same geometry. \sa Image, ChannelDescriptor */ class MITKCORE_EXPORT ImageDescriptor : public itk::Object { public: mitkClassMacroItkParent(ImageDescriptor, itk::Object); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** Insert new channel @param ptype Pixel Type @param name channel's name */ void AddNewChannel(mitk::PixelType ptype, const char *name = nullptr); /** \brief Initialize the image descriptor by the dimensions */ void Initialize(const unsigned int *dims, const unsigned int dim); /** \brief Initialize the descriptor by an referenced Descriptor */ void Initialize(const ImageDescriptor::Pointer refDescriptor, unsigned int channel = 0); /** \brief Get the C-array of unsigned int holding the size for each dimension of the image The C-array has allways lenght of MAX_IMAGE_DIMENSIONS */ const unsigned int *GetDimensions() const { return m_Dimensions; } /** \brief Get the number dimensions used (e.g. non-zero size) The return value does not exceed MAX_IMAGE_DIMENSIONS */ unsigned int GetNumberOfDimensions() const { return m_NumberOfDimensions; } /** \brief Get the name of selected channel If the name of the channel wasn't initialized, the string returned is set to "Unnamed [ <PixelTypeName> ]" \sa PixelType, ChannelDescriptor */ const std::string GetChannelName(unsigned int id) const; /** \brief Get the pixel type of a channel specified by its name Returns an uninitialized PixelType object if no channel with given name was found */ PixelType GetChannelTypeByName(const char *name) const; /** \brief Get the pixel type of a channel specified by its id Returns an uninitialized PixelType object if no channel with given id was found */ PixelType GetChannelTypeById(unsigned int id) const; /** \brief Get the ChannelDescriptor for a channel specified by its id */ ChannelDescriptor GetChannelDescriptor(unsigned int id = 0) const; /** \brief Get the count of channels used */ unsigned int GetNumberOfChannels() const { return m_NumberOfChannels; } protected: /** Protected constructor */ ImageDescriptor(); /** Protected desctructor */ ~ImageDescriptor() override{}; private: /** A std::vector holding a pointer to a ChannelDescriptor for each active channel of the image */ std::vector<ChannelDescriptor> m_ChannelDesc; /** A vector holding the names of corresponding channels */ std::vector<std::string> m_ChannelNames; /** Constant iterator for traversing the vector of channel's names */ typedef std::vector<std::string>::const_iterator ConstChannelNamesIter; /** Constant iterator for traversing the vector of ChannelDescriptors */ typedef std::vector<ChannelDescriptor>::const_iterator ConstChannelsIter; unsigned int m_NumberOfChannels; unsigned int m_NumberOfDimensions; unsigned int m_Dimensions[MAX_IMAGE_DIMENSIONS]; }; } // end namespace #endif // MITKIMAGEDESCRIPTOR_H diff --git a/Modules/Core/resource/Interactions/DisplayConfigActivateCoupling.xml b/Modules/Core/resource/Interactions/DisplayConfigActivateCoupling.xml new file mode 100644 index 0000000000..469efc9168 --- /dev/null +++ b/Modules/Core/resource/Interactions/DisplayConfigActivateCoupling.xml @@ -0,0 +1,3 @@ +<config> + <param name="coupled" value="true"/> +</config> diff --git a/Modules/Core/resource/Interactions/DisplayConfigPACSCrosshair.xml b/Modules/Core/resource/Interactions/DisplayConfigCrosshair.xml similarity index 100% copy from Modules/Core/resource/Interactions/DisplayConfigPACSCrosshair.xml copy to Modules/Core/resource/Interactions/DisplayConfigCrosshair.xml diff --git a/Modules/Core/resource/Interactions/DisplayConfigMITK.xml b/Modules/Core/resource/Interactions/DisplayConfigMITK.xml deleted file mode 100644 index 269d079e79..0000000000 --- a/Modules/Core/resource/Interactions/DisplayConfigMITK.xml +++ /dev/null @@ -1,59 +0,0 @@ -<!-- -* - MITK : The original interaction scheme -* - left mouse button : set crosshair -* - middle mouse button : panning -* - right mouse button : zooming -* - wheel : scrolling ---> -<config> - <!-- Zoom sensitivity --> - <param name="zoomFactor" value="5"/> - <!-- Zoom either by moving mouse leftright or updown --> - <param name="zoomDirection" value="updown"/> - <!-- react to an event, even tough is was already processed by a DataInteractor--> - <param name="alwaysReact" value="false"/> - <!-- Crosshair --> - <event_variant class="MousePressEvent" name="SetCrosshair"> - <attribute name="EventButton" value="LeftMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="MoveCrosshair"> - <attribute name="ButtonState" value="LeftMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndMoveCrosshair"> - <attribute name="EventButton" value="LeftMouseButton"/> - </event_variant> - <!-- Moving --> - <event_variant class="MousePressEvent" name="StartMove"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Moving"> - <attribute name="ButtonState" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndMoving"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <!-- Zooming --> - <event_variant class="MousePressEvent" name="StartZoom"> - <attribute name="EventButton" value="RightMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Zooming"> - <attribute name="ButtonState" value="RightMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndZooming"> - <attribute name="EventButton" value="RightMouseButton"/> - </event_variant> - <!-- Scrolling through planes --> - <event_variant class="MouseWheelEvent" name="PlaneUP"> - <attribute name="ScrollDirection" value="up"/> - </event_variant> - <event_variant class="MouseWheelEvent" name="PlaneDown"> - <attribute name="ScrollDirection" value="down"/> - </event_variant> - <!-- Change TimeSteps --> - <event_variant class="InteractionKeyEvent" name="IncreaseTimeStep"> - <attribute name="Key" value="ArrowRight"/> - </event_variant> - <event_variant class="InteractionKeyEvent" name="DecreaseTimeStep"> - <attribute name="Key" value="ArrowLeft"/> - </event_variant> -</config> diff --git a/Modules/Core/resource/Interactions/DisplayConfigMITKNoCrosshair.xml b/Modules/Core/resource/Interactions/DisplayConfigMITKBase.xml similarity index 90% rename from Modules/Core/resource/Interactions/DisplayConfigMITKNoCrosshair.xml rename to Modules/Core/resource/Interactions/DisplayConfigMITKBase.xml index 8e9e78ebe1..beee9551aa 100644 --- a/Modules/Core/resource/Interactions/DisplayConfigMITKNoCrosshair.xml +++ b/Modules/Core/resource/Interactions/DisplayConfigMITKBase.xml @@ -1,49 +1,49 @@ <!-- * - MITK : The original interaction scheme -* - left mouse button : set crosshair +* - left mouse button : specified by secondary file (default: crosshair) * - middle mouse button : panning * - right mouse button : zooming * - wheel : scrolling --> <config> <!-- Zoom sensitivity --> <param name="zoomFactor" value="5"/> <!-- Zoom either by moving mouse leftright or updown --> <param name="zoomDirection" value="updown"/> - <!-- react to an event, even tough is was already processed by a DataInteractor--> + <!-- react to an event, even though it was already processed by a DataInteractor--> <param name="alwaysReact" value="false"/> <!-- Moving --> <event_variant class="MousePressEvent" name="StartMove"> <attribute name="EventButton" value="MiddleMouseButton"/> </event_variant> - <event_variant class="MouseReleaseEvent" name="EndMoving"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> <event_variant class="MouseMoveEvent" name="Moving"> <attribute name="ButtonState" value="MiddleMouseButton"/> </event_variant> + <event_variant class="MouseReleaseEvent" name="EndMoving"> + <attribute name="EventButton" value="MiddleMouseButton"/> + </event_variant> <!-- Zooming --> <event_variant class="MousePressEvent" name="StartZoom"> <attribute name="EventButton" value="RightMouseButton"/> </event_variant> <event_variant class="MouseMoveEvent" name="Zooming"> <attribute name="ButtonState" value="RightMouseButton"/> </event_variant> <event_variant class="MouseReleaseEvent" name="EndZooming"> <attribute name="EventButton" value="RightMouseButton"/> </event_variant> <!-- Scrolling through planes --> <event_variant class="MouseWheelEvent" name="PlaneUP"> <attribute name="ScrollDirection" value="up"/> </event_variant> <event_variant class="MouseWheelEvent" name="PlaneDown"> <attribute name="ScrollDirection" value="down"/> </event_variant> - <!-- Moving between time steps--> + <!-- Change TimeSteps --> <event_variant class="InteractionKeyEvent" name="IncreaseTimeStep"> <attribute name="Key" value="ArrowRight"/> </event_variant> <event_variant class="InteractionKeyEvent" name="DecreaseTimeStep"> <attribute name="Key" value="ArrowLeft"/> </event_variant> </config> diff --git a/Modules/Core/resource/Interactions/DisplayConfigMITKRotation.xml b/Modules/Core/resource/Interactions/DisplayConfigMITKRotation.xml deleted file mode 100644 index a2dfcd187b..0000000000 --- a/Modules/Core/resource/Interactions/DisplayConfigMITKRotation.xml +++ /dev/null @@ -1,54 +0,0 @@ -<!-- -* - MITK : The original interaction scheme -* - left mouse button : rotate -* - middle mouse button : panning -* - right mouse button : zooming -* - wheel : scrolling ---> -<config> - <!-- Zoom sensitivity --> - <param name="zoomFactor" value="5"/> - <!-- Zoom either by moving mouse leftright or updown --> - <param name="zoomDirection" value="updown"/> - <param name="coupled" value="true"/> - <!-- react to an event, even tough is was already processed by a DataInteractor--> - <param name="alwaysReact" value="false"/> - <!-- Crosshair --> - <event_variant class="MousePressEvent" name="StartRotate"> - <attribute name="EventButton" value="LeftMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Move"/> - <event_variant class="MouseMoveEvent" name="Rotate"> - <attribute name="ButtonState" value="LeftMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndRotate"> - <attribute name="EventButton" value="LeftMouseButton"/> - </event_variant> - <!-- Moving --> - <event_variant class="MousePressEvent" name="StartMove"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndMoving"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Moving"> - <attribute name="ButtonState" value="MiddleMouseButton"/> - </event_variant> - <!-- Zooming --> - <event_variant class="MousePressEvent" name="StartZoom"> - <attribute name="EventButton" value="RightMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Zooming"> - <attribute name="ButtonState" value="RightMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndZooming"> - <attribute name="EventButton" value="RightMouseButton"/> - </event_variant> - <!-- Scrolling through planes --> - <event_variant class="MouseWheelEvent" name="PlaneUP"> - <attribute name="ScrollDirection" value="up"/> - </event_variant> - <event_variant class="MouseWheelEvent" name="PlaneDown"> - <attribute name="ScrollDirection" value="down"/> - </event_variant> -</config> diff --git a/Modules/Core/resource/Interactions/DisplayConfigMITKRotationUnCoupled.xml b/Modules/Core/resource/Interactions/DisplayConfigMITKRotationUnCoupled.xml deleted file mode 100644 index 405c554908..0000000000 --- a/Modules/Core/resource/Interactions/DisplayConfigMITKRotationUnCoupled.xml +++ /dev/null @@ -1,54 +0,0 @@ -<!-- -* - MITK : The original interaction scheme -* - left mouse button : rotate -* - middle mouse button : panning -* - right mouse button : zooming -* - wheel : scrolling ---> -<config> - <!-- Zoom sensitivity --> - <param name="zoomFactor" value="5"/> - <!-- Zoom either by moving mouse leftright or updown --> - <param name="zoomDirection" value="updown"/> - <param name="coupled" value="false"/> - <!-- react to an event, even tough is was already processed by a DataInteractor--> - <param name="alwaysReact" value="false"/> - <!-- Crosshair --> - <event_variant class="MousePressEvent" name="StartRotate"> - <attribute name="EventButton" value="LeftMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Move"/> - <event_variant class="MouseMoveEvent" name="Rotate"> - <attribute name="ButtonState" value="LeftMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndRotate"> - <attribute name="EventButton" value="LeftMouseButton"/> - </event_variant> - <!-- Moving --> - <event_variant class="MousePressEvent" name="StartMove"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndMoving"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Moving"> - <attribute name="ButtonState" value="MiddleMouseButton"/> - </event_variant> - <!-- Zooming --> - <event_variant class="MousePressEvent" name="StartZoom"> - <attribute name="EventButton" value="RightMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Zooming"> - <attribute name="ButtonState" value="RightMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndZooming"> - <attribute name="EventButton" value="RightMouseButton"/> - </event_variant> - <!-- Scrolling through planes --> - <event_variant class="MouseWheelEvent" name="PlaneUP"> - <attribute name="ScrollDirection" value="up"/> - </event_variant> - <event_variant class="MouseWheelEvent" name="PlaneDown"> - <attribute name="ScrollDirection" value="down"/> - </event_variant> -</config> diff --git a/Modules/Core/resource/Interactions/DisplayConfigMITKSwivel.xml b/Modules/Core/resource/Interactions/DisplayConfigMITKSwivel.xml deleted file mode 100644 index 9cd3ea50c1..0000000000 --- a/Modules/Core/resource/Interactions/DisplayConfigMITKSwivel.xml +++ /dev/null @@ -1,54 +0,0 @@ -<!-- -* - MITK : The original interaction scheme -* - left mouse button : swivel -* - middle mouse button : panning -* - right mouse button : zooming -* - wheel : scrolling ---> -<config> - <!-- Zoom sensitivity --> - <param name="zoomFactor" value="5"/> - <param name="coupled" value="false"/> - <!-- Zoom either by moving mouse leftright or updown --> - <param name="zoomDirection" value="updown"/> - <!-- react to an event, even tough is was already processed by a DataInteractor--> - <param name="alwaysReact" value="false"/> - <!-- Crosshair --> - <event_variant class="MousePressEvent" name="StartSwivel"> - <attribute name="EventButton" value="LeftMouseButton"/> - </event_variant> - - <event_variant class="MouseMoveEvent" name="Swivel"> - <attribute name="ButtonState" value="LeftMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndSwivel"> - <attribute name="EventButton" value="LeftMouseButton"/> - </event_variant> - <!-- Moving --> - <event_variant class="MousePressEvent" name="StartMove"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndMoving"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Moving"> - <attribute name="ButtonState" value="MiddleMouseButton"/> - </event_variant> - <!-- Zooming --> - <event_variant class="MousePressEvent" name="StartZoom"> - <attribute name="EventButton" value="RightMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Zooming"> - <attribute name="ButtonState" value="RightMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndZooming"> - <attribute name="EventButton" value="RightMouseButton"/> - </event_variant> - <!-- Scrolling through planes --> - <event_variant class="MouseWheelEvent" name="PlaneUP"> - <attribute name="ScrollDirection" value="up"/> - </event_variant> - <event_variant class="MouseWheelEvent" name="PlaneDown"> - <attribute name="ScrollDirection" value="down"/> - </event_variant> -</config> diff --git a/Modules/Core/resource/Interactions/DisplayConfigPACS.xml b/Modules/Core/resource/Interactions/DisplayConfigPACSBase.xml similarity index 69% rename from Modules/Core/resource/Interactions/DisplayConfigPACS.xml rename to Modules/Core/resource/Interactions/DisplayConfigPACSBase.xml index 5183391440..5259c473e8 100644 --- a/Modules/Core/resource/Interactions/DisplayConfigPACS.xml +++ b/Modules/Core/resource/Interactions/DisplayConfigPACSBase.xml @@ -1,62 +1,75 @@ +<!-- +* - PACS : The original interaction scheme +* - left mouse button : UNUSED +* - middle mouse button : UNUSED +* - right mouse button +* with shift modifier : moving +* - right mouse button +* with ctrl modifier : zooming +* - right mouse button : adjust level window +* - wheel : scrolling +--> <config> <!-- Zoom sensitivity --> <param name="zoomFactor" value="5"/> - <!-- Zoom either by moving mouse leftright or updown --> + <!-- Zoom either by moving mouse left-right or up-down --> <param name="zoomDirection" value="updown"/> - <!-- scrolling either by moving mouse leftright or updown --> + <!-- scrolling either by moving mouse left-right or up-down --> <param name="scrollDirection" value="updown"/> <!-- Sets how many pixel the mouse has to be moved for scrolling 1 slice--> <param name="pixelPerSlice" value="3"/> <!-- when scrolling restart at beginning of volume, when end is reached--> <param name="autoRepeat" value="true"/> - <!-- react to an event, even tough is was already processed by a DataInteractor--> + <!-- react to an event, even though it was already processed by a DataInteractor--> <param name="alwaysReact" value="true"/> - <!-- Moving --> + + <!-- Right mouse with shift modifier: Moving --> <event_variant class="MousePressEvent" name="StartMove"> <attribute name="EventButton" value="RightMouseButton"/> <attribute name="Modifiers" value="shift"/> </event_variant> <event_variant class="MouseReleaseEvent" name="EndMoving"> <attribute name="EventButton" value="RightMouseButton"/> <attribute name="Modifiers" value="shift"/> </event_variant> <event_variant class="MouseMoveEvent" name="Moving"> <attribute name="ButtonState" value="RightMouseButton"/> <attribute name="Modifiers" value="shift"/> </event_variant> - <!-- Zooming --> + + <!-- Right mouse with ctrl modifier: Zooming --> <event_variant class="MousePressEvent" name="StartZoom"> <attribute name="EventButton" value="RightMouseButton"/> <attribute name="Modifiers" value="ctrl"/> </event_variant> <event_variant class="MouseMoveEvent" name="Zooming"> <attribute name="ButtonState" value="RightMouseButton"/> <attribute name="Modifiers" value="ctrl"/> </event_variant> <event_variant class="MouseReleaseEvent" name="EndZooming"> <attribute name="EventButton" value="RightMouseButton"/> <attribute name="Modifiers" value="ctrl"/> </event_variant> - <!-- scrolling --> - <event_variant class="MousePressEvent" name="StartScroll"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseReleaseEvent" name="EndScrolling"> - <attribute name="EventButton" value="MiddleMouseButton"/> - </event_variant> - <event_variant class="MouseMoveEvent" name="Scrolling"> - <attribute name="ButtonState" value="MiddleMouseButton"/> - </event_variant> - <!-- LevelWindow --> + + <!-- Right mouse: LevelWindow adjusting--> <event_variant class="MousePressEvent" name="StartAdjustLevelWindow"> <attribute name="EventButton" value="RightMouseButton"/> </event_variant> <event_variant class="MouseReleaseEvent" name="EndLevelWindow"> <attribute name="EventButton" value="RightMouseButton"/> </event_variant> <event_variant class="MouseMoveEvent" name="adjustlevelwindow"> <attribute name="ButtonState" value="RightMouseButton"/> </event_variant> + + <!-- Mouse wheel: Scrolling through planes --> + <event_variant class="MouseWheelEvent" name="PlaneUP"> + <attribute name="ScrollDirection" value="up"/> + </event_variant> + <event_variant class="MouseWheelEvent" name="PlaneDown"> + <attribute name="ScrollDirection" value="down"/> + </event_variant> + <!-- General --> <event_variant class="MouseMoveEvent" name="ResetState"/> </config> diff --git a/Modules/Core/resource/Interactions/DisplayConfigRotation.xml b/Modules/Core/resource/Interactions/DisplayConfigRotation.xml new file mode 100644 index 0000000000..0b351c4d52 --- /dev/null +++ b/Modules/Core/resource/Interactions/DisplayConfigRotation.xml @@ -0,0 +1,14 @@ +<!-- left mouse button : rotate --> +<config> + <param name="coupled" value="false"/> + <event_variant class="MousePressEvent" name="StartRotate"> + <attribute name="EventButton" value="LeftMouseButton"/> + </event_variant> + <event_variant class="MouseMoveEvent" name="Move"/> + <event_variant class="MouseMoveEvent" name="Rotate"> + <attribute name="ButtonState" value="LeftMouseButton"/> + </event_variant> + <event_variant class="MouseReleaseEvent" name="EndRotate"> + <attribute name="EventButton" value="LeftMouseButton"/> + </event_variant> +</config> diff --git a/Modules/Core/resource/Interactions/DisplayConfigPACSCrosshair.xml b/Modules/Core/resource/Interactions/DisplayConfigSwivel.xml similarity index 54% rename from Modules/Core/resource/Interactions/DisplayConfigPACSCrosshair.xml rename to Modules/Core/resource/Interactions/DisplayConfigSwivel.xml index 88430a286d..1cb4a69094 100644 --- a/Modules/Core/resource/Interactions/DisplayConfigPACSCrosshair.xml +++ b/Modules/Core/resource/Interactions/DisplayConfigSwivel.xml @@ -1,11 +1,12 @@ <config> - <event_variant class="MousePressEvent" name="SetCrosshair"> + <param name="coupled" value="false"/> + <event_variant class="MousePressEvent" name="StartSwivel"> <attribute name="EventButton" value="LeftMouseButton"/> </event_variant> - <event_variant class="MouseMoveEvent" name="MoveCrosshair"> + <event_variant class="MouseMoveEvent" name="Swivel"> <attribute name="ButtonState" value="LeftMouseButton"/> </event_variant> - <event_variant class="MouseReleaseEvent" name="EndMoveCrosshair"> + <event_variant class="MouseReleaseEvent" name="EndSwivel"> <attribute name="EventButton" value="LeftMouseButton"/> </event_variant> </config> diff --git a/Modules/Core/resource/Interactions/DisplayInteraction.xml b/Modules/Core/resource/Interactions/DisplayInteraction.xml index acf53f7cd8..81e8d9e23f 100644 --- a/Modules/Core/resource/Interactions/DisplayInteraction.xml +++ b/Modules/Core/resource/Interactions/DisplayInteraction.xml @@ -1,171 +1,175 @@ <!-- State machine pattern for display interactions: -Zooming -Panning -Scrolling through planes -Adjusting the LevelWindow For some interactions several transitions exists, which one is used can be determined by the configuration file. If an event_variant is not declared in the configuration file it is disabled. For example scrolling can be triggered by Key-, Wheel- or MouseMove events, where the latter needs an extra state for scrolling. So they are triggered by different event_variants, to choose which one is used, describe the desired event_variant in a config file and omit the others. See DisplayConfig___ for examples and also for parameters for the interaction behaviour. TODO Std move to abort interaction of scroll/pan/zoom --> <statemachine> <state name="start" startstate="true" > <transition event_class="InteractionPositionEvent" event_variant="StartMove" target="move"> <condition name="check_position_event"/> <action name="init"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="StartZoom" target="zoom"> <condition name="check_position_event"/> <action name="init"/> </transition> - <!-- mitkDispplayInteractor.cpp implements this for all events --> + <!-- mitkDisplayInteractor.cpp implements this for all events --> <transition event_class="InteractionEvent" event_variant="PlaneUP" target="start"> <action name="ScrollOneUp"/> <action name="updateStatusbar"/> </transition> <transition event_class="InteractionEvent" event_variant="PlaneDown" target="start"> <action name="ScrollOneDown"/> <action name="updateStatusbar"/> </transition> <transition event_class="MousePressEvent" event_variant="StartScroll" target="scroll"> <action name="init"/> </transition> <transition event_class="MousePressEvent" event_variant="StartAdjustLevelWindow" target="adjustlevelwindow"> <action name="init"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="SetCrosshair" target="crosshair"> <action name="setCrosshair"/> <action name="updateStatusbar"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="Move" target="rotationPossible"> <condition name="check_can_rotate"/> <action name="startRotation"/> </transition> <!-- Case when we do crosshair instead of rotation) --> <transition event_class="InteractionPositionEvent" event_variant="StartRotate" target="crosshair"> <condition name="check_can_rotate" inverted="true" /> + <action name="setCrosshair"/> + <action name="updateStatusbar"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="StartSwivel" target="swivel"> <condition name="check_can_swivel"/> </transition> <!-- Case when we do crosshair instead of swivel) --> <transition event_class="InteractionPositionEvent" event_variant="StartSwivel" target="crosshair"> <condition name="check_can_swivel" inverted="true"/> + <action name="setCrosshair"/> + <action name="updateStatusbar"/> </transition> <!-- Change TimeSteps by clicking left or right Arrow--> <transition event_class="InteractionEvent" event_variant="IncreaseTimeStep" target="start"> <action name="IncreaseTimeStep"/> </transition> <transition event_class="InteractionEvent" event_variant="DecreaseTimeStep" target="start"> <action name="DecreaseTimeStep"/> </transition> </state> <state name="crosshair"> <transition event_class="InteractionPositionEvent" event_variant="MoveCrosshair" target="crosshair"> <action name="setCrosshair"/> <action name="updateStatusbar"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndMoveCrosshair" target="start"/> <!-- Case when we jumped in from rotation (wanted to rotate, but not possible, so alternative action is to set crosshair) --> <transition event_class="InteractionPositionEvent" event_variant="Rotate" target="crosshair"> <action name="setCrosshair"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndRotate" target="start"/> <!-- Case when we do crosshair instead of swivel) --> <transition event_class="InteractionPositionEvent" event_variant="Swivel" target="crosshair"> <action name="setCrosshair"/> <action name="updateStatusbar"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndSwivel" target="start"/> <transition event_class="InteractionEvent" event_variant="ResetState" target="start"/> </state> <state name="move"> <transition event_class="InteractionPositionEvent" event_variant="Moving" target="move"> <condition name="check_position_event"/> <action name="move"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndMoving" target="start"/> <transition event_class="InteractionEvent" event_variant="ResetState" target="start"/> </state> <state name="zoom"> <transition event_class="InteractionPositionEvent" event_variant="Zooming" target="zoom"> <condition name="check_position_event"/> <action name="zoom"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndZooming" target="start"/> <transition event_class="InteractionEvent" event_variant="ResetState" target="start"/> </state> <state name="scroll"> <transition event_class="InteractionPositionEvent" event_variant="Scrolling" target="scroll"> <condition name="check_position_event"/> <action name="scroll"/> <action name="updateStatusbar"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndScrolling" target="start"/> <transition event_class="InteractionPositionEvent" event_variant="EndScrollingVar" target="start"/> <transition event_class="InteractionEvent" event_variant="ResetState" target="start"/> </state> <state name="adjustlevelwindow"> <transition event_class="InteractionPositionEvent" event_variant="adjustlevelwindow" target="adjustlevelwindow"> <condition name="check_position_event"/> <action name="levelWindow"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndLevelWindow" target="start"/> <transition event_class="InteractionEvent" event_variant="ResetState" target="start"/> </state> <state name="rotationPossible"> <transition event_class="InteractionPositionEvent" event_variant="StartRotate" target="rotation"> <action name="rotate"/> </transition> - <transition event_class="InternalEvent" event_variant="LeaveRenderWindow" target="start"> - <action name="endRotation"/> - </transition> + <transition event_class="InternalEvent" event_variant="LeaveRenderWindow" target="start"> + <action name="endRotation"/> + </transition> <transition event_class="InteractionPositionEvent" event_variant="Move" target="start"> <condition name="check_can_rotate" inverted="true" /> <action name="endRotation"/> </transition> <transition event_class="InteractionEvent" event_variant="PlaneUP" target="rotationPossible"> <action name="ScrollOneUp"/> <action name="updateStatusbar"/> </transition> <transition event_class="InteractionEvent" event_variant="PlaneDown" target="rotationPossible"> <action name="ScrollOneDown"/> <action name="updateStatusbar"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="StartMove" target="move"> <condition name="check_position_event"/> <action name="init"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="StartZoom" target="zoom"> <condition name="check_position_event"/> <action name="init"/> </transition> <transition event_class="InteractionEvent" event_variant="ResetState" target="start"/> </state> <state name="rotation"> <transition event_class="InteractionPositionEvent" event_variant="Rotate" target="rotation"> <action name="rotate"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndRotate" target="start"> <action name="endRotation"/> </transition> <transition event_class="InteractionEvent" event_variant="ResetState" target="start"/> </state> <state name="swivel"> <transition event_class="InteractionPositionEvent" event_variant="Swivel" target="swivel"> <action name="swivel"/> </transition> <transition event_class="InteractionPositionEvent" event_variant="EndSwivel" target="start"/> <transition event_class="InteractionEvent" event_variant="ResetState" target="start"/> </state> </statemachine> diff --git a/Modules/Core/src/Algorithms/mitkImageToSurfaceFilter.cpp b/Modules/Core/src/Algorithms/mitkImageToSurfaceFilter.cpp index 46da45fdaf..be0fc11b2c 100644 --- a/Modules/Core/src/Algorithms/mitkImageToSurfaceFilter.cpp +++ b/Modules/Core/src/Algorithms/mitkImageToSurfaceFilter.cpp @@ -1,230 +1,230 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkException.h" #include <mitkImageToSurfaceFilter.h> #include <vtkDecimatePro.h> #include <vtkImageChangeInformation.h> #include <vtkImageData.h> #include <vtkLinearTransform.h> #include <vtkMath.h> #include <vtkMatrix4x4.h> #include <vtkQuadricDecimation.h> #include <vtkCleanPolyData.h> #include <vtkPolyDataNormals.h> #include <vtkSmartPointer.h> #include "mitkProgressBar.h" mitk::ImageToSurfaceFilter::ImageToSurfaceFilter() : m_Smooth(false), m_Decimate(NoDecimation), m_Threshold(1.0), m_TargetReduction(0.95f), m_SmoothIteration(50), m_SmoothRelaxation(0.1) { } mitk::ImageToSurfaceFilter::~ImageToSurfaceFilter() { } void mitk::ImageToSurfaceFilter::CreateSurface(int time, vtkImageData *vtkimage, mitk::Surface *surface, const ScalarType threshold) { vtkImageChangeInformation *indexCoordinatesImageFilter = vtkImageChangeInformation::New(); indexCoordinatesImageFilter->SetInputData(vtkimage); indexCoordinatesImageFilter->SetOutputOrigin(0.0, 0.0, 0.0); // MarchingCube -->create Surface vtkSmartPointer<vtkMarchingCubes> skinExtractor = vtkSmartPointer<vtkMarchingCubes>::New(); skinExtractor->ComputeScalarsOff(); skinExtractor->SetInputConnection(indexCoordinatesImageFilter->GetOutputPort()); // RC++ indexCoordinatesImageFilter->Delete(); skinExtractor->SetValue(0, threshold); vtkPolyData *polydata; skinExtractor->Update(); polydata = skinExtractor->GetOutput(); polydata->Register(nullptr); // RC++ - if (m_Smooth) + if (m_Smooth && polydata->GetNumberOfPoints() > 0 && polydata->GetNumberOfCells() > 0) { vtkSmoothPolyDataFilter *smoother = vtkSmoothPolyDataFilter::New(); // read poly1 (poly1 can be the original polygon, or the decimated polygon) smoother->SetInputConnection(skinExtractor->GetOutputPort()); // RC++ smoother->SetNumberOfIterations(m_SmoothIteration); smoother->SetRelaxationFactor(m_SmoothRelaxation); smoother->SetFeatureAngle(60); smoother->FeatureEdgeSmoothingOff(); smoother->BoundarySmoothingOff(); smoother->SetConvergence(0); smoother->Update(); polydata->Delete(); // RC-- polydata = smoother->GetOutput(); polydata->Register(nullptr); // RC++ smoother->Delete(); } ProgressBar::GetInstance()->Progress(); // decimate = to reduce number of polygons if (m_Decimate == DecimatePro) { vtkDecimatePro *decimate = vtkDecimatePro::New(); decimate->SplittingOff(); decimate->SetErrorIsAbsolute(5); decimate->SetFeatureAngle(30); decimate->PreserveTopologyOn(); decimate->BoundaryVertexDeletionOff(); decimate->SetDegree(10); // std-value is 25! decimate->SetInputData(polydata); // RC++ decimate->SetTargetReduction(m_TargetReduction); decimate->SetMaximumError(0.002); decimate->Update(); polydata->Delete(); // RC-- polydata = decimate->GetOutput(); polydata->Register(nullptr); // RC++ decimate->Delete(); } else if (m_Decimate == QuadricDecimation) { vtkQuadricDecimation *decimate = vtkQuadricDecimation::New(); decimate->SetTargetReduction(m_TargetReduction); decimate->SetInputData(polydata); decimate->Update(); polydata->Delete(); polydata = decimate->GetOutput(); polydata->Register(nullptr); decimate->Delete(); } ProgressBar::GetInstance()->Progress(); if (polydata->GetNumberOfPoints() > 0) { mitk::Vector3D spacing = GetInput()->GetGeometry(time)->GetSpacing(); vtkPoints *points = polydata->GetPoints(); vtkMatrix4x4 *vtkmatrix = vtkMatrix4x4::New(); GetInput()->GetGeometry(time)->GetVtkTransform()->GetMatrix(vtkmatrix); double(*matrix)[4] = vtkmatrix->Element; unsigned int i, j; for (i = 0; i < 3; ++i) for (j = 0; j < 3; ++j) matrix[i][j] /= spacing[j]; unsigned int n = points->GetNumberOfPoints(); double point[3]; for (i = 0; i < n; i++) { points->GetPoint(i, point); mitkVtkLinearTransformPoint(matrix, point, point); points->SetPoint(i, point); } vtkmatrix->Delete(); } ProgressBar::GetInstance()->Progress(); // determine point_data normals for the poly data points. vtkSmartPointer<vtkPolyDataNormals> normalsGenerator = vtkSmartPointer<vtkPolyDataNormals>::New(); normalsGenerator->SetInputData(polydata); normalsGenerator->FlipNormalsOn(); vtkSmartPointer<vtkCleanPolyData> cleanPolyDataFilter = vtkSmartPointer<vtkCleanPolyData>::New(); cleanPolyDataFilter->SetInputConnection(normalsGenerator->GetOutputPort()); cleanPolyDataFilter->PieceInvariantOff(); cleanPolyDataFilter->ConvertLinesToPointsOff(); cleanPolyDataFilter->ConvertPolysToLinesOff(); cleanPolyDataFilter->ConvertStripsToPolysOff(); cleanPolyDataFilter->PointMergingOn(); cleanPolyDataFilter->Update(); surface->SetVtkPolyData(cleanPolyDataFilter->GetOutput(), time); polydata->UnRegister(nullptr); } void mitk::ImageToSurfaceFilter::GenerateData() { mitk::Surface *surface = this->GetOutput(); auto *image = (mitk::Image *)GetInput(); if (image == nullptr || !image->IsInitialized()) mitkThrow() << "No input image set, please set an valid input image!"; mitk::Image::RegionType outputRegion = image->GetRequestedRegion(); int tstart = outputRegion.GetIndex(3); int tmax = tstart + outputRegion.GetSize(3); // GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgeloest if ((tmax - tstart) > 0) { ProgressBar::GetInstance()->AddStepsToDo(4 * (tmax - tstart)); } int t; for (t = tstart; t < tmax; ++t) { vtkImageData *vtkimagedata = image->GetVtkImageData(t); CreateSurface(t, vtkimagedata, surface, m_Threshold); ProgressBar::GetInstance()->Progress(); } } void mitk::ImageToSurfaceFilter::SetSmoothIteration(int smoothIteration) { m_SmoothIteration = smoothIteration; } void mitk::ImageToSurfaceFilter::SetSmoothRelaxation(float smoothRelaxation) { m_SmoothRelaxation = smoothRelaxation; } void mitk::ImageToSurfaceFilter::SetInput(const mitk::Image *image) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput(0, const_cast<mitk::Image *>(image)); } const mitk::Image *mitk::ImageToSurfaceFilter::GetInput(void) { if (this->GetNumberOfInputs() < 1) { return nullptr; } return static_cast<const mitk::Image *>(this->ProcessObject::GetInput(0)); } void mitk::ImageToSurfaceFilter::GenerateOutputInformation() { mitk::Image::ConstPointer inputImage = (mitk::Image *)this->GetInput(); // mitk::Image *inputImage = (mitk::Image*)this->GetImage(); mitk::Surface::Pointer output = this->GetOutput(); itkDebugMacro(<< "GenerateOutputInformation()"); if (inputImage.IsNull()) return; // Set Data } diff --git a/Modules/Core/src/Controllers/mitkStepper.cpp b/Modules/Core/src/Controllers/mitkStepper.cpp index 24099f682a..57acf82314 100644 --- a/Modules/Core/src/Controllers/mitkStepper.cpp +++ b/Modules/Core/src/Controllers/mitkStepper.cpp @@ -1,205 +1,212 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkStepper.h" mitk::Stepper::Stepper() : m_Pos(0), m_Steps(0), m_AutoRepeat(false), m_PingPong(false), m_InverseDirection(false), m_RangeMin(0.0), m_RangeMax(-1.0), m_RangeValid(false), m_HasRange(false), m_HasUnitName(false) { } mitk::Stepper::~Stepper() { } void mitk::Stepper::SetRange(ScalarType min, ScalarType max) { m_RangeMin = min; m_RangeMax = max; m_HasRange = true; m_RangeValid = true; this->Modified(); } void mitk::Stepper::InvalidateRange() { m_HasRange = true; m_RangeValid = false; this->Modified(); } mitk::ScalarType mitk::Stepper::GetRangeMin() const { return m_RangeMin; } mitk::ScalarType mitk::Stepper::GetRangeMax() const { return m_RangeMax; } void mitk::Stepper::RemoveRange() { m_HasRange = false; this->Modified(); } bool mitk::Stepper::HasValidRange() const { return (m_HasRange && m_RangeValid); } bool mitk::Stepper::HasRange() const { return m_HasRange; } void mitk::Stepper::SetUnitName(const char *unitName) { m_UnitName = std::string(unitName); m_HasUnitName = true; this->Modified(); } const char *mitk::Stepper::GetUnitName() const { return m_UnitName.c_str(); } void mitk::Stepper::RemoveUnitName() { m_HasUnitName = false; this->Modified(); } bool mitk::Stepper::HasUnitName() const { return m_HasUnitName; } void mitk::Stepper::Increase() { if (this->GetPos() < this->GetSteps() - 1) { this->SetPos(this->GetPos() + 1); } else if (m_AutoRepeat) { if (!m_PingPong) { this->SetPos(0); } else { m_InverseDirection = true; if (this->GetPos() > 0) { this->SetPos(this->GetPos() - 1); } } } } void mitk::Stepper::Decrease() { if (this->GetPos() > 0) { this->SetPos(this->GetPos() - 1); } else if (m_AutoRepeat) { if (!m_PingPong) { this->SetPos(this->GetSteps() - 1); } else { m_InverseDirection = false; if (this->GetPos() < this->GetSteps() - 1) { this->SetPos(this->GetPos() + 1); } } } } void mitk::Stepper::Next() { if (!m_InverseDirection) { this->Increase(); } else { this->Decrease(); } } void mitk::Stepper::Previous() { if (!m_InverseDirection) { this->Decrease(); } else { this->Increase(); } } void mitk::Stepper::MoveSlice(int sliceDelta) { - int newPosition = this->GetPos() + sliceDelta; - // if auto repeat is on, increasing continues at the first slice if the last slice was reached and vice versa int maxSlices = this->GetSteps(); + if (0 == maxSlices) + { + // cannot move slice if no slices available (no image loaded) + return; + } + + int newPosition = this->GetPos() + sliceDelta; + if (m_AutoRepeat) { + // if auto repeat is on, increasing continues at the first slice if the last slice was reached and vice versa while (newPosition < 0) { newPosition += maxSlices; } while (newPosition >= maxSlices) { newPosition -= maxSlices; } } else { // if the new slice is below 0 we still show slice 0 // due to the stepper using unsigned int we have to do this ourselves if (newPosition < 1) { newPosition = 0; } } this->SetPos(newPosition); } void mitk::Stepper::First() { this->SetPos(0); } void mitk::Stepper::Last() { this->SetPos(this->GetSteps() - 1); } diff --git a/Modules/Core/src/DataManagement/mitkImage.cpp b/Modules/Core/src/DataManagement/mitkImage.cpp index 251e1ca36f..bd5ba5e95d 100644 --- a/Modules/Core/src/DataManagement/mitkImage.cpp +++ b/Modules/Core/src/DataManagement/mitkImage.cpp @@ -1,1369 +1,1358 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // MITK #include "mitkImage.h" #include "mitkCompareImageDataFilter.h" #include "mitkImageStatisticsHolder.h" #include "mitkImageVtkReadAccessor.h" #include "mitkImageVtkWriteAccessor.h" #include "mitkPixelTypeMultiplex.h" #include <mitkProportionalTimeGeometry.h> // VTK #include <vtkImageData.h> // ITK #include <itkMutexLockHolder.h> // Other #include <cmath> #define FILL_C_ARRAY(_arr, _size, _value) \ for (unsigned int i = 0u; i < _size; i++) \ \ { \ _arr[i] = _value; \ } mitk::Image::Image() : m_Dimension(0), m_Dimensions(nullptr), m_ImageDescriptor(nullptr), m_OffsetTable(nullptr), m_CompleteData(nullptr), m_ImageStatistics(nullptr) { m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS]; FILL_C_ARRAY(m_Dimensions, MAX_IMAGE_DIMENSIONS, 0u); m_Initialized = false; } mitk::Image::Image(const Image &other) : SlicedData(other), m_Dimension(0), m_Dimensions(nullptr), m_ImageDescriptor(nullptr), m_OffsetTable(nullptr), m_CompleteData(nullptr), m_ImageStatistics(nullptr) { m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS]; FILL_C_ARRAY(m_Dimensions, MAX_IMAGE_DIMENSIONS, 0u); this->Initialize(other.GetPixelType(), other.GetDimension(), other.GetDimensions()); // Since the above called "Initialize" method doesn't take the geometry into account we need to set it // here manually TimeGeometry::Pointer cloned = other.GetTimeGeometry()->Clone(); this->SetTimeGeometry(cloned.GetPointer()); if (this->GetDimension() > 3) { const unsigned int time_steps = this->GetDimension(3); for (unsigned int i = 0u; i < time_steps; ++i) { ImageDataItemPointer volume = other.GetVolumeData(i); this->SetVolume(volume->GetData(), i); } } else { ImageDataItemPointer volume = other.GetVolumeData(0); this->SetVolume(volume->GetData(), 0); } } mitk::Image::~Image() { this->Clear(); m_ReferenceCount = 3; m_ReferenceCount = 0; delete[] m_OffsetTable; delete m_ImageStatistics; } const mitk::PixelType mitk::Image::GetPixelType(int n) const { return this->m_ImageDescriptor->GetChannelTypeById(n); } unsigned int mitk::Image::GetDimension() const { return m_Dimension; } unsigned int mitk::Image::GetDimension(int i) const { if ((i >= 0) && (i < (int)m_Dimension)) return m_Dimensions[i]; return 1; } template <class T> void AccessPixel(const mitk::PixelType ptype, void *data, const unsigned int offset, double &value) { value = 0.0; if (data == nullptr) return; if (ptype.GetBpe() != 24) { value = (double)(((T *)data)[offset]); } else { const unsigned int rgboffset = offset; double returnvalue = (((T *)data)[rgboffset]); returnvalue += (((T *)data)[rgboffset + 1]); returnvalue += (((T *)data)[rgboffset + 2]); value = returnvalue; } } vtkImageData *mitk::Image::GetVtkImageData(int t, int n) { if (m_Initialized == false) { if (GetSource().IsNull()) return nullptr; if (GetSource()->Updating() == false) GetSource()->UpdateOutputInformation(); } ImageDataItemPointer volume = GetVolumeData(t, n); return volume.GetPointer() == nullptr ? nullptr : volume->GetVtkImageAccessor(this)->GetVtkImageData(); } const vtkImageData *mitk::Image::GetVtkImageData(int t, int n) const { if (m_Initialized == false) { if (GetSource().IsNull()) return nullptr; if (GetSource()->Updating() == false) GetSource()->UpdateOutputInformation(); } ImageDataItemPointer volume = GetVolumeData(t, n); return volume.GetPointer() == nullptr ? nullptr : volume->GetVtkImageAccessor(this)->GetVtkImageData(); } mitk::Image::ImageDataItemPointer mitk::Image::GetSliceData( int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const { MutexHolder lock(m_ImageDataArraysLock); return GetSliceData_unlocked(s, t, n, data, importMemoryManagement); } mitk::Image::ImageDataItemPointer mitk::Image::GetSliceData_unlocked( int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const { if (IsValidSlice(s, t, n) == false) return nullptr; const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); // slice directly available? int pos = GetSliceIndex(s, t, n); if (m_Slices[pos].GetPointer() != nullptr) { return m_Slices[pos]; } // is slice available as part of a volume that is available? ImageDataItemPointer sl, ch, vol; vol = m_Volumes[GetVolumeIndex(t, n)]; if ((vol.GetPointer() != nullptr) && (vol->IsComplete())) { sl = new ImageDataItem(*vol, m_ImageDescriptor, t, 2, data, importMemoryManagement == ManageMemory, ((size_t)s) * m_OffsetTable[2] * (ptypeSize)); sl->SetComplete(true); return m_Slices[pos] = sl; } // is slice available as part of a channel that is available? ch = m_Channels[n]; if ((ch.GetPointer() != nullptr) && (ch->IsComplete())) { sl = new ImageDataItem(*ch, m_ImageDescriptor, t, 2, data, importMemoryManagement == ManageMemory, (((size_t)s) * m_OffsetTable[2] + ((size_t)t) * m_OffsetTable[3]) * (ptypeSize)); sl->SetComplete(true); return m_Slices[pos] = sl; } // slice is unavailable. Can we calculate it? if ((GetSource().IsNotNull()) && (GetSource()->Updating() == false)) { // ... wir mussen rechnen!!! .... m_RequestedRegion.SetIndex(0, 0); m_RequestedRegion.SetIndex(1, 0); m_RequestedRegion.SetIndex(2, s); m_RequestedRegion.SetIndex(3, t); m_RequestedRegion.SetIndex(4, n); m_RequestedRegion.SetSize(0, m_Dimensions[0]); m_RequestedRegion.SetSize(1, m_Dimensions[1]); m_RequestedRegion.SetSize(2, 1); m_RequestedRegion.SetSize(3, 1); m_RequestedRegion.SetSize(4, 1); m_RequestedRegionInitialized = true; GetSource()->Update(); if (IsSliceSet_unlocked(s, t, n)) // yes: now we can call ourselves without the risk of a endless loop (see "if" above) return GetSliceData_unlocked(s, t, n, data, importMemoryManagement); else return nullptr; } else { ImageDataItemPointer item = AllocateSliceData_unlocked(s, t, n, data, importMemoryManagement); item->SetComplete(true); return item; } } mitk::Image::ImageDataItemPointer mitk::Image::GetVolumeData(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const { MutexHolder lock(m_ImageDataArraysLock); return GetVolumeData_unlocked(t, n, data, importMemoryManagement); } mitk::Image::ImageDataItemPointer mitk::Image::GetVolumeData_unlocked( int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const { if (IsValidVolume(t, n) == false) return nullptr; ImageDataItemPointer ch, vol; // volume directly available? int pos = GetVolumeIndex(t, n); vol = m_Volumes[pos]; if ((vol.GetPointer() != nullptr) && (vol->IsComplete())) return vol; const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); // is volume available as part of a channel that is available? ch = m_Channels[n]; if ((ch.GetPointer() != nullptr) && (ch->IsComplete())) { vol = new ImageDataItem(*ch, m_ImageDescriptor, t, 3, data, importMemoryManagement == ManageMemory, (((size_t)t) * m_OffsetTable[3]) * (ptypeSize)); vol->SetComplete(true); return m_Volumes[pos] = vol; } // let's see if all slices of the volume are set, so that we can (could) combine them to a volume bool complete = true; unsigned int s; for (s = 0; s < m_Dimensions[2]; ++s) { if (m_Slices[GetSliceIndex(s, t, n)].GetPointer() == nullptr) { complete = false; break; } } if (complete) { // if there is only single slice we do not need to combine anything if (m_Dimensions[2] <= 1) { ImageDataItemPointer sl; sl = GetSliceData_unlocked(0, t, n, data, importMemoryManagement); vol = new ImageDataItem(*sl, m_ImageDescriptor, t, 3, data, importMemoryManagement == ManageMemory); vol->SetComplete(true); } else { mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(n); vol = m_Volumes[pos]; // ok, let's combine the slices! if (vol.GetPointer() == nullptr) { vol = new ImageDataItem(chPixelType, t, 3, m_Dimensions, nullptr, true); } vol->SetComplete(true); size_t size = m_OffsetTable[2] * (ptypeSize); for (s = 0; s < m_Dimensions[2]; ++s) { int posSl; ImageDataItemPointer sl; posSl = GetSliceIndex(s, t, n); sl = m_Slices[posSl]; if (sl->GetParent() != vol) { // copy data of slices in volume size_t offset = ((size_t)s) * size; std::memcpy(static_cast<char *>(vol->GetData()) + offset, sl->GetData(), size); - // FIXME mitkIpPicDescriptor * pic = sl->GetPicDescriptor(); - // replace old slice with reference to volume sl = new ImageDataItem( *vol, m_ImageDescriptor, t, 2, data, importMemoryManagement == ManageMemory, ((size_t)s) * size); sl->SetComplete(true); - // mitkIpFuncCopyTags(sl->GetPicDescriptor(), pic); m_Slices[posSl] = sl; } } - // if(vol->GetPicDescriptor()->info->tags_head==nullptr) - // mitkIpFuncCopyTags(vol->GetPicDescriptor(), m_Slices[GetSliceIndex(0,t,n)]->GetPicDescriptor()); } return m_Volumes[pos] = vol; } // volume is unavailable. Can we calculate it? if ((GetSource().IsNotNull()) && (GetSource()->Updating() == false)) { // ... wir muessen rechnen!!! .... m_RequestedRegion.SetIndex(0, 0); m_RequestedRegion.SetIndex(1, 0); m_RequestedRegion.SetIndex(2, 0); m_RequestedRegion.SetIndex(3, t); m_RequestedRegion.SetIndex(4, n); m_RequestedRegion.SetSize(0, m_Dimensions[0]); m_RequestedRegion.SetSize(1, m_Dimensions[1]); m_RequestedRegion.SetSize(2, m_Dimensions[2]); m_RequestedRegion.SetSize(3, 1); m_RequestedRegion.SetSize(4, 1); m_RequestedRegionInitialized = true; GetSource()->Update(); if (IsVolumeSet_unlocked(t, n)) // yes: now we can call ourselves without the risk of a endless loop (see "if" above) return GetVolumeData_unlocked(t, n, data, importMemoryManagement); else return nullptr; } else { ImageDataItemPointer item = AllocateVolumeData_unlocked(t, n, data, importMemoryManagement); item->SetComplete(true); return item; } } mitk::Image::ImageDataItemPointer mitk::Image::GetChannelData(int n, void *data, ImportMemoryManagementType importMemoryManagement) const { MutexHolder lock(m_ImageDataArraysLock); return GetChannelData_unlocked(n, data, importMemoryManagement); } mitk::Image::ImageDataItemPointer mitk::Image::GetChannelData_unlocked( int n, void *data, ImportMemoryManagementType importMemoryManagement) const { if (IsValidChannel(n) == false) return nullptr; ImageDataItemPointer ch, vol; ch = m_Channels[n]; if ((ch.GetPointer() != nullptr) && (ch->IsComplete())) return ch; // let's see if all volumes are set, so that we can (could) combine them to a channel if (IsChannelSet_unlocked(n)) { // if there is only one time frame we do not need to combine anything if (m_Dimensions[3] <= 1) { vol = GetVolumeData_unlocked(0, n, data, importMemoryManagement); ch = new ImageDataItem(*vol, m_ImageDescriptor, 0, m_ImageDescriptor->GetNumberOfDimensions(), data, importMemoryManagement == ManageMemory); ch->SetComplete(true); } else { const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ch = m_Channels[n]; // ok, let's combine the volumes! if (ch.GetPointer() == nullptr) ch = new ImageDataItem(this->m_ImageDescriptor, -1, nullptr, true); ch->SetComplete(true); size_t size = m_OffsetTable[m_Dimension - 1] * (ptypeSize); unsigned int t; auto slicesIt = m_Slices.begin() + n * m_Dimensions[2] * m_Dimensions[3]; for (t = 0; t < m_Dimensions[3]; ++t) { int posVol; ImageDataItemPointer vol; posVol = GetVolumeIndex(t, n); vol = GetVolumeData_unlocked(t, n, data, importMemoryManagement); if (vol->GetParent() != ch) { // copy data of volume in channel size_t offset = ((size_t)t) * m_OffsetTable[3] * (ptypeSize); std::memcpy(static_cast<char *>(ch->GetData()) + offset, vol->GetData(), size); - // REVEIW FIX mitkIpPicDescriptor * pic = vol->GetPicDescriptor(); - // replace old volume with reference to channel vol = new ImageDataItem(*ch, m_ImageDescriptor, t, 3, data, importMemoryManagement == ManageMemory, offset); vol->SetComplete(true); - // mitkIpFuncCopyTags(vol->GetPicDescriptor(), pic); m_Volumes[posVol] = vol; // get rid of slices - they may point to old volume ImageDataItemPointer dnull = nullptr; for (unsigned int i = 0; i < m_Dimensions[2]; ++i, ++slicesIt) { assert(slicesIt != m_Slices.end()); *slicesIt = dnull; } } } - // REVIEW FIX - // if(ch->GetPicDescriptor()->info->tags_head==nullptr) - // mitkIpFuncCopyTags(ch->GetPicDescriptor(), m_Volumes[GetVolumeIndex(0,n)]->GetPicDescriptor()); } return m_Channels[n] = ch; } // channel is unavailable. Can we calculate it? if ((GetSource().IsNotNull()) && (GetSource()->Updating() == false)) { // ... wir muessen rechnen!!! .... m_RequestedRegion.SetIndex(0, 0); m_RequestedRegion.SetIndex(1, 0); m_RequestedRegion.SetIndex(2, 0); m_RequestedRegion.SetIndex(3, 0); m_RequestedRegion.SetIndex(4, n); m_RequestedRegion.SetSize(0, m_Dimensions[0]); m_RequestedRegion.SetSize(1, m_Dimensions[1]); m_RequestedRegion.SetSize(2, m_Dimensions[2]); m_RequestedRegion.SetSize(3, m_Dimensions[3]); m_RequestedRegion.SetSize(4, 1); m_RequestedRegionInitialized = true; GetSource()->Update(); // did it work? if (IsChannelSet_unlocked(n)) // yes: now we can call ourselves without the risk of a endless loop (see "if" above) return GetChannelData_unlocked(n, data, importMemoryManagement); else return nullptr; } else { ImageDataItemPointer item = AllocateChannelData_unlocked(n, data, importMemoryManagement); item->SetComplete(true); return item; } } bool mitk::Image::IsSliceSet(int s, int t, int n) const { MutexHolder lock(m_ImageDataArraysLock); return IsSliceSet_unlocked(s, t, n); } bool mitk::Image::IsSliceSet_unlocked(int s, int t, int n) const { if (IsValidSlice(s, t, n) == false) return false; if (m_Slices[GetSliceIndex(s, t, n)].GetPointer() != nullptr) { return true; } ImageDataItemPointer ch, vol; vol = m_Volumes[GetVolumeIndex(t, n)]; if ((vol.GetPointer() != nullptr) && (vol->IsComplete())) { return true; } ch = m_Channels[n]; if ((ch.GetPointer() != nullptr) && (ch->IsComplete())) { return true; } return false; } bool mitk::Image::IsVolumeSet(int t, int n) const { MutexHolder lock(m_ImageDataArraysLock); return IsVolumeSet_unlocked(t, n); } bool mitk::Image::IsVolumeSet_unlocked(int t, int n) const { if (IsValidVolume(t, n) == false) return false; ImageDataItemPointer ch, vol; // volume directly available? vol = m_Volumes[GetVolumeIndex(t, n)]; if ((vol.GetPointer() != nullptr) && (vol->IsComplete())) return true; // is volume available as part of a channel that is available? ch = m_Channels[n]; if ((ch.GetPointer() != nullptr) && (ch->IsComplete())) return true; // let's see if all slices of the volume are set, so that we can (could) combine them to a volume unsigned int s; for (s = 0; s < m_Dimensions[2]; ++s) { if (m_Slices[GetSliceIndex(s, t, n)].GetPointer() == nullptr) { return false; } } return true; } bool mitk::Image::IsChannelSet(int n) const { MutexHolder lock(m_ImageDataArraysLock); return IsChannelSet_unlocked(n); } bool mitk::Image::IsChannelSet_unlocked(int n) const { if (IsValidChannel(n) == false) return false; ImageDataItemPointer ch, vol; ch = m_Channels[n]; if ((ch.GetPointer() != nullptr) && (ch->IsComplete())) return true; // let's see if all volumes are set, so that we can (could) combine them to a channel unsigned int t; for (t = 0; t < m_Dimensions[3]; ++t) { if (IsVolumeSet_unlocked(t, n) == false) { return false; } } return true; } bool mitk::Image::SetSlice(const void *data, int s, int t, int n) { // const_cast is no risk for ImportMemoryManagementType == CopyMemory return SetImportSlice(const_cast<void *>(data), s, t, n, CopyMemory); } bool mitk::Image::SetVolume(const void *data, int t, int n) { // const_cast is no risk for ImportMemoryManagementType == CopyMemory return SetImportVolume(const_cast<void *>(data), t, n, CopyMemory); } bool mitk::Image::SetChannel(const void *data, int n) { // const_cast is no risk for ImportMemoryManagementType == CopyMemory return SetImportChannel(const_cast<void *>(data), n, CopyMemory); } bool mitk::Image::SetImportSlice(void *data, int s, int t, int n, ImportMemoryManagementType importMemoryManagement) { if (IsValidSlice(s, t, n) == false) return false; ImageDataItemPointer sl; const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); if (IsSliceSet(s, t, n)) { sl = GetSliceData(s, t, n, data, importMemoryManagement); if (sl->GetManageMemory() == false) { sl = AllocateSliceData(s, t, n, data, importMemoryManagement); if (sl.GetPointer() == nullptr) return false; } if (sl->GetData() != data) std::memcpy(sl->GetData(), data, m_OffsetTable[2] * (ptypeSize)); sl->Modified(); // we have changed the data: call Modified()! Modified(); } else { sl = AllocateSliceData(s, t, n, data, importMemoryManagement); if (sl.GetPointer() == nullptr) return false; if (sl->GetData() != data) std::memcpy(sl->GetData(), data, m_OffsetTable[2] * (ptypeSize)); // we just added a missing slice, which is not regarded as modification. // Therefore, we do not call Modified()! } return true; } bool mitk::Image::SetImportVolume(void *data, int t, int n, ImportMemoryManagementType importMemoryManagement) { if (IsValidVolume(t, n) == false) return false; const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ImageDataItemPointer vol; if (IsVolumeSet(t, n)) { vol = GetVolumeData(t, n, data, importMemoryManagement); if (vol->GetManageMemory() == false) { vol = AllocateVolumeData(t, n, data, importMemoryManagement); if (vol.GetPointer() == nullptr) return false; } if (vol->GetData() != data) std::memcpy(vol->GetData(), data, m_OffsetTable[3] * (ptypeSize)); vol->Modified(); vol->SetComplete(true); // we have changed the data: call Modified()! Modified(); } else { vol = AllocateVolumeData(t, n, data, importMemoryManagement); if (vol.GetPointer() == nullptr) return false; if (vol->GetData() != data) { std::memcpy(vol->GetData(), data, m_OffsetTable[3] * (ptypeSize)); } vol->SetComplete(true); this->m_ImageDescriptor->GetChannelDescriptor(n).SetData(vol->GetData()); // we just added a missing Volume, which is not regarded as modification. // Therefore, we do not call Modified()! } return true; } bool mitk::Image::SetImportVolume(const void *const_data, int t, int n) { return this->SetImportVolume(const_cast<void*>(const_data), t, n, CopyMemory); } bool mitk::Image::SetImportChannel(void *data, int n, ImportMemoryManagementType importMemoryManagement) { if (IsValidChannel(n) == false) return false; // channel descriptor const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ImageDataItemPointer ch; if (IsChannelSet(n)) { ch = GetChannelData(n, data, importMemoryManagement); if (ch->GetManageMemory() == false) { ch = AllocateChannelData(n, data, importMemoryManagement); if (ch.GetPointer() == nullptr) return false; } if (ch->GetData() != data) std::memcpy(ch->GetData(), data, m_OffsetTable[4] * (ptypeSize)); ch->Modified(); ch->SetComplete(true); // we have changed the data: call Modified()! Modified(); } else { ch = AllocateChannelData(n, data, importMemoryManagement); if (ch.GetPointer() == nullptr) return false; if (ch->GetData() != data) std::memcpy(ch->GetData(), data, m_OffsetTable[4] * (ptypeSize)); ch->SetComplete(true); this->m_ImageDescriptor->GetChannelDescriptor(n).SetData(ch->GetData()); // we just added a missing Channel, which is not regarded as modification. // Therefore, we do not call Modified()! } return true; } void mitk::Image::Initialize() { ImageDataItemPointerArray::iterator it, end; for (it = m_Slices.begin(), end = m_Slices.end(); it != end; ++it) { (*it) = nullptr; } for (it = m_Volumes.begin(), end = m_Volumes.end(); it != end; ++it) { (*it) = nullptr; } for (it = m_Channels.begin(), end = m_Channels.end(); it != end; ++it) { (*it) = nullptr; } m_CompleteData = nullptr; if (m_ImageStatistics == nullptr) { m_ImageStatistics = new mitk::ImageStatisticsHolder(this); } SetRequestedRegionToLargestPossibleRegion(); } void mitk::Image::Initialize(const mitk::ImageDescriptor::Pointer inDesc) { // store the descriptor this->m_ImageDescriptor = inDesc; // initialize image this->Initialize( inDesc->GetChannelDescriptor(0).GetPixelType(), inDesc->GetNumberOfDimensions(), inDesc->GetDimensions(), 1); } void mitk::Image::Initialize(const mitk::PixelType &type, unsigned int dimension, const unsigned int *dimensions, unsigned int channels) { Clear(); m_Dimension = dimension; if (!dimensions) itkExceptionMacro(<< "invalid zero dimension image"); unsigned int i; for (i = 0; i < dimension; ++i) { if (dimensions[i] < 1) itkExceptionMacro(<< "invalid dimension[" << i << "]: " << dimensions[i]); } // create new array since the old was deleted m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS]; // initialize the first four dimensions to 1, the remaining 4 to 0 FILL_C_ARRAY(m_Dimensions, 4, 1u); FILL_C_ARRAY((m_Dimensions + 4), 4, 0u); // copy in the passed dimension information std::memcpy(m_Dimensions, dimensions, sizeof(unsigned int) * m_Dimension); this->m_ImageDescriptor = mitk::ImageDescriptor::New(); this->m_ImageDescriptor->Initialize(this->m_Dimensions, this->m_Dimension); for (i = 0; i < 4; ++i) { m_LargestPossibleRegion.SetIndex(i, 0); m_LargestPossibleRegion.SetSize(i, m_Dimensions[i]); } m_LargestPossibleRegion.SetIndex(i, 0); m_LargestPossibleRegion.SetSize(i, channels); if (m_LargestPossibleRegion.GetNumberOfPixels() == 0) { delete[] m_Dimensions; m_Dimensions = nullptr; return; } for (unsigned int i = 0u; i < channels; i++) { this->m_ImageDescriptor->AddNewChannel(type); } PlaneGeometry::Pointer planegeometry = PlaneGeometry::New(); planegeometry->InitializeStandardPlane(m_Dimensions[0], m_Dimensions[1]); SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New(); slicedGeometry->InitializeEvenlySpaced(planegeometry, m_Dimensions[2]); ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]); for (TimeStepType step = 0; step < timeGeometry->CountTimeSteps(); ++step) { timeGeometry->GetGeometryForTimeStep(step)->ImageGeometryOn(); } SetTimeGeometry(timeGeometry); ImageDataItemPointer dnull = nullptr; m_Channels.assign(GetNumberOfChannels(), dnull); m_Volumes.assign(GetNumberOfChannels() * m_Dimensions[3], dnull); m_Slices.assign(GetNumberOfChannels() * m_Dimensions[3] * m_Dimensions[2], dnull); ComputeOffsetTable(); Initialize(); m_Initialized = true; } void mitk::Image::Initialize(const mitk::PixelType &type, const mitk::BaseGeometry &geometry, unsigned int channels, int tDim) { mitk::ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(geometry.Clone(), tDim); this->Initialize(type, *timeGeometry, channels, tDim); } void mitk::Image::Initialize(const mitk::PixelType &type, const mitk::TimeGeometry &geometry, unsigned int channels, int tDim) { unsigned int dimensions[5]; dimensions[0] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(0) + 0.5); dimensions[1] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(1) + 0.5); dimensions[2] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(2) + 0.5); dimensions[3] = (tDim > 0) ? tDim : geometry.CountTimeSteps(); dimensions[4] = 0; unsigned int dimension = 2; if (dimensions[2] > 1) dimension = 3; if (dimensions[3] > 1) dimension = 4; Initialize(type, dimension, dimensions, channels); if (geometry.CountTimeSteps() > 1) { TimeGeometry::Pointer cloned = geometry.Clone(); SetTimeGeometry(cloned.GetPointer()); // make sure the image geometry flag is properly set for all time steps for (TimeStepType step = 0; step < cloned->CountTimeSteps(); ++step) { if (!cloned->GetGeometryCloneForTimeStep(step)->GetImageGeometry()) { MITK_WARN("Image.3DnT.Initialize") << " Attempt to initialize an image with a non-image geometry. " "Re-interpretting the initialization geometry for timestep " << step << " as image geometry, the original geometry remains unchanged."; cloned->GetGeometryForTimeStep(step)->ImageGeometryOn(); } } } else { // make sure the image geometry coming from outside has proper value of the image geometry flag BaseGeometry::Pointer cloned = geometry.GetGeometryCloneForTimeStep(0)->Clone(); if (!cloned->GetImageGeometry()) { MITK_WARN("Image.Initialize") << " Attempt to initialize an image with a non-image geometry. Re-interpretting " "the initialization geometry as image geometry, the original geometry remains " "unchanged."; cloned->ImageGeometryOn(); } Superclass::SetGeometry(cloned); } } void mitk::Image::Initialize(const mitk::PixelType &type, int sDim, const mitk::PlaneGeometry &geometry2d, unsigned int channels, int tDim) { SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New(); slicedGeometry->InitializeEvenlySpaced(geometry2d.Clone(), sDim); Initialize(type, *slicedGeometry, channels, tDim); } void mitk::Image::Initialize(const mitk::Image *image) { Initialize(image->GetPixelType(), *image->GetTimeGeometry()); } void mitk::Image::Initialize(vtkImageData *vtkimagedata, int channels, int tDim, int sDim, int pDim) { if (vtkimagedata == nullptr) return; m_Dimension = vtkimagedata->GetDataDimension(); unsigned int i, *tmpDimensions = new unsigned int[m_Dimension > 4 ? m_Dimension : 4]; for (i = 0; i < m_Dimension; ++i) tmpDimensions[i] = vtkimagedata->GetDimensions()[i]; if (m_Dimension < 4) { unsigned int *p; for (i = 0, p = tmpDimensions + m_Dimension; i < 4 - m_Dimension; ++i, ++p) *p = 1; } if (pDim >= 0) { tmpDimensions[1] = pDim; if (m_Dimension < 2) m_Dimension = 2; } if (sDim >= 0) { tmpDimensions[2] = sDim; if (m_Dimension < 3) m_Dimension = 3; } if (tDim >= 0) { tmpDimensions[3] = tDim; if (m_Dimension < 4) m_Dimension = 4; } mitk::PixelType pixelType(MakePixelType(vtkimagedata)); Initialize(pixelType, m_Dimension, tmpDimensions, channels); const double *spacinglist = vtkimagedata->GetSpacing(); Vector3D spacing; FillVector3D(spacing, spacinglist[0], 1.0, 1.0); if (m_Dimension >= 2) spacing[1] = spacinglist[1]; if (m_Dimension >= 3) spacing[2] = spacinglist[2]; // access origin of vtkImage Point3D origin; double vtkorigin[3]; vtkimagedata->GetOrigin(vtkorigin); FillVector3D(origin, vtkorigin[0], 0.0, 0.0); if (m_Dimension >= 2) origin[1] = vtkorigin[1]; if (m_Dimension >= 3) origin[2] = vtkorigin[2]; SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(0); // re-initialize PlaneGeometry with origin and direction auto *planeGeometry = static_cast<PlaneGeometry *>(slicedGeometry->GetPlaneGeometry(0)); planeGeometry->SetOrigin(origin); // re-initialize SlicedGeometry3D slicedGeometry->SetOrigin(origin); slicedGeometry->SetSpacing(spacing); ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]); SetTimeGeometry(timeGeometry); delete[] tmpDimensions; } bool mitk::Image::IsValidSlice(int s, int t, int n) const { if (m_Initialized) return ((s >= 0) && (s < (int)m_Dimensions[2]) && (t >= 0) && (t < (int)m_Dimensions[3]) && (n >= 0) && (n < (int)GetNumberOfChannels())); else return false; } bool mitk::Image::IsValidVolume(int t, int n) const { if (m_Initialized) return IsValidSlice(0, t, n); else return false; } bool mitk::Image::IsValidChannel(int n) const { if (m_Initialized) return IsValidSlice(0, 0, n); else return false; } void mitk::Image::ComputeOffsetTable() { if (m_OffsetTable != nullptr) delete[] m_OffsetTable; m_OffsetTable = new size_t[m_Dimension > 4 ? m_Dimension + 1 : 4 + 1]; unsigned int i; size_t num = 1; m_OffsetTable[0] = 1; for (i = 0; i < m_Dimension; ++i) { num *= m_Dimensions[i]; m_OffsetTable[i + 1] = num; } for (; i < 4; ++i) m_OffsetTable[i + 1] = num; } bool mitk::Image::IsValidTimeStep(int t) const { return ((m_Dimension >= 4 && t <= (int)m_Dimensions[3] && t > 0) || (t == 0)); } void mitk::Image::Expand(unsigned int timeSteps) { if (timeSteps < 1) itkExceptionMacro(<< "Invalid timestep in Image!"); Superclass::Expand(timeSteps); } int mitk::Image::GetSliceIndex(int s, int t, int n) const { if (IsValidSlice(s, t, n) == false) return false; return ((size_t)s) + ((size_t)t) * m_Dimensions[2] + ((size_t)n) * m_Dimensions[3] * m_Dimensions[2]; //?? } int mitk::Image::GetVolumeIndex(int t, int n) const { if (IsValidVolume(t, n) == false) return false; return ((size_t)t) + ((size_t)n) * m_Dimensions[3]; //?? } mitk::Image::ImageDataItemPointer mitk::Image::AllocateSliceData( int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const { MutexHolder lock(m_ImageDataArraysLock); return AllocateSliceData_unlocked(s, t, n, data, importMemoryManagement); } mitk::Image::ImageDataItemPointer mitk::Image::AllocateSliceData_unlocked( int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const { int pos; pos = GetSliceIndex(s, t, n); const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); // is slice available as part of a volume that is available? ImageDataItemPointer sl, ch, vol; vol = m_Volumes[GetVolumeIndex(t, n)]; if (vol.GetPointer() != nullptr) { sl = new ImageDataItem(*vol, m_ImageDescriptor, t, 2, data, importMemoryManagement == ManageMemory, ((size_t)s) * m_OffsetTable[2] * (ptypeSize)); sl->SetComplete(true); return m_Slices[pos] = sl; } // is slice available as part of a channel that is available? ch = m_Channels[n]; if (ch.GetPointer() != nullptr) { sl = new ImageDataItem(*ch, m_ImageDescriptor, t, 2, data, importMemoryManagement == ManageMemory, (((size_t)s) * m_OffsetTable[2] + ((size_t)t) * m_OffsetTable[3]) * (ptypeSize)); sl->SetComplete(true); return m_Slices[pos] = sl; } // allocate new volume (instead of a single slice to keep data together!) m_Volumes[GetVolumeIndex(t, n)] = vol = AllocateVolumeData_unlocked(t, n, nullptr, importMemoryManagement); sl = new ImageDataItem(*vol, m_ImageDescriptor, t, 2, data, importMemoryManagement == ManageMemory, ((size_t)s) * m_OffsetTable[2] * (ptypeSize)); sl->SetComplete(true); return m_Slices[pos] = sl; ////ALTERNATIVE: //// allocate new slice // sl=new ImageDataItem(*m_PixelType, 2, m_Dimensions); // m_Slices[pos]=sl; // return vol; } mitk::Image::ImageDataItemPointer mitk::Image::AllocateVolumeData( int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const { MutexHolder lock(m_ImageDataArraysLock); return AllocateVolumeData_unlocked(t, n, data, importMemoryManagement); } mitk::Image::ImageDataItemPointer mitk::Image::AllocateVolumeData_unlocked( int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const { int pos; pos = GetVolumeIndex(t, n); const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); // is volume available as part of a channel that is available? ImageDataItemPointer ch, vol; ch = m_Channels[n]; if (ch.GetPointer() != nullptr) { vol = new ImageDataItem(*ch, m_ImageDescriptor, t, 3, data, importMemoryManagement == ManageMemory, (((size_t)t) * m_OffsetTable[3]) * (ptypeSize)); return m_Volumes[pos] = vol; } mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(n); // allocate new volume if (importMemoryManagement == CopyMemory) { vol = new ImageDataItem(chPixelType, t, 3, m_Dimensions, nullptr, true); if (data != nullptr) std::memcpy(vol->GetData(), data, m_OffsetTable[3] * (ptypeSize)); } else { vol = new ImageDataItem(chPixelType, t, 3, m_Dimensions, data, importMemoryManagement == ManageMemory); } m_Volumes[pos] = vol; return vol; } mitk::Image::ImageDataItemPointer mitk::Image::AllocateChannelData( int n, void *data, ImportMemoryManagementType importMemoryManagement) const { MutexHolder lock(m_ImageDataArraysLock); return AllocateChannelData_unlocked(n, data, importMemoryManagement); } mitk::Image::ImageDataItemPointer mitk::Image::AllocateChannelData_unlocked( int n, void *data, ImportMemoryManagementType importMemoryManagement) const { ImageDataItemPointer ch; // allocate new channel if (importMemoryManagement == CopyMemory) { const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ch = new ImageDataItem(this->m_ImageDescriptor, -1, nullptr, true); if (data != nullptr) std::memcpy(ch->GetData(), data, m_OffsetTable[4] * (ptypeSize)); } else { ch = new ImageDataItem(this->m_ImageDescriptor, -1, data, importMemoryManagement == ManageMemory); } m_Channels[n] = ch; return ch; } unsigned int *mitk::Image::GetDimensions() const { return m_Dimensions; } void mitk::Image::Clear() { Superclass::Clear(); delete[] m_Dimensions; m_Dimensions = nullptr; } void mitk::Image::SetGeometry(BaseGeometry *aGeometry3D) { // Please be aware of the 0.5 offset/pixel-center issue! See Geometry documentation for further information if (aGeometry3D->GetImageGeometry() == false) { MITK_INFO << "WARNING: Applied a non-image geometry onto an image. Please be SURE that this geometry is " "pixel-center-based! If it is not, you need to call " "Geometry3D->ChangeImageGeometryConsideringOriginOffset(true) before calling image->setGeometry(..)\n"; } Superclass::SetGeometry(aGeometry3D); for (TimeStepType step = 0; step < GetTimeGeometry()->CountTimeSteps(); ++step) GetTimeGeometry()->GetGeometryForTimeStep(step)->ImageGeometryOn(); } void mitk::Image::PrintSelf(std::ostream &os, itk::Indent indent) const { if (m_Initialized) { unsigned char i; os << indent << " Dimension: " << m_Dimension << std::endl; os << indent << " Dimensions: "; for (i = 0; i < m_Dimension; ++i) os << GetDimension(i) << " "; os << std::endl; for (unsigned int ch = 0; ch < this->m_ImageDescriptor->GetNumberOfChannels(); ch++) { mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(ch); os << indent << " Channel: " << this->m_ImageDescriptor->GetChannelName(ch) << std::endl; os << indent << " PixelType: " << chPixelType.GetPixelTypeAsString() << std::endl; os << indent << " BytesPerElement: " << chPixelType.GetSize() << std::endl; os << indent << " ComponentType: " << chPixelType.GetComponentTypeAsString() << std::endl; os << indent << " NumberOfComponents: " << chPixelType.GetNumberOfComponents() << std::endl; os << indent << " BitsPerComponent: " << chPixelType.GetBitsPerComponent() << std::endl; } } else { os << indent << " Image not initialized: m_Initialized: false" << std::endl; } Superclass::PrintSelf(os, indent); } bool mitk::Image::IsRotated() const { const mitk::BaseGeometry *geo = this->GetGeometry(); bool ret = false; if (geo) { const vnl_matrix_fixed<ScalarType, 3, 3> &mx = geo->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix(); mitk::ScalarType ref = 0; for (short k = 0; k < 3; ++k) ref += mx[k][k]; ref /= 1000; // Arbitrary value; if a non-diagonal (nd) element is bigger then this, matrix is considered nd. for (short i = 0; i < 3; ++i) { for (short j = 0; j < 3; ++j) { if (i != j) { if (std::abs(mx[i][j]) > ref) // matrix is nd ret = true; } } } } return ret; } bool mitk::Equal(const mitk::Image &leftHandSide, const mitk::Image &rightHandSide, ScalarType eps, bool verbose) { bool returnValue = true; // Dimensionality if (rightHandSide.GetDimension() != leftHandSide.GetDimension()) { if (verbose) { MITK_INFO << "[( Image )] Dimensionality differs."; MITK_INFO << "leftHandSide is " << leftHandSide.GetDimension() << "rightHandSide is " << rightHandSide.GetDimension(); } returnValue = false; } // Pair-wise dimension (size) comparison unsigned int minDimensionality = std::min(rightHandSide.GetDimension(), leftHandSide.GetDimension()); for (unsigned int i = 0; i < minDimensionality; ++i) { if (rightHandSide.GetDimension(i) != leftHandSide.GetDimension(i)) { returnValue = false; if (verbose) { MITK_INFO << "[( Image )] dimension differs."; MITK_INFO << "leftHandSide->GetDimension(" << i << ") is " << leftHandSide.GetDimension(i) << "rightHandSide->GetDimension(" << i << ") is " << rightHandSide.GetDimension(i); } } } // Pixeltype mitk::PixelType pixelTypeRightHandSide = rightHandSide.GetPixelType(); mitk::PixelType pixelTypeLeftHandSide = leftHandSide.GetPixelType(); if (!(pixelTypeRightHandSide == pixelTypeLeftHandSide)) { if (verbose) { MITK_INFO << "[( Image )] PixelType differs."; MITK_INFO << "leftHandSide is " << pixelTypeLeftHandSide.GetTypeAsString() << "rightHandSide is " << pixelTypeRightHandSide.GetTypeAsString(); } returnValue = false; } // Geometries if (!mitk::Equal(*leftHandSide.GetGeometry(), *rightHandSide.GetGeometry(), eps, verbose)) { if (verbose) { MITK_INFO << "[( Image )] Geometries differ."; } returnValue = false; } // Pixel values - default mode [ 0 threshold in difference ] // compare only if all previous checks were successfull, otherwise the ITK filter will throw an exception if (returnValue) { mitk::CompareImageDataFilter::Pointer compareFilter = mitk::CompareImageDataFilter::New(); compareFilter->SetInput(0, &rightHandSide); compareFilter->SetInput(1, &leftHandSide); compareFilter->SetTolerance(eps); compareFilter->Update(); if ((!compareFilter->GetResult())) { returnValue = false; if (verbose) { MITK_INFO << "[(Image)] Pixel values differ: "; compareFilter->GetCompareResults().PrintSelf(); } } } return returnValue; } diff --git a/Modules/Core/src/Interactions/mitkDisplayActionEventBroadcast.cpp b/Modules/Core/src/Interactions/mitkDisplayActionEventBroadcast.cpp index 10842c4182..fb52e35151 100644 --- a/Modules/Core/src/Interactions/mitkDisplayActionEventBroadcast.cpp +++ b/Modules/Core/src/Interactions/mitkDisplayActionEventBroadcast.cpp @@ -1,914 +1,914 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkDisplayActionEventBroadcast.h" // us #include "usGetModuleContext.h" #include "usModuleContext.h" // mitk core module #include <mitkCompositePixelValueToString.h> #include <mitkDisplayActionEvents.h> #include <mitkImage.h> #include <mitkImagePixelReadAccessor.h> #include <mitkInteractionConst.h> #include <mitkInteractionPositionEvent.h> #include <mitkLine.h> #include <mitkNodePredicateDataType.h> #include <mitkPixelTypeMultiplex.h> #include <mitkRotationOperation.h> #include <mitkStatusBar.h> #include <rotate_cursor.xpm> mitk::DisplayActionEventBroadcast::DisplayActionEventBroadcast() : m_AlwaysReact(false) , m_AutoRepeat(false) , m_IndexToSliceModifier(4) , m_InvertScrollDirection(false) , m_InvertZoomDirection(false) , m_ZoomFactor(2) , m_InvertMoveDirection(false) , m_InvertLevelWindowDirection(false) , m_LinkPlanes(true) { m_StartCoordinateInMM.Fill(0); m_LastDisplayCoordinate.Fill(0); m_LastCoordinateInMM.Fill(0); m_CurrentDisplayCoordinate.Fill(0); // register the broadcast class (itself) as an interaction event observer via micro services us::ServiceProperties props; props["name"] = std::string("DisplayActionEventBroadcast"); m_ServiceRegistration = us::GetModuleContext()->RegisterService<InteractionEventObserver>(this, props); } mitk::DisplayActionEventBroadcast::~DisplayActionEventBroadcast() { m_ServiceRegistration.Unregister(); } void mitk::DisplayActionEventBroadcast::Notify(InteractionEvent* interactionEvent, bool isHandled) { // the event is passed to the state machine interface to be handled if (!isHandled || m_AlwaysReact) { HandleEvent(interactionEvent, nullptr); } } void mitk::DisplayActionEventBroadcast::ConnectActionsAndFunctions() { CONNECT_CONDITION("check_position_event", CheckPositionEvent); CONNECT_CONDITION("check_can_rotate", CheckRotationPossible); CONNECT_CONDITION("check_can_swivel", CheckSwivelPossible); CONNECT_FUNCTION("init", Init); CONNECT_FUNCTION("move", Move); CONNECT_FUNCTION("zoom", Zoom); CONNECT_FUNCTION("scroll", Scroll); CONNECT_FUNCTION("ScrollOneUp", ScrollOneUp); CONNECT_FUNCTION("ScrollOneDown", ScrollOneDown); CONNECT_FUNCTION("levelWindow", AdjustLevelWindow); CONNECT_FUNCTION("setCrosshair", SetCrosshair); CONNECT_FUNCTION("updateStatusbar", UpdateStatusbar) CONNECT_FUNCTION("startRotation", StartRotation); CONNECT_FUNCTION("endRotation", EndRotation); CONNECT_FUNCTION("rotate", Rotate); CONNECT_FUNCTION("swivel", Swivel); CONNECT_FUNCTION("IncreaseTimeStep", IncreaseTimeStep); CONNECT_FUNCTION("DecreaseTimeStep", DecreaseTimeStep); } void mitk::DisplayActionEventBroadcast::ConfigurationChanged() { PropertyList::Pointer properties = GetAttributes(); // allwaysReact std::string strAlwaysReact = ""; m_AlwaysReact = false; if (properties->GetStringProperty("alwaysReact", strAlwaysReact)) { if (strAlwaysReact == "true") { m_AlwaysReact = true; } } // auto repeat std::string strAutoRepeat = ""; m_AutoRepeat = false; if (properties->GetStringProperty("autoRepeat", strAutoRepeat)) { if (strAutoRepeat == "true") { m_AutoRepeat = true; } } // pixel movement for scrolling one slice std::string strPixelPerSlice = ""; m_IndexToSliceModifier = 4; if (properties->GetStringProperty("pixelPerSlice", strPixelPerSlice)) { m_IndexToSliceModifier = atoi(strPixelPerSlice.c_str()); } // scroll direction if (!properties->GetStringProperty("scrollDirection", m_ScrollDirection)) { m_ScrollDirection = "updown"; } m_InvertScrollDirection = GetBoolProperty(properties, "invertScrollDirection", false); // zoom direction if (!properties->GetStringProperty("zoomDirection", m_ZoomDirection)) { m_ZoomDirection = "updown"; } m_InvertZoomDirection = GetBoolProperty(properties, "invertZoomDirection", false); m_InvertMoveDirection = GetBoolProperty(properties, "invertMoveDirection", false); if (!properties->GetStringProperty("levelWindowDirection", m_LevelDirection)) { m_LevelDirection = "leftright"; } m_InvertLevelWindowDirection = GetBoolProperty(properties, "invertLevelWindowDirection", false); // coupled rotation std::string strCoupled = ""; m_LinkPlanes = false; if (properties->GetStringProperty("coupled", strCoupled)) { if (strCoupled == "true") { m_LinkPlanes = true; } } // zoom factor std::string strZoomFactor = ""; properties->GetStringProperty("zoomFactor", strZoomFactor); m_ZoomFactor = .05; if (atoi(strZoomFactor.c_str()) > 0) { m_ZoomFactor = 1.0 + (atoi(strZoomFactor.c_str()) / 100.0); } } bool mitk::DisplayActionEventBroadcast::FilterEvents(InteractionEvent* interactionEvent, DataNode * /*dataNode*/) { BaseRenderer* sendingRenderer = interactionEvent->GetSender(); if (nullptr == sendingRenderer) { return false; } if (BaseRenderer::Standard3D == sendingRenderer->GetMapperID()) { return false; } return true; } bool mitk::DisplayActionEventBroadcast::CheckPositionEvent(const InteractionEvent *interactionEvent) { const auto* positionEvent = dynamic_cast<const InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return false; } return true; } bool mitk::DisplayActionEventBroadcast::CheckRotationPossible(const InteractionEvent *interactionEvent) { // Decide between moving and rotation slices. /* Detailed logic: 1. Find the SliceNavigationController that has sent the event: this one defines our rendering plane and will NOT be rotated. Needs not even be counted or checked. 2. Inspect every other SliceNavigationController - calculate the line intersection of this SliceNavigationController's plane with our rendering plane - if there is NO intersection, ignore and continue - IF there is an intersection - check the mouse cursor's distance from that line. 0. if the line is NOT near the cursor, remember the plane as "one of the other planes" (which can be rotated in "locked" mode) 1. on first line near the cursor, just remember this intersection line as THE other plane that we want to rotate 2. on every consecutive line near the cursor, check if the line is geometrically identical to the line that we want to rotate - if yes, we just push this line to the "other" lines and rotate it along - if no, then we have a situation where the mouse is near two other lines (e.g. crossing point) and don't want to rotate */ const auto* positionEvent = dynamic_cast<const InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return false; } BaseRenderer* renderer = positionEvent->GetSender(); if (nullptr == renderer) { return false; } const PlaneGeometry* rendererWorldPlaneGeometry = renderer->GetCurrentWorldPlaneGeometry(); if (nullptr == rendererWorldPlaneGeometry) { return false; } Point3D position = positionEvent->GetPositionInWorld(); const auto spacing = rendererWorldPlaneGeometry->GetSpacing(); const PlaneGeometry *geometryToBeRotated = nullptr; // this one is under the mouse cursor const PlaneGeometry *anyOtherGeometry = nullptr; // this is also visible (for calculation of intersection ONLY) Line3D intersectionLineWithGeometryToBeRotated; bool hitMultipleLines(false); m_SNCsToBeRotated.clear(); const ScalarType threshholdDistancePixels = 12.0; auto allRenderWindows = RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); for (auto renderWindow : allRenderWindows) { SliceNavigationController* snc = BaseRenderer::GetInstance(renderWindow)->GetSliceNavigationController(); // If the mouse cursor is in 3D Renderwindow, do not check for intersecting planes. if (BaseRenderer::Standard3D == BaseRenderer::GetInstance(renderWindow)->GetMapperID()) { continue; } const PlaneGeometry* rendererPlaneGeometry = snc->GetCurrentPlaneGeometry(); if (nullptr == rendererPlaneGeometry) { continue; // ignore, we don't see a plane } // check if there is an intersection between rendered / clicked geometry and the one being analyzed Line3D intersectionLine; if (!rendererWorldPlaneGeometry->IntersectionLine(rendererPlaneGeometry, intersectionLine)) { continue; // we ignore this plane, it's parallel to our plane } // check distance from intersection line const double distanceFromIntersectionLine = intersectionLine.Distance(position) / spacing[snc->GetDefaultViewDirection()]; // far away line, only remember for linked rotation if necessary if (distanceFromIntersectionLine > threshholdDistancePixels) { // we just take the last one, so overwrite each iteration (we just need some crossing point) // TODO what about multiple crossings? NOW we have undefined behavior / random crossing point is used anyOtherGeometry = rendererPlaneGeometry; if (m_LinkPlanes) { // if planes are linked, apply rotation to all planes m_SNCsToBeRotated.push_back(snc); } } else // close to cursor { if (nullptr == geometryToBeRotated) // first one close to the cursor { geometryToBeRotated = rendererPlaneGeometry; intersectionLineWithGeometryToBeRotated = intersectionLine; m_SNCsToBeRotated.push_back(snc); } else { // compare to the line defined by geometryToBeRotated: if identical, just rotate this otherRenderersRenderPlane // together with the primary one // if different, DON'T rotate if (intersectionLine.IsParallel(intersectionLineWithGeometryToBeRotated) && intersectionLine.Distance(intersectionLineWithGeometryToBeRotated.GetPoint1()) < eps) { m_SNCsToBeRotated.push_back(snc); } else { hitMultipleLines = true; } } } } bool moveSlices(true); if (geometryToBeRotated && anyOtherGeometry && rendererWorldPlaneGeometry && !hitMultipleLines) { // assure all three are valid, so calculation of center of rotation can be done moveSlices = false; } // question in state machine is: "rotate?" if (moveSlices) // i.e. NOT rotate { return false; } else { // we have enough information for rotation // remember where the last cursor position ON THE LINE has been observed m_LastCursorPosition = intersectionLineWithGeometryToBeRotated.Project(position); // find center of rotation by intersection with any of the OTHER lines if (anyOtherGeometry->IntersectionPoint(intersectionLineWithGeometryToBeRotated, m_CenterOfRotation)) { return true; } else { return false; } } return false; } bool mitk::DisplayActionEventBroadcast::CheckSwivelPossible(const InteractionEvent *interactionEvent) { // Decide between moving and rotation: if we're close to the crossing // point of the planes, moving mode is entered, otherwise // rotation/swivel mode const auto* positionEvent = dynamic_cast<const InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return false; } BaseRenderer* renderer = positionEvent->GetSender(); if (nullptr == renderer) { return false; } const Point3D& position = positionEvent->GetPositionInWorld(); m_SNCsToBeRotated.clear(); const PlaneGeometry* clickedGeometry(nullptr); const PlaneGeometry* otherGeometry1(nullptr); const PlaneGeometry* otherGeometry2(nullptr); const ScalarType threshholdDistancePixels = 6.0; auto allRenderWindows = RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); for (auto renderWindow : allRenderWindows) { SliceNavigationController* snc = BaseRenderer::GetInstance(renderWindow)->GetSliceNavigationController(); // If the mouse cursor is in 3D Renderwindow, do not check for intersecting planes. if (BaseRenderer::Standard3D == BaseRenderer::GetInstance(renderWindow)->GetMapperID()) { continue; } const PlaneGeometry* rendererPlaneGeometry = snc->GetCurrentPlaneGeometry(); if (nullptr == rendererPlaneGeometry) { continue; // ignore, we don't see a plane } if (snc == renderer->GetSliceNavigationController()) { clickedGeometry = rendererPlaneGeometry; m_SNCsToBeRotated.push_back(snc); } else { if (nullptr == otherGeometry1) { otherGeometry1 = rendererPlaneGeometry; } else { otherGeometry2 = rendererPlaneGeometry; } if (m_LinkPlanes) { // if planes are linked, apply rotation to all planes m_SNCsToBeRotated.push_back(snc); } } } Line3D line; Point3D point; if ((nullptr != clickedGeometry) && (nullptr != otherGeometry1) && (nullptr != otherGeometry2) && clickedGeometry->IntersectionLine(otherGeometry1, line) && otherGeometry2->IntersectionPoint(line, point)) { m_CenterOfRotation = point; if (m_CenterOfRotation.EuclideanDistanceTo(position) < threshholdDistancePixels) { return false; } else { m_ReferenceCursor = positionEvent->GetPointerPositionOnScreen(); // Get main axes of rotation plane and store it for rotation step m_RotationPlaneNormal = clickedGeometry->GetNormal(); ScalarType xVector[] = { 1.0, 0.0, 0.0 }; ScalarType yVector[] = { 0.0, 1.0, 0.0 }; clickedGeometry->BaseGeometry::IndexToWorld(Vector3D(xVector), m_RotationPlaneXVector); clickedGeometry->BaseGeometry::IndexToWorld(Vector3D(yVector), m_RotationPlaneYVector); m_RotationPlaneNormal.Normalize(); m_RotationPlaneXVector.Normalize(); m_RotationPlaneYVector.Normalize(); m_PreviousRotationAxis.Fill(0.0); m_PreviousRotationAxis[2] = 1.0; m_PreviousRotationAngle = 0.0; return true; } } else { return false; } return false; } void mitk::DisplayActionEventBroadcast::Init(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } m_LastDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); m_CurrentDisplayCoordinate = m_LastDisplayCoordinate; positionEvent->GetSender()->DisplayToPlane(m_LastDisplayCoordinate, m_StartCoordinateInMM); m_LastCoordinateInMM = m_StartCoordinateInMM; } void mitk::DisplayActionEventBroadcast::Move(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } BaseRenderer* sender = interactionEvent->GetSender(); Vector2D moveVector = m_LastDisplayCoordinate - positionEvent->GetPointerPositionOnScreen(); if (m_InvertMoveDirection) { moveVector *= -1.0; } moveVector *= sender->GetScaleFactorMMPerDisplayUnit(); // #TODO: put here? // store new display coordinate m_LastDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); // propagate move event with computed geometry values InvokeEvent(DisplayMoveEvent(interactionEvent, moveVector)); } void mitk::DisplayActionEventBroadcast::SetCrosshair(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } Point3D position = positionEvent->GetPositionInWorld(); // propagate set crosshair event with computed geometry values InvokeEvent(DisplaySetCrosshairEvent(interactionEvent, position)); } void mitk::DisplayActionEventBroadcast::Zoom(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } float factor = 1.0; float distance = 0; if (m_ZoomDirection == "updown") { distance = m_CurrentDisplayCoordinate[1] - m_LastDisplayCoordinate[1]; } else { distance = m_CurrentDisplayCoordinate[0] - m_LastDisplayCoordinate[0]; } if (m_InvertZoomDirection) { distance *= -1.0; } // set zooming speed if (distance < 0.0) { factor = 1.0 / m_ZoomFactor; } else if (distance > 0.0) { factor = 1.0 * m_ZoomFactor; } // store new display coordinates m_LastDisplayCoordinate = m_CurrentDisplayCoordinate; m_CurrentDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); // propagate zoom event with computed geometry values InvokeEvent(DisplayZoomEvent(interactionEvent, factor, m_StartCoordinateInMM)); } void mitk::DisplayActionEventBroadcast::Scroll(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } int sliceDelta = 0; // scroll direction if (m_ScrollDirection == "updown") { sliceDelta = static_cast<int>(m_CurrentDisplayCoordinate[1] - m_LastDisplayCoordinate[1]); } else { sliceDelta = static_cast<int>(m_CurrentDisplayCoordinate[0] - m_LastDisplayCoordinate[0]); } if (m_InvertScrollDirection) { sliceDelta *= -1; } // set how many pixels the mouse has to be moved to scroll one slice // if the mouse has been moved less than 'm_IndexToSliceModifier', pixels slice ONE slice only if (sliceDelta > 0 && sliceDelta < m_IndexToSliceModifier) { sliceDelta = m_IndexToSliceModifier; } else if (sliceDelta < 0 && sliceDelta > -m_IndexToSliceModifier) { sliceDelta = -m_IndexToSliceModifier; } sliceDelta /= m_IndexToSliceModifier; // store new display coordinates m_LastDisplayCoordinate = m_CurrentDisplayCoordinate; m_CurrentDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); // propagate scroll event with computed geometry values - InvokeEvent(DisplayScrollEvent(interactionEvent, sliceDelta)); + InvokeEvent(DisplayScrollEvent(interactionEvent, sliceDelta, m_AutoRepeat)); } void mitk::DisplayActionEventBroadcast::ScrollOneUp(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { int sliceDelta = 1; if (m_InvertScrollDirection) { sliceDelta = -1; } // propagate scroll event with a single slice delta (increase) - InvokeEvent(DisplayScrollEvent(interactionEvent, sliceDelta)); + InvokeEvent(DisplayScrollEvent(interactionEvent, sliceDelta, m_AutoRepeat)); } void mitk::DisplayActionEventBroadcast::ScrollOneDown(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { int sliceDelta = -1; if (m_InvertScrollDirection) { sliceDelta = 1; } // propagate scroll event with a single slice delta (decrease) - InvokeEvent(DisplayScrollEvent(interactionEvent, sliceDelta)); + InvokeEvent(DisplayScrollEvent(interactionEvent, sliceDelta, m_AutoRepeat)); } void mitk::DisplayActionEventBroadcast::AdjustLevelWindow(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } ScalarType level; ScalarType window; if (m_LevelDirection == "leftright") { level = m_CurrentDisplayCoordinate[0] - m_LastDisplayCoordinate[0]; window = m_CurrentDisplayCoordinate[1] - m_LastDisplayCoordinate[1]; } else { level = m_CurrentDisplayCoordinate[1] - m_LastDisplayCoordinate[1]; window = m_CurrentDisplayCoordinate[0] - m_LastDisplayCoordinate[0]; } if (m_InvertLevelWindowDirection) { level *= -1; window *= -1; } level *= static_cast<ScalarType>(2); window *= static_cast<ScalarType>(2); // store new display coordinates m_LastDisplayCoordinate = m_CurrentDisplayCoordinate; m_CurrentDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); // propagate set level window event with the level and window delta InvokeEvent(DisplaySetLevelWindowEvent(interactionEvent, level, window)); } void mitk::DisplayActionEventBroadcast::StartRotation(StateMachineAction* /*stateMachineAction*/, InteractionEvent* /*interactionEvent*/) { SetMouseCursor(rotate_cursor_xpm, 0, 0); } void mitk::DisplayActionEventBroadcast::EndRotation(StateMachineAction* /*stateMachineAction*/, InteractionEvent* /*interactionEvent*/) { ResetMouseCursor(); } void mitk::DisplayActionEventBroadcast::Rotate(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } Point3D position = positionEvent->GetPositionInWorld(); Vector3D toProjected = m_LastCursorPosition - m_CenterOfRotation; Vector3D toCursor = position - m_CenterOfRotation; // cross product: | A x B | = |A| * |B| * sin(angle) Vector3D axisOfRotation; vnl_vector_fixed<ScalarType, 3> vnlDirection = vnl_cross_3d(toCursor.GetVnlVector(), toProjected.GetVnlVector()); axisOfRotation.SetVnlVector(vnlDirection); // scalar product: A * B = |A| * |B| * cos(angle) // tan = sin / cos ScalarType angle = -atan2((double)(axisOfRotation.GetNorm()), (double)(toCursor * toProjected)); angle *= 180.0 / vnl_math::pi; m_LastCursorPosition = position; // create RotationOperation and apply to all SNCs that should be rotated RotationOperation rotationOperation(OpROTATE, m_CenterOfRotation, axisOfRotation, angle); // iterate the OTHER slice navigation controllers for (auto iter = m_SNCsToBeRotated.begin(); iter != m_SNCsToBeRotated.end(); ++iter) { TimeGeometry* timeGeometry = (*iter)->GetCreatedWorldGeometry(); if (nullptr == timeGeometry) { continue; } timeGeometry->ExecuteOperation(&rotationOperation); (*iter)->SendCreatedWorldGeometryUpdate(); } RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::DisplayActionEventBroadcast::Swivel(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } // Determine relative mouse movement projected onto world space Point2D position = positionEvent->GetPointerPositionOnScreen(); Vector2D relativeCursor = position - m_ReferenceCursor; Vector3D relativeCursorAxis = m_RotationPlaneXVector * relativeCursor[0] + m_RotationPlaneYVector * relativeCursor[1]; // Determine rotation axis (perpendicular to rotation plane and cursor movement) Vector3D rotationAxis = itk::CrossProduct(m_RotationPlaneNormal, relativeCursorAxis); ScalarType rotationAngle = relativeCursor.GetNorm() / 2.0; // Restore the initial plane pose by undoing the previous rotation operation RotationOperation op(OpROTATE, m_CenterOfRotation, m_PreviousRotationAxis, -m_PreviousRotationAngle); SNCVector::iterator iter; for (iter = m_SNCsToBeRotated.begin(); iter != m_SNCsToBeRotated.end(); ++iter) { if (!(*iter)->GetSliceRotationLocked()) { TimeGeometry* timeGeometry = (*iter)->GetCreatedWorldGeometry(); if (nullptr == timeGeometry) { continue; } timeGeometry->ExecuteOperation(&op); (*iter)->SendCreatedWorldGeometryUpdate(); } } // Apply new rotation operation to all relevant SNCs RotationOperation op2(OpROTATE, m_CenterOfRotation, rotationAxis, rotationAngle); for (iter = m_SNCsToBeRotated.begin(); iter != m_SNCsToBeRotated.end(); ++iter) { if (!(*iter)->GetSliceRotationLocked()) { // Retrieve the TimeGeometry of this SliceNavigationController TimeGeometry *timeGeometry = (*iter)->GetCreatedWorldGeometry(); if (nullptr == timeGeometry) { continue; } // Execute the new rotation timeGeometry->ExecuteOperation(&op2); // Notify listeners (*iter)->SendCreatedWorldGeometryUpdate(); } } m_PreviousRotationAxis = rotationAxis; m_PreviousRotationAngle = rotationAngle; RenderingManager::GetInstance()->RequestUpdateAll(); return; } void mitk::DisplayActionEventBroadcast::IncreaseTimeStep(StateMachineAction*, InteractionEvent*) { auto sliceNaviController = RenderingManager::GetInstance()->GetTimeNavigationController(); auto stepper = sliceNaviController->GetTime(); stepper->SetAutoRepeat(true); stepper->Next(); } void mitk::DisplayActionEventBroadcast::DecreaseTimeStep(StateMachineAction*, InteractionEvent*) { auto sliceNaviController = RenderingManager::GetInstance()->GetTimeNavigationController(); auto stepper = sliceNaviController->GetTime(); stepper->SetAutoRepeat(true); stepper->Previous(); } void mitk::DisplayActionEventBroadcast::UpdateStatusbar(StateMachineAction* /*stateMachineAction*/, InteractionEvent* interactionEvent) { const auto* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent); if (nullptr == positionEvent) { return; } BaseRenderer::Pointer renderer = positionEvent->GetSender(); TNodePredicateDataType<Image>::Pointer isImageData = TNodePredicateDataType<Image>::New(); DataStorage::SetOfObjects::ConstPointer nodes = renderer->GetDataStorage()->GetSubset(isImageData).GetPointer(); if (nodes.IsNull()) { return; } Point3D worldposition; renderer->DisplayToWorld(positionEvent->GetPointerPositionOnScreen(), worldposition); auto globalCurrentTimePoint = renderer->GetTime(); Image::Pointer image3D; DataNode::Pointer node; DataNode::Pointer topSourceNode; int component = 0; node = FindTopmostVisibleNode(nodes, worldposition, globalCurrentTimePoint, renderer); if (node.IsNull()) { return; } bool isBinary(false); node->GetBoolProperty("binary", isBinary); if (isBinary) { DataStorage::SetOfObjects::ConstPointer sourcenodes = renderer->GetDataStorage()->GetSources(node, nullptr, true); if (!sourcenodes->empty()) { topSourceNode = FindTopmostVisibleNode(nodes, worldposition, globalCurrentTimePoint, renderer); } if (topSourceNode.IsNotNull()) { image3D = dynamic_cast<Image*>(topSourceNode->GetData()); topSourceNode->GetIntProperty("Image.Displayed Component", component); } else { image3D = dynamic_cast<Image*>(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } else { image3D = dynamic_cast<Image *>(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } // get the position and pixel value from the image and build up status bar text auto statusBar = StatusBar::GetInstance(); if (image3D.IsNotNull() && statusBar != nullptr) { itk::Index<3> p; image3D->GetGeometry()->WorldToIndex(worldposition, p); auto pixelType = image3D->GetChannelDescriptor().GetPixelType().GetPixelType(); if (pixelType == itk::ImageIOBase::RGB || pixelType == itk::ImageIOBase::RGBA) { std::string pixelValue = "Pixel RGB(A) value: "; pixelValue.append(ConvertCompositePixelValueToString(image3D, p)); statusBar->DisplayImageInfo(worldposition, p, renderer->GetTime(), pixelValue.c_str()); } else if (pixelType == itk::ImageIOBase::DIFFUSIONTENSOR3D || pixelType == itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR) { std::string pixelValue = "See ODF Details view. "; statusBar->DisplayImageInfo(worldposition, p, renderer->GetTime(), pixelValue.c_str()); } else { ScalarType pixelValue; mitkPixelTypeMultiplex5( FastSinglePixelAccess, image3D->GetChannelDescriptor().GetPixelType(), image3D, image3D->GetVolumeData(renderer->GetTimeStep()), p, pixelValue, component); statusBar->DisplayImageInfo(worldposition, p, renderer->GetTime(), pixelValue); } } else { statusBar->DisplayImageInfoInvalid(); } } bool mitk::DisplayActionEventBroadcast::GetBoolProperty(PropertyList::Pointer propertyList, const char* propertyName, bool defaultValue) { std::string valueAsString; if (!propertyList->GetStringProperty(propertyName, valueAsString)) { return defaultValue; } else { if (valueAsString == "true") { return true; } else { return false; } } } diff --git a/Modules/Core/src/Interactions/mitkDisplayActionEventFunctions.cpp b/Modules/Core/src/Interactions/mitkDisplayActionEventFunctions.cpp index 665c2fba21..25c90c502b 100644 --- a/Modules/Core/src/Interactions/mitkDisplayActionEventFunctions.cpp +++ b/Modules/Core/src/Interactions/mitkDisplayActionEventFunctions.cpp @@ -1,319 +1,321 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkDisplayActionEventFunctions.h" // mitk core #include "mitkBaseRenderer.h" #include "mitkCameraController.h" #include "mitkDisplayActionEvents.h" #include "mitkInteractionPositionEvent.h" #include "mitkLevelWindow.h" #include "mitkLevelWindowProperty.h" #include "mitkNodePredicateDataType.h" ////////////////////////////////////////////////////////////////////////// // STANDARD FUNCTIONS ////////////////////////////////////////////////////////////////////////// mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::MoveSenderCameraAction() { mitk::StdFunctionCommand::ActionFunction actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplayMoveEvent().CheckEvent(&displayInteractorEvent)) { const DisplayMoveEvent* displayActionEvent = dynamic_cast<const DisplayMoveEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } sendingRenderer->GetCameraController()->MoveBy(displayActionEvent->GetMoveVector()); RenderingManager::GetInstance()->RequestUpdate(sendingRenderer->GetRenderWindow()); } }; return actionFunction; } mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::SetCrosshairAction() { auto actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplaySetCrosshairEvent().CheckEvent(&displayInteractorEvent)) { const DisplaySetCrosshairEvent* displayActionEvent = dynamic_cast<const DisplaySetCrosshairEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } BaseRenderer::GetInstance(sendingRenderer->GetRenderWindow())->GetSliceNavigationController()->SelectSliceByPoint(displayActionEvent->GetPosition()); } }; return actionFunction; } mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::ZoomSenderCameraAction() { auto actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplayZoomEvent().CheckEvent(&displayInteractorEvent)) { const DisplayZoomEvent* displayActionEvent = dynamic_cast<const DisplayZoomEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } if (1.0 != displayActionEvent->GetZoomFactor()) { sendingRenderer->GetCameraController()->Zoom(displayActionEvent->GetZoomFactor(), displayActionEvent->GetStartCoordinate()); RenderingManager::GetInstance()->RequestUpdate(sendingRenderer->GetRenderWindow()); } } }; return actionFunction; } mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::ScrollSliceStepperAction() { auto actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplayScrollEvent().CheckEvent(&displayInteractorEvent)) { const DisplayScrollEvent* displayActionEvent = dynamic_cast<const DisplayScrollEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } mitk::SliceNavigationController* sliceNavigationController = sendingRenderer->GetSliceNavigationController(); if (nullptr == sliceNavigationController) { return; } if (sliceNavigationController->GetSliceLocked()) { return; } mitk::Stepper* sliceStepper = sliceNavigationController->GetSlice(); if (nullptr == sliceStepper) { return; } // if only a single slice image was loaded, scrolling will affect the time steps if (sliceStepper->GetSteps() <= 1) { sliceStepper = sliceNavigationController->GetTime(); } + sliceStepper->SetAutoRepeat(displayActionEvent->GetAutoRepeat()); sliceStepper->MoveSlice(displayActionEvent->GetSliceDelta()); } }; return actionFunction; } mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::SetLevelWindowAction() { auto actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplaySetLevelWindowEvent().CheckEvent(&displayInteractorEvent)) { const DisplaySetLevelWindowEvent* displayActionEvent = dynamic_cast<const DisplaySetLevelWindowEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } // get the the topmost visible image of the sending renderer DataStorage::Pointer storage = sendingRenderer->GetDataStorage(); DataStorage::SetOfObjects::ConstPointer allImageNodes = storage->GetSubset(NodePredicateDataType::New("Image")); Point3D worldposition; const auto* positionEvent = dynamic_cast<const InteractionPositionEvent*>(displayActionEvent->GetInteractionEvent()); sendingRenderer->DisplayToWorld(positionEvent->GetPointerPositionOnScreen(), worldposition); auto globalCurrentTimePoint = sendingRenderer->GetTime(); DataNode::Pointer node = FindTopmostVisibleNode(allImageNodes, worldposition, globalCurrentTimePoint, sendingRenderer); if (node.IsNull()) { return; } LevelWindow levelWindow = LevelWindow(); node->GetLevelWindow(levelWindow); ScalarType level = levelWindow.GetLevel(); ScalarType window = levelWindow.GetWindow(); level += displayActionEvent->GetLevel(); window += displayActionEvent->GetWindow(); levelWindow.SetLevelWindow(level, window); auto* levelWindowProperty = dynamic_cast<LevelWindowProperty*>(node->GetProperty("levelwindow")); if (nullptr != levelWindowProperty) { levelWindowProperty->SetLevelWindow(levelWindow); RenderingManager::GetInstance()->RequestUpdateAll(); } } }; return actionFunction; } ////////////////////////////////////////////////////////////////////////// // SYNCHRONIZED FUNCTIONS ////////////////////////////////////////////////////////////////////////// mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::MoveCameraSynchronizedAction() { mitk::StdFunctionCommand::ActionFunction actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplayMoveEvent().CheckEvent(&displayInteractorEvent)) { const DisplayMoveEvent* displayActionEvent = dynamic_cast<const DisplayMoveEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } auto renderingManager = RenderingManager::GetInstance(); auto allRenderWindows = renderingManager->GetAllRegisteredRenderWindows(); for (auto renderWindow : allRenderWindows) { if (BaseRenderer::GetInstance(renderWindow)->GetMapperID() == BaseRenderer::Standard2D) { BaseRenderer* currentRenderer = BaseRenderer::GetInstance(renderWindow); currentRenderer->GetCameraController()->MoveBy(displayActionEvent->GetMoveVector()); renderingManager->RequestUpdate(currentRenderer->GetRenderWindow()); } } } }; return actionFunction; } mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::SetCrosshairSynchronizedAction() { auto actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplaySetCrosshairEvent().CheckEvent(&displayInteractorEvent)) { const DisplaySetCrosshairEvent* displayActionEvent = dynamic_cast<const DisplaySetCrosshairEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } auto allRenderWindows = RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); for (auto renderWindow : allRenderWindows) { if (BaseRenderer::GetInstance(renderWindow)->GetMapperID() == BaseRenderer::Standard2D) { BaseRenderer::GetInstance(renderWindow)->GetSliceNavigationController()->SelectSliceByPoint(displayActionEvent->GetPosition()); } } } }; return actionFunction; } mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::ZoomCameraSynchronizedAction() { auto actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplayZoomEvent().CheckEvent(&displayInteractorEvent)) { const DisplayZoomEvent* displayActionEvent = dynamic_cast<const DisplayZoomEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } if (1.0 != displayActionEvent->GetZoomFactor()) { auto renderingManager = RenderingManager::GetInstance(); auto allRenderWindows = renderingManager->GetAllRegisteredRenderWindows(); for (auto renderWindow : allRenderWindows) { if (BaseRenderer::GetInstance(renderWindow)->GetMapperID() == BaseRenderer::Standard2D) { BaseRenderer* currentRenderer = BaseRenderer::GetInstance(renderWindow); currentRenderer->GetCameraController()->Zoom(displayActionEvent->GetZoomFactor(), displayActionEvent->GetStartCoordinate()); renderingManager->RequestUpdate(currentRenderer->GetRenderWindow()); } } } } }; return actionFunction; } mitk::StdFunctionCommand::ActionFunction mitk::DisplayActionEventFunctions::ScrollSliceStepperSynchronizedAction() { auto actionFunction = [](const itk::EventObject& displayInteractorEvent) { if (DisplayScrollEvent().CheckEvent(&displayInteractorEvent)) { const DisplayScrollEvent* displayActionEvent = dynamic_cast<const DisplayScrollEvent*>(&displayInteractorEvent); const BaseRenderer::Pointer sendingRenderer = displayActionEvent->GetSender(); if (nullptr == sendingRenderer) { return; } auto allRenderWindows = RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); for (auto renderWindow : allRenderWindows) { if (BaseRenderer::GetInstance(renderWindow)->GetMapperID() == BaseRenderer::Standard2D) { mitk::SliceNavigationController* sliceNavigationController = BaseRenderer::GetInstance(renderWindow)->GetSliceNavigationController(); if (nullptr == sliceNavigationController) { return; } if (sliceNavigationController->GetSliceLocked()) { return; } mitk::Stepper* sliceStepper = sliceNavigationController->GetSlice(); if (nullptr == sliceStepper) { return; } // if only a single slice image was loaded, scrolling will affect the time steps if (sliceStepper->GetSteps() <= 1) { sliceStepper = sliceNavigationController->GetTime(); } + sliceStepper->SetAutoRepeat(displayActionEvent->GetAutoRepeat()); sliceStepper->MoveSlice(displayActionEvent->GetSliceDelta()); } } } }; return actionFunction; } diff --git a/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp b/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp index 5829ee15f5..9f60092bc1 100644 --- a/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp +++ b/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp @@ -1,37 +1,37 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkDisplayActionEventHandlerDesynchronized.h" // mitk core #include "mitkDisplayActionEventFunctions.h" // itk #include <itkEventObject.h> void mitk::DisplayActionEventHandlerDesynchronized::InitActionsImpl() { StdFunctionCommand::ActionFunction actionFunction = DisplayActionEventFunctions::MoveSenderCameraAction(); ConnectDisplayActionEvent(DisplayMoveEvent(nullptr, Vector2D()), actionFunction); actionFunction = DisplayActionEventFunctions::SetCrosshairAction(); ConnectDisplayActionEvent(DisplaySetCrosshairEvent(nullptr, Point3D()), actionFunction); actionFunction = DisplayActionEventFunctions::ZoomSenderCameraAction(); ConnectDisplayActionEvent(DisplayZoomEvent(nullptr, 0.0, Point2D()), actionFunction); actionFunction = DisplayActionEventFunctions::ScrollSliceStepperAction(); - ConnectDisplayActionEvent(DisplayScrollEvent(nullptr, 0), actionFunction); + ConnectDisplayActionEvent(DisplayScrollEvent(nullptr, 0, true), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::SetLevelWindowAction(); ConnectDisplayActionEvent(mitk::DisplaySetLevelWindowEvent(nullptr, mitk::ScalarType(), mitk::ScalarType()), actionFunction); } diff --git a/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerStd.cpp b/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerStd.cpp index af0d7c2d61..c10c885b77 100644 --- a/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerStd.cpp +++ b/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerStd.cpp @@ -1,41 +1,41 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkDisplayActionEventHandlerStd.h" // mitk core #include "mitkDisplayActionEventFunctions.h" // itk #include <itkEventObject.h> void mitk::DisplayActionEventHandlerStd::InitActionsImpl() { // synchronized action event function StdFunctionCommand::ActionFunction actionFunction = DisplayActionEventFunctions::SetCrosshairSynchronizedAction(); ConnectDisplayActionEvent(DisplaySetCrosshairEvent(nullptr, Point3D()), actionFunction); // desynchronized action event function actionFunction = DisplayActionEventFunctions::MoveSenderCameraAction(); ConnectDisplayActionEvent(DisplayMoveEvent(nullptr, Vector2D()), actionFunction); // desynchronized action event function actionFunction = DisplayActionEventFunctions::ZoomSenderCameraAction(); ConnectDisplayActionEvent(DisplayZoomEvent(nullptr, 0.0, Point2D()), actionFunction); // desynchronized action event function actionFunction = DisplayActionEventFunctions::ScrollSliceStepperAction(); - ConnectDisplayActionEvent(DisplayScrollEvent(nullptr, 0), actionFunction); + ConnectDisplayActionEvent(DisplayScrollEvent(nullptr, 0, true), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::SetLevelWindowAction(); ConnectDisplayActionEvent(mitk::DisplaySetLevelWindowEvent(nullptr, mitk::ScalarType(), mitk::ScalarType()), actionFunction); } diff --git a/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerSynchronized.cpp b/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerSynchronized.cpp index 56c6425982..0f937e27ac 100644 --- a/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerSynchronized.cpp +++ b/Modules/Core/src/Interactions/mitkDisplayActionEventHandlerSynchronized.cpp @@ -1,37 +1,37 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkDisplayActionEventHandlerSynchronized.h" // mitk core #include "mitkDisplayActionEventFunctions.h" // itk #include <itkEventObject.h> void mitk::DisplayActionEventHandlerSynchronized::InitActionsImpl() { StdFunctionCommand::ActionFunction actionFunction = DisplayActionEventFunctions::MoveCameraSynchronizedAction(); ConnectDisplayActionEvent(DisplayMoveEvent(nullptr, Vector2D()), actionFunction); actionFunction = DisplayActionEventFunctions::SetCrosshairSynchronizedAction(); ConnectDisplayActionEvent(DisplaySetCrosshairEvent(nullptr, Point3D()), actionFunction); actionFunction = DisplayActionEventFunctions::ZoomCameraSynchronizedAction(); ConnectDisplayActionEvent(DisplayZoomEvent(nullptr, 0.0, Point2D()), actionFunction); actionFunction = DisplayActionEventFunctions::ScrollSliceStepperSynchronizedAction(); - ConnectDisplayActionEvent(DisplayScrollEvent(nullptr, 0), actionFunction); + ConnectDisplayActionEvent(DisplayScrollEvent(nullptr, 0, true), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::SetLevelWindowAction(); ConnectDisplayActionEvent(mitk::DisplaySetLevelWindowEvent(nullptr, mitk::ScalarType(), mitk::ScalarType()), actionFunction); } diff --git a/Modules/Core/src/Interactions/mitkInteractionEventHandler.cpp b/Modules/Core/src/Interactions/mitkInteractionEventHandler.cpp index 461e2cf569..dcb0415331 100644 --- a/Modules/Core/src/Interactions/mitkInteractionEventHandler.cpp +++ b/Modules/Core/src/Interactions/mitkInteractionEventHandler.cpp @@ -1,114 +1,119 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkInteractionEventHandler.h" #include "mitkInteractionEvent.h" mitk::InteractionEventHandler::InteractionEventHandler() : m_EventConfig() { } mitk::InteractionEventHandler::~InteractionEventHandler() { } bool mitk::InteractionEventHandler::SetEventConfig(const std::string &filename, const us::Module *module) { EventConfig newConfig(filename, module); if (newConfig.IsValid()) { m_EventConfig = newConfig; // notify sub-classes that new config is set ConfigurationChanged(); return true; } MITK_ERROR << "InteractionEventHandler: Failed to load EventConfiguration"; return false; } bool mitk::InteractionEventHandler::SetEventConfig(const EventConfig &config) { if (config.IsValid()) { m_EventConfig = config; // notify sub-classes that new config is set ConfigurationChanged(); return true; } return false; } mitk::EventConfig mitk::InteractionEventHandler::GetEventConfig() const { return m_EventConfig; } bool mitk::InteractionEventHandler::AddEventConfig(const std::string &filename, const us::Module *module) { + if (filename.empty()) + { + return false; + } + if (!m_EventConfig.IsValid()) { MITK_ERROR << "SetEventConfig has to be called before AddEventConfig can be used."; return false; } // notify sub-classes that new config is set bool success = m_EventConfig.AddConfig(filename, module); if (success) { ConfigurationChanged(); } return success; } bool mitk::InteractionEventHandler::AddEventConfig(const EventConfig &config) { if (!m_EventConfig.IsValid()) { MITK_ERROR << "SetEventConfig has to be called before AddEventConfig can be used."; return false; } // notify sub-classes that new config is set bool success = m_EventConfig.AddConfig(config); if (success) { ConfigurationChanged(); } return success; } mitk::PropertyList::Pointer mitk::InteractionEventHandler::GetAttributes() const { if (m_EventConfig.IsValid()) { return m_EventConfig.GetAttributes(); } else { MITK_ERROR << "InteractionEventHandler::GetAttributes() requested, but not configuration loaded."; return nullptr; } } std::string mitk::InteractionEventHandler::MapToEventVariant(InteractionEvent *interactionEvent) { if (m_EventConfig.IsValid()) { return m_EventConfig.GetMappedEvent(interactionEvent); } else { return ""; } } void mitk::InteractionEventHandler::ConfigurationChanged() { } diff --git a/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp b/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp index 0b104903dc..dc9f1fa6ab 100644 --- a/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp +++ b/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp @@ -1,102 +1,108 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkInteractionSchemeSwitcher.h" // mitk core #include <mitkInteractionEventObserver.h> #include <mitkExceptionMacro.h> mitk::InteractionSchemeSwitcher::InteractionSchemeSwitcher() { // nothing here } mitk::InteractionSchemeSwitcher::~InteractionSchemeSwitcher() { // nothing here } void mitk::InteractionSchemeSwitcher::SetInteractionScheme(InteractionEventHandler* interactionEventHandler, InteractionScheme interactionScheme) { if (nullptr == interactionEventHandler) { mitkThrow() << "Not a valid interaction event handler to set the interaction scheme."; } switch (interactionScheme) { // MITK MODE case MITKStandard: { - interactionEventHandler->SetEventConfig("DisplayConfigMITK.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigMITKBase.xml"); + interactionEventHandler->AddEventConfig("DisplayConfigCrosshair.xml"); break; } case MITKRotationUncoupled: { - interactionEventHandler->SetEventConfig("DisplayConfigMITKRotationUnCoupled.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigMITKBase.xml"); + interactionEventHandler->AddEventConfig("DisplayConfigRotation.xml"); break; } case MITKRotationCoupled: { - interactionEventHandler->SetEventConfig("DisplayConfigMITKRotation.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigMITKBase.xml"); + interactionEventHandler->AddEventConfig("DisplayConfigRotation.xml"); + interactionEventHandler->AddEventConfig("DisplayConfigActivateCoupling.xml"); break; } case MITKSwivel: { - interactionEventHandler->SetEventConfig("DisplayConfigMITKSwivel.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigMITKBase.xml"); + interactionEventHandler->AddEventConfig("DisplayConfigSwivel.xml"); break; } // PACS MODE case PACSBase: { - interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigPACSBase.xml"); break; } case PACSStandard: { - interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); - interactionEventHandler->AddEventConfig("DisplayConfigPACSCrosshair.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigPACSBase.xml"); + interactionEventHandler->AddEventConfig("DisplayConfigCrosshair.xml"); break; } case PACSLevelWindow: { - interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigPACSBase.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSLevelWindow.xml"); break; } case PACSPan: { - interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigPACSBase.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSPan.xml"); break; } case PACSScroll: { - interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigPACSBase.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSScroll.xml"); break; } case PACSZoom: { - interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigPACSBase.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSZoom.xml"); break; } default: { - interactionEventHandler->SetEventConfig("DisplayConfigMITK.xml"); + interactionEventHandler->SetEventConfig("DisplayConfigMITKBase.xml"); + interactionEventHandler->AddEventConfig("DisplayConfigCrosshair.xml"); } } InvokeEvent(InteractionSchemeChangedEvent()); } diff --git a/Modules/Core/src/mitkCoreObjectFactoryBase.cpp b/Modules/Core/src/mitkCoreObjectFactoryBase.cpp index 32cf6111ca..08d0443af4 100644 --- a/Modules/Core/src/mitkCoreObjectFactoryBase.cpp +++ b/Modules/Core/src/mitkCoreObjectFactoryBase.cpp @@ -1,67 +1,67 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkCoreObjectFactoryBase.h" void mitk::CoreObjectFactoryBase::CreateFileExtensions(MultimapType fileExtensionsMap, std::string &fileExtensions) { std::map<std::string, std::string> aMap; // group the extensions by extension-group // e.g. aMap["DICOM files"] = "*.dcm *.DCM *.dc3 *.DC3 *.gdcm" for (auto it = fileExtensionsMap.begin(); it != fileExtensionsMap.end(); ++it) { std::string aValue = aMap[(*it).second]; if (aValue.compare("") != 0) { aValue.append(" "); } aValue.append((*it).first); aMap[(*it).second] = aValue; } // build the "all" entry (it contains all the extensions) // and add it to the string in the first position // e.g. "all (*.dcm *.DCM *.dc3 *.DC3 *.gdcm *.ima *.mhd ... *.vti *.hdr *.nrrd *.nhdr );;" fileExtensions = "known extensions ("; std::string lastKey = ""; for (auto it = fileExtensionsMap.begin(); it != fileExtensionsMap.end(); ++it) { std::string aKey = (*it).first; if (aKey.compare(lastKey) != 0) { if (lastKey.compare("") != 0) { fileExtensions.append(" "); } fileExtensions.append(aKey); } lastKey = aKey; } fileExtensions.append(");;all (*);;"); // build the entry for each extension-group - // e.g. "Sets of 2D slices (*.pic *.pic.gz *.bmp *.png *.dcm *.gdcm *.ima *.tiff);;" + // e.g. "Sets of 2D slices (*.bmp *.png *.dcm *.gdcm *.ima *.tiff);;" for (auto it = aMap.begin(); it != aMap.end(); ++it) { // cout << " [" << (*it).first << ", " << (*it).second << "]" << endl; std::string aKey = (*it).first; if (aKey.compare("") != 0) { fileExtensions.append((*it).first); fileExtensions.append(" ("); fileExtensions.append((*it).second); fileExtensions.append(");;"); } } } diff --git a/Modules/Core/test/CMakeLists.txt b/Modules/Core/test/CMakeLists.txt index 7839cb73bd..61f89dd6b6 100644 --- a/Modules/Core/test/CMakeLists.txt +++ b/Modules/Core/test/CMakeLists.txt @@ -1,177 +1,177 @@ # The core tests need relaxed compiler flags... # TODO fix core tests to compile without these additional no-error flags if(MSVC_VERSION) # disable deprecated warnings (they would lead to errors) mitkFunctionCheckCAndCXXCompilerFlags("/wd4996" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) else() mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated-declarations" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() MITK_CREATE_MODULE_TESTS() if(TARGET ${TESTDRIVER}) mitk_use_modules(TARGET ${TESTDRIVER} PACKAGES ITK|IONRRD VTK|TestingRendering tinyxml2) mitkAddCustomModuleTest(mitkVolumeCalculatorTest_Png2D-bw mitkVolumeCalculatorTest ${MITK_DATA_DIR}/Png2D-bw.png ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) mitkAddCustomModuleTest(mitkEventConfigTest_CreateObjectInDifferentWays mitkEventConfigTest ${MITK_SOURCE_DIR}/Modules/Core/test/resource/Interactions/StatemachineConfigTest.xml ) mitkAddCustomModuleTest(mitkDataStorageTest_US4DCyl mitkDataStorageTest ${MITK_DATA_DIR}/US4DCyl.nrrd ) mitkAddCustomModuleTest(mitkPointSetReaderTest mitkPointSetReaderTest ${MITK_DATA_DIR}/PointSetReaderTestData.mps ) mitkAddCustomModuleTest(mitkImageTest_4DImageData mitkImageTest ${MITK_DATA_DIR}/US4DCyl.nrrd ) mitkAddCustomModuleTest(mitkImageTest_2D+tImageData mitkImageTest ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) mitkAddCustomModuleTest(mitkImageTest_3DImageData mitkImageTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkImageEqualTest mitkImageEqualTest) mitkAddCustomModuleTest(mitkImageTest_brainImage mitkImageTest ${MITK_DATA_DIR}/brain.mhd ) mitkAddCustomModuleTest(mitkMultiComponentImageDataComparisonFilterTest mitkMultiComponentImageDataComparisonFilterTest ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg ) mitkAddCustomModuleTest(mitkImageToItkTest mitkImageToItkTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkImageSliceSelectorTest mitkImageSliceSelectorTest ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) mitkAddCustomModuleTest(mitkRotatedSlice4DTest mitkRotatedSlice4DTest ${MITK_DATA_DIR}/UltrasoundImages/4D_TEE_Data_MV.dcm ) mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2DTest ${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/rgbaImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3d640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2DColorTest #test for color property (=blue) Pic3D sagittal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dColorBlue640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2DLevelWindowTest #test for levelwindow property (=blood) #Pic3D sagittal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dLevelWindowBlood640x480REF.png #corresponding reference #screenshot ) mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DSwivelTest #test for a randomly chosen Pic3D swivelled slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dSwivel640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2DTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAlone640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2DImageTest ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/PointSetForPic3D.mps #input point set and image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Pic3DPointSetForPic3D640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2DGlyphTypeTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneGlyphType640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkPointSetVtkMapper2D_openMeAloneTransformed640x480 mitkPointSetVtkMapper2DTransformedPointsTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneTransformedPoints640x480REF.png #corresponding reference screenshot ) # Currently not working on windows because of a rendering timing issue # see bug 18083 for details if(NOT WIN32) mitkAddCustomModuleRenderingTest(mitkSurfaceDepthSortingTransparency_StanfordBunnySTL640x480 mitkSurfaceDepthSortingTest ${MITK_DATA_DIR}/RenderingTestData/Stanford_bunny.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Stanford_bunnySTLDepthSorting640x480REF.png) endif() # BUG 18695 - tests deactivated, because win 32 bit continuous renders images slightly different. TODO! #Test reslice interpolation #note: nearest mode is already tested by swivel test #mitkAddCustomModuleRenderingTest(ResliceInterpolationIsLinear mitkImageVtkMapper2DResliceInterpolationPropertyTest # 1 #linear # ${MITK_DATA_DIR}/Pic3D.nrrd # -V # ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefLinear.png #corresponding reference screenshot LINEAR #) #mitkAddCustomModuleRenderingTest(ResliceInterpolationIsCubic mitkImageVtkMapper2DResliceInterpolationPropertyTest # 3 #cubic # ${MITK_DATA_DIR}/Pic3D.nrrd # -V # ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefCubic.png #corresponding reference screenshot CUBIC #) #End test reslice interpolation # Testing of the rendering of binary images #mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2D_binaryTestImage640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice # ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage # -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImage640x480REF.png #corresponding reference screenshot #) #mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2D_binaryTestImageWithRef640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice # ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage # -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImageWithRef640x480REF.png #corresponding reference screenshot #) # End of binary image tests mitkAddCustomModuleRenderingTest(mitkSurfaceVtkMapper3DTest_TextureProperty mitkSurfaceVtkMapper3DTest ${MITK_DATA_DIR}/RenderingTestData/earth.jpg -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedSphere640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DTransferFunctionTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-TransferFunctionRGBImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2DOpacityTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DOpacityTransferFunctionTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-OpacityTransferFunctionRGBImage640x480REF.png #corresponding reference screenshot ) ############################## DISABLED TESTS mitkAddCustomModuleRenderingTest(mitkImageVtkMapper2DLookupTableTest_Png2D-bw mitkImageVtkMapper2DLookupTableTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-LookupTableRGBImage640x480REF.png #corresponding reference screenshot ) #mitkAddCustomModuleRenderingTest(mitkImageTest_color2DImage mitkImageTest # ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg #) #mitkAddCustomModuleRenderingTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest - # ${MITK_DATA_DIR}/Pic3D.pic.gz ${MITK_DATA_DIR}/BallBinary30x30x30.pic.gz + # ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/BallBinary30x30x30.nrrd #) mitkAddCustomModuleRenderingTest(mitkPlaneGeometryDataMapper2DTest mitkPlaneGeometryDataMapper2DTest ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/PlaneGeometryMapper640x480REF.png #corresponding reference screenshot ) endif() # TARGET ${TESTDRIVER} diff --git a/Modules/Core/test/mitkImageSliceSelectorTest.cpp b/Modules/Core/test/mitkImageSliceSelectorTest.cpp index 6881f5cdbd..98c0285616 100644 --- a/Modules/Core/test/mitkImageSliceSelectorTest.cpp +++ b/Modules/Core/test/mitkImageSliceSelectorTest.cpp @@ -1,207 +1,138 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkIOUtil.h> #include <mitkImage.h> #include <mitkImageSliceSelector.h> #include <fstream> int mitkImageSliceSelectorTest(int argc, char *argv[]) { int slice_nr = 1; std::cout << "Loading file: "; if (argc == 0) { std::cout << "no file specified [FAILED]" << std::endl; return EXIT_FAILURE; } mitk::Image::Pointer image; try { image = mitk::IOUtil::Load<mitk::Image>(argv[1]); } catch (const mitk::Exception &) { std::cout << "file not an image - test will not be applied [PASSED]" << std::endl; std::cout << "[TEST DONE]" << std::endl; return EXIT_SUCCESS; } catch ( const itk::ExceptionObject &ex ) { std::cout << "Exception: " << ex.GetDescription() << "[FAILED]" << std::endl; return EXIT_FAILURE; } if (image->GetDimension(2) < 2) slice_nr = 0; // Take a slice mitk::ImageSliceSelector::Pointer slice = mitk::ImageSliceSelector::New(); slice->SetInput(image); slice->SetSliceNr(slice_nr); slice->Update(); std::cout << "Testing IsInitialized(): "; if (slice->GetOutput()->IsInitialized() == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing IsSliceSet(): "; if (slice->GetOutput()->IsSliceSet(0) == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; - /* deactivated because IpPic is not available any more (see bug 16662) - if(itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameExtension(argv[1])).find(".pic")!=std::string::npos) - { - std::cout << "Testing whether the slice is identical with a slice loaded by mitkIpPicGetSlice:"; - mitkIpPicDescriptor *picslice = mitkIpPicGetSlice(argv[1], nullptr, (image->GetDimension(2)-1-slice_nr)+1); - int i, size = _mitkIpPicSize(picslice); - char * p1 = (char*)slice->GetPic()->data; - char * p2 = (char*)picslice->data; - //picslice->info->write_protect=mitkIpFalse; - //mitkIpPicPut("C:\\1aaaaIPPIC.pic", picslice); - //mitkIpPicPut("C:\\1aaaaSEL.pic", slice->GetPic()); - for(i=0; i<size; ++i, ++p1, ++p2) - { - if((*p1) != (*p2)) - { - std::cout<<"[FAILED]"<<std::endl; - return EXIT_FAILURE; - } - } - std::cout<<"[PASSED]"<<std::endl; - mitkIpPicFree(picslice); - } - */ - - /* Deactivated because CylindricToCartesianFilter is not available any more (see bug 16662) - try - { - std::cout << "Testing another, smaller (!!) input with the same slice-selector(): "; - //Use CylindricToCartesianFilter - mitk::CylindricToCartesianFilter::Pointer cyl2cart = mitk::CylindricToCartesianFilter::New(); - cyl2cart->SetInput(image); - //the output size of this filter is smaller than the of the input!! - cyl2cart->SetTargetXSize( 64 ); - - //Use the same slice-selector again, this time to take a slice of the filtered image - //which is smaller than the one of the old input!! - slice->SetInput(cyl2cart->GetOutput()); - slice->SetSliceNr(1); - - //The requested region is still the old one, - //therefore the following results in most ITK versions - //in an exception! - slice->Update(); - - //If no exception occured, check that the requested region is now - //the one of the smaller image - if(cyl2cart->GetOutput()->GetLargestPossibleRegion().GetSize()[0]!=64) - { - std::cout<<"Part 1 [FAILED]"<<std::endl; - return EXIT_FAILURE; - } - std::cout<<"Part 1 (without exception) [PASSED] "; - - //Check that the size of the output is now the one of the smaller image - if((cyl2cart->GetOutput()->GetDimensions()[0]!=64) || (cyl2cart->GetOutput()->GetDimensions()[1]!=64)) - { - std::cout<<"Part 1b [FAILED]"<<std::endl; - return EXIT_FAILURE; - } - std::cout<<"Part 1b [PASSED] "; - } - catch (const itk::ExceptionObject &err) - { - std::cout<<"Part 1(with expected exception) ... seems to be not ITK 2.0.0 [PASSED]"<<std::endl; - std::cout<<err<<std::endl; - //after such an exception, we need to call ResetPipeline. - slice->ResetPipeline(); - } - */ try { slice->UpdateLargestPossibleRegion(); } catch (const itk::ExceptionObject &) { std::cout << "Part 2 [FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "Part 2 [PASSED]" << std::endl; std::cout << "Testing IsInitialized(): "; if (slice->GetOutput()->IsInitialized() == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing IsSliceSet(): "; if (slice->GetOutput()->IsSliceSet(0) == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; if (image->GetDimension(3) > 1) { int time = image->GetDimension(3) - 1; std::cout << "Testing 3D+t: Setting time to " << time << ": "; slice->SetTimeNr(time); if (slice->GetTimeNr() != time) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing 3D+t: Updating slice: "; slice->Update(); if (slice->GetOutput()->IsInitialized() == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing 3D+t: IsSliceSet(): "; if (slice->GetOutput()->IsSliceSet(0) == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing 3D+t: First slice in reader available: "; if (image->IsSliceSet(0, time) == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; } std::cout << "[TEST DONE]" << std::endl; return EXIT_SUCCESS; } diff --git a/Modules/Core/test/mitkImageTest.cpp b/Modules/Core/test/mitkImageTest.cpp index bd86398541..18abf3c780 100644 --- a/Modules/Core/test/mitkImageTest.cpp +++ b/Modules/Core/test/mitkImageTest.cpp @@ -1,552 +1,538 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // mitk includes #include "mitkException.h" #include "mitkIOUtil.h" #include "mitkImageGenerator.h" #include "mitkImagePixelReadAccessor.h" #include "mitkImageReadAccessor.h" #include "mitkPixelTypeMultiplex.h" #include <mitkImage.h> #include <mitkImageCast.h> #include <mitkImageDataItem.h> #include <mitkImageStatisticsHolder.h> #include <mitkTestingMacros.h> #include "mitkImageSliceSelector.h" // itk includes #include <itkImage.h> #include <itkMersenneTwisterRandomVariateGenerator.h> // stl includes #include <fstream> // vtk includes #include <vtkImageData.h> // Checks if reference count is correct after using GetVtkImageData() bool ImageVtkDataReferenceCheck(const char *fname) { const std::string filename = std::string(fname); try { mitk::Image::Pointer image = mitk::IOUtil::Load<mitk::Image>(filename); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "Non-nullptr image") vtkImageData *vtk = image->GetVtkImageData(); if (vtk == nullptr) return false; } catch (...) { MITK_TEST_FAILED_MSG(<< "Could not read file for testing: " << filename); return false; } return true; } template <class T> void TestRandomPixelAccess(const mitk::PixelType /*ptype*/, mitk::Image::Pointer image, mitk::Point3D &point, mitk::ScalarType &value) { // generate a random point in world coordinates mitk::Point3D xMax, yMax, zMax, xMaxIndex, yMaxIndex, zMaxIndex; xMaxIndex.Fill(0.0f); yMaxIndex.Fill(0.0f); zMaxIndex.Fill(0.0f); xMaxIndex[0] = image->GetLargestPossibleRegion().GetSize()[0]; yMaxIndex[1] = image->GetLargestPossibleRegion().GetSize()[1]; zMaxIndex[2] = image->GetLargestPossibleRegion().GetSize()[2]; image->GetGeometry()->IndexToWorld(xMaxIndex, xMax); image->GetGeometry()->IndexToWorld(yMaxIndex, yMax); image->GetGeometry()->IndexToWorld(zMaxIndex, zMax); MITK_INFO << "Origin " << image->GetGeometry()->GetOrigin()[0] << " " << image->GetGeometry()->GetOrigin()[1] << " " << image->GetGeometry()->GetOrigin()[2] << ""; MITK_INFO << "MaxExtend " << xMax[0] << " " << yMax[1] << " " << zMax[2] << ""; itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randomGenerator = itk::Statistics::MersenneTwisterRandomVariateGenerator::New(); randomGenerator->Initialize(std::rand()); // initialize with random value, to get sensible random points for the image point[0] = randomGenerator->GetUniformVariate(image->GetGeometry()->GetOrigin()[0], xMax[0]); point[1] = randomGenerator->GetUniformVariate(image->GetGeometry()->GetOrigin()[1], yMax[1]); point[2] = randomGenerator->GetUniformVariate(image->GetGeometry()->GetOrigin()[2], zMax[2]); MITK_INFO << "RandomPoint " << point[0] << " " << point[1] << " " << point[2] << ""; // test values and max/min mitk::ScalarType imageMin = image->GetStatistics()->GetScalarValueMin(); mitk::ScalarType imageMax = image->GetStatistics()->GetScalarValueMax(); // test accessing PixelValue with coordinate leading to a negative index const mitk::Point3D geom_origin = image->GetGeometry()->GetOrigin(); const mitk::Point3D geom_center = image->GetGeometry()->GetCenter(); // shift position from origin outside of the image ( in the opposite direction to [center-origin] vector which points // in the inside) mitk::Point3D position = geom_origin + (geom_origin - geom_center); MITK_INFO << "Testing access outside of the image"; unsigned int dim = image->GetDimension(); if (dim == 3 || dim == 4) { mitk::ImagePixelReadAccessor<T, 3> imAccess3(image, image->GetVolumeData(0)); // Comparison ?>=0 not needed since all position[i] and timestep are unsigned int // (position[0]>=0 && position[1] >=0 && position[2]>=0 && timestep>=0) // bug-11978 : we still need to catch index with negative values if (point[0] < 0 || point[1] < 0 || point[2] < 0) { MITK_WARN << "Given position (" << point << ") is out of image range, returning 0."; } else { value = static_cast<mitk::ScalarType>(imAccess3.GetPixelByWorldCoordinates(point)); MITK_TEST_CONDITION((value >= imageMin && value <= imageMax), "Value returned is between max/min"); } itk::Index<3> itkIndex; image->GetGeometry()->WorldToIndex(position, itkIndex); MITK_TEST_FOR_EXCEPTION_BEGIN(mitk::Exception); imAccess3.GetPixelByIndexSafe(itkIndex); MITK_TEST_FOR_EXCEPTION_END(mitk::Exception); } MITK_INFO << imageMin << " " << imageMax << " " << value << ""; } class mitkImageTestClass { public: void SetClonedGeometry_None_ClonedEqualInput() { mitk::Image::Pointer image = mitk::ImageGenerator::GenerateRandomImage<float>(100, 100, 100, 1, 0.2, 0.3, 0.4); //----------------- // geometry information for image mitk::Point3D origin; mitk::Vector3D right, bottom; mitk::Vector3D spacing; mitk::FillVector3D(origin, 17.0, 19.92, 7.83); mitk::FillVector3D(right, 1.0, 2.0, 3.0); mitk::FillVector3D(bottom, 0.0, -3.0, 2.0); mitk::FillVector3D(spacing, 0.78, 0.91, 2.23); // InitializeStandardPlane(rightVector, downVector, spacing) mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing); planegeometry->SetOrigin(origin); planegeometry->ChangeImageGeometryConsideringOriginOffset(true); image->SetClonedGeometry(planegeometry); mitk::BaseGeometry::Pointer imageGeometry = image->GetGeometry(); MITK_ASSERT_EQUAL(imageGeometry, planegeometry, "Matrix elements of cloned matrix equal original matrix"); } }; int mitkImageTest(int argc, char *argv[]) { MITK_TEST_BEGIN(mitkImageTest); mitkImageTestClass tester; tester.SetClonedGeometry_None_ClonedEqualInput(); // Create Image out of nowhere mitk::Image::Pointer imgMem = mitk::Image::New(); mitk::PixelType pt = mitk::MakeScalarPixelType<int>(); unsigned int dim[] = {100, 100, 20}; MITK_TEST_CONDITION_REQUIRED(imgMem.IsNotNull(), "An image was created. "); // Initialize image imgMem->Initialize(pt, 3, dim); MITK_TEST_CONDITION_REQUIRED(imgMem->IsInitialized(), "Image::IsInitialized() ?"); MITK_TEST_CONDITION_REQUIRED(imgMem->GetPixelType() == pt, "PixelType was set correctly."); int *p = nullptr; int *p2 = nullptr; try { mitk::ImageReadAccessor imgMemAcc(imgMem); p = (int *)imgMemAcc.GetData(); } catch ( const mitk::Exception &e ) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION(p != nullptr, "GetData() returned not-nullptr pointer."); // filling image const unsigned int size = dim[0] * dim[1] * dim[2]; for (unsigned int i = 0; i < size; ++i, ++p) *p = (signed int)i; // Getting it again and compare with filled values: try { mitk::ImageReadAccessor imgMemAcc(imgMem); p2 = (int *)imgMemAcc.GetData(); } catch ( const mitk::Exception &e ) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION(p2 != nullptr, "GetData() returned not-nullptr pointer."); bool isEqual = true; for (unsigned int i = 0; i < size; ++i, ++p2) { if (*p2 != (signed int)i) { isEqual = false; } } MITK_TEST_CONDITION(isEqual, "The values previously set as data are correct [pixelwise comparison]."); // Testing GetSliceData() and compare with filled values: try { mitk::ImageReadAccessor imgMemAcc(imgMem, imgMem->GetSliceData(dim[2] / 2)); p2 = (int *)imgMemAcc.GetData(); } catch ( const mitk::Exception &e ) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION_REQUIRED(p2 != nullptr, "Valid slice data returned"); unsigned int xy_size = dim[0] * dim[1]; unsigned int start_mid_slice = (dim[2] / 2) * xy_size; isEqual = true; for (unsigned int i = 0; i < xy_size; ++i, ++p2) { if (*p2 != (signed int)(i + start_mid_slice)) { isEqual = false; } } MITK_TEST_CONDITION(isEqual, "The SliceData are correct [pixelwise comparison]. "); imgMem = mitk::Image::New(); // testing re-initialization of test image mitk::PixelType pType = mitk::MakePixelType<int, int, 1>(); imgMem->Initialize(pType, 3, dim); MITK_TEST_CONDITION_REQUIRED(imgMem->GetDimension() == 3, "Testing initialization parameter dimension!"); MITK_TEST_CONDITION_REQUIRED(imgMem->GetPixelType() == pType, "Testing initialization parameter pixeltype!"); MITK_TEST_CONDITION_REQUIRED( imgMem->GetDimension(0) == dim[0] && imgMem->GetDimension(1) == dim[1] && imgMem->GetDimension(2) == dim[2], "Testing initialization of dimensions!"); MITK_TEST_CONDITION(imgMem->IsInitialized(), "Image is initialized."); // Setting volume again: try { mitk::ImageReadAccessor imgMemAcc(imgMem); imgMem->SetVolume(imgMemAcc.GetData()); } catch ( const mitk::Exception &e ) { MITK_ERROR << e.what(); } //----------------- // geometry information for image mitk::Point3D origin; mitk::Vector3D right, bottom; mitk::Vector3D spacing; mitk::FillVector3D(origin, 17.0, 19.92, 7.83); mitk::FillVector3D(right, 1.0, 2.0, 3.0); mitk::FillVector3D(bottom, 0.0, -3.0, 2.0); mitk::FillVector3D(spacing, 0.78, 0.91, 2.23); // InitializeStandardPlane(rightVector, downVector, spacing) mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing); planegeometry->SetOrigin(origin); planegeometry->SetImageGeometry(true); // Testing Initialize(const mitk::PixelType& type, const mitk::Geometry3D& geometry, unsigned int slices) with // PlaneGeometry and GetData(): "; imgMem->Initialize(mitk::MakePixelType<int, int, 1>(), *planegeometry); MITK_TEST_CONDITION_REQUIRED( imgMem->GetGeometry()->GetOrigin() == static_cast<mitk::BaseGeometry *>(planegeometry)->GetOrigin(), "Testing correct setting of geometry via initialize!"); try { mitk::ImageReadAccessor imgMemAcc(imgMem); p = (int *)imgMemAcc.GetData(); } catch ( const mitk::Exception &e ) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION_REQUIRED(p != nullptr, "GetData() returned valid pointer."); // Testing Initialize(const mitk::PixelType& type, int sDim, const mitk::PlaneGeometry& geometry) and GetData(): "; imgMem->Initialize(mitk::MakePixelType<int, int, 1>(), 40, *planegeometry); try { mitk::ImageReadAccessor imgMemAcc(imgMem); p = (int *)imgMemAcc.GetData(); } catch ( const mitk::Exception &e ) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION_REQUIRED(p != nullptr, "GetData() returned valid pointer."); //----------------- // testing origin information and methods MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetOrigin(), origin), "Testing correctness of origin via GetGeometry()->GetOrigin(): "); // Setting origin via SetOrigin(origin): "; mitk::FillVector3D(origin, 37.0, 17.92, 27.83); imgMem->SetOrigin(origin); // Test origin MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetOrigin(), origin), "Testing correctness of changed origin via GetGeometry()->GetOrigin(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetSlicedGeometry()->GetPlaneGeometry(0)->GetOrigin(), origin), "Testing correctness of changed origin via GetSlicedGeometry()->GetPlaneGeometry(0)->GetOrigin(): "); //----------------- // testing spacing information and methodsunsigned int dim[]={100,100,20}; MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetSpacing(), spacing), "Testing correct spacing from Geometry3D!"); mitk::FillVector3D(spacing, 7.0, 0.92, 1.83); imgMem->SetSpacing(spacing); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetSpacing(), spacing), "Testing correctness of changed spacing via GetGeometry()->GetSpacing(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetSlicedGeometry()->GetPlaneGeometry(0)->GetSpacing(), spacing), "Testing correctness of changed spacing via GetSlicedGeometry()->GetPlaneGeometry(0)->GetSpacing(): "); mitk::Image::Pointer vecImg = mitk::Image::New(); try { mitk::ImageReadAccessor imgMemAcc(imgMem); vecImg->Initialize(imgMem->GetPixelType(), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/); vecImg->SetImportChannel(const_cast<void *>(imgMemAcc.GetData()), 0, mitk::Image::CopyMemory); vecImg->SetImportChannel(const_cast<void *>(imgMemAcc.GetData()), 1, mitk::Image::CopyMemory); mitk::ImageReadAccessor vecImgAcc(vecImg); mitk::ImageReadAccessor vecImgAcc0(vecImg, vecImg->GetChannelData(0)); mitk::ImageReadAccessor vecImgAcc1(vecImg, vecImg->GetChannelData(1)); MITK_TEST_CONDITION_REQUIRED(vecImgAcc0.GetData() != nullptr && vecImgAcc1.GetData() != nullptr, "Testing set and return of channel data!"); MITK_TEST_CONDITION_REQUIRED(vecImg->IsValidSlice(0, 0, 1), ""); MITK_TEST_OUTPUT(<< " Testing whether CopyMemory worked"); MITK_TEST_CONDITION_REQUIRED(imgMemAcc.GetData() != vecImgAcc.GetData(), ""); MITK_TEST_OUTPUT(<< " Testing destruction after SetImportChannel"); vecImg = nullptr; MITK_TEST_CONDITION_REQUIRED(vecImg.IsNull(), "testing destruction!"); } catch ( const mitk::Exception &e ) { MITK_ERROR << e.what(); } //----------------- MITK_TEST_OUTPUT(<< "Testing initialization via vtkImageData"); MITK_TEST_OUTPUT(<< " Setting up vtkImageData"); vtkImageData *vtkimage = vtkImageData::New(); vtkimage->Initialize(); vtkimage->SetDimensions(2, 3, 4); double vtkorigin[] = {-350, -358.203, -1363.5}; vtkimage->SetOrigin(vtkorigin); mitk::Point3D vtkoriginAsMitkPoint; mitk::vtk2itk(vtkorigin, vtkoriginAsMitkPoint); double vtkspacing[] = {1.367, 1.367, 2}; vtkimage->SetSpacing(vtkspacing); vtkimage->AllocateScalars(VTK_SHORT, 1); std::cout << "[PASSED]" << std::endl; MITK_TEST_OUTPUT(<< " Testing mitk::Image::Initialize(vtkImageData*, ...)"); mitk::Image::Pointer mitkByVtkImage = mitk::Image::New(); mitkByVtkImage->Initialize(vtkimage); MITK_TEST_CONDITION_REQUIRED(mitkByVtkImage->IsInitialized(), ""); vtkimage->Delete(); MITK_TEST_OUTPUT(<< " Testing whether spacing has been correctly initialized from vtkImageData"); mitk::Vector3D spacing2 = mitkByVtkImage->GetGeometry()->GetSpacing(); mitk::Vector3D vtkspacingAsMitkVector; mitk::vtk2itk(vtkspacing, vtkspacingAsMitkVector); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(spacing2, vtkspacingAsMitkVector), ""); MITK_TEST_OUTPUT( << " Testing whether GetSlicedGeometry(0)->GetOrigin() has been correctly initialized from vtkImageData"); mitk::Point3D origin2 = mitkByVtkImage->GetSlicedGeometry(0)->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2, vtkoriginAsMitkPoint), ""); MITK_TEST_OUTPUT(<< " Testing whether GetGeometry()->GetOrigin() has been correctly initialized from vtkImageData"); origin2 = mitkByVtkImage->GetGeometry()->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2, vtkoriginAsMitkPoint), ""); MITK_TEST_OUTPUT(<< " Testing if vtkOrigin is (0, 0, 0). This behaviour is due to historical development of MITK. " "Aslo see bug 5050!"); vtkImageData *vtkImage = imgMem->GetVtkImageData(); auto vtkOrigin = vtkImage->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vtkOrigin[0], 0), "testing vtkOrigin[0] to be 0"); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vtkOrigin[1], 0), "testing vtkOrigin[1] to be 0"); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vtkOrigin[2], 0), "testing vtkOrigin[2] to be 0"); - // TODO test the following initializers on channel-incorporation - // void mitk::Image::Initialize(const mitk::PixelType& type, unsigned int dimension, unsigned int *dimensions, - // unsigned int channels) - // void mitk::Image::Initialize(const mitk::PixelType& type, int sDim, const mitk::PlaneGeometry& geometry2d, bool - // flipped, unsigned int channels, int tDim ) - // void mitk::Image::Initialize(const mitk::Image* image) - // void mitk::Image::Initialize(const mitkIpPicDescriptor* pic, int channels, int tDim, int sDim) - - // mitk::Image::Pointer vecImg = mitk::Image::New(); - // vecImg->Initialize(PixelType(typeid(float), 6, itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR), - // *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/, false /*shiftBoundingBoxMinimumToZero*/ ); - // vecImg->Initialize(PixelType(typeid(itk::Vector<float,6>)), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/, - // false /*shiftBoundingBoxMinimumToZero*/ ); - // testing access by index coordinates and by world coordinates MITK_TEST_CONDITION_REQUIRED(argc == 2, "Check if test image is accessible!"); const std::string filename = std::string(argv[1]); mitk::Image::Pointer image; try { image = mitk::IOUtil::Load<mitk::Image>(filename); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "Non-nullptr image") } catch (...) { MITK_TEST_FAILED_MSG(<< "Could not read file for testing: " << filename); return 0; } mitk::Point3D point; mitk::ScalarType value = -1.; mitkPixelTypeMultiplex3( TestRandomPixelAccess, image->GetImageDescriptor()->GetChannelTypeById(0), image, point, value) { // testing the clone method of mitk::Image mitk::Image::Pointer cloneImage = image->Clone(); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetDimension() == image->GetDimension(), "Clone (testing dimension)"); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetPixelType() == image->GetPixelType(), "Clone (testing pixel type)"); // After cloning an image the geometry of both images should be equal too MITK_TEST_CONDITION_REQUIRED(cloneImage->GetGeometry()->GetOrigin() == image->GetGeometry()->GetOrigin(), "Clone (testing origin)"); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetGeometry()->GetSpacing() == image->GetGeometry()->GetSpacing(), "Clone (testing spacing)"); MITK_TEST_CONDITION_REQUIRED( mitk::MatrixEqualElementWise(cloneImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix(), image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix()), "Clone (testing transformation matrix)"); MITK_TEST_CONDITION_REQUIRED( mitk::MatrixEqualElementWise(cloneImage->GetTimeGeometry() ->GetGeometryForTimeStep(cloneImage->GetDimension(3) - 1) ->GetIndexToWorldTransform() ->GetMatrix(), cloneImage->GetTimeGeometry() ->GetGeometryForTimeStep(image->GetDimension(3) - 1) ->GetIndexToWorldTransform() ->GetMatrix()), "Clone(testing time sliced geometry)"); for (unsigned int i = 0u; i < cloneImage->GetDimension(); ++i) { MITK_TEST_CONDITION_REQUIRED(cloneImage->GetDimension(i) == image->GetDimension(i), "Clone (testing dimension " << i << ")"); } } // access via itk if (image->GetDimension() > 3) // CastToItk only works with 3d images so we need to check for 4d images { mitk::ImageTimeSelector::Pointer selector = mitk::ImageTimeSelector::New(); selector->SetTimeNr(0); selector->SetInput(image); selector->Update(); image = selector->GetOutput(); } if (image->GetDimension() == 3) { typedef itk::Image<double, 3> ItkFloatImage3D; ItkFloatImage3D::Pointer itkimage; try { mitk::CastToItkImage(image, itkimage); MITK_TEST_CONDITION_REQUIRED(itkimage.IsNotNull(), "Test conversion to itk::Image!"); } catch ( const std::exception &e ) { MITK_INFO << e.what(); } mitk::Point3D itkPhysicalPoint; image->GetGeometry()->WorldToItkPhysicalPoint(point, itkPhysicalPoint); MITK_INFO << "ITKPoint " << itkPhysicalPoint[0] << " " << itkPhysicalPoint[1] << " " << itkPhysicalPoint[2] << ""; mitk::Point3D backTransformedPoint; image->GetGeometry()->ItkPhysicalPointToWorld(itkPhysicalPoint, backTransformedPoint); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(point, backTransformedPoint), "Testing world->itk-physical->world consistency"); itk::Index<3> idx; bool status = itkimage->TransformPhysicalPointToIndex(itkPhysicalPoint, idx); MITK_INFO << "ITK Index " << idx[0] << " " << idx[1] << " " << idx[2] << ""; if (status && value != -1.) { float valByItk = itkimage->GetPixel(idx); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(valByItk, value), "Compare value of pixel returned by mitk in comparison to itk"); } else { MITK_WARN << "Index is out buffered region!"; } } else { MITK_INFO << "Image does not contain three dimensions, some test cases are skipped!"; } // clone generated 3D image with one slice in z direction (cf. bug 11058) auto *threeDdim = new unsigned int[3]; threeDdim[0] = 100; threeDdim[1] = 200; threeDdim[2] = 1; mitk::Image::Pointer threeDImage = mitk::Image::New(); threeDImage->Initialize(mitk::MakeScalarPixelType<float>(), 3, threeDdim); mitk::Image::Pointer cloneThreeDImage = threeDImage->Clone(); // check that the clone image has the same dimensionality as the source image MITK_TEST_CONDITION_REQUIRED(cloneThreeDImage->GetDimension() == 3, "Testing if the clone image initializes with 3D!"); MITK_TEST_CONDITION_REQUIRED(ImageVtkDataReferenceCheck(argv[1]), "Checking reference count of Image after using GetVtkImageData()"); MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkVtkPropRendererTest.cpp b/Modules/Core/test/mitkVtkPropRendererTest.cpp deleted file mode 100644 index e884fc91b9..0000000000 --- a/Modules/Core/test/mitkVtkPropRendererTest.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "vtkActor.h" -#include "vtkPolyDataMapper.h" -#include "vtkProperty.h" -#include "vtkRenderWindow.h" -#include "vtkRenderWindowInteractor.h" -#include "vtkRenderer.h" -#include "vtkSphereSource.h" -#include "vtkUnsignedCharArray.h" - -#include <mitkImage.h> -#include <mitkPicFileReader.h> - -#include <mitkDataStorage.h> -#include <mitkLevelWindow.h> -#include <mitkLevelWindowProperty.h> - -#include <mitkVtkLayerController.h> -#include <mitkVtkPropRenderer.h> -#include <vtkMitkRenderProp.h> - -#include <itksys/SystemTools.hxx> - -#include <fstream> -int mitkVtkPropRendererTest(int argc, char *argv[]) -{ - // independently read header of pic file - mitkIpPicDescriptor *picheader = nullptr; - if (argc >= 1) - { - if (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameExtension(argv[1])).find(".pic") != - std::string::npos) - picheader = mitkIpPicGetHeader(argv[1], nullptr); - } - if (picheader == nullptr) - { - std::cout << "file not found/not a pic-file - test not applied [PASSED]" << std::endl; - std::cout << "[TEST DONE]" << std::endl; - return EXIT_SUCCESS; - } - - static long int sum_orig_Pic3D_pic_gz = 14685408; - - mitkIpPicGetTags(argv[1], picheader); - - // Read pic-Image from file - std::cout << "Reading image: "; - mitk::PicFileReader::Pointer reader = mitk::PicFileReader::New(); - reader->SetFileName(argv[1]); - reader->Update(); - std::cout << "[PASSED]" << std::endl; - - mitk::Image::Pointer image = reader->GetOutput(); - - std::cout << "Creating node: "; - mitk::DataNode::Pointer node = mitk::DataNode::New(); - node->SetData(image); - std::cout << "[PASSED]" << std::endl; - - std::cout << "Creating DataStorage: "; - mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); - std::cout << "[PASSED]" << std::endl; - - std::cout << "Adding node via DataStorage: "; - ds->Add(node); - std::cout << "[PASSED]" << std::endl; - - std::cout << "Adding level-window property: "; - mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); - mitk::LevelWindow levelwindow; - levelwindow.SetAuto(image); - levWinProp->SetLevelWindow(levelwindow); - node->GetPropertyList()->SetProperty("levelwindow", levWinProp); - std::cout << "[PASSED]" << std::endl; - - std::cout << "Creating a vtk sphere: "; - vtkSphereSource *sphere = vtkSphereSource::New(); - sphere->SetRadius(1.0); - sphere->SetThetaResolution(18); - sphere->SetPhiResolution(18); - - vtkPolyDataMapper *map = vtkPolyDataMapper::New(); - map->SetInput(sphere->GetOutput()); - sphere->Delete(); - - vtkActor *aSphere = vtkActor::New(); - aSphere->SetMapper(map); - map->Delete(); - aSphere->GetProperty()->SetColor(0, 0, 1); // sphere color blue - std::cout << "[PASSED]" << std::endl; - - std::cout << "Creating a renderer for the sphere: "; - vtkRenderer *sphereRenderer = vtkRenderer::New(); - sphereRenderer->AddActor(aSphere); - aSphere->Delete(); - // sphereRenderer->SetBackground(1,1,1); // Background color white - std::cout << "[PASSED]" << std::endl; - - std::cout << "Creating vtkRenderWindow and VtkPropRenderer: "; - vtkRenderWindow *renderWindow = vtkRenderWindow::New(); - mitk::VtkPropRenderer::Pointer propRenderer = mitk::VtkPropRenderer::New("the renderer", renderWindow); - // propRenderer->SetMapperID(2); - std::cout << "[PASSED]" << std::endl; - - // renderWindow->AddRenderer(sphereRenderer); - // renderWindow->SetErase(0); - - std::cout << "BaseRenderer::SetData(iterator): "; - propRenderer->SetDataStorage(ds); - std::cout << "[PASSED]" << std::endl; - - std::cout << "Creating vtkMitkRenderProp and connecting it to the VtkPropRenderer: "; - vtkMitkRenderProp *renderProp = vtkMitkRenderProp::New(); - renderProp->SetPropRenderer(propRenderer); - propRenderer->GetVtkRenderer()->AddViewProp(renderProp); - std::cout << "[PASSED]" << std::endl; - - std::cout << "Inserting the sphere into the foreground of the VtkLayerController: "; - mitk::VtkLayerController::GetInstance(renderWindow)->InsertForegroundRenderer(sphereRenderer, true); - std::cout << "[PASSED]" << std::endl; - - // mouse interaction for debugging - // vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); - // iren->SetRenderWindow(renderWindow); - - std::cout << "Setting and getting size of renderWindow: "; - renderWindow->SetSize(400, 400); - int *size = renderWindow->GetSize(); - std::cout << "[PASSED]" << std::endl; - - std::cout << "Do the rendering: "; - renderWindow->Render(); - std::cout << "[PASSED]" << std::endl; - - // iren->Start(); - - std::cout << "Testing to pick a world position: "; - mitk::Point2D p; - mitk::Point3D p_mm; - p[0] = 10; - p[1] = 10; - propRenderer->PickWorldPoint(p, p_mm); - std::cout << "returned world position: " << p_mm << "\n"; - - std::cout << "Creating vtkUnsignedCharArray: "; - vtkUnsignedCharArray *vtkImage = vtkUnsignedCharArray::New(); - std::cout << "[PASSED]" << std::endl; - - cout << "Reading image from renderWindow" << std::endl; - renderWindow->GetRGBACharPixelData(0, 0, size[0] - 1, size[1] - 1, 0, vtkImage); - cout << "Read " << size[0] * size[1] << " data points\n"; - - cout << "Computing sum of all RGBA values..\n"; - long int sum_now = 0; - for (int i = 0; i < size[0] * size[1]; i++) - sum_now += vtkImage->GetValue(i); - std::cout << "Sum of all RGBA values: " << sum_now << "\n"; - std::cout << "Sum should be: " << sum_orig_Pic3D_pic_gz << "\n"; - - // std::string Pic3d_pic_gz_str("Pic3D.pic.gz"); - // std::cout << "pic3d " << Pic3d_pic_gz_str << "\n"; - // std::cout << "argv " << argv_str << "\n"; - // std::cout << "find " << (int) argv_str.find("Pic3D.pic.gz") << "\n"; - // std::cout << "size " << argv_str.size() << "\n"; - - // if(argv_str.size() - ((int) argv_str.find("Pic3D.pic.gz")) == 12) - //{ - // std::cout << "Input image is Pic3D.pic.gz\n"; - // std::cout << "Sum should be: " << sum_orig_Pic3D_pic_gz << "\n"; - // if(sum_orig_Pic3D_pic_gz!=sum_now) - // { - // std::cout<<"[FAILED]"<<std::endl; - // return EXIT_FAILURE; - // } - // std::cout<<"[PASSED]"<<std::endl; - //} - // else - //{ - // std::cout<<"Unknown image, comparison test skipped"<<std::endl; - //} - - propRenderer->GetVtkRenderer()->RemoveViewProp(renderProp); - renderProp->Delete(); - propRenderer = nullptr; - sphereRenderer->Delete(); - - renderWindow->Delete(); - - vtkImage->Delete(); - ds = nullptr; - - std::cout << "[TEST DONE]" << std::endl; - return EXIT_SUCCESS; -} diff --git a/Modules/DICOM/src/mitkGantryTiltInformation.cpp b/Modules/DICOM/src/mitkGantryTiltInformation.cpp index b6efd46967..f268ddf8c8 100644 --- a/Modules/DICOM/src/mitkGantryTiltInformation.cpp +++ b/Modules/DICOM/src/mitkGantryTiltInformation.cpp @@ -1,254 +1,255 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ //#define MBILOG_ENABLE_DEBUG #include "mitkGantryTiltInformation.h" #include "mitkDICOMTag.h" #include "mitkLogMacros.h" mitk::GantryTiltInformation::GantryTiltInformation() : m_ShiftUp(0.0) , m_ShiftRight(0.0) , m_ShiftNormal(0.0) , m_ITKAssumedSliceSpacing(0.0) , m_NumberOfSlicesApart(0) { } #define doublepoint(x) \ Point3Dd x; \ x[0] = x ## f[0]; \ x[1] = x ## f[1]; \ x[2] = x ## f[2]; #define doublevector(x) \ Vector3Dd x; \ x[0] = x ## f[0]; \ x[1] = x ## f[1]; \ x[2] = x ## f[2]; mitk::GantryTiltInformation::GantryTiltInformation( const Point3D& origin1f, const Point3D& origin2f, const Vector3D& rightf, const Vector3D& upf, unsigned int numberOfSlicesApart) : m_ShiftUp(0.0) , m_ShiftRight(0.0) , m_ShiftNormal(0.0) +, m_ITKAssumedSliceSpacing(0.0) , m_NumberOfSlicesApart(numberOfSlicesApart) { assert(numberOfSlicesApart); doublepoint(origin1); doublepoint(origin2); doublevector(right); doublevector(up); // determine if slice 1 (imagePosition1 and imageOrientation1) and slice 2 can be in one orthogonal slice stack: // calculate a line from origin 1, directed along the normal of slice (calculated as the cross product of orientation 1) // check if this line passes through origin 2 /* Determine if line (imagePosition2 + l * normal) contains imagePosition1. Done by calculating the distance of imagePosition1 from line (imagePosition2 + l *normal) E.g. http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html squared distance = | (pointAlongNormal - origin2) x (origin2 - origin1) | ^ 2 / |pointAlongNormal - origin2| ^ 2 ( x meaning the cross product ) */ Vector3Dd normal = itk::CrossProduct(right, up); Point3Dd pointAlongNormal = origin2 + normal; double numerator = itk::CrossProduct( pointAlongNormal - origin2 , origin2 - origin1 ).GetSquaredNorm(); double denominator = (pointAlongNormal - origin2).GetSquaredNorm(); double distance = sqrt(numerator / denominator); if ( distance > 0.001 ) // mitk::eps is too small; 1/1000 of a mm should be enough to detect tilt { MITK_DEBUG << " Series seems to contain a tilted (or sheared) geometry"; MITK_DEBUG << " Distance of expected slice origin from actual slice origin: " << distance; MITK_DEBUG << " ==> storing this shift for later analysis:"; MITK_DEBUG << " v origin1: " << origin1; MITK_DEBUG << " v origin2: " << origin2; MITK_DEBUG << " v right: " << right; MITK_DEBUG << " v up: " << up; MITK_DEBUG << " v normal: " << normal; Point3Dd projectionRight = projectPointOnLine( origin1, origin2, right ); Point3Dd projectionNormal = projectPointOnLine( origin1, origin2, normal ); m_ShiftRight = (projectionRight - origin2).GetNorm(); m_ShiftNormal = (projectionNormal - origin2).GetNorm(); /* now also check to which side the image is shifted. Calculation e.g. from http://mathworld.wolfram.com/Point-PlaneDistance.html */ Point3Dd testPoint = origin1; Vector3Dd planeNormal = up; double signedDistance = ( planeNormal[0] * testPoint[0] + planeNormal[1] * testPoint[1] + planeNormal[2] * testPoint[2] - ( planeNormal[0] * origin2[0] + planeNormal[1] * origin2[1] + planeNormal[2] * origin2[2] ) ) / sqrt( planeNormal[0] * planeNormal[0] + planeNormal[1] * planeNormal[1] + planeNormal[2] * planeNormal[2] ); m_ShiftUp = signedDistance; m_ITKAssumedSliceSpacing = (origin2 - origin1).GetNorm(); // How do we now this is assumed? See header documentation for ITK code references //double itkAssumedSliceSpacing = sqrt( m_ShiftUp * m_ShiftUp + m_ShiftNormal * m_ShiftNormal ); MITK_DEBUG << " calculated from slices " << m_NumberOfSlicesApart << " slices apart"; MITK_DEBUG << " shift normal: " << m_ShiftNormal; MITK_DEBUG << " shift normal assumed by ITK: " << m_ITKAssumedSliceSpacing; MITK_DEBUG << " shift up: " << m_ShiftUp; MITK_DEBUG << " shift right: " << m_ShiftRight; MITK_DEBUG << " tilt angle (deg): " << atan( m_ShiftUp / m_ShiftNormal ) * 180.0 / 3.1415926535; } } mitk::GantryTiltInformation mitk::GantryTiltInformation ::MakeFromTagValues( const std::string& origin1String, const std::string& origin2String, const std::string& orientationString, unsigned int numberOfSlicesApart) { Vector3D right; right.Fill(0.0); Vector3D up; right.Fill(0.0); // might be down as well, but it is just a name at this point bool orientationConversion(false); DICOMStringToOrientationVectors( orientationString, right, up, orientationConversion ); if (orientationConversion && !origin1String.empty() && !origin2String.empty() ) { bool firstOriginConversion(false); bool lastOriginConversion(false); Point3D firstOrigin = DICOMStringToPoint3D( origin1String, firstOriginConversion ); Point3D lastOrigin = DICOMStringToPoint3D( origin2String, lastOriginConversion ); if (firstOriginConversion && lastOriginConversion) { return GantryTiltInformation( firstOrigin, lastOrigin, right, up, numberOfSlicesApart ); } } std::stringstream ss; ss << "Invalid tag values when constructing tilt information from origin1 '" << origin1String << "', origin2 '" << origin2String << "', and orientation '" << orientationString << "'"; throw std::invalid_argument(ss.str()); } void mitk::GantryTiltInformation ::Print(std::ostream& os) const { os << " calculated from slices " << m_NumberOfSlicesApart << " slices apart" << std::endl; os << " shift normal: " << m_ShiftNormal << std::endl; os << " shift normal assumed by ITK: " << m_ITKAssumedSliceSpacing << std::endl; os << " shift up: " << m_ShiftUp << std::endl; os << " shift right: " << m_ShiftRight << std::endl; os << " tilt angle (deg): " << atan( m_ShiftUp / m_ShiftNormal ) * 180.0 / 3.1415926535 << std::endl; } mitk::Point3D mitk::GantryTiltInformation::projectPointOnLine( Point3Dd p, Point3Dd lineOrigin, Vector3Dd lineDirection ) { /** See illustration at http://mo.mathematik.uni-stuttgart.de/inhalt/aussage/aussage472/ vector(lineOrigin,p) = normal * ( innerproduct((p - lineOrigin),normal) / squared-length(normal) ) */ Vector3Dd lineOriginToP = p - lineOrigin; double innerProduct = lineOriginToP * lineDirection; double factor = innerProduct / lineDirection.GetSquaredNorm(); Point3Dd projection = lineOrigin + factor * lineDirection; return projection; } double mitk::GantryTiltInformation::GetTiltCorrectedAdditionalSize(unsigned int imageSizeZ) const { return fabs(m_ShiftUp / static_cast<double>(m_NumberOfSlicesApart) * static_cast<double>(imageSizeZ-1)); } double mitk::GantryTiltInformation::GetTiltAngleInDegrees() const { return atan( fabs(m_ShiftUp) / m_ShiftNormal ) * 180.0 / 3.1415926535; } double mitk::GantryTiltInformation::GetMatrixCoefficientForCorrectionInWorldCoordinates() const { // so many mm need to be shifted per slice! return m_ShiftUp / static_cast<double>(m_NumberOfSlicesApart); } double mitk::GantryTiltInformation::GetRealZSpacing() const { return m_ShiftNormal / static_cast<double>(m_NumberOfSlicesApart); } bool mitk::GantryTiltInformation::IsSheared() const { return m_NumberOfSlicesApart && ( fabs(m_ShiftRight) > 0.001 || fabs(m_ShiftUp) > 0.001); } bool mitk::GantryTiltInformation::IsRegularGantryTilt() const { return m_NumberOfSlicesApart && ( fabs(m_ShiftRight) < 0.001 && fabs(m_ShiftUp) > 0.001); } diff --git a/Modules/GraphAlgorithms/itkShortestPathImageFilter.h b/Modules/GraphAlgorithms/itkShortestPathImageFilter.h index f392465b02..5d0aa957bc 100644 --- a/Modules/GraphAlgorithms/itkShortestPathImageFilter.h +++ b/Modules/GraphAlgorithms/itkShortestPathImageFilter.h @@ -1,231 +1,235 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef __itkShortestPathImageFilter_h #define __itkShortestPathImageFilter_h #include "itkImageToImageFilter.h" #include "itkShortestPathCostFunction.h" #include "itkShortestPathNode.h" #include <itkImageRegionIteratorWithIndex.h> #include <itkMacro.h> // ------- INFORMATION ---------- /// SET FUNCTIONS // void SetInput( ItkImage ) // Compulsory // void SetStartIndex (const IndexType & StartIndex); // Compulsory // void SetEndIndex(const IndexType & EndIndex); // Compulsory // void SetFullNeighborsMode(bool) // Optional (default=false), if false N4, if true N26 // void SetActivateTimeOut(bool) // Optional (default=false), for debug issues: after 30s algorithms terminates. You can // have a look at the VectorOrderImage to see how far it came // void SetMakeOutputImage(bool) // Optional (default=true), Generate an outputimage of the path. You can also get the // path directoy with GetVectorPath() // void SetCalcAllDistances(bool) // Optional (default=false), Calculate Distances over the whole image. CAREFUL, // algorithm time extends a lot. Necessary for GetDistanceImage // void SetStoreVectorOrder(bool) // Optional (default=false), Stores in which order the pixels were checked. Necessary // for GetVectorOrderImage // void AddEndIndex(const IndexType & EndIndex) //Optional. By calling this function you can add several endpoints! The // algorithm will look for several shortest Pathes. From Start to all Endpoints. // /// GET FUNCTIONS // std::vector< itk::Index<3> > GetVectorPath(); // returns the shortest path as vector // std::vector< std::vector< itk::Index<3> > GetMultipleVectorPathe(); // returns a vector of shortest Pathes (which are // vectors of points) // GetDistanceImage // Returns the distance image // GetVectorOrderIMage // Returns the Vector Order image // // EXAMPLE USE // pleae see qmitkmitralvalvesegmentation4dtee bundle namespace itk { template <class TInputImageType, class TOutputImageType> class ShortestPathImageFilter : public ImageToImageFilter<TInputImageType, TOutputImageType> { public: // Standard Typedefs typedef ShortestPathImageFilter Self; typedef ImageToImageFilter<TInputImageType, TOutputImageType> Superclass; typedef SmartPointer<Self> Pointer; typedef SmartPointer<const Self> ConstPointer; // Typdefs for metric typedef ShortestPathCostFunction<TInputImageType> CostFunctionType; typedef typename CostFunctionType::Pointer CostFunctionTypePointer; // More typdefs for convenience typedef TInputImageType InputImageType; typedef typename TInputImageType::Pointer InputImagePointer; typedef typename TInputImageType::PixelType InputImagePixelType; typedef typename TInputImageType::SizeType InputImageSizeType; typedef typename TInputImageType::IndexType IndexType; typedef typename itk::ImageRegionIteratorWithIndex<InputImageType> InputImageIteratorType; typedef TOutputImageType OutputImageType; typedef typename TOutputImageType::Pointer OutputImagePointer; typedef typename TOutputImageType::PixelType OutputImagePixelType; typedef typename TOutputImageType::IndexType OutputImageIndexType; typedef ImageRegionIteratorWithIndex<OutputImageType> OutputImageIteratorType; typedef itk::ShapedNeighborhoodIterator<TInputImageType> itkShapedNeighborhoodIteratorType; // New Macro for smartpointer instantiation itkFactorylessNewMacro(Self); itkCloneMacro(Self); - // Run-time type information - itkTypeMacro(ShortestPathImageFilter, ImageToImageFilter); + // Run-time type information + itkTypeMacro(ShortestPathImageFilter, ImageToImageFilter); - // Display - void PrintSelf(std::ostream &os, Indent indent) const override; + // Display + void PrintSelf(std::ostream &os, Indent indent) const override; // Compare function for A_STAR struct CompareNodeStar { bool operator()(ShortestPathNode *a, ShortestPathNode *b) { return (a->distAndEst > b->distAndEst); } }; // \brief Set Starpoint for ShortestPath Calculation void SetStartIndex(const IndexType &StartIndex); // \brief Adds Endpoint for multiple ShortestPath Calculation void AddEndIndex(const IndexType &index); // \brief Set Endpoint for ShortestPath Calculation void SetEndIndex(const IndexType &EndIndex); // \brief Set FullNeighborsMode. false = no diagonal neighbors, in 2D this means N4 Neigborhood. true = would be N8 // in 2D itkSetMacro(FullNeighborsMode, bool); itkGetMacro(FullNeighborsMode, bool); // \brief Set Graph_fullNeighbors. false = no diagonal neighbors, in 2D this means N4 Neigborhood. true = would be // N8 in 2D itkSetMacro(Graph_fullNeighbors, bool); - // \brief (default=true), Produce output image, which shows the shortest path. But you can also get the shortest - // Path directly as vector with the function GetVectorPath - itkSetMacro(MakeOutputImage, bool); + // \brief (default=true), Produce output image, which shows the shortest path. But you can also get the shortest + // Path directly as vector with the function GetVectorPath + itkSetMacro(MakeOutputImage, bool); itkGetMacro(MakeOutputImage, bool); // \brief (default=false), Store an Vector of Order, so you can call getVectorOrderImage after update itkSetMacro(StoreVectorOrder, bool); itkGetMacro(StoreVectorOrder, bool); // \brief (default=false), // Calculate all Distances to all pixels, so you can call getDistanceImage after update // (warning algo will take a long time) itkSetMacro(CalcAllDistances, bool); itkGetMacro(CalcAllDistances, bool); // \brief (default=false), for debug issues: after 30s algorithms terminates. You can have a look at the // VectorOrderImage to see how far it came itkSetMacro(ActivateTimeOut, bool); itkGetMacro(ActivateTimeOut, bool); // \brief returns shortest Path as vector std::vector<IndexType> GetVectorPath(); // \brief returns Multiple shortest Paths. You can call this function, when u performed a multiple shortest path // search (one start, several ends) std::vector<std::vector<IndexType>> GetMultipleVectorPaths(); // \brief returns the vector order image. It shows in which order the pixels were checked. good for debugging. Be // sure to have m_StoreVectorOrder=true OutputImagePointer GetVectorOrderImage(); // \brief returns the distance image. It shows the distances from the startpoint to all other pixels. Be sure to // have m_CalcAllDistances=true OutputImagePointer GetDistanceImage(); // \brief Fill m_VectorPath void MakeShortestPathVector(); // \brief cleans up the filter void CleanUp(); itkSetObjectMacro(CostFunction, CostFunctionType); // itkSetObjectMacro = set function that uses pointer as parameter itkGetObjectMacro(CostFunction, CostFunctionType); + void SetUseCostFunction(bool doUseCostFunction) { m_useCostFunction = doUseCostFunction; }; + bool GetUseCostFunction() { return m_useCostFunction; }; + protected: std::vector<IndexType> m_endPoints; // if you fill this vector, the algo will not rest until all endPoints have been reached std::vector<IndexType> m_endPointsClosed; ShortestPathNode *m_Nodes; // main list that contains all nodes NodeNumType m_Graph_NumberOfNodes; NodeNumType m_Graph_StartNode; NodeNumType m_Graph_EndNode; bool m_Graph_fullNeighbors; + bool m_useCostFunction; std::vector<ShortestPathNode *> m_Graph_DiscoveredNodeList; ShortestPathImageFilter(Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented const static int BACKGROUND = 0; const static int FOREGROUND = 255; bool m_FullNeighborsMode; bool m_MakeOutputImage; bool m_StoreVectorOrder; // Store an Vector of Order, so you can call getVectorOrderImage after update bool m_CalcAllDistances; // Calculate all Distances, so you can call getDistanceImage after update (warning algo // will take a long time) bool multipleEndPoints; bool m_ActivateTimeOut; // if true, then i search max. 30 secs. then abort bool m_Initialized; CostFunctionTypePointer m_CostFunction; IndexType m_StartIndex, m_EndIndex; std::vector<IndexType> m_VectorPath; std::vector<std::vector<IndexType>> m_MultipleVectorPaths; std::vector<NodeNumType> m_VectorOrder; ShortestPathImageFilter(); ~ShortestPathImageFilter() override; // \brief Create all the outputs void MakeOutputs(); // \brief Generate Data void GenerateData() override; // \brief gets the estimate costs from pixel a to target. double getEstimatedCostsToTarget(const IndexType &a); typename InputImageType::Pointer m_magnitudeImage; // \brief Convert a indexnumber of a node in m_Nodes to image coordinates typename TInputImageType::IndexType NodeToCoord(NodeNumType); // \brief Convert image coordinate to a indexnumber of a node in m_Nodes unsigned int CoordToNode(IndexType); // \brief Returns the neighbors of a node std::vector<ShortestPathNode *> GetNeighbors(NodeNumType nodeNum, bool FullNeighbors); // \brief Check if coords are in bounds of image bool CoordIsInBounds(IndexType); // \brief Initializes the graph void InitGraph(); // \brief Start ShortestPathSearch void StartShortestPathSearch(); }; } // end of namespace itk #include "itkShortestPathImageFilter.txx" #endif diff --git a/Modules/GraphAlgorithms/itkShortestPathImageFilter.txx b/Modules/GraphAlgorithms/itkShortestPathImageFilter.txx index 73fee98147..1e4a4c2756 100644 --- a/Modules/GraphAlgorithms/itkShortestPathImageFilter.txx +++ b/Modules/GraphAlgorithms/itkShortestPathImageFilter.txx @@ -1,890 +1,897 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef __itkShortestPathImageFilter_txx #define __itkShortestPathImageFilter_txx #include "itkShortestPathImageFilter.h" #include "mitkMemoryUtilities.h" #include <ctime> #include <algorithm> #include <iostream> #include <vector> namespace itk { // Constructor (initialize standard values) template <class TInputImageType, class TOutputImageType> ShortestPathImageFilter<TInputImageType, TOutputImageType>::ShortestPathImageFilter() : m_Nodes(nullptr), m_Graph_NumberOfNodes(0), m_Graph_fullNeighbors(false), + m_useCostFunction(true), m_FullNeighborsMode(false), m_MakeOutputImage(true), m_StoreVectorOrder(false), m_CalcAllDistances(false), multipleEndPoints(false), m_ActivateTimeOut(false), m_Initialized(false) { m_endPoints.clear(); m_endPointsClosed.clear(); if (m_MakeOutputImage) { this->SetNumberOfRequiredOutputs(1); this->SetNthOutput(0, OutputImageType::New()); } } template <class TInputImageType, class TOutputImageType> ShortestPathImageFilter<TInputImageType, TOutputImageType>::~ShortestPathImageFilter() { delete[] m_Nodes; } template <class TInputImageType, class TOutputImageType> inline typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::IndexType ShortestPathImageFilter<TInputImageType, TOutputImageType>::NodeToCoord(NodeNumType node) { const InputImageSizeType &size = this->GetInput()->GetRequestedRegion().GetSize(); int dim = InputImageType::ImageDimension; IndexType coord; if (dim == 2) { coord[1] = node / size[0]; coord[0] = node % size[0]; if (((unsigned long)coord[0] >= size[0]) || ((unsigned long)coord[1] >= size[1])) { coord[0] = 0; coord[1] = 0; } } if (dim == 3) { coord[2] = node / (size[0] * size[1]); coord[1] = (node % (size[0] * size[1])) / size[0]; coord[0] = (node % (size[0] * size[1])) % size[0]; if (((unsigned long)coord[0] >= size[0]) || ((unsigned long)coord[1] >= size[1]) || ((unsigned long)coord[2] >= size[2])) { coord[0] = 0; coord[1] = 0; coord[2] = 0; } } return coord; } template <class TInputImageType, class TOutputImageType> inline typename itk::NodeNumType ShortestPathImageFilter<TInputImageType, TOutputImageType>::CoordToNode( IndexType coord) { const InputImageSizeType &size = this->GetInput()->GetRequestedRegion().GetSize(); int dim = InputImageType::ImageDimension; NodeNumType node = 0; if (dim == 2) { node = (coord[1] * size[0]) + coord[0]; } if (dim == 3) { node = (coord[2] * size[0] * size[1]) + (coord[1] * size[0]) + coord[0]; } if ((m_Graph_NumberOfNodes > 0) && (node >= m_Graph_NumberOfNodes)) { /*MITK_INFO << "WARNING! Coordinates outside image!"; MITK_INFO << "Coords = " << coord ; MITK_INFO << "ImageDim = " << dim ; MITK_INFO << "RequestedRegionSize = " << size ;*/ node = 0; } return node; } template <class TInputImageType, class TOutputImageType> inline bool ShortestPathImageFilter<TInputImageType, TOutputImageType>::CoordIsInBounds(IndexType coord) { const InputImageSizeType &size = this->GetInput()->GetRequestedRegion().GetSize(); int dim = InputImageType::ImageDimension; if (dim == 2) { if ((coord[0] >= 0) && ((unsigned long)coord[0] < size[0]) && (coord[1] >= 0) && ((unsigned long)coord[1] < size[1])) { return true; } } if (dim == 3) { if ((coord[0] >= 0) && ((unsigned long)coord[0] < size[0]) && (coord[1] >= 0) && ((unsigned long)coord[1] < size[1]) && (coord[2] >= 0) && ((unsigned long)coord[2] < size[2])) { return true; } } return false; } template <class TInputImageType, class TOutputImageType> inline std::vector<ShortestPathNode *> ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetNeighbors( unsigned int nodeNum, bool FullNeighbors) { // returns a vector of nodepointers.. these nodes are the neighbors int dim = InputImageType::ImageDimension; IndexType Coord = NodeToCoord(nodeNum); IndexType NeighborCoord; std::vector<ShortestPathNode *> nodeList; int neighborDistance = 1; // if i increase that, i might not hit the endnote // maybe use itkNeighborhoodIterator here, might be faster if (dim == 2) { // N4 NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); if (FullNeighbors) { // N8 NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); } } if (dim == 3) { // N6 NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1]; NeighborCoord[2] = Coord[2]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1]; NeighborCoord[2] = Coord[2]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1]; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1]; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); if (FullNeighbors) { // N26 // Middle Slice NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2]; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); // BackSlice (Diagonal) NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); // BackSlice (Non-Diag) NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1]; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1]; NeighborCoord[2] = Coord[2] - neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); // FrontSlice (Diagonal) NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); // FrontSlice(Non-Diag) NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1] - neighborDistance; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] + neighborDistance; NeighborCoord[1] = Coord[1]; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0]; NeighborCoord[1] = Coord[1] + neighborDistance; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); NeighborCoord[0] = Coord[0] - neighborDistance; NeighborCoord[1] = Coord[1]; NeighborCoord[2] = Coord[2] + neighborDistance; if (CoordIsInBounds(NeighborCoord)) nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]); } } return nodeList; } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::SetStartIndex( const typename TInputImageType::IndexType &StartIndex) { for (unsigned int i = 0; i < TInputImageType::ImageDimension; ++i) { m_StartIndex[i] = StartIndex[i]; } m_Graph_StartNode = CoordToNode(m_StartIndex); // MITK_INFO << "StartIndex = " << StartIndex; // MITK_INFO << "StartNode = " << m_Graph_StartNode; m_Initialized = false; } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::SetEndIndex( const typename TInputImageType::IndexType &EndIndex) { for (unsigned int i = 0; i < TInputImageType::ImageDimension; ++i) { m_EndIndex[i] = EndIndex[i]; } m_Graph_EndNode = CoordToNode(m_EndIndex); // MITK_INFO << "EndNode = " << m_Graph_EndNode; } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::AddEndIndex( const typename TInputImageType::IndexType &index) { // ONLY FOR MULTIPLE END POINTS SEARCH IndexType newEndIndex; for (unsigned int i = 0; i < TInputImageType::ImageDimension; ++i) { newEndIndex[i] = index[i]; } m_endPoints.push_back(newEndIndex); SetEndIndex(m_endPoints[0]); multipleEndPoints = true; } template <class TInputImageType, class TOutputImageType> inline double ShortestPathImageFilter<TInputImageType, TOutputImageType>::getEstimatedCostsToTarget( const typename TInputImageType::IndexType &a) { // Returns the minimal possible costs for a path from "a" to targetnode. itk::Vector<float, 3> v; v[0] = m_EndIndex[0] - a[0]; v[1] = m_EndIndex[1] - a[1]; v[2] = m_EndIndex[2] - a[2]; return m_CostFunction->GetMinCost() * v.GetNorm(); } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::InitGraph() { if (!m_Initialized) { // Clean up previous stuff CleanUp(); // Calc Number of nodes auto imageDimensions = TInputImageType::ImageDimension; const InputImageSizeType &size = this->GetInput()->GetRequestedRegion().GetSize(); m_Graph_NumberOfNodes = 1; for (NodeNumType i = 0; i < imageDimensions; ++i) m_Graph_NumberOfNodes = m_Graph_NumberOfNodes * size[i]; // Initialize mainNodeList with that number m_Nodes = new ShortestPathNode[m_Graph_NumberOfNodes]; // Initialize each node in nodelist for (NodeNumType i = 0; i < m_Graph_NumberOfNodes; i++) { m_Nodes[i].distAndEst = -1; m_Nodes[i].distance = -1; m_Nodes[i].prevNode = -1; m_Nodes[i].mainListIndex = i; m_Nodes[i].closed = false; } m_Initialized = true; } // In the beginning, the Startnode needs a distance of 0 m_Nodes[m_Graph_StartNode].distance = 0; m_Nodes[m_Graph_StartNode].distAndEst = 0; // initalize cost function m_CostFunction->Initialize(); } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::StartShortestPathSearch() { // Setup Timer clock_t startAll = clock(); clock_t stopAll = clock(); // init variables double durationAll = 0; bool timeout = false; NodeNumType mainNodeListIndex = 0; DistanceType curNodeDistance = 0; NodeNumType numberOfNodesChecked = 0; // Create Multimap (tree structure for fast searching) std::multimap<double, ShortestPathNode *> myMap; std::pair<std::multimap<double, ShortestPathNode *>::iterator, std::multimap<double, ShortestPathNode *>::iterator> ret; std::multimap<double, ShortestPathNode *>::iterator it; // At first, only startNote is discovered. myMap.insert( std::pair<double, ShortestPathNode *>(m_Nodes[m_Graph_StartNode].distAndEst, &m_Nodes[m_Graph_StartNode])); // While there are discovered Nodes, pick the one with lowest distance, // update its neighbors and eventually delete it from the discovered Nodes list. while (!myMap.empty()) { numberOfNodesChecked++; /*if ( (numberOfNodesChecked % (m_Graph_NumberOfNodes/100)) == 0) { MITK_INFO << "Checked " << ( numberOfNodesChecked / (m_Graph_NumberOfNodes/100) ) << "% List: " << myMap.size() << "\n"; }*/ // Get element with lowest score mainNodeListIndex = myMap.begin()->second->mainListIndex; curNodeDistance = myMap.begin()->second->distance; myMap.begin()->second->closed = true; // close it // Debug: // MITK_INFO << "INFO: size " << myMap.size(); /* for (it = myMap.begin(); it != myMap.end(); ++it) { MITK_INFO << "(1) " << it->first << "|" << it->second->distAndEst << "|"<<it->second->mainListIndex; } */ // Kicks out element with lowest score myMap.erase(myMap.begin()); // if wanted, store vector order if (m_StoreVectorOrder) { m_VectorOrder.push_back(mainNodeListIndex); } // Check neighbors std::vector<ShortestPathNode *> neighborNodes = GetNeighbors(mainNodeListIndex, m_Graph_fullNeighbors); for (NodeNumType i = 0; i < neighborNodes.size(); i++) { if (neighborNodes[i]->closed) continue; // this nodes is already closed, go to next neighbor IndexType coordCurNode = NodeToCoord(mainNodeListIndex); IndexType coordNeighborNode = NodeToCoord(neighborNodes[i]->mainListIndex); // calculate the new Distance to the current neighbor double newDistance = curNodeDistance + (m_CostFunction->GetCost(coordCurNode, coordNeighborNode)); // if it is shorter than any yet known path to this neighbor, than the current path is better. Save that! if ((newDistance < neighborNodes[i]->distance) || (neighborNodes[i]->distance == -1)) { // if that neighbornode is not in discoverednodeList yet, Push it there and update if (neighborNodes[i]->distance == -1) { neighborNodes[i]->distance = newDistance; neighborNodes[i]->distAndEst = newDistance + getEstimatedCostsToTarget(coordNeighborNode); neighborNodes[i]->prevNode = mainNodeListIndex; myMap.insert(std::pair<double, ShortestPathNode *>(m_Nodes[neighborNodes[i]->mainListIndex].distAndEst, &m_Nodes[neighborNodes[i]->mainListIndex])); /* MITK_INFO << "Inserted: " << m_Nodes[neighborNodes[i]->mainListIndex].distAndEst << "|" << m_Nodes[neighborNodes[i]->mainListIndex].mainListIndex; MITK_INFO << "INFO: size " << myMap.size(); for (it = myMap.begin(); it != myMap.end(); ++it) { MITK_INFO << "(1) " << it->first << "|" << it->second->distAndEst << "|"<<it->second->mainListIndex; } */ } // or if is already in discoverednodelist, update else { /* it = myMap.find(neighborNodes[i]->distAndEst); if (it == myMap.end() ) { MITK_INFO << "Nothing!"; // look further for (it = myMap.begin(); it != myMap.end(); ++it) { if ((*it).second->mainListIndex == lookForId) { MITK_INFO << "But it is there!!!"; MITK_INFO << "Searched for: " << lookFor << " but had: " << (*it).second->distAndEst; } } } */ // 1st : find and delete old element bool found = false; ret = myMap.equal_range(neighborNodes[i]->distAndEst); if ((ret.first == ret.second)) { /*+++++++++++++ no exact match +++++++++++++*/ // MITK_INFO << "No exact match!"; // if this happens, you are screwed /* MITK_INFO << "Was looking for: " << lookFor << " ID: " << lookForId; if (ret.first != myMap.end() ) { it = ret.first; MITK_INFO << "Found: " << it->first << " ID: " << it->second->mainListIndex; ++it; MITK_INFO << "Found: " << it->first << " ID: " << it->second->mainListIndex; --it; --it; MITK_INFO << "Found: " << it->first << " ID: " << it->second->mainListIndex; } // look if that ID is found in the map for (it = myMap.begin(); it != myMap.end(); ++it) { if ((*it).second->mainListIndex == lookForId) { MITK_INFO << "But it is there!!!"; MITK_INFO << "Searched dist: " << lookFor << " found dist: " << (*it).second->distAndEst; } } */ } else { for (it = ret.first; it != ret.second; ++it) { if (it->second->mainListIndex == neighborNodes[i]->mainListIndex) { found = true; myMap.erase(it); /* MITK_INFO << "INFO: size " << myMap.size(); MITK_INFO << "Erase: " << it->first << "|" << it->second->mainListIndex; MITK_INFO << "INFO: size " << myMap.size(); for (it = myMap.begin(); it != myMap.end(); ++it) { MITK_INFO << "(1) " << it->first << "|" << it->second->distAndEst << "|"<<it->second->mainListIndex; } */ break; } } } if (!found) { // MITK_INFO << "Could not find it! :("; continue; } // 2nd: update and insert new element neighborNodes[i]->distance = newDistance; neighborNodes[i]->distAndEst = newDistance + getEstimatedCostsToTarget(coordNeighborNode); neighborNodes[i]->prevNode = mainNodeListIndex; // myMap.insert( std::pair<double,ShortestPathNode*> (neighborNodes[i]->distAndEst, neighborNodes[i])); myMap.insert(std::pair<double, ShortestPathNode *>(m_Nodes[neighborNodes[i]->mainListIndex].distAndEst, &m_Nodes[neighborNodes[i]->mainListIndex])); // MITK_INFO << "Re-Inserted: " << m_Nodes[neighborNodes[i]->mainListIndex].distAndEst << "|" << // m_Nodes[neighborNodes[i]->mainListIndex].mainListIndex; // MITK_INFO << "INFO: size " << myMap.size(); /*for (it = myMap.begin(); it != myMap.end(); ++it) { MITK_INFO << "(1) " << it->first << "|" << it->second->distAndEst << "|"<<it->second->mainListIndex; }*/ } } } // finished with checking all neighbors. // Check Timeout, if activated if (m_ActivateTimeOut) { stopAll = clock(); durationAll = (double)(stopAll - startAll) / CLOCKS_PER_SEC; if (durationAll >= 30) { // MITK_INFO << "TIMEOUT!! Search took over 30 seconds"; timeout = true; } } // Check end criteria: // For multiple points if (multipleEndPoints) { // super slow, make it faster for (unsigned int i = 0; i < m_endPoints.size(); i++) { if (CoordToNode(m_endPoints[i]) == mainNodeListIndex) { m_endPointsClosed.push_back(NodeToCoord(mainNodeListIndex)); m_endPoints.erase(m_endPoints.begin() + i); if (m_endPoints.empty()) { // Finished! break return; } if (m_Graph_EndNode == mainNodeListIndex) { // set new end SetEndIndex(m_endPoints[0]); } } } } // if single end point, then end, if this one is reached or timeout happened. else if ((mainNodeListIndex == m_Graph_EndNode || timeout) && !m_CalcAllDistances) { /*if (m_StoreVectorOrder) MITK_INFO << "Number of Nodes checked: " << m_VectorOrder.size() ;*/ return; } } } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::MakeOutputs() { // MITK_INFO << "Make Output"; if (m_MakeOutputImage) { OutputImagePointer output0 = this->GetOutput(0); output0->SetRegions(this->GetInput()->GetLargestPossibleRegion()); output0->Allocate(); OutputImageIteratorType shortestPathImageIt(output0, output0->GetRequestedRegion()); // Create ShortestPathImage (Output 0) for (shortestPathImageIt.GoToBegin(); !shortestPathImageIt.IsAtEnd(); ++shortestPathImageIt) { // First intialize with background color shortestPathImageIt.Set(BACKGROUND); } if (!multipleEndPoints) // Only one path was calculated { for (unsigned int i = 0; i < m_VectorPath.size(); i++) { shortestPathImageIt.SetIndex(m_VectorPath[i]); shortestPathImageIt.Set(FOREGROUND); } } else // multiple pathes has been calculated, draw all { for (unsigned int i = 0; i < m_MultipleVectorPaths.size(); i++) { for (unsigned int j = 0; j < m_MultipleVectorPaths[i].size(); j++) { shortestPathImageIt.SetIndex(m_MultipleVectorPaths[i][j]); shortestPathImageIt.Set(FOREGROUND); } } } } } template <class TInputImageType, class TOutputImageType> typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::OutputImagePointer ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetVectorOrderImage() { // Create Vector Order Image // Return it OutputImagePointer image = OutputImageType::New(); image->SetRegions(this->GetInput()->GetLargestPossibleRegion()); image->Allocate(); OutputImageIteratorType vectorOrderImageIt(image, image->GetRequestedRegion()); // MITK_INFO << "GetVectorOrderImage"; for (vectorOrderImageIt.GoToBegin(); !vectorOrderImageIt.IsAtEnd(); ++vectorOrderImageIt) { // First intialize with background color vectorOrderImageIt.Value() = BACKGROUND; } for (int i = 0; i < m_VectorOrder.size(); i++) { vectorOrderImageIt.SetIndex(NodeToCoord(m_VectorOrder[i])); vectorOrderImageIt.Set(BACKGROUND + i); } return image; } template <class TInputImageType, class TOutputImageType> typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::OutputImagePointer ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetDistanceImage() { // Create Distance Image // Return it OutputImagePointer image = OutputImageType::New(); image->SetRegions(this->GetInput()->GetLargestPossibleRegion()); image->Allocate(); ; OutputImageIteratorType distanceImageIt(image, image->GetRequestedRegion()); // Create Distance Image (Output 1) NodeNumType myNodeNum; for (distanceImageIt.GoToBegin(); !distanceImageIt.IsAtEnd(); ++distanceImageIt) { IndexType index = distanceImageIt.GetIndex(); myNodeNum = CoordToNode(index); double newVal = m_Nodes[myNodeNum].distance; distanceImageIt.Set(newVal); } } template <class TInputImageType, class TOutputImageType> std::vector<typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::IndexType> ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetVectorPath() { return m_VectorPath; } template <class TInputImageType, class TOutputImageType> std::vector<std::vector<typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::IndexType>> ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetMultipleVectorPaths() { return m_MultipleVectorPaths; } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::MakeShortestPathVector() { // MITK_INFO << "Make ShortestPath Vec"; + if (m_useCostFunction == false) + { + m_VectorPath.push_back(NodeToCoord(m_Graph_StartNode)); + m_VectorPath.push_back(NodeToCoord(m_Graph_EndNode)); + return; + } // single end point if (!multipleEndPoints) { // fill m_VectorPath with the Shortest Path m_VectorPath.clear(); // Go backwards from endnote to startnode NodeNumType prevNode = m_Graph_EndNode; while (prevNode != m_Graph_StartNode) { m_VectorPath.push_back(NodeToCoord(prevNode)); prevNode = m_Nodes[prevNode].prevNode; } m_VectorPath.push_back(NodeToCoord(prevNode)); // reverse it std::reverse(m_VectorPath.begin(), m_VectorPath.end()); } // Multiple end end points and pathes else { for (unsigned int i = 0; i < m_endPointsClosed.size(); i++) { m_VectorPath.clear(); // Go backwards from endnote to startnode NodeNumType prevNode = CoordToNode(m_endPointsClosed[i]); while (prevNode != m_Graph_StartNode) { m_VectorPath.push_back(NodeToCoord(prevNode)); prevNode = m_Nodes[prevNode].prevNode; } m_VectorPath.push_back(NodeToCoord(prevNode)); // reverse it std::reverse(m_VectorPath.begin(), m_VectorPath.end()); // push_back m_MultipleVectorPaths.push_back(m_VectorPath); } } } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::CleanUp() { m_VectorOrder.clear(); m_VectorPath.clear(); // TODO: if multiple Path, clear all multiple Paths if (m_Nodes) delete[] m_Nodes; } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::GenerateData() { // Build Graph InitGraph(); // Calc Shortest Parth StartShortestPathSearch(); // Fill Shortest Path MakeShortestPathVector(); // Make Outputs MakeOutputs(); } template <class TInputImageType, class TOutputImageType> void ShortestPathImageFilter<TInputImageType, TOutputImageType>::PrintSelf(std::ostream &os, Indent indent) const { Superclass::PrintSelf(os, indent); } } /* end namespace itk */ #endif // __itkShortestPathImageFilter_txx diff --git a/Modules/ImageStatistics/mitkImageStatisticsCalculator.cpp b/Modules/ImageStatistics/mitkImageStatisticsCalculator.cpp index e7f7f64ccb..bfa5041c2f 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsCalculator.cpp +++ b/Modules/ImageStatistics/mitkImageStatisticsCalculator.cpp @@ -1,552 +1,552 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkImageStatisticsCalculator.h" #include <mitkExtendedLabelStatisticsImageFilter.h> #include <mitkExtendedStatisticsImageFilter.h> #include <mitkImage.h> #include <mitkImageAccessByItk.h> #include <mitkImageCast.h> #include <mitkImageStatisticsConstants.h> #include <mitkImageTimeSelector.h> #include <mitkImageToItk.h> #include <mitkMaskUtilities.h> #include <mitkMinMaxImageFilterWithIndex.h> #include <mitkMinMaxLabelmageFilterWithIndex.h> #include <mitkitkMaskImageFilter.h> namespace mitk { void ImageStatisticsCalculator::SetInputImage(const mitk::Image *image) { if (image != m_Image) { m_Image = image; this->Modified(); } } void ImageStatisticsCalculator::SetMask(mitk::MaskGenerator *mask) { if (mask != m_MaskGenerator) { m_MaskGenerator = mask; this->Modified(); } } void ImageStatisticsCalculator::SetSecondaryMask(mitk::MaskGenerator *mask) { if (mask != m_SecondaryMaskGenerator) { m_SecondaryMaskGenerator = mask; this->Modified(); } } void ImageStatisticsCalculator::SetNBinsForHistogramStatistics(unsigned int nBins) { if (nBins != m_nBinsForHistogramStatistics) { m_nBinsForHistogramStatistics = nBins; this->Modified(); this->m_UseBinSizeOverNBins = false; } if (m_UseBinSizeOverNBins) { this->Modified(); this->m_UseBinSizeOverNBins = false; } } unsigned int ImageStatisticsCalculator::GetNBinsForHistogramStatistics() const { return m_nBinsForHistogramStatistics; } void ImageStatisticsCalculator::SetBinSizeForHistogramStatistics(double binSize) { if (binSize != m_binSizeForHistogramStatistics) { m_binSizeForHistogramStatistics = binSize; this->Modified(); this->m_UseBinSizeOverNBins = true; } if (!m_UseBinSizeOverNBins) { this->Modified(); this->m_UseBinSizeOverNBins = true; } } double ImageStatisticsCalculator::GetBinSizeForHistogramStatistics() const { return m_binSizeForHistogramStatistics; } mitk::ImageStatisticsContainer* ImageStatisticsCalculator::GetStatistics(LabelIndex label) { if (m_Image.IsNull()) { mitkThrow() << "no image"; } if (!m_Image->IsInitialized()) { mitkThrow() << "Image not initialized!"; } if (IsUpdateRequired(label)) { auto timeGeometry = m_Image->GetTimeGeometry(); // always compute statistics on all timesteps for (unsigned int timeStep = 0; timeStep < m_Image->GetTimeSteps(); timeStep++) { if (m_MaskGenerator.IsNotNull()) { m_MaskGenerator->SetTimeStep(timeStep); //See T25625: otherwise, the mask is not computed again after setting a different time step m_MaskGenerator->Modified(); m_InternalMask = m_MaskGenerator->GetMask(); if (m_MaskGenerator->GetReferenceImage().IsNotNull()) { m_InternalImageForStatistics = m_MaskGenerator->GetReferenceImage(); } else { m_InternalImageForStatistics = m_Image; } } else { m_InternalImageForStatistics = m_Image; } if (m_SecondaryMaskGenerator.IsNotNull()) { m_SecondaryMaskGenerator->SetTimeStep(timeStep); m_SecondaryMask = m_SecondaryMaskGenerator->GetMask(); } ImageTimeSelector::Pointer imgTimeSel = ImageTimeSelector::New(); imgTimeSel->SetInput(m_InternalImageForStatistics); imgTimeSel->SetTimeNr(timeStep); imgTimeSel->UpdateLargestPossibleRegion(); imgTimeSel->Update(); m_ImageTimeSlice = imgTimeSel->GetOutput(); // Calculate statistics with/without mask if (m_MaskGenerator.IsNull() && m_SecondaryMaskGenerator.IsNull()) { // 1) calculate statistics unmasked: AccessByItk_2(m_ImageTimeSlice, InternalCalculateStatisticsUnmasked, timeGeometry, timeStep) } else { // 2) calculate statistics masked AccessByItk_2(m_ImageTimeSlice, InternalCalculateStatisticsMasked, timeGeometry, timeStep) } } } auto it = m_StatisticContainers.find(label); if (it != m_StatisticContainers.end()) { return (it->second).GetPointer(); } else { mitkThrow() << "unknown label"; return nullptr; } } template <typename TPixel, unsigned int VImageDimension> void ImageStatisticsCalculator::InternalCalculateStatisticsUnmasked( typename itk::Image<TPixel, VImageDimension> *image, const TimeGeometry *timeGeometry, TimeStepType timeStep) { typedef typename itk::Image<TPixel, VImageDimension> ImageType; typedef typename itk::ExtendedStatisticsImageFilter<ImageType> ImageStatisticsFilterType; typedef typename itk::MinMaxImageFilterWithIndex<ImageType> MinMaxFilterType; // reset statistics container if exists ImageStatisticsContainer::Pointer statisticContainerForImage; LabelIndex labelNoMask = 1; auto it = m_StatisticContainers.find(labelNoMask); if (it != m_StatisticContainers.end()) { statisticContainerForImage = it->second; } else { statisticContainerForImage = ImageStatisticsContainer::New(); statisticContainerForImage->SetTimeGeometry(const_cast<mitk::TimeGeometry*>(timeGeometry)); m_StatisticContainers.emplace(labelNoMask, statisticContainerForImage); } auto statObj = ImageStatisticsContainer::ImageStatisticsObject(); typename ImageStatisticsFilterType::Pointer statisticsFilter = ImageStatisticsFilterType::New(); statisticsFilter->SetInput(image); statisticsFilter->SetCoordinateTolerance(0.001); statisticsFilter->SetDirectionTolerance(0.001); // TODO: this is single threaded. Implement our own image filter that does this multi threaded // typename itk::MinimumMaximumImageCalculator<ImageType>::Pointer imgMinMaxFilter = // itk::MinimumMaximumImageCalculator<ImageType>::New(); imgMinMaxFilter->SetImage(image); // imgMinMaxFilter->Compute(); vnl_vector<int> minIndex, maxIndex; typename MinMaxFilterType::Pointer minMaxFilter = MinMaxFilterType::New(); minMaxFilter->SetInput(image); minMaxFilter->UpdateLargestPossibleRegion(); typename ImageType::PixelType minval = minMaxFilter->GetMin(); typename ImageType::PixelType maxval = minMaxFilter->GetMax(); typename ImageType::IndexType tmpMinIndex = minMaxFilter->GetMinIndex(); typename ImageType::IndexType tmpMaxIndex = minMaxFilter->GetMaxIndex(); // typename ImageType::IndexType tmpMinIndex = imgMinMaxFilter->GetIndexOfMinimum(); // typename ImageType::IndexType tmpMaxIndex = imgMinMaxFilter->GetIndexOfMaximum(); minIndex.set_size(tmpMaxIndex.GetIndexDimension()); maxIndex.set_size(tmpMaxIndex.GetIndexDimension()); for (unsigned int i = 0; i < tmpMaxIndex.GetIndexDimension(); i++) { minIndex[i] = tmpMinIndex[i]; maxIndex[i] = tmpMaxIndex[i]; } statObj.AddStatistic(mitk::ImageStatisticsConstants::MINIMUMPOSITION(), minIndex); statObj.AddStatistic(mitk::ImageStatisticsConstants::MAXIMUMPOSITION(), maxIndex); // convert m_binSize in m_nBins if necessary unsigned int nBinsForHistogram; if (m_UseBinSizeOverNBins) { nBinsForHistogram = std::max(static_cast<double>(std::ceil(maxval - minval)) / m_binSizeForHistogramStatistics, 10.); // do not allow less than 10 bins } else { nBinsForHistogram = m_nBinsForHistogramStatistics; } statisticsFilter->SetHistogramParameters(nBinsForHistogram, minval, maxval); try { statisticsFilter->Update(); } catch (const itk::ExceptionObject &e) { mitkThrow() << "Image statistics calculation failed due to following ITK Exception: \n " << e.what(); } auto voxelVolume = GetVoxelVolume<TPixel, VImageDimension>(image); auto numberOfPixels = image->GetLargestPossibleRegion().GetNumberOfPixels(); auto volume = static_cast<double>(numberOfPixels) * voxelVolume; auto variance = statisticsFilter->GetSigma() * statisticsFilter->GetSigma(); auto rms = std::sqrt(std::pow(statisticsFilter->GetMean(), 2.) + statisticsFilter->GetVariance()); // variance = sigma^2 statObj.AddStatistic(mitk::ImageStatisticsConstants::NUMBEROFVOXELS(), static_cast<ImageStatisticsContainer::VoxelCountType>(numberOfPixels)); statObj.AddStatistic(mitk::ImageStatisticsConstants::VOLUME(), volume); statObj.AddStatistic(mitk::ImageStatisticsConstants::MEAN(), statisticsFilter->GetMean()); statObj.AddStatistic(mitk::ImageStatisticsConstants::MINIMUM(), static_cast<ImageStatisticsContainer::RealType>(statisticsFilter->GetMinimum())); statObj.AddStatistic(mitk::ImageStatisticsConstants::MAXIMUM(), static_cast<ImageStatisticsContainer::RealType>(statisticsFilter->GetMaximum())); statObj.AddStatistic(mitk::ImageStatisticsConstants::STANDARDDEVIATION(), statisticsFilter->GetSigma()); statObj.AddStatistic(mitk::ImageStatisticsConstants::VARIANCE(), variance); statObj.AddStatistic(mitk::ImageStatisticsConstants::SKEWNESS(), statisticsFilter->GetSkewness()); statObj.AddStatistic(mitk::ImageStatisticsConstants::KURTOSIS(), statisticsFilter->GetKurtosis()); statObj.AddStatistic(mitk::ImageStatisticsConstants::RMS(), rms); statObj.AddStatistic(mitk::ImageStatisticsConstants::MPP(), statisticsFilter->GetMPP()); statObj.AddStatistic(mitk::ImageStatisticsConstants::ENTROPY(), statisticsFilter->GetEntropy()); statObj.AddStatistic(mitk::ImageStatisticsConstants::MEDIAN(), statisticsFilter->GetMedian()); statObj.AddStatistic(mitk::ImageStatisticsConstants::UNIFORMITY(), statisticsFilter->GetUniformity()); statObj.AddStatistic(mitk::ImageStatisticsConstants::UPP(), statisticsFilter->GetUPP()); statObj.m_Histogram = statisticsFilter->GetHistogram().GetPointer(); statisticContainerForImage->SetStatisticsForTimeStep(timeStep, statObj); } template <typename TPixel, unsigned int VImageDimension> double ImageStatisticsCalculator::GetVoxelVolume(typename itk::Image<TPixel, VImageDimension> *image) const { auto spacing = image->GetSpacing(); double voxelVolume = 1.; for (unsigned int i = 0; i < image->GetImageDimension(); i++) { voxelVolume *= spacing[i]; } return voxelVolume; } template <typename TPixel, unsigned int VImageDimension> void ImageStatisticsCalculator::InternalCalculateStatisticsMasked(typename itk::Image<TPixel, VImageDimension> *image, const TimeGeometry *timeGeometry, unsigned int timeStep) { typedef itk::Image<TPixel, VImageDimension> ImageType; typedef itk::Image<MaskPixelType, VImageDimension> MaskType; typedef typename MaskType::PixelType LabelPixelType; typedef itk::ExtendedLabelStatisticsImageFilter<ImageType, MaskType> ImageStatisticsFilterType; typedef MaskUtilities<TPixel, VImageDimension> MaskUtilType; typedef typename itk::MinMaxLabelImageFilterWithIndex<ImageType, MaskType> MinMaxLabelFilterType; typedef typename ImageType::PixelType InputImgPixelType; // workaround: if m_SecondaryMaskGenerator ist not null but m_MaskGenerator is! (this is the case if we request a // 'ignore zuero valued pixels' mask in the gui but do not define a primary mask) bool swapMasks = false; if (m_SecondaryMask.IsNotNull() && m_InternalMask.IsNull()) { m_InternalMask = m_SecondaryMask; m_SecondaryMask = nullptr; swapMasks = true; } // maskImage has to have the same dimension as image typename MaskType::Pointer maskImage = MaskType::New(); try { // try to access the pixel values directly (no copying or casting). Only works if mask pixels are of pixelType // unsigned short maskImage = ImageToItkImage<MaskPixelType, VImageDimension>(m_InternalMask); } catch (const itk::ExceptionObject &) { // if the pixel type of the mask is not short, then we have to make a copy of m_InternalMask (and cast the values) CastToItkImage(m_InternalMask, maskImage); } // if we have a secondary mask (say a ignoreZeroPixelMask) we need to combine the masks (corresponds to AND) if (m_SecondaryMask.IsNotNull()) { // dirty workaround for a bug when pf mask + any other mask is used in conjunction. We need a proper fix for this // (Fabian Isensee is responsible and probably working on it!) if (m_InternalMask->GetDimension() == 2 && (m_SecondaryMask->GetDimension() == 3 || m_SecondaryMask->GetDimension() == 4)) { mitk::Image::ConstPointer old_img = m_SecondaryMaskGenerator->GetReferenceImage(); m_SecondaryMaskGenerator->SetInputImage(m_MaskGenerator->GetReferenceImage()); m_SecondaryMask = m_SecondaryMaskGenerator->GetMask(); m_SecondaryMaskGenerator->SetInputImage(old_img); } typename MaskType::Pointer secondaryMaskImage = MaskType::New(); secondaryMaskImage = ImageToItkImage<MaskPixelType, VImageDimension>(m_SecondaryMask); // secondary mask should be a ignore zero value pixel mask derived from image. it has to be cropped to the mask // region (which may be planar or simply smaller) typename MaskUtilities<MaskPixelType, VImageDimension>::Pointer secondaryMaskMaskUtil = MaskUtilities<MaskPixelType, VImageDimension>::New(); secondaryMaskMaskUtil->SetImage(secondaryMaskImage.GetPointer()); secondaryMaskMaskUtil->SetMask(maskImage.GetPointer()); typename MaskType::Pointer adaptedSecondaryMaskImage = secondaryMaskMaskUtil->ExtractMaskImageRegion(); typename itk::MaskImageFilter2<MaskType, MaskType, MaskType>::Pointer maskFilter = itk::MaskImageFilter2<MaskType, MaskType, MaskType>::New(); maskFilter->SetInput1(maskImage); maskFilter->SetInput2(adaptedSecondaryMaskImage); maskFilter->SetMaskingValue( 1); // all pixels of maskImage where secondaryMaskImage==1 will be kept, all the others are set to 0 maskFilter->UpdateLargestPossibleRegion(); maskImage = maskFilter->GetOutput(); } typename MaskUtilType::Pointer maskUtil = MaskUtilType::New(); maskUtil->SetImage(image); maskUtil->SetMask(maskImage.GetPointer()); // if mask is smaller than image, extract the image region where the mask is typename ImageType::Pointer adaptedImage = ImageType::New(); adaptedImage = maskUtil->ExtractMaskImageRegion(); // this also checks mask sanity // find min, max, minindex and maxindex typename MinMaxLabelFilterType::Pointer minMaxFilter = MinMaxLabelFilterType::New(); minMaxFilter->SetInput(adaptedImage); minMaxFilter->SetLabelInput(maskImage); minMaxFilter->UpdateLargestPossibleRegion(); // set histogram parameters for each label individually (min/max may be different for each label) typedef typename std::map<LabelPixelType, InputImgPixelType> MapType; typedef typename std::pair<LabelPixelType, InputImgPixelType> PairType; std::vector<LabelPixelType> relevantLabels = minMaxFilter->GetRelevantLabels(); MapType minVals; MapType maxVals; std::map<LabelPixelType, unsigned int> nBins; for (LabelPixelType label : relevantLabels) { minVals.insert(PairType(label, minMaxFilter->GetMin(label))); maxVals.insert(PairType(label, minMaxFilter->GetMax(label))); unsigned int nBinsForHistogram; if (m_UseBinSizeOverNBins) { nBinsForHistogram = std::max(static_cast<double>(std::ceil(minMaxFilter->GetMax(label) - minMaxFilter->GetMin(label))) / m_binSizeForHistogramStatistics, 10.); // do not allow less than 10 bins } else { nBinsForHistogram = m_nBinsForHistogramStatistics; } nBins.insert(typename std::pair<LabelPixelType, unsigned int>(label, nBinsForHistogram)); } typename ImageStatisticsFilterType::Pointer imageStatisticsFilter = ImageStatisticsFilterType::New(); imageStatisticsFilter->SetDirectionTolerance(0.001); imageStatisticsFilter->SetCoordinateTolerance(0.001); imageStatisticsFilter->SetInput(adaptedImage); imageStatisticsFilter->SetLabelInput(maskImage); imageStatisticsFilter->SetHistogramParametersForLabels(nBins, minVals, maxVals); imageStatisticsFilter->Update(); std::list<int> labels = imageStatisticsFilter->GetRelevantLabels(); auto it = labels.begin(); while (it != labels.end()) { ImageStatisticsContainer::Pointer statisticContainerForLabelImage; auto labelIt = m_StatisticContainers.find(*it); // reset if statisticContainer already exist if (labelIt != m_StatisticContainers.end()) { statisticContainerForLabelImage = labelIt->second; } // create new statisticContainer else { statisticContainerForLabelImage = ImageStatisticsContainer::New(); statisticContainerForLabelImage->SetTimeGeometry(const_cast<mitk::TimeGeometry*>(timeGeometry)); // link label (*it) to statisticContainer m_StatisticContainers.emplace(*it, statisticContainerForLabelImage); } ImageStatisticsContainer::ImageStatisticsObject statObj; // find min, max, minindex and maxindex // make sure to only look in the masked region, use a masker for this vnl_vector<int> minIndex, maxIndex; mitk::Point3D worldCoordinateMin; mitk::Point3D worldCoordinateMax; mitk::Point3D indexCoordinateMin; mitk::Point3D indexCoordinateMax; m_InternalImageForStatistics->GetGeometry()->IndexToWorld(minMaxFilter->GetMinIndex(*it), worldCoordinateMin); m_InternalImageForStatistics->GetGeometry()->IndexToWorld(minMaxFilter->GetMaxIndex(*it), worldCoordinateMax); m_Image->GetGeometry()->WorldToIndex(worldCoordinateMin, indexCoordinateMin); m_Image->GetGeometry()->WorldToIndex(worldCoordinateMax, indexCoordinateMax); minIndex.set_size(3); maxIndex.set_size(3); // for (unsigned int i=0; i < tmpMaxIndex.GetIndexDimension(); i++) for (unsigned int i = 0; i < 3; i++) { minIndex[i] = indexCoordinateMin[i]; maxIndex[i] = indexCoordinateMax[i]; } statObj.AddStatistic(mitk::ImageStatisticsConstants::MINIMUMPOSITION(), minIndex); statObj.AddStatistic(mitk::ImageStatisticsConstants::MAXIMUMPOSITION(), maxIndex); assert(std::abs(minMaxFilter->GetMax(*it) - imageStatisticsFilter->GetMaximum(*it)) < mitk::eps); assert(std::abs(minMaxFilter->GetMin(*it) - imageStatisticsFilter->GetMinimum(*it)) < mitk::eps); auto voxelVolume = GetVoxelVolume<TPixel, VImageDimension>(image); auto numberOfVoxels = - static_cast<unsigned long>(imageStatisticsFilter->GetSum(*it) / (double)imageStatisticsFilter->GetMean(*it)); + static_cast<unsigned long>(imageStatisticsFilter->GetCount(*it)); auto volume = static_cast<double>(numberOfVoxels) * voxelVolume; auto rms = std::sqrt(std::pow(imageStatisticsFilter->GetMean(*it), 2.) + imageStatisticsFilter->GetVariance(*it)); // variance = sigma^2 auto variance = imageStatisticsFilter->GetSigma(*it) * imageStatisticsFilter->GetSigma(*it); statObj.AddStatistic(mitk::ImageStatisticsConstants::NUMBEROFVOXELS(), numberOfVoxels); statObj.AddStatistic(mitk::ImageStatisticsConstants::VOLUME(), volume); statObj.AddStatistic(mitk::ImageStatisticsConstants::MEAN(), imageStatisticsFilter->GetMean(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::MINIMUM(), imageStatisticsFilter->GetMinimum(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::MAXIMUM(), imageStatisticsFilter->GetMaximum(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::STANDARDDEVIATION(), imageStatisticsFilter->GetSigma(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::VARIANCE(), variance); statObj.AddStatistic(mitk::ImageStatisticsConstants::SKEWNESS(), imageStatisticsFilter->GetSkewness(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::KURTOSIS(), imageStatisticsFilter->GetKurtosis(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::RMS(), rms); statObj.AddStatistic(mitk::ImageStatisticsConstants::MPP(), imageStatisticsFilter->GetMPP(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::ENTROPY(), imageStatisticsFilter->GetEntropy(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::MEDIAN(), imageStatisticsFilter->GetMedian(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::UNIFORMITY(), imageStatisticsFilter->GetUniformity(*it)); statObj.AddStatistic(mitk::ImageStatisticsConstants::UPP(), imageStatisticsFilter->GetUPP(*it)); statObj.m_Histogram = imageStatisticsFilter->GetHistogram(*it).GetPointer(); statisticContainerForLabelImage->SetStatisticsForTimeStep(timeStep, statObj); ++it; } // swap maskGenerators back if (swapMasks) { m_SecondaryMask = m_InternalMask; m_InternalMask = nullptr; } } bool ImageStatisticsCalculator::IsUpdateRequired(LabelIndex label) const { unsigned long thisClassTimeStamp = this->GetMTime(); unsigned long inputImageTimeStamp = m_Image->GetMTime(); auto it = m_StatisticContainers.find(label); if (it == m_StatisticContainers.end()) { return true; } unsigned long statisticsTimeStamp = it->second->GetMTime(); if (thisClassTimeStamp > statisticsTimeStamp) // inputs have changed { return true; } if (inputImageTimeStamp > statisticsTimeStamp) // image has changed { return true; } if (m_MaskGenerator.IsNotNull()) { unsigned long maskGeneratorTimeStamp = m_MaskGenerator->GetMTime(); if (maskGeneratorTimeStamp > statisticsTimeStamp) // there is a mask generator and it has changed { return true; } } if (m_SecondaryMaskGenerator.IsNotNull()) { unsigned long maskGeneratorTimeStamp = m_SecondaryMaskGenerator->GetMTime(); if (maskGeneratorTimeStamp > statisticsTimeStamp) // there is a secondary mask generator and it has changed { return true; } } return false; } } // namespace mitk diff --git a/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp b/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp index 6b8851bdd4..0f63304ab9 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp +++ b/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp @@ -1,240 +1,248 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkImageStatisticsContainer.h> #include <algorithm> namespace mitk { ImageStatisticsContainer::ImageStatisticsContainer() { this->Reset(); } // The order is derived from the old (<2018) image statistics plugin. const ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector ImageStatisticsContainer::ImageStatisticsObject::m_DefaultNames = {ImageStatisticsConstants::MEAN(), ImageStatisticsConstants::MEDIAN(), ImageStatisticsConstants::STANDARDDEVIATION(), ImageStatisticsConstants::RMS(), ImageStatisticsConstants::MAXIMUM(), ImageStatisticsConstants::MAXIMUMPOSITION(), ImageStatisticsConstants::MINIMUM(), ImageStatisticsConstants::MINIMUMPOSITION(), ImageStatisticsConstants::NUMBEROFVOXELS(), ImageStatisticsConstants::VOLUME(), ImageStatisticsConstants::SKEWNESS(), ImageStatisticsConstants::KURTOSIS(), ImageStatisticsConstants::UNIFORMITY(), ImageStatisticsConstants::ENTROPY(), ImageStatisticsConstants::MPP(), ImageStatisticsConstants::UPP()}; ImageStatisticsContainer::ImageStatisticsObject::ImageStatisticsObject() { Reset(); } void ImageStatisticsContainer::ImageStatisticsObject::AddStatistic(const std::string &key, StatisticsVariantType value) { m_Statistics.emplace(key, value); if (std::find(m_DefaultNames.cbegin(), m_DefaultNames.cend(), key) == m_DefaultNames.cend()) { if (std::find(m_CustomNames.cbegin(), m_CustomNames.cend(), key) == m_CustomNames.cend()) { m_CustomNames.emplace_back(key); } } } const ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector & ImageStatisticsContainer::ImageStatisticsObject::GetDefaultStatisticNames() { return m_DefaultNames; } const ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector & ImageStatisticsContainer::ImageStatisticsObject::GetCustomStatisticNames() const { return m_CustomNames; } ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector ImageStatisticsContainer::ImageStatisticsObject::GetAllStatisticNames() const { StatisticNameVector names = GetDefaultStatisticNames(); names.insert(names.cend(), m_CustomNames.cbegin(), m_CustomNames.cend()); return names; } ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector ImageStatisticsContainer::ImageStatisticsObject::GetExistingStatisticNames() const { StatisticNameVector names; std::transform(m_Statistics.begin(), m_Statistics.end(), std::back_inserter(names), [](const auto &pair) { return pair.first; }); return names; } bool ImageStatisticsContainer::ImageStatisticsObject::HasStatistic(const std::string &name) const { return m_Statistics.find(name) != m_Statistics.cend(); } ImageStatisticsContainer::StatisticsVariantType ImageStatisticsContainer::ImageStatisticsObject::GetValueNonConverted( const std::string &name) const { if (HasStatistic(name)) { return m_Statistics.find(name)->second; } else { mitkThrow() << "invalid statistic key, could not find"; } } void ImageStatisticsContainer::ImageStatisticsObject::Reset() { m_Statistics.clear(); m_CustomNames.clear(); } bool ImageStatisticsContainer::TimeStepExists(TimeStepType timeStep) const { return m_TimeStepMap.find(timeStep) != m_TimeStepMap.end(); } const ImageStatisticsContainer::HistogramType* ImageStatisticsContainer::GetHistogramForTimeStep(TimeStepType timeStep) const { return this->GetStatisticsForTimeStep(timeStep).m_Histogram; } const ImageStatisticsContainer::ImageStatisticsObject &ImageStatisticsContainer::GetStatisticsForTimeStep( TimeStepType timeStep) const { auto it = m_TimeStepMap.find(timeStep); if (it != m_TimeStepMap.end()) { return it->second; } mitkThrow() << "StatisticsObject for timeStep " << timeStep << " not found!"; } void ImageStatisticsContainer::SetStatisticsForTimeStep(TimeStepType timeStep, ImageStatisticsObject statistics) { if (timeStep < this->GetTimeSteps()) { m_TimeStepMap.emplace(timeStep, statistics); this->Modified(); } else { mitkThrow() << "Given timeStep " << timeStep << " out of timeStep geometry bounds. TimeSteps in geometry: " << this->GetTimeSteps(); } } void ImageStatisticsContainer::PrintSelf(std::ostream &os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); for (unsigned int i = 0; i < this->GetTimeSteps(); i++) { - auto statisticsValues = GetStatisticsForTimeStep(i); os << std::endl << indent << "Statistics instance for timeStep " << i << ":"; - auto statisticKeys = statisticsValues.GetExistingStatisticNames(); - os << std::endl << indent << "Number of entries: " << statisticKeys.size(); - for (const auto &aKey : statisticKeys) + if (this->TimeStepExists(i)) { - os << std::endl << indent.GetNextIndent() << aKey << ": " << statisticsValues.GetValueNonConverted(aKey); + auto statisticsValues = GetStatisticsForTimeStep(i); + + auto statisticKeys = statisticsValues.GetExistingStatisticNames(); + os << std::endl << indent << "Number of entries: " << statisticKeys.size(); + for (const auto& aKey : statisticKeys) + { + os << std::endl << indent.GetNextIndent() << aKey << ": " << statisticsValues.GetValueNonConverted(aKey); + } + } + else + { + os << std::endl << indent << "N/A"; } } } unsigned int ImageStatisticsContainer::GetNumberOfTimeSteps() const { return this->GetTimeSteps(); } void ImageStatisticsContainer::Reset() { for (auto iter = m_TimeStepMap.begin(); iter != m_TimeStepMap.end(); iter++) { iter->second.Reset(); } } itk::LightObject::Pointer ImageStatisticsContainer::InternalClone() const { itk::LightObject::Pointer ioPtr = Superclass::InternalClone(); Self::Pointer rval = dynamic_cast<Self *>(ioPtr.GetPointer()); if (rval.IsNull()) { itkExceptionMacro(<< "downcast to type " << "StatisticsContainer" << " failed."); } rval->SetTimeStepMap(m_TimeStepMap); rval->SetTimeGeometry(this->GetTimeGeometry()->Clone()); return ioPtr; } void ImageStatisticsContainer::SetTimeStepMap(TimeStepMapType map) { m_TimeStepMap = map; } ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector GetAllStatisticNames( const ImageStatisticsContainer *container) { ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector names = ImageStatisticsContainer::ImageStatisticsObject::GetDefaultStatisticNames(); if (container) { std::set<std::string> customKeys; for (unsigned int i = 0; i < container->GetTimeSteps(); i++) { auto statisticKeys = container->GetStatisticsForTimeStep(i).GetCustomStatisticNames(); customKeys.insert(statisticKeys.cbegin(), statisticKeys.cend()); } names.insert(names.cend(), customKeys.cbegin(), customKeys.cend()); } return names; } ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector GetAllStatisticNames( std::vector<ImageStatisticsContainer::ConstPointer> containers) { ImageStatisticsContainer::ImageStatisticsObject::StatisticNameVector names = ImageStatisticsContainer::ImageStatisticsObject::GetDefaultStatisticNames(); std::set<std::string> customKeys; for (const auto &container : containers) { for (unsigned int i = 0; i < container->GetTimeSteps(); i++) { if(container->TimeStepExists(i)) { auto statisticKeys = container->GetStatisticsForTimeStep(i).GetCustomStatisticNames(); customKeys.insert(statisticKeys.cbegin(), statisticKeys.cend()); } } } names.insert(names.end(), customKeys.begin(), customKeys.end()); return names; }; } // namespace mitk diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp index cfaea25dce..91d3eb0141 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp @@ -1,102 +1,106 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkImageStatisticsWidget.h" #include "QmitkStatisticsModelToStringConverter.h" #include "QmitkImageStatisticsTreeModel.h" #include <QSortFilterProxyModel> #include <QClipboard> QmitkImageStatisticsWidget::QmitkImageStatisticsWidget(QWidget* parent) : QWidget(parent) { m_Controls.setupUi(this); m_imageStatisticsModel = new QmitkImageStatisticsTreeModel(parent); CreateConnections(); m_ProxyModel = new QSortFilterProxyModel(this); m_Controls.treeViewStatistics->setEnabled(false); m_Controls.treeViewStatistics->setModel(m_ProxyModel); m_ProxyModel->setSourceModel(m_imageStatisticsModel); connect(m_imageStatisticsModel, &QmitkImageStatisticsTreeModel::dataAvailable, this, &QmitkImageStatisticsWidget::OnDataAvailable); connect(m_imageStatisticsModel, &QmitkImageStatisticsTreeModel::modelChanged, m_Controls.treeViewStatistics, &QTreeView::expandAll); + connect(m_Controls.checkBoxIgnoreZeroValuedVoxel, &QCheckBox::stateChanged, + this, &QmitkImageStatisticsWidget::IgnoreZeroValuedVoxelStateChanged); } void QmitkImageStatisticsWidget::SetDataStorage(mitk::DataStorage* newDataStorage) { m_imageStatisticsModel->SetDataStorage(newDataStorage); } void QmitkImageStatisticsWidget::SetImageNodes(const std::vector<mitk::DataNode::ConstPointer>& nodes) { m_imageStatisticsModel->SetImageNodes(nodes); } void QmitkImageStatisticsWidget::SetMaskNodes(const std::vector<mitk::DataNode::ConstPointer>& nodes) { m_imageStatisticsModel->SetMaskNodes(nodes); } void QmitkImageStatisticsWidget::Reset() { m_imageStatisticsModel->Clear(); m_Controls.treeViewStatistics->setEnabled(false); m_Controls.buttonCopyImageStatisticsToClipboard->setEnabled(false); + m_Controls.checkBoxIgnoreZeroValuedVoxel->setEnabled(false); } void QmitkImageStatisticsWidget::SetIgnoreZeroValueVoxel(bool _arg) { m_imageStatisticsModel->SetIgnoreZeroValueVoxel(_arg); } bool QmitkImageStatisticsWidget::GetIgnoreZeroValueVoxel() const { return this->m_imageStatisticsModel->GetIgnoreZeroValueVoxel(); } void QmitkImageStatisticsWidget::SetHistogramNBins(unsigned int nbins) { m_imageStatisticsModel->SetHistogramNBins(nbins); } unsigned int QmitkImageStatisticsWidget::GetHistogramNBins() const { return this->m_imageStatisticsModel->GetHistogramNBins(); } void QmitkImageStatisticsWidget::CreateConnections() { connect(m_Controls.buttonCopyImageStatisticsToClipboard, &QPushButton::clicked, this, &QmitkImageStatisticsWidget::OnClipboardButtonClicked); } void QmitkImageStatisticsWidget::OnDataAvailable() { m_Controls.buttonCopyImageStatisticsToClipboard->setEnabled(true); m_Controls.treeViewStatistics->setEnabled(true); + m_Controls.checkBoxIgnoreZeroValuedVoxel->setEnabled(true); } void QmitkImageStatisticsWidget::OnClipboardButtonClicked() { QmitkStatisticsModelToStringConverter converter; converter.SetColumnDelimiter('\t'); converter.SetModel(m_imageStatisticsModel); converter.SetRootIndex(m_Controls.treeViewStatistics->rootIndex()); converter.SetIncludeHeaderData(true); QString clipboardAsString = converter.GetString(); QApplication::clipboard()->clear(); QApplication::clipboard()->setText(clipboardAsString, QClipboard::Clipboard); } diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.h b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.h index 13e4fef97d..b755b5fc46 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.h +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.h @@ -1,63 +1,65 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkImageStatisticsWidget_H__INCLUDED #define QmitkImageStatisticsWidget_H__INCLUDED #include <MitkImageStatisticsUIExports.h> #include <ui_QmitkImageStatisticsWidget.h> #include <mitkDataStorage.h> #include <mitkDataNode.h> class QSortFilterProxyModel; class QmitkImageStatisticsTreeModel; class MITKIMAGESTATISTICSUI_EXPORT QmitkImageStatisticsWidget : public QWidget { Q_OBJECT public: QmitkImageStatisticsWidget(QWidget *parent = nullptr); /**Documentation Set the data storage the model should fetch its statistic objects from. @pre data storage must be valid */ void SetDataStorage(mitk::DataStorage *newDataStorage); void SetImageNodes(const std::vector<mitk::DataNode::ConstPointer> &nodes); void SetMaskNodes(const std::vector<mitk::DataNode::ConstPointer> &nodes); void Reset(); /*! /brief Set flag to ignore zero valued voxels */ void SetIgnoreZeroValueVoxel(bool _arg); /*! /brief Get status of zero value voxel ignoring. */ bool GetIgnoreZeroValueVoxel() const; /*! /brief Set bin size for histogram resolution.*/ void SetHistogramNBins(unsigned int nbins); /*! /brief Get bin size for histogram resolution.*/ unsigned int GetHistogramNBins() const; +signals: + void IgnoreZeroValuedVoxelStateChanged(int status); + private: void CreateConnections(); void OnDataAvailable(); /** \brief Saves the image statistics to the clipboard */ void OnClipboardButtonClicked(); -private: Ui::QmitkImageStatisticsControls m_Controls; QmitkImageStatisticsTreeModel *m_imageStatisticsModel; QSortFilterProxyModel *m_ProxyModel; }; #endif // QmitkImageStatisticsWidget_H__INCLUDED diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.ui b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.ui index db87e06c53..e9f05754a3 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.ui +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.ui @@ -1,92 +1,99 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>QmitkImageStatisticsControls</class> <widget class="QWidget" name="QmitkImageStatisticsControls"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>395</width> <height>366</height> </rect> </property> <property name="minimumSize"> <size> <width>0</width> <height>0</height> </size> </property> <property name="windowTitle"> <string>Form</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <property name="leftMargin"> <number>2</number> </property> <property name="topMargin"> <number>2</number> </property> <property name="rightMargin"> <number>2</number> </property> <property name="bottomMargin"> <number>2</number> </property> <item> <widget class="QTreeView" name="treeViewStatistics"/> </item> <item> <widget class="QWidget" name="widgetClipboard" native="true"> - <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0"> + <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0"> <property name="spacing"> <number>0</number> </property> <property name="leftMargin"> <number>0</number> </property> <property name="topMargin"> <number>0</number> </property> <property name="rightMargin"> <number>0</number> </property> <property name="bottomMargin"> <number>0</number> </property> <item> <widget class="QPushButton" name="buttonCopyImageStatisticsToClipboard"> <property name="enabled"> <bool>false</bool> </property> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> <string>Copy to Clipboard</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_2"> + <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> + <item> + <widget class="QCheckBox" name="checkBoxIgnoreZeroValuedVoxel"> + <property name="text"> + <string>Ignore zero-valued voxels</string> + </property> + </widget> + </item> </layout> </widget> </item> </layout> </widget> <resources/> <connections/> </ui> diff --git a/Modules/IpPicSupportIO/CMakeLists.txt b/Modules/IpPicSupportIO/CMakeLists.txt deleted file mode 100644 index 7eb227a8c8..0000000000 --- a/Modules/IpPicSupportIO/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -#mitkFunctionCheckCompilerFlags("-Wno-deprecated-declarations" CMAKE_CXX_FLAGS) - -MITK_CREATE_MODULE( - DEPENDS MitkCore MitkIpPic - AUTOLOAD_WITH MitkCore - ) - -if(BUILD_TESTING) - #add_subdirectory(Testing) -endif() diff --git a/Modules/IpPicSupportIO/Internal/mitkIpPicSupportIOActivator.cpp b/Modules/IpPicSupportIO/Internal/mitkIpPicSupportIOActivator.cpp deleted file mode 100644 index bda1a4b95a..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkIpPicSupportIOActivator.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <usModuleActivator.h> - -#include "mitkPicFileReader.h" - -class US_ABI_LOCAL mitkIpPicSupportIOActivator : public us::ModuleActivator -{ -public: - void Load(us::ModuleContext *) override { m_Reader = new mitk::PicFileReader(); } - void Unload(us::ModuleContext *) override { delete m_Reader; } -private: - mitk::IFileReader *m_Reader; -}; - -US_EXPORT_MODULE_ACTIVATOR(mitkIpPicSupportIOActivator) diff --git a/Modules/IpPicSupportIO/Internal/mitkPicFileReader.cpp b/Modules/IpPicSupportIO/Internal/mitkPicFileReader.cpp deleted file mode 100644 index 61884011f1..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicFileReader.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPicFileReader.h" -#include "mitkPicHelper.h" - -#include "mitkCustomMimeType.h" -#include "mitkImageWriteAccessor.h" - -#include <mitkIpPic.h> - - -static mitk::PixelType CastToPixelType(mitkIpPicType_t pictype, size_t bpe) -{ - const bool isSignedIntegralType = (pictype == mitkIpPicInt); - const bool isUnsignedIntegralType = (pictype == mitkIpPicUInt); - - if (isSignedIntegralType) - { - switch (bpe) - { - case sizeof(char) : - return mitk::MakeScalarPixelType<char>(); - case sizeof(short) : - return mitk::MakeScalarPixelType<short>(); - default: - return mitk::MakeScalarPixelType<int>(); - } - } - else if (isUnsignedIntegralType) - { - switch (bpe) - { - case sizeof(unsigned char) : - return mitk::MakeScalarPixelType<unsigned char>(); - case sizeof(unsigned short) : - return mitk::MakeScalarPixelType<unsigned short>(); - default: - return mitk::MakeScalarPixelType<unsigned int>(); - } - } - else // is floating point type - { - switch (bpe) - { - case sizeof(float) : - return mitk::MakeScalarPixelType<float>(); - default: - return mitk::MakeScalarPixelType<double>(); - } - } -} - -static mitk::ImageDescriptor::Pointer CastToImageDescriptor(mitkIpPicDescriptor *desc) -{ - mitk::ImageDescriptor::Pointer imDescriptor = mitk::ImageDescriptor::New(); - - imDescriptor->Initialize(desc->n, desc->dim); - - mitk::PixelType ptype = ::CastToPixelType(desc->type, (desc->bpe / 8)); - imDescriptor->AddNewChannel(ptype, "imported by pic"); - - return imDescriptor; -} - -static mitkIpPicType_t CastToIpPicType(int intype) -{ - const bool isSignedIntegralType = (intype == itk::ImageIOBase::INT || intype == itk::ImageIOBase::SHORT || - intype == itk::ImageIOBase::CHAR || intype == itk::ImageIOBase::LONG); - - const bool isUnsignedIntegralType = (intype == itk::ImageIOBase::UINT || intype == itk::ImageIOBase::USHORT || - intype == itk::ImageIOBase::UCHAR || intype == itk::ImageIOBase::ULONG); - - const bool isFloatingPointType = (intype == itk::ImageIOBase::FLOAT || intype == itk::ImageIOBase::DOUBLE); - - if (isSignedIntegralType) - return mitkIpPicInt; - if (isUnsignedIntegralType) - return mitkIpPicUInt; - if (isFloatingPointType) - return mitkIpPicFloat; - return mitkIpPicUnknown; -} - -static mitkIpPicDescriptor * CastToIpPicDescriptor(mitk::Image::Pointer refImg, - mitk::ImageWriteAccessor *imageAccess, - mitkIpPicDescriptor *picDesc) -{ - const mitk::ImageDescriptor::Pointer imDesc = refImg->GetImageDescriptor(); - - // initialize dimension information - for (unsigned int i = 0; i < 8; i++) - { - picDesc->n[i] = 1; - } - - // set dimension information - picDesc->dim = refImg->GetDimension(); - memcpy(picDesc->n, imDesc->GetDimensions(), picDesc->dim * sizeof(unsigned int)); - - picDesc->type = ::CastToIpPicType(refImg->GetPixelType().GetComponentType()); - picDesc->bpe = refImg->GetPixelType().GetBpe(); - if (imageAccess != nullptr) - { - picDesc->data = imageAccess->GetData(); - } - - return picDesc; -} - - -mitk::PicFileReader::PicFileReader() : AbstractFileReader() -{ - CustomMimeType mimeType(this->GetMimeTypePrefix() + "mbipic"); - mimeType.AddExtension("pic"); - mimeType.AddExtension("pic.gz"); - mimeType.AddExtension("PIC"); - mimeType.AddExtension("PIC.gz"); - mimeType.SetCategory("Images"); - mimeType.SetComment("DKFZ Legacy PIC Format"); - - this->SetMimeType(mimeType); - this->SetDescription("DKFZ PIC"); - - this->RegisterService(); -} - -std::vector<mitk::BaseData::Pointer> mitk::PicFileReader::DoRead() -{ - mitk::Image::Pointer image = this->CreateImage(); - this->FillImage(image); - std::vector<BaseData::Pointer> result; - result.push_back(image.GetPointer()); - return result; -} - -mitk::Image::Pointer mitk::PicFileReader::CreateImage() -{ - Image::Pointer output = Image::New(); - - std::string fileName = this->GetLocalFileName(); - - mitkIpPicDescriptor *header = mitkIpPicGetHeader(fileName.c_str(), nullptr); - - if (!header) - { - mitkThrow() << "File could not be read."; - } - - header = mitkIpPicGetTags(fileName.c_str(), header); - - int channels = 1; - - mitkIpPicTSV_t *tsv; - if ((tsv = mitkIpPicQueryTag(header, "SOURCE HEADER")) != nullptr) - { - if (tsv->n[0] > 1e+06) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag(header, "SOURCE HEADER"); - mitkIpPicFreeTag(tsvSH); - } - } - if ((tsv = mitkIpPicQueryTag(header, "ICON80x80")) != nullptr) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag(header, "ICON80x80"); - mitkIpPicFreeTag(tsvSH); - } - if ((tsv = mitkIpPicQueryTag(header, "VELOCITY")) != nullptr) - { - ++channels; - mitkIpPicDelTag(header, "VELOCITY"); - } - - if (header == nullptr || header->bpe == 0) - { - mitkThrow() << " Could not read file " << fileName; - } - - // if pic image only 2D, the n[2] value is not initialized - unsigned int slices = 1; - if (header->dim == 2) - { - header->n[2] = slices; - } - - // First initialize the geometry of the output image by the pic-header - SlicedGeometry3D::Pointer slicedGeometry = mitk::SlicedGeometry3D::New(); - PicHelper::InitializeEvenlySpaced(header, header->n[2], slicedGeometry); - - // if pic image only 3D, the n[3] value is not initialized - unsigned int timesteps = 1; - if (header->dim > 3) - { - timesteps = header->n[3]; - } - - slicedGeometry->ImageGeometryOn(); - ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); - timeGeometry->Initialize(slicedGeometry, timesteps); - - // Cast the pic descriptor to ImageDescriptor and initialize the output - - output->Initialize(CastToImageDescriptor(header)); - output->SetTimeGeometry(timeGeometry); - mitkIpPicFree(header); - - return output; -} - -void mitk::PicFileReader::ConvertHandedness(mitkIpPicDescriptor *pic) -{ - // left to right handed conversion - if (pic->dim >= 3) - { - mitkIpPicDescriptor *slice = mitkIpPicCopyHeader(pic, nullptr); - slice->dim = 2; - size_t size = _mitkIpPicSize(slice); - slice->data = malloc(size); - - size_t v, volumes = (pic->dim > 3 ? pic->n[3] : 1); - size_t volume_size = size * pic->n[2]; - - for (v = 0; v < volumes; ++v) - { - auto *p_first = (unsigned char *)pic->data; - auto *p_last = (unsigned char *)pic->data; - p_first += v * volume_size; - p_last += size * (pic->n[2] - 1) + v * volume_size; - - size_t i, smid = pic->n[2] / 2; - for (i = 0; i < smid; ++i, p_last -= size, p_first += size) - { - memcpy(slice->data, p_last, size); - memcpy(p_last, p_first, size); - memcpy(p_first, slice->data, size); - } - } - mitkIpPicFree(slice); - } -} - -mitk::PicFileReader *mitk::PicFileReader::Clone() const -{ - return new PicFileReader(*this); -} - -void mitk::PicFileReader::FillImage(Image::Pointer output) -{ - mitkIpPicDescriptor *outputPic = mitkIpPicNew(); - outputPic = CastToIpPicDescriptor(output, nullptr, outputPic); - mitkIpPicDescriptor *pic = mitkIpPicGet(this->GetLocalFileName().c_str(), outputPic); - // comes upside-down (in MITK coordinates) from PIC file - ConvertHandedness(pic); - - mitkIpPicTSV_t *tsv; - if ((tsv = mitkIpPicQueryTag(pic, "SOURCE HEADER")) != nullptr) - { - if (tsv->n[0] > 1e+06) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag(pic, "SOURCE HEADER"); - mitkIpPicFreeTag(tsvSH); - } - } - if ((tsv = mitkIpPicQueryTag(pic, "ICON80x80")) != nullptr) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag(pic, "ICON80x80"); - mitkIpPicFreeTag(tsvSH); - } - if ((tsv = mitkIpPicQueryTag(pic, "VELOCITY")) != nullptr) - { - mitkIpPicDescriptor *header = mitkIpPicCopyHeader(pic, nullptr); - header->data = tsv->value; - ConvertHandedness(header); - output->SetChannel(header->data, 1); - header->data = nullptr; - mitkIpPicFree(header); - mitkIpPicDelTag(pic, "VELOCITY"); - } - - // Copy the memory to avoid mismatches of malloc() and delete[]. - // mitkIpPicGet will always allocate a new memory block with malloc(), - // but MITK Images delete the data via delete[]. - output->SetImportChannel(pic->data, 0, Image::CopyMemory); - pic->data = nullptr; - mitkIpPicFree(pic); -} diff --git a/Modules/IpPicSupportIO/Internal/mitkPicFileReader.h b/Modules/IpPicSupportIO/Internal/mitkPicFileReader.h deleted file mode 100644 index f472490732..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicFileReader.h +++ /dev/null @@ -1,48 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef PICFILEREADER_H_HEADER_INCLUDED_C1F48A22 -#define PICFILEREADER_H_HEADER_INCLUDED_C1F48A22 - -#include "mitkAbstractFileReader.h" - -#include "mitkImage.h" - -#include "mitkIpPic.h" - -namespace mitk -{ - //##Documentation - //## @brief Reader to read files in DKFZ-pic-format - class PicFileReader : public AbstractFileReader - { - public: - PicFileReader(); - - using AbstractFileReader::Read; - - protected: - void FillImage(Image::Pointer image); - - Image::Pointer CreateImage(); - - std::vector<itk::SmartPointer<BaseData>> DoRead() override; - - private: - static void ConvertHandedness(mitkIpPicDescriptor *pic); - - PicFileReader *Clone() const override; - }; - -} // namespace mitk - -#endif /* PICFILEREADER_H_HEADER_INCLUDED_C1F48A22 */ diff --git a/Modules/IpPicSupportIO/Internal/mitkPicHelper.cpp b/Modules/IpPicSupportIO/Internal/mitkPicHelper.cpp deleted file mode 100644 index 6a9c030958..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicHelper.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPicHelper.h" -#include "mitkConfig.h" -#include "mitkPlaneGeometry.h" -#include "mitkSlicedGeometry3D.h" -#ifdef HAVE_IPDICOM -#include "ipDicom/ipDicom.h" -#endif /* HAVE_IPDICOM */ - -bool mitk::PicHelper::GetSpacing(const mitkIpPicDescriptor *aPic, Vector3D &spacing) -{ - auto *pic = const_cast<mitkIpPicDescriptor *>(aPic); - - mitkIpPicTSV_t *tsv; - bool pixelSize = false; - - tsv = mitkIpPicQueryTag(pic, "REAL PIXEL SIZE"); - if (tsv == nullptr) - { - tsv = mitkIpPicQueryTag(pic, "PIXEL SIZE"); - pixelSize = true; - } - if (tsv) - { - bool tagFound = false; - if ((tsv->dim * tsv->n[0] >= 3) && (tsv->type == mitkIpPicFloat)) - { - if (tsv->bpe == 32) - { - FillVector3D(spacing, - ((mitkIpFloat4_t *)tsv->value)[0], - ((mitkIpFloat4_t *)tsv->value)[1], - ((mitkIpFloat4_t *)tsv->value)[2]); - tagFound = true; - } - else if (tsv->bpe == 64) - { - FillVector3D(spacing, - ((mitkIpFloat8_t *)tsv->value)[0], - ((mitkIpFloat8_t *)tsv->value)[1], - ((mitkIpFloat8_t *)tsv->value)[2]); - tagFound = true; - } - } - if (tagFound && pixelSize) - { - tsv = mitkIpPicQueryTag(pic, "PIXEL SPACING"); - if (tsv) - { - mitk::ScalarType zSpacing = 0; - if ((tsv->dim * tsv->n[0] >= 3) && (tsv->type == mitkIpPicFloat)) - { - if (tsv->bpe == 32) - { - zSpacing = ((mitkIpFloat4_t *)tsv->value)[2]; - } - else if (tsv->bpe == 64) - { - zSpacing = ((mitkIpFloat8_t *)tsv->value)[2]; - } - if (zSpacing != 0) - { - spacing[2] = zSpacing; - } - } - } - } - if (tagFound) - return true; - } -#ifdef HAVE_IPDICOM - tsv = mitkIpPicQueryTag(pic, "SOURCE HEADER"); - if (tsv) - { - void *data; - mitkIpUInt4_t len; - mitkIpFloat8_t spacing_z = 0; - mitkIpFloat8_t thickness = 1; - mitkIpFloat8_t fx = 1; - mitkIpFloat8_t fy = 1; - bool ok = false; - - if (dicomFindElement((unsigned char *)tsv->value, 0x0018, 0x0088, &data, &len)) - { - ok = true; - sscanf((char *)data, "%lf", &spacing_z); - // itkGenericOutputMacro( "spacing: " << spacing_z << " mm"); - } - if (dicomFindElement((unsigned char *)tsv->value, 0x0018, 0x0050, &data, &len)) - { - ok = true; - sscanf((char *)data, "%lf", &thickness); - // itkGenericOutputMacro( "thickness: " << thickness << " mm"); - - if (thickness == 0) - thickness = 1; - } - if (dicomFindElement((unsigned char *)tsv->value, 0x0028, 0x0030, &data, &len) && len > 0 && ((char *)data)[0]) - { - sscanf((char *)data, "%lf\\%lf", &fy, &fx); // row / column value - // itkGenericOutputMacro( "fx, fy: " << fx << "/" << fy << " mm"); - } - else - ok = false; - if (ok) - FillVector3D(spacing, fx, fy, (spacing_z > 0 ? spacing_z : thickness)); - return ok; - } -#endif /* HAVE_IPDICOM */ - if (spacing[0] <= 0 || spacing[1] <= 0 || spacing[2] <= 0) - { - itkGenericOutputMacro(<< "illegal spacing by pic tag: " << spacing << ". Setting spacing to (1,1,1)."); - spacing.Fill(1); - } - return false; -} - -bool mitk::PicHelper::GetTimeSpacing(const mitkIpPicDescriptor *aPic, float &timeSpacing) -{ - auto *pic = const_cast<mitkIpPicDescriptor *>(aPic); - - mitkIpPicTSV_t *tsv; - - tsv = mitkIpPicQueryTag(pic, "PIXEL SIZE"); - if (tsv) - { - timeSpacing = ((mitkIpFloat4_t *)tsv->value)[3]; - if (timeSpacing <= 0) - timeSpacing = 1; - } - else - timeSpacing = 1; - return true; -} - -bool mitk::PicHelper::SetSpacing(const mitkIpPicDescriptor *aPic, SlicedGeometry3D *slicedgeometry) -{ - auto *pic = const_cast<mitkIpPicDescriptor *>(aPic); - - Vector3D spacing(slicedgeometry->GetSpacing()); - - mitkIpPicTSV_t *tsv; - if ((tsv = mitkIpPicQueryTag(pic, "REAL PIXEL SIZES")) != nullptr) - { - int count = tsv->n[1]; - auto *value = (float *)tsv->value; - mitk::Vector3D pixelSize; - spacing.Fill(0); - - for (int s = 0; s < count; s++) - { - pixelSize[0] = (ScalarType)*value++; - pixelSize[1] = (ScalarType)*value++; - pixelSize[2] = (ScalarType)*value++; - spacing += pixelSize; - } - spacing *= 1.0f / count; - slicedgeometry->SetSpacing(spacing); - - itkGenericOutputMacro(<< "the slices are inhomogeneous"); - } - else if (GetSpacing(pic, spacing)) - { - slicedgeometry->SetSpacing(spacing); - return true; - } - return false; -} - -void mitk::PicHelper::InitializeEvenlySpaced(const mitkIpPicDescriptor *pic, - unsigned int slices, - SlicedGeometry3D *slicedgeometry) -{ - assert(pic != nullptr); - assert(slicedgeometry != nullptr); - - mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); - - mitkIpPicTSV_t *geometryTag; - if ((geometryTag = mitkIpPicQueryTag(const_cast<mitkIpPicDescriptor *>(pic), "ISG")) != nullptr) - { - mitk::Point3D origin; - mitk::Vector3D rightVector; - mitk::Vector3D downVector; - mitk::Vector3D spacing; - - mitk::vtk2itk(((float *)geometryTag->value + 0), origin); - mitk::vtk2itk(((float *)geometryTag->value + 3), rightVector); - mitk::vtk2itk(((float *)geometryTag->value + 6), downVector); - mitk::vtk2itk(((float *)geometryTag->value + 9), spacing); - - mitk::PlaneGeometry::Pointer planegeometry = PlaneGeometry::New(); - planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], rightVector, downVector, &spacing); - planegeometry->SetOrigin(origin); - slicedgeometry->InitializeEvenlySpaced(planegeometry, slices); - } - else - { - Vector3D spacing; - spacing.Fill(1); - GetSpacing(pic, spacing); - planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], spacing); - slicedgeometry->InitializeEvenlySpaced(planegeometry, spacing[2], slices); - } -} - -bool mitk::PicHelper::SetPlaneGeometry(const mitkIpPicDescriptor *aPic, int s, SlicedGeometry3D *slicedgeometry) -{ - auto *pic = const_cast<mitkIpPicDescriptor *>(aPic); - if ((pic != nullptr) && (slicedgeometry->IsValidSlice(s))) - { - // construct standard view - mitk::Point3D origin; - mitk::Vector3D rightDV, bottomDV; - mitkIpPicTSV_t *tsv; - if ((tsv = mitkIpPicQueryTag(pic, "REAL PIXEL SIZES")) != nullptr) - { - auto count = (unsigned int)tsv->n[1]; - auto *value = (float *)tsv->value; - mitk::Vector3D pixelSize; - ScalarType zPosition = 0.0f; - - if (s >= 0) - { - if (count < (unsigned int)s) - return false; - count = s; - } - else - { - if (count < slicedgeometry->GetSlices()) - return false; - count = slicedgeometry->GetSlices(); - } - - unsigned int slice; - for (slice = 0; slice < count; ++slice) - { - pixelSize[0] = (ScalarType)*value++; - pixelSize[1] = (ScalarType)*value++; - pixelSize[2] = (ScalarType)*value++; - - zPosition += pixelSize[2] / 2.0f; // first half slice thickness - - if ((s == -1) || (slice == (unsigned int)s)) - { - Vector3D spacing; - spacing = pixelSize; - FillVector3D(origin, 0, 0, zPosition); - FillVector3D(rightDV, pic->n[0], 0, 0); - FillVector3D(bottomDV, 0, pic->n[1], 0); - - mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); - planegeometry->InitializeStandardPlane( - pic->n[0], pic->n[1], rightDV.GetVnlVector(), bottomDV.GetVnlVector(), &spacing); - planegeometry->SetOrigin(origin); - slicedgeometry->SetPlaneGeometry(planegeometry, s); - } - - zPosition += pixelSize[2] / 2.0f; // second half slice thickness - } - } - else - { - FillVector3D(origin, 0, 0, s); - slicedgeometry->IndexToWorld(origin, origin); - FillVector3D(rightDV, pic->n[0], 0, 0); - FillVector3D(bottomDV, 0, pic->n[1], 0); - - mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); - Vector3D spacing = slicedgeometry->GetSpacing(); - planegeometry->InitializeStandardPlane( - pic->n[0], pic->n[1], rightDV.GetVnlVector(), bottomDV.GetVnlVector(), &spacing); - planegeometry->SetOrigin(origin); - slicedgeometry->SetPlaneGeometry(planegeometry, s); - } - return true; - } - return false; -} diff --git a/Modules/IpPicSupportIO/Internal/mitkPicHelper.h b/Modules/IpPicSupportIO/Internal/mitkPicHelper.h deleted file mode 100644 index 7ac64991b5..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicHelper.h +++ /dev/null @@ -1,52 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPICHELPER_H_HEADER_INCLUDED_C1F4DAB4 -#define MITKPICHELPER_H_HEADER_INCLUDED_C1F4DAB4 - -#include "mitkVector.h" -#include <mitkCommon.h> -#include <mitkIpPic.h> - -namespace mitk -{ - class SlicedGeometry3D; - - //##Documentation - //## @brief Internal class for managing references on sub-images - class PicHelper - { - public: - static const char *GetNameOfClass() { return "PicHelper"; } - static bool GetSpacing(const mitkIpPicDescriptor *pic, Vector3D &spacing); - - static bool SetSpacing(const mitkIpPicDescriptor *pic, SlicedGeometry3D *slicedgeometry); - - static bool GetTimeSpacing(const mitkIpPicDescriptor *pic, float &timeSpacing); - - static void InitializeEvenlySpaced(const mitkIpPicDescriptor *pic, - unsigned int slices, - SlicedGeometry3D *slicedgeometry); - - static bool SetPlaneGeometry(const mitkIpPicDescriptor *pic, int s, SlicedGeometry3D *slicedgeometry); - /** -* \deprecatedSince{2014_10} Please use SetPlaneGeometry -*/ - DEPRECATED(static bool SetGeometry2D(const mitkIpPicDescriptor *pic, int s, SlicedGeometry3D *slicedgeometry)) - { - return SetPlaneGeometry(pic, s, slicedgeometry); - }; - }; - -} // namespace mitk - -#endif /* MITKPICHELPER_H_HEADER_INCLUDED_C1F4DAB4 */ diff --git a/Modules/IpPicSupportIO/Testing/CMakeLists.txt b/Modules/IpPicSupportIO/Testing/CMakeLists.txt deleted file mode 100644 index 9e874e1ea1..0000000000 --- a/Modules/IpPicSupportIO/Testing/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -MITK_CREATE_MODULE_TESTS() - -mitkAddCustomModuleTest(mitkPicFileReaderTest_emptyFile mitkPicFileReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/Data/emptyFile.pic) -mitkAddCustomModuleTest(mitkPicFileReaderTest_emptyGzipFile mitkPicFileReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/Data/emptyFile.pic.gz) diff --git a/Modules/IpPicSupportIO/Testing/files.cmake b/Modules/IpPicSupportIO/Testing/files.cmake deleted file mode 100644 index 4c577b2ba3..0000000000 --- a/Modules/IpPicSupportIO/Testing/files.cmake +++ /dev/null @@ -1,11 +0,0 @@ -set(MODULE_IMAGE_TESTS - #mitkPicFileIOTest.cpp - mitkPicFileReaderTest.cpp -) - -set(MODULE_TESTIMAGE - US4DCyl.pic.gz - Pic3D.pic.gz - Pic2DplusT.pic.gz - BallBinary30x30x30.pic.gz -) diff --git a/Modules/IpPicSupportIO/Testing/mitkPicFileIOTest.cpp b/Modules/IpPicSupportIO/Testing/mitkPicFileIOTest.cpp deleted file mode 100644 index 826517ec8f..0000000000 --- a/Modules/IpPicSupportIO/Testing/mitkPicFileIOTest.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkImage.h" -#include "mitkImageAccessByItk.h" -#include "mitkImageWriter.h" -#include "mitkPicFileReader.h" - -#include <itksys/SystemTools.hxx> - -unsigned int numberOfTestImages = 3; - -// create one test image -mitk::Image::Pointer CreateTestImage(unsigned int which) -{ - mitk::Image::Pointer image = mitk::Image::New(); - - switch (which) - { - case 0: - { - unsigned int dim[] = {10, 10, 20}; // image dimensions - - image->Initialize(mitk::PixelType(typeid(int)), 3, dim); - int *p = (int *)image->GetData(); // pointer to pixel data - int size = dim[0] * dim[1] * dim[2]; - for (int i = 0; i < size; ++i, ++p) - *p = i - size / 2; // fill image - } - break; - - case 1: - { - unsigned int dim[] = {10, 10, 20}; // image dimensions - - image->Initialize(mitk::PixelType(typeid(float)), 3, dim); - float *p = (float *)image->GetData(); // pointer to pixel data - int size = dim[0] * dim[1] * dim[2]; - for (int i = 0; i < size; ++i, ++p) - *p = (float)i - size / 2; // fill image - } - break; - - case 2: - { - unsigned int dim[] = {10, 10, 20}; // image dimensions - - image->Initialize(mitk::PixelType(typeid(double)), 3, dim); - double *p = (double *)image->GetData(); // pointer to pixel data - int size = dim[0] * dim[1] * dim[2]; - for (int i = 0; i < size; ++i, ++p) - *p = (double)i - size / 2; // fill image - } - break; - - default: - { - unsigned int dim[] = {10, 10, 20}; // image dimensions - - image->Initialize(mitk::PixelType(typeid(int)), 3, dim); - int *p = (int *)image->GetData(); // pointer to pixel data - int size = dim[0] * dim[1] * dim[2]; - for (int i = 0; i < size; ++i, ++p) - *p = i - size / 2; // fill image - } - } - - return image; -} - -template <typename TPixel, unsigned int VImageDimension> -void ItkImageProcessing(itk::Image<TPixel, VImageDimension> *itkImage, mitk::Image *mitkImage, bool &identical) -{ - typename itk::Image<TPixel, VImageDimension>::Pointer itkImage2; - - mitk::CastToItkImage(mitkImage, itkImage2); - - if (!itkImage2 || !itkImage2.GetPointer()) - { - identical = false; - return; - } - - itk::ImageRegionConstIterator<itk::Image<TPixel, VImageDimension>> iterItkImage1( - itkImage, itkImage->GetLargestPossibleRegion()); - itk::ImageRegionConstIterator<itk::Image<TPixel, VImageDimension>> iterItkImage2( - itkImage, itkImage2->GetLargestPossibleRegion()); - - iterItkImage1.GoToBegin(); - iterItkImage2.GoToBegin(); - - while (!iterItkImage1.IsAtEnd()) - { - if (iterItkImage1.Get() != iterItkImage2.Get()) - { - std::cout << iterItkImage1.Get() << " != " << iterItkImage2.Get() << std::endl; - identical = false; - return; - } - - ++iterItkImage1; - ++iterItkImage2; - } - - // if we reach this point, all pixel are the same - identical = true; -} - -int mitkPicFileIOTest(int, char *[]) -{ - unsigned int numberFailed(0); - - for (unsigned int i = 0; i < numberOfTestImages; ++i) - { - mitk::Image::Pointer originalImage = CreateTestImage(i); - mitk::Image::Pointer secondImage; - - // write - try - { - mitk::ImageWriter::Pointer imageWriter = mitk::ImageWriter::New(); - imageWriter->SetInput(originalImage); - - imageWriter->SetFileName("test_image"); - imageWriter->SetExtension(".pic"); - imageWriter->Write(); - } - catch (std::exception &e) - { - std::cerr << "Error during attempt to write 'test_image.pic' Exception says:" << std::endl; - std::cerr << e.what() << std::endl; - ++numberFailed; - continue; - } - - // load - try - { - mitk::PicFileReader::Pointer imageReader = mitk::PicFileReader::New(); - - imageReader->SetFileName("test_image.pic"); - imageReader->Update(); - - secondImage = imageReader->GetOutput(); - } - catch (std::exception &e) - { - std::cerr << "Error during attempt to read 'test_image.pic' Exception says:" << std::endl; - std::cerr << e.what() << std::endl; - ++numberFailed; - continue; - } - - if (secondImage.IsNull()) - { - std::cerr << "Error reading 'test_image.pic'. No image created." << std::endl; - ++numberFailed; - continue; - } - - std::remove("test_image.pic"); - - // compare - - bool identical(false); - AccessFixedDimensionByItk_2(secondImage.GetPointer(), ItkImageProcessing, 3, originalImage.GetPointer(), identical); - - if (!identical) - { - std::cerr << "Images differ for testimage " << i << std::endl; - ++numberFailed; - continue; - } - } - - // if one fails, whole test fails - if (numberFailed > 0) - { - std::cout << "[FAILED]: " << numberFailed << " of " << numberOfTestImages << " sub-tests failed." << std::endl; - return EXIT_FAILURE; - } - else - { - std::cout << "[PASSED]" << std::endl; - return EXIT_SUCCESS; - } -} diff --git a/Modules/IpPicSupportIO/Testing/mitkPicFileReaderTest.cpp b/Modules/IpPicSupportIO/Testing/mitkPicFileReaderTest.cpp deleted file mode 100644 index b01188d57d..0000000000 --- a/Modules/IpPicSupportIO/Testing/mitkPicFileReaderTest.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkTestingMacros.h" - -#include "mitkImage.h" -#include "mitkPicFileReader.h" -#include "mitkPicHelper.h" -#include "mitkSlicedGeometry3D.h" -#include <itkImageFileReader.h> -#include <itksys/SystemTools.hxx> -#include <mitkTimeGeometry.h> - -#include <fstream> -int mitkPicFileReaderTest(int argc, char *argv[]) -{ - MITK_TEST_BEGIN(mitkPicFileReaderTest) - - if (argc >= 1) - { - if (itksys::SystemTools::FileLength(argv[1]) == 0) - { - mitk::PicFileReader::Pointer emptyFileReader = mitk::PicFileReader::New(); - emptyFileReader->SetFileName(argv[1]); - MITK_TEST_FOR_EXCEPTION(itk::ImageFileReaderException, emptyFileReader->Update()); - } - else - { - // independently read header of pic file - mitkIpPicDescriptor *picheader = nullptr; - if (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameExtension(argv[1])).find(".pic") != - std::string::npos) - { - picheader = mitkIpPicGetHeader(argv[1], nullptr); - } - if (picheader == nullptr) - { - std::cout << "file not found/not a pic-file - test not applied [PASSED]" << std::endl; - std::cout << "[TEST DONE]" << std::endl; - return EXIT_SUCCESS; - } - mitkIpPicGetTags(argv[1], picheader); - - // Read pic-Image from file - mitk::PicFileReader::Pointer reader = mitk::PicFileReader::New(); - reader->SetFileName(argv[1]); - reader->Update(); - - std::cout << "Testing IsInitialized(): "; - if (reader->GetOutput()->IsInitialized() == false) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing IsSliceSet(): "; - if (reader->GetOutput()->IsSliceSet(0) == false) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing availability of geometry: "; - if (reader->GetOutput()->GetGeometry() == nullptr) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing type of geometry (TimeGeometry expected): "; - mitk::TimeGeometry *timeGeometry; - timeGeometry = reader->GetOutput()->GetTimeGeometry(); - if (timeGeometry == nullptr) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing availability of first geometry contained in the TimeGeometry: "; - if (timeGeometry->GetGeometryForTimeStep(0).IsNull()) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing type of first geometry contained in the TimeGeometry (SlicedGeometry3D expected): "; - mitk::SlicedGeometry3D *slicedgeometry; - slicedgeometry = dynamic_cast<mitk::SlicedGeometry3D *>(timeGeometry->GetGeometryForTimeStep(0).GetPointer()); - if (slicedgeometry == nullptr) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing availability of first geometry contained in the SlicedGeometry3D: "; - mitk::Geometry2D *geometry2d = slicedgeometry->GetGeometry2D(0); - if (geometry2d == nullptr) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing extent in units of first geometry contained in the SlicedGeometry3D: "; - if ((fabs(geometry2d->GetExtent(0) - picheader->n[0]) > mitk::eps) || - (fabs(geometry2d->GetExtent(1) - picheader->n[1]) > mitk::eps)) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing extent in units of image of SlicedGeometry3D: "; - if ((fabs(slicedgeometry->GetExtent(0) - picheader->n[0]) > mitk::eps) || - (fabs(slicedgeometry->GetExtent(1) - picheader->n[1]) > mitk::eps) || - (picheader->dim > 2 && (fabs(slicedgeometry->GetExtent(2) - picheader->n[2]) > mitk::eps))) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - std::cout << "Testing consistency of spacing from matrix and stored spacing in the first SlicedGeometry3D: "; - mitk::Vector3D spacing; - spacing[0] = slicedgeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0).two_norm(); - spacing[1] = slicedgeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1).two_norm(); - spacing[2] = slicedgeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2).two_norm(); - mitk::Vector3D readspacing = slicedgeometry->GetSpacing(); - mitk::Vector3D dist = spacing - readspacing; - if (dist.GetSquaredNorm() > mitk::eps) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - // independently read the overall spacing - spacing.Fill(1); - mitk::PicHelper::GetSpacing(picheader, spacing); - - std::cout << "Testing correct reading of overall spacing stored in the first SlicedGeometry3D: "; - dist = spacing - readspacing; - if (dist.GetSquaredNorm() > mitk::eps) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - - if (picheader->dim == 4) - { - std::cout << "4D dataset: Testing that timebounds are not infinite: "; - if ((slicedgeometry->GetTimeBounds()[0] == itk::NumericTraits<mitk::ScalarType>::NonpositiveMin()) && - (slicedgeometry->GetTimeBounds()[1] == itk::NumericTraits<mitk::ScalarType>::max())) - { - std::cout << "[FAILED]" << std::endl; - return EXIT_FAILURE; - } - std::cout << "[PASSED]" << std::endl; - } - - mitkIpPicFree(picheader); - } - } - - MITK_TEST_END(); -} diff --git a/Modules/IpPicSupportIO/files.cmake b/Modules/IpPicSupportIO/files.cmake deleted file mode 100644 index 828edcafa3..0000000000 --- a/Modules/IpPicSupportIO/files.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(CPP_FILES - Internal/mitkIpPicSupportIOActivator.cpp - Internal/mitkPicFileReader.cpp - Internal/mitkPicHelper.cpp -) diff --git a/Modules/LegacyIO/mitkImageWriter.cpp b/Modules/LegacyIO/mitkImageWriter.cpp index 1b80e14b55..3405fbb559 100644 --- a/Modules/LegacyIO/mitkImageWriter.cpp +++ b/Modules/LegacyIO/mitkImageWriter.cpp @@ -1,476 +1,458 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkImageWriter.h" #include "mitkImage.h" #include "mitkImageAccessByItk.h" #include "mitkImageReadAccessor.h" #include "mitkImageTimeSelector.h" #include "mitkItkPictureWrite.h" #include <mitkLocaleSwitch.h> #include <itkImageIOBase.h> #include <itkImageIOFactory.h> mitk::ImageWriter::ImageWriter() : m_UseCompression(true) { this->SetNumberOfRequiredInputs(1); m_MimeType = ""; SetDefaultExtension(); } mitk::ImageWriter::~ImageWriter() { } void mitk::ImageWriter::SetFileName(const char *fileName) { if (fileName && (fileName == this->m_FileName)) { return; } if (fileName) { this->m_FileName = fileName; this->m_FileNameWithoutExtension = this->m_FileName; this->m_Extension.clear(); std::size_t pos = this->m_FileName.find_last_of("/\\"); if (pos != std::string::npos) { std::size_t ppos = this->m_FileName.find_first_of('.', pos); if (ppos != std::string::npos) { this->m_FileNameWithoutExtension = this->m_FileName.substr(0, ppos); this->m_Extension = this->m_FileName.substr(ppos); } } } else { this->m_FileName.clear(); this->m_FileNameWithoutExtension.clear(); this->m_Extension.clear(); } this->Modified(); } void mitk::ImageWriter::SetFileName(const std::string &fileName) { this->SetFileName(fileName.c_str()); } void mitk::ImageWriter::SetExtension(const char *extension) { if (extension && (extension == this->m_Extension)) { return; } if (extension) { this->m_Extension = extension; this->m_FileName = this->m_FileNameWithoutExtension + this->m_Extension; } else { this->m_Extension.clear(); this->m_FileName = this->m_FileNameWithoutExtension; } this->Modified(); } void mitk::ImageWriter::SetExtension(const std::string &extension) { this->SetFileName(extension.c_str()); } void mitk::ImageWriter::SetDefaultExtension() { this->m_Extension = ".mhd"; this->m_FileName = this->m_FileNameWithoutExtension + this->m_Extension; this->Modified(); } #include <vtkConfigure.h> #include <vtkImageData.h> #include <vtkXMLImageDataWriter.h> static void writeVti(const char *filename, mitk::Image *image, int t = 0) { vtkXMLImageDataWriter *vtkwriter = vtkXMLImageDataWriter::New(); vtkwriter->SetFileName(filename); vtkwriter->SetInputData(image->GetVtkImageData(t)); vtkwriter->Write(); vtkwriter->Delete(); } #include <itkRGBAPixel.h> void mitk::ImageWriter::WriteByITK(mitk::Image *image, const std::string &fileName) { MITK_INFO << "Writing image: " << fileName << std::endl; // Pictures and picture series like .png are written via a different mechanism then volume images. // So, they are still multiplexed and thus not support vector images. if (fileName.find(".png") != std::string::npos || fileName.find(".tif") != std::string::npos || fileName.find(".jpg") != std::string::npos || fileName.find(".bmp") != std::string::npos) { try { // switch processing of single/multi-component images if (image->GetPixelType(0).GetNumberOfComponents() == 1) { AccessByItk_1(image, _mitkItkPictureWrite, fileName); } else { AccessFixedPixelTypeByItk_1(image, _mitkItkPictureWriteComposite, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES_SEQ, fileName); } } catch (itk::ExceptionObject &e) { std::cerr << "Caught " << e.what() << std::endl; } catch (std::exception &e) { std::cerr << "Caught std::exception " << e.what() << std::endl; } return; } // Implementation of writer using itkImageIO directly. This skips the use // of templated itkImageFileWriter, which saves the multiplexing on MITK side. unsigned int dimension = image->GetDimension(); unsigned int *dimensions = image->GetDimensions(); mitk::PixelType pixelType = image->GetPixelType(); mitk::Vector3D mitkSpacing = image->GetGeometry()->GetSpacing(); mitk::Point3D mitkOrigin = image->GetGeometry()->GetOrigin(); // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin, though they are not supported in MITK itk::Vector<double, 4u> spacing4D; spacing4D[0] = mitkSpacing[0]; spacing4D[1] = mitkSpacing[1]; spacing4D[2] = mitkSpacing[2]; spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have an valid value here itk::Vector<double, 4u> origin4D; origin4D[0] = mitkOrigin[0]; origin4D[1] = mitkOrigin[1]; origin4D[2] = mitkOrigin[2]; origin4D[3] = 0; // There is no support for a 4D origin. However, we should have an valid value here itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(fileName.c_str(), itk::ImageIOFactory::WriteMode); if (imageIO.IsNull()) { itkExceptionMacro(<< "Error: Could not create itkImageIO via factory for file " << fileName); } // Set the necessary information for imageIO imageIO->SetNumberOfDimensions(dimension); imageIO->SetPixelType(pixelType.GetPixelType()); imageIO->SetComponentType(pixelType.GetComponentType() < PixelComponentUserType ? static_cast<itk::ImageIOBase::IOComponentType>(pixelType.GetComponentType()) : itk::ImageIOBase::UNKNOWNCOMPONENTTYPE); imageIO->SetNumberOfComponents(pixelType.GetNumberOfComponents()); itk::ImageIORegion ioRegion(dimension); for (unsigned int i = 0; i < dimension; i++) { imageIO->SetDimensions(i, dimensions[i]); imageIO->SetSpacing(i, spacing4D[i]); imageIO->SetOrigin(i, origin4D[i]); mitk::Vector3D mitkDirection; mitkDirection.SetVnlVector( image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i)); itk::Vector<double, 4u> direction4D; direction4D[0] = mitkDirection[0]; direction4D[1] = mitkDirection[1]; direction4D[2] = mitkDirection[2]; // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix. if (i == 3) direction4D[3] = 1; // homogenous component else direction4D[3] = 0; vnl_vector<double> axisDirection(dimension); for (unsigned int j = 0; j < dimension; j++) { axisDirection[j] = direction4D[j] / spacing4D[i]; } imageIO->SetDirection(i, axisDirection); ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i)); ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i)); } // use compression if available imageIO->SetUseCompression(m_UseCompression); imageIO->SetIORegion(ioRegion); imageIO->SetFileName(fileName); ImageReadAccessor imageAccess(image); imageIO->Write(imageAccess.GetData()); } void mitk::ImageWriter::GenerateData() { mitk::LocaleSwitch localeSwitch("C"); if (m_FileName == "") { itkWarningMacro(<< "Sorry, filename has not been set!"); return; } FILE *tempFile = fopen(m_FileName.c_str(), "w"); if (tempFile == nullptr) { itkExceptionMacro(<< "File location not writeable"); return; } fclose(tempFile); remove(m_FileName.c_str()); // Creating clone of input image, since i might change the geometry mitk::Image::Pointer input = this->GetInput()->Clone(); // Check if geometry information will be lost if (input->GetDimension() == 2) { if (!input->GetGeometry()->Is2DConvertable()) { MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might " "consider using Convert2Dto3DImageFilter before saving."; // set matrix to identity mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New(); affTrans->SetIdentity(); mitk::Vector3D spacing = input->GetGeometry()->GetSpacing(); mitk::Point3D origin = input->GetGeometry()->GetOrigin(); input->GetGeometry()->SetIndexToWorldTransform(affTrans); input->GetGeometry()->SetSpacing(spacing); input->GetGeometry()->SetOrigin(origin); } } bool vti = (m_Extension.find(".vti") != std::string::npos); - // If the extension is NOT .pic and NOT .nrrd and NOT .nii and NOT .nii.gz the following block is entered - if (m_Extension.find(".pic") == std::string::npos && m_Extension.find(".nrrd") == std::string::npos && - m_Extension.find(".nii") == std::string::npos && m_Extension.find(".nii.gz") == std::string::npos) + // If the extension is NOT .nrrd and NOT .nii and NOT .nii.gz the following block is entered + if (m_Extension.find(".nrrd") == std::string::npos && + m_Extension.find(".nii") == std::string::npos && + m_Extension.find(".nii.gz") == std::string::npos) { if (input->GetDimension() > 3) { int t, timesteps; timesteps = input->GetDimension(3); ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New(); timeSelector->SetInput(input); mitk::Image::Pointer image = timeSelector->GetOutput(); for (t = 0; t < timesteps; ++t) { std::ostringstream filename; timeSelector->SetTimeNr(t); timeSelector->Update(); if (input->GetTimeGeometry()->IsValidTimeStep(t)) { const mitk::TimeBounds timebounds = input->GetTimeGeometry()->GetTimeBounds(t); filename << m_FileNameWithoutExtension << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << m_Extension; } else { itkWarningMacro(<< "Error on write: TimeGeometry invalid of image " << filename.str() << "."); filename << m_FileNameWithoutExtension << "_T" << t << m_Extension; } if (vti) { writeVti(filename.str().c_str(), input, t); } else { WriteByITK(image, filename.str()); } } } else if (vti) { writeVti(m_FileName.c_str(), input); } else { WriteByITK(input, m_FileName); } } else { - // use the PicFileWriter for the .pic data type - if (m_Extension.find(".pic") != std::string::npos) + if (m_Extension.find(".nrrd") != std::string::npos || + m_Extension.find(".nii") != std::string::npos || + m_Extension.find(".nii.gz") != std::string::npos) { - /* PicFileWriter::Pointer picWriter = PicFileWriter::New(); - size_t found; - found = m_FileName.find( m_Extension ); // !!! HAS to be at the very end of the filename (not somewhere in the middle) - if( m_FileName.length() > 3 && found != m_FileName.length() - 4 ) - { - //if Extension not in Filename - std::ostringstream filename; - filename << m_FileName.c_str() << m_Extension; - picWriter->SetFileName( filename.str().c_str() ); - } - else - { - picWriter->SetFileName( m_FileName.c_str() ); - } - picWriter->SetInputImage( input ); - picWriter->Write(); - */ } - - // use the ITK .nrrd Image writer - if (m_Extension.find(".nrrd") != std::string::npos || m_Extension.find(".nii") != std::string::npos || - m_Extension.find(".nii.gz") != std::string::npos) - { - WriteByITK(input, this->m_FileName); - } + WriteByITK(input, this->m_FileName); + } + else + { + itkExceptionMacro(<< "File type not writeable"); + } } m_MimeType = "application/MITK.Pic"; } bool mitk::ImageWriter::CanWriteDataType(DataNode *input) { if (input) { return this->CanWriteBaseDataType(input->GetData()); } return false; } void mitk::ImageWriter::SetInput(DataNode *input) { if (input && CanWriteDataType(input)) this->ProcessObject::SetNthInput(0, dynamic_cast<mitk::Image *>(input->GetData())); } std::string mitk::ImageWriter::GetWritenMIMEType() { return m_MimeType; } std::vector<std::string> mitk::ImageWriter::GetPossibleFileExtensions() { std::vector<std::string> possibleFileExtensions; - possibleFileExtensions.push_back(".pic"); - possibleFileExtensions.push_back(".pic.gz"); possibleFileExtensions.push_back(".bmp"); possibleFileExtensions.push_back(".dcm"); possibleFileExtensions.push_back(".DCM"); possibleFileExtensions.push_back(".dicom"); possibleFileExtensions.push_back(".DICOM"); possibleFileExtensions.push_back(".gipl"); possibleFileExtensions.push_back(".gipl.gz"); possibleFileExtensions.push_back(".mha"); possibleFileExtensions.push_back(".nii"); possibleFileExtensions.push_back(".nii.gz"); possibleFileExtensions.push_back(".nrrd"); possibleFileExtensions.push_back(".nhdr"); possibleFileExtensions.push_back(".png"); possibleFileExtensions.push_back(".PNG"); possibleFileExtensions.push_back(".spr"); possibleFileExtensions.push_back(".mhd"); possibleFileExtensions.push_back(".vtk"); possibleFileExtensions.push_back(".vti"); possibleFileExtensions.push_back(".hdr"); possibleFileExtensions.push_back(".img"); possibleFileExtensions.push_back(".img.gz"); possibleFileExtensions.push_back(".png"); possibleFileExtensions.push_back(".tif"); possibleFileExtensions.push_back(".jpg"); return possibleFileExtensions; } std::string mitk::ImageWriter::GetSupportedBaseData() const { return Image::GetStaticNameOfClass(); } std::string mitk::ImageWriter::GetFileExtension() { return m_Extension; } void mitk::ImageWriter::SetInput(mitk::Image *image) { this->ProcessObject::SetNthInput(0, image); } const mitk::Image *mitk::ImageWriter::GetInput() { if (this->GetNumberOfInputs() < 1) { return nullptr; } else { return static_cast<const mitk::Image *>(this->ProcessObject::GetInput(0)); } } const char *mitk::ImageWriter::GetDefaultFilename() { return "Image.nrrd"; } const char *mitk::ImageWriter::GetFileDialogPattern() { return "Nearly Raw Raster Data (*.nrrd);;" "NIfTI format (*.nii *.nii.gz);;" "VTK Image Data Files (*.vti);;" "NRRD with detached header (*.nhdr);;" "Analyze Format (*.hdr);;" "MetaImage (*.mhd);;" "Sets of 2D slices (*.png *.tiff *.jpg *.jpeg *.bmp);;" "DICOM (*.dcm *.DCM *.dicom *.DICOM);;" "UMDS GIPL Format Files (*.gipl *.gipl.gz)"; } const char *mitk::ImageWriter::GetDefaultExtension() { return ".nrrd"; } bool mitk::ImageWriter::CanWriteBaseDataType(BaseData::Pointer data) { return dynamic_cast<mitk::Image *>(data.GetPointer()); } void mitk::ImageWriter::DoWrite(BaseData::Pointer data) { if (this->CanWriteBaseDataType(data)) { this->SetInput(dynamic_cast<mitk::Image *>(data.GetPointer())); this->Update(); } } void mitk::ImageWriter::SetUseCompression(bool useCompression) { m_UseCompression = useCompression; } diff --git a/Modules/LegacyIO/mitkImageWriter.h b/Modules/LegacyIO/mitkImageWriter.h index 67033cd7c9..1d9a7b9ea4 100644 --- a/Modules/LegacyIO/mitkImageWriter.h +++ b/Modules/LegacyIO/mitkImageWriter.h @@ -1,171 +1,171 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef _MITK_IMAGE_WRITER__H_ #define _MITK_IMAGE_WRITER__H_ #include <MitkLegacyIOExports.h> #include <mitkFileWriterWithInformation.h> namespace mitk { class Image; /** * @brief Writer for mitk::Image * * Uses the given extension (SetExtension) to decide the format to write - * (.mhd is default, .pic, .tif, .png, .jpg supported yet). + * (.mhd is default, .tif, .png, .jpg supported yet). * @ingroup MitkLegacyIOModule * @deprecatedSince{2014_10} Use mitk::IOUtils or mitk::FileWriterRegistry instead. */ class MITKLEGACYIO_EXPORT ImageWriter : public mitk::FileWriterWithInformation { public: mitkClassMacro(ImageWriter, mitk::FileWriter); itkFactorylessNewMacro(Self); itkCloneMacro(Self); mitkWriterMacro; /** * Sets the filename of the file to write. * @param fileName the name of the file to write. */ void SetFileName(const char *fileName) override; virtual void SetFileName(const std::string &fileName); /** * @returns the name of the file to be written to disk. */ itkGetStringMacro(FileName); /** * \brief Explicitly set the extension to be added to the filename. * @param extension Extension to be added to the filename, including a "." * (e.g., ".mhd"). */ virtual void SetExtension(const char *extension); virtual void SetExtension(const std::string &extension); /** * \brief Get the extension to be added to the filename. * @returns the extension to be added to the filename (e.g., * ".mhd"). */ itkGetStringMacro(Extension); /** * \brief Set the extension to be added to the filename to the default */ void SetDefaultExtension(); /** * @warning multiple write not (yet) supported */ itkSetStringMacro(FilePrefix); /** * @warning multiple write not (yet) supported */ itkGetStringMacro(FilePrefix); /** * @warning multiple write not (yet) supported */ itkSetStringMacro(FilePattern); /** * @warning multiple write not (yet) supported */ itkGetStringMacro(FilePattern); /** * Sets the 0'th input object for the filter. * @param input the first input for the filter. */ void SetInput(mitk::Image *input); //##Documentation //## @brief Return the possible file extensions for the data type associated with the writer std::vector<std::string> GetPossibleFileExtensions() override; std::string GetSupportedBaseData() const override; /** * @brief Return the extension to be added to the filename. */ std::string GetFileExtension() override; /** * @brief Check if the Writer can write the Content of the */ bool CanWriteDataType(DataNode *) override; /** * @brief Return the MimeType of the saved File. */ std::string GetWritenMIMEType() override; using Superclass::SetInput; /** * @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function. */ virtual void SetInput(DataNode *); /** * @returns the 0'th input object of the filter. */ const mitk::Image *GetInput(); // FileWriterWithInformation methods const char *GetDefaultFilename() override; const char *GetFileDialogPattern() override; const char *GetDefaultExtension() override; bool CanWriteBaseDataType(BaseData::Pointer data) override; void DoWrite(BaseData::Pointer data) override; void SetUseCompression(bool useCompression); protected: /** * Constructor. */ ImageWriter(); /** * Virtual destructor. */ ~ImageWriter() override; void GenerateData() override; virtual void WriteByITK(mitk::Image *image, const std::string &fileName); std::string m_FileName; std::string m_FileNameWithoutExtension; std::string m_FilePrefix; std::string m_FilePattern; std::string m_Extension; std::string m_MimeType; bool m_UseCompression; }; } #endif //_MITK_IMAGE_WRITER__H_ diff --git a/Modules/MapperExt/src/mitkVolumeMapperVtkSmart3D.cpp b/Modules/MapperExt/src/mitkVolumeMapperVtkSmart3D.cpp index ee9a32ef57..03cd67e759 100644 --- a/Modules/MapperExt/src/mitkVolumeMapperVtkSmart3D.cpp +++ b/Modules/MapperExt/src/mitkVolumeMapperVtkSmart3D.cpp @@ -1,237 +1,236 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkVolumeMapperVtkSmart3D.h" #include "mitkTransferFunctionProperty.h" #include "mitkTransferFunctionInitializer.h" #include "mitkLevelWindowProperty.h" #include <vtkObjectFactory.h> #include <vtkColorTransferFunction.h> #include <vtkPiecewiseFunction.h> #include <vtkAutoInit.h> void mitk::VolumeMapperVtkSmart3D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) { bool value; this->GetDataNode()->GetBoolProperty("volumerendering", value, renderer); if (!value) { m_Volume->VisibilityOff(); return; } else { + createMapper(GetInputImage()); m_Volume->VisibilityOn(); } UpdateTransferFunctions(renderer); UpdateRenderMode(renderer); this->Modified(); } vtkProp* mitk::VolumeMapperVtkSmart3D::GetVtkProp(mitk::BaseRenderer *) { if (!m_Volume->GetMapper()) { createMapper(GetInputImage()); createVolume(); createVolumeProperty(); } return m_Volume; } void mitk::VolumeMapperVtkSmart3D::ApplyProperties(vtkActor *, mitk::BaseRenderer *) { } void mitk::VolumeMapperVtkSmart3D::SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer, bool overwrite) { // GPU_INFO << "SetDefaultProperties"; node->AddProperty("volumerendering", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.usemip", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.cpu.ambient", mitk::FloatProperty::New(0.10f), renderer, overwrite); node->AddProperty("volumerendering.cpu.diffuse", mitk::FloatProperty::New(0.50f), renderer, overwrite); node->AddProperty("volumerendering.cpu.specular", mitk::FloatProperty::New(0.40f), renderer, overwrite); node->AddProperty("volumerendering.cpu.specular.power", mitk::FloatProperty::New(16.0f), renderer, overwrite); node->AddProperty("volumerendering.usegpu", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.useray", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.gpu.ambient", mitk::FloatProperty::New(0.25f), renderer, overwrite); node->AddProperty("volumerendering.gpu.diffuse", mitk::FloatProperty::New(0.50f), renderer, overwrite); node->AddProperty("volumerendering.gpu.specular", mitk::FloatProperty::New(0.40f), renderer, overwrite); node->AddProperty("volumerendering.gpu.specular.power", mitk::FloatProperty::New(16.0f), renderer, overwrite); node->AddProperty("binary", mitk::BoolProperty::New(false), renderer, overwrite); mitk::Image::Pointer image = dynamic_cast<mitk::Image *>(node->GetData()); if (image.IsNotNull() && image->IsInitialized()) { if ((overwrite) || (node->GetProperty("TransferFunction", renderer) == nullptr)) { // add a default transfer function mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(tf); tfInit->SetTransferFunctionMode(0); node->SetProperty("TransferFunction", mitk::TransferFunctionProperty::New(tf.GetPointer())); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } vtkImageData* mitk::VolumeMapperVtkSmart3D::GetInputImage() { auto input = dynamic_cast<mitk::Image*>(this->GetDataNode()->GetData()); return input->GetVtkImageData(this->GetTimestep()); } void mitk::VolumeMapperVtkSmart3D::createMapper(vtkImageData* imageData) { Vector3D spacing; FillVector3D(spacing, 1.0, 1.0, 1.0); m_ImageChangeInformation->SetInputData(imageData); m_ImageChangeInformation->SetOutputSpacing(spacing.GetDataPointer()); m_SmartVolumeMapper->SetBlendModeToComposite(); m_SmartVolumeMapper->SetInputConnection(m_ImageChangeInformation->GetOutputPort()); } void mitk::VolumeMapperVtkSmart3D::createVolume() { - m_Volume->VisibilityOff(); m_Volume->SetMapper(m_SmartVolumeMapper); m_Volume->SetProperty(m_VolumeProperty); } void mitk::VolumeMapperVtkSmart3D::createVolumeProperty() { m_VolumeProperty->ShadeOn(); m_VolumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION); } void mitk::VolumeMapperVtkSmart3D::UpdateTransferFunctions(mitk::BaseRenderer *renderer) { vtkSmartPointer<vtkPiecewiseFunction> opacityTransferFunction; vtkSmartPointer<vtkPiecewiseFunction> gradientTransferFunction; vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction; bool isBinary = false; this->GetDataNode()->GetBoolProperty("binary", isBinary, renderer); if (isBinary) { colorTransferFunction = vtkSmartPointer<vtkColorTransferFunction>::New(); float rgb[3]; if (!GetDataNode()->GetColor(rgb, renderer)) rgb[0] = rgb[1] = rgb[2] = 1; colorTransferFunction->AddRGBPoint(0, rgb[0], rgb[1], rgb[2]); colorTransferFunction->Modified(); opacityTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New(); gradientTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New(); } else { auto *transferFunctionProp = dynamic_cast<mitk::TransferFunctionProperty *>(this->GetDataNode()->GetProperty("TransferFunction", renderer)); if (transferFunctionProp) { opacityTransferFunction = transferFunctionProp->GetValue()->GetScalarOpacityFunction(); gradientTransferFunction = transferFunctionProp->GetValue()->GetGradientOpacityFunction(); colorTransferFunction = transferFunctionProp->GetValue()->GetColorTransferFunction(); } else { opacityTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New(); gradientTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New(); colorTransferFunction = vtkSmartPointer<vtkColorTransferFunction>::New(); } } - m_VolumeProperty->SetColor(colorTransferFunction); m_VolumeProperty->SetScalarOpacity(opacityTransferFunction); m_VolumeProperty->SetGradientOpacity(gradientTransferFunction); } void mitk::VolumeMapperVtkSmart3D::UpdateRenderMode(mitk::BaseRenderer *renderer) { bool usegpu = false; bool useray = false; bool usemip = false; this->GetDataNode()->GetBoolProperty("volumerendering.usegpu", usegpu); this->GetDataNode()->GetBoolProperty("volumerendering.useray", useray); this->GetDataNode()->GetBoolProperty("volumerendering.usemip", usemip); if (usegpu) m_SmartVolumeMapper->SetRequestedRenderModeToGPU(); else if (useray) m_SmartVolumeMapper->SetRequestedRenderModeToRayCast(); else m_SmartVolumeMapper->SetRequestedRenderModeToDefault(); int blendMode; if (this->GetDataNode()->GetIntProperty("volumerendering.blendmode", blendMode)) m_SmartVolumeMapper->SetBlendMode(blendMode); else if (usemip) m_SmartVolumeMapper->SetBlendMode(vtkSmartVolumeMapper::MAXIMUM_INTENSITY_BLEND); // shading parameter if (m_SmartVolumeMapper->GetRequestedRenderMode() == vtkSmartVolumeMapper::GPURenderMode) { float value = 0; if (this->GetDataNode()->GetFloatProperty("volumerendering.gpu.ambient", value, renderer)) m_VolumeProperty->SetAmbient(value); if (this->GetDataNode()->GetFloatProperty("volumerendering.gpu.diffuse", value, renderer)) m_VolumeProperty->SetDiffuse(value); if (this->GetDataNode()->GetFloatProperty("volumerendering.gpu.specular", value, renderer)) m_VolumeProperty->SetSpecular(value); if (this->GetDataNode()->GetFloatProperty("volumerendering.gpu.specular.power", value, renderer)) m_VolumeProperty->SetSpecularPower(value); } else { float value = 0; if (this->GetDataNode()->GetFloatProperty("volumerendering.cpu.ambient", value, renderer)) m_VolumeProperty->SetAmbient(value); if (this->GetDataNode()->GetFloatProperty("volumerendering.cpu.diffuse", value, renderer)) m_VolumeProperty->SetDiffuse(value); if (this->GetDataNode()->GetFloatProperty("volumerendering.cpu.specular", value, renderer)) m_VolumeProperty->SetSpecular(value); if (this->GetDataNode()->GetFloatProperty("volumerendering.cpu.specular.power", value, renderer)) m_VolumeProperty->SetSpecularPower(value); } } mitk::VolumeMapperVtkSmart3D::VolumeMapperVtkSmart3D() { m_SmartVolumeMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New(); m_SmartVolumeMapper->SetBlendModeToComposite(); m_ImageChangeInformation = vtkSmartPointer<vtkImageChangeInformation>::New(); m_VolumeProperty = vtkSmartPointer<vtkVolumeProperty>::New(); m_Volume = vtkSmartPointer<vtkVolume>::New(); } mitk::VolumeMapperVtkSmart3D::~VolumeMapperVtkSmart3D() { } diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index c36c213269..641e2370b6 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,81 +1,77 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(MITK_MODULES Core CommandLine CoreCmdApps AppUtil LegacyIO DataTypesExt Annotation LegacyGL AlgorithmsExt MapperExt DICOM DICOMQI DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction SceneSerialization Gizmo GraphAlgorithms Multilabel Chart ImageStatistics ContourModel SurfaceInterpolation Segmentation QtWidgets QtWidgetsExt ImageStatisticsUI SegmentationUI MatchPointRegistration MatchPointRegistrationUI Classification OpenIGTLink IGTBase IGT CameraCalibration OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI US USUI DICOMUI Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI RT RTUI IOExt XNAT TubeGraph BoundingShape RenderWindowManager RenderWindowManagerUI SemanticRelations SemanticRelationsUI CEST BasicImageProcessing ModelFit ModelFitUI Pharmacokinetics PharmacokineticsUI DICOMPM REST RESTService DICOMweb ) - -if(MITK_ENABLE_PIC_READER) - list(APPEND MITK_MODULES IpPicSupportIO) -endif() diff --git a/Modules/Multilabel/mitkLabelSetImage.cpp b/Modules/Multilabel/mitkLabelSetImage.cpp index 8ebc7838fb..9b4253fc63 100644 --- a/Modules/Multilabel/mitkLabelSetImage.cpp +++ b/Modules/Multilabel/mitkLabelSetImage.cpp @@ -1,1012 +1,1026 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkLabelSetImage.h" #include "mitkImageAccessByItk.h" #include "mitkImageCast.h" #include "mitkImagePixelReadAccessor.h" #include "mitkImagePixelWriteAccessor.h" #include "mitkInteractionConst.h" #include "mitkLookupTableProperty.h" #include "mitkPadImageFilter.h" #include "mitkRenderingManager.h" #include "mitkDICOMSegmentationPropertyHelper.h" #include "mitkDICOMQIPropertyHelper.h" #include <vtkCell.h> #include <vtkTransform.h> #include <vtkTransformPolyDataFilter.h> #include <itkImageRegionIterator.h> #include <itkQuadEdgeMesh.h> #include <itkTriangleMeshToBinaryImageFilter.h> //#include <itkRelabelComponentImageFilter.h> #include <itkCommand.h> template <typename TPixel, unsigned int VDimensions> void SetToZero(itk::Image<TPixel, VDimensions> *source) { source->FillBuffer(0); } template <unsigned int VImageDimension = 3> void CreateLabelMaskProcessing(mitk::Image *layerImage, mitk::Image *mask, mitk::LabelSet::PixelType index) { mitk::ImagePixelReadAccessor<mitk::LabelSet::PixelType, VImageDimension> readAccessor(layerImage); mitk::ImagePixelWriteAccessor<mitk::LabelSet::PixelType, VImageDimension> writeAccessor(mask); std::size_t numberOfPixels = 1; for (int dim = 0; dim < static_cast<int>(VImageDimension); ++dim) numberOfPixels *= static_cast<std::size_t>(readAccessor.GetDimension(dim)); auto src = readAccessor.GetData(); auto dest = writeAccessor.GetData(); for (std::size_t i = 0; i < numberOfPixels; ++i) { if (index == *(src + i)) *(dest + i) = 1; } } mitk::LabelSetImage::LabelSetImage() : mitk::Image(), m_ActiveLayer(0), m_activeLayerInvalid(false), m_ExteriorLabel(nullptr) { // Iniitlaize Background Label mitk::Color color; color.Set(0, 0, 0); m_ExteriorLabel = mitk::Label::New(); m_ExteriorLabel->SetColor(color); m_ExteriorLabel->SetName("Exterior"); m_ExteriorLabel->SetOpacity(0.0); m_ExteriorLabel->SetLocked(false); m_ExteriorLabel->SetValue(0); // Add some DICOM Tags as properties to segmentation image DICOMSegmentationPropertyHelper::DeriveDICOMSegmentationProperties(this); } mitk::LabelSetImage::LabelSetImage(const mitk::LabelSetImage &other) : Image(other), m_ActiveLayer(other.GetActiveLayer()), m_activeLayerInvalid(false), m_ExteriorLabel(other.GetExteriorLabel()->Clone()) { for (unsigned int i = 0; i < other.GetNumberOfLayers(); i++) { // Clone LabelSet data mitk::LabelSet::Pointer lsClone = other.GetLabelSet(i)->Clone(); // add modified event listener to LabelSet (listen to LabelSet changes) itk::SimpleMemberCommand<Self>::Pointer command = itk::SimpleMemberCommand<Self>::New(); command->SetCallbackFunction(this, &mitk::LabelSetImage::OnLabelSetModified); lsClone->AddObserver(itk::ModifiedEvent(), command); m_LabelSetContainer.push_back(lsClone); // clone layer Image data mitk::Image::Pointer liClone = other.GetLayerImage(i)->Clone(); m_LayerContainer.push_back(liClone); } // Add some DICOM Tags as properties to segmentation image DICOMSegmentationPropertyHelper::DeriveDICOMSegmentationProperties(this); } void mitk::LabelSetImage::OnLabelSetModified() { Superclass::Modified(); } void mitk::LabelSetImage::SetExteriorLabel(mitk::Label *label) { m_ExteriorLabel = label; } mitk::Label *mitk::LabelSetImage::GetExteriorLabel() { return m_ExteriorLabel; } const mitk::Label *mitk::LabelSetImage::GetExteriorLabel() const { return m_ExteriorLabel; } void mitk::LabelSetImage::Initialize(const mitk::Image *other) { mitk::PixelType pixelType(mitk::MakeScalarPixelType<LabelSetImage::PixelType>()); if (other->GetDimension() == 2) { const unsigned int dimensions[] = {other->GetDimension(0), other->GetDimension(1), 1}; Superclass::Initialize(pixelType, 3, dimensions); } else { Superclass::Initialize(pixelType, other->GetDimension(), other->GetDimensions()); } auto originalGeometry = other->GetTimeGeometry()->Clone(); this->SetTimeGeometry(originalGeometry); // initialize image memory to zero if (4 == this->GetDimension()) { AccessFixedDimensionByItk(this, SetToZero, 4); } else { AccessByItk(this, SetToZero); } // Transfer some general DICOM properties from the source image to derived image (e.g. Patient information,...) DICOMQIPropertyHelper::DeriveDICOMSourceProperties(other, this); // Add a inital LabelSet ans corresponding image data to the stack AddLayer(); } mitk::LabelSetImage::~LabelSetImage() { m_LabelSetContainer.clear(); } mitk::Image *mitk::LabelSetImage::GetLayerImage(unsigned int layer) { return m_LayerContainer[layer]; } const mitk::Image *mitk::LabelSetImage::GetLayerImage(unsigned int layer) const { return m_LayerContainer[layer]; } unsigned int mitk::LabelSetImage::GetActiveLayer() const { return m_ActiveLayer; } unsigned int mitk::LabelSetImage::GetNumberOfLayers() const { return m_LabelSetContainer.size(); } void mitk::LabelSetImage::RemoveLayer() { int layerToDelete = GetActiveLayer(); // remove all observers from active label set GetLabelSet(layerToDelete)->RemoveAllObservers(); // set the active layer to one below, if exists. if (layerToDelete != 0) { SetActiveLayer(layerToDelete - 1); } else { // we are deleting layer zero, it should not be copied back into the vector m_activeLayerInvalid = true; } // remove labelset and image data m_LabelSetContainer.erase(m_LabelSetContainer.begin() + layerToDelete); m_LayerContainer.erase(m_LayerContainer.begin() + layerToDelete); if (layerToDelete == 0) { this->SetActiveLayer(layerToDelete); } this->Modified(); } unsigned int mitk::LabelSetImage::AddLayer(mitk::LabelSet::Pointer lset) { mitk::Image::Pointer newImage = mitk::Image::New(); newImage->Initialize(this->GetPixelType(), this->GetDimension(), this->GetDimensions(), this->GetImageDescriptor()->GetNumberOfChannels()); newImage->SetTimeGeometry(this->GetTimeGeometry()->Clone()); if (newImage->GetDimension() < 4) { AccessByItk(newImage, SetToZero); } else { AccessFixedDimensionByItk(newImage, SetToZero, 4); } unsigned int newLabelSetId = this->AddLayer(newImage, lset); return newLabelSetId; } unsigned int mitk::LabelSetImage::AddLayer(mitk::Image::Pointer layerImage, mitk::LabelSet::Pointer lset) { unsigned int newLabelSetId = m_LayerContainer.size(); // Add labelset to layer mitk::LabelSet::Pointer ls; if (lset.IsNotNull()) { ls = lset; } else { ls = mitk::LabelSet::New(); ls->AddLabel(GetExteriorLabel()); ls->SetActiveLabel(0 /*Exterior Label*/); } ls->SetLayer(newLabelSetId); // Add exterior Label to label set // mitk::Label::Pointer exteriorLabel = CreateExteriorLabel(); // push a new working image for the new layer m_LayerContainer.push_back(layerImage); // push a new labelset for the new layer m_LabelSetContainer.push_back(ls); // add modified event listener to LabelSet (listen to LabelSet changes) itk::SimpleMemberCommand<Self>::Pointer command = itk::SimpleMemberCommand<Self>::New(); command->SetCallbackFunction(this, &mitk::LabelSetImage::OnLabelSetModified); ls->AddObserver(itk::ModifiedEvent(), command); SetActiveLayer(newLabelSetId); // MITK_INFO << GetActiveLayer(); this->Modified(); return newLabelSetId; } void mitk::LabelSetImage::AddLabelSetToLayer(const unsigned int layerIdx, const mitk::LabelSet::Pointer labelSet) { if (m_LayerContainer.size() <= layerIdx) { mitkThrow() << "Trying to add labelSet to non-existing layer."; } if (layerIdx < m_LabelSetContainer.size()) { m_LabelSetContainer[layerIdx] = labelSet; } else { while (layerIdx >= m_LabelSetContainer.size()) { mitk::LabelSet::Pointer defaultLabelSet = mitk::LabelSet::New(); defaultLabelSet->AddLabel(GetExteriorLabel()); defaultLabelSet->SetActiveLabel(0 /*Exterior Label*/); defaultLabelSet->SetLayer(m_LabelSetContainer.size()); m_LabelSetContainer.push_back(defaultLabelSet); } m_LabelSetContainer.push_back(labelSet); } } void mitk::LabelSetImage::SetActiveLayer(unsigned int layer) { try { if (4 == this->GetDimension()) { if ((layer != GetActiveLayer() || m_activeLayerInvalid) && (layer < this->GetNumberOfLayers())) { BeforeChangeLayerEvent.Send(); if (m_activeLayerInvalid) { // We should not write the invalid layer back to the vector m_activeLayerInvalid = false; } else { AccessFixedDimensionByItk_n(this, ImageToLayerContainerProcessing, 4, (GetActiveLayer())); } m_ActiveLayer = layer; // only at this place m_ActiveLayer should be manipulated!!! Use Getter and Setter AccessFixedDimensionByItk_n(this, LayerContainerToImageProcessing, 4, (GetActiveLayer())); AfterChangeLayerEvent.Send(); } } else { if ((layer != GetActiveLayer() || m_activeLayerInvalid) && (layer < this->GetNumberOfLayers())) { BeforeChangeLayerEvent.Send(); if (m_activeLayerInvalid) { // We should not write the invalid layer back to the vector m_activeLayerInvalid = false; } else { AccessByItk_1(this, ImageToLayerContainerProcessing, GetActiveLayer()); } m_ActiveLayer = layer; // only at this place m_ActiveLayer should be manipulated!!! Use Getter and Setter AccessByItk_1(this, LayerContainerToImageProcessing, GetActiveLayer()); AfterChangeLayerEvent.Send(); } } } catch (itk::ExceptionObject &e) { mitkThrow() << e.GetDescription(); } this->Modified(); } void mitk::LabelSetImage::Concatenate(mitk::LabelSetImage *other) { const unsigned int *otherDims = other->GetDimensions(); const unsigned int *thisDims = this->GetDimensions(); if ((otherDims[0] != thisDims[0]) || (otherDims[1] != thisDims[1]) || (otherDims[2] != thisDims[2])) mitkThrow() << "Dimensions do not match."; try { int numberOfLayers = other->GetNumberOfLayers(); for (int layer = 0; layer < numberOfLayers; ++layer) { this->SetActiveLayer(layer); AccessByItk_1(this, ConcatenateProcessing, other); mitk::LabelSet *ls = other->GetLabelSet(layer); auto it = ls->IteratorConstBegin(); auto end = ls->IteratorConstEnd(); it++; // skip exterior while (it != end) { GetLabelSet()->AddLabel((it->second)); // AddLabelEvent.Send(); it++; } } } catch (itk::ExceptionObject &e) { mitkThrow() << e.GetDescription(); } this->Modified(); } void mitk::LabelSetImage::ClearBuffer() { try { - AccessByItk(this, ClearBufferProcessing); + if (this->GetDimension() == 4) + { //remark: this extra branch was added, because LabelSetImage instances can be + //dynamic (4D), but AccessByItk by support only supports 2D and 3D. + //The option to change the CMake default dimensions for AccessByItk was + //dropped (for details see discussion in T28756) + AccessFixedDimensionByItk(this, ClearBufferProcessing,4); + } + else + { + AccessByItk(this, ClearBufferProcessing); + } this->Modified(); } catch (itk::ExceptionObject &e) { mitkThrow() << e.GetDescription(); } } bool mitk::LabelSetImage::ExistLabel(PixelType pixelValue) const { bool exist = false; for (unsigned int lidx = 0; lidx < GetNumberOfLayers(); lidx++) exist |= m_LabelSetContainer[lidx]->ExistLabel(pixelValue); return exist; } bool mitk::LabelSetImage::ExistLabel(PixelType pixelValue, unsigned int layer) const { bool exist = m_LabelSetContainer[layer]->ExistLabel(pixelValue); return exist; } bool mitk::LabelSetImage::ExistLabelSet(unsigned int layer) const { return layer < m_LabelSetContainer.size(); } void mitk::LabelSetImage::MergeLabel(PixelType pixelValue, PixelType sourcePixelValue, unsigned int layer) { try { AccessByItk_2(this, MergeLabelProcessing, pixelValue, sourcePixelValue); } catch (itk::ExceptionObject &e) { mitkThrow() << e.GetDescription(); } GetLabelSet(layer)->SetActiveLabel(pixelValue); Modified(); } void mitk::LabelSetImage::MergeLabels(PixelType pixelValue, std::vector<PixelType>& vectorOfSourcePixelValues, unsigned int layer) { try { for (unsigned int idx = 0; idx < vectorOfSourcePixelValues.size(); idx++) { AccessByItk_2(this, MergeLabelProcessing, pixelValue, vectorOfSourcePixelValues[idx]); } } catch (itk::ExceptionObject &e) { mitkThrow() << e.GetDescription(); } GetLabelSet(layer)->SetActiveLabel(pixelValue); Modified(); } void mitk::LabelSetImage::RemoveLabels(std::vector<PixelType> &VectorOfLabelPixelValues, unsigned int layer) { for (unsigned int idx = 0; idx < VectorOfLabelPixelValues.size(); idx++) { GetLabelSet(layer)->RemoveLabel(VectorOfLabelPixelValues[idx]); EraseLabel(VectorOfLabelPixelValues[idx], layer); } } void mitk::LabelSetImage::EraseLabels(std::vector<PixelType> &VectorOfLabelPixelValues, unsigned int layer) { for (unsigned int i = 0; i < VectorOfLabelPixelValues.size(); i++) { this->EraseLabel(VectorOfLabelPixelValues[i], layer); } } void mitk::LabelSetImage::EraseLabel(PixelType pixelValue, unsigned int layer) { try { if (4 == this->GetDimension()) { AccessFixedDimensionByItk_2(this, EraseLabelProcessing, 4, pixelValue, layer); } else { AccessByItk_2(this, EraseLabelProcessing, pixelValue, layer); } } catch (const itk::ExceptionObject &e) { mitkThrow() << e.GetDescription(); } Modified(); } mitk::Label *mitk::LabelSetImage::GetActiveLabel(unsigned int layer) { if (m_LabelSetContainer.size() <= layer) return nullptr; else return m_LabelSetContainer[layer]->GetActiveLabel(); } const mitk::Label* mitk::LabelSetImage::GetActiveLabel(unsigned int layer) const { if (m_LabelSetContainer.size() <= layer) return nullptr; else return m_LabelSetContainer[layer]->GetActiveLabel(); } mitk::Label *mitk::LabelSetImage::GetLabel(PixelType pixelValue, unsigned int layer) const { if (m_LabelSetContainer.size() <= layer) return nullptr; else return m_LabelSetContainer[layer]->GetLabel(pixelValue); } mitk::LabelSet *mitk::LabelSetImage::GetLabelSet(unsigned int layer) { if (m_LabelSetContainer.size() <= layer) return nullptr; else return m_LabelSetContainer[layer].GetPointer(); } const mitk::LabelSet *mitk::LabelSetImage::GetLabelSet(unsigned int layer) const { if (m_LabelSetContainer.size() <= layer) return nullptr; else return m_LabelSetContainer[layer].GetPointer(); } mitk::LabelSet *mitk::LabelSetImage::GetActiveLabelSet() { if (m_LabelSetContainer.size() == 0) return nullptr; else return m_LabelSetContainer[GetActiveLayer()].GetPointer(); } const mitk::LabelSet* mitk::LabelSetImage::GetActiveLabelSet() const { if (m_LabelSetContainer.size() == 0) return nullptr; else return m_LabelSetContainer[GetActiveLayer()].GetPointer(); } void mitk::LabelSetImage::UpdateCenterOfMass(PixelType pixelValue, unsigned int layer) { if (4 == this->GetDimension()) { AccessFixedDimensionByItk_2(this, CalculateCenterOfMassProcessing, 4, pixelValue, layer); } else { AccessByItk_2(this, CalculateCenterOfMassProcessing, pixelValue, layer); } } unsigned int mitk::LabelSetImage::GetNumberOfLabels(unsigned int layer) const { return m_LabelSetContainer[layer]->GetNumberOfLabels(); } unsigned int mitk::LabelSetImage::GetTotalNumberOfLabels() const { unsigned int totalLabels(0); auto layerIter = m_LabelSetContainer.begin(); for (; layerIter != m_LabelSetContainer.end(); ++layerIter) totalLabels += (*layerIter)->GetNumberOfLabels(); return totalLabels; } void mitk::LabelSetImage::MaskStamp(mitk::Image *mask, bool forceOverwrite) { try { mitk::PadImageFilter::Pointer padImageFilter = mitk::PadImageFilter::New(); padImageFilter->SetInput(0, mask); padImageFilter->SetInput(1, this); padImageFilter->SetPadConstant(0); padImageFilter->SetBinaryFilter(false); padImageFilter->SetLowerThreshold(0); padImageFilter->SetUpperThreshold(1); padImageFilter->Update(); mitk::Image::Pointer paddedMask = padImageFilter->GetOutput(); if (paddedMask.IsNull()) return; AccessByItk_2(this, MaskStampProcessing, paddedMask, forceOverwrite); } catch (...) { mitkThrow() << "Could not stamp the provided mask on the selected label."; } } mitk::Image::Pointer mitk::LabelSetImage::CreateLabelMask(PixelType index, bool useActiveLayer, unsigned int layer) { auto previousActiveLayer = this->GetActiveLayer(); auto mask = mitk::Image::New(); try { - mask->Initialize(this); + // mask->Initialize(this) does not work here if this label set image has a single slice, + // since the mask would be automatically flattened to a 2-d image, whereas we expect the + // original dimension of this label set image. Hence, initialize the mask more explicitly: + mask->Initialize(this->GetPixelType(), this->GetDimension(), this->GetDimensions()); + mask->SetTimeGeometry(this->GetTimeGeometry()->Clone()); auto byteSize = sizeof(LabelSetImage::PixelType); for (unsigned int dim = 0; dim < mask->GetDimension(); ++dim) byteSize *= mask->GetDimension(dim); { ImageWriteAccessor accessor(mask); memset(accessor.GetData(), 0, byteSize); } if (!useActiveLayer) this->SetActiveLayer(layer); if (4 == this->GetDimension()) { ::CreateLabelMaskProcessing<4>(this, mask, index); } else if (3 == this->GetDimension()) { ::CreateLabelMaskProcessing(this, mask, index); } else { mitkThrow(); } } catch (...) { if (!useActiveLayer) this->SetActiveLayer(previousActiveLayer); mitkThrow() << "Could not create a mask out of the selected label."; } if (!useActiveLayer) this->SetActiveLayer(previousActiveLayer); return mask; } void mitk::LabelSetImage::InitializeByLabeledImage(mitk::Image::Pointer image) { if (image.IsNull() || image->IsEmpty() || !image->IsInitialized()) mitkThrow() << "Invalid labeled image."; try { this->Initialize(image); unsigned int byteSize = sizeof(LabelSetImage::PixelType); for (unsigned int dim = 0; dim < image->GetDimension(); ++dim) { byteSize *= image->GetDimension(dim); } mitk::ImageWriteAccessor *accessor = new mitk::ImageWriteAccessor(static_cast<mitk::Image *>(this)); memset(accessor->GetData(), 0, byteSize); delete accessor; auto geometry = image->GetTimeGeometry()->Clone(); this->SetTimeGeometry(geometry); if (image->GetDimension() == 3) { AccessTwoImagesFixedDimensionByItk(this, image, InitializeByLabeledImageProcessing, 3); } else if (image->GetDimension() == 4) { AccessTwoImagesFixedDimensionByItk(this, image, InitializeByLabeledImageProcessing, 4); } else { mitkThrow() << image->GetDimension() << "-dimensional label set images not yet supported"; } } catch (...) { mitkThrow() << "Could not intialize by provided labeled image."; } this->Modified(); } template <typename LabelSetImageType, typename ImageType> void mitk::LabelSetImage::InitializeByLabeledImageProcessing(LabelSetImageType *labelSetImage, ImageType *image) { typedef itk::ImageRegionConstIteratorWithIndex<ImageType> SourceIteratorType; typedef itk::ImageRegionIterator<LabelSetImageType> TargetIteratorType; TargetIteratorType targetIter(labelSetImage, labelSetImage->GetRequestedRegion()); targetIter.GoToBegin(); SourceIteratorType sourceIter(image, image->GetRequestedRegion()); sourceIter.GoToBegin(); while (!sourceIter.IsAtEnd()) { auto sourceValue = static_cast<PixelType>(sourceIter.Get()); targetIter.Set(sourceValue); if (!this->ExistLabel(sourceValue)) { std::stringstream name; name << "object-" << sourceValue; double rgba[4]; m_LabelSetContainer[this->GetActiveLayer()]->GetLookupTable()->GetTableValue(sourceValue, rgba); mitk::Color color; color.SetRed(rgba[0]); color.SetGreen(rgba[1]); color.SetBlue(rgba[2]); auto label = mitk::Label::New(); label->SetName(name.str().c_str()); label->SetColor(color); label->SetOpacity(rgba[3]); label->SetValue(sourceValue); this->GetLabelSet()->AddLabel(label); if (GetActiveLabelSet()->GetNumberOfLabels() >= mitk::Label::MAX_LABEL_VALUE || sourceValue >= mitk::Label::MAX_LABEL_VALUE) this->AddLayer(); } ++sourceIter; ++targetIter; } } template <typename ImageType> void mitk::LabelSetImage::MaskStampProcessing(ImageType *itkImage, mitk::Image *mask, bool forceOverwrite) { typename ImageType::Pointer itkMask; mitk::CastToItkImage(mask, itkMask); typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType; typedef itk::ImageRegionIterator<ImageType> TargetIteratorType; SourceIteratorType sourceIter(itkMask, itkMask->GetLargestPossibleRegion()); sourceIter.GoToBegin(); TargetIteratorType targetIter(itkImage, itkImage->GetLargestPossibleRegion()); targetIter.GoToBegin(); int activeLabel = this->GetActiveLabel(GetActiveLayer())->GetValue(); while (!sourceIter.IsAtEnd()) { PixelType sourceValue = sourceIter.Get(); PixelType targetValue = targetIter.Get(); if ((sourceValue != 0) && (forceOverwrite || !this->GetLabel(targetValue)->GetLocked())) // skip exterior and locked labels { targetIter.Set(activeLabel); } ++sourceIter; ++targetIter; } this->Modified(); } template <typename ImageType> void mitk::LabelSetImage::CalculateCenterOfMassProcessing(ImageType *itkImage, PixelType pixelValue, unsigned int layer) { // for now, we just retrieve the voxel in the middle typedef itk::ImageRegionConstIterator<ImageType> IteratorType; IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion()); iter.GoToBegin(); std::vector<typename ImageType::IndexType> indexVector; while (!iter.IsAtEnd()) { // TODO fix comparison warning more effective if (iter.Get() == pixelValue) { indexVector.push_back(iter.GetIndex()); } ++iter; } mitk::Point3D pos; pos.Fill(0.0); if (!indexVector.empty()) { typename itk::ImageRegionConstIteratorWithIndex<ImageType>::IndexType centerIndex; centerIndex = indexVector.at(indexVector.size() / 2); if (centerIndex.GetIndexDimension() == 3) { pos[0] = centerIndex[0]; pos[1] = centerIndex[1]; pos[2] = centerIndex[2]; } else return; } GetLabelSet(layer)->GetLabel(pixelValue)->SetCenterOfMassIndex(pos); this->GetSlicedGeometry()->IndexToWorld(pos, pos); // TODO: TimeGeometry? GetLabelSet(layer)->GetLabel(pixelValue)->SetCenterOfMassCoordinates(pos); } template <typename ImageType> void mitk::LabelSetImage::ClearBufferProcessing(ImageType *itkImage) { itkImage->FillBuffer(0); } // todo: concatenate all layers and not just the active one template <typename ImageType> void mitk::LabelSetImage::ConcatenateProcessing(ImageType *itkTarget, mitk::LabelSetImage *other) { typename ImageType::Pointer itkSource = ImageType::New(); mitk::CastToItkImage(other, itkSource); typedef itk::ImageRegionConstIterator<ImageType> ConstIteratorType; typedef itk::ImageRegionIterator<ImageType> IteratorType; ConstIteratorType sourceIter(itkSource, itkSource->GetLargestPossibleRegion()); IteratorType targetIter(itkTarget, itkTarget->GetLargestPossibleRegion()); int numberOfTargetLabels = this->GetNumberOfLabels(GetActiveLayer()) - 1; // skip exterior sourceIter.GoToBegin(); targetIter.GoToBegin(); while (!sourceIter.IsAtEnd()) { PixelType sourceValue = sourceIter.Get(); PixelType targetValue = targetIter.Get(); if ((sourceValue != 0) && !this->GetLabel(targetValue)->GetLocked()) // skip exterior and locked labels { targetIter.Set(sourceValue + numberOfTargetLabels); } ++sourceIter; ++targetIter; } } template <typename TPixel, unsigned int VImageDimension> void mitk::LabelSetImage::LayerContainerToImageProcessing(itk::Image<TPixel, VImageDimension> *target, unsigned int layer) { typedef itk::Image<TPixel, VImageDimension> ImageType; typename ImageType::Pointer itkSource; // mitk::CastToItkImage(m_LayerContainer[layer], itkSource); itkSource = ImageToItkImage<TPixel, VImageDimension>(m_LayerContainer[layer]); typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType; typedef itk::ImageRegionIterator<ImageType> TargetIteratorType; SourceIteratorType sourceIter(itkSource, itkSource->GetLargestPossibleRegion()); sourceIter.GoToBegin(); TargetIteratorType targetIter(target, target->GetLargestPossibleRegion()); targetIter.GoToBegin(); while (!sourceIter.IsAtEnd()) { targetIter.Set(sourceIter.Get()); ++sourceIter; ++targetIter; } } template <typename TPixel, unsigned int VImageDimension> void mitk::LabelSetImage::ImageToLayerContainerProcessing(itk::Image<TPixel, VImageDimension> *source, unsigned int layer) const { typedef itk::Image<TPixel, VImageDimension> ImageType; typename ImageType::Pointer itkTarget; // mitk::CastToItkImage(m_LayerContainer[layer], itkTarget); itkTarget = ImageToItkImage<TPixel, VImageDimension>(m_LayerContainer[layer]); typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType; typedef itk::ImageRegionIterator<ImageType> TargetIteratorType; SourceIteratorType sourceIter(source, source->GetLargestPossibleRegion()); sourceIter.GoToBegin(); TargetIteratorType targetIter(itkTarget, itkTarget->GetLargestPossibleRegion()); targetIter.GoToBegin(); while (!sourceIter.IsAtEnd()) { targetIter.Set(sourceIter.Get()); ++sourceIter; ++targetIter; } } template <typename ImageType> void mitk::LabelSetImage::EraseLabelProcessing(ImageType *itkImage, PixelType pixelValue, unsigned int /*layer*/) { typedef itk::ImageRegionIterator<ImageType> IteratorType; IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion()); iter.GoToBegin(); while (!iter.IsAtEnd()) { PixelType value = iter.Get(); if (value == pixelValue) { iter.Set(0); } ++iter; } } template <typename ImageType> void mitk::LabelSetImage::MergeLabelProcessing(ImageType *itkImage, PixelType pixelValue, PixelType index) { typedef itk::ImageRegionIterator<ImageType> IteratorType; IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion()); iter.GoToBegin(); while (!iter.IsAtEnd()) { if (iter.Get() == index) { iter.Set(pixelValue); } ++iter; } } bool mitk::Equal(const mitk::LabelSetImage &leftHandSide, const mitk::LabelSetImage &rightHandSide, ScalarType eps, bool verbose) { bool returnValue = true; /* LabelSetImage members */ MITK_INFO(verbose) << "--- LabelSetImage Equal ---"; // number layers returnValue = leftHandSide.GetNumberOfLayers() == rightHandSide.GetNumberOfLayers(); if (!returnValue) { MITK_INFO(verbose) << "Number of layers not equal."; return false; } // total number labels returnValue = leftHandSide.GetTotalNumberOfLabels() == rightHandSide.GetTotalNumberOfLabels(); if (!returnValue) { MITK_INFO(verbose) << "Total number of labels not equal."; return false; } // active layer returnValue = leftHandSide.GetActiveLayer() == rightHandSide.GetActiveLayer(); if (!returnValue) { MITK_INFO(verbose) << "Active layer not equal."; return false; } if (4 == leftHandSide.GetDimension()) { MITK_INFO(verbose) << "Can not compare image data for 4D images - skipping check."; } else { // working image data returnValue = mitk::Equal((const mitk::Image &)leftHandSide, (const mitk::Image &)rightHandSide, eps, verbose); if (!returnValue) { MITK_INFO(verbose) << "Working image data not equal."; return false; } } for (unsigned int layerIndex = 0; layerIndex < leftHandSide.GetNumberOfLayers(); layerIndex++) { if (4 == leftHandSide.GetDimension()) { MITK_INFO(verbose) << "Can not compare image data for 4D images - skipping check."; } else { // layer image data returnValue = mitk::Equal(*leftHandSide.GetLayerImage(layerIndex), *rightHandSide.GetLayerImage(layerIndex), eps, verbose); if (!returnValue) { MITK_INFO(verbose) << "Layer image data not equal."; return false; } } // layer labelset data returnValue = mitk::Equal(*leftHandSide.GetLabelSet(layerIndex), *rightHandSide.GetLabelSet(layerIndex), eps, verbose); if (!returnValue) { MITK_INFO(verbose) << "Layer labelset data not equal."; return false; } } return returnValue; } diff --git a/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModel.cpp index 4c53a5c238..dedc6d3917 100644 --- a/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModel.cpp +++ b/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModel.cpp @@ -1,177 +1,182 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkExtendedToftsModel.h" #include "mitkConvolutionHelper.h" #include <vnl/algo/vnl_fft_1d.h> #include <fstream> const std::string mitk::ExtendedToftsModel::MODEL_DISPLAY_NAME = "Extended Tofts Model"; const std::string mitk::ExtendedToftsModel::NAME_PARAMETER_Ktrans = "KTrans"; const std::string mitk::ExtendedToftsModel::NAME_PARAMETER_ve = "ve"; const std::string mitk::ExtendedToftsModel::NAME_PARAMETER_vp = "vp"; const std::string mitk::ExtendedToftsModel::UNIT_PARAMETER_Ktrans = "ml/min/100ml"; const std::string mitk::ExtendedToftsModel::UNIT_PARAMETER_ve = "ml/ml"; const std::string mitk::ExtendedToftsModel::UNIT_PARAMETER_vp = "ml/ml"; const unsigned int mitk::ExtendedToftsModel::POSITION_PARAMETER_Ktrans = 0; const unsigned int mitk::ExtendedToftsModel::POSITION_PARAMETER_ve = 1; const unsigned int mitk::ExtendedToftsModel::POSITION_PARAMETER_vp = 2; const unsigned int mitk::ExtendedToftsModel::NUMBER_OF_PARAMETERS = 3; std::string mitk::ExtendedToftsModel::GetModelDisplayName() const { return MODEL_DISPLAY_NAME; }; std::string mitk::ExtendedToftsModel::GetModelType() const { return "Perfusion.MR"; }; mitk::ExtendedToftsModel::ExtendedToftsModel() { } mitk::ExtendedToftsModel::~ExtendedToftsModel() { } mitk::ExtendedToftsModel::ParameterNamesType mitk::ExtendedToftsModel::GetParameterNames() const { ParameterNamesType result; result.push_back(NAME_PARAMETER_Ktrans); result.push_back(NAME_PARAMETER_ve); result.push_back(NAME_PARAMETER_vp); return result; } mitk::ExtendedToftsModel::ParametersSizeType mitk::ExtendedToftsModel::GetNumberOfParameters() const { return NUMBER_OF_PARAMETERS; } mitk::ExtendedToftsModel::ParamterUnitMapType mitk::ExtendedToftsModel::GetParameterUnits() const { ParamterUnitMapType result; result.insert(std::make_pair(NAME_PARAMETER_Ktrans, UNIT_PARAMETER_Ktrans)); result.insert(std::make_pair(NAME_PARAMETER_vp, UNIT_PARAMETER_vp)); result.insert(std::make_pair(NAME_PARAMETER_ve, UNIT_PARAMETER_ve)); return result; }; mitk::ExtendedToftsModel::ParameterNamesType mitk::ExtendedToftsModel::GetDerivedParameterNames() const { ParameterNamesType result; result.push_back("kep"); return result; }; mitk::ExtendedToftsModel::ParametersSizeType mitk::ExtendedToftsModel::GetNumberOfDerivedParameters() const { return 1; }; mitk::ExtendedToftsModel::ParamterUnitMapType mitk::ExtendedToftsModel::GetDerivedParameterUnits() const { ParamterUnitMapType result; result.insert(std::make_pair("kep", "1/min")); return result; }; mitk::ExtendedToftsModel::ModelResultType mitk::ExtendedToftsModel::ComputeModelfunction( const ParametersType& parameters) const { if (this->m_TimeGrid.GetSize() == 0) { itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); } AterialInputFunctionType aterialInputFunction; aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); unsigned int timeSteps = this->m_TimeGrid.GetSize(); //Model Parameters double ktrans = parameters[POSITION_PARAMETER_Ktrans] / 6000.0; double ve = parameters[POSITION_PARAMETER_ve]; double vp = parameters[POSITION_PARAMETER_vp]; + if (ve == 0.0) + { + itkExceptionMacro("ve is 0! Cannot calculate signal"); + } + double lambda = ktrans / ve; mitk::ModelBase::ModelResultType convolution = mitk::convoluteAIFWithExponential(this->m_TimeGrid, aterialInputFunction, lambda); //Signal that will be returned by ComputeModelFunction mitk::ModelBase::ModelResultType signal(timeSteps); signal.fill(0.0); mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); mitk::ModelBase::ModelResultType::const_iterator res = convolution.begin(); for (AterialInputFunctionType::iterator Cp = aterialInputFunction.begin(); Cp != aterialInputFunction.end(); ++res, ++signalPos, ++Cp) { *signalPos = (*Cp) * vp + ktrans * (*res); } return signal; } mitk::ModelBase::DerivedParameterMapType mitk::ExtendedToftsModel::ComputeDerivedParameters( const mitk::ModelBase::ParametersType& parameters) const { DerivedParameterMapType result; double kep = parameters[POSITION_PARAMETER_Ktrans] / parameters[POSITION_PARAMETER_ve]; result.insert(std::make_pair("kep", kep)); return result; }; itk::LightObject::Pointer mitk::ExtendedToftsModel::InternalClone() const { ExtendedToftsModel::Pointer newClone = ExtendedToftsModel::New(); newClone->SetTimeGrid(this->m_TimeGrid); return newClone.GetPointer(); }; void mitk::ExtendedToftsModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const { Superclass::PrintSelf(os, indent); }; diff --git a/Modules/Pharmacokinetics/test/files.cmake b/Modules/Pharmacokinetics/test/files.cmake index 713e14913f..d6ce07a366 100644 --- a/Modules/Pharmacokinetics/test/files.cmake +++ b/Modules/Pharmacokinetics/test/files.cmake @@ -1,4 +1,7 @@ SET(MODULE_TESTS mitkDescriptivePharmacokineticBrixModelTest.cpp + mitkStandardToftsModelTest.cpp #ConvertToConcentrationTest.cpp + mitkTwoCompartmentExchangeModelTest.cpp + mitkExtendedToftsModelTest.cpp ) diff --git a/Modules/Pharmacokinetics/test/mitkExtendedToftsModelTest.cpp b/Modules/Pharmacokinetics/test/mitkExtendedToftsModelTest.cpp new file mode 100644 index 0000000000..5bd2a350e1 --- /dev/null +++ b/Modules/Pharmacokinetics/test/mitkExtendedToftsModelTest.cpp @@ -0,0 +1,164 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +// Testing +#include "mitkTestingMacros.h" +#include "mitkTestFixture.h" +#include "math.h" + +//MITK includes +#include "mitkVector.h" +#include "mitkExtendedToftsModel.h" +#include "mitkAIFBasedModelBase.h" + +class mitkExtendedToftsModelTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkExtendedToftsModelTestSuite); + MITK_TEST(GetModelDisplayNameTest); + MITK_TEST(GetModelTypeTest); + MITK_TEST(GetParameterNamesTest); + MITK_TEST(GetNumberOfParametersTest); + MITK_TEST(GetParameterUnitsTest); + MITK_TEST(GetDerivedParameterNamesTest); + MITK_TEST(GetNumberOfDerivedParametersTest); + MITK_TEST(GetDerivedParameterUnitsTest); + MITK_TEST(ComputeModelfunctionTest); + MITK_TEST(ComputeDerivedParametersTest); + CPPUNIT_TEST_SUITE_END(); + +private: + mitk::ExtendedToftsModel::Pointer m_testmodel; + mitk::ModelBase::ModelResultType m_output; + mitk::ModelBase::DerivedParameterMapType m_derivedParameters; + +public: + void setUp() override + { + mitk::ModelBase::TimeGridType m_grid(60); + mitk::ModelBase::ParametersType m_testparameters(3); + mitk::AIFBasedModelBase::AterialInputFunctionType m_arterialInputFunction (60); + + m_testparameters[mitk::ExtendedToftsModel::POSITION_PARAMETER_Ktrans] = 35.0; + m_testparameters(mitk::ExtendedToftsModel::POSITION_PARAMETER_ve) = 0.5; + m_testparameters[mitk::ExtendedToftsModel::POSITION_PARAMETER_vp] = 0.05; + + for (int i = 0; i < 22; ++i) + { + // time grid in seconds, 14s between frames + m_grid[i] = (double)14 * i; + } + + // AIF from Weinmann, H. J., Laniado, M., and W.M�tzel (1984). Pharmacokinetics of GD - DTPA / dimeglumine after intravenous injection into healthy volunteers. Phys Chem Phys Med NMR, 16(2) : 167�72. + int D = 1; + double a1 = 3.99; + double m1 = 0.144; + double a2 = 4.78; + double m2 = 0.0111; + for (int i = 0; i < 22; ++i) + { + m_arterialInputFunction[i] = D * (a1 * exp(-m1 * m_grid[i]) + a2 * exp(-m2 * m_grid[i])); + } + + m_testmodel = mitk::ExtendedToftsModel::New(); + m_testmodel->SetTimeGrid(m_grid); + m_testmodel->SetAterialInputFunctionValues(m_arterialInputFunction); + m_testmodel->SetAterialInputFunctionTimeGrid(m_grid); + + //ComputeModelfunction is called within GetSignal(), therefore no explicit testing of ComputeModelFunction() + m_output = m_testmodel->GetSignal(m_testparameters); + m_derivedParameters = m_testmodel->GetDerivedParameters(m_testparameters); + } + + void tearDown() override + { + m_testmodel = nullptr; + m_output.clear(); + m_derivedParameters.clear(); + } + + void GetModelDisplayNameTest() + { + m_testmodel->GetModelDisplayName(); + CPPUNIT_ASSERT_MESSAGE("Checking model display name.", m_testmodel->GetModelDisplayName() == "Extended Tofts Model"); + } + + + void GetModelTypeTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking model type.", m_testmodel->GetModelType() == "Perfusion.MR"); + } + + + void GetParameterNamesTest() + { + mitk::ExtendedToftsModel::ParameterNamesType parameterNames; + parameterNames.push_back("KTrans"); + parameterNames.push_back("ve"); + parameterNames.push_back("vp"); + CPPUNIT_ASSERT_MESSAGE("Checking parameter names.", m_testmodel->GetParameterNames() == parameterNames); + } + + void GetNumberOfParametersTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking number of parameters in model.", m_testmodel->GetNumberOfParameters() == 3); + } + + + void GetParameterUnitsTest() + { + mitk::ExtendedToftsModel::ParamterUnitMapType parameterUnits; + parameterUnits.insert(std::make_pair("KTrans", "ml/min/100ml")); + parameterUnits.insert(std::make_pair("vp", "ml/ml")); + parameterUnits.insert(std::make_pair("ve","ml/ml")); + + CPPUNIT_ASSERT_MESSAGE("Checking parameter units.", m_testmodel->GetParameterUnits() == parameterUnits); + } + + void GetDerivedParameterNamesTest() + { + mitk::ExtendedToftsModel::ParameterNamesType derivedParameterNames; + + derivedParameterNames.push_back("kep"); + + CPPUNIT_ASSERT_MESSAGE("Checking derived parameter names.", m_testmodel->GetDerivedParameterNames() == derivedParameterNames); + } + + void GetNumberOfDerivedParametersTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking number of parameters in model.", m_testmodel->GetNumberOfDerivedParameters() == 1); + } + + void GetDerivedParameterUnitsTest() + { + mitk::ExtendedToftsModel::ParamterUnitMapType derivedParameterUnits; + derivedParameterUnits.insert(std::make_pair("kep", "1/min")); + + CPPUNIT_ASSERT_MESSAGE("Checking parameter units.", m_testmodel->GetDerivedParameterUnits() == derivedParameterUnits); + } + + void ComputeModelfunctionTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 0.", mitk::Equal(0.438500, m_output[0], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 5.", mitk::Equal(1.094436, m_output[5], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 10", mitk::Equal(0.890956, m_output[10], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 15", mitk::Equal(0.580996, m_output[15], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 20", mitk::Equal(0.342851, m_output[20], 1e-6, true) == true); + } + + void ComputeDerivedParametersTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking kep.", mitk::Equal(70.00, m_derivedParameters["kep"], 1e-6, true) == true); + } + +}; + +MITK_TEST_SUITE_REGISTRATION(mitkExtendedToftsModel) diff --git a/Modules/Pharmacokinetics/test/mitkStandardToftsModelTest.cpp b/Modules/Pharmacokinetics/test/mitkStandardToftsModelTest.cpp new file mode 100644 index 0000000000..5b0c907166 --- /dev/null +++ b/Modules/Pharmacokinetics/test/mitkStandardToftsModelTest.cpp @@ -0,0 +1,162 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +// Testing +#include "mitkTestingMacros.h" +#include "mitkTestFixture.h" + +//MITK includes +#include "mitkVector.h" +#include "mitkStandardToftsModel.h" +#include "mitkAIFBasedModelBase.h" + +class mitkStandardToftsModelTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkStandardToftsModelTestSuite); + MITK_TEST(GetModelDisplayNameTest); + MITK_TEST(GetModelTypeTest); + MITK_TEST(GetParameterNamesTest); + MITK_TEST(GetNumberOfParametersTest); + MITK_TEST(GetParameterUnitsTest); + MITK_TEST(GetDerivedParameterNamesTest); + MITK_TEST(GetNumberOfDerivedParametersTest); + MITK_TEST(GetDerivedParameterUnitsTest); + MITK_TEST(ComputeModelfunctionTest); + MITK_TEST(ComputeDerivedParametersTest); + CPPUNIT_TEST_SUITE_END(); + +private: + mitk::StandardToftsModel::Pointer m_testmodel; + mitk::ModelBase::ModelResultType m_output; + mitk::ModelBase::DerivedParameterMapType m_derivedParameters; + +public: + void setUp() override + { + mitk::ModelBase::TimeGridType m_grid(22); + mitk::ModelBase::ParametersType m_testparameters(2); + mitk::AIFBasedModelBase::AterialInputFunctionType m_arterialInputFunction (22); + + m_testparameters[mitk::StandardToftsModel::POSITION_PARAMETER_Ktrans] = 35.0; + m_testparameters(mitk::StandardToftsModel::POSITION_PARAMETER_ve) = 0.5; + + for (int i = 0; i < 22; ++i) + { + // time grid in seconds, 14s between frames + m_grid[i] = (double)14 * i; + } + + // AIF from Weinmann, H. J., Laniado, M., and W.M�tzel (1984). Pharmacokinetics of GD - DTPA / dimeglumine after intravenous injection into healthy volunteers. Phys Chem Phys Med NMR, 16(2) : 167�72. + int D = 1; + double a1 = 3.99; + double m1 = 0.144; + double a2 = 4.78; + double m2 = 0.0111; + for (int i = 0; i < 22; ++i) + { + if (i < 5) + m_arterialInputFunction[i] = 0; + else + m_arterialInputFunction[i] = D * (a1 * exp(-m1 * m_grid[i]) + a2 * exp(-m2 * m_grid[i])); + } + + m_testmodel = mitk::StandardToftsModel::New(); + m_testmodel->SetTimeGrid(m_grid); + m_testmodel->SetAterialInputFunctionValues(m_arterialInputFunction); + m_testmodel->SetAterialInputFunctionTimeGrid(m_grid); + + //ComputeModelfunction is called within GetSignal(), therefore no explicit testing of ComputeModelFunction() + m_output = m_testmodel->GetSignal(m_testparameters); + m_derivedParameters = m_testmodel->GetDerivedParameters(m_testparameters); + } + + void tearDown() override + { + m_testmodel = nullptr; + m_output.clear(); + m_derivedParameters.clear(); + } + + void GetModelDisplayNameTest() + { + m_testmodel->GetModelDisplayName(); + CPPUNIT_ASSERT_MESSAGE("Checking model display name.", m_testmodel->GetModelDisplayName() == "Standard Tofts Model"); + } + + + void GetModelTypeTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking model type.", m_testmodel->GetModelType() == "Perfusion.MR"); + } + + + void GetParameterNamesTest() + { + mitk::StandardToftsModel::ParameterNamesType parameterNames; + parameterNames.push_back("KTrans"); + parameterNames.push_back("ve"); + CPPUNIT_ASSERT_MESSAGE("Checking parameter names.", m_testmodel->GetParameterNames() == parameterNames); + } + + void GetNumberOfParametersTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking number of parameters in model.", m_testmodel->GetNumberOfParameters() == 2); + } + + + void GetParameterUnitsTest() + { + mitk::StandardToftsModel::ParamterUnitMapType parameterUnits; + parameterUnits.insert(std::make_pair("KTrans", "ml/min/100ml")); + parameterUnits.insert(std::make_pair("ve", "ml/ml")); + + CPPUNIT_ASSERT_MESSAGE("Checking parameter units.", m_testmodel->GetParameterUnits() == parameterUnits); + } + + void GetDerivedParameterNamesTest() + { + mitk::StandardToftsModel::ParameterNamesType derivedParameterNames; + + derivedParameterNames.push_back("kep"); + + CPPUNIT_ASSERT_MESSAGE("Checking derived parameter names.", m_testmodel->GetDerivedParameterNames() == derivedParameterNames); + } + + void GetNumberOfDerivedParametersTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking number of parameters in model.", m_testmodel->GetNumberOfDerivedParameters() == 1); + } + + void GetDerivedParameterUnitsTest() + { + mitk::StandardToftsModel::ParamterUnitMapType derivedParameterUnits; + derivedParameterUnits.insert(std::make_pair("kep", "1/min")); + + CPPUNIT_ASSERT_MESSAGE("Checking parameter units.", m_testmodel->GetDerivedParameterUnits() == derivedParameterUnits); + } + + void ComputeModelfunctionTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 0.", mitk::Equal(0.0, m_output[0], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 5.", mitk::Equal(0.085056, m_output[5], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 10.", mitk::Equal(0.442948, m_output[10], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 20.", mitk::Equal(0.254551, m_output[20], 1e-6, true) == true); + } + + void ComputeDerivedParametersTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking kep.", mitk::Equal(70.0, m_derivedParameters["kep"], 1e-6, true) == true); + } + +}; + +MITK_TEST_SUITE_REGISTRATION(mitkStandardToftsModel) diff --git a/Modules/Pharmacokinetics/test/mitkTwoCompartmentExchangeModelTest.cpp b/Modules/Pharmacokinetics/test/mitkTwoCompartmentExchangeModelTest.cpp new file mode 100644 index 0000000000..652198ec20 --- /dev/null +++ b/Modules/Pharmacokinetics/test/mitkTwoCompartmentExchangeModelTest.cpp @@ -0,0 +1,137 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +// Testing +#include "mitkTestingMacros.h" +#include "mitkTestFixture.h" + +//MITK includes +#include "mitkVector.h" +#include "mitkTwoCompartmentExchangeModel.h" +#include "mitkAIFBasedModelBase.h" + +class mitkTwoCompartmentExchangeModelTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkTwoCompartmentExchangeModelTestSuite); + MITK_TEST(GetModelDisplayNameTest); + MITK_TEST(GetModelTypeTest); + MITK_TEST(GetParameterNamesTest); + MITK_TEST(GetNumberOfParametersTest); + MITK_TEST(GetParameterUnitsTest); + MITK_TEST(ComputeModelfunctionTest); + CPPUNIT_TEST_SUITE_END(); + +private: + mitk::TwoCompartmentExchangeModel::Pointer m_testmodel; + mitk::ModelBase::ModelResultType m_output; + +public: + void setUp() override + { + mitk::ModelBase::TimeGridType m_grid(22); + mitk::ModelBase::ParametersType m_testparameters(4); + mitk::AIFBasedModelBase::AterialInputFunctionType m_arterialInputFunction (22); + + m_testparameters[mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_F] = 35.0; + m_testparameters(mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_PS) = 5.0; + m_testparameters(mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_ve) = 0.5; + m_testparameters(mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_vp) = 0.05; + + + for (int i = 0; i < 22; ++i) + { + // time grid in seconds, 14s between frames + m_grid[i] = (double)14 * i; + } + + // AIF from Weinmann, H. J., Laniado, M., and W.M�tzel (1984). Pharmacokinetics of GD - DTPA / dimeglumine after intravenous injection into healthy volunteers. Phys Chem Phys Med NMR, 16(2) : 167�72. + int D = 1; + double a1 = 3.99; + double m1 = 0.144; + double a2 = 4.78; + double m2 = 0.0111; + + for (int i = 0; i < 22; ++i) + { + if (i < 5) + m_arterialInputFunction[i] = 0; + else + m_arterialInputFunction[i] = D * (a1 * exp(-m1 * m_grid[i]) + a2 * exp(-m2 * m_grid[i])); + } + + m_testmodel = mitk::TwoCompartmentExchangeModel::New(); + m_testmodel->SetTimeGrid(m_grid); + m_testmodel->SetAterialInputFunctionValues(m_arterialInputFunction); + m_testmodel->SetAterialInputFunctionTimeGrid(m_grid); + + //ComputeModelfunction is called within GetSignal(), therefore no explicit testing of ComputeModelFunction() + m_output = m_testmodel->GetSignal(m_testparameters); + } + void tearDown() override + { + m_testmodel = nullptr; + m_output.clear(); + } + + void GetModelDisplayNameTest() + { + m_testmodel->GetModelDisplayName(); + CPPUNIT_ASSERT_MESSAGE("Checking model display name.", m_testmodel->GetModelDisplayName() == "Two Compartment Exchange Model"); + } + + + void GetModelTypeTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking model type.", m_testmodel->GetModelType() == "Perfusion.MR"); + } + + + void GetParameterNamesTest() + { + mitk::TwoCompartmentExchangeModel::ParameterNamesType parameterNames; + parameterNames.push_back("F"); + parameterNames.push_back("PS"); + parameterNames.push_back("ve"); + parameterNames.push_back("vp"); + CPPUNIT_ASSERT_MESSAGE("Checking parameter names.", m_testmodel->GetParameterNames() == parameterNames); + } + + + void GetNumberOfParametersTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking number of parameters in model.", m_testmodel->GetNumberOfParameters() == 4); + } + + + void GetParameterUnitsTest() + { + mitk::TwoCompartmentExchangeModel::ParamterUnitMapType parameterUnits; + parameterUnits.insert(std::make_pair("F", "ml/min/100ml")); + parameterUnits.insert(std::make_pair("PS", "ml/min/100ml")); + parameterUnits.insert(std::make_pair("ve", "ml/ml")); + parameterUnits.insert(std::make_pair("vp", "ml/ml")); + + CPPUNIT_ASSERT_MESSAGE("Checking parameter units.", m_testmodel->GetParameterUnits() == parameterUnits); + } + + void ComputeModelfunctionTest() + { + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 0.", mitk::Equal(0.0, m_output[0], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 5.", mitk::Equal(0.057246, m_output[5], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 10.", mitk::Equal(0.127806, m_output[10], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 15.", mitk::Equal(0.131465, m_output[15], 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking signal at time frame 20.", mitk::Equal(0.126101, m_output[20], 1e-6, true) == true); + } + +}; + +MITK_TEST_SUITE_REGISTRATION(mitkTwoCompartmentExchangeModel) diff --git a/Modules/QtWidgets/include/QmitkAbstractMultiWidget.h b/Modules/QtWidgets/include/QmitkAbstractMultiWidget.h index d2e3bec908..e3d5a3558d 100644 --- a/Modules/QtWidgets/include/QmitkAbstractMultiWidget.h +++ b/Modules/QtWidgets/include/QmitkAbstractMultiWidget.h @@ -1,156 +1,160 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKABSTRACTMULTIWIDGET_H #define QMITKABSTRACTMULTIWIDGET_H // mitk qt widgets module #include "MitkQtWidgetsExports.h" // mitk core #include <mitkBaseRenderer.h> #include <mitkDisplayActionEventHandler.h> #include <mitkInteractionSchemeSwitcher.h> #include <mitkPoint.h> // qt #include <QWidget> // c++ #include <map> #include <memory> class QmitkMultiWidgetLayoutManager; class QmitkRenderWindow; class QmitkRenderWindowWidget; namespace mitk { class DataStorage; class InteractionEventHandler; } /** * @brief The 'QmitkAbstractMultiWidget' is a 'QWidget' that can be subclassed to display multiple render windows at once. * Render windows can dynamically be added and removed to change the layout of the multi widget. * A subclass of this multi widget can be used inside a 'QmitkAbstractMultiWidgetEditor'. * * The class uses the 'DisplayActionEventBroadcast' and 'DisplayActionEventHandler' classes to * load a state machine and set an event configuration. * * Using the 'Synchronize' function the user can enable or disable the synchronization of display action events. * See 'DisplayActionEventFunctions'-class for the different synchronized and non-synchronized functions used. */ class MITKQTWIDGETS_EXPORT QmitkAbstractMultiWidget : public QWidget { Q_OBJECT public: using RenderWindowWidgetPointer = std::shared_ptr<QmitkRenderWindowWidget>; using RenderWindowWidgetMap = std::map<QString, std::shared_ptr<QmitkRenderWindowWidget>>; using RenderWindowHash = QHash<QString, QmitkRenderWindow*>; using ViewDirection = mitk::BaseRenderer::ViewDirection; QmitkAbstractMultiWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, const QString& multiWidgetName = "multiwidget"); virtual ~QmitkAbstractMultiWidget(); virtual void InitializeMultiWidget() = 0; virtual void MultiWidgetOpened() { } virtual void MultiWidgetClosed() { } virtual void SetDataStorage(mitk::DataStorage* dataStorage); mitk::DataStorage* GetDataStorage() const; int GetRowCount() const; int GetColumnCount() const; virtual void SetLayout(int row, int column); virtual void Synchronize(bool) { }; virtual void SetInteractionScheme(mitk::InteractionSchemeSwitcher::InteractionScheme scheme); mitk::InteractionEventHandler* GetInteractionEventHandler(); void SetDisplayActionEventHandler(std::unique_ptr<mitk::DisplayActionEventHandler> displayActionEventHandler); mitk::DisplayActionEventHandler* GetDisplayActionEventHandler(); RenderWindowWidgetMap GetRenderWindowWidgets() const; RenderWindowWidgetMap Get2DRenderWindowWidgets() const; RenderWindowWidgetMap Get3DRenderWindowWidgets() const; RenderWindowWidgetPointer GetRenderWindowWidget(int row, int column) const; RenderWindowWidgetPointer GetRenderWindowWidget(const QString& widgetName) const; RenderWindowWidgetPointer GetRenderWindowWidget(const QmitkRenderWindow* renderWindow) const; RenderWindowHash GetRenderWindows() const; QmitkRenderWindow* GetRenderWindow(int row, int column) const; virtual QmitkRenderWindow* GetRenderWindow(const QString& widgetName) const; virtual QmitkRenderWindow* GetRenderWindow(const ViewDirection& viewDirection) const = 0; virtual void SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget); RenderWindowWidgetPointer GetActiveRenderWindowWidget() const; RenderWindowWidgetPointer GetFirstRenderWindowWidget() const; RenderWindowWidgetPointer GetLastRenderWindowWidget() const; virtual QString GetNameFromIndex(int row, int column) const; virtual QString GetNameFromIndex(size_t index) const; unsigned int GetNumberOfRenderWindowWidgets() const; void RequestUpdate(const QString& widgetName); void RequestUpdateAll(); void ForceImmediateUpdate(const QString& widgetName); void ForceImmediateUpdateAll(); virtual void SetSelectedPosition(const mitk::Point3D& newPosition, const QString& widgetName) = 0; virtual const mitk::Point3D GetSelectedPosition(const QString& widgetName) const = 0; virtual void SetCrosshairVisibility(bool visible) = 0; virtual bool GetCrosshairVisibility() const = 0; virtual void ResetCrosshair() = 0; virtual void SetWidgetPlaneMode(int mode) = 0; virtual void ActivateMenuWidget(bool state); virtual bool IsMenuWidgetEnabled() const; QmitkMultiWidgetLayoutManager* GetMultiWidgetLayoutManager() const; -Q_SIGNALS: +signals: void ActiveRenderWindowChanged(); +private slots: + + void OnFocusChanged(itk::Object*, const itk::EventObject& event); + protected: virtual void AddRenderWindowWidget(const QString& widgetName, RenderWindowWidgetPointer renderWindowWidget); virtual void RemoveRenderWindowWidget(); private: /** * @brief This function will be called by the function 'SetLayout' and * can be implemented and customized in the subclasses. */ virtual void SetLayoutImpl() = 0; /** * @brief This function will be called by the function 'SetInteractionScheme' and * can be implemented and customized in the subclasses. */ virtual void SetInteractionSchemeImpl() = 0; struct Impl; std::unique_ptr<Impl> m_Impl; }; #endif // QMITKABSTRACTMULTIWIDGET_H diff --git a/Modules/QtWidgets/include/QmitkMxNMultiWidget.h b/Modules/QtWidgets/include/QmitkMxNMultiWidget.h index 2143d7668e..3755235595 100644 --- a/Modules/QtWidgets/include/QmitkMxNMultiWidget.h +++ b/Modules/QtWidgets/include/QmitkMxNMultiWidget.h @@ -1,82 +1,86 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKMXNMULTIWIDGET_H #define QMITKMXNMULTIWIDGET_H // qt widgets module #include "MitkQtWidgetsExports.h" #include "QmitkAbstractMultiWidget.h" /** * @brief The 'QmitkMxNMultiWidget' is a 'QmitkAbstractMultiWidget' that is used to display multiple render windows at once. * Render windows can dynamically be added and removed to change the layout of the multi widget. This * is done by using the 'SetLayout'-function to define a layout. This will automatically add or remove * the appropriate number of render window widgets. */ class MITKQTWIDGETS_EXPORT QmitkMxNMultiWidget : public QmitkAbstractMultiWidget { Q_OBJECT public: QmitkMxNMultiWidget(QWidget* parent = nullptr, Qt::WindowFlags f = 0, const QString& multiWidgetName = "mxnmulti"); - ~QmitkMxNMultiWidget() = default; + ~QmitkMxNMultiWidget(); void InitializeMultiWidget() override; void MultiWidgetOpened() override; void MultiWidgetClosed() override; void Synchronize(bool synchronized) override; QmitkRenderWindow* GetRenderWindow(const QString& widgetName) const override; QmitkRenderWindow* GetRenderWindow(const mitk::BaseRenderer::ViewDirection& viewDirection) const override; void SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget) override; void SetSelectedPosition(const mitk::Point3D& newPosition, const QString& widgetName) override; const mitk::Point3D GetSelectedPosition(const QString& widgetName) const override; void SetCrosshairVisibility(bool activate) override; bool GetCrosshairVisibility() const override { return m_CrosshairVisibility; } void ResetCrosshair() override; void SetWidgetPlaneMode(int userMode) override; + mitk::SliceNavigationController* GetTimeNavigationController(); + public Q_SLOTS: // mouse events void wheelEvent(QWheelEvent* e) override; void mousePressEvent(QMouseEvent* e) override; void moveEvent(QMoveEvent* e) override; Q_SIGNALS: void WheelMoved(QWheelEvent *); void Moved(); private: void SetLayoutImpl() override; void SetInteractionSchemeImpl() override { } void CreateRenderWindowWidget(); + mitk::SliceNavigationController* m_TimeNavigationController; + bool m_CrosshairVisibility; }; #endif // QMITKMXNMULTIWIDGET_H diff --git a/Modules/QtWidgets/include/QmitkRenderWindow.h b/Modules/QtWidgets/include/QmitkRenderWindow.h index 668cbc7e69..51f83d8b84 100644 --- a/Modules/QtWidgets/include/QmitkRenderWindow.h +++ b/Modules/QtWidgets/include/QmitkRenderWindow.h @@ -1,156 +1,154 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKRENDERWINDOW_H #define QMITKRENDERWINDOW_H #include "mitkRenderWindowBase.h" #include "QmitkRenderWindowMenu.h" #include <MitkQtWidgetsExports.h> #include <vtkGenericOpenGLRenderWindow.h> #include <QVTKOpenGLNativeWidget.h> #include "mitkBaseRenderer.h" #include "mitkInteractionEventConst.h" class QDragEnterEvent; class QDropEvent; class QInputEvent; class QMouseEvent; /** * \ingroup QmitkModule * \brief MITK implementation of the QVTKWidget */ class MITKQTWIDGETS_EXPORT QmitkRenderWindow : public QVTKOpenGLNativeWidget, public mitk::RenderWindowBase { Q_OBJECT public: QmitkRenderWindow( QWidget *parent = nullptr, const QString &name = "unnamed renderwindow", mitk::VtkPropRenderer *renderer = nullptr); ~QmitkRenderWindow() override; /** * \brief Whether Qt events should be passed to parent (default: true) * * With introduction of the QVTKWidget the behaviour regarding Qt events changed. * QVTKWidget "accepts" Qt events like mouse clicks (i.e. set an "accepted" flag). * When this flag is set, Qt fininshed handling of this event -- otherwise it is * reached through to the widget's parent. * * This reaching through to the parent was implicitly required by QmitkMaterialWidget / QmitkMaterialShowCase. * * The default behaviour of QmitkRenderWindow is now to clear the "accepted" flag * of Qt events after they were handled by QVTKWidget. This way parents can also * handle events. * * If you don't want this behaviour, call SetResendQtEvents(true) on your render window. */ virtual void SetResendQtEvents(bool resend); // Set Layout Index to define the Layout Type void SetLayoutIndex(QmitkRenderWindowMenu::LayoutIndex layoutIndex); // Get Layout Index to define the Layout Type QmitkRenderWindowMenu::LayoutIndex GetLayoutIndex(); // MenuWidget need to update the Layout Design List when Layout had changed void UpdateLayoutDesignList(QmitkRenderWindowMenu::LayoutDesign layoutDesign); void UpdateCrosshairVisibility(bool); void UpdateCrosshairRotationMode(int); // Activate or Deactivate MenuWidget. void ActivateMenuWidget(bool state); bool GetActivateMenuWidgetFlag() { return m_MenuWidgetActivated; } // Get it from the QVTKWidget parent vtkRenderWindow *GetVtkRenderWindow() override { return this->renderWindow(); } vtkRenderWindowInteractor *GetVtkRenderWindowInteractor() override { return nullptr; } protected: // catch-all event handler bool event(QEvent *e) override; // overloaded move handler void moveEvent(QMoveEvent *event) override; // overloaded show handler void showEvent(QShowEvent *event) override; // overloaded enter handler void enterEvent(QEvent *) override; // overloaded leave handler void leaveEvent(QEvent *) override; // Overloaded resize handler, see decs in QVTKOpenGLWidget. // Basically, we have to ensure the VTK rendering is updated for each change in window size. void resizeGL(int w, int h) override; /// \brief Simply says we accept the event type. void dragEnterEvent(QDragEnterEvent *event) override; /// \brief If the dropped type is application/x-mitk-datanodes we process the request by converting to mitk::DataNode /// pointers and emitting the NodesDropped signal. void dropEvent(QDropEvent *event) override; Q_SIGNALS: void LayoutDesignChanged(QmitkRenderWindowMenu::LayoutDesign); void ResetView(); void CrosshairRotationModeChanged(int); void CrosshairVisibilityChanged(bool); void moved(); /// \brief Emits a signal to say that this window has had the following nodes dropped on it. void NodesDropped(QmitkRenderWindow *thisWindow, std::vector<mitk::DataNode *> nodes); - void mouseEvent(QMouseEvent *); - private Q_SLOTS: void DeferredHideMenu(); private: // Helper Functions to Convert Qt-Events to Mitk-Events mitk::Point2D GetMousePosition(QMouseEvent *me) const; mitk::Point2D GetMousePosition(QWheelEvent *we) const; mitk::InteractionEvent::MouseButtons GetEventButton(QMouseEvent *me) const; mitk::InteractionEvent::MouseButtons GetButtonState(QMouseEvent *me) const; mitk::InteractionEvent::ModifierKeys GetModifiers(QInputEvent *me) const; mitk::InteractionEvent::MouseButtons GetButtonState(QWheelEvent *we) const; std::string GetKeyLetter(QKeyEvent *ke) const; int GetDelta(QWheelEvent *we) const; bool m_ResendQtEvents; QmitkRenderWindowMenu *m_MenuWidget; bool m_MenuWidgetActivated; QmitkRenderWindowMenu::LayoutIndex m_LayoutIndex; vtkSmartPointer<vtkGenericOpenGLRenderWindow> m_InternalRenderWindow; }; #endif // QMITKRENDERWINDOW_H diff --git a/Modules/QtWidgets/include/QmitkRenderWindowWidget.h b/Modules/QtWidgets/include/QmitkRenderWindowWidget.h index a2444a3472..736b361b62 100644 --- a/Modules/QtWidgets/include/QmitkRenderWindowWidget.h +++ b/Modules/QtWidgets/include/QmitkRenderWindowWidget.h @@ -1,110 +1,106 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKRENDERWINDOWWIDGET_H #define QMITKRENDERWINDOWWIDGET_H // qt widgets module #include "MitkQtWidgetsExports.h" #include "QmitkRenderWindow.h" // mitk core #include <mitkDataStorage.h> #include <mitkPointSet.h> #include <mitkRenderWindow.h> // qt #include <QFrame> #include <QHBoxLayout> #include <QMouseEvent> class vtkCornerAnnotation; /** * @brief The 'QmitkRenderWindowWidget' is a QFrame that holds a render window * and some associates properties, like a crosshair (pointset) and decorations. * Decorations are corner annotation (text and color), frame color or background color * and can be set using this class. * The 'QmitkRenderWindowWidget' is used inside a 'QmitkAbstractMultiWidget', where a map contains * several render window widgets to create the multi widget display. */ class MITKQTWIDGETS_EXPORT QmitkRenderWindowWidget : public QFrame { Q_OBJECT public: QmitkRenderWindowWidget( QWidget* parent = nullptr, const QString& widgetName = "", mitk::DataStorage* dataStorage = nullptr); ~QmitkRenderWindowWidget() override; void SetDataStorage(mitk::DataStorage* dataStorage); const QString& GetWidgetName() const { return m_WidgetName; }; QmitkRenderWindow* GetRenderWindow() const { return m_RenderWindow; }; mitk::SliceNavigationController* GetSliceNavigationController() const; void RequestUpdate(); void ForceImmediateUpdate(); void SetGradientBackgroundColors(const mitk::Color& upper, const mitk::Color& lower); void ShowGradientBackground(bool enable); std::pair<mitk::Color, mitk::Color> GetGradientBackgroundColors() const { return m_GradientBackgroundColors; }; bool IsGradientBackgroundOn() const; void SetDecorationColor(const mitk::Color& color); mitk::Color GetDecorationColor() const { return m_DecorationColor; }; void ShowColoredRectangle(bool show); bool IsColoredRectangleVisible() const; void ShowCornerAnnotation(bool show); bool IsCornerAnnotationVisible() const; void SetCornerAnnotationText(const std::string& cornerAnnotation); std::string GetCornerAnnotationText() const; bool IsRenderWindowMenuActivated() const; void ActivateCrosshair(bool activate); -Q_SIGNALS: - - void MouseEvent(QMouseEvent* e); - private: void InitializeGUI(); void InitializeDecorations(); void SetCrosshair(mitk::Point3D selectedPoint); QString m_WidgetName; QHBoxLayout* m_Layout; mitk::DataStorage* m_DataStorage; QmitkRenderWindow* m_RenderWindow; mitk::DataNode::Pointer m_PointSetNode; mitk::PointSet::Pointer m_PointSet; std::pair<mitk::Color, mitk::Color> m_GradientBackgroundColors; mitk::Color m_DecorationColor; vtkSmartPointer<vtkCornerAnnotation> m_CornerAnnotation; }; #endif // QMITKRENDERWINDOWWIDGET_H diff --git a/Modules/QtWidgets/src/QmitkAbstractMultiWidget.cpp b/Modules/QtWidgets/src/QmitkAbstractMultiWidget.cpp index 9c96ffb57c..4584bd9a89 100644 --- a/Modules/QtWidgets/src/QmitkAbstractMultiWidget.cpp +++ b/Modules/QtWidgets/src/QmitkAbstractMultiWidget.cpp @@ -1,384 +1,416 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // mitk qt widgets module #include "QmitkAbstractMultiWidget.h" #include "QmitkLevelWindowWidget.h" #include "QmitkMultiWidgetLayoutManager.h" #include "QmitkRenderWindowWidget.h" // mitk core #include <mitkDataStorage.h> #include <mitkDisplayActionEventBroadcast.h> // qt #include <QMouseEvent> // c++ #include <iomanip> struct QmitkAbstractMultiWidget::Impl final { - Impl(QmitkAbstractMultiWidget* multiWidget, - const QString& multiWidgetName); + Impl(QmitkAbstractMultiWidget* multiWidget, const QString& multiWidgetName); + ~Impl(); void SetDataStorage(mitk::DataStorage* dataStorage) { if (dataStorage == m_DataStorage) { return; } m_DataStorage = dataStorage; // set new data storage for the render window widgets for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->SetDataStorage(m_DataStorage); } } void InitializeDisplayActionEventHandling() { m_DisplayActionEventBroadcast = mitk::DisplayActionEventBroadcast::New(); m_DisplayActionEventBroadcast->LoadStateMachine("DisplayInteraction.xml"); } mitk::DataStorage::Pointer m_DataStorage; QString m_MultiWidgetName; RenderWindowWidgetMap m_RenderWindowWidgets; RenderWindowWidgetPointer m_ActiveRenderWindowWidget; int m_MultiWidgetRows; int m_MultiWidgetColumns; // interaction + unsigned long m_RenderWindowFocusObserverTag; mitk::DisplayActionEventBroadcast::Pointer m_DisplayActionEventBroadcast; std::unique_ptr<mitk::DisplayActionEventHandler> m_DisplayActionEventHandler; QmitkMultiWidgetLayoutManager* m_LayoutManager; }; -QmitkAbstractMultiWidget::Impl::Impl(QmitkAbstractMultiWidget* multiWidget, - const QString& multiWidgetName) +QmitkAbstractMultiWidget::Impl::Impl(QmitkAbstractMultiWidget* multiWidget, const QString& multiWidgetName) : m_DataStorage(nullptr) , m_MultiWidgetName(multiWidgetName) , m_MultiWidgetRows(0) , m_MultiWidgetColumns(0) + , m_RenderWindowFocusObserverTag(0) , m_DisplayActionEventBroadcast(nullptr) , m_DisplayActionEventHandler(nullptr) , m_LayoutManager(new QmitkMultiWidgetLayoutManager(multiWidget)) { + auto command = itk::MemberCommand<QmitkAbstractMultiWidget>::New(); + command->SetCallbackFunction(multiWidget, &QmitkAbstractMultiWidget::OnFocusChanged); + m_RenderWindowFocusObserverTag = + mitk::RenderingManager::GetInstance()->AddObserver(mitk::FocusChangedEvent(), command); + InitializeDisplayActionEventHandling(); } +QmitkAbstractMultiWidget::Impl::~Impl() +{ + mitk::RenderingManager::GetInstance()->RemoveObserver(m_RenderWindowFocusObserverTag); +} + QmitkAbstractMultiWidget::QmitkAbstractMultiWidget(QWidget* parent, Qt::WindowFlags f/* = 0*/, const QString& multiWidgetName/* = "multiwidget"*/) : QWidget(parent, f) , m_Impl(std::make_unique<Impl>(this, multiWidgetName)) { // nothing here } QmitkAbstractMultiWidget::~QmitkAbstractMultiWidget() { } void QmitkAbstractMultiWidget::SetDataStorage(mitk::DataStorage* dataStorage) { m_Impl->SetDataStorage(dataStorage); } mitk::DataStorage* QmitkAbstractMultiWidget::GetDataStorage() const { return m_Impl->m_DataStorage; } int QmitkAbstractMultiWidget::GetRowCount() const { return m_Impl->m_MultiWidgetRows; } int QmitkAbstractMultiWidget::GetColumnCount() const { return m_Impl->m_MultiWidgetColumns; } void QmitkAbstractMultiWidget::SetLayout(int row, int column) { m_Impl->m_MultiWidgetRows = row; m_Impl->m_MultiWidgetColumns = column; SetLayoutImpl(); } void QmitkAbstractMultiWidget::SetInteractionScheme(mitk::InteractionSchemeSwitcher::InteractionScheme scheme) { auto interactionSchemeSwitcher = mitk::InteractionSchemeSwitcher::New(); auto interactionEventHandler = GetInteractionEventHandler(); try { interactionSchemeSwitcher->SetInteractionScheme(interactionEventHandler, scheme); } catch (const mitk::Exception&) { return; } SetInteractionSchemeImpl(); } mitk::InteractionEventHandler* QmitkAbstractMultiWidget::GetInteractionEventHandler() { return m_Impl->m_DisplayActionEventBroadcast.GetPointer(); } void QmitkAbstractMultiWidget::SetDisplayActionEventHandler(std::unique_ptr<mitk::DisplayActionEventHandler> displayActionEventHandler) { m_Impl->m_DisplayActionEventHandler = std::move(displayActionEventHandler); m_Impl->m_DisplayActionEventHandler->SetObservableBroadcast(m_Impl->m_DisplayActionEventBroadcast); } mitk::DisplayActionEventHandler* QmitkAbstractMultiWidget::GetDisplayActionEventHandler() { return m_Impl->m_DisplayActionEventHandler.get(); } QmitkAbstractMultiWidget::RenderWindowWidgetMap QmitkAbstractMultiWidget::GetRenderWindowWidgets() const { return m_Impl->m_RenderWindowWidgets; } QmitkAbstractMultiWidget::RenderWindowWidgetMap QmitkAbstractMultiWidget::Get2DRenderWindowWidgets() const { RenderWindowWidgetMap renderWindowWidgets2D; auto renderWindowWidgets = GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { auto renderWindow = renderWindowWidget.second->GetRenderWindow(); if(mitk::BaseRenderer::Standard2D == mitk::BaseRenderer::GetInstance(renderWindow->GetVtkRenderWindow())->GetMapperID()) { renderWindowWidgets2D.insert(std::make_pair(renderWindowWidget.first, renderWindowWidget.second)); } } return renderWindowWidgets2D; } QmitkAbstractMultiWidget::RenderWindowWidgetMap QmitkAbstractMultiWidget::Get3DRenderWindowWidgets() const { RenderWindowWidgetMap renderWindowWidgets3D; auto renderWindowWidgets = GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { auto renderWindow = renderWindowWidget.second->GetRenderWindow(); if (mitk::BaseRenderer::Standard3D == mitk::BaseRenderer::GetInstance(renderWindow->GetVtkRenderWindow())->GetMapperID()) { renderWindowWidgets3D.insert(std::make_pair(renderWindowWidget.first, renderWindowWidget.second)); } } return renderWindowWidgets3D; } QmitkAbstractMultiWidget::RenderWindowWidgetPointer QmitkAbstractMultiWidget::GetRenderWindowWidget(int row, int column) const { return GetRenderWindowWidget(GetNameFromIndex(row, column)); } QmitkAbstractMultiWidget::RenderWindowWidgetPointer QmitkAbstractMultiWidget::GetRenderWindowWidget(const QString& widgetName) const { RenderWindowWidgetMap::const_iterator it = m_Impl->m_RenderWindowWidgets.find(widgetName); if (it != m_Impl->m_RenderWindowWidgets.end()) { return it->second; } return nullptr; } QmitkAbstractMultiWidget::RenderWindowWidgetPointer QmitkAbstractMultiWidget::GetRenderWindowWidget(const QmitkRenderWindow* renderWindow) const { auto renderWindowWidgets = GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { if (renderWindowWidget.second->GetRenderWindow() == renderWindow) { return renderWindowWidget.second; } } return nullptr; } QmitkAbstractMultiWidget::RenderWindowHash QmitkAbstractMultiWidget::GetRenderWindows() const { RenderWindowHash result; // create QHash on demand auto renderWindowWidgets = GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { result.insert(renderWindowWidget.first, renderWindowWidget.second->GetRenderWindow()); } return result; } QmitkRenderWindow* QmitkAbstractMultiWidget::GetRenderWindow(int row, int column) const { return GetRenderWindow(GetNameFromIndex(row, column)); } QmitkRenderWindow* QmitkAbstractMultiWidget::GetRenderWindow(const QString& widgetName) const { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { return renderWindowWidget->GetRenderWindow(); } return nullptr; } void QmitkAbstractMultiWidget::SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget) { m_Impl->m_ActiveRenderWindowWidget = activeRenderWindowWidget; emit ActiveRenderWindowChanged(); } QmitkAbstractMultiWidget::RenderWindowWidgetPointer QmitkAbstractMultiWidget::GetActiveRenderWindowWidget() const { return m_Impl->m_ActiveRenderWindowWidget; } QmitkAbstractMultiWidget::RenderWindowWidgetPointer QmitkAbstractMultiWidget::GetFirstRenderWindowWidget() const { if (!m_Impl->m_RenderWindowWidgets.empty()) { return m_Impl->m_RenderWindowWidgets.begin()->second; } else { return nullptr; } } QmitkAbstractMultiWidget::RenderWindowWidgetPointer QmitkAbstractMultiWidget::GetLastRenderWindowWidget() const { if (!m_Impl->m_RenderWindowWidgets.empty()) { return m_Impl->m_RenderWindowWidgets.rbegin()->second; } else { return nullptr; } } QString QmitkAbstractMultiWidget::GetNameFromIndex(int row, int column) const { if (0 <= row && m_Impl->m_MultiWidgetRows > row && 0 <= column && m_Impl->m_MultiWidgetColumns > column) { return GetNameFromIndex(row * m_Impl->m_MultiWidgetColumns + column); } return QString(); } QString QmitkAbstractMultiWidget::GetNameFromIndex(size_t index) const { if (index <= m_Impl->m_RenderWindowWidgets.size()) { return m_Impl->m_MultiWidgetName + ".widget" + QString::number(index); } return QString(); } unsigned int QmitkAbstractMultiWidget::GetNumberOfRenderWindowWidgets() const { return m_Impl->m_RenderWindowWidgets.size(); } void QmitkAbstractMultiWidget::RequestUpdate(const QString& widgetName) { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { return renderWindowWidget->RequestUpdate(); } } void QmitkAbstractMultiWidget::RequestUpdateAll() { for (const auto& renderWindowWidget : m_Impl->m_RenderWindowWidgets) { renderWindowWidget.second->RequestUpdate(); } } void QmitkAbstractMultiWidget::ForceImmediateUpdate(const QString& widgetName) { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { renderWindowWidget->ForceImmediateUpdate(); } } void QmitkAbstractMultiWidget::ForceImmediateUpdateAll() { for (const auto& renderWindowWidget : m_Impl->m_RenderWindowWidgets) { renderWindowWidget.second->ForceImmediateUpdate(); } } void QmitkAbstractMultiWidget::ActivateMenuWidget(bool state) { for (const auto& renderWindowWidget : m_Impl->m_RenderWindowWidgets) { auto renderWindow = renderWindowWidget.second->GetRenderWindow(); renderWindow->ActivateMenuWidget(state); } } bool QmitkAbstractMultiWidget::IsMenuWidgetEnabled() const { return m_Impl->m_ActiveRenderWindowWidget->GetRenderWindow()->GetActivateMenuWidgetFlag(); } QmitkMultiWidgetLayoutManager* QmitkAbstractMultiWidget::GetMultiWidgetLayoutManager() const { return m_Impl->m_LayoutManager; } +void QmitkAbstractMultiWidget::OnFocusChanged(itk::Object*, const itk::EventObject& event) +{ + auto focusEvent = dynamic_cast<const mitk::FocusChangedEvent*>(&event); + if (nullptr == focusEvent) + { + return; + } + + auto focusedRenderWindow = mitk::RenderingManager::GetInstance()->GetFocusedRenderWindow(); + RenderWindowWidgetMap renderWindowWidgets = this->GetRenderWindowWidgets(); + for (const auto& renderWindowWidget : renderWindowWidgets) + { + const auto vtkRenderWindow = renderWindowWidget.second->GetRenderWindow()->GetVtkRenderWindow(); + if (vtkRenderWindow == focusedRenderWindow) + { + this->SetActiveRenderWindowWidget(renderWindowWidget.second); + break; + } + } +} + void QmitkAbstractMultiWidget::AddRenderWindowWidget(const QString& widgetName, RenderWindowWidgetPointer renderWindowWidget) { m_Impl->m_RenderWindowWidgets.insert(std::make_pair(widgetName, renderWindowWidget)); } void QmitkAbstractMultiWidget::RemoveRenderWindowWidget() { auto iterator = m_Impl->m_RenderWindowWidgets.find(GetNameFromIndex(GetRenderWindowWidgets().size() - 1)); if (iterator == m_Impl->m_RenderWindowWidgets.end()) { return; } // disconnect each signal of this render window widget RenderWindowWidgetPointer renderWindowWidgetToRemove = iterator->second; disconnect(renderWindowWidgetToRemove.get(), 0, 0, 0); // erase the render window from the map m_Impl->m_RenderWindowWidgets.erase(iterator); } diff --git a/Modules/QtWidgets/src/QmitkLevelWindowWidgetContextMenu.cpp b/Modules/QtWidgets/src/QmitkLevelWindowWidgetContextMenu.cpp index dd290731b4..4423c16d4d 100644 --- a/Modules/QtWidgets/src/QmitkLevelWindowWidgetContextMenu.cpp +++ b/Modules/QtWidgets/src/QmitkLevelWindowWidgetContextMenu.cpp @@ -1,304 +1,276 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <QmitkLevelWindowWidgetContextMenu.h> // mitk core #include <mitkRenderingManager.h> // mitk qt widgets #include "QmitkLevelWindowPresetDefinitionDialog.h" #include "QmitkLevelWindowRangeChangeDialog.h" // qt #include <QCursor> QmitkLevelWindowWidgetContextMenu::QmitkLevelWindowWidgetContextMenu(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { m_LevelWindowPreset = mitk::LevelWindowPreset::New(); m_LevelWindowPreset->LoadPreset(); } QmitkLevelWindowWidgetContextMenu::~QmitkLevelWindowWidgetContextMenu() { m_LevelWindowPreset->Delete(); } void QmitkLevelWindowWidgetContextMenu::OnSetPreset(const QAction *presetAction) { QString item = presetAction->text(); if (!(presetAction == m_PresetAction)) { double dlevel = m_LevelWindowPreset->getLevel(item.toStdString()); double dwindow = m_LevelWindowPreset->getWindow(item.toStdString()); - if ((dlevel + dwindow / 2) > m_LevelWindow.GetRangeMax()) - { - double lowerBound = (dlevel - dwindow / 2); - if (!(lowerBound > m_LevelWindow.GetRangeMax())) - { - dwindow = m_LevelWindow.GetRangeMax() - lowerBound; - dlevel = lowerBound + dwindow / 2; - } - else - { - dlevel = m_LevelWindow.GetRangeMax() - 1; - dwindow = 2; - } - } - else if ((dlevel - dwindow / 2) < m_LevelWindow.GetRangeMin()) - { - double upperBound = (dlevel + dwindow / 2); - if (!(upperBound < m_LevelWindow.GetRangeMin())) - { - dwindow = m_LevelWindow.GetRangeMin() + upperBound; - dlevel = upperBound - dwindow / 2; - } - else - { - dlevel = m_LevelWindow.GetRangeMin() + 1; - dwindow = 2; - } - } m_LevelWindow.SetLevelWindow(dlevel, dwindow); m_Manager->SetLevelWindow(m_LevelWindow); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLevelWindowWidgetContextMenu::SetLevelWindowManager(mitk::LevelWindowManager *levelWindowManager) { m_Manager = levelWindowManager; } void QmitkLevelWindowWidgetContextMenu::OnAddPreset() { QmitkLevelWindowPresetDefinitionDialog addPreset(this); addPreset.setPresets(m_LevelWindowPreset->getLevelPresets(), m_LevelWindowPreset->getWindowPresets(), QString::number((int)m_LevelWindow.GetLevel()), QString::number((int)m_LevelWindow.GetWindow())); if (addPreset.exec()) { m_LevelWindowPreset->newPresets(addPreset.getLevelPresets(), addPreset.getWindowPresets()); } } void QmitkLevelWindowWidgetContextMenu::OnSetFixed() { m_LevelWindow.SetFixed(!m_LevelWindow.GetFixed()); m_Manager->SetLevelWindow(m_LevelWindow); } void QmitkLevelWindowWidgetContextMenu::OnUseAllGreyvaluesFromImage() { m_LevelWindow.SetToImageRange(m_Manager->GetCurrentImage()); m_Manager->SetLevelWindow(m_LevelWindow); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLevelWindowWidgetContextMenu::OnUseOptimizedLevelWindow() { m_LevelWindow.SetAuto(m_Manager->GetCurrentImage(), false, false); m_Manager->SetLevelWindow(m_LevelWindow); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLevelWindowWidgetContextMenu::OnSetDefaultLevelWindow() { m_LevelWindow.ResetDefaultLevelWindow(); m_Manager->SetLevelWindow(m_LevelWindow); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLevelWindowWidgetContextMenu::OnSetMaximumWindow() { m_LevelWindow.SetToMaxWindowSize(); m_Manager->SetLevelWindow(m_LevelWindow); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLevelWindowWidgetContextMenu::OnSetDefaultScaleRange() { m_LevelWindow.ResetDefaultRangeMinMax(); m_LevelWindow.SetLevelWindow(m_LevelWindow.GetLevel(), m_LevelWindow.GetWindow()); m_Manager->SetLevelWindow(m_LevelWindow); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLevelWindowWidgetContextMenu::OnChangeScaleRange() { QmitkLevelWindowRangeChangeDialog changeRange(this); changeRange.setLowerLimit((mitk::ScalarType)m_LevelWindow.GetRangeMin()); changeRange.setUpperLimit((mitk::ScalarType)m_LevelWindow.GetRangeMax()); if (changeRange.exec()) { m_LevelWindow.SetRangeMinMax(changeRange.getLowerLimit(), changeRange.getUpperLimit()); m_LevelWindow.SetLevelWindow(m_LevelWindow.GetLevel(), m_LevelWindow.GetWindow()); m_Manager->SetLevelWindow(m_LevelWindow); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLevelWindowWidgetContextMenu::OnSetImage(QAction *imageAction) { if (imageAction == m_AutoTopmostAction) { if (m_Manager->IsAutoTopMost() == false) { m_Manager->SetAutoTopMostImage(true); m_SelectedImagesAction->setChecked(false); } else { m_Manager->SetAutoTopMostImage(false); } } else if(imageAction == m_SelectedImagesAction) { if (m_Manager->IsSelectedImages() == false) { m_Manager->SetSelectedImages(true); m_AutoTopmostAction->setChecked(false); } else { m_Manager->SetSelectedImages(false); } } else { m_AutoTopmostAction->setChecked(false); m_SelectedImagesAction->setChecked(false); m_Manager->SetLevelWindowProperty(m_Images.at(imageAction)); } } void QmitkLevelWindowWidgetContextMenu::GetContextMenu(QMenu *contextMenu) { if (nullptr == contextMenu) { return; } try { m_LevelWindow = m_Manager->GetLevelWindow(); QAction *sliderFixed = contextMenu->addAction(tr("Set slider fixed"), this, &QmitkLevelWindowWidgetContextMenu::OnSetFixed); sliderFixed->setCheckable(true); sliderFixed->setChecked(m_LevelWindow.IsFixed()); contextMenu->addSeparator(); contextMenu->addAction(tr("Use whole image grey values"), this, &QmitkLevelWindowWidgetContextMenu::OnUseAllGreyvaluesFromImage); contextMenu->addAction(tr("Use optimized level-window"), this, &QmitkLevelWindowWidgetContextMenu::OnUseOptimizedLevelWindow); contextMenu->addSeparator(); contextMenu->addAction(tr("Set maximum window"), this, &QmitkLevelWindowWidgetContextMenu::OnSetMaximumWindow); contextMenu->addAction(tr("Default level-window"), this, &QmitkLevelWindowWidgetContextMenu::OnSetDefaultLevelWindow); contextMenu->addSeparator(); contextMenu->addAction(tr("Change scale range"), this, &QmitkLevelWindowWidgetContextMenu::OnChangeScaleRange); contextMenu->addAction(tr("Default scale range"), this, &QmitkLevelWindowWidgetContextMenu::OnSetDefaultScaleRange); contextMenu->addSeparator(); m_PresetSubmenu = new QMenu(this); m_PresetSubmenu->setTitle("Presets"); m_PresetAction = m_PresetSubmenu->addAction(tr("Preset definition"), this, &QmitkLevelWindowWidgetContextMenu::OnAddPreset); m_PresetSubmenu->addSeparator(); std::map<std::string, double> preset = m_LevelWindowPreset->getLevelPresets(); for (auto iter = preset.begin(); iter != preset.end(); iter++) { QString item = ((*iter).first.c_str()); m_PresetSubmenu->addAction(item); } connect(m_PresetSubmenu, &QMenu::triggered, this, &QmitkLevelWindowWidgetContextMenu::OnSetPreset); contextMenu->addMenu(m_PresetSubmenu); contextMenu->addSeparator(); m_ImageSubmenu = new QMenu(this); m_ImageSubmenu->setTitle("Images"); // add action for "auto topmost image" action m_AutoTopmostAction = m_ImageSubmenu->addAction(tr("Set topmost image")); m_AutoTopmostAction->setCheckable(true); if (m_Manager->IsAutoTopMost()) { m_AutoTopmostAction->setChecked(true); } // add action for "selected images" action m_SelectedImagesAction = m_ImageSubmenu->addAction(tr("Use selected images")); m_SelectedImagesAction->setCheckable(true); if (m_Manager->IsSelectedImages()) { m_SelectedImagesAction->setChecked(true); } // add action for individual images m_ImageSubmenu->addSeparator(); mitk::DataStorage::SetOfObjects::ConstPointer allObjects = m_Manager->GetRelevantNodes(); for (mitk::DataStorage::SetOfObjects::ConstIterator objectIter = allObjects->Begin(); objectIter != allObjects->End(); ++objectIter) { mitk::DataNode *node = objectIter->Value(); if (nullptr == node) { continue; } bool isHelperObject = false; node->GetBoolProperty("helper object", isHelperObject); if (isHelperObject) { continue; } if (!node->IsVisible(nullptr)) { continue; } mitk::LevelWindowProperty::Pointer levelWindowProperty = dynamic_cast<mitk::LevelWindowProperty *>(node->GetProperty("levelwindow")); if (levelWindowProperty.IsNotNull()) { std::string name; node->GetName(name); QString item = name.c_str(); QAction *id = m_ImageSubmenu->addAction(item); id->setCheckable(true); m_Images[id] = levelWindowProperty; if (levelWindowProperty == m_Manager->GetLevelWindowProperty()) { id->setChecked(true); } } } connect(m_ImageSubmenu, &QMenu::triggered, this, &QmitkLevelWindowWidgetContextMenu::OnSetImage); contextMenu->addMenu(m_ImageSubmenu); contextMenu->exec(QCursor::pos()); } catch (...) { } } void QmitkLevelWindowWidgetContextMenu::GetContextMenu() { auto contextMenu = new QMenu(this); GetContextMenu(contextMenu); delete contextMenu; } diff --git a/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp b/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp index 6146d1e0e7..393363adb8 100644 --- a/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp +++ b/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp @@ -1,273 +1,279 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkMxNMultiWidget.h" #include "QmitkRenderWindowWidget.h" // mitk core #include <mitkDisplayActionEventFunctions.h> #include <mitkDisplayActionEventHandlerDesynchronized.h> #include <mitkDisplayActionEventHandlerSynchronized.h> // qt #include <QGridLayout> QmitkMxNMultiWidget::QmitkMxNMultiWidget(QWidget* parent, Qt::WindowFlags f/* = 0*/, const QString& multiWidgetName/* = "mxnmulti"*/) : QmitkAbstractMultiWidget(parent, f, multiWidgetName) + , m_TimeNavigationController(nullptr) , m_CrosshairVisibility(false) { - // nothing here + m_TimeNavigationController = mitk::RenderingManager::GetInstance()->GetTimeNavigationController(); } +QmitkMxNMultiWidget::~QmitkMxNMultiWidget() +{ + auto allRenderWindows = this->GetRenderWindows(); + for (auto& renderWindow : allRenderWindows) + { + m_TimeNavigationController->Disconnect(renderWindow->GetSliceNavigationController()); + } +} + + void QmitkMxNMultiWidget::InitializeMultiWidget() { SetLayout(1, 1); ActivateMenuWidget(true); SetDisplayActionEventHandler(std::make_unique<mitk::DisplayActionEventHandlerDesynchronized>()); auto displayActionEventHandler = GetDisplayActionEventHandler(); if (nullptr != displayActionEventHandler) { displayActionEventHandler->InitActions(); } } void QmitkMxNMultiWidget::MultiWidgetOpened() { SetCrosshairVisibility(true); } void QmitkMxNMultiWidget::MultiWidgetClosed() { SetCrosshairVisibility(false); } void QmitkMxNMultiWidget::Synchronize(bool synchronized) { if (synchronized) { SetDisplayActionEventHandler(std::make_unique<mitk::DisplayActionEventHandlerSynchronized>()); } else { SetDisplayActionEventHandler(std::make_unique<mitk::DisplayActionEventHandlerDesynchronized>()); } auto displayActionEventHandler = GetDisplayActionEventHandler(); if (nullptr != displayActionEventHandler) { displayActionEventHandler->InitActions(); } } QmitkRenderWindow* QmitkMxNMultiWidget::GetRenderWindow(const QString& widgetName) const { if ("axial" == widgetName || "sagittal" == widgetName || "coronal" == widgetName || "3d" == widgetName) { return GetActiveRenderWindowWidget()->GetRenderWindow(); } return QmitkAbstractMultiWidget::GetRenderWindow(widgetName); } QmitkRenderWindow* QmitkMxNMultiWidget::GetRenderWindow(const mitk::BaseRenderer::ViewDirection& /*viewDirection*/) const { // currently no mapping between view directions and render windows // simply return the currently active render window return GetActiveRenderWindowWidget()->GetRenderWindow(); } void QmitkMxNMultiWidget::SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget) { auto currentActiveRenderWindowWidget = GetActiveRenderWindowWidget(); if (currentActiveRenderWindowWidget == activeRenderWindowWidget) { return; } // reset the decoration color of the previously active render window widget if (nullptr != currentActiveRenderWindowWidget) { auto decorationColor = currentActiveRenderWindowWidget->GetDecorationColor(); QColor hexColor(decorationColor[0] * 255, decorationColor[1] * 255, decorationColor[2] * 255); currentActiveRenderWindowWidget->setStyleSheet("QmitkRenderWindowWidget { border: 2px solid " + hexColor.name(QColor::HexRgb) + "; }"); } // set the new decoration color of the currently active render window widget if (nullptr != activeRenderWindowWidget) { activeRenderWindowWidget->setStyleSheet("QmitkRenderWindowWidget { border: 2px solid #FF6464; }"); } QmitkAbstractMultiWidget::SetActiveRenderWindowWidget(activeRenderWindowWidget); } void QmitkMxNMultiWidget::SetSelectedPosition(const mitk::Point3D& newPosition, const QString& widgetName) { RenderWindowWidgetPointer renderWindowWidget; if (widgetName.isNull()) { renderWindowWidget = GetActiveRenderWindowWidget(); } else { renderWindowWidget = GetRenderWindowWidget(widgetName); } if (nullptr != renderWindowWidget) { renderWindowWidget->GetSliceNavigationController()->SelectSliceByPoint(newPosition); renderWindowWidget->RequestUpdate(); return; } MITK_ERROR << "Position can not be set for an unknown render window widget."; } const mitk::Point3D QmitkMxNMultiWidget::GetSelectedPosition(const QString& /*widgetName*/) const { // see T26208 return mitk::Point3D(); } void QmitkMxNMultiWidget::SetCrosshairVisibility(bool activate) { auto renderWindowWidgets = GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { renderWindowWidget.second->ActivateCrosshair(activate); } m_CrosshairVisibility = activate; } void QmitkMxNMultiWidget::ResetCrosshair() { auto dataStorage = GetDataStorage(); if (nullptr == dataStorage) { return; } mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage); SetWidgetPlaneMode(mitk::InteractionSchemeSwitcher::MITKStandard); } void QmitkMxNMultiWidget::SetWidgetPlaneMode(int userMode) { MITK_DEBUG << "Changing crosshair mode to " << userMode; switch (userMode) { case 0: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKStandard); break; case 1: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKRotationUncoupled); break; case 2: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKRotationCoupled); break; case 3: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKSwivel); break; } } +mitk::SliceNavigationController* QmitkMxNMultiWidget::GetTimeNavigationController() +{ + return m_TimeNavigationController; +} + ////////////////////////////////////////////////////////////////////////// // PUBLIC SLOTS // MOUSE EVENTS ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::wheelEvent(QWheelEvent* e) { emit WheelMoved(e); } -void QmitkMxNMultiWidget::mousePressEvent(QMouseEvent* e) +void QmitkMxNMultiWidget::mousePressEvent(QMouseEvent*) { - if (QEvent::MouseButtonPress != e->type()) - { - return; - } - - auto renderWindowWidget = dynamic_cast<QmitkRenderWindowWidget*>(this->sender()); - if (nullptr == renderWindowWidget) - { - return; - } - - auto renderWindowWidgetPointer = GetRenderWindowWidget(renderWindowWidget->GetWidgetName()); - SetActiveRenderWindowWidget(renderWindowWidgetPointer); + // nothing here, but necessary for mouse interactions (.xml-configuration files) } void QmitkMxNMultiWidget::moveEvent(QMoveEvent* e) { QWidget::moveEvent(e); // it is necessary to readjust the position of the overlays as the MultiWidget has moved // unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here emit Moved(); } ////////////////////////////////////////////////////////////////////////// // PRIVATE ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::SetLayoutImpl() { int requiredRenderWindowWidgets = GetRowCount() * GetColumnCount(); int existingRenderWindowWidgets = GetRenderWindowWidgets().size(); int difference = requiredRenderWindowWidgets - existingRenderWindowWidgets; while (0 < difference) { // more render window widgets needed CreateRenderWindowWidget(); --difference; } while (0 > difference) { // less render window widgets needed RemoveRenderWindowWidget(); ++difference; } auto firstRenderWindowWidget = GetFirstRenderWindowWidget(); if (nullptr != firstRenderWindowWidget) { SetActiveRenderWindowWidget(firstRenderWindowWidget); } GetMultiWidgetLayoutManager()->SetLayoutDesign(QmitkMultiWidgetLayoutManager::LayoutDesign::DEFAULT); } void QmitkMxNMultiWidget::CreateRenderWindowWidget() { // create the render window widget and connect signal / slot QString renderWindowWidgetName = GetNameFromIndex(GetNumberOfRenderWindowWidgets()); RenderWindowWidgetPointer renderWindowWidget = std::make_shared<QmitkRenderWindowWidget>(this, renderWindowWidgetName, GetDataStorage()); renderWindowWidget->SetCornerAnnotationText(renderWindowWidgetName.toStdString()); - - connect(renderWindowWidget.get(), &QmitkRenderWindowWidget::MouseEvent, this, &QmitkMxNMultiWidget::mousePressEvent); - AddRenderWindowWidget(renderWindowWidgetName, renderWindowWidget); auto renderWindow = renderWindowWidget->GetRenderWindow(); auto layoutManager = GetMultiWidgetLayoutManager(); connect(renderWindow, &QmitkRenderWindow::LayoutDesignChanged, layoutManager, &QmitkMultiWidgetLayoutManager::SetLayoutDesign); connect(renderWindow, &QmitkRenderWindow::ResetView, this, &QmitkMxNMultiWidget::ResetCrosshair); connect(renderWindow, &QmitkRenderWindow::CrosshairVisibilityChanged, this, &QmitkMxNMultiWidget::SetCrosshairVisibility); connect(renderWindow, &QmitkRenderWindow::CrosshairRotationModeChanged, this, &QmitkMxNMultiWidget::SetWidgetPlaneMode); + + // connect time navigation controller to react on geometry time events with the render window's slice naviation controller + m_TimeNavigationController->ConnectGeometryTimeEvent(renderWindow->GetSliceNavigationController(), false); + // reverse connection between the render window's slice navigation ontroller and the time navigation controller + renderWindow->GetSliceNavigationController()->ConnectGeometryTimeEvent(m_TimeNavigationController, false); } diff --git a/Modules/QtWidgets/src/QmitkRenderWindowWidget.cpp b/Modules/QtWidgets/src/QmitkRenderWindowWidget.cpp index c30c15cd4f..4ed8d8ac2a 100644 --- a/Modules/QtWidgets/src/QmitkRenderWindowWidget.cpp +++ b/Modules/QtWidgets/src/QmitkRenderWindowWidget.cpp @@ -1,251 +1,249 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkRenderWindowWidget.h" // vtk #include <vtkCornerAnnotation.h> #include <vtkTextProperty.h> QmitkRenderWindowWidget::QmitkRenderWindowWidget(QWidget* parent/* = nullptr*/, const QString& widgetName/* = ""*/, mitk::DataStorage* dataStorage/* = nullptr*/) : QFrame(parent) , m_WidgetName(widgetName) , m_DataStorage(dataStorage) , m_RenderWindow(nullptr) , m_PointSetNode(nullptr) , m_PointSet(nullptr) { this->InitializeGUI(); } QmitkRenderWindowWidget::~QmitkRenderWindowWidget() { auto sliceNavigationController = m_RenderWindow->GetSliceNavigationController(); if (nullptr != sliceNavigationController) { sliceNavigationController->SetCrosshairEvent.RemoveListener(mitk::MessageDelegate1<QmitkRenderWindowWidget, mitk::Point3D>(this, &QmitkRenderWindowWidget::SetCrosshair)); } if (nullptr != m_DataStorage) { m_DataStorage->Remove(m_PointSetNode); } } void QmitkRenderWindowWidget::SetDataStorage(mitk::DataStorage* dataStorage) { if (dataStorage == m_DataStorage) { return; } m_DataStorage = dataStorage; if (nullptr != m_RenderWindow) { mitk::BaseRenderer::GetInstance(m_RenderWindow->renderWindow())->SetDataStorage(dataStorage); } } mitk::SliceNavigationController* QmitkRenderWindowWidget::GetSliceNavigationController() const { return m_RenderWindow->GetSliceNavigationController(); } void QmitkRenderWindowWidget::RequestUpdate() { mitk::RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow->renderWindow()); } void QmitkRenderWindowWidget::ForceImmediateUpdate() { mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(m_RenderWindow->renderWindow()); } void QmitkRenderWindowWidget::SetGradientBackgroundColors(const mitk::Color& upper, const mitk::Color& lower) { vtkRenderer* vtkRenderer = m_RenderWindow->GetRenderer()->GetVtkRenderer(); if (nullptr == vtkRenderer) { return; } m_GradientBackgroundColors.first = upper; m_GradientBackgroundColors.second = lower; vtkRenderer->SetBackground(lower[0], lower[1], lower[2]); vtkRenderer->SetBackground2(upper[0], upper[1], upper[2]); ShowGradientBackground(true); } void QmitkRenderWindowWidget::ShowGradientBackground(bool show) { m_RenderWindow->GetRenderer()->GetVtkRenderer()->SetGradientBackground(show); } bool QmitkRenderWindowWidget::IsGradientBackgroundOn() const { return m_RenderWindow->GetRenderer()->GetVtkRenderer()->GetGradientBackground(); } void QmitkRenderWindowWidget::SetDecorationColor(const mitk::Color& color) { m_DecorationColor = color; m_CornerAnnotation->GetTextProperty()->SetColor(m_DecorationColor[0], m_DecorationColor[1], m_DecorationColor[2]); QColor hexColor(m_DecorationColor[0] * 255, m_DecorationColor[1] * 255, m_DecorationColor[2] * 255); setStyleSheet("QmitkRenderWindowWidget { border: 2px solid " + hexColor.name(QColor::HexRgb) + "; }"); } void QmitkRenderWindowWidget::ShowColoredRectangle(bool show) { if (show) { setFrameStyle(QFrame::Box | QFrame::Plain); } else { setFrameStyle(NoFrame); } } bool QmitkRenderWindowWidget::IsColoredRectangleVisible() const { return frameStyle() > 0; } void QmitkRenderWindowWidget::ShowCornerAnnotation(bool show) { m_CornerAnnotation->SetVisibility(show); } bool QmitkRenderWindowWidget::IsCornerAnnotationVisible() const { return m_CornerAnnotation->GetVisibility() > 0; } void QmitkRenderWindowWidget::SetCornerAnnotationText(const std::string& cornerAnnotation) { m_CornerAnnotation->SetText(0, cornerAnnotation.c_str()); } std::string QmitkRenderWindowWidget::GetCornerAnnotationText() const { return std::string(m_CornerAnnotation->GetText(0)); } bool QmitkRenderWindowWidget::IsRenderWindowMenuActivated() const { return m_RenderWindow->GetActivateMenuWidgetFlag(); } void QmitkRenderWindowWidget::ActivateCrosshair(bool activate) { if (nullptr == m_DataStorage) { return; } if (activate) { try { m_DataStorage->Add(m_PointSetNode); } catch(std::invalid_argument& /*e*/) { // crosshair already existing return; } } else { m_DataStorage->Remove(m_PointSetNode); } } void QmitkRenderWindowWidget::InitializeGUI() { m_Layout = new QHBoxLayout(this); m_Layout->setMargin(0); setLayout(m_Layout); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setContentsMargins(0, 0, 0, 0); if (nullptr == m_DataStorage) { return; } mitk::RenderingManager::GetInstance()->SetDataStorage(m_DataStorage); // create render window for this render window widget m_RenderWindow = new QmitkRenderWindow(this, m_WidgetName, nullptr); m_RenderWindow->SetLayoutIndex(mitk::BaseRenderer::ViewDirection::SAGITTAL); m_RenderWindow->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Sagittal); m_RenderWindow->GetSliceNavigationController()->SetCrosshairEvent.AddListener(mitk::MessageDelegate1<QmitkRenderWindowWidget, mitk::Point3D>(this, &QmitkRenderWindowWidget::SetCrosshair)); - connect(m_RenderWindow, &QmitkRenderWindow::mouseEvent, this, &QmitkRenderWindowWidget::MouseEvent); - mitk::TimeGeometry::ConstPointer timeGeometry = m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(timeGeometry); m_Layout->addWidget(m_RenderWindow); // add point set as a crosshair m_PointSetNode = mitk::DataNode::New(); m_PointSetNode->SetProperty("name", mitk::StringProperty::New("Crosshair of render window " + m_WidgetName.toStdString())); m_PointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true)); // crosshair-node should typically be invisible // set the crosshair only visible for this specific renderer m_PointSetNode->SetBoolProperty("fixedLayer", true, m_RenderWindow->GetRenderer()); m_PointSetNode->SetVisibility(true, m_RenderWindow->GetRenderer()); m_PointSetNode->SetVisibility(false); m_PointSet = mitk::PointSet::New(); m_PointSetNode->SetData(m_PointSet); // set colors and corner annotation InitializeDecorations(); } void QmitkRenderWindowWidget::InitializeDecorations() { vtkRenderer* vtkRenderer = m_RenderWindow->GetRenderer()->GetVtkRenderer(); if (nullptr == vtkRenderer) { return; } // initialize background color gradients float black[3] = { 0.0f, 0.0f, 0.0f }; SetGradientBackgroundColors(black, black); // initialize annotation text and decoration color setFrameStyle(QFrame::Box | QFrame::Plain); m_CornerAnnotation = vtkSmartPointer<vtkCornerAnnotation>::New(); m_CornerAnnotation->SetText(0, "Sagittal"); m_CornerAnnotation->SetMaximumFontSize(12); if (0 == vtkRenderer->HasViewProp(m_CornerAnnotation)) { vtkRenderer->AddViewProp(m_CornerAnnotation); } float white[3] = { 1.0f, 1.0f, 1.0f }; SetDecorationColor(mitk::Color(white)); } void QmitkRenderWindowWidget::SetCrosshair(mitk::Point3D selectedPoint) { m_PointSet->SetPoint(1, selectedPoint, 0); mitk::RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow->renderWindow()); } diff --git a/Modules/QtWidgets/src/QmitkStdMultiWidget.cpp b/Modules/QtWidgets/src/QmitkStdMultiWidget.cpp index 2b83c9cb66..57d17f093c 100644 --- a/Modules/QtWidgets/src/QmitkStdMultiWidget.cpp +++ b/Modules/QtWidgets/src/QmitkStdMultiWidget.cpp @@ -1,823 +1,808 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #define SMW_INFO MITK_INFO("widget.stdmulti") #include "QmitkStdMultiWidget.h" #include "QmitkRenderWindowWidget.h" // mitk core #include <mitkCameraController.h> #include <mitkImage.h> #include <mitkImagePixelReadAccessor.h> #include <mitkInteractionConst.h> #include <mitkLine.h> #include <mitkNodePredicateBase.h> #include <mitkNodePredicateDataType.h> #include <mitkNodePredicateNot.h> #include <mitkNodePredicateProperty.h> #include <mitkPixelTypeMultiplex.h> #include <mitkPlaneGeometryDataMapper2D.h> #include <mitkPointSet.h> #include <mitkProperties.h> #include <mitkStatusBar.h> #include <mitkDisplayActionEventHandlerStd.h> #include <mitkVtkLayerController.h> // qt #include <QList> #include <QMouseEvent> #include <QTimer> // vtk #include <vtkSmartPointer.h> // c++ #include <iomanip> QmitkStdMultiWidget::QmitkStdMultiWidget(QWidget *parent, Qt::WindowFlags f/* = 0*/, const QString &name/* = "stdmulti"*/) : QmitkAbstractMultiWidget(parent, f, name) , m_TimeNavigationController(nullptr) , m_PendingCrosshairPositionEvent(false) { m_TimeNavigationController = mitk::RenderingManager::GetInstance()->GetTimeNavigationController(); } QmitkStdMultiWidget::~QmitkStdMultiWidget() { - m_TimeNavigationController->Disconnect(GetRenderWindow1()->GetSliceNavigationController()); - m_TimeNavigationController->Disconnect(GetRenderWindow2()->GetSliceNavigationController()); - m_TimeNavigationController->Disconnect(GetRenderWindow3()->GetSliceNavigationController()); - m_TimeNavigationController->Disconnect(GetRenderWindow4()->GetSliceNavigationController()); + auto allRenderWindows = this->GetRenderWindows(); + for (auto& renderWindow : allRenderWindows) + { + m_TimeNavigationController->Disconnect(renderWindow->GetSliceNavigationController()); + } } void QmitkStdMultiWidget::InitializeMultiWidget() { // yellow is default color for widget4 m_DecorationColorWidget4[0] = 1.0f; m_DecorationColorWidget4[1] = 1.0f; m_DecorationColorWidget4[2] = 0.0f; SetLayout(2, 2); // transfer colors in WorldGeometry-Nodes of the associated Renderer mitk::IntProperty::Pointer layer; // of widget 1 m_PlaneNode1 = mitk::BaseRenderer::GetInstance(GetRenderWindow1()->renderWindow())->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode1->SetColor(GetDecorationColor(0)); layer = mitk::IntProperty::New(1000); m_PlaneNode1->SetProperty("layer", layer); // of widget 2 m_PlaneNode2 = mitk::BaseRenderer::GetInstance(GetRenderWindow2()->renderWindow())->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode2->SetColor(GetDecorationColor(1)); layer = mitk::IntProperty::New(1000); m_PlaneNode2->SetProperty("layer", layer); // of widget 3 m_PlaneNode3 = mitk::BaseRenderer::GetInstance(GetRenderWindow3()->renderWindow())->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode3->SetColor(GetDecorationColor(2)); layer = mitk::IntProperty::New(1000); m_PlaneNode3->SetProperty("layer", layer); // the parent node m_ParentNodeForGeometryPlanes = mitk::BaseRenderer::GetInstance(GetRenderWindow4()->renderWindow())->GetCurrentWorldPlaneGeometryNode(); layer = mitk::IntProperty::New(1000); m_ParentNodeForGeometryPlanes->SetProperty("layer", layer); AddDisplayPlaneSubTree(); SetDisplayActionEventHandler(std::make_unique<mitk::DisplayActionEventHandlerStd>()); auto displayActionEventHandler = GetDisplayActionEventHandler(); if (nullptr != displayActionEventHandler) { displayActionEventHandler->InitActions(); } } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow(const QString& widgetName) const { if ("axial" == widgetName) { return GetRenderWindow1(); } if ("sagittal" == widgetName) { return GetRenderWindow2(); } if ("coronal" == widgetName) { return GetRenderWindow3(); } if ("3d" == widgetName) { return GetRenderWindow4(); } return QmitkAbstractMultiWidget::GetRenderWindow(widgetName); } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow(const mitk::BaseRenderer::ViewDirection& viewDirection) const { return GetRenderWindow(static_cast<unsigned int>(viewDirection)); } void QmitkStdMultiWidget::SetSelectedPosition(const mitk::Point3D& newPosition, const QString& /*widgetName*/) { GetRenderWindow1()->GetSliceNavigationController()->SelectSliceByPoint(newPosition); GetRenderWindow2()->GetSliceNavigationController()->SelectSliceByPoint(newPosition); GetRenderWindow3()->GetSliceNavigationController()->SelectSliceByPoint(newPosition); RequestUpdateAll(); } const mitk::Point3D QmitkStdMultiWidget::GetSelectedPosition(const QString& /*widgetName*/) const { const mitk::PlaneGeometry* plane1 = GetRenderWindow1()->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry* plane2 = GetRenderWindow2()->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry* plane3 = GetRenderWindow3()->GetSliceNavigationController()->GetCurrentPlaneGeometry(); mitk::Line3D line; if ((plane1 != nullptr) && (plane2 != nullptr) && (plane1->IntersectionLine(plane2, line))) { mitk::Point3D point; if ((plane3 != nullptr) && (plane3->IntersectionPoint(line, point))) { return point; } } return mitk::Point3D(); } void QmitkStdMultiWidget::SetCrosshairVisibility(bool visible) { if (m_PlaneNode1.IsNotNull()) { m_PlaneNode1->SetVisibility(visible); } if (m_PlaneNode2.IsNotNull()) { m_PlaneNode2->SetVisibility(visible); } if (m_PlaneNode3.IsNotNull()) { m_PlaneNode3->SetVisibility(visible); } emit NotifyCrosshairVisibilityChanged(visible); RequestUpdateAll(); } bool QmitkStdMultiWidget::GetCrosshairVisibility() const { bool crosshairVisibility = true; if (m_PlaneNode1.IsNotNull()) { bool visibilityProperty = false; m_PlaneNode1->GetVisibility(visibilityProperty, nullptr); crosshairVisibility &= visibilityProperty; } if (m_PlaneNode2.IsNotNull()) { bool visibilityProperty = false; crosshairVisibility &= m_PlaneNode2->GetVisibility(visibilityProperty, nullptr); crosshairVisibility &= visibilityProperty; } if (m_PlaneNode3.IsNotNull()) { bool visibilityProperty = false; crosshairVisibility &= m_PlaneNode3->GetVisibility(visibilityProperty, nullptr); crosshairVisibility &= visibilityProperty; } return crosshairVisibility; } void QmitkStdMultiWidget::ResetCrosshair() { auto dataStorage = GetDataStorage(); if (nullptr == dataStorage) { return; } mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage); SetWidgetPlaneMode(mitk::InteractionSchemeSwitcher::MITKStandard); } void QmitkStdMultiWidget::SetWidgetPlaneMode(int userMode) { MITK_DEBUG << "Changing crosshair mode to " << userMode; switch (userMode) { case 0: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKStandard); break; case 1: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKRotationUncoupled); break; case 2: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKRotationCoupled); break; case 3: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKSwivel); break; } emit NotifyCrosshairRotationModeChanged(userMode); } mitk::SliceNavigationController* QmitkStdMultiWidget::GetTimeNavigationController() { return m_TimeNavigationController; } void QmitkStdMultiWidget::AddPlanesToDataStorage() { auto dataStorage = GetDataStorage(); if (nullptr == dataStorage) { return; } if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_ParentNodeForGeometryPlanes.IsNotNull()) { dataStorage->Add(m_ParentNodeForGeometryPlanes); dataStorage->Add(m_PlaneNode1, m_ParentNodeForGeometryPlanes); dataStorage->Add(m_PlaneNode2, m_ParentNodeForGeometryPlanes); dataStorage->Add(m_PlaneNode3, m_ParentNodeForGeometryPlanes); } } void QmitkStdMultiWidget::RemovePlanesFromDataStorage() { auto dataStorage = GetDataStorage(); if (nullptr == dataStorage) { return; } if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_ParentNodeForGeometryPlanes.IsNotNull()) { dataStorage->Remove(m_PlaneNode1); dataStorage->Remove(m_PlaneNode2); dataStorage->Remove(m_PlaneNode3); dataStorage->Remove(m_ParentNodeForGeometryPlanes); } } void QmitkStdMultiWidget::HandleCrosshairPositionEvent() { if (!m_PendingCrosshairPositionEvent) { m_PendingCrosshairPositionEvent = true; QTimer::singleShot(0, this, SLOT(HandleCrosshairPositionEventDelayed())); } } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow(unsigned int number) const { switch (number) { case 0: return GetRenderWindow1(); case 1: return GetRenderWindow2(); case 2: return GetRenderWindow3(); case 3: return GetRenderWindow4(); default: MITK_ERROR << "Requested unknown render window"; break; } return nullptr; } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow1() const { return QmitkAbstractMultiWidget::GetRenderWindow(GetNameFromIndex(0, 0)); } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow2() const { return QmitkAbstractMultiWidget::GetRenderWindow(GetNameFromIndex(0, 1)); } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow3() const { return QmitkAbstractMultiWidget::GetRenderWindow(GetNameFromIndex(1, 0)); } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow4() const { return QmitkAbstractMultiWidget::GetRenderWindow(GetNameFromIndex(1, 1)); } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane1() const { return m_PlaneNode1; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane2() const { return m_PlaneNode2; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane3() const { return m_PlaneNode3; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane(unsigned number) const { switch (number) { case 1: return m_PlaneNode1; case 2: return m_PlaneNode2; case 3: return m_PlaneNode3; default: MITK_ERROR << "Requested unknown render window"; break; } return nullptr; } void QmitkStdMultiWidget::SetDecorationColor(unsigned int widgetNumber, mitk::Color color) { switch (widgetNumber) { case 0: if (m_PlaneNode1.IsNotNull()) { m_PlaneNode1->SetColor(color); } break; case 1: if (m_PlaneNode2.IsNotNull()) { m_PlaneNode2->SetColor(color); } break; case 2: if (m_PlaneNode3.IsNotNull()) { m_PlaneNode3->SetColor(color); } break; case 3: m_DecorationColorWidget4 = color; break; default: MITK_ERROR << "Decoration color for unknown widget!"; break; } } mitk::Color QmitkStdMultiWidget::GetDecorationColor(unsigned int widgetNumber) { // The implementation looks a bit messy here, but it avoids // synchronization of the color of the geometry nodes and an // internal member here. // Default colors were chosen for decent visibility. // Feel free to change your preferences in the workbench. float tmp[3] = { 0.0f, 0.0f, 0.0f }; switch (widgetNumber) { case 0: { if (m_PlaneNode1.IsNotNull()) { if (m_PlaneNode1->GetColor(tmp)) { return dynamic_cast<mitk::ColorProperty *>(m_PlaneNode1->GetProperty("color"))->GetColor(); } } float red[3] = { 0.753f, 0.0f, 0.0f }; // This is #C00000 in hex return mitk::Color(red); } case 1: { if (m_PlaneNode2.IsNotNull()) { if (m_PlaneNode2->GetColor(tmp)) { return dynamic_cast<mitk::ColorProperty *>(m_PlaneNode2->GetProperty("color"))->GetColor(); } } float green[3] = { 0.0f, 0.69f, 0.0f }; // This is #00B000 in hex return mitk::Color(green); } case 2: { if (m_PlaneNode3.IsNotNull()) { if (m_PlaneNode3->GetColor(tmp)) { return dynamic_cast<mitk::ColorProperty *>(m_PlaneNode3->GetProperty("color"))->GetColor(); } } float blue[3] = { 0.0, 0.502f, 1.0f }; // This is #0080FF in hex return mitk::Color(blue); } case 3: { return m_DecorationColorWidget4; } default: MITK_ERROR << "Decoration color for unknown widget!"; float black[3] = { 0.0f, 0.0f, 0.0f }; return mitk::Color(black); } } -void QmitkStdMultiWidget::mousePressEvent(QMouseEvent* e) +void QmitkStdMultiWidget::mousePressEvent(QMouseEvent*) { - if (QEvent::MouseButtonPress != e->type()) - { - return; - } - - auto renderWindowWidget = dynamic_cast<QmitkRenderWindowWidget*>(this->sender()); - if (nullptr == renderWindowWidget) - { - return; - } - - auto renderWindowWidgetPointer = GetRenderWindowWidget(renderWindowWidget->GetWidgetName()); - SetActiveRenderWindowWidget(renderWindowWidgetPointer); + // nothing here, but necessary for mouse interactions (.xml-configuration files) } void QmitkStdMultiWidget::moveEvent(QMoveEvent* e) { QWidget::moveEvent(e); // it is necessary to readjust the position of the Annotation as the StdMultiWidget has moved // unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here emit Moved(); } void QmitkStdMultiWidget::wheelEvent(QWheelEvent* e) { emit WheelMoved(e); } void QmitkStdMultiWidget::HandleCrosshairPositionEventDelayed() { auto dataStorage = GetDataStorage(); if (nullptr == dataStorage) { return; } m_PendingCrosshairPositionEvent = false; // find image with highest layer mitk::TNodePredicateDataType<mitk::Image>::Pointer isImageData = mitk::TNodePredicateDataType<mitk::Image>::New(); mitk::DataStorage::SetOfObjects::ConstPointer nodes = dataStorage->GetSubset(isImageData).GetPointer(); mitk::Point3D crosshairPos = GetSelectedPosition(""); mitk::BaseRenderer* baseRenderer = GetRenderWindow1()->GetSliceNavigationController()->GetRenderer(); auto globalCurrentTimePoint = baseRenderer->GetTime(); mitk::DataNode::Pointer node = mitk::FindTopmostVisibleNode(nodes, crosshairPos, globalCurrentTimePoint, baseRenderer); mitk::DataNode::Pointer topSourceNode; mitk::Image::Pointer image; bool isBinary = false; int component = 0; if (node.IsNotNull()) { node->GetBoolProperty("binary", isBinary); if (isBinary) { mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = dataStorage->GetSources(node, nullptr, true); if (!sourcenodes->empty()) { topSourceNode = mitk::FindTopmostVisibleNode(sourcenodes, crosshairPos, globalCurrentTimePoint, baseRenderer); } if (topSourceNode.IsNotNull()) { image = dynamic_cast<mitk::Image *>(topSourceNode->GetData()); topSourceNode->GetIntProperty("Image.Displayed Component", component); } else { image = dynamic_cast<mitk::Image *>(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } else { image = dynamic_cast<mitk::Image *>(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } std::string statusText; std::stringstream stream; itk::Index<3> p; unsigned int timestep = baseRenderer->GetTimeStep(); if (image.IsNotNull() && (image->GetTimeSteps() > timestep)) { image->GetGeometry()->WorldToIndex(crosshairPos, p); stream.precision(2); stream << "Position: <" << std::fixed << crosshairPos[0] << ", " << std::fixed << crosshairPos[1] << ", " << std::fixed << crosshairPos[2] << "> mm"; stream << "; Index: <" << p[0] << ", " << p[1] << ", " << p[2] << "> "; mitk::ScalarType pixelValue; mitkPixelTypeMultiplex5(mitk::FastSinglePixelAccess, image->GetChannelDescriptor().GetPixelType(), image, image->GetVolumeData(image->GetTimeGeometry()->TimePointToTimeStep(globalCurrentTimePoint)), p, pixelValue, component); if (fabs(pixelValue) > 1000000 || fabs(pixelValue) < 0.01) { stream << "; Time: " << globalCurrentTimePoint << " ms; Pixelvalue: " << std::scientific << pixelValue << " "; } else { stream << "; Time: " << globalCurrentTimePoint << " ms; Pixelvalue: " << pixelValue << " "; } } else { stream << "No image information at this position!"; } statusText = stream.str(); mitk::StatusBar::GetInstance()->DisplayGreyValueText(statusText.c_str()); } void QmitkStdMultiWidget::Fit() { vtkSmartPointer<vtkRenderer> vtkrenderer; vtkrenderer = mitk::BaseRenderer::GetInstance(GetRenderWindow1()->renderWindow())->GetVtkRenderer(); if (nullptr != vtkrenderer) { vtkrenderer->ResetCamera(); } vtkrenderer = mitk::BaseRenderer::GetInstance(GetRenderWindow2()->renderWindow())->GetVtkRenderer(); if (nullptr != vtkrenderer) { vtkrenderer->ResetCamera(); } vtkrenderer = mitk::BaseRenderer::GetInstance(GetRenderWindow3()->renderWindow())->GetVtkRenderer(); if (nullptr != vtkrenderer) { vtkrenderer->ResetCamera(); } vtkrenderer = mitk::BaseRenderer::GetInstance(GetRenderWindow4()->renderWindow())->GetVtkRenderer(); if (nullptr != vtkrenderer) { vtkrenderer->ResetCamera(); } mitk::BaseRenderer::GetInstance(GetRenderWindow1()->renderWindow())->GetCameraController()->Fit(); mitk::BaseRenderer::GetInstance(GetRenderWindow2()->renderWindow())->GetCameraController()->Fit(); mitk::BaseRenderer::GetInstance(GetRenderWindow3()->renderWindow())->GetCameraController()->Fit(); mitk::BaseRenderer::GetInstance(GetRenderWindow4()->renderWindow())->GetCameraController()->Fit(); int w = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); vtkObject::SetGlobalWarningDisplay(w); } void QmitkStdMultiWidget::AddDisplayPlaneSubTree() { // add the displayed planes of the multiwidget to a node to which the subtree // @a planesSubTree points ... mitk::PlaneGeometryDataMapper2D::Pointer mapper; // ... of widget 1 mitk::BaseRenderer* renderer1 = mitk::BaseRenderer::GetInstance(GetRenderWindow1()->renderWindow()); m_PlaneNode1 = renderer1->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode1->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode1->SetProperty("name", mitk::StringProperty::New(std::string(renderer1->GetName()) + ".plane")); m_PlaneNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode1->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 2 mitk::BaseRenderer* renderer2 = mitk::BaseRenderer::GetInstance(GetRenderWindow2()->renderWindow()); m_PlaneNode2 = renderer2->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode2->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode2->SetProperty("name", mitk::StringProperty::New(std::string(renderer2->GetName()) + ".plane")); m_PlaneNode2->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode2->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode2->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 3 mitk::BaseRenderer *renderer3 = mitk::BaseRenderer::GetInstance(GetRenderWindow3()->renderWindow()); m_PlaneNode3 = renderer3->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode3->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode3->SetProperty("name", mitk::StringProperty::New(std::string(renderer3->GetName()) + ".plane")); m_PlaneNode3->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode3->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode3->SetMapper(mitk::BaseRenderer::Standard2D, mapper); m_ParentNodeForGeometryPlanes = mitk::DataNode::New(); m_ParentNodeForGeometryPlanes->SetProperty("name", mitk::StringProperty::New("Widgets")); m_ParentNodeForGeometryPlanes->SetProperty("helper object", mitk::BoolProperty::New(true)); } void QmitkStdMultiWidget::EnsureDisplayContainsPoint(mitk::BaseRenderer *renderer, const mitk::Point3D &p) { mitk::Point2D pointOnDisplay; renderer->WorldToDisplay(p, pointOnDisplay); if (pointOnDisplay[0] < renderer->GetVtkRenderer()->GetOrigin()[0] || pointOnDisplay[1] < renderer->GetVtkRenderer()->GetOrigin()[1] || pointOnDisplay[0] > renderer->GetVtkRenderer()->GetOrigin()[0] + renderer->GetViewportSize()[0] || pointOnDisplay[1] > renderer->GetVtkRenderer()->GetOrigin()[1] + renderer->GetViewportSize()[1]) { mitk::Point2D pointOnPlane; renderer->GetCurrentWorldPlaneGeometry()->Map(p, pointOnPlane); renderer->GetCameraController()->MoveCameraToPoint(pointOnPlane); } } void QmitkStdMultiWidget::SetWidgetPlaneVisibility(const char *widgetName, bool visible, mitk::BaseRenderer *renderer) { auto dataStorage = GetDataStorage(); if (nullptr != dataStorage) { mitk::DataNode* dataNode = dataStorage->GetNamedNode(widgetName); if (dataNode != nullptr) { dataNode->SetVisibility(visible, renderer); } } } void QmitkStdMultiWidget::SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer) { if (m_PlaneNode1.IsNotNull()) { m_PlaneNode1->SetVisibility(visible, renderer); } if (m_PlaneNode2.IsNotNull()) { m_PlaneNode2->SetVisibility(visible, renderer); } if (m_PlaneNode3.IsNotNull()) { m_PlaneNode3->SetVisibility(visible, renderer); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } ////////////////////////////////////////////////////////////////////////// // PRIVATE ////////////////////////////////////////////////////////////////////////// void QmitkStdMultiWidget::SetLayoutImpl() { CreateRenderWindowWidgets(); GetMultiWidgetLayoutManager()->SetLayoutDesign(QmitkMultiWidgetLayoutManager::LayoutDesign::DEFAULT); // Initialize views as axial, sagittal, coronal to all data objects in DataStorage auto geo = GetDataStorage()->ComputeBoundingGeometry3D(GetDataStorage()->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(geo); } void QmitkStdMultiWidget::CreateRenderWindowWidgets() { // create axial render window (widget) QString renderWindowWidgetName = GetNameFromIndex(0, 0); RenderWindowWidgetPointer renderWindowWidget1 = std::make_shared<QmitkRenderWindowWidget>(this, renderWindowWidgetName, GetDataStorage()); auto renderWindow1 = renderWindowWidget1->GetRenderWindow(); renderWindow1->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial); renderWindowWidget1->SetDecorationColor(GetDecorationColor(0)); renderWindowWidget1->SetCornerAnnotationText("Axial"); renderWindowWidget1->GetRenderWindow()->SetLayoutIndex(ViewDirection::AXIAL); AddRenderWindowWidget(renderWindowWidgetName, renderWindowWidget1); // create sagittal render window (widget) renderWindowWidgetName = GetNameFromIndex(0, 1); RenderWindowWidgetPointer renderWindowWidget2 = std::make_shared<QmitkRenderWindowWidget>(this, renderWindowWidgetName, GetDataStorage()); auto renderWindow2 = renderWindowWidget2->GetRenderWindow(); renderWindow2->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Sagittal); renderWindowWidget2->SetDecorationColor(GetDecorationColor(1)); renderWindowWidget2->setStyleSheet("border: 0px"); renderWindowWidget2->SetCornerAnnotationText("Sagittal"); renderWindowWidget2->GetRenderWindow()->SetLayoutIndex(ViewDirection::SAGITTAL); AddRenderWindowWidget(renderWindowWidgetName, renderWindowWidget2); // create coronal render window (widget) renderWindowWidgetName = GetNameFromIndex(1, 0); RenderWindowWidgetPointer renderWindowWidget3 = std::make_shared<QmitkRenderWindowWidget>(this, renderWindowWidgetName, GetDataStorage()); auto renderWindow3 = renderWindowWidget3->GetRenderWindow(); renderWindow3->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Frontal); renderWindowWidget3->SetDecorationColor(GetDecorationColor(2)); renderWindowWidget3->SetCornerAnnotationText("Coronal"); renderWindowWidget3->GetRenderWindow()->SetLayoutIndex(ViewDirection::CORONAL); AddRenderWindowWidget(renderWindowWidgetName, renderWindowWidget3); // create 3D render window (widget) renderWindowWidgetName = GetNameFromIndex(1, 1); RenderWindowWidgetPointer renderWindowWidget4 = std::make_shared<QmitkRenderWindowWidget>(this, renderWindowWidgetName, GetDataStorage()); auto renderWindow4 = renderWindowWidget4->GetRenderWindow(); renderWindow4->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Original); renderWindowWidget4->SetDecorationColor(GetDecorationColor(3)); renderWindowWidget4->SetCornerAnnotationText("3D"); renderWindowWidget4->GetRenderWindow()->SetLayoutIndex(ViewDirection::THREE_D); mitk::BaseRenderer::GetInstance(renderWindowWidget4->GetRenderWindow()->renderWindow())->SetMapperID(mitk::BaseRenderer::Standard3D); AddRenderWindowWidget(renderWindowWidgetName, renderWindowWidget4); SetActiveRenderWindowWidget(renderWindowWidget1); // connect to the "time navigation controller": send time via sliceNavigationControllers m_TimeNavigationController->ConnectGeometryTimeEvent(renderWindow1->GetSliceNavigationController(), false); m_TimeNavigationController->ConnectGeometryTimeEvent(renderWindow2->GetSliceNavigationController(), false); m_TimeNavigationController->ConnectGeometryTimeEvent(renderWindow3->GetSliceNavigationController(), false); m_TimeNavigationController->ConnectGeometryTimeEvent(renderWindow4->GetSliceNavigationController(), false); renderWindow1->GetSliceNavigationController()->ConnectGeometrySendEvent( mitk::BaseRenderer::GetInstance(renderWindow4->renderWindow())); // reverse connection between sliceNavigationControllers and timeNavigationController renderWindow1->GetSliceNavigationController()->ConnectGeometryTimeEvent(m_TimeNavigationController, false); renderWindow2->GetSliceNavigationController()->ConnectGeometryTimeEvent(m_TimeNavigationController, false); renderWindow3->GetSliceNavigationController()->ConnectGeometryTimeEvent(m_TimeNavigationController, false); //renderWindow4->GetSliceNavigationController()->ConnectGeometryTimeEvent(m_TimeNavigationController, false); auto layoutManager = GetMultiWidgetLayoutManager(); - connect(renderWindowWidget1.get(), &QmitkRenderWindowWidget::MouseEvent, this, &QmitkStdMultiWidget::mousePressEvent); connect(renderWindow1, &QmitkRenderWindow::ResetView, this, &QmitkStdMultiWidget::ResetCrosshair); connect(renderWindow1, &QmitkRenderWindow::CrosshairVisibilityChanged, this, &QmitkStdMultiWidget::SetCrosshairVisibility); connect(renderWindow1, &QmitkRenderWindow::CrosshairRotationModeChanged, this, &QmitkStdMultiWidget::SetWidgetPlaneMode); connect(renderWindow1, &QmitkRenderWindow::LayoutDesignChanged, layoutManager, &QmitkMultiWidgetLayoutManager::SetLayoutDesign); connect(this, &QmitkStdMultiWidget::NotifyCrosshairVisibilityChanged, renderWindow1, &QmitkRenderWindow::UpdateCrosshairVisibility); connect(this, &QmitkStdMultiWidget::NotifyCrosshairRotationModeChanged, renderWindow1, &QmitkRenderWindow::UpdateCrosshairRotationMode); - connect(renderWindowWidget2.get(), &QmitkRenderWindowWidget::MouseEvent, this, &QmitkStdMultiWidget::mousePressEvent); connect(renderWindow2, &QmitkRenderWindow::ResetView, this, &QmitkStdMultiWidget::ResetCrosshair); connect(renderWindow2, &QmitkRenderWindow::CrosshairVisibilityChanged, this, &QmitkStdMultiWidget::SetCrosshairVisibility); connect(renderWindow2, &QmitkRenderWindow::CrosshairRotationModeChanged, this, &QmitkStdMultiWidget::SetWidgetPlaneMode); connect(renderWindow2, &QmitkRenderWindow::LayoutDesignChanged, layoutManager, &QmitkMultiWidgetLayoutManager::SetLayoutDesign); connect(this, &QmitkStdMultiWidget::NotifyCrosshairVisibilityChanged, renderWindow2, &QmitkRenderWindow::UpdateCrosshairVisibility); connect(this, &QmitkStdMultiWidget::NotifyCrosshairRotationModeChanged, renderWindow2, &QmitkRenderWindow::UpdateCrosshairRotationMode); - connect(renderWindowWidget3.get(), &QmitkRenderWindowWidget::MouseEvent, this, &QmitkStdMultiWidget::mousePressEvent); connect(renderWindow3, &QmitkRenderWindow::ResetView, this, &QmitkStdMultiWidget::ResetCrosshair); connect(renderWindow3, &QmitkRenderWindow::CrosshairVisibilityChanged, this, &QmitkStdMultiWidget::SetCrosshairVisibility); connect(renderWindow3, &QmitkRenderWindow::CrosshairRotationModeChanged, this, &QmitkStdMultiWidget::SetWidgetPlaneMode); connect(renderWindow3, &QmitkRenderWindow::LayoutDesignChanged, layoutManager, &QmitkMultiWidgetLayoutManager::SetLayoutDesign); connect(this, &QmitkStdMultiWidget::NotifyCrosshairVisibilityChanged, renderWindow3, &QmitkRenderWindow::UpdateCrosshairVisibility); connect(this, &QmitkStdMultiWidget::NotifyCrosshairRotationModeChanged, renderWindow3, &QmitkRenderWindow::UpdateCrosshairRotationMode); - connect(renderWindowWidget4.get(), &QmitkRenderWindowWidget::MouseEvent, this, &QmitkStdMultiWidget::mousePressEvent); connect(renderWindow4, &QmitkRenderWindow::ResetView, this, &QmitkStdMultiWidget::ResetCrosshair); connect(renderWindow4, &QmitkRenderWindow::CrosshairVisibilityChanged, this, &QmitkStdMultiWidget::SetCrosshairVisibility); connect(renderWindow4, &QmitkRenderWindow::CrosshairRotationModeChanged, this, &QmitkStdMultiWidget::SetWidgetPlaneMode); connect(renderWindow4, &QmitkRenderWindow::LayoutDesignChanged, layoutManager, &QmitkMultiWidgetLayoutManager::SetLayoutDesign); connect(this, &QmitkStdMultiWidget::NotifyCrosshairVisibilityChanged, renderWindow4, &QmitkRenderWindow::UpdateCrosshairVisibility); connect(this, &QmitkStdMultiWidget::NotifyCrosshairRotationModeChanged, renderWindow4, &QmitkRenderWindow::UpdateCrosshairRotationMode); } diff --git a/Modules/QtWidgetsExt/include/QmitkTransferFunctionGeneratorWidget.h b/Modules/QtWidgetsExt/include/QmitkTransferFunctionGeneratorWidget.h index 5bf7ea8d64..443f1b7cac 100644 --- a/Modules/QtWidgetsExt/include/QmitkTransferFunctionGeneratorWidget.h +++ b/Modules/QtWidgetsExt/include/QmitkTransferFunctionGeneratorWidget.h @@ -1,80 +1,80 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKTRANSFERFUNCTIONGENERATORWIDGET_H #define QMITKTRANSFERFUNCTIONGENERATORWIDGET_H #include "MitkQtWidgetsExtExports.h" #include "ui_QmitkTransferFunctionGeneratorWidget.h" #include <mitkCommon.h> #include <QWidget> #include <mitkDataNode.h> #include <mitkTransferFunctionProperty.h> class MITKQTWIDGETSEXT_EXPORT QmitkTransferFunctionGeneratorWidget : public QWidget, public Ui::QmitkTransferFunctionGeneratorWidget { Q_OBJECT public: QmitkTransferFunctionGeneratorWidget(QWidget *parent = nullptr, Qt::WindowFlags f = nullptr); ~QmitkTransferFunctionGeneratorWidget() override; - void SetDataNode(mitk::DataNode *node); + void SetDataNode(mitk::DataNode *node, mitk::TimeStepType timestep = 0); int AddPreset(const QString &presetName); void SetPresetsTabEnabled(bool enable); void SetThresholdTabEnabled(bool enable); void SetBellTabEnabled(bool enable); public slots: void OnSavePreset(); void OnLoadPreset(); void OnDeltaLevelWindow(int dx, int dy); void OnDeltaThreshold(int dx, int dy); signals: void SignalTransferFunctionModeChanged(int); void SignalUpdateCanvas(); protected slots: void OnPreset(int mode); protected: mitk::TransferFunctionProperty::Pointer tfpToChange; double histoMinimum; double histoMaximum; double thPos; double thDelta; double deltaScale; double deltaMax; double deltaMin; const mitk::Image::HistogramType *histoGramm; QString presetFileName; double ScaleDelta(int d) const; }; #endif diff --git a/Modules/QtWidgetsExt/include/QmitkTransferFunctionWidget.h b/Modules/QtWidgetsExt/include/QmitkTransferFunctionWidget.h index d1d5a901d4..0ab5534657 100755 --- a/Modules/QtWidgetsExt/include/QmitkTransferFunctionWidget.h +++ b/Modules/QtWidgetsExt/include/QmitkTransferFunctionWidget.h @@ -1,79 +1,79 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKTRANSFERFUNCTIONWIDGET_H #define QMITKTRANSFERFUNCTIONWIDGET_H #include "MitkQtWidgetsExtExports.h" #include "ui_QmitkTransferFunctionWidget.h" #include <mitkCommon.h> #include <QWidget> #include <mitkDataNode.h> #include <mitkTransferFunctionProperty.h> #include <QPushButton> #include <QSlider> #include <QmitkTransferFunctionWidget.h> namespace mitk { class BaseRenderer; } class MITKQTWIDGETSEXT_EXPORT QmitkTransferFunctionWidget : public QWidget, public Ui::QmitkTransferFunctionWidget { Q_OBJECT public: QmitkTransferFunctionWidget(QWidget *parent = nullptr, Qt::WindowFlags f = nullptr); ~QmitkTransferFunctionWidget() override; - void SetDataNode(mitk::DataNode *node, const mitk::BaseRenderer *renderer = nullptr); + void SetDataNode(mitk::DataNode *node, mitk::TimeStepType timestep = 0, const mitk::BaseRenderer *renderer = nullptr); void SetScalarLabel(const QString &scalarLabel); void ShowScalarOpacityFunction(bool show); void ShowColorFunction(bool show); void ShowGradientOpacityFunction(bool show); void SetScalarOpacityFunctionEnabled(bool enable); void SetColorFunctionEnabled(bool enable); void SetGradientOpacityFunctionEnabled(bool enable); public slots: void SetXValueScalar(const QString text); void SetYValueScalar(const QString text); void SetXValueGradient(const QString text); void SetYValueGradient(const QString text); void SetXValueColor(const QString text); void OnUpdateCanvas(); void UpdateRanges(); void OnResetSlider(); void OnSpanChanged(int lower, int upper); protected: mitk::TransferFunctionProperty::Pointer tfpToChange; int m_RangeSliderMin; int m_RangeSliderMax; mitk::SimpleHistogramCache histogramCache; }; #endif diff --git a/Modules/QtWidgetsExt/src/QmitkTransferFunctionGeneratorWidget.cpp b/Modules/QtWidgetsExt/src/QmitkTransferFunctionGeneratorWidget.cpp index e244bb77a1..861c103b23 100644 --- a/Modules/QtWidgetsExt/src/QmitkTransferFunctionGeneratorWidget.cpp +++ b/Modules/QtWidgetsExt/src/QmitkTransferFunctionGeneratorWidget.cpp @@ -1,353 +1,367 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkTransferFunctionGeneratorWidget.h" #include <QFileDialog> #include <QFontMetrics> #include <mitkImageStatisticsHolder.h> #include <mitkRenderingManager.h> #include <mitkTransferFunctionInitializer.h> #include <mitkTransferFunctionProperty.h> #include <mitkUnstructuredGrid.h> #include <mitkTransferFunctionPropertySerializer.h> #include <vtkUnstructuredGrid.h> QmitkTransferFunctionGeneratorWidget::QmitkTransferFunctionGeneratorWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f), deltaScale(1.0), deltaMax(1024), deltaMin(1) { histoGramm = nullptr; this->setupUi(this); // LevelWindow Tab { connect(m_CrossLevelWindow, SIGNAL(SignalDeltaMove(int, int)), this, SLOT(OnDeltaLevelWindow(int, int))); } // Threshold Tab { connect(m_CrossThreshold, SIGNAL(SignalDeltaMove(int, int)), this, SLOT(OnDeltaThreshold(int, int))); thDelta = 100; } // Presets Tab { m_TransferFunctionComboBox->setVisible(false); connect(m_TransferFunctionComboBox, SIGNAL(activated(int)), this, SIGNAL(SignalTransferFunctionModeChanged(int))); connect(m_TransferFunctionComboBox, SIGNAL(activated(int)), this, SLOT(OnPreset(int))); connect(m_SavePreset, SIGNAL(clicked()), this, SLOT(OnSavePreset())); connect(m_LoadPreset, SIGNAL(clicked()), this, SLOT(OnLoadPreset())); } presetFileName = "."; } int QmitkTransferFunctionGeneratorWidget::AddPreset(const QString &presetName) { m_TransferFunctionComboBox->setVisible(true); m_TransferFunctionComboBox->addItem(presetName); return m_TransferFunctionComboBox->count() - 1; } void QmitkTransferFunctionGeneratorWidget::SetPresetsTabEnabled(bool enable) { m_PresetTab->setEnabled(enable); } void QmitkTransferFunctionGeneratorWidget::SetThresholdTabEnabled(bool enable) { m_ThresholdTab->setEnabled(enable); } void QmitkTransferFunctionGeneratorWidget::SetBellTabEnabled(bool enable) { m_BellTab->setEnabled(enable); } void QmitkTransferFunctionGeneratorWidget::OnSavePreset() { if (tfpToChange.IsNull()) return; mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); presetFileName = QFileDialog::getSaveFileName( this, "Choose a filename to save the transfer function", presetFileName, "Transferfunction (*.xml)"); if (!presetFileName.endsWith(".xml")) presetFileName.append(".xml"); MITK_INFO << "Saving Transferfunction under path: " << presetFileName.toStdString(); if (mitk::TransferFunctionPropertySerializer::SerializeTransferFunction(presetFileName.toLatin1(), tf)) { QFontMetrics metrics(m_InfoPreset->font()); QString text = metrics.elidedText(presetFileName, Qt::ElideMiddle, m_InfoPreset->width()); m_InfoPreset->setText(QString("saved ") + text); } else { m_InfoPreset->setText(QString("saving failed")); } } void QmitkTransferFunctionGeneratorWidget::OnLoadPreset() { if (tfpToChange.IsNull()) return; presetFileName = QFileDialog::getOpenFileName( this, "Choose a file to open the transfer function from", presetFileName, "Transferfunction (*.xml)"); MITK_INFO << "Loading Transferfunction from path: " << presetFileName.toStdString(); mitk::TransferFunction::Pointer tf = mitk::TransferFunctionPropertySerializer::DeserializeTransferFunction(presetFileName.toLatin1()); if (tf.IsNotNull()) { tfpToChange->SetValue(tf); QFontMetrics metrics(m_InfoPreset->font()); QString text = metrics.elidedText(presetFileName, Qt::ElideMiddle, m_InfoPreset->width()); m_InfoPreset->setText(QString("loaded ") + text); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalUpdateCanvas(); } } void QmitkTransferFunctionGeneratorWidget::OnPreset(int mode) { // first item is only information if (--mode == -1) return; m_InfoPreset->setText(QString("selected ") + m_TransferFunctionComboBox->currentText()); // revert to first item m_TransferFunctionComboBox->setCurrentIndex(0); } static double transformationGlocke(double x) { double z = 0.1; double a = 2 - 2 * z; double b = 2 * z - 1; x = a * x + b; return x; } static double stepFunctionGlocke(double x) { x = 1 - (2 * x - 1.0); // map [0.5;1] to [0,1] x = x * (3 * x - 2 * x * x); // apply smoothing function x = x * x; return x; } double QmitkTransferFunctionGeneratorWidget::ScaleDelta(int d) const { return deltaScale * (double)d; } void QmitkTransferFunctionGeneratorWidget::OnDeltaLevelWindow(int dx, int dy) // bell { if (tfpToChange.IsNull()) return; thPos += ScaleDelta(dx); thDelta -= ScaleDelta(dy); if (thDelta < deltaMin) thDelta = deltaMin; if (thDelta > deltaMax) thDelta = deltaMax; if (thPos < histoMinimum) thPos = histoMinimum; if (thPos > histoMaximum) thPos = histoMaximum; std::stringstream ss; ss << "Click on the cross and move the mouse" << "\n" << "\n" << "center at " << thPos << "\n" << "width " << thDelta * 2; m_InfoLevelWindow->setText(QString(ss.str().c_str())); mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); // grayvalue->opacity { vtkPiecewiseFunction *f = tf->GetScalarOpacityFunction(); f->RemoveAllPoints(); for (int r = 0; r <= 6; r++) { double relPos = (r / 6.0) * 0.5 + 0.5; f->AddPoint(thPos + thDelta * (-transformationGlocke(relPos)), stepFunctionGlocke(relPos)); f->AddPoint(thPos + thDelta * (transformationGlocke(relPos)), stepFunctionGlocke(relPos)); } f->Modified(); } // gradient at grayvalue->opacity { vtkPiecewiseFunction *f = tf->GetGradientOpacityFunction(); f->RemoveAllPoints(); f->AddPoint(0, 1.0); f->Modified(); } tf->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalUpdateCanvas(); } static double stepFunctionThreshold(double x) { x = 0.5 * x + 0.5; // map [-1;1] to [0,1] x = x * (3 * x - 2 * x * x); // apply smoothing function x = x * x; return x; } void QmitkTransferFunctionGeneratorWidget::OnDeltaThreshold(int dx, int dy) // LEVELWINDOW { if (tfpToChange.IsNull()) return; thPos += ScaleDelta(dx); thDelta += ScaleDelta(dy); if (thDelta < deltaMin) thDelta = deltaMin; if (thDelta > deltaMax) thDelta = deltaMax; if (thPos < histoMinimum) thPos = histoMinimum; if (thPos > histoMaximum) thPos = histoMaximum; std::stringstream ss; ss << "Click on the cross and move the mouse" << "\n" << "\n" << "threshold at " << thPos << "\n" << "width " << thDelta * 2; m_InfoThreshold->setText(QString(ss.str().c_str())); mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); // grayvalue->opacity { vtkPiecewiseFunction *f = tf->GetScalarOpacityFunction(); f->RemoveAllPoints(); for (int r = 1; r <= 4; r++) { double relPos = r / 4.0; f->AddPoint(thPos + thDelta * (-relPos), stepFunctionThreshold(-relPos)); f->AddPoint(thPos + thDelta * (relPos), stepFunctionThreshold(relPos)); } f->Modified(); } // gradient at grayvalue->opacity { vtkPiecewiseFunction *f = tf->GetGradientOpacityFunction(); f->RemoveAllPoints(); f->AddPoint(0, 1.0); f->Modified(); } tf->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalUpdateCanvas(); } QmitkTransferFunctionGeneratorWidget::~QmitkTransferFunctionGeneratorWidget() { } -void QmitkTransferFunctionGeneratorWidget::SetDataNode(mitk::DataNode *node) +void QmitkTransferFunctionGeneratorWidget::SetDataNode(mitk::DataNode *node, mitk::TimeStepType timestep) { histoGramm = nullptr; if (node) { tfpToChange = dynamic_cast<mitk::TransferFunctionProperty *>(node->GetProperty("TransferFunction")); if (!tfpToChange) node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New()); mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); if (mitk::Image *image = dynamic_cast<mitk::Image *>(node->GetData())) { - mitk::ImageStatisticsHolder *statistics = image->GetStatistics(); + mitk::Image::Pointer inputImage = image; + if (image->GetTimeSteps() > 1) + { + if (!image->GetTimeGeometry()->IsValidTimeStep(timestep)) + { + return; + } + mitk::ImageTimeSelector::Pointer timeselector = mitk::ImageTimeSelector::New(); + timeselector->SetInput(image); + timeselector->SetTimeNr(timestep); + timeselector->UpdateLargestPossibleRegion(); + inputImage = timeselector->GetOutput(); + } + + mitk::ImageStatisticsHolder *statistics = inputImage->GetStatistics(); histoMinimum = statistics->GetScalarValueMin(); histoMaximum = statistics->GetScalarValueMax(); } else if (mitk::UnstructuredGrid *grid = dynamic_cast<mitk::UnstructuredGrid *>(node->GetData())) { double *range = grid->GetVtkUnstructuredGrid()->GetScalarRange(); histoMinimum = range[0]; histoMaximum = range[1]; double histoRange = histoMaximum - histoMinimum; deltaMax = histoRange / 4.0; deltaMin = histoRange / 400.0; deltaScale = histoRange / 1024.0; } else { MITK_WARN << "QmitkTransferFunctonGeneratorWidget does not support " << node->GetData()->GetNameOfClass() << " instances"; } thPos = (histoMinimum + histoMaximum) / 2.0; } else { tfpToChange = nullptr; m_InfoPreset->setText(QString("")); } } diff --git a/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.cpp b/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.cpp index bde5c54854..2f5e727ba6 100755 --- a/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.cpp +++ b/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.cpp @@ -1,246 +1,263 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkTransferFunctionWidget.h" +#include "mitkImageTimeSelector.h" #include <mitkTransferFunctionProperty.h> QmitkTransferFunctionWidget::QmitkTransferFunctionWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { this->setupUi(this); // signals and slots connections connect(m_XEditScalarOpacity, SIGNAL(textEdited(const QString &)), this, SLOT(SetXValueScalar(const QString &))); connect(m_YEditScalarOpacity, SIGNAL(textEdited(const QString &)), this, SLOT(SetYValueScalar(const QString &))); connect(m_XEditGradientOpacity, SIGNAL(textEdited(const QString &)), this, SLOT(SetXValueGradient(const QString &))); connect(m_YEditGradientOpacity, SIGNAL(textEdited(const QString &)), this, SLOT(SetYValueGradient(const QString &))); connect(m_XEditColor, SIGNAL(textEdited(const QString &)), this, SLOT(SetXValueColor(const QString &))); m_RangeSlider->setMinimum(-2048); m_RangeSlider->setMaximum(2048); connect(m_RangeSlider, SIGNAL(valuesChanged(int, int)), this, SLOT(OnSpanChanged(int, int))); // reset button connect(m_RangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetSlider())); m_ScalarOpacityFunctionCanvas->SetQLineEdits(m_XEditScalarOpacity, m_YEditScalarOpacity); m_GradientOpacityCanvas->SetQLineEdits(m_XEditGradientOpacity, m_YEditGradientOpacity); m_ColorTransferFunctionCanvas->SetQLineEdits(m_XEditColor, nullptr); m_ScalarOpacityFunctionCanvas->SetTitle("Grayvalue -> Opacity"); m_GradientOpacityCanvas->SetTitle("Grayvalue/Gradient -> Opacity"); m_ColorTransferFunctionCanvas->SetTitle("Grayvalue -> Color"); } QmitkTransferFunctionWidget::~QmitkTransferFunctionWidget() { } void QmitkTransferFunctionWidget::SetScalarLabel(const QString &scalarLabel) { m_textLabelX->setText(scalarLabel); m_textLabelX_2->setText(scalarLabel); m_textLabelX_3->setText(scalarLabel); m_ScalarOpacityFunctionCanvas->SetTitle(scalarLabel + " -> Opacity"); m_GradientOpacityCanvas->SetTitle(scalarLabel + "/Gradient -> Opacity"); m_ColorTransferFunctionCanvas->SetTitle(scalarLabel + " -> Color"); } void QmitkTransferFunctionWidget::ShowScalarOpacityFunction(bool show) { m_ScalarOpacityWidget->setVisible(show); } void QmitkTransferFunctionWidget::ShowColorFunction(bool show) { m_ColorWidget->setVisible(show); } void QmitkTransferFunctionWidget::ShowGradientOpacityFunction(bool show) { m_GradientOpacityWidget->setVisible(show); } void QmitkTransferFunctionWidget::SetScalarOpacityFunctionEnabled(bool enable) { m_ScalarOpacityWidget->setEnabled(enable); } void QmitkTransferFunctionWidget::SetColorFunctionEnabled(bool enable) { m_ColorWidget->setEnabled(enable); } void QmitkTransferFunctionWidget::SetGradientOpacityFunctionEnabled(bool enable) { m_GradientOpacityWidget->setEnabled(enable); } -void QmitkTransferFunctionWidget::SetDataNode(mitk::DataNode *node, const mitk::BaseRenderer *renderer) +void QmitkTransferFunctionWidget::SetDataNode(mitk::DataNode *node, mitk::TimeStepType timestep, const mitk::BaseRenderer *renderer) { if (node) { tfpToChange = dynamic_cast<mitk::TransferFunctionProperty *>(node->GetProperty("TransferFunction", renderer)); - if (!tfpToChange) { if (!dynamic_cast<mitk::Image *>(node->GetData())) { MITK_WARN << "QmitkTransferFunctionWidget::SetDataNode called with non-image node"; goto turnOff; } node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New()); } mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); - if (mitk::BaseData *data = node->GetData()) + if (mitk::Image *data = dynamic_cast<mitk::Image *>(node->GetData())) { - mitk::SimpleHistogram *h = histogramCache[data]; + mitk::SimpleHistogram *h = nullptr; + if (data->GetTimeSteps() > 1) + { + if (!data->GetTimeGeometry()->IsValidTimeStep(timestep)) + { + return; + } + mitk::ImageTimeSelector::Pointer timeselector = mitk::ImageTimeSelector::New(); + timeselector->SetInput(data); + timeselector->SetTimeNr(timestep); + timeselector->UpdateLargestPossibleRegion(); + auto inputImage = timeselector->GetOutput(); + h = histogramCache[inputImage]; + } + else + { + h = histogramCache[data]; + } m_RangeSliderMin = h->GetMin(); m_RangeSliderMax = h->GetMax(); m_RangeSlider->blockSignals(true); m_RangeSlider->setMinimum(m_RangeSliderMin); m_RangeSlider->setMaximum(m_RangeSliderMax); m_RangeSlider->setMinimumValue(m_RangeSliderMin); m_RangeSlider->setMaximumValue(m_RangeSliderMax); m_RangeSlider->blockSignals(false); m_ScalarOpacityFunctionCanvas->SetHistogram(h); m_GradientOpacityCanvas->SetHistogram(h); m_ColorTransferFunctionCanvas->SetHistogram(h); } OnUpdateCanvas(); return; } turnOff: m_ScalarOpacityFunctionCanvas->setEnabled(false); m_ScalarOpacityFunctionCanvas->SetHistogram(nullptr); m_GradientOpacityCanvas->setEnabled(false); m_GradientOpacityCanvas->SetHistogram(nullptr); m_ColorTransferFunctionCanvas->setEnabled(false); m_ColorTransferFunctionCanvas->SetHistogram(nullptr); tfpToChange = nullptr; } void QmitkTransferFunctionWidget::OnUpdateCanvas() { if (tfpToChange.IsNull()) return; mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); if (tf.IsNull()) return; m_ScalarOpacityFunctionCanvas->SetPiecewiseFunction(tf->GetScalarOpacityFunction()); m_GradientOpacityCanvas->SetPiecewiseFunction(tf->GetGradientOpacityFunction()); m_ColorTransferFunctionCanvas->SetColorTransferFunction(tf->GetColorTransferFunction()); UpdateRanges(); m_ScalarOpacityFunctionCanvas->update(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); } void QmitkTransferFunctionWidget::SetXValueScalar(const QString text) { if (!text.endsWith(".")) { m_ScalarOpacityFunctionCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetYValueScalar(const QString text) { if (!text.endsWith(".")) { m_ScalarOpacityFunctionCanvas->SetY(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetXValueGradient(const QString text) { if (!text.endsWith(".")) { m_GradientOpacityCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetYValueGradient(const QString text) { if (!text.endsWith(".")) { m_GradientOpacityCanvas->SetY(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetXValueColor(const QString text) { if (!text.endsWith(".")) { m_ColorTransferFunctionCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::UpdateRanges() { int lower = m_RangeSlider->minimumValue(); int upper = m_RangeSlider->maximumValue(); m_ScalarOpacityFunctionCanvas->SetMin(lower); m_ScalarOpacityFunctionCanvas->SetMax(upper); m_GradientOpacityCanvas->SetMin(lower); m_GradientOpacityCanvas->SetMax(upper); m_ColorTransferFunctionCanvas->SetMin(lower); m_ColorTransferFunctionCanvas->SetMax(upper); } void QmitkTransferFunctionWidget::OnSpanChanged(int, int) { UpdateRanges(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); m_ScalarOpacityFunctionCanvas->update(); } void QmitkTransferFunctionWidget::OnResetSlider() { m_RangeSlider->blockSignals(true); m_RangeSlider->setMaximumValue(m_RangeSliderMax); m_RangeSlider->setMinimumValue(m_RangeSliderMin); m_RangeSlider->blockSignals(false); UpdateRanges(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); m_ScalarOpacityFunctionCanvas->update(); } diff --git a/Modules/SceneSerialization/src/mitkImageSerializer.cpp b/Modules/SceneSerialization/src/mitkImageSerializer.cpp index 82ded44882..6d262f9322 100644 --- a/Modules/SceneSerialization/src/mitkImageSerializer.cpp +++ b/Modules/SceneSerialization/src/mitkImageSerializer.cpp @@ -1,57 +1,57 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkImageSerializer.h" #include "mitkIOUtil.h" #include "mitkImage.h" #include <Poco/Path.h> MITK_REGISTER_SERIALIZER(ImageSerializer) mitk::ImageSerializer::ImageSerializer() { } mitk::ImageSerializer::~ImageSerializer() { } std::string mitk::ImageSerializer::Serialize() { const auto *image = dynamic_cast<const Image *>(m_Data.GetPointer()); if (!image) { MITK_ERROR << " Object at " << (const void *)this->m_Data << " is not an mitk::Image. Cannot serialize as image."; return ""; } std::string filename(this->GetUniqueFilenameInWorkingDirectory()); std::cout << "creating file " << filename << " in " << m_WorkingDirectory << std::endl; filename += "_"; filename += m_FilenameHint; std::string fullname(m_WorkingDirectory); fullname += Poco::Path::separator(); fullname += filename + ".nrrd"; try { IOUtil::Save(image, fullname); } catch (std::exception &e) { MITK_ERROR << " Error serializing object at " << (const void *)this->m_Data << " to " << fullname << ": " << e.what(); return ""; } - return Poco::Path(fullname).getFileName(); // + ".pic"; + return Poco::Path(fullname).getFileName(); } diff --git a/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp b/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp index c55bf4e681..46060c5661 100644 --- a/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp +++ b/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp @@ -1,457 +1,462 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkSceneReaderV1.h" #include "Poco/Path.h" #include "mitkBaseRenderer.h" #include "mitkIOUtil.h" #include "mitkProgressBar.h" #include "mitkPropertyListDeserializer.h" #include "mitkSerializerMacros.h" #include <mitkUIDManipulator.h> #include <mitkRenderingModeProperty.h> #include <tinyxml2.h> MITK_REGISTER_SERIALIZER(SceneReaderV1) namespace { typedef std::pair<mitk::DataNode::Pointer, std::list<std::string>> NodesAndParentsPair; bool NodeSortByLayerIsLessThan(const NodesAndParentsPair &left, const NodesAndParentsPair &right) { if (left.first.IsNotNull() && right.first.IsNotNull()) { int leftLayer; int rightLayer; if (left.first->GetIntProperty("layer", leftLayer) && right.first->GetIntProperty("layer", rightLayer)) { return leftLayer < rightLayer; } else { // fall back to name sort return left.first->GetName() < right.first->GetName(); } } // in all other cases, fall back to stupid pointer comparison // this is not reasonable but at least answers the sorting // question clearly return left.first.GetPointer() < right.first.GetPointer(); } // This is a workaround until we are able to save time-related information in an // actual file format of surfaces. void ApplyProportionalTimeGeometryProperties(mitk::BaseData* data) { if (nullptr == data) return; auto properties = data->GetPropertyList(); if (properties.IsNull()) return; auto* geometry = dynamic_cast<mitk::ProportionalTimeGeometry*>(data->GetTimeGeometry()); if (nullptr == geometry) return; float value = 0.0f; if (properties->GetFloatProperty("ProportionalTimeGeometry.FirstTimePoint", value)) + { + if (value == -std::numeric_limits<float>::infinity()) + value = std::numeric_limits<float>::lowest(); + geometry->SetFirstTimePoint(value); + } if (properties->GetFloatProperty("ProportionalTimeGeometry.StepDuration", value)) geometry->SetStepDuration(value); } } bool mitk::SceneReaderV1::LoadScene(tinyxml2::XMLDocument &document, const std::string &workingDirectory, DataStorage *storage) { assert(storage); bool error(false); // TODO prepare to detect errors (such as cycles) from wrongly written or edited xml files // Get number of elements to initialze progress bar // 1. if there is a <data type="..." file="..."> element, // - construct a name for the appropriate serializer // - try to instantiate this serializer via itk object factory // - if serializer could be created, use it to read the file into a BaseData object // - if successful, call the new node's SetData(..) // create a node for the tag "data" and test if node was created typedef std::vector<mitk::DataNode::Pointer> DataNodeVector; DataNodeVector DataNodes; unsigned int listSize = 0; for (auto *element = document.FirstChildElement("node"); element != nullptr; element = element->NextSiblingElement("node")) { ++listSize; } ProgressBar::GetInstance()->AddStepsToDo(listSize * 2); for (auto *element = document.FirstChildElement("node"); element != nullptr; element = element->NextSiblingElement("node")) { DataNodes.push_back(LoadBaseDataFromDataTag(element->FirstChildElement("data"), workingDirectory, error)); ProgressBar::GetInstance()->Progress(); } // iterate all nodes // first level nodes should be <node> elements auto nit = DataNodes.begin(); for (auto *element = document.FirstChildElement("node"); element != nullptr || nit != DataNodes.end(); element = element->NextSiblingElement("node"), ++nit) { mitk::DataNode::Pointer node = *nit; // in case dataXmlElement is valid test whether it containts the "properties" child tag // and process further if and only if yes auto *dataXmlElement = element->FirstChildElement("data"); if (dataXmlElement && dataXmlElement->FirstChildElement("properties")) { auto *baseDataElement = dataXmlElement->FirstChildElement("properties"); if (node->GetData()) { DecorateBaseDataWithProperties(node->GetData(), baseDataElement, workingDirectory); ApplyProportionalTimeGeometryProperties(node->GetData()); } else { MITK_WARN << "BaseData properties stored in scene file, but BaseData could not be read" << std::endl; } } // 2. check child nodes const char *uida = element->Attribute("UID"); std::string uid(""); if (uida) { uid = uida; m_NodeForID[uid] = node.GetPointer(); m_IDForNode[node.GetPointer()] = uid; } else { MITK_ERROR << "No UID found for current node. Node will have no parents."; error = true; } // 3. if there are <properties> nodes, // - instantiate the appropriate PropertyListDeSerializer // - use them to construct PropertyList objects // - add these properties to the node (if necessary, use renderwindow name) bool success = DecorateNodeWithProperties(node, element, workingDirectory); if (!success) { MITK_ERROR << "Could not load properties for node."; error = true; } // remember node for later adding to DataStorage m_OrderedNodePairs.push_back(std::make_pair(node, std::list<std::string>())); // 4. if there are <source> elements, remember parent objects for (auto *source = element->FirstChildElement("source"); source != nullptr; source = source->NextSiblingElement("source")) { const char *sourceUID = source->Attribute("UID"); if (sourceUID) { m_OrderedNodePairs.back().second.push_back(std::string(sourceUID)); } } ProgressBar::GetInstance()->Progress(); } // end for all <node> // sort our nodes by their "layer" property // (to be inserted in that order) m_OrderedNodePairs.sort(&NodeSortByLayerIsLessThan); // remove all unknown parent UIDs for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { for (auto parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end();) { if (m_NodeForID.find(*parentsIter) == m_NodeForID.end()) { parentsIter = nodesIter->second.erase(parentsIter); MITK_WARN << "Found a DataNode with unknown parents. Will add it to DataStorage without any parent objects."; error = true; } else { ++parentsIter; } } } // repeat the following loop ... // ... for all created nodes unsigned int lastMapSize(0); while (lastMapSize != m_OrderedNodePairs .size()) // this is to prevent infinite loops; each iteration must at least add one node to DataStorage { lastMapSize = m_OrderedNodePairs.size(); // iterate (layer) ordered nodes backwards // we insert the highest layers first for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { bool addThisNode(true); // if any parent node is not yet in DataStorage, skip node for now and check later for (auto parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end(); ++parentsIter) { if (!storage->Exists(m_NodeForID[*parentsIter])) { addThisNode = false; break; } } if (addThisNode) { DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New(); for (auto parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end(); ++parentsIter) { parents->push_back(m_NodeForID[*parentsIter]); } // if all parents are found in datastorage (or are unknown), add node to DataStorage storage->Add(nodesIter->first, parents); // remove this node from m_OrderedNodePairs m_OrderedNodePairs.erase(nodesIter); // break this for loop because iterators are probably invalid break; } } } // All nodes that are still in m_OrderedNodePairs at this point are not part of a proper directed graph structure. // We'll add such nodes without any parent information. for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { storage->Add(nodesIter->first); MITK_WARN << "Encountered node that is not part of a directed graph structure. Will be added to DataStorage " "without parents."; error = true; } return !error; } mitk::DataNode::Pointer mitk::SceneReaderV1::LoadBaseDataFromDataTag(const tinyxml2::XMLElement *dataElement, const std::string &workingDirectory, bool &error) { DataNode::Pointer node; if (dataElement) { const char *filename = dataElement->Attribute("file"); if (filename && strlen(filename) != 0) { try { std::vector<BaseData::Pointer> baseData = IOUtil::Load(workingDirectory + Poco::Path::separator() + filename); if (baseData.size() > 1) { MITK_WARN << "Discarding multiple base data results from " << filename << " except the first one."; } node = DataNode::New(); node->SetData(baseData.front()); } catch (std::exception &e) { MITK_ERROR << "Error during attempt to read '" << filename << "'. Exception says: " << e.what(); error = true; } if (node.IsNull()) { MITK_ERROR << "Error during attempt to read '" << filename << "'. Factory returned nullptr object."; error = true; } } const char* dataUID = dataElement->Attribute("UID"); if (!error && dataUID != nullptr) { UIDManipulator manip(node->GetData()); manip.SetUID(dataUID); } } // in case there was no <data> element we create a new empty node (for appending a propertylist later) if (node.IsNull()) { node = DataNode::New(); } return node; } void mitk::SceneReaderV1::ClearNodePropertyListWithExceptions(DataNode &node, PropertyList &propertyList) { // Basically call propertyList.Clear(), but implement exceptions (see bug 19354) BaseData *data = node.GetData(); PropertyList::Pointer propertiesToKeep = PropertyList::New(); if (dynamic_cast<Image *>(data)) { /* Older scene files (before changes of bug 17547) could contain a RenderingMode property with value "LevelWindow_Color". Since bug 17547 this value has been removed and replaced by the default value LookupTable_LevelWindow_Color. This new default value does only result in "black-to-white" CT images (or others) if there is a corresponding lookup table. Such a lookup table is provided as a default value by the Image mapper. Since that value was never present in older scene files, we do well in not removing the new default value here. Otherwise the mapper would fall back to another default which is all the colors of the rainbow :-( */ BaseProperty::Pointer lutProperty = propertyList.GetProperty("LookupTable"); propertiesToKeep->SetProperty("LookupTable", lutProperty); /* Older scene files (before changes of T14807) may contain multi-component images without the "Image.Displayed Component" property. As the treatment as multi-component image and the corresponding visualization options hinges on that property we should not delete it, if it was added by the mapper. This is a fix for the issue reported in T19919. */ BaseProperty::Pointer compProperty = propertyList.GetProperty("Image.Displayed Component"); if (compProperty.IsNotNull()) { propertiesToKeep->SetProperty("Image.Displayed Component", compProperty); } } propertyList.Clear(); propertyList.ConcatenatePropertyList(propertiesToKeep); } bool mitk::SceneReaderV1::DecorateNodeWithProperties(DataNode *node, const tinyxml2::XMLElement *nodeElement, const std::string &workingDirectory) { assert(node); assert(nodeElement); bool error(false); for (auto *properties = nodeElement->FirstChildElement("properties"); properties != nullptr; properties = properties->NextSiblingElement("properties")) { const char *propertiesfilea(properties->Attribute("file")); std::string propertiesfile(propertiesfilea ? propertiesfilea : ""); const char *renderwindowa(properties->Attribute("renderwindow")); std::string renderwindow(renderwindowa ? renderwindowa : ""); PropertyList::Pointer propertyList = node->GetPropertyList(renderwindow); // DataNode implementation always returns a propertylist ClearNodePropertyListWithExceptions(*node, *propertyList); // use deserializer to construct new properties PropertyListDeserializer::Pointer deserializer = PropertyListDeserializer::New(); deserializer->SetFilename(workingDirectory + Poco::Path::separator() + propertiesfile); bool success = deserializer->Deserialize(); error |= !success; PropertyList::Pointer readProperties = deserializer->GetOutput(); if (readProperties.IsNotNull()) { propertyList->ConcatenatePropertyList(readProperties, true); // true = replace } else { MITK_ERROR << "Property list reader did not return a property list. This is an implementation error. Please tell " "your developer."; error = true; } } return !error; } bool mitk::SceneReaderV1::DecorateBaseDataWithProperties(BaseData::Pointer data, const tinyxml2::XMLElement *baseDataNodeElem, const std::string &workingDir) { // check given variables, initialize error variable assert(baseDataNodeElem); bool error(false); // get the file name stored in the <properties ...> tag const char *baseDataPropertyFile(baseDataNodeElem->Attribute("file")); // check if the filename was found if (baseDataPropertyFile) { // PropertyList::Pointer dataPropList = data->GetPropertyList(); PropertyListDeserializer::Pointer propertyDeserializer = PropertyListDeserializer::New(); // initialize the property reader propertyDeserializer->SetFilename(workingDir + Poco::Path::separator() + baseDataPropertyFile); bool ioSuccess = propertyDeserializer->Deserialize(); error = !ioSuccess; // get the output PropertyList::Pointer inProperties = propertyDeserializer->GetOutput(); // store the read-in properties to the given node or throw error otherwise if (inProperties.IsNotNull()) { data->SetPropertyList(inProperties); } else { MITK_ERROR << "The property deserializer did not return a (valid) property list."; error = true; } } else { MITK_ERROR << "Function DecorateBaseDataWithProperties(...) called with false XML element. \n \t ->Given element " "does not contain a 'file' attribute. \n"; error = true; } return !error; } diff --git a/Modules/Segmentation/Algorithms/mitkContourModelSetToImageFilter.cpp b/Modules/Segmentation/Algorithms/mitkContourModelSetToImageFilter.cpp index 65cae86e50..3a2d7f7262 100644 --- a/Modules/Segmentation/Algorithms/mitkContourModelSetToImageFilter.cpp +++ b/Modules/Segmentation/Algorithms/mitkContourModelSetToImageFilter.cpp @@ -1,271 +1,271 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkContourModelSetToImageFilter.h" #include <mitkContourModelSet.h> #include <mitkContourModelUtils.h> #include <mitkExtractSliceFilter.h> #include <mitkImageWriteAccessor.h> #include <mitkProgressBar.h> #include <mitkTimeHelper.h> #include <mitkVtkImageOverwrite.h> mitk::ContourModelSetToImageFilter::ContourModelSetToImageFilter() : m_MakeOutputBinary(true), m_TimeStep(0), m_ReferenceImage(nullptr) { // Create the output. itk::DataObject::Pointer output = this->MakeOutput(0); Superclass::SetNumberOfRequiredInputs(1); Superclass::SetNumberOfRequiredOutputs(1); Superclass::SetNthOutput(0, output); } mitk::ContourModelSetToImageFilter::~ContourModelSetToImageFilter() { } void mitk::ContourModelSetToImageFilter::GenerateInputRequestedRegion() { mitk::Image *output = this->GetOutput(); if ((output->IsInitialized() == false)) return; GenerateTimeInInputRegion(output, const_cast<mitk::Image *>(m_ReferenceImage)); } void mitk::ContourModelSetToImageFilter::GenerateOutputInformation() { mitk::Image::Pointer output = this->GetOutput(); itkDebugMacro(<< "GenerateOutputInformation()"); if ((m_ReferenceImage == nullptr) || (m_ReferenceImage->IsInitialized() == false) || (m_ReferenceImage->GetTimeGeometry() == nullptr)) return; if (m_MakeOutputBinary) { output->Initialize(mitk::MakeScalarPixelType<unsigned char>(), *m_ReferenceImage->GetTimeGeometry(), 1); } else { output->Initialize(m_ReferenceImage->GetPixelType(), *m_ReferenceImage->GetTimeGeometry()); } output->SetPropertyList(m_ReferenceImage->GetPropertyList()->Clone()); } itk::DataObject::Pointer mitk::ContourModelSetToImageFilter::MakeOutput(DataObjectPointerArraySizeType /*idx*/) { return OutputType::New().GetPointer(); } itk::DataObject::Pointer mitk::ContourModelSetToImageFilter::MakeOutput(const DataObjectIdentifierType &name) { itkDebugMacro("MakeOutput(" << name << ")"); if (this->IsIndexedOutputName(name)) { return this->MakeOutput(this->MakeIndexFromOutputName(name)); } return OutputType::New().GetPointer(); } const mitk::ContourModelSet *mitk::ContourModelSetToImageFilter::GetInput(void) { if (this->GetNumberOfInputs() < 1) { return nullptr; } return static_cast<const mitk::ContourModelSet *>(this->ProcessObject::GetInput(0)); } void mitk::ContourModelSetToImageFilter::SetInput(const ContourModelSet *input) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput(0, const_cast<mitk::ContourModelSet *>(input)); } void mitk::ContourModelSetToImageFilter::SetImage(const mitk::Image *refImage) { m_ReferenceImage = refImage; } const mitk::Image *mitk::ContourModelSetToImageFilter::GetImage(void) { return m_ReferenceImage; } void mitk::ContourModelSetToImageFilter::GenerateData() { auto *contourSet = const_cast<mitk::ContourModelSet *>(this->GetInput()); // Initializing progressbar unsigned int num_contours = contourSet->GetContourModelList()->size(); mitk::ProgressBar::GetInstance()->AddStepsToDo(num_contours); // Assure that the volume data of the output is set (fill volume with zeros) this->InitializeOutputEmpty(); mitk::Image::Pointer outputImage = const_cast<mitk::Image *>(this->GetOutput()); if (outputImage.IsNull() || outputImage->IsInitialized() == false || !outputImage->IsVolumeSet(m_TimeStep)) { mitkThrow() << "Error creating output for specified image!"; } if (!contourSet || contourSet->GetContourModelList()->size() == 0) { mitkThrow() << "No contours specified!"; } mitk::BaseGeometry *outputImageGeo = outputImage->GetGeometry(m_TimeStep); // Create mitkVtkImageOverwrite which is needed to write the slice back into the volume vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New(); // Create ExtractSliceFilter for extracting the corresponding slices from the volume mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice); extractor->SetInput(outputImage); extractor->SetTimeStep(m_TimeStep); extractor->SetResliceTransformByGeometry(outputImageGeo); // Fill each contour of the contourmodelset into the image auto it = contourSet->Begin(); auto end = contourSet->End(); while (it != end) { mitk::ContourModel *contour = it->GetPointer(); // 1. Create slice geometry using the contour points mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New(); mitk::Point3D point3D, tempPoint; mitk::Vector3D normal; mitk::Image::Pointer slice; int sliceIndex; bool isFrontside = true; bool isRotated = false; // Determine plane orientation point3D = contour->GetVertexAt(0)->Coordinates; tempPoint = contour->GetVertexAt(contour->GetNumberOfVertices() * 0.25)->Coordinates; mitk::Vector3D vec = point3D - tempPoint; vec.Normalize(); outputImageGeo->WorldToIndex(point3D, point3D); mitk::PlaneGeometry::PlaneOrientation orientation; if (mitk::Equal(vec[0], 0)) { orientation = mitk::PlaneGeometry::Sagittal; sliceIndex = point3D[0]; } else if (mitk::Equal(vec[1], 0)) { orientation = mitk::PlaneGeometry::Frontal; sliceIndex = point3D[1]; } else if (mitk::Equal(vec[2], 0)) { orientation = mitk::PlaneGeometry::Axial; sliceIndex = point3D[2]; } else { // TODO Maybe rotate geometry to extract slice? MITK_ERROR << "Cannot detect correct slice number! Only axial, sagittal and frontal oriented contours are supported!"; return; } // Initialize plane using the detected orientation plane->InitializeStandardPlane(outputImageGeo, orientation, sliceIndex, isFrontside, isRotated); point3D = plane->GetOrigin(); normal = plane->GetNormal(); normal.Normalize(); point3D += normal * 0.5; // pixelspacing is 1, so half the spacing is 0.5 plane->SetOrigin(point3D); // 2. Extract slice at the given position extractor->SetWorldGeometry(plane); extractor->SetVtkOutputRequest(false); reslice->SetOverwriteMode(false); extractor->Modified(); extractor->Update(); slice = extractor->GetOutput(); slice->DisconnectPipeline(); // 3. Fill contour into slice mitk::ContourModel::Pointer projectedContour = - mitk::ContourModelUtils::ProjectContourTo2DSlice(slice, contour, true, false); + mitk::ContourModelUtils::ProjectContourTo2DSlice(slice, contour); mitk::ContourModelUtils::FillContourInSlice(projectedContour, slice, outputImage); // 4. Write slice back into image volume reslice->SetInputSlice(slice->GetVtkImageData()); // set overwrite mode to true to write back to the image volume reslice->SetOverwriteMode(true); reslice->Modified(); extractor->Modified(); extractor->Update(); reslice->SetInputSlice(nullptr); // Progress mitk::ProgressBar::GetInstance()->Progress(); ++it; } outputImage->Modified(); outputImage->GetVtkImageData()->Modified(); } void mitk::ContourModelSetToImageFilter::InitializeOutputEmpty() { // Initialize the output's volume with zeros mitk::Image *output = this->GetOutput(); unsigned int byteSize = output->GetPixelType().GetSize(); if (output->GetDimension() < 4) { for (unsigned int dim = 0; dim < output->GetDimension(); ++dim) { byteSize *= output->GetDimension(dim); } mitk::ImageWriteAccessor writeAccess(output, output->GetVolumeData(0)); memset(writeAccess.GetData(), 0, byteSize); } else { // if we have a time-resolved image we need to set memory to 0 for each time step for (unsigned int dim = 0; dim < 3; ++dim) { byteSize *= output->GetDimension(dim); } for (unsigned int volumeNumber = 0; volumeNumber < output->GetDimension(3); volumeNumber++) { mitk::ImageWriteAccessor writeAccess(output, output->GetVolumeData(volumeNumber)); memset(writeAccess.GetData(), 0, byteSize); } } } diff --git a/Modules/Segmentation/Algorithms/mitkContourUtils.cpp b/Modules/Segmentation/Algorithms/mitkContourUtils.cpp index 718ff2d18a..40eb9c05a0 100755 --- a/Modules/Segmentation/Algorithms/mitkContourUtils.cpp +++ b/Modules/Segmentation/Algorithms/mitkContourUtils.cpp @@ -1,71 +1,69 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkContourUtils.h" #include "mitkContourModelUtils.h" mitk::ContourUtils::ContourUtils() { } mitk::ContourUtils::~ContourUtils() { } mitk::ContourModel::Pointer mitk::ContourUtils::ProjectContourTo2DSlice(Image *slice, - Contour *contourIn3D, - bool itkNotUsed(correctionForIpSegmentation), - bool constrainToInside) + Contour *contourIn3D) { mitk::Contour::PointsContainerIterator it = contourIn3D->GetPoints()->Begin(); mitk::Contour::PointsContainerIterator end = contourIn3D->GetPoints()->End(); mitk::ContourModel::Pointer contour = mitk::ContourModel::New(); while (it != end) { contour->AddVertex(it.Value()); it++; } - return mitk::ContourModelUtils::ProjectContourTo2DSlice(slice, contour, false /*not used*/, constrainToInside); + return mitk::ContourModelUtils::ProjectContourTo2DSlice(slice, contour); } mitk::ContourModel::Pointer mitk::ContourUtils::BackProjectContourFrom2DSlice( - const BaseGeometry *sliceGeometry, Contour *contourIn2D, bool itkNotUsed(correctionForIpSegmentation)) + const BaseGeometry *sliceGeometry, Contour *contourIn2D) { mitk::Contour::PointsContainerIterator it = contourIn2D->GetPoints()->Begin(); mitk::Contour::PointsContainerIterator end = contourIn2D->GetPoints()->End(); mitk::ContourModel::Pointer contour = mitk::ContourModel::New(); while (it != end) { contour->AddVertex(it.Value()); it++; } - return mitk::ContourModelUtils::BackProjectContourFrom2DSlice(sliceGeometry, contour, false /*not used*/); + return mitk::ContourModelUtils::BackProjectContourFrom2DSlice(sliceGeometry, contour); } void mitk::ContourUtils::FillContourInSlice(Contour *projectedContour, Image *sliceImage, int paintingPixelValue) { mitk::Contour::PointsContainerIterator it = projectedContour->GetPoints()->Begin(); mitk::Contour::PointsContainerIterator end = projectedContour->GetPoints()->End(); mitk::ContourModel::Pointer contour = mitk::ContourModel::New(); while (it != end) { contour->AddVertex(it.Value()); it++; } mitk::ContourModelUtils::FillContourInSlice(contour, sliceImage, sliceImage, paintingPixelValue); } diff --git a/Modules/Segmentation/Algorithms/mitkContourUtils.h b/Modules/Segmentation/Algorithms/mitkContourUtils.h index 66bb8b4a97..af5db548ee 100644 --- a/Modules/Segmentation/Algorithms/mitkContourUtils.h +++ b/Modules/Segmentation/Algorithms/mitkContourUtils.h @@ -1,73 +1,65 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkContourUtilshIncludett #define mitkContourUtilshIncludett #include "mitkContour.h" #include "mitkContourModel.h" #include "mitkImage.h" #include <MitkSegmentationExports.h> namespace mitk { /** * \brief Helpful methods for working with contours and images * * Legacy support for mitk::Contour * TODO remove this class when mitk::Contour is removed */ class MITKSEGMENTATION_EXPORT ContourUtils : public itk::Object { public: mitkClassMacroItkParent(ContourUtils, itk::Object); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** \brief Projects a contour onto an image point by point. Converts from world to index coordinates. \param slice \param contourIn3D - \param correctionForIpSegmentation adds 0.5 to x and y index coordinates (difference between ipSegmentation and - MITK contours) - \param constrainToInside */ ContourModel::Pointer ProjectContourTo2DSlice(Image *slice, - Contour *contourIn3D, - bool correctionForIpSegmentation, - bool constrainToInside); + Contour *contourIn3D); /** \brief Projects a slice index coordinates of a contour back into world coordinates. \param sliceGeometry \param contourIn2D - \param correctionForIpSegmentation subtracts 0.5 to x and y index coordinates (difference between - ipSegmentation and MITK contours) */ ContourModel::Pointer BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry, - Contour *contourIn2D, - bool correctionForIpSegmentation = false); + Contour *contourIn2D); /** \brief Fill a contour in a 2D slice with a specified pixel value. */ void FillContourInSlice(Contour *projectedContour, Image *sliceImage, int paintingPixelValue = 1); protected: ContourUtils(); ~ContourUtils() override; }; } #endif diff --git a/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.cpp b/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.cpp index 7b5208ceb5..27a8beb883 100644 --- a/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.cpp +++ b/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.cpp @@ -1,486 +1,486 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkCorrectorAlgorithm.h" #include "mitkContourUtils.h" #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" #include "mitkImageCast.h" #include "mitkImageDataItem.h" #include <mitkContourModelUtils.h> #include "itkCastImageFilter.h" #include "itkImageDuplicator.h" #include "itkImageRegionIterator.h" mitk::CorrectorAlgorithm::CorrectorAlgorithm() : ImageToImageFilter(), m_FillColor(1), m_EraseColor(0) { } mitk::CorrectorAlgorithm::~CorrectorAlgorithm() { } template <typename TPixel, unsigned int VDimensions> void ConvertBackToCorrectPixelType( itk::Image<TPixel, VDimensions> *, mitk::Image::Pointer target, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer segmentationPixelTypeImage) { typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2> InputImageType; typedef itk::Image<TPixel, 2> OutputImageType; typedef itk::CastImageFilter<InputImageType, OutputImageType> CastImageFilterType; typename CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New(); castImageFilter->SetInput(segmentationPixelTypeImage); castImageFilter->Update(); typename OutputImageType::Pointer tempItkImage = castImageFilter->GetOutput(); tempItkImage->DisconnectPipeline(); mitk::CastToMitkImage(tempItkImage, target); } void mitk::CorrectorAlgorithm::GenerateData() { Image::Pointer inputImage = ImageToImageFilter::GetInput(0); if (inputImage.IsNull() || inputImage->GetDimension() != 2) { itkExceptionMacro("CorrectorAlgorithm needs a 2D image as input."); } if (m_Contour.IsNull()) { itkExceptionMacro("CorrectorAlgorithm needs a Contour object as input."); } // copy the input (since m_WorkingImage will be changed later) m_WorkingImage = inputImage; TimeGeometry::Pointer originalGeometry = nullptr; if (inputImage->GetTimeGeometry()) { originalGeometry = inputImage->GetTimeGeometry()->Clone(); m_WorkingImage->SetTimeGeometry(originalGeometry); } else { itkExceptionMacro("Original image does not have a 'Time sliced geometry'! Cannot copy."); } Image::Pointer temporarySlice; // Convert to DefaultSegmentationDataType (because TobiasHeimannCorrectionAlgorithm relys on that data type) { itk::Image<DefaultSegmentationDataType, 2>::Pointer correctPixelTypeImage; CastToItkImage(m_WorkingImage, correctPixelTypeImage); assert(correctPixelTypeImage.IsNotNull()); // possible bug in CastToItkImage ? // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479: // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 // && aSpacing[2]>0' failed // solution here: we overwrite it with an unity matrix itk::Image<DefaultSegmentationDataType, 2>::DirectionType imageDirection; imageDirection.SetIdentity(); // correctPixelTypeImage->SetDirection(imageDirection); temporarySlice = this->GetOutput(); // temporarySlice = ImportItkImage( correctPixelTypeImage ); // m_FillColor = 1; m_EraseColor = 0; ImprovedHeimannCorrectionAlgorithm(correctPixelTypeImage); // this is suboptimal, needs to be kept synchronous to DefaultSegmentationDataType if (inputImage->GetChannelDescriptor().GetPixelType().GetComponentType() == itk::ImageIOBase::USHORT) { // the cast at the beginning did not copy the data CastToMitkImage(correctPixelTypeImage, temporarySlice); } else { // it did copy the data and cast the pixel type AccessByItk_n(m_WorkingImage, ConvertBackToCorrectPixelType, (temporarySlice, correctPixelTypeImage)); } } temporarySlice->SetTimeGeometry(originalGeometry); } template <typename ScalarType> itk::Index<2> mitk::CorrectorAlgorithm::ensureIndexInImage(ScalarType i0, ScalarType i1) { itk::Index<2> toReturn; itk::Size<5> size = m_WorkingImage->GetLargestPossibleRegion().GetSize(); toReturn[0] = std::min((ScalarType)(size[0] - 1), std::max((ScalarType)0.0, i0)); toReturn[1] = std::min((ScalarType)(size[1] - 1), std::max((ScalarType)0.0, i1)); return toReturn; } bool mitk::CorrectorAlgorithm::ImprovedHeimannCorrectionAlgorithm( itk::Image<DefaultSegmentationDataType, 2>::Pointer pic) { /*! Some documentation (not by the original author) TobiasHeimannCorrectionAlgorithm will be called, when the user has finished drawing a freehand line. There should be different results, depending on the line's properties: 1. Without any prior segmentation, the start point and the end point of the drawn line will be connected to a contour and the area enclosed by the contour will be marked as segmentation. 2. When the whole line is inside a segmentation, start and end point will be connected to a contour and the area of this contour will be subtracted from the segmentation. 3. When the line starts inside a segmentation and ends outside with only a single transition from segmentation to no-segmentation, nothing will happen. 4. When there are multiple transitions between inside-segmentation and outside-segmentation, the line will be divided in so called segments. Each segment is either fully inside or fully outside a segmentation. When it is inside a segmentation, its enclosed area will be subtracted from the segmentation. When the segment is outside a segmentation, its enclosed area it will be added to the segmentation. The algorithm is described in full length in Tobias Heimann's diploma thesis (MBI Technical Report 145, p. 37 - 40). */ ContourModel::Pointer projectedContour = - mitk::ContourModelUtils::ProjectContourTo2DSlice(m_WorkingImage, m_Contour, true, false); + mitk::ContourModelUtils::ProjectContourTo2DSlice(m_WorkingImage, m_Contour); if (projectedContour.IsNull() || projectedContour->GetNumberOfVertices() < 2) return false; // Read the first point of the contour auto contourIter = projectedContour->Begin(); if (contourIter == projectedContour->End()) return false; itk::Index<2> previousIndex; previousIndex = ensureIndexInImage((*contourIter)->Coordinates[0], (*contourIter)->Coordinates[1]); ++contourIter; int currentColor = (pic->GetPixel(previousIndex) == m_FillColor); TSegData currentSegment; int countOfSegments = 1; bool firstSegment = true; auto contourEnd = projectedContour->End(); for (; contourIter != contourEnd; ++contourIter) { // Get current point itk::Index<2> currentIndex; currentIndex = ensureIndexInImage((*contourIter)->Coordinates[0] + 0.5, (*contourIter)->Coordinates[1] + 0.5); // Calculate length and slope double slopeX = currentIndex[0] - previousIndex[0]; double slopeY = currentIndex[1] - previousIndex[1]; double length = std::sqrt(slopeX * slopeX + slopeY * slopeY); double deltaX = slopeX / length; double deltaY = slopeY / length; for (double i = 0; i <= length && length > 0; i += 1) { itk::Index<2> temporaryIndex; temporaryIndex = ensureIndexInImage(previousIndex[0] + deltaX * i, previousIndex[1] + deltaY * i); if (!pic->GetLargestPossibleRegion().IsInside(temporaryIndex)) continue; if ((pic->GetPixel(temporaryIndex) == m_FillColor) != currentColor) { currentSegment.points.push_back(temporaryIndex); if (!firstSegment) { ModifySegment(currentSegment, pic); } else { firstSegment = false; } currentSegment = TSegData(); ++countOfSegments; currentColor = (pic->GetPixel(temporaryIndex) == m_FillColor); } currentSegment.points.push_back(temporaryIndex); } previousIndex = currentIndex; } return true; } void mitk::CorrectorAlgorithm::ColorSegment( const mitk::CorrectorAlgorithm::TSegData &segment, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic) { int colorMode = (pic->GetPixel(segment.points[0]) == m_FillColor); int color = 0; if (colorMode) color = m_EraseColor; else color = m_FillColor; std::vector<itk::Index<2>>::const_iterator indexIterator; std::vector<itk::Index<2>>::const_iterator indexEnd; indexIterator = segment.points.begin(); indexEnd = segment.points.end(); for (; indexIterator != indexEnd; ++indexIterator) { pic->SetPixel(*indexIterator, color); } } itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer mitk::CorrectorAlgorithm::CloneImage( itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic) { typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2> ItkImageType; typedef itk::ImageDuplicator<ItkImageType> DuplicatorType; DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage(pic); duplicator->Update(); return duplicator->GetOutput(); } itk::Index<2> mitk::CorrectorAlgorithm::GetFirstPoint( const mitk::CorrectorAlgorithm::TSegData &segment, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic) { int colorMode = (pic->GetPixel(segment.points[0]) == m_FillColor); std::vector<itk::Index<2>>::const_iterator indexIterator; std::vector<itk::Index<2>>::const_iterator indexEnd; indexIterator = segment.points.begin(); indexEnd = segment.points.end(); itk::Index<2> index; for (; indexIterator != indexEnd; ++indexIterator) { for (int xOffset = -1; xOffset < 2; ++xOffset) { for (int yOffset = -1; yOffset < 2; ++yOffset) { index = ensureIndexInImage((*indexIterator)[0] - xOffset, (*indexIterator)[1] - yOffset); if ((pic->GetPixel(index) == m_FillColor) != colorMode) { return index; } } } } mitkThrow() << "No Starting point is found next to the curve."; } std::vector<itk::Index<2>> mitk::CorrectorAlgorithm::FindSeedPoints( const mitk::CorrectorAlgorithm::TSegData &segment, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic) { typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer ItkImagePointerType; std::vector<itk::Index<2>> seedPoints; try { itk::Index<2> firstPoint = GetFirstPoint(segment, pic); seedPoints.push_back(firstPoint); } catch (const mitk::Exception&) { return seedPoints; } if (segment.points.size() < 4) return seedPoints; std::vector<itk::Index<2>>::const_iterator indexIterator; std::vector<itk::Index<2>>::const_iterator indexEnd; indexIterator = segment.points.begin(); indexEnd = segment.points.end(); ItkImagePointerType listOfPoints = CloneImage(pic); listOfPoints->FillBuffer(0); listOfPoints->SetPixel(seedPoints[0], 1); for (; indexIterator != indexEnd; ++indexIterator) { listOfPoints->SetPixel(*indexIterator, 2); } indexIterator = segment.points.begin(); indexIterator++; indexIterator++; indexEnd--; indexEnd--; for (; indexIterator != indexEnd; ++indexIterator) { bool pointFound = true; while (pointFound) { pointFound = false; itk::Index<2> index; itk::Index<2> index2; for (int xOffset = -1; xOffset < 2; ++xOffset) { for (int yOffset = -1; yOffset < 2; ++yOffset) { index = ensureIndexInImage((*indexIterator)[0] - xOffset, (*indexIterator)[1] - yOffset); index2 = index; if (listOfPoints->GetPixel(index2) > 0) continue; index[0] = index[0] - 1; index = ensureIndexInImage(index[0], index[1]); if (listOfPoints->GetPixel(index) == 1) { pointFound = true; seedPoints.push_back(index2); listOfPoints->SetPixel(index2, 1); continue; } index[0] = index[0] + 2; index = ensureIndexInImage(index[0], index[1]); if (listOfPoints->GetPixel(index) == 1) { pointFound = true; seedPoints.push_back(index2); listOfPoints->SetPixel(index2, 1); continue; } index[0] = index[0] - 1; index[1] = index[1] - 1; index = ensureIndexInImage(index[0], index[1]); if (listOfPoints->GetPixel(index) == 1) { pointFound = true; seedPoints.push_back(index2); listOfPoints->SetPixel(index2, 1); continue; } index[1] = index[1] + 2; index = ensureIndexInImage(index[0], index[1]); if (listOfPoints->GetPixel(index) == 1) { pointFound = true; seedPoints.push_back(index2); listOfPoints->SetPixel(index2, 1); continue; } } } } } return seedPoints; } int mitk::CorrectorAlgorithm::FillRegion( const std::vector<itk::Index<2>> &seedPoints, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic) { int numberOfPixel = 0; int mode = (pic->GetPixel(seedPoints[0]) == m_FillColor); int drawColor = m_FillColor; if (mode) { drawColor = m_EraseColor; } std::vector<itk::Index<2>> workPoints; workPoints = seedPoints; // workPoints.push_back(seedPoints[0]); while (workPoints.size() > 0) { itk::Index<2> currentIndex = workPoints.back(); workPoints.pop_back(); if ((pic->GetPixel(currentIndex) == m_FillColor) == mode) ++numberOfPixel; pic->SetPixel(currentIndex, drawColor); currentIndex = ensureIndexInImage(currentIndex[0] - 1, currentIndex[1]); if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == m_FillColor) == mode) workPoints.push_back(currentIndex); currentIndex = ensureIndexInImage(currentIndex[0] + 2, currentIndex[1]); if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == m_FillColor) == mode) workPoints.push_back(currentIndex); currentIndex = ensureIndexInImage(currentIndex[0] - 1, currentIndex[1] - 1); if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == m_FillColor) == mode) workPoints.push_back(currentIndex); currentIndex = ensureIndexInImage(currentIndex[0], currentIndex[1] + 2); if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == m_FillColor) == mode) workPoints.push_back(currentIndex); } return numberOfPixel; } void mitk::CorrectorAlgorithm::OverwriteImage( itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer source, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer target) { typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2> ItkImageType; typedef itk::ImageRegionIterator<ItkImageType> ImageIteratorType; ImageIteratorType sourceIter(source, source->GetLargestPossibleRegion()); ImageIteratorType targetIter(target, target->GetLargestPossibleRegion()); while (!sourceIter.IsAtEnd()) { targetIter.Set(sourceIter.Get()); ++sourceIter; ++targetIter; } } bool mitk::CorrectorAlgorithm::ModifySegment(const TSegData &segment, itk::Image<DefaultSegmentationDataType, 2>::Pointer pic) { typedef itk::Image<DefaultSegmentationDataType, 2>::Pointer ItkImagePointerType; ItkImagePointerType firstSideImage = CloneImage(pic); ColorSegment(segment, firstSideImage); ItkImagePointerType secondSideImage = CloneImage(firstSideImage); std::vector<itk::Index<2>> seedPoints = FindSeedPoints(segment, firstSideImage); if (seedPoints.size() < 1) return false; int firstSidePixel = FillRegion(seedPoints, firstSideImage); std::vector<itk::Index<2>> secondSeedPoints = FindSeedPoints(segment, firstSideImage); if (secondSeedPoints.size() < 1) return false; int secondSidePixel = FillRegion(secondSeedPoints, secondSideImage); if (firstSidePixel < secondSidePixel) { OverwriteImage(firstSideImage, pic); } else { OverwriteImage(secondSideImage, pic); } return true; } diff --git a/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.h b/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.h index ae3eba97a3..0223978c6b 100644 --- a/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.h +++ b/Modules/Segmentation/Algorithms/mitkCorrectorAlgorithm.h @@ -1,109 +1,108 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkCorrectorAlgorithmhIncluded #define mitkCorrectorAlgorithmhIncluded -#include "ipSegmentation.h" #include "mitkContourModel.h" #include "mitkImageToImageFilter.h" #include <MitkSegmentationExports.h> #include <mitkLabel.h> #include <itkImage.h> #define multilabelSegmentationType unsigned short namespace mitk { /** * This class encapsulates an algorithm, which takes a 2D binary image and a contour. * The algorithm tests if the line begins and ends inside or outside a segmentation * and whether areas should be added to or subtracted from the segmentation shape. * * This class has two outputs: * \li the modified input image from GetOutput() * * The output image is a combination of the original input with the generated difference image. * * \sa CorrectorTool2D */ class MITKSEGMENTATION_EXPORT CorrectorAlgorithm : public ImageToImageFilter { public: mitkClassMacro(CorrectorAlgorithm, ImageToImageFilter); itkFactorylessNewMacro(Self); itkCloneMacro(Self); typedef mitk::Label::PixelType DefaultSegmentationDataType; /** * \brief User drawn contour */ void SetContour(ContourModel *contour) { this->m_Contour = contour; } itkSetMacro(FillColor, int); itkGetConstMacro(FillColor, int); itkSetMacro(EraseColor, int); itkGetConstMacro(EraseColor, int); /** * \brief Calculated difference image. */ // itkGetObjectMacro(DifferenceImage, Image); // used by TobiasHeimannCorrectionAlgorithm typedef struct { int lineStart; int lineEnd; bool modified; std::vector<itk::Index<2>> points; } TSegData; protected: CorrectorAlgorithm(); ~CorrectorAlgorithm() override; // does the actual processing void GenerateData() override; bool ImprovedHeimannCorrectionAlgorithm(itk::Image<DefaultSegmentationDataType, 2>::Pointer pic); bool ModifySegment(const TSegData &segment, itk::Image<DefaultSegmentationDataType, 2>::Pointer pic); Image::Pointer m_WorkingImage; ContourModel::Pointer m_Contour; Image::Pointer m_DifferenceImage; int m_FillColor; int m_EraseColor; private: template <typename ScalarType> itk::Index<2> ensureIndexInImage(ScalarType i0, ScalarType i1); void ColorSegment(const mitk::CorrectorAlgorithm::TSegData &segment, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic); itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer CloneImage( itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic); itk::Index<2> GetFirstPoint(const mitk::CorrectorAlgorithm::TSegData &segment, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic); std::vector<itk::Index<2>> FindSeedPoints( const mitk::CorrectorAlgorithm::TSegData &segment, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic); int FillRegion(const std::vector<itk::Index<2>> &seedPoints, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic); void OverwriteImage(itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer source, itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer target); }; } #endif diff --git a/Modules/Segmentation/Algorithms/mitkImageLiveWireContourModelFilter.h b/Modules/Segmentation/Algorithms/mitkImageLiveWireContourModelFilter.h index b3c2f482d5..e8780e6a56 100644 --- a/Modules/Segmentation/Algorithms/mitkImageLiveWireContourModelFilter.h +++ b/Modules/Segmentation/Algorithms/mitkImageLiveWireContourModelFilter.h @@ -1,156 +1,158 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef _mitkImageLiveWireContourModelFilter_h__ #define _mitkImageLiveWireContourModelFilter_h__ #include "mitkCommon.h" #include "mitkContourModel.h" #include "mitkContourModelSource.h" #include <MitkSegmentationExports.h> #include <mitkImage.h> #include <mitkImageAccessByItk.h> #include <mitkImageCast.h> #include <itkShortestPathCostFunctionLiveWire.h> #include <itkShortestPathImageFilter.h> namespace mitk { /** \brief Calculates a LiveWire contour between two points in an image. For defining costs between two pixels specific features are extraced from the image and tranformed into a single cost value. \sa ShortestPathCostFunctionLiveWire The filter is able to create dynamic cost tranfer map and thus use on the fly training. \note On the fly training will only be used for next update. The computation uses the last calculated segment to map cost according to features in the area of the segment. Caution: time support currently not available. Filter will always work on the first timestep in its current implementation. \ingroup ContourModelFilters \ingroup Process */ class MITKSEGMENTATION_EXPORT ImageLiveWireContourModelFilter : public ContourModelSource { public: mitkClassMacro(ImageLiveWireContourModelFilter, ContourModelSource); itkFactorylessNewMacro(Self); itkCloneMacro(Self); typedef ContourModel OutputType; typedef OutputType::Pointer OutputTypePointer; typedef mitk::Image InputType; typedef itk::Image<float, 2> InternalImageType; typedef itk::ShortestPathImageFilter<InternalImageType, InternalImageType> ShortestPathImageFilterType; typedef itk::ShortestPathCostFunctionLiveWire<InternalImageType> CostFunctionType; typedef std::vector<itk::Index<2>> ShortestPathType; /** \brief start point in world coordinates*/ itkSetMacro(StartPoint, mitk::Point3D); itkGetMacro(StartPoint, mitk::Point3D); /** \brief end point in woorld coordinates*/ itkSetMacro(EndPoint, mitk::Point3D); itkGetMacro(EndPoint, mitk::Point3D); /** \brief Create dynamic cost tranfer map - use on the fly training. \note On the fly training will be used for next update only. The computation uses the last calculated segment to map cost according to features in the area of the segment. */ itkSetMacro(UseDynamicCostMap, bool); itkGetMacro(UseDynamicCostMap, bool); /** \brief Clear all repulsive points used in the cost function */ void ClearRepulsivePoints(); /** \brief Set a vector with repulsive points to use in the cost function */ void SetRepulsivePoints(const ShortestPathType &points); /** \brief Add a single repulsive point to the cost function */ void AddRepulsivePoint(const itk::Index<2> &idx); /** \brief Remove a single repulsive point from the cost function */ void RemoveRepulsivePoint(const itk::Index<2> &idx); virtual void SetInput(const InputType *input); using Superclass::SetInput; virtual void SetInput(unsigned int idx, const InputType *input); const InputType *GetInput(void); const InputType *GetInput(unsigned int idx); virtual OutputType *GetOutput(); virtual void DumpMaskImage(); /** \brief Create dynamic cost tranfer map - on the fly training*/ bool CreateDynamicCostMap(mitk::ContourModel *path = nullptr); + void SetUseCostFunction(bool doUseCostFunction) { m_ShortestPathFilter->SetUseCostFunction(doUseCostFunction); }; + protected: ImageLiveWireContourModelFilter(); ~ImageLiveWireContourModelFilter() override; void GenerateOutputInformation() override{}; void GenerateData() override; void UpdateLiveWire(); /** \brief start point in worldcoordinates*/ mitk::Point3D m_StartPoint; /** \brief end point in woorldcoordinates*/ mitk::Point3D m_EndPoint; /** \brief Start point in index*/ mitk::Point3D m_StartPointInIndex; /** \brief End point in index*/ mitk::Point3D m_EndPointInIndex; /** \brief The cost function to compute costs between two pixels*/ CostFunctionType::Pointer m_CostFunction; /** \brief Shortest path filter according to cost function m_CostFunction*/ ShortestPathImageFilterType::Pointer m_ShortestPathFilter; /** \brief Flag to use a dynmic cost map or not*/ bool m_UseDynamicCostMap; unsigned int m_TimeStep; template <typename TPixel, unsigned int VImageDimension> void ItkPreProcessImage(const itk::Image<TPixel, VImageDimension> *inputImage); template <typename TPixel, unsigned int VImageDimension> void CreateDynamicCostMapByITK(const itk::Image<TPixel, VImageDimension> *inputImage, mitk::ContourModel *path = nullptr); InternalImageType::Pointer m_InternalImage; }; } #endif diff --git a/Modules/Segmentation/Algorithms/mitkManualSegmentationToSurfaceFilter.cpp b/Modules/Segmentation/Algorithms/mitkManualSegmentationToSurfaceFilter.cpp index 3f42d39014..6c4ba80f85 100644 --- a/Modules/Segmentation/Algorithms/mitkManualSegmentationToSurfaceFilter.cpp +++ b/Modules/Segmentation/Algorithms/mitkManualSegmentationToSurfaceFilter.cpp @@ -1,164 +1,184 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ +#include <array> + #include <mitkManualSegmentationToSurfaceFilter.h> #include <vtkImageShiftScale.h> +#include <vtkImageConstantPad.h> #include <vtkSmartPointer.h> #include "mitkProgressBar.h" mitk::ManualSegmentationToSurfaceFilter::ManualSegmentationToSurfaceFilter() { m_MedianFilter3D = false; m_MedianKernelSizeX = 3; m_MedianKernelSizeY = 3; m_MedianKernelSizeZ = 3; m_UseGaussianImageSmooth = false; m_GaussianStandardDeviation = 1.5; m_Interpolation = false; m_InterpolationX = 1.0f; m_InterpolationY = 1.0f; m_InterpolationZ = 1.0f; }; mitk::ManualSegmentationToSurfaceFilter::~ManualSegmentationToSurfaceFilter(){}; void mitk::ManualSegmentationToSurfaceFilter::GenerateData() { mitk::Surface *surface = this->GetOutput(); auto *image = (mitk::Image *)GetInput(); mitk::Image::RegionType outputRegion = image->GetRequestedRegion(); int tstart = outputRegion.GetIndex(3); int tmax = tstart + outputRegion.GetSize(3); // GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgeloest ScalarType thresholdExpanded = this->m_Threshold; if ((tmax - tstart) > 0) { ProgressBar::GetInstance()->AddStepsToDo(4 * (tmax - tstart)); } else { ProgressBar::GetInstance()->AddStepsToDo(4); } for (int t = tstart; t < tmax; ++t) { vtkSmartPointer<vtkImageData> vtkimage = image->GetVtkImageData(t); + // If the image has a single slice, pad it with an empty slice to explicitly make it + // recognizable as 3-d by VTK. Otherwise, the vtkMarchingCubes filter will + // complain about dimensionality and won't produce any output. + if (2 == vtkimage->GetDataDimension()) + { + std::array<int, 6> extent; + vtkimage->GetExtent(extent.data()); + extent[5] = 1; + + auto padFilter = vtkSmartPointer<vtkImageConstantPad>::New(); + padFilter->SetInputData(vtkimage); + padFilter->SetOutputWholeExtent(extent.data()); + padFilter->UpdateInformation(); + padFilter->Update(); + vtkimage = padFilter->GetOutput(); + } + // Median -->smooth 3D // MITK_INFO << (m_MedianFilter3D ? "Applying median..." : "No median filtering"); if (m_MedianFilter3D) { vtkImageMedian3D *median = vtkImageMedian3D::New(); median->SetInputData(vtkimage); // RC++ (VTK < 5.0) median->SetKernelSize(m_MedianKernelSizeX, m_MedianKernelSizeY, m_MedianKernelSizeZ); // Std: 3x3x3 median->ReleaseDataFlagOn(); median->UpdateInformation(); median->Update(); vtkimage = median->GetOutput(); //->Out median->Delete(); } ProgressBar::GetInstance()->Progress(); // Interpolate image spacing // MITK_INFO << (m_Interpolation ? "Resampling..." : "No resampling"); if (m_Interpolation) { vtkImageResample *imageresample = vtkImageResample::New(); imageresample->SetInputData(vtkimage); // Set Spacing Manual to 1mm in each direction (Original spacing is lost during image processing) imageresample->SetAxisOutputSpacing(0, m_InterpolationX); imageresample->SetAxisOutputSpacing(1, m_InterpolationY); imageresample->SetAxisOutputSpacing(2, m_InterpolationZ); imageresample->UpdateInformation(); imageresample->Update(); vtkimage = imageresample->GetOutput(); //->Output imageresample->Delete(); } ProgressBar::GetInstance()->Progress(); // MITK_INFO << (m_UseGaussianImageSmooth ? "Applying gaussian smoothing..." : "No gaussian smoothing"); if (m_UseGaussianImageSmooth) // gauss { vtkImageShiftScale *scalefilter = vtkImageShiftScale::New(); scalefilter->SetScale(100); scalefilter->SetInputData(vtkimage); scalefilter->Update(); vtkImageGaussianSmooth *gaussian = vtkImageGaussianSmooth::New(); gaussian->SetInputConnection(scalefilter->GetOutputPort()); gaussian->SetDimensionality(3); gaussian->SetRadiusFactor(0.49); gaussian->SetStandardDeviation(m_GaussianStandardDeviation); gaussian->ReleaseDataFlagOn(); gaussian->UpdateInformation(); gaussian->Update(); vtkimage = scalefilter->GetOutput(); double range[2]; vtkimage->GetScalarRange(range); if (range[1] != 0) // too little slices, image smoothing eliminates all segmentation pixels { vtkimage = gaussian->GetOutput(); //->Out } else { MITK_INFO << "Smoothing would remove all pixels of the segmentation. Use unsmoothed result instead."; } gaussian->Delete(); scalefilter->Delete(); } ProgressBar::GetInstance()->Progress(); // Create surface for t-Slice CreateSurface(t, vtkimage, surface, thresholdExpanded); ProgressBar::GetInstance()->Progress(); } // MITK_INFO << "Updating Time Geometry to ensure right timely displaying"; // Fixing wrong time geometry TimeGeometry *surfaceTG = surface->GetTimeGeometry(); auto *surfacePTG = dynamic_cast<ProportionalTimeGeometry *>(surfaceTG); TimeGeometry *imageTG = image->GetTimeGeometry(); auto *imagePTG = dynamic_cast<ProportionalTimeGeometry *>(imageTG); // Requires ProportionalTimeGeometries to work. May not be available for all steps. assert(surfacePTG != nullptr); assert(imagePTG != nullptr); if ((surfacePTG != nullptr) && (imagePTG != nullptr)) { TimePointType firstTime = imagePTG->GetFirstTimePoint(); TimePointType duration = imagePTG->GetStepDuration(); surfacePTG->SetFirstTimePoint(firstTime); surfacePTG->SetStepDuration(duration); // MITK_INFO << "First Time Point: " << firstTime << " Duration: " << duration; } }; void mitk::ManualSegmentationToSurfaceFilter::SetMedianKernelSize(int x, int y, int z) { m_MedianKernelSizeX = x; m_MedianKernelSizeY = y; m_MedianKernelSizeZ = z; } void mitk::ManualSegmentationToSurfaceFilter::SetInterpolation(vtkDouble x, vtkDouble y, vtkDouble z) { m_InterpolationX = x; m_InterpolationY = y; m_InterpolationZ = z; } diff --git a/Modules/Segmentation/Algorithms/mitkShowSegmentationAsSurface.cpp b/Modules/Segmentation/Algorithms/mitkShowSegmentationAsSurface.cpp index c578a4e198..f64e713f13 100644 --- a/Modules/Segmentation/Algorithms/mitkShowSegmentationAsSurface.cpp +++ b/Modules/Segmentation/Algorithms/mitkShowSegmentationAsSurface.cpp @@ -1,316 +1,333 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkShowSegmentationAsSurface.h" #include "mitkManualSegmentationToSurfaceFilter.h" #include "mitkVtkRepresentationProperty.h" #include <mitkCoreObjectFactory.h> #include <mitkLabelSetImage.h> #include <vtkPolyDataNormals.h> namespace mitk { ShowSegmentationAsSurface::ShowSegmentationAsSurface() : m_UIDGeneratorSurfaces("Surface_"), m_IsLabelSetImage(false) { } ShowSegmentationAsSurface::~ShowSegmentationAsSurface() { } void ShowSegmentationAsSurface::Initialize(const NonBlockingAlgorithm *other) { Superclass::Initialize(other); bool syncVisibility(false); if (other) { other->GetParameter("Sync visibility", syncVisibility); } SetParameter("Sync visibility", syncVisibility); SetParameter("Median kernel size", 3u); SetParameter("Apply median", true); SetParameter("Smooth", true); SetParameter("Gaussian SD", 1.5); SetParameter("Decimate mesh", true); SetParameter("Decimation rate", 0.8); SetParameter("Wireframe", false); m_SurfaceNodes.clear(); } bool ShowSegmentationAsSurface::ReadyToRun() { try { Image::Pointer image; GetPointerParameter("Input", image); return image.IsNotNull() && GetGroupNode(); } catch (std::invalid_argument &) { return false; } } bool ShowSegmentationAsSurface::ThreadedUpdateFunction() { Image::Pointer image; GetPointerParameter("Input", image); bool smooth(true); GetParameter("Smooth", smooth); bool applyMedian(true); GetParameter("Apply median", applyMedian); bool decimateMesh(true); GetParameter("Decimate mesh", decimateMesh); unsigned int medianKernelSize(3); GetParameter("Median kernel size", medianKernelSize); double gaussianSD(1.5); GetParameter("Gaussian SD", gaussianSD); double reductionRate(0.8); GetParameter("Decimation rate", reductionRate); MITK_INFO << "Creating polygon model with smoothing " << smooth << " gaussianSD " << gaussianSD << " median " << applyMedian << " median kernel " << medianKernelSize << " mesh reduction " << decimateMesh << " reductionRate " << reductionRate; auto labelSetImage = dynamic_cast<LabelSetImage *>(image.GetPointer()); if (nullptr != labelSetImage) { auto numberOfLayers = labelSetImage->GetNumberOfLayers(); for (decltype(numberOfLayers) layerIndex = 0; layerIndex < numberOfLayers; ++layerIndex) { auto labelSet = labelSetImage->GetLabelSet(layerIndex); for (auto labelIter = labelSet->IteratorConstBegin(); labelIter != labelSet->IteratorConstEnd(); ++labelIter) { if (0 == labelIter->first) continue; // Do not process background label auto labelImage = labelSetImage->CreateLabelMask(labelIter->first, false, layerIndex); if (labelImage.IsNull()) continue; auto labelSurface = this->ConvertBinaryImageToSurface(labelImage); if (labelSurface.IsNull()) continue; + auto* polyData = labelSurface->GetVtkPolyData(); + + if (smooth && (polyData->GetNumberOfPoints() < 1 || polyData->GetNumberOfCells() < 1)) + { + MITK_WARN << "Label \"" << labelIter->second->GetName() << "\" didn't produce any smoothed surface data (try again without smoothing)."; + continue; + } + auto node = DataNode::New(); node->SetData(labelSurface); node->SetColor(labelIter->second->GetColor()); node->SetName(labelIter->second->GetName()); m_SurfaceNodes.push_back(node); } } } else { auto surface = this->ConvertBinaryImageToSurface(image); if (surface.IsNotNull()) { - auto node = DataNode::New(); - node->SetData(surface); - m_SurfaceNodes.push_back(node); + auto* polyData = surface->GetVtkPolyData(); + + if (smooth && (polyData->GetNumberOfPoints() < 1 || polyData->GetNumberOfCells() < 1)) + { + MITK_WARN << "Could not produce smoothed surface data (try again without smoothing)."; + } + else + { + auto node = DataNode::New(); + node->SetData(surface); + m_SurfaceNodes.push_back(node); + } } } m_IsLabelSetImage = nullptr != labelSetImage; return true; } void ShowSegmentationAsSurface::ThreadedUpdateSuccessful() { for (const auto &node : m_SurfaceNodes) { bool wireframe = false; GetParameter("Wireframe", wireframe); if (wireframe) { auto representation = dynamic_cast<VtkRepresentationProperty *>(node->GetProperty("material.representation")); if (nullptr != representation) representation->SetRepresentationToWireframe(); } node->SetProperty("opacity", FloatProperty::New(0.3f)); node->SetProperty("line width", FloatProperty::New(1.0f)); node->SetProperty("scalar visibility", BoolProperty::New(false)); auto name = node->GetName(); auto groupNode = this->GetGroupNode(); if (!m_IsLabelSetImage) { if ((name.empty() || DataNode::NO_NAME_VALUE() == name) && nullptr != groupNode) name = groupNode->GetName(); if (name.empty()) name = "Surface"; } bool smooth = true; GetParameter("Smooth", smooth); if (smooth) name.append(" (smoothed)"); node->SetName(name); if (!m_IsLabelSetImage) { auto colorProp = groupNode->GetProperty("color"); if (nullptr != colorProp) { node->ReplaceProperty("color", colorProp->Clone()); } else { node->SetProperty("color", ColorProperty::New(1.0, 1.0, 0.0)); } } bool showResult = true; GetParameter("Show result", showResult); bool syncVisibility = false; GetParameter("Sync visibility", syncVisibility); auto visibleProp = groupNode->GetProperty("visible"); if (nullptr != visibleProp && syncVisibility) { node->ReplaceProperty("visible", visibleProp->Clone()); } else { node->SetProperty("visible", BoolProperty::New(showResult)); } if (!m_IsLabelSetImage) { Image::Pointer image; GetPointerParameter("Input", image); if (image.IsNotNull()) { auto organTypeProp = image->GetProperty("organ type"); if (nullptr != organTypeProp) node->GetData()->SetProperty("organ type", organTypeProp); } } this->InsertBelowGroupNode(node); } Superclass::ThreadedUpdateSuccessful(); } Surface::Pointer ShowSegmentationAsSurface::ConvertBinaryImageToSurface(Image::Pointer binaryImage) { bool smooth = true; GetParameter("Smooth", smooth); bool applyMedian = true; GetParameter("Apply median", applyMedian); bool decimateMesh = true; GetParameter("Decimate mesh", decimateMesh); unsigned int medianKernelSize = 3; GetParameter("Median kernel size", medianKernelSize); double gaussianSD = 1.5; GetParameter("Gaussian SD", gaussianSD); double reductionRate = 0.8; GetParameter("Decimation rate", reductionRate); auto filter = ManualSegmentationToSurfaceFilter::New(); filter->SetInput(binaryImage); filter->SetThreshold(0.5); filter->SetUseGaussianImageSmooth(smooth); filter->SetSmooth(smooth); filter->SetMedianFilter3D(applyMedian); if (smooth) { filter->InterpolationOn(); filter->SetGaussianStandardDeviation(gaussianSD); } if (applyMedian) filter->SetMedianKernelSize(medianKernelSize, medianKernelSize, medianKernelSize); // Fix to avoid VTK warnings (see T5390) if (binaryImage->GetDimension() > 3) decimateMesh = false; if (decimateMesh) { filter->SetDecimate(ImageToSurfaceFilter::QuadricDecimation); filter->SetTargetReduction(reductionRate); } else { filter->SetDecimate(ImageToSurfaceFilter::NoDecimation); } filter->UpdateLargestPossibleRegion(); auto surface = filter->GetOutput(); auto polyData = surface->GetVtkPolyData(); if (nullptr == polyData) throw std::logic_error("Could not create polygon model"); polyData->SetVerts(nullptr); polyData->SetLines(nullptr); if (smooth || applyMedian || decimateMesh) { auto normals = vtkSmartPointer<vtkPolyDataNormals>::New(); normals->AutoOrientNormalsOn(); normals->FlipNormalsOff(); normals->SetInputData(polyData); normals->Update(); surface->SetVtkPolyData(normals->GetOutput()); } else { surface->SetVtkPolyData(polyData); } return surface; } } diff --git a/Modules/Segmentation/CMakeLists.txt b/Modules/Segmentation/CMakeLists.txt index b73d0ba055..9c77de4682 100644 --- a/Modules/Segmentation/CMakeLists.txt +++ b/Modules/Segmentation/CMakeLists.txt @@ -1,9 +1,9 @@ mitk_create_module( INCLUDE_DIRS Algorithms Controllers DataManagement Interactions Rendering SegmentationUtilities/BooleanOperations SegmentationUtilities/MorphologicalOperations - DEPENDS MitkAlgorithmsExt MitkIpSegmentation MitkIpFunc MitkSurfaceInterpolation MitkGraphAlgorithms MitkContourModel MitkMultilabel + DEPENDS MitkAlgorithmsExt MitkSurfaceInterpolation MitkGraphAlgorithms MitkContourModel MitkMultilabel PACKAGE_DEPENDS PUBLIC ITK|QuadEdgeMesh PRIVATE ITK|LabelMap+Watersheds VTK|ImagingGeneral ) add_subdirectory(Testing) diff --git a/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp b/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp index e19770ed6a..10f5b55451 100644 --- a/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp +++ b/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp @@ -1,549 +1,551 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkAutoSegmentationWithPreviewTool.h" #include "mitkToolManager.h" #include "mitkColorProperty.h" #include "mitkLevelWindowProperty.h" #include "mitkProperties.h" #include "mitkDataStorage.h" #include "mitkRenderingManager.h" #include <mitkSliceNavigationController.h> #include "mitkImageAccessByItk.h" #include "mitkImageCast.h" #include "mitkImageStatisticsHolder.h" #include "mitkImageTimeSelector.h" #include "mitkLabelSetImage.h" #include "mitkMaskAndCutRoiImageFilter.h" #include "mitkPadImageFilter.h" #include "mitkNodePredicateGeometry.h" #include "mitkSegTool2D.h" mitk::AutoSegmentationWithPreviewTool::AutoSegmentationWithPreviewTool(bool lazyDynamicPreviews): m_LazyDynamicPreviews(lazyDynamicPreviews) { m_ProgressCommand = mitk::ToolCommand::New(); } mitk::AutoSegmentationWithPreviewTool::AutoSegmentationWithPreviewTool(bool lazyDynamicPreviews, const char* interactorType, const us::Module* interactorModule) : AutoSegmentationTool(interactorType, interactorModule), m_LazyDynamicPreviews(lazyDynamicPreviews) { m_ProgressCommand = mitk::ToolCommand::New(); } mitk::AutoSegmentationWithPreviewTool::~AutoSegmentationWithPreviewTool() { } bool mitk::AutoSegmentationWithPreviewTool::CanHandle(const BaseData* referenceData, const BaseData* workingData) const { if (!Superclass::CanHandle(referenceData, workingData)) return false; if (workingData == nullptr) return true; auto* labelSet = dynamic_cast<const LabelSetImage*>(workingData); if (labelSet != nullptr) return true; auto* image = dynamic_cast<const Image*>(workingData); if (image == nullptr) return false; //if it is a normal image and not a label set image is used as working data //it must have the same pixel type as a label set. return MakeScalarPixelType< DefaultSegmentationDataType >() == image->GetPixelType(); } void mitk::AutoSegmentationWithPreviewTool::Activated() { Superclass::Activated(); this->GetToolManager()->RoiDataChanged += mitk::MessageDelegate<mitk::AutoSegmentationWithPreviewTool>(this, &mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged); this->GetToolManager()->SelectedTimePointChanged += mitk::MessageDelegate<mitk::AutoSegmentationWithPreviewTool>(this, &mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged); m_ReferenceDataNode = this->GetToolManager()->GetReferenceData(0); m_SegmentationInputNode = m_ReferenceDataNode; m_LastTimePointOfUpdate = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); if (m_PreviewSegmentationNode.IsNull()) { m_PreviewSegmentationNode = DataNode::New(); m_PreviewSegmentationNode->SetProperty("color", ColorProperty::New(0.0, 1.0, 0.0)); m_PreviewSegmentationNode->SetProperty("name", StringProperty::New(std::string(this->GetName())+" preview")); m_PreviewSegmentationNode->SetProperty("opacity", FloatProperty::New(0.3)); m_PreviewSegmentationNode->SetProperty("binary", BoolProperty::New(true)); m_PreviewSegmentationNode->SetProperty("helper object", BoolProperty::New(true)); } if (m_SegmentationInputNode.IsNotNull()) { this->ResetPreviewNode(); this->InitiateToolByInput(); } else { this->GetToolManager()->ActivateTool(-1); } } void mitk::AutoSegmentationWithPreviewTool::Deactivated() { this->GetToolManager()->RoiDataChanged -= mitk::MessageDelegate<mitk::AutoSegmentationWithPreviewTool>(this, &mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged); this->GetToolManager()->SelectedTimePointChanged -= mitk::MessageDelegate<mitk::AutoSegmentationWithPreviewTool>(this, &mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged); m_SegmentationInputNode = nullptr; m_ReferenceDataNode = nullptr; m_WorkingPlaneGeometry = nullptr; try { if (DataStorage *storage = this->GetToolManager()->GetDataStorage()) { storage->Remove(m_PreviewSegmentationNode); RenderingManager::GetInstance()->RequestUpdateAll(); } } catch (...) { // don't care } if (m_PreviewSegmentationNode.IsNotNull()) { m_PreviewSegmentationNode->SetData(nullptr); } Superclass::Deactivated(); } void mitk::AutoSegmentationWithPreviewTool::ConfirmSegmentation() { if (m_LazyDynamicPreviews && m_CreateAllTimeSteps) { // The tool should create all time steps but is currently in lazy mode, // thus ensure that a preview for all time steps is available. this->UpdatePreview(true); } CreateResultSegmentationFromPreview(); RenderingManager::GetInstance()->RequestUpdateAll(); if (!m_KeepActiveAfterAccept) { this->GetToolManager()->ActivateTool(-1); } } void mitk::AutoSegmentationWithPreviewTool::InitiateToolByInput() { //default implementation does nothing. //implement in derived classes to change behavior } mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetPreviewSegmentation() { if (m_PreviewSegmentationNode.IsNull()) { return nullptr; } return dynamic_cast<Image*>(m_PreviewSegmentationNode->GetData()); } mitk::DataNode* mitk::AutoSegmentationWithPreviewTool::GetPreviewSegmentationNode() { return m_PreviewSegmentationNode; } const mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetSegmentationInput() const { if (m_SegmentationInputNode.IsNull()) { return nullptr; } return dynamic_cast<const Image*>(m_SegmentationInputNode->GetData()); } const mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetReferenceData() const { if (m_ReferenceDataNode.IsNull()) { return nullptr; } return dynamic_cast<const Image*>(m_ReferenceDataNode->GetData()); } void mitk::AutoSegmentationWithPreviewTool::ResetPreviewNode() { itk::RGBPixel<float> previewColor; previewColor[0] = 0.0f; previewColor[1] = 1.0f; previewColor[2] = 0.0f; const auto image = this->GetSegmentationInput(); if (nullptr != image) { mitk::LabelSetImage::ConstPointer workingImage = dynamic_cast<const mitk::LabelSetImage *>(this->GetToolManager()->GetWorkingData(0)->GetData()); if (workingImage.IsNotNull()) { auto newPreviewImage = workingImage->Clone(); if (this->GetResetsToEmptyPreview()) { newPreviewImage->ClearBuffer(); } if (newPreviewImage.IsNull()) { MITK_ERROR << "Cannot create preview helper objects. Unable to clone working image"; return; } m_PreviewSegmentationNode->SetData(newPreviewImage); // Let's paint the feedback node green... - newPreviewImage->GetActiveLabel()->SetColor(previewColor); - newPreviewImage->GetActiveLabelSet()->UpdateLookupTable(newPreviewImage->GetActiveLabel()->GetValue()); + auto* activeLayer = newPreviewImage->GetActiveLabelSet(); + auto* activeLabel = activeLayer->GetActiveLabel(); + activeLabel->SetColor(previewColor); + activeLayer->UpdateLookupTable(activeLabel->GetValue()); } else { mitk::Image::ConstPointer workingImageBin = dynamic_cast<const mitk::Image*>(this->GetToolManager()->GetWorkingData(0)->GetData()); if (workingImageBin.IsNotNull()) { mitk::Image::Pointer newPreviewImage; if (this->GetResetsToEmptyPreview()) { newPreviewImage = mitk::Image::New(); newPreviewImage->Initialize(workingImageBin); } else { auto newPreviewImage = workingImageBin->Clone(); } if (newPreviewImage.IsNull()) { MITK_ERROR << "Cannot create preview helper objects. Unable to clone working image"; return; } m_PreviewSegmentationNode->SetData(newPreviewImage); } else { mitkThrow() << "Tool is an invalid state. Cannot setup preview node. Working data is an unsupported class and should have not been accepted by CanHandle()."; } } m_PreviewSegmentationNode->SetColor(previewColor); m_PreviewSegmentationNode->SetOpacity(0.5); int layer(50); m_ReferenceDataNode->GetIntProperty("layer", layer); m_PreviewSegmentationNode->SetIntProperty("layer", layer + 1); if (DataStorage *ds = this->GetToolManager()->GetDataStorage()) { if (!ds->Exists(m_PreviewSegmentationNode)) ds->Add(m_PreviewSegmentationNode, m_ReferenceDataNode); } } } template <typename TPixel, unsigned int VImageDimension> static void ITKSetVolume(const itk::Image<TPixel, VImageDimension> *originalImage, mitk::Image *segmentation, unsigned int timeStep) { auto constPixelContainer = originalImage->GetPixelContainer(); //have to make a const cast because itk::PixelContainer does not provide a const correct access :( auto pixelContainer = const_cast<typename itk::Image<TPixel, VImageDimension>::PixelContainer*>(constPixelContainer); segmentation->SetVolume((void *)pixelContainer->GetBufferPointer(), timeStep); } void mitk::AutoSegmentationWithPreviewTool::TransferImageAtTimeStep(const Image* sourceImage, Image* destinationImage, const TimeStepType timeStep) { try { Image::ConstPointer sourceImageAtTimeStep = this->GetImageByTimeStep(sourceImage, timeStep); if (sourceImageAtTimeStep->GetPixelType() != destinationImage->GetPixelType()) { mitkThrow() << "Cannot transfer images. Tool is in an invalid state, source image and destination image do not have the same pixel type. " << "Source pixel type: " << sourceImage->GetPixelType().GetTypeAsString() << "; destination pixel type: " << destinationImage->GetPixelType().GetTypeAsString(); } if (!Equal(*(sourceImage->GetGeometry(timeStep)), *(destinationImage->GetGeometry(timeStep)), NODE_PREDICATE_GEOMETRY_DEFAULT_CHECK_COORDINATE_PRECISION, NODE_PREDICATE_GEOMETRY_DEFAULT_CHECK_DIRECTION_PRECISION, false)) { mitkThrow() << "Cannot transfer images. Tool is in an invalid state, source image and destination image do not have the same geometry."; } if (nullptr != this->GetWorkingPlaneGeometry()) { auto sourceSlice = SegTool2D::GetAffectedImageSliceAs2DImage(this->GetWorkingPlaneGeometry(), sourceImage, timeStep); SegTool2D::WriteBackSegmentationResult(this->GetTargetSegmentationNode(), m_WorkingPlaneGeometry, sourceSlice, timeStep); } else { //take care of the full segmentation volume if (sourceImageAtTimeStep->GetDimension() == 2) { AccessFixedDimensionByItk_2( sourceImageAtTimeStep, ITKSetVolume, 2, destinationImage, timeStep); } else { AccessFixedDimensionByItk_2( sourceImageAtTimeStep, ITKSetVolume, 3, destinationImage, timeStep); } } } catch (...) { Tool::ErrorMessage("Error accessing single time steps of the original image. Cannot create segmentation."); throw; } } void mitk::AutoSegmentationWithPreviewTool::CreateResultSegmentationFromPreview() { const auto segInput = this->GetSegmentationInput(); auto previewImage = this->GetPreviewSegmentation(); if (nullptr != segInput && nullptr != previewImage) { DataNode::Pointer resultSegmentationNode = GetTargetSegmentationNode(); if (resultSegmentationNode.IsNotNull()) { const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); auto resultSegmentation = dynamic_cast<Image*>(resultSegmentationNode->GetData()); // REMARK: the following code in this scope assumes that previewImage and resultSegmentation // are clones of the working image (segmentation provided to the tool). Therefore they have // the same time geometry. if (previewImage->GetTimeSteps() != resultSegmentation->GetTimeSteps()) { mitkThrow() << "Cannot perform threshold. Internal tool state is invalid." << " Preview segmentation and segmentation result image have different time geometries."; } if (m_CreateAllTimeSteps) { for (unsigned int timeStep = 0; timeStep < previewImage->GetTimeSteps(); ++timeStep) { this->TransferImageAtTimeStep(previewImage, resultSegmentation, timeStep); } } else { const auto timeStep = resultSegmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint); this->TransferImageAtTimeStep(previewImage, resultSegmentation, timeStep); } // since we are maybe working on a smaller image, pad it to the size of the original image if (m_ReferenceDataNode.GetPointer() != m_SegmentationInputNode.GetPointer()) { mitk::PadImageFilter::Pointer padFilter = mitk::PadImageFilter::New(); padFilter->SetInput(0, resultSegmentation); padFilter->SetInput(1, dynamic_cast<mitk::Image*>(m_ReferenceDataNode->GetData())); padFilter->SetBinaryFilter(true); padFilter->SetUpperThreshold(1); padFilter->SetLowerThreshold(1); padFilter->Update(); resultSegmentationNode->SetData(padFilter->GetOutput()); } if (m_OverwriteExistingSegmentation) { //if we overwrite the segmentation (and not just store it as a new result //in the data storage) we update also the tool manager state. this->GetToolManager()->SetWorkingData(resultSegmentationNode); this->GetToolManager()->GetWorkingData(0)->Modified(); } this->EnsureTargetSegmentationNodeInDataStorage(); } } } void mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged() { mitk::DataNode::ConstPointer node = this->GetToolManager()->GetRoiData(0); if (node.IsNotNull()) { mitk::MaskAndCutRoiImageFilter::Pointer roiFilter = mitk::MaskAndCutRoiImageFilter::New(); mitk::Image::Pointer image = dynamic_cast<mitk::Image *>(m_SegmentationInputNode->GetData()); if (image.IsNull()) return; roiFilter->SetInput(image); roiFilter->SetRegionOfInterest(node->GetData()); roiFilter->Update(); mitk::DataNode::Pointer tmpNode = mitk::DataNode::New(); tmpNode->SetData(roiFilter->GetOutput()); m_SegmentationInputNode = tmpNode; } else m_SegmentationInputNode = m_ReferenceDataNode; this->ResetPreviewNode(); this->InitiateToolByInput(); this->UpdatePreview(); } void mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged() { if (m_IsTimePointChangeAware && m_PreviewSegmentationNode.IsNotNull() && m_SegmentationInputNode.IsNotNull()) { const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); const bool isStaticSegOnDynamicImage = m_PreviewSegmentationNode->GetData()->GetTimeSteps() == 1 && m_SegmentationInputNode->GetData()->GetTimeSteps() > 1; if (timePoint!=m_LastTimePointOfUpdate && (isStaticSegOnDynamicImage || m_LazyDynamicPreviews)) { //we only need to update either because we are lazzy //or because we have a static segmentation with a dynamic image this->UpdatePreview(); } } } void mitk::AutoSegmentationWithPreviewTool::UpdatePreview(bool ignoreLazyPreviewSetting) { const auto inputImage = this->GetSegmentationInput(); auto previewImage = this->GetPreviewSegmentation(); int progress_steps = 200; const auto workingImage = dynamic_cast<const mitk::Image*>(this->GetToolManager()->GetWorkingData(0)->GetData()); this->CurrentlyBusy.Send(true); m_IsUpdating = true; this->UpdatePrepare(); const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); try { if (nullptr != inputImage && nullptr != previewImage) { m_ProgressCommand->AddStepsToDo(progress_steps); if (previewImage->GetTimeSteps() > 1 && (ignoreLazyPreviewSetting || !m_LazyDynamicPreviews)) { for (unsigned int timeStep = 0; timeStep < previewImage->GetTimeSteps(); ++timeStep) { Image::ConstPointer feedBackImage; Image::ConstPointer currentSegImage; auto previewTimePoint = previewImage->GetTimeGeometry()->TimeStepToTimePoint(timeStep); auto inputTimeStep = inputImage->GetTimeGeometry()->TimePointToTimeStep(previewTimePoint); if (nullptr != this->GetWorkingPlaneGeometry()) { //only extract a specific slice defined by the working plane as feedback image. feedBackImage = SegTool2D::GetAffectedImageSliceAs2DImage(this->GetWorkingPlaneGeometry(), inputImage, inputTimeStep); currentSegImage = SegTool2D::GetAffectedImageSliceAs2DImageByTimePoint(this->GetWorkingPlaneGeometry(), workingImage, previewTimePoint); } else { //work on the whole feedback image feedBackImage = this->GetImageByTimeStep(inputImage, inputTimeStep); currentSegImage = this->GetImageByTimePoint(workingImage, previewTimePoint); } this->DoUpdatePreview(feedBackImage, currentSegImage, previewImage, timeStep); } } else { Image::ConstPointer feedBackImage; Image::ConstPointer currentSegImage; if (nullptr != this->GetWorkingPlaneGeometry()) { feedBackImage = SegTool2D::GetAffectedImageSliceAs2DImageByTimePoint(this->GetWorkingPlaneGeometry(), inputImage, timePoint); currentSegImage = SegTool2D::GetAffectedImageSliceAs2DImageByTimePoint(this->GetWorkingPlaneGeometry(), workingImage, timePoint); } else { feedBackImage = this->GetImageByTimePoint(inputImage, timePoint); currentSegImage = this->GetImageByTimePoint(workingImage, timePoint); } auto timeStep = previewImage->GetTimeGeometry()->TimePointToTimeStep(timePoint); this->DoUpdatePreview(feedBackImage, currentSegImage, previewImage, timeStep); } RenderingManager::GetInstance()->RequestUpdateAll(); } } catch (itk::ExceptionObject & excep) { MITK_ERROR << "Exception caught: " << excep.GetDescription(); m_ProgressCommand->SetProgress(progress_steps); std::string msg = excep.GetDescription(); ErrorMessage.Send(msg); } catch (...) { m_ProgressCommand->SetProgress(progress_steps); m_IsUpdating = false; CurrentlyBusy.Send(false); throw; } this->UpdateCleanUp(); m_LastTimePointOfUpdate = timePoint; m_ProgressCommand->SetProgress(progress_steps); m_IsUpdating = false; CurrentlyBusy.Send(false); } bool mitk::AutoSegmentationWithPreviewTool::IsUpdating() const { return m_IsUpdating; } void mitk::AutoSegmentationWithPreviewTool::UpdatePrepare() { // default implementation does nothing //reimplement in derived classes for special behavior } void mitk::AutoSegmentationWithPreviewTool::UpdateCleanUp() { // default implementation does nothing //reimplement in derived classes for special behavior } mitk::TimePointType mitk::AutoSegmentationWithPreviewTool::GetLastTimePointOfUpdate() const { return m_LastTimePointOfUpdate; } diff --git a/Modules/Segmentation/Interactions/mitkContourModelLiveWireInteractor.cpp b/Modules/Segmentation/Interactions/mitkContourModelLiveWireInteractor.cpp index e2e0e95b68..27e02d9986 100644 --- a/Modules/Segmentation/Interactions/mitkContourModelLiveWireInteractor.cpp +++ b/Modules/Segmentation/Interactions/mitkContourModelLiveWireInteractor.cpp @@ -1,485 +1,426 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkContourModelLiveWireInteractor.h" #include "mitkInteractionPositionEvent.h" #include "mitkToolManager.h" #include "mitkBaseRenderer.h" #include "mitkRenderingManager.h" #include <mitkInteractionConst.h> #include "mitkIOUtil.h" mitk::ContourModelLiveWireInteractor::ContourModelLiveWireInteractor() : ContourModelInteractor() { m_LiveWireFilter = mitk::ImageLiveWireContourModelFilter::New(); - + m_LiveWireFilter->SetUseCostFunction(true); m_NextActiveVertexDown.Fill(0); m_NextActiveVertexUp.Fill(0); } mitk::ContourModelLiveWireInteractor::~ContourModelLiveWireInteractor() { } void mitk::ContourModelLiveWireInteractor::ConnectActionsAndFunctions() { CONNECT_CONDITION("checkisOverPoint", OnCheckPointClick); CONNECT_CONDITION("mouseMove", IsHovering); CONNECT_FUNCTION("movePoint", OnMovePoint); CONNECT_FUNCTION("deletePoint", OnDeletePoint); CONNECT_FUNCTION("finish", OnFinishEditing); } bool mitk::ContourModelLiveWireInteractor::OnCheckPointClick(const InteractionEvent *interactionEvent) { const auto *positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); if (!positionEvent) return false; const auto timeStep = interactionEvent->GetSender()->GetTimeStep(GetDataNode()->GetData()); auto *contour = dynamic_cast<mitk::ContourModel *>(this->GetDataNode()->GetData()); if (contour == nullptr) { MITK_ERROR << "Invalid Contour"; return false; } contour->Deselect(); // Check distance to any vertex. // Transition YES if click close to a vertex mitk::Point3D click = positionEvent->GetPositionInWorld(); - if (contour->SelectVertexAt(click, 1.5, timeStep)) - { - contour->SetSelectedVertexAsControlPoint(false); - m_ContourLeft = mitk::ContourModel::New(); - // get coordinates of next active vertex downwards from selected vertex - int downIndex = this->SplitContourFromSelectedVertex(contour, m_ContourLeft, false, timeStep); - - m_NextActiveVertexDownIter = contour->IteratorBegin() + downIndex; - m_NextActiveVertexDown = (*m_NextActiveVertexDownIter)->Coordinates; - - m_ContourRight = mitk::ContourModel::New(); - - // get coordinates of next active vertex upwards from selected vertex - int upIndex = this->SplitContourFromSelectedVertex(contour, m_ContourRight, true, timeStep); - - m_NextActiveVertexUpIter = contour->IteratorBegin() + upIndex; - m_NextActiveVertexUp = (*m_NextActiveVertexUpIter)->Coordinates; + bool isVertexSelected = false; + // Check, if clicked position is close to control vertex and if so, select closest control vertex. + isVertexSelected = contour->SelectControlVertexAt(click, mitk::ContourModelLiveWireInteractor::eps, timeStep); - // clear previous void positions - this->m_LiveWireFilter->ClearRepulsivePoints(); + // If the position is not close to control vertex. but hovering the contour line, we check, if it is close to non-control vertex. + // The closest vertex will be set as a control vertex. + if (isVertexSelected == false) + isVertexSelected = contour->SelectVertexAt(click, mitk::ContourModelLiveWireInteractor::eps, timeStep); - // set the current contour as void positions in the cost map - // start with down side - auto iter = contour->IteratorBegin(timeStep); - for (; iter != m_NextActiveVertexDownIter; iter++) + // If the position is not close to control or non-control vertex. but hovering the contour line, we create a vertex at the position. + if (isVertexSelected == false) + { + bool isHover = false; + if (this->GetDataNode()->GetBoolProperty("contour.hovering", isHover, positionEvent->GetSender()) == false) { - itk::Index<2> idx; - this->m_WorkingSlice->GetGeometry()->WorldToIndex((*iter)->Coordinates, idx); - this->m_LiveWireFilter->AddRepulsivePoint(idx); + MITK_WARN << "Unknown property contour.hovering"; } - - // continue with upper side - iter = m_NextActiveVertexUpIter + 1; - for (; iter != contour->IteratorEnd(timeStep); iter++) + if (isHover) { - itk::Index<2> idx; - this->m_WorkingSlice->GetGeometry()->WorldToIndex((*iter)->Coordinates, idx); - this->m_LiveWireFilter->AddRepulsivePoint(idx); + contour->AddVertex(click, timeStep); + isVertexSelected = contour->SelectVertexAt(click, mitk::ContourModelLiveWireInteractor::eps, timeStep); } + } + + if (isVertexSelected) + { + contour->SetSelectedVertexAsControlPoint(true); + auto controlVertices = contour->GetControlVertices(timeStep); + const mitk::ContourModel::VertexType *nextPoint = contour->GetNextControlVertexAt(click, mitk::ContourModelLiveWireInteractor::eps, timeStep); + const mitk::ContourModel::VertexType *previousPoint = contour->GetPreviousControlVertexAt(click, mitk::ContourModelLiveWireInteractor::eps, timeStep); + this->SplitContourFromSelectedVertex(contour, nextPoint, previousPoint, timeStep); + m_NextActiveVertexUp = nextPoint->Coordinates; + m_NextActiveVertexDown = previousPoint->Coordinates; + + // clear previous void positions + this->m_LiveWireFilter->ClearRepulsivePoints(); + // all points in lower and upper part should be marked as repulsive points to not be changed + this->SetRepulsivePoints(previousPoint, m_ContourLeft, timeStep); + this->SetRepulsivePoints(nextPoint, m_ContourRight, timeStep); // clear container with void points between neighboring control points m_ContourBeingModified.clear(); - // let us have the selected point as a control point - contour->SetSelectedVertexAsControlPoint(true); - // finally, return true to pass this condition return true; } else { // do not pass condition return false; } mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); return true; } void mitk::ContourModelLiveWireInteractor::SetEditingContourModelNode(mitk::DataNode *_arg) { if (this->m_EditingContourNode != _arg) { this->m_EditingContourNode = _arg; } } void mitk::ContourModelLiveWireInteractor::SetWorkingImage(mitk::Image *_arg) { if (this->m_WorkingSlice != _arg) { this->m_WorkingSlice = _arg; this->m_LiveWireFilter->SetInput(this->m_WorkingSlice); } } void mitk::ContourModelLiveWireInteractor::OnDeletePoint(StateMachineAction *, InteractionEvent *interactionEvent) { const auto timeStep = interactionEvent->GetSender()->GetTimeStep(GetDataNode()->GetData()); auto *contour = dynamic_cast<mitk::ContourModel *>(this->GetDataNode()->GetData()); if (contour == nullptr) { MITK_ERROR << "Invalid Contour!"; return; } if (contour->GetSelectedVertex()) { mitk::ContourModel::Pointer newContour = mitk::ContourModel::New(); newContour->Expand(contour->GetTimeSteps()); newContour->SetTimeGeometry(contour->GetTimeGeometry()->Clone()); newContour->Concatenate(m_ContourLeft, timeStep); // recompute contour between neighbored two active control points this->m_LiveWireFilter->SetStartPoint(this->m_NextActiveVertexDown); this->m_LiveWireFilter->SetEndPoint(this->m_NextActiveVertexUp); - // this->m_LiveWireFilter->ClearRepulsivePoints(); this->m_LiveWireFilter->Update(); mitk::ContourModel *liveWireContour = this->m_LiveWireFilter->GetOutput(); assert(liveWireContour); if (liveWireContour->IsEmpty(timeStep)) return; liveWireContour->RemoveVertexAt(0, timeStep); liveWireContour->RemoveVertexAt(liveWireContour->GetNumberOfVertices(timeStep) - 1, timeStep); // insert new live wire computed points newContour->Concatenate(liveWireContour, timeStep); // insert right side of original contour newContour->Concatenate(this->m_ContourRight, timeStep); newContour->SetClosed(contour->IsClosed(timeStep), timeStep); // instead of leaving a single point, delete all points if (newContour->GetNumberOfVertices(timeStep) <= 2) { newContour->Clear(timeStep); } this->GetDataNode()->SetData(newContour); mitk::RenderingManager::GetInstance()->RequestUpdate(interactionEvent->GetSender()->GetRenderWindow()); } } void mitk::ContourModelLiveWireInteractor::OnMovePoint(StateMachineAction *, InteractionEvent *interactionEvent) { const auto *positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); if (!positionEvent) return; const auto timeStep = interactionEvent->GetSender()->GetTimeStep(GetDataNode()->GetData()); mitk::Point3D currentPosition = positionEvent->GetPositionInWorld(); auto *contour = dynamic_cast<mitk::ContourModel *>(this->GetDataNode()->GetData()); if (contour == nullptr) { MITK_ERROR << "invalid contour"; return; } mitk::ContourModel::Pointer editingContour = mitk::ContourModel::New(); editingContour->Expand(contour->GetTimeSteps()); editingContour->SetTimeGeometry(contour->GetTimeGeometry()->Clone()); // recompute left live wire, i.e. the contour between previous active vertex and selected vertex this->m_LiveWireFilter->SetStartPoint(this->m_NextActiveVertexDown); this->m_LiveWireFilter->SetEndPoint(currentPosition); // remove void positions between previous active vertex and next active vertex. if (!m_ContourBeingModified.empty()) { std::vector<itk::Index<2>>::const_iterator iter = m_ContourBeingModified.begin(); for (; iter != m_ContourBeingModified.end(); iter++) { this->m_LiveWireFilter->RemoveRepulsivePoint((*iter)); } } // update to get the left livewire. Remember that the points in the rest of the contour are already // set as void positions in the filter this->m_LiveWireFilter->Update(); mitk::ContourModel::Pointer leftLiveWire = this->m_LiveWireFilter->GetOutput(); assert(leftLiveWire); if (!leftLiveWire->IsEmpty(timeStep)) leftLiveWire->RemoveVertexAt(0, timeStep); editingContour->Concatenate(leftLiveWire, timeStep); // the new index of the selected vertex unsigned int selectedVertexIndex = this->m_ContourLeft->GetNumberOfVertices(timeStep) + leftLiveWire->GetNumberOfVertices(timeStep) - 1; // at this point the container has to be empty m_ContourBeingModified.clear(); // add points from left live wire contour auto iter = leftLiveWire->IteratorBegin(timeStep); for (; iter != leftLiveWire->IteratorEnd(timeStep); iter++) { itk::Index<2> idx; this->m_WorkingSlice->GetGeometry()->WorldToIndex((*iter)->Coordinates, idx); this->m_LiveWireFilter->AddRepulsivePoint(idx); // add indices m_ContourBeingModified.push_back(idx); } // recompute right live wire, i.e. the contour between selected vertex and next active vertex this->m_LiveWireFilter->SetStartPoint(currentPosition); this->m_LiveWireFilter->SetEndPoint(m_NextActiveVertexUp); // update filter with all contour points set as void but the right live wire portion to be calculated now this->m_LiveWireFilter->Update(); mitk::ContourModel::Pointer rightLiveWire = this->m_LiveWireFilter->GetOutput(); assert(rightLiveWire); // reject strange paths if (abs(rightLiveWire->GetNumberOfVertices(timeStep) - leftLiveWire->GetNumberOfVertices(timeStep)) > 50) { return; } if (!leftLiveWire->IsEmpty(timeStep)) leftLiveWire->SetControlVertexAt(leftLiveWire->GetNumberOfVertices() - 1, timeStep); if (!rightLiveWire->IsEmpty(timeStep)) rightLiveWire->RemoveVertexAt(0, timeStep); editingContour->Concatenate(rightLiveWire, timeStep); m_EditingContourNode->SetData(editingContour); mitk::ContourModel::Pointer newContour = mitk::ContourModel::New(); newContour->Expand(contour->GetTimeSteps()); newContour->SetTimeGeometry(contour->GetTimeGeometry()->Clone()); // concatenate left original contour newContour->Concatenate(this->m_ContourLeft, timeStep); newContour->Concatenate(editingContour, timeStep, true); // set last inserted vertex as selected newContour->SelectVertexAt(selectedVertexIndex, timeStep); // set as control point newContour->SetSelectedVertexAsControlPoint(true); // concatenate right original contour newContour->Concatenate(this->m_ContourRight, timeStep); newContour->SetClosed(contour->IsClosed(timeStep), timeStep); this->GetDataNode()->SetData(newContour); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } bool mitk::ContourModelLiveWireInteractor::IsHovering(const InteractionEvent *interactionEvent) { const auto *positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); if (!positionEvent) return false; const auto timeStep = interactionEvent->GetSender()->GetTimeStep(GetDataNode()->GetData()); auto *contour = dynamic_cast<mitk::ContourModel *>(this->GetDataNode()->GetData()); mitk::Point3D currentPosition = positionEvent->GetPositionInWorld(); bool isHover = false; this->GetDataNode()->GetBoolProperty("contour.hovering", isHover, positionEvent->GetSender()); - if (contour->IsNearContour(currentPosition, 1.5, timeStep)) + if (contour->IsNearContour(currentPosition, mitk::ContourModelLiveWireInteractor::eps, timeStep)) { if (isHover == false) { this->GetDataNode()->SetBoolProperty("contour.hovering", true); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } + return true; } else { if (isHover == true) { this->GetDataNode()->SetBoolProperty("contour.hovering", false); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } } return false; } -int mitk::ContourModelLiveWireInteractor::SplitContourFromSelectedVertex(mitk::ContourModel *srcContour, - mitk::ContourModel *destContour, - bool fromSelectedUpwards, - int timestep) +void mitk::ContourModelLiveWireInteractor::SplitContourFromSelectedVertex(mitk::ContourModel *srcContour, + const mitk::ContourModel::VertexType *nextPoint, + const mitk::ContourModel::VertexType *previousPoint, + int timeStep) { - auto end = srcContour->IteratorEnd(); - auto begin = srcContour->IteratorBegin(); + m_ContourLeft = mitk::ContourModel::New(); + m_ContourRight = mitk::ContourModel::New(); - // search next active control point to left and rigth and set as start and end point for filter - auto itSelected = begin; + auto it = srcContour->IteratorBegin(); + // part between nextPoint and end of Countour + bool upperPart = false; + // part between start of countour and previousPoint + bool lowerPart = true; - // move iterator to position - while ((*itSelected) != srcContour->GetSelectedVertex()) + // edge cases when point right before first control vertex is selected or first control vertex is selected + if (nextPoint == (*it) || srcContour->GetSelectedVertex() == (*it)) { - itSelected++; + upperPart = true; + lowerPart = false; + m_ContourLeft->AddVertex(previousPoint->Coordinates, previousPoint->IsControlPoint, timeStep); } - - // CASE search upwards for next control point - if (fromSelectedUpwards) + // if first control vertex is selected, move to next point before adding vertices to m_ContourRight + // otherwise, second line appears when moving the vertex + if (srcContour->GetSelectedVertex() == (*it)) { - auto itUp = itSelected; - - if (itUp != end) + while (*it != nextPoint) { - itUp++; // step once up otherwise the loop breaks immediately + it++; } + } - while (itUp != end && !((*itUp)->IsControlPoint)) + for (; it != srcContour->IteratorEnd(timeStep); it++) + { + // everything in lower part should be added to m_CountoutLeft + if (lowerPart) { - itUp++; + m_ContourLeft->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timeStep); } - - auto it = itUp; - - if (itSelected != begin) + // start of "restricted area" where no vertex should be added to m_CountoutLeft or m_CountoutRight + if (*it == previousPoint) { - // copy the rest of the original contour - while (it != end) - { - destContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timestep); - it++; - } + lowerPart = false; + upperPart = false; } - // else do not copy the contour - - // return the offset of iterator at one before next-vertex-upwards - if (itUp != begin) + // start of upperPart + if (*it == nextPoint) { - return std::distance(begin, itUp) - 1; + upperPart = true; } - else + // everything in upper part should be added to m_CountoutRight + if (upperPart) { - return std::distance(begin, itUp); + m_ContourRight->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timeStep); } } - else // CASE search downwards for next control point - { - auto itDown = itSelected; - auto it = srcContour->IteratorBegin(); +} - if (itSelected != begin) - { - if (itDown != begin) - { - itDown--; // step once down otherwise the the loop breaks immediately - } - - while (itDown != begin && !((*itDown)->IsControlPoint)) - { - itDown--; - } - - if (it != end) // if not empty - { - // always add the first vertex - destContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timestep); - it++; - } - // copy from begin to itDown - while (it <= itDown) - { - destContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timestep); - it++; - } - } - else - { - // if selected vertex is the first element search from end of contour downwards - itDown = end; - itDown--; - while (!((*itDown)->IsControlPoint) && itDown != begin) - { - itDown--; - } - - // move one forward as we don't want the first control point - it++; - // move iterator to second control point - while ((it != end) && !((*it)->IsControlPoint)) - { - it++; - } - // copy from begin to itDown - while (it <= itDown) - { - // copy the contour from second control point to itDown - destContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timestep); - it++; - } - } - /* - //add vertex at itDown - it's not considered during while loop - if( it != begin && it != end) - { - //destContour->AddVertex( (*it)->Coordinates, (*it)->IsControlPoint, timestep); - } - */ - // return the offset of iterator at one after next-vertex-downwards - if (itDown != end) - { - return std::distance(begin, itDown); // + 1;//index of next vertex - } - else +void mitk::ContourModelLiveWireInteractor::SetRepulsivePoints(const mitk::ContourModel::VertexType *pointToExclude, + mitk::ContourModel *contour, + int timeStep) +{ + auto it = contour->IteratorBegin(); + for (; it != contour->IteratorEnd(timeStep); it++) + { + if (*it != pointToExclude) { - return std::distance(begin, itDown) - 1; + itk::Index<2> idx; + this->m_WorkingSlice->GetGeometry()->WorldToIndex((*it)->Coordinates, idx); + this->m_LiveWireFilter->AddRepulsivePoint(idx); } } } void mitk::ContourModelLiveWireInteractor::OnFinishEditing(StateMachineAction *, InteractionEvent *interactionEvent) { const auto timeStep = interactionEvent->GetSender()->GetTimeStep(GetDataNode()->GetData()); auto *editingContour = dynamic_cast<mitk::ContourModel *>(this->m_EditingContourNode->GetData()); editingContour->Clear(timeStep); mitk::RenderingManager::GetInstance()->RequestUpdate(interactionEvent->GetSender()->GetRenderWindow()); } diff --git a/Modules/Segmentation/Interactions/mitkContourModelLiveWireInteractor.h b/Modules/Segmentation/Interactions/mitkContourModelLiveWireInteractor.h index 5d437fa213..6352775048 100644 --- a/Modules/Segmentation/Interactions/mitkContourModelLiveWireInteractor.h +++ b/Modules/Segmentation/Interactions/mitkContourModelLiveWireInteractor.h @@ -1,84 +1,95 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkContourModelLiveWireInteractor_h_Included #define mitkContourModelLiveWireInteractor_h_Included #include "mitkCommon.h" #include "mitkContourModelInteractor.h" #include <MitkSegmentationExports.h> #include <mitkImageLiveWireContourModelFilter.h> namespace mitk { /** \brief \sa Interactor \sa ContourModelInteractor \ingroup Interaction \warning Make sure the working image is properly set, otherwise the algorithm for computing livewire contour segments will not work! */ class MITKSEGMENTATION_EXPORT ContourModelLiveWireInteractor : public ContourModelInteractor { public: mitkClassMacro(ContourModelLiveWireInteractor, ContourModelInteractor); itkFactorylessNewMacro(Self); itkCloneMacro(Self); virtual void SetEditingContourModelNode(mitk::DataNode *_arg); virtual void SetWorkingImage(mitk::Image *_arg); void ConnectActionsAndFunctions() override; protected: ContourModelLiveWireInteractor(); ~ContourModelLiveWireInteractor() override; + /// \brief Select/ add and select vertex to modify contour and prepare for modification of contour. bool OnCheckPointClick(const InteractionEvent *interactionEvent) override; + /// \brief Check if mouse is hovering over contour bool IsHovering(const InteractionEvent *interactionEvent) override; + /// \brief Update contour when point is moved. void OnMovePoint(StateMachineAction *, InteractionEvent *interactionEvent) override; + /// \brief Delete selected vertex and recompute contour. void OnDeletePoint(StateMachineAction *, InteractionEvent *interactionEvent) override; + /// \brief Finish modification of contour. void OnFinishEditing(StateMachineAction *, InteractionEvent *interactionEvent) override; - int SplitContourFromSelectedVertex(mitk::ContourModel *srcContour, - mitk::ContourModel *destContour, - bool fromSelectedUpwards, - int timestep); - + /// \brief Split contour into a part before the selected vertex and after the selected vertex + void SplitContourFromSelectedVertex(mitk::ContourModel *srcContour, + const mitk::ContourModel::VertexType *nextPoint, + const mitk::ContourModel::VertexType *previousPoint, + int timestep); + /// \brief Set repulsive points which should not be changed during editing of the contour. + void SetRepulsivePoints(const mitk::ContourModel::VertexType *nextPoint, + mitk::ContourModel *contour, + int timestep); + + const float eps = 3.0; mitk::ImageLiveWireContourModelFilter::Pointer m_LiveWireFilter; mitk::Image::Pointer m_WorkingSlice; mitk::Point3D m_NextActiveVertexDown; mitk::Point3D m_NextActiveVertexUp; mitk::ContourModel::VertexIterator m_NextActiveVertexDownIter; mitk::ContourModel::VertexIterator m_NextActiveVertexUpIter; std::vector<itk::Index<2>> m_ContourBeingModified; mitk::DataNode::Pointer m_EditingContourNode; mitk::ContourModel::Pointer m_ContourLeft; mitk::ContourModel::Pointer m_ContourRight; }; } // namespace mitk #endif // mitkContourModelLiveWireInteractor_h_Included diff --git a/Modules/Segmentation/Interactions/mitkFeedbackContourTool.cpp b/Modules/Segmentation/Interactions/mitkFeedbackContourTool.cpp index e37f014527..ba1be71de4 100644 --- a/Modules/Segmentation/Interactions/mitkFeedbackContourTool.cpp +++ b/Modules/Segmentation/Interactions/mitkFeedbackContourTool.cpp @@ -1,278 +1,272 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkFeedbackContourTool.h" #include "mitkToolManager.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkStringProperty.h" #include "mitkBaseRenderer.h" #include "mitkDataStorage.h" #include "mitkRenderingManager.h" #include "mitkAbstractTransformGeometry.h" mitk::FeedbackContourTool::FeedbackContourTool(const char *type) : SegTool2D(type), m_FeedbackContourVisible(false) { m_FeedbackContourNode = DataNode::New(); m_FeedbackContourNode->SetProperty("name", StringProperty::New("One of FeedbackContourTool's feedback nodes")); m_FeedbackContourNode->SetProperty("visible", BoolProperty::New(true)); m_FeedbackContourNode->SetProperty("helper object", BoolProperty::New(true)); m_FeedbackContourNode->SetProperty("layer", IntProperty::New(1000)); m_FeedbackContourNode->SetProperty("contour.project-onto-plane", BoolProperty::New(false)); m_FeedbackContourNode->SetProperty("contour.width", FloatProperty::New(1.0)); // set to max short, max int doesn't work, max value somewhere hardcoded? m_FeedbackContourNode->SetProperty("layer", IntProperty::New(std::numeric_limits<short>::max())); m_FeedbackContourNode->SetProperty("fixedLayer", BoolProperty::New(true)); this->InitializeFeedbackContour(true); SetFeedbackContourColorDefault(); } mitk::FeedbackContourTool::~FeedbackContourTool() { } void mitk::FeedbackContourTool::SetFeedbackContourColor(float r, float g, float b) { m_FeedbackContourNode->SetProperty("contour.color", ColorProperty::New(r, g, b)); } void mitk::FeedbackContourTool::SetFeedbackContourColorDefault() { m_FeedbackContourNode->SetProperty("contour.color", ColorProperty::New(0.0 / 255.0, 255.0 / 255.0, 0.0 / 255.0)); } void mitk::FeedbackContourTool::Deactivated() { Superclass::Deactivated(); DataStorage *storage = this->GetToolManager()->GetDataStorage(); if (storage && m_FeedbackContourNode.IsNotNull()) { storage->Remove(m_FeedbackContourNode); m_FeedbackContour->Clear(); SetFeedbackContourVisible(false); } } void mitk::FeedbackContourTool::Activated() { Superclass::Activated(); this->InitializeFeedbackContour(true); this->SetFeedbackContourVisible(true); } const mitk::ContourModel *mitk::FeedbackContourTool::GetFeedbackContour() const { return m_FeedbackContour; } void mitk::FeedbackContourTool::InitializeFeedbackContour(bool isClosed) { m_FeedbackContour = ContourModel::New(); m_FeedbackContour->SetClosed(isClosed); auto workingImage = this->GetWorkingData(); if (nullptr != workingImage) { m_FeedbackContour->Expand(workingImage->GetTimeSteps()); auto contourTimeGeometry = workingImage->GetTimeGeometry()->Clone(); contourTimeGeometry->ReplaceTimeStepGeometries(m_FeedbackContour->GetGeometry()); m_FeedbackContour->SetTimeGeometry(contourTimeGeometry); for (unsigned int t = 0; t < m_FeedbackContour->GetTimeSteps(); ++t) { m_FeedbackContour->SetClosed(isClosed, t); } } m_FeedbackContourNode->SetData(m_FeedbackContour); } void mitk::FeedbackContourTool::ClearsCurrentFeedbackContour(bool isClosed) { if (!m_FeedbackContour->GetTimeGeometry()->IsValidTimePoint(this->GetLastTimePointTriggered())) { MITK_WARN << "Cannot clear feedback contour at current time step. Feedback contour is in invalid state as its time geometry does not support current selected time point. Invalid time point: " << this->GetLastTimePointTriggered(); return; } auto feedbackTimeStep = m_FeedbackContour->GetTimeGeometry()->TimePointToTimeStep(this->GetLastTimePointTriggered()); m_FeedbackContour->Clear(feedbackTimeStep); m_FeedbackContour->SetClosed(isClosed, feedbackTimeStep); } void mitk::FeedbackContourTool::UpdateCurrentFeedbackContour(const ContourModel* sourceModel, TimeStepType sourceTimeStep) { if (nullptr == sourceModel) return; if (!m_FeedbackContour->GetTimeGeometry()->IsValidTimePoint(this->GetLastTimePointTriggered())) { MITK_WARN << "Cannot update feedback contour. Feedback contour is in invalid state as its time geometry does not support current selected time point. Invalid time point: "<<this->GetLastTimePointTriggered(); return; } auto feedbackTimeStep = m_FeedbackContour->GetTimeGeometry()->TimePointToTimeStep(this->GetLastTimePointTriggered()); this->UpdateFeedbackContour(sourceModel, feedbackTimeStep, sourceTimeStep); } void mitk::FeedbackContourTool::UpdateFeedbackContour(const ContourModel* sourceModel, TimeStepType feedbackTimeStep, TimeStepType sourceTimeStep) { if (nullptr == sourceModel) return; if (!sourceModel->GetTimeGeometry()->IsValidTimeStep(sourceTimeStep)) { MITK_WARN << "Cannot update feedback contour. Source contour time geometry does not support passed time step. Invalid time step: " << sourceTimeStep; return; } if (!m_FeedbackContour->GetTimeGeometry()->IsValidTimeStep(feedbackTimeStep)) { MITK_WARN << "Cannot update feedback contour. Feedback contour time geometry does not support passed time step. Invalid time step: "<<feedbackTimeStep; return; } m_FeedbackContour->UpdateContour(sourceModel, feedbackTimeStep, sourceTimeStep); } void mitk::FeedbackContourTool::AddVertexToCurrentFeedbackContour(const Point3D& point) { if (!m_FeedbackContour->GetTimeGeometry()->IsValidTimePoint(this->GetLastTimePointTriggered())) { MITK_WARN << "Cannot add vertex to feedback contour. Feedback contour is in invalid state as its time geometry does not support current selected time point. Invalid time point: " << this->GetLastTimePointTriggered(); return; } auto feedbackTimeStep = m_FeedbackContour->GetTimeGeometry()->TimePointToTimeStep(this->GetLastTimePointTriggered()); this->AddVertexToFeedbackContour(point, feedbackTimeStep); }; /** Adds a vertex to the feedback contour for the passed time step. If time step is invalid, nothing will be added.*/ void mitk::FeedbackContourTool::AddVertexToFeedbackContour(const Point3D& point, TimeStepType feedbackTimeStep) { if (!m_FeedbackContour->GetTimeGeometry()->IsValidTimeStep(feedbackTimeStep)) { MITK_WARN << "Cannot add vertex to feedback contour. Feedback contour time geometry does not support passed time step. Invalid time step: " << feedbackTimeStep; return; } m_FeedbackContour->AddVertex(point, feedbackTimeStep); } void mitk::FeedbackContourTool::SetFeedbackContourVisible(bool visible) { if (m_FeedbackContourVisible == visible) return; // nothing changed if (DataStorage *storage = this->GetToolManager()->GetDataStorage()) { if (visible) { // Add the feedback contour node as a derived node of the first working data. // If there is no working data, the node is added at the top level. storage->Add(m_FeedbackContourNode, this->GetWorkingDataNode()); } else { storage->Remove(m_FeedbackContourNode); } } m_FeedbackContourVisible = visible; } mitk::ContourModel::Pointer mitk::FeedbackContourTool::ProjectContourTo2DSlice(const Image *slice, - const ContourModel *contourIn3D, - bool correctionForIpSegmentation, - bool constrainToInside) + const ContourModel *contourIn3D) { - return mitk::ContourModelUtils::ProjectContourTo2DSlice( - slice, contourIn3D, correctionForIpSegmentation, constrainToInside); + return mitk::ContourModelUtils::ProjectContourTo2DSlice(slice, contourIn3D); } mitk::ContourModel::Pointer mitk::FeedbackContourTool::BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry, - const ContourModel *contourIn2D, - bool correctionForIpSegmentation) + const ContourModel *contourIn2D) { - return mitk::ContourModelUtils::BackProjectContourFrom2DSlice( - sliceGeometry, contourIn2D, correctionForIpSegmentation); + return mitk::ContourModelUtils::BackProjectContourFrom2DSlice(sliceGeometry, contourIn2D); } void mitk::FeedbackContourTool::WriteBackFeedbackContourAsSegmentationResult(const InteractionPositionEvent* positionEvent, int paintingPixelValue, bool setInvisibleAfterSuccess) { if (!positionEvent) return; auto workingImage = this->GetWorkingData(); const auto planeGeometry((positionEvent->GetSender()->GetCurrentWorldPlaneGeometry())); if (!workingImage || !planeGeometry) return; const auto* abstractTransformGeometry( dynamic_cast<const AbstractTransformGeometry*>(positionEvent->GetSender()->GetCurrentWorldPlaneGeometry())); if (nullptr != abstractTransformGeometry) return; Image::Pointer slice = FeedbackContourTool::GetAffectedWorkingSlice(positionEvent); if (slice.IsNull()) { MITK_ERROR << "Unable to extract slice." << std::endl; return; } const auto feedbackContour = FeedbackContourTool::GetFeedbackContour(); auto contourTimeStep = positionEvent->GetSender()->GetTimeStep(feedbackContour); ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( - slice, feedbackContour, false, false); // false: don't add 0.5 (done by FillContourInSlice) - // false: don't constrain the contour to the image's inside + slice, feedbackContour); if (projectedContour.IsNull()) return; auto activePixelValue = ContourModelUtils::GetActivePixelValue(workingImage); mitk::ContourModelUtils::FillContourInSlice( projectedContour, contourTimeStep, slice, workingImage, paintingPixelValue * activePixelValue); this->WriteBackSegmentationResult(positionEvent, slice); if (setInvisibleAfterSuccess) { this->SetFeedbackContourVisible(false); } } void mitk::FeedbackContourTool::FillContourInSlice(ContourModel *projectedContour, Image *sliceImage, int paintingPixelValue) { this->FillContourInSlice(projectedContour, 0, sliceImage, paintingPixelValue); } void mitk::FeedbackContourTool::FillContourInSlice(ContourModel *projectedContour, unsigned int timeStep, Image *sliceImage, int paintingPixelValue) { mitk::ContourModelUtils::FillContourInSlice(projectedContour, timeStep, sliceImage, sliceImage, paintingPixelValue); } diff --git a/Modules/Segmentation/Interactions/mitkFeedbackContourTool.h b/Modules/Segmentation/Interactions/mitkFeedbackContourTool.h index 60c6b60f34..cac430741d 100644 --- a/Modules/Segmentation/Interactions/mitkFeedbackContourTool.h +++ b/Modules/Segmentation/Interactions/mitkFeedbackContourTool.h @@ -1,149 +1,141 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkFeedbackContourTool_h_Included #define mitkFeedbackContourTool_h_Included #include "mitkCommon.h" #include "mitkContourModelUtils.h" #include "mitkContourUtils.h" //TODO remove legacy support #include "mitkImage.h" #include "mitkSegTool2D.h" #include <MitkSegmentationExports.h> #include "mitkDataNode.h" #include "mitkImageCast.h" namespace mitk { /** \brief Base class for tools that use a contour for feedback \sa Tool \sa ContourModel \ingroup Interaction \ingroup ToolManagerEtAl Implements helper methods, that might be of use to all kind of 2D segmentation tools that use a contour for user feedback. - Providing a feedback contour that might be added or removed from the visible scene (SetFeedbackContourVisible). - Filling of a contour into a 2D slice These helper methods are actually implemented in ContourUtils now. FeedbackContourTool only forwards such requests. \warning Only to be instantiated by mitk::ToolManager. $Author: nolden $ */ class MITKSEGMENTATION_EXPORT FeedbackContourTool : public SegTool2D { public: mitkClassMacro(FeedbackContourTool, SegTool2D); protected: FeedbackContourTool(); // purposely hidden FeedbackContourTool(const char *); // purposely hidden ~FeedbackContourTool() override; const ContourModel *GetFeedbackContour() const; /** (Re)initialize the feesback contour by creating a new instance. * It is assured that the new instance as the same time geometry than * the working image.*/ void InitializeFeedbackContour(bool isClosed); /** Clears the current time step of the feedback contour and resets its closed state.*/ void ClearsCurrentFeedbackContour(bool isClosed); /** Updates the feedback contour of the currently selected time point. The update will be done * by clearing all existings vertices at the current time point and copying the vertics of the * source model at the specified source time step.*/ void UpdateCurrentFeedbackContour(const ContourModel* sourceModel, TimeStepType sourceTimeStep = 0); /** Updates the feedback contour at the time step specified by feedbackTimeStep. The update will be done * by clearing all existings vertices at feedbackTimeStep and copying the vertics of the * source model at the specified source time step.*/ void UpdateFeedbackContour(const ContourModel* sourceModel, TimeStepType feedbackTimeStep, TimeStepType sourceTimeStep = 0); /** Adds a vertex to the feedback contour for the current time point. */ void AddVertexToCurrentFeedbackContour(const Point3D& point); /** Adds a vertex to the feedback contour for the passed time step. If time step is invalid, nothing will be added.*/ void AddVertexToFeedbackContour(const Point3D& point, TimeStepType feedbackTimeStep); void SetFeedbackContourVisible(bool); /// Provide values from 0.0 (black) to 1.0 (full color) void SetFeedbackContourColor(float r, float g, float b); void SetFeedbackContourColorDefault(); void Deactivated() override; void Activated() override; /** \brief Projects a contour onto an image point by point. Converts from world to index coordinates. \param slice \param contourIn3D - \param correctionForIpSegmentation adds 0.5 to x and y index coordinates (difference between ipSegmentation and - MITK contours) - \param constrainToInside */ ContourModel::Pointer ProjectContourTo2DSlice(const Image *slice, - const ContourModel *contourIn3D, - bool correctionForIpSegmentation = false, - bool constrainToInside = true); + const ContourModel *contourIn3D); /** \brief Projects a slice index coordinates of a contour back into world coordinates. \param sliceGeometry \param contourIn2D - \param correctionForIpSegmentation subtracts 0.5 to x and y index coordinates (difference between ipSegmentation - and MITK contours) */ ContourModel::Pointer BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry, - const ContourModel *contourIn2D, - bool correctionForIpSegmentation = false); + const ContourModel *contourIn2D); /** Helper methods that checks all precondition and if they are fullfilled does the following: * 1. Gets the contour of the time point specified by positionEvent. * 2. Gets the affacted working slice of the time point specified by positionEvent. * 3. projects the contour onto the working slice and then fills it with the passed paintingPixelValue (adjusted by the current active lable value) * to the slice. * 4. writes the slice back into the working image using SegTool2D::WriteBackSegmentationResult().*/ void WriteBackFeedbackContourAsSegmentationResult(const InteractionPositionEvent* positionEvent, int paintingPixelValue, bool setInvisibleAfterSuccess = true); /** \brief Fill a contour in a 2D slice with a specified pixel value. */ void FillContourInSlice(ContourModel *projectedContour, Image *sliceImage, int paintingPixelValue = 1); /** \brief Fill a contour in a 2D slice with a specified pixel value at a given time step. */ void FillContourInSlice(ContourModel *projectedContour, unsigned int timeStep, Image *sliceImage, int paintingPixelValue = 1); private: ContourModel::Pointer m_FeedbackContour; DataNode::Pointer m_FeedbackContourNode; bool m_FeedbackContourVisible; }; } // namespace #endif diff --git a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp index 9ba41907cd..e8d13314c3 100644 --- a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp +++ b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp @@ -1,620 +1,694 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkContourModelUtils.h> #include <mitkLiveWireTool2D.h> #include <mitkLiveWireTool2D.xpm> #include <mitkToolManager.h> #include <usGetModuleContext.h> #include <usModuleResource.h> #include <type_traits> namespace mitk { MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, LiveWireTool2D, "LiveWire tool"); } mitk::LiveWireTool2D::LiveWireTool2D() : SegTool2D("LiveWireTool"), m_CreateAndUseDynamicCosts(false) { } mitk::LiveWireTool2D::~LiveWireTool2D() { this->ClearSegmentation(); } void mitk::LiveWireTool2D::RemoveHelperObjects() { auto dataStorage = this->GetToolManager()->GetDataStorage(); if (nullptr == dataStorage) return; for (const auto &editingContour : m_EditingContours) dataStorage->Remove(editingContour.first); for (const auto &workingContour : m_WorkingContours) dataStorage->Remove(workingContour.first); if (m_EditingContourNode.IsNotNull()) dataStorage->Remove(m_EditingContourNode); if (m_LiveWireContourNode.IsNotNull()) dataStorage->Remove(m_LiveWireContourNode); + if (m_ClosureContourNode.IsNotNull()) + dataStorage->Remove(m_ClosureContourNode); + if (m_ContourNode.IsNotNull()) dataStorage->Remove(m_ContourNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::LiveWireTool2D::ReleaseHelperObjects() { this->RemoveHelperObjects(); m_EditingContours.clear(); m_WorkingContours.clear(); m_EditingContourNode = nullptr; m_EditingContour = nullptr; m_LiveWireContourNode = nullptr; m_LiveWireContour = nullptr; + m_ClosureContourNode = nullptr; + m_ClosureContour = nullptr; + m_ContourNode = nullptr; m_Contour = nullptr; } void mitk::LiveWireTool2D::ReleaseInteractors() { this->EnableContourLiveWireInteraction(false); m_LiveWireInteractors.clear(); } void mitk::LiveWireTool2D::ConnectActionsAndFunctions() { - CONNECT_CONDITION("CheckContourClosed", OnCheckPoint); - CONNECT_FUNCTION("InitObject", OnInitLiveWire); CONNECT_FUNCTION("AddPoint", OnAddPoint); CONNECT_FUNCTION("CtrlAddPoint", OnAddPoint); CONNECT_FUNCTION("MovePoint", OnMouseMoveNoDynamicCosts); CONNECT_FUNCTION("FinishContour", OnFinish); CONNECT_FUNCTION("DeletePoint", OnLastSegmentDelete); CONNECT_FUNCTION("CtrlMovePoint", OnMouseMoved); } const char **mitk::LiveWireTool2D::GetXPM() const { return mitkLiveWireTool2D_xpm; } us::ModuleResource mitk::LiveWireTool2D::GetIconResource() const { return us::GetModuleContext()->GetModule()->GetResource("LiveWire_48x48.png"); } us::ModuleResource mitk::LiveWireTool2D::GetCursorIconResource() const { return us::GetModuleContext()->GetModule()->GetResource("LiveWire_Cursor_32x32.png"); } const char *mitk::LiveWireTool2D::GetName() const { return "Live Wire"; } void mitk::LiveWireTool2D::Activated() { Superclass::Activated(); this->ResetToStartState(); this->EnableContourLiveWireInteraction(true); } void mitk::LiveWireTool2D::Deactivated() { this->ConfirmSegmentation(); Superclass::Deactivated(); } void mitk::LiveWireTool2D::UpdateLiveWireContour() { if (m_Contour.IsNotNull()) { auto timeGeometry = m_Contour->GetTimeGeometry()->Clone(); m_LiveWireContour = this->m_LiveWireFilter->GetOutput(); - m_LiveWireContour->SetTimeGeometry(timeGeometry); //needed because the results of the filter are always from 0 ms to 1 ms and the filter also resets its outputs. + m_LiveWireContour->SetTimeGeometry(timeGeometry); // needed because the results of the filter are always from 0 ms + // to 1 ms and the filter also resets its outputs. m_LiveWireContourNode->SetData(this->m_LiveWireContour); + + m_ClosureContour = this->m_LiveWireFilterClosure->GetOutput(); + m_ClosureContour->SetTimeGeometry(timeGeometry); // needed because the results of the filter are always from 0 ms + // to 1 ms and the filter also resets its outputs. + m_ClosureContourNode->SetData(this->m_ClosureContour); } } void mitk::LiveWireTool2D::OnTimePointChanged() { auto reference = this->GetReferenceData(); if (nullptr == reference || m_PlaneGeometry.IsNull() || m_LiveWireFilter.IsNull() || m_LiveWireContourNode.IsNull()) return; auto timeStep = reference->GetTimeGeometry()->TimePointToTimeStep(this->GetLastTimePointTriggered()); m_ReferenceDataSlice = GetAffectedImageSliceAs2DImageByTimePoint(m_PlaneGeometry, reference, timeStep); m_LiveWireFilter->SetInput(m_ReferenceDataSlice); m_LiveWireFilter->Update(); + m_LiveWireFilterClosure->SetInput(m_ReferenceDataSlice); + + m_LiveWireFilterClosure->Update(); + this->UpdateLiveWireContour(); RenderingManager::GetInstance()->RequestUpdateAll(); }; void mitk::LiveWireTool2D::EnableContourLiveWireInteraction(bool on) { for (const auto &interactor : m_LiveWireInteractors) interactor->EnableInteraction(on); } void mitk::LiveWireTool2D::ConfirmSegmentation() { auto referenceImage = this->GetReferenceData(); auto workingImage = this->GetWorkingData(); if (nullptr != referenceImage && nullptr != workingImage) { std::vector<SliceInformation> sliceInfos; sliceInfos.reserve(m_WorkingContours.size()); const auto currentTimePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); TimeStepType workingImageTimeStep = workingImage->GetTimeGeometry()->TimePointToTimeStep(currentTimePoint); for (const auto &workingContour : m_WorkingContours) { auto contour = dynamic_cast<ContourModel *>(workingContour.first->GetData()); if (nullptr == contour || contour->IsEmpty()) continue; auto sameSlicePredicate = [&workingContour, workingImageTimeStep](const SliceInformation& si) { return workingContour.second->IsOnPlane(si.plane) && workingImageTimeStep == si.timestep; }; auto finding = std::find_if(sliceInfos.begin(), sliceInfos.end(), sameSlicePredicate); if (finding == sliceInfos.end()) { auto workingSlice = this->GetAffectedImageSliceAs2DImage(workingContour.second, workingImage, workingImageTimeStep)->Clone(); sliceInfos.emplace_back(workingSlice, workingContour.second, workingImageTimeStep); finding = std::prev(sliceInfos.end()); } //cast const away is OK in this case, because these are all slices created and manipulated //localy in this function call. And we want to keep the high constness of SliceInformation for //public interfaces. auto workingSlice = const_cast<Image*>(finding->slice.GetPointer()); - auto projectedContour = ContourModelUtils::ProjectContourTo2DSlice(workingSlice, contour, true, false); + auto projectedContour = ContourModelUtils::ProjectContourTo2DSlice(workingSlice, contour); int activePixelValue = ContourModelUtils::GetActivePixelValue(workingImage); ContourModelUtils::FillContourInSlice( projectedContour, workingSlice, workingImage, activePixelValue); } this->WriteBackSegmentationResults(sliceInfos); } this->ClearSegmentation(); } void mitk::LiveWireTool2D::ClearSegmentation() { this->ReleaseHelperObjects(); this->ReleaseInteractors(); this->ResetToStartState(); } bool mitk::LiveWireTool2D::IsPositionEventInsideImageRegion(mitk::InteractionPositionEvent *positionEvent, mitk::BaseData *data) { bool isPositionEventInsideImageRegion = nullptr != data && data->GetGeometry()->IsInside(positionEvent->GetPositionInWorld()); if (!isPositionEventInsideImageRegion) MITK_WARN("LiveWireTool2D") << "PositionEvent is outside ImageRegion!"; return isPositionEventInsideImageRegion; } mitk::ContourModel::Pointer mitk::LiveWireTool2D::CreateNewContour() const { auto workingData = this->GetWorkingData(); if (nullptr == workingData) { this->InteractiveSegmentationBugMessage("Cannot create new contour. No valid working data is set. Application is in invalid state."); mitkThrow() << "Cannot create new contour. No valid working data is set. Application is in invalid state."; } auto contour = ContourModel::New(); //generate a time geometry that is always visible as the working contour should always be. auto contourTimeGeometry = ProportionalTimeGeometry::New(); contourTimeGeometry->SetStepDuration(std::numeric_limits<TimePointType>::max()); contourTimeGeometry->SetTimeStepGeometry(contour->GetTimeGeometry()->GetGeometryForTimeStep(0)->Clone(), 0); contour->SetTimeGeometry(contourTimeGeometry); return contour; } void mitk::LiveWireTool2D::OnInitLiveWire(StateMachineAction *, InteractionEvent *interactionEvent) { auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (nullptr == positionEvent) return; auto workingDataNode = this->GetWorkingDataNode(); if (!IsPositionEventInsideImageRegion(positionEvent, workingDataNode->GetData())) { this->ResetToStartState(); return; } m_LastEventSender = positionEvent->GetSender(); m_LastEventSlice = m_LastEventSender->GetSlice(); m_Contour = this->CreateNewContour(); m_ContourNode = mitk::DataNode::New(); m_ContourNode->SetData(m_Contour); m_ContourNode->SetName("working contour node"); m_ContourNode->SetProperty("layer", IntProperty::New(100)); m_ContourNode->AddProperty("fixedLayer", BoolProperty::New(true)); m_ContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_ContourNode->AddProperty("contour.color", ColorProperty::New(1.0f, 1.0f, 0.0f), nullptr, true); m_ContourNode->AddProperty("contour.points.color", ColorProperty::New(1.0f, 0.0f, 0.1f), nullptr, true); m_ContourNode->AddProperty("contour.controlpoints.show", BoolProperty::New(true), nullptr, true); m_LiveWireContour = this->CreateNewContour(); m_LiveWireContourNode = mitk::DataNode::New(); m_LiveWireContourNode->SetData(m_LiveWireContour); m_LiveWireContourNode->SetName("active livewire node"); m_LiveWireContourNode->SetProperty("layer", IntProperty::New(101)); m_LiveWireContourNode->AddProperty("fixedLayer", BoolProperty::New(true)); m_LiveWireContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_LiveWireContourNode->AddProperty("contour.color", ColorProperty::New(0.1f, 1.0f, 0.1f), nullptr, true); m_LiveWireContourNode->AddProperty("contour.width", mitk::FloatProperty::New(4.0f), nullptr, true); + m_ClosureContour = this->CreateNewContour(); + m_ClosureContourNode = mitk::DataNode::New(); + m_ClosureContourNode->SetData(m_ClosureContour); + m_ClosureContourNode->SetName("active closure node"); + m_ClosureContourNode->SetProperty("layer", IntProperty::New(101)); + m_ClosureContourNode->AddProperty("fixedLayer", BoolProperty::New(true)); + m_ClosureContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); + m_ClosureContourNode->AddProperty("contour.color", ColorProperty::New(0.0f, 1.0f, 0.1f), nullptr, true); + m_ClosureContourNode->AddProperty("contour.width", mitk::FloatProperty::New(2.0f), nullptr, true); + m_EditingContour = this->CreateNewContour(); m_EditingContourNode = mitk::DataNode::New(); m_EditingContourNode->SetData(m_EditingContour); m_EditingContourNode->SetName("editing node"); m_EditingContourNode->SetProperty("layer", IntProperty::New(102)); m_EditingContourNode->AddProperty("fixedLayer", BoolProperty::New(true)); m_EditingContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_EditingContourNode->AddProperty("contour.color", ColorProperty::New(0.1f, 1.0f, 0.1f), nullptr, true); m_EditingContourNode->AddProperty("contour.points.color", ColorProperty::New(0.0f, 0.0f, 1.0f), nullptr, true); m_EditingContourNode->AddProperty("contour.width", mitk::FloatProperty::New(4.0f), nullptr, true); auto dataStorage = this->GetToolManager()->GetDataStorage(); dataStorage->Add(m_ContourNode, workingDataNode); dataStorage->Add(m_LiveWireContourNode, workingDataNode); + dataStorage->Add(m_ClosureContourNode, workingDataNode); dataStorage->Add(m_EditingContourNode, workingDataNode); // Set current slice as input for ImageToLiveWireContourFilter m_ReferenceDataSlice = this->GetAffectedReferenceSlice(positionEvent); auto origin = m_ReferenceDataSlice->GetSlicedGeometry()->GetOrigin(); m_ReferenceDataSlice->GetSlicedGeometry()->WorldToIndex(origin, origin); m_ReferenceDataSlice->GetSlicedGeometry()->IndexToWorld(origin, origin); m_ReferenceDataSlice->GetSlicedGeometry()->SetOrigin(origin); m_LiveWireFilter = ImageLiveWireContourModelFilter::New(); + m_LiveWireFilter->SetUseCostFunction(true); m_LiveWireFilter->SetInput(m_ReferenceDataSlice); + m_LiveWireFilterClosure = ImageLiveWireContourModelFilter::New(); + m_LiveWireFilterClosure->SetUseCostFunction(false); + m_LiveWireFilterClosure->SetInput(m_ReferenceDataSlice); + // Map click to pixel coordinates auto click = positionEvent->GetPositionInWorld(); itk::Index<3> idx; m_ReferenceDataSlice->GetGeometry()->WorldToIndex(click, idx); // Get the pixel with the highest gradient in a 7x7 region itk::Index<3> indexWithHighestGradient; AccessFixedDimensionByItk_2(m_ReferenceDataSlice, FindHighestGradientMagnitudeByITK, 2, idx, indexWithHighestGradient); click[0] = indexWithHighestGradient[0]; click[1] = indexWithHighestGradient[1]; click[2] = indexWithHighestGradient[2]; m_ReferenceDataSlice->GetGeometry()->IndexToWorld(click, click); // Set initial start point m_Contour->AddVertex(click, true); m_LiveWireFilter->SetStartPoint(click); + //m_LiveWireFilterClosure->SetStartPoint(click); + m_LiveWireFilterClosure->SetEndPoint(click); // Remember PlaneGeometry to determine if events were triggered in the same plane m_PlaneGeometry = interactionEvent->GetSender()->GetCurrentWorldPlaneGeometry(); m_CreateAndUseDynamicCosts = true; mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } void mitk::LiveWireTool2D::OnAddPoint(StateMachineAction *, InteractionEvent *interactionEvent) { // Complete LiveWire interaction for the last segment. Add current LiveWire contour to // the finished contour and reset to start a new segment and computation. auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (nullptr == positionEvent) return; if (m_PlaneGeometry.IsNotNull()) { // Check if the point is in the correct slice if (m_PlaneGeometry->DistanceFromPlane(positionEvent->GetPositionInWorld()) > mitk::sqrteps) return; } // Add repulsive points to avoid getting the same path again std::for_each(m_LiveWireContour->IteratorBegin(), m_LiveWireContour->IteratorEnd(), [this](ContourElement::VertexType *vertex) { ImageLiveWireContourModelFilter::InternalImageType::IndexType idx; this->m_ReferenceDataSlice->GetGeometry()->WorldToIndex(vertex->Coordinates, idx); this->m_LiveWireFilter->AddRepulsivePoint(idx); + this->m_LiveWireFilterClosure->AddRepulsivePoint(idx); }); // Remove duplicate first vertex, it's already contained in m_Contour m_LiveWireContour->RemoveVertexAt(0); // Set last point as control point m_LiveWireContour->SetControlVertexAt(m_LiveWireContour->GetNumberOfVertices() - 1); // Merge contours m_Contour->Concatenate(m_LiveWireContour); // Clear the LiveWire contour and reset the corresponding DataNode m_LiveWireContour->Clear(); // Set new start point m_LiveWireFilter->SetStartPoint(positionEvent->GetPositionInWorld()); + m_LiveWireFilterClosure->SetStartPoint(positionEvent->GetPositionInWorld()); if (m_CreateAndUseDynamicCosts) { // Use dynamic cost map for next update m_LiveWireFilter->CreateDynamicCostMap(m_Contour); m_LiveWireFilter->SetUseDynamicCostMap(true); + + m_LiveWireFilterClosure->CreateDynamicCostMap(m_Contour); + m_LiveWireFilterClosure->SetUseDynamicCostMap(true); } mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } void mitk::LiveWireTool2D::OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent) { // Compute LiveWire segment from last control point to current mouse position auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (nullptr == positionEvent) return; + if (m_PlaneGeometry.IsNotNull()) + { + // Check if the point is in the correct slice + if (m_PlaneGeometry->DistanceFromPlane(positionEvent->GetPositionInWorld()) > mitk::sqrteps) + return; + } + + //if (m_ClosureContour->IsEmpty()) + //{ + // m_ClosureContour->AddVertex(m_Contour->GetVertexAt(0)->Coordinates); + // m_ClosureContour->AddVertex(positionEvent->GetPositionInWorld()); + //} + //else + //{ + // m_ClosureContour->SetVertexAt(1, positionEvent->GetPositionInWorld()); + //} + m_LiveWireFilter->SetEndPoint(positionEvent->GetPositionInWorld()); m_LiveWireFilter->Update(); + m_LiveWireFilterClosure->SetStartPoint(positionEvent->GetPositionInWorld()); + m_LiveWireFilterClosure->Update(); + this->UpdateLiveWireContour(); RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } void mitk::LiveWireTool2D::OnMouseMoveNoDynamicCosts(StateMachineAction *, InteractionEvent *interactionEvent) { m_LiveWireFilter->SetUseDynamicCostMap(false); + m_LiveWireFilterClosure->SetUseDynamicCostMap(false); this->OnMouseMoved(nullptr, interactionEvent); m_LiveWireFilter->SetUseDynamicCostMap(true); + m_LiveWireFilterClosure->SetUseDynamicCostMap(true); } bool mitk::LiveWireTool2D::OnCheckPoint(const InteractionEvent *interactionEvent) { // Check double click on first control point to finish the LiveWire tool auto positionEvent = dynamic_cast<const mitk::InteractionPositionEvent *>(interactionEvent); if (nullptr == positionEvent) return false; mitk::Point3D click = positionEvent->GetPositionInWorld(); mitk::Point3D first = this->m_Contour->GetVertexAt(0)->Coordinates; return first.EuclideanDistanceTo(click) < 4.5; } void mitk::LiveWireTool2D::OnFinish(StateMachineAction *, InteractionEvent *interactionEvent) { // Finish LiveWire tool interaction + m_Contour->Concatenate(m_ClosureContour); auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (nullptr == positionEvent) return; - // Remove last control point added by double click - m_Contour->RemoveVertexAt(m_Contour->GetNumberOfVertices() - 1); + if (m_PlaneGeometry.IsNotNull()) + { + // Check if the point is in the correct slice + if (m_PlaneGeometry->DistanceFromPlane(positionEvent->GetPositionInWorld()) > mitk::sqrteps) + return; + } + + //m_Contour->AddVertex(m_Contour->GetVertexAt(0)->Coordinates, false); + // Remove last control point added by double click, if double click was performed on first point + //if (OnCheckPoint(interactionEvent)) + // m_Contour->RemoveVertexAt(m_Contour->GetNumberOfVertices() - 1); + + // remove green connection between mouse position and start point + m_ClosureContour->Clear(); // Save contour and corresponding plane geometry to list this->m_WorkingContours.emplace_back(std::make_pair(m_ContourNode, positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone())); this->m_EditingContours.emplace_back(std::make_pair(m_EditingContourNode, positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone())); m_LiveWireFilter->SetUseDynamicCostMap(false); + m_LiveWireFilterClosure->SetUseDynamicCostMap(false); this->FinishTool(); } void mitk::LiveWireTool2D::FinishTool() { auto numberOfTimesteps = static_cast<int>(m_Contour->GetTimeSteps()); for (int i = 0; i <= numberOfTimesteps; ++i) m_Contour->Close(i); this->GetToolManager()->GetDataStorage()->Remove(m_LiveWireContourNode); m_LiveWireContourNode = nullptr; m_LiveWireContour = nullptr; m_ContourInteractor = mitk::ContourModelLiveWireInteractor::New(); m_ContourInteractor->SetDataNode(m_ContourNode); m_ContourInteractor->LoadStateMachine("ContourModelModificationInteractor.xml", us::GetModuleContext()->GetModule()); m_ContourInteractor->SetEventConfig("ContourModelModificationConfig.xml", us::GetModuleContext()->GetModule()); m_ContourInteractor->SetWorkingImage(this->m_ReferenceDataSlice); m_ContourInteractor->SetEditingContourModelNode(this->m_EditingContourNode); m_ContourNode->SetDataInteractor(m_ContourInteractor.GetPointer()); this->m_LiveWireInteractors.push_back(m_ContourInteractor); } void mitk::LiveWireTool2D::OnLastSegmentDelete(StateMachineAction *, InteractionEvent *interactionEvent) { // If last point of current contour will be removed go to start state and remove nodes if (m_Contour->GetNumberOfVertices() <= 1) { auto dataStorage = this->GetToolManager()->GetDataStorage(); dataStorage->Remove(m_LiveWireContourNode); dataStorage->Remove(m_ContourNode); dataStorage->Remove(m_EditingContourNode); m_LiveWireContour = this->CreateNewContour(); m_LiveWireContourNode->SetData(m_LiveWireContour); m_Contour = this->CreateNewContour(); m_ContourNode->SetData(m_Contour); this->ResetToStartState(); } else // Remove last segment from contour and reset LiveWire contour { m_LiveWireContour = this->CreateNewContour(); m_LiveWireContourNode->SetData(m_LiveWireContour); auto newContour = this->CreateNewContour(); auto begin = m_Contour->IteratorBegin(); // Iterate from last point to next active point auto newLast = m_Contour->IteratorBegin() + (m_Contour->GetNumberOfVertices() - 1); // Go at least one down if (newLast != begin) --newLast; // Search next active control point while (newLast != begin && !((*newLast)->IsControlPoint)) --newLast; // Set position of start point for LiveWire filter to coordinates of the new last point m_LiveWireFilter->SetStartPoint((*newLast)->Coordinates); + //m_LiveWireFilterClosure->SetStartPoint((*newLast)->Coordinates); auto it = m_Contour->IteratorBegin(); // Fll new Contour while (it <= newLast) { newContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint); ++it; } newContour->SetClosed(m_Contour->IsClosed()); m_ContourNode->SetData(newContour); m_Contour = newContour; mitk::RenderingManager::GetInstance()->RequestUpdate(interactionEvent->GetSender()->GetRenderWindow()); } } template <typename TPixel, unsigned int VImageDimension> void mitk::LiveWireTool2D::FindHighestGradientMagnitudeByITK(itk::Image<TPixel, VImageDimension> *inputImage, itk::Index<3> &index, itk::Index<3> &returnIndex) { typedef itk::Image<TPixel, VImageDimension> InputImageType; typedef typename InputImageType::IndexType IndexType; const auto MAX_X = inputImage->GetLargestPossibleRegion().GetSize()[0]; const auto MAX_Y = inputImage->GetLargestPossibleRegion().GetSize()[1]; returnIndex[0] = index[0]; returnIndex[1] = index[1]; returnIndex[2] = 0.0; double gradientMagnitude = 0.0; double maxGradientMagnitude = 0.0; // The size and thus the region of 7x7 is only used to calculate the gradient magnitude in that region, // not for searching the maximum value. // Maximum value in each direction for size typename InputImageType::SizeType size; size[0] = 7; size[1] = 7; // Minimum value in each direction for startRegion IndexType startRegion; startRegion[0] = index[0] - 3; startRegion[1] = index[1] - 3; if (startRegion[0] < 0) startRegion[0] = 0; if (startRegion[1] < 0) startRegion[1] = 0; if (MAX_X - index[0] < 7) startRegion[0] = MAX_X - 7; if (MAX_Y - index[1] < 7) startRegion[1] = MAX_Y - 7; index[0] = startRegion[0] + 3; index[1] = startRegion[1] + 3; typename InputImageType::RegionType region; region.SetSize(size); region.SetIndex(startRegion); typedef typename itk::GradientMagnitudeImageFilter<InputImageType, InputImageType> GradientMagnitudeFilterType; typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New(); gradientFilter->SetInput(inputImage); gradientFilter->GetOutput()->SetRequestedRegion(region); gradientFilter->Update(); typename InputImageType::Pointer gradientMagnitudeImage; gradientMagnitudeImage = gradientFilter->GetOutput(); IndexType currentIndex; currentIndex[0] = 0; currentIndex[1] = 0; // Search max (approximate) gradient magnitude for (int x = -1; x <= 1; ++x) { currentIndex[0] = index[0] + x; for (int y = -1; y <= 1; ++y) { currentIndex[1] = index[1] + y; gradientMagnitude = gradientMagnitudeImage->GetPixel(currentIndex); // Check for new max if (maxGradientMagnitude < gradientMagnitude) { maxGradientMagnitude = gradientMagnitude; returnIndex[0] = currentIndex[0]; returnIndex[1] = currentIndex[1]; returnIndex[2] = 0.0; } } currentIndex[1] = index[1]; } } diff --git a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.h b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.h index dff07f7a0b..33e85d700a 100644 --- a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.h +++ b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.h @@ -1,139 +1,143 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkLiveWireTool2D_h #define mitkLiveWireTool2D_h #include <mitkSegTool2D.h> #include <mitkContourModelLiveWireInteractor.h> namespace mitk { /** \brief A 2D segmentation tool based on a LiveWire approach. The contour between the last point and the current mouse position is computed by searching the shortest path according to specific features of the image. The contour thus tends to snap to the boundary of objects. The tool always assumes that unconfirmed contours are always defined for the current time point. So the time step in which the contours will be stored as segmentations will be determined when the contours got confirmed. Then they will be transfered to the slices of the currently selected time step. Changing the time point/time step while tool is active will updated the working slice the live wire filter. So the behavior of the active live wire contour is always WYSIWYG (What you see is what you get). \sa SegTool2D \sa ImageLiveWireContourModelFilter \ingroup Interaction \ingroup ToolManagerEtAl \warning Only to be instantiated by mitk::ToolManager. */ class MITKSEGMENTATION_EXPORT LiveWireTool2D : public SegTool2D { public: mitkClassMacro(LiveWireTool2D, SegTool2D); itkFactorylessNewMacro(Self); us::ModuleResource GetCursorIconResource() const override; us::ModuleResource GetIconResource() const override; const char *GetName() const override; const char **GetXPM() const override; /// \brief Convert all current contours to binary segmentations. void ConfirmSegmentation(); /// \brief Delete all current contours. void ClearSegmentation(); protected: LiveWireTool2D(); ~LiveWireTool2D() override; void ConnectActionsAndFunctions() override; void Activated() override; void Deactivated() override; void UpdateLiveWireContour(); void OnTimePointChanged() override; private: /// \brief Initialize tool. void OnInitLiveWire(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Add a control point and finish current segment. void OnAddPoint(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Actual LiveWire computation. void OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Check double click on first control point to finish the LiveWire tool. bool OnCheckPoint(const InteractionEvent *interactionEvent); /// \brief Finish LiveWire tool. void OnFinish(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Close the contour. void OnLastSegmentDelete(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Don't use dynamic cost map for LiveWire calculation. void OnMouseMoveNoDynamicCosts(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Finish contour interaction. void FinishTool(); void EnableContourLiveWireInteraction(bool on); bool IsPositionEventInsideImageRegion(InteractionPositionEvent *positionEvent, BaseData *data); void ReleaseInteractors(); void ReleaseHelperObjects(); void RemoveHelperObjects(); template <typename TPixel, unsigned int VImageDimension> void FindHighestGradientMagnitudeByITK(itk::Image<TPixel, VImageDimension> *inputImage, itk::Index<3> &index, itk::Index<3> &returnIndex); ContourModel::Pointer CreateNewContour() const; mitk::ContourModel::Pointer m_Contour; mitk::DataNode::Pointer m_ContourNode; mitk::ContourModel::Pointer m_LiveWireContour; mitk::DataNode::Pointer m_LiveWireContourNode; + mitk::ContourModel::Pointer m_ClosureContour; + mitk::DataNode::Pointer m_ClosureContourNode; + mitk::ContourModel::Pointer m_EditingContour; mitk::DataNode::Pointer m_EditingContourNode; mitk::ContourModelLiveWireInteractor::Pointer m_ContourInteractor; /** Slice of the reference data the tool is currently actively working on to define contours.*/ mitk::Image::Pointer m_ReferenceDataSlice; mitk::ImageLiveWireContourModelFilter::Pointer m_LiveWireFilter; + mitk::ImageLiveWireContourModelFilter::Pointer m_LiveWireFilterClosure; bool m_CreateAndUseDynamicCosts; std::vector<std::pair<mitk::DataNode::Pointer, mitk::PlaneGeometry::Pointer>> m_WorkingContours; std::vector<std::pair<mitk::DataNode::Pointer, mitk::PlaneGeometry::Pointer>> m_EditingContours; std::vector<mitk::ContourModelLiveWireInteractor::Pointer> m_LiveWireInteractors; PlaneGeometry::ConstPointer m_PlaneGeometry; }; } #endif diff --git a/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp b/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp index 0fa978346e..2bc6b9c576 100644 --- a/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp +++ b/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp @@ -1,573 +1,510 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkRegionGrowingTool.h" #include "mitkBaseRenderer.h" #include "mitkImageToContourModelFilter.h" #include "mitkRegionGrowingTool.xpm" #include "mitkRenderingManager.h" #include "mitkToolManager.h" // us #include <usGetModuleContext.h> #include <usModule.h> #include <usModuleContext.h> #include <usModuleResource.h> // ITK #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" #include <itkConnectedComponentImageFilter.h> #include <itkConnectedThresholdImageFilter.h> #include <itkNeighborhoodIterator.h> #include <itkImageDuplicator.h> #include <limits> namespace mitk { MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, RegionGrowingTool, "Region growing tool"); } #define ROUND(a) ((a) > 0 ? (int)((a) + 0.5) : -(int)(0.5 - (a))) mitk::RegionGrowingTool::RegionGrowingTool() : FeedbackContourTool("PressMoveRelease"), m_SeedValue(0), m_ScreenYDifference(0), m_ScreenXDifference(0), m_MouseDistanceScaleFactor(0.5), m_PaintingPixelValue(0), m_FillFeedbackContour(true), m_ConnectedComponentValue(1) { } mitk::RegionGrowingTool::~RegionGrowingTool() { } void mitk::RegionGrowingTool::ConnectActionsAndFunctions() { CONNECT_FUNCTION("PrimaryButtonPressed", OnMousePressed); CONNECT_FUNCTION("Move", OnMouseMoved); CONNECT_FUNCTION("Release", OnMouseReleased); } const char **mitk::RegionGrowingTool::GetXPM() const { return mitkRegionGrowingTool_xpm; } us::ModuleResource mitk::RegionGrowingTool::GetIconResource() const { us::Module *module = us::GetModuleContext()->GetModule(); us::ModuleResource resource = module->GetResource("RegionGrowing_48x48.png"); return resource; } us::ModuleResource mitk::RegionGrowingTool::GetCursorIconResource() const { us::Module *module = us::GetModuleContext()->GetModule(); us::ModuleResource resource = module->GetResource("RegionGrowing_Cursor_32x32.png"); return resource; } const char *mitk::RegionGrowingTool::GetName() const { return "Region Growing"; } void mitk::RegionGrowingTool::Activated() { Superclass::Activated(); } void mitk::RegionGrowingTool::Deactivated() { Superclass::Deactivated(); } // Get the average pixel value of square/cube with radius=neighborhood around index template <typename TPixel, unsigned int imageDimension> void mitk::RegionGrowingTool::GetNeighborhoodAverage(const itk::Image<TPixel, imageDimension> *itkImage, const itk::Index<imageDimension>& index, ScalarType *result, unsigned int neighborhood) { // maybe assert that image dimension is only 2 or 3? auto neighborhoodInt = (int)neighborhood; TPixel averageValue(0); unsigned int numberOfPixels = (2 * neighborhood + 1) * (2 * neighborhood + 1); if (imageDimension == 3) { numberOfPixels *= (2 * neighborhood + 1); } MITK_DEBUG << "Getting neighborhood of " << numberOfPixels << " pixels around " << index; itk::Index<imageDimension> currentIndex; for (int i = (0 - neighborhoodInt); i <= neighborhoodInt; ++i) { currentIndex[0] = index[0] + i; for (int j = (0 - neighborhoodInt); j <= neighborhoodInt; ++j) { currentIndex[1] = index[1] + j; if (imageDimension == 3) { for (int k = (0 - neighborhoodInt); k <= neighborhoodInt; ++k) { currentIndex[2] = index[2] + k; if (itkImage->GetLargestPossibleRegion().IsInside(currentIndex)) { averageValue += itkImage->GetPixel(currentIndex); } else { numberOfPixels -= 1; } } } else { if (itkImage->GetLargestPossibleRegion().IsInside(currentIndex)) { averageValue += itkImage->GetPixel(currentIndex); } else { numberOfPixels -= 1; } } } } *result = (ScalarType)averageValue; *result /= numberOfPixels; } // Check whether index lies inside a segmentation template <typename TPixel, unsigned int imageDimension> void mitk::RegionGrowingTool::IsInsideSegmentation(const itk::Image<TPixel, imageDimension> *itkImage, const itk::Index<imageDimension>& index, bool *result) { if (itkImage->GetPixel(index) > 0) { *result = true; } else { *result = false; } } // Do the region growing (i.e. call an ITK filter that does it) template <typename TPixel, unsigned int imageDimension> void mitk::RegionGrowingTool::StartRegionGrowing(const itk::Image<TPixel, imageDimension> *inputImage, const itk::Index<imageDimension>& seedIndex, const std::array<ScalarType, 2>& thresholds, mitk::Image::Pointer &outputImage) { MITK_DEBUG << "Starting region growing at index " << seedIndex << " with lower threshold " << thresholds[0] << " and upper threshold " << thresholds[1]; typedef itk::Image<TPixel, imageDimension> InputImageType; typedef itk::Image<DefaultSegmentationDataType, imageDimension> OutputImageType; typedef itk::ConnectedThresholdImageFilter<InputImageType, OutputImageType> RegionGrowingFilterType; typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); // perform region growing in desired segmented region regionGrower->SetInput(inputImage); regionGrower->SetSeed(seedIndex); regionGrower->SetLower(thresholds[0]); regionGrower->SetUpper(thresholds[1]); try { regionGrower->Update(); } catch (...) { return; // Should we do something? } typename OutputImageType::Pointer resultImage = regionGrower->GetOutput(); // Smooth result: Every pixel is replaced by the majority of the neighborhood typedef itk::NeighborhoodIterator<OutputImageType> NeighborhoodIteratorType; typedef itk::ImageRegionIterator<OutputImageType> ImageIteratorType; typename NeighborhoodIteratorType::RadiusType radius; radius.Fill(2); // for now, maybe make this something the user can adjust in the preferences? typedef itk::ImageDuplicator< OutputImageType > DuplicatorType; typename DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage(resultImage); duplicator->Update(); typename OutputImageType::Pointer resultDup = duplicator->GetOutput(); NeighborhoodIteratorType neighborhoodIterator(radius, resultDup, resultDup->GetRequestedRegion()); ImageIteratorType imageIterator(resultImage, resultImage->GetRequestedRegion()); for (neighborhoodIterator.GoToBegin(), imageIterator.GoToBegin(); !neighborhoodIterator.IsAtEnd(); ++neighborhoodIterator, ++imageIterator) { DefaultSegmentationDataType voteYes(0); DefaultSegmentationDataType voteNo(0); for (unsigned int i = 0; i < neighborhoodIterator.Size(); ++i) { if (neighborhoodIterator.GetPixel(i) > 0) { voteYes += 1; } else { voteNo += 1; } } if (voteYes > voteNo) { imageIterator.Set(1); } else { imageIterator.Set(0); } } if (resultImage.IsNull()) { MITK_DEBUG << "Region growing result is empty."; } // Can potentially have multiple regions, use connected component image filter to label disjunct regions typedef itk::ConnectedComponentImageFilter<OutputImageType, OutputImageType> ConnectedComponentImageFilterType; typename ConnectedComponentImageFilterType::Pointer connectedComponentFilter = ConnectedComponentImageFilterType::New(); connectedComponentFilter->SetInput(resultImage); connectedComponentFilter->Update(); typename OutputImageType::Pointer resultImageCC = connectedComponentFilter->GetOutput(); m_ConnectedComponentValue = resultImageCC->GetPixel(seedIndex); outputImage = mitk::GrabItkImageMemory(resultImageCC); } template <typename TPixel, unsigned int imageDimension> void mitk::RegionGrowingTool::CalculateInitialThresholds(const itk::Image<TPixel, imageDimension>*) { LevelWindow levelWindow; this->GetToolManager()->GetReferenceData(0)->GetLevelWindow(levelWindow); m_ThresholdExtrema[0] = static_cast<ScalarType>(std::numeric_limits<TPixel>::lowest()); m_ThresholdExtrema[1] = static_cast<ScalarType>(std::numeric_limits<TPixel>::max()); const ScalarType lowerWindowBound = std::max(m_ThresholdExtrema[0], levelWindow.GetLowerWindowBound()); const ScalarType upperWindowBound = std::min(m_ThresholdExtrema[1], levelWindow.GetUpperWindowBound()); if (m_SeedValue < lowerWindowBound) { m_InitialThresholds = { m_ThresholdExtrema[0], lowerWindowBound }; } else if (m_SeedValue > upperWindowBound) { m_InitialThresholds = { upperWindowBound, m_ThresholdExtrema[1] }; } else { const ScalarType range = 0.1 * (upperWindowBound - lowerWindowBound); // 10% of the visible window m_InitialThresholds[0] = std::min(std::max(lowerWindowBound, m_SeedValue - 0.5 * range), upperWindowBound - range); m_InitialThresholds[1] = m_InitialThresholds[0] + range; } } void mitk::RegionGrowingTool::OnMousePressed(StateMachineAction *, InteractionEvent *interactionEvent) { auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (!positionEvent) return; m_LastEventSender = positionEvent->GetSender(); m_LastEventSlice = m_LastEventSender->GetSlice(); m_LastScreenPosition = Point2I(positionEvent->GetPointerPositionOnScreen()); // ReferenceSlice is from the underlying image, WorkingSlice from the active segmentation (can be empty) m_ReferenceSlice = FeedbackContourTool::GetAffectedReferenceSlice(positionEvent); m_WorkingSlice = FeedbackContourTool::GetAffectedWorkingSlice(positionEvent); if (m_WorkingSlice.IsNotNull()) // can't do anything without a working slice (i.e. a possibly empty segmentation) { // 2. Determine if the user clicked inside or outside of the segmentation/working slice (i.e. the whole volume) mitk::BaseGeometry::Pointer workingSliceGeometry; workingSliceGeometry = m_WorkingSlice->GetGeometry(); workingSliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), m_SeedPoint); itk::Index<2> indexInWorkingSlice2D; indexInWorkingSlice2D[0] = m_SeedPoint[0]; indexInWorkingSlice2D[1] = m_SeedPoint[1]; if (workingSliceGeometry->IsIndexInside(m_SeedPoint)) { MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates " << m_SeedPoint << ") is inside working slice"; // 3. determine the pixel value under the last click to determine what to do bool inside(true); AccessFixedDimensionByItk_2(m_WorkingSlice, IsInsideSegmentation, 2, indexInWorkingSlice2D, &inside); m_PaintingPixelValue = inside ? 0 : 1; if (inside) { MITK_DEBUG << "Clicked inside segmentation"; // For now, we're doing nothing when the user clicks inside the segmentation. Behaviour can be implemented via // OnMousePressedInside() // When you do, be sure to remove the m_PaintingPixelValue check in OnMouseMoved() and OnMouseReleased() return; } else { MITK_DEBUG << "Clicked outside of segmentation"; OnMousePressedOutside(nullptr, interactionEvent); } } } } // Use this to implement a behaviour for when the user clicks inside a segmentation (for example remove something) -// Old IpPic code is kept as comment for reference void mitk::RegionGrowingTool::OnMousePressedInside() { - // mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent - // ); - // //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); // checked in - // OnMousePressed - // // 3.1.1. Create a skeletonization of the segmentation and try to find a nice cut - // // apply the skeletonization-and-cut algorithm - // // generate contour to remove - // // set m_ReferenceSlice = nullptr so nothing will happen during mouse move - // // remember to fill the contour with 0 in mouserelease - // mitkIpPicDescriptor* segmentationHistory = ipMITKSegmentationCreateGrowerHistory( workingPicSlice, - // m_LastWorkingSeed, nullptr ); // free again - // if (segmentationHistory) - // { - // tCutResult cutContour = ipMITKSegmentationGetCutPoints( workingPicSlice, segmentationHistory, - // initialWorkingOffset ); // tCutResult is a ipSegmentation type - // mitkIpPicFree( segmentationHistory ); - // if (cutContour.cutIt) - // { - // int timestep = positionEvent->GetSender()->GetTimeStep(); - // // 3.1.2 copy point from float* to mitk::Contour - // ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New(); - // contourInImageIndexCoordinates->Expand(timestep + 1); - // contourInImageIndexCoordinates->SetClosed(true, timestep); - // Point3D newPoint; - // for (int index = 0; index < cutContour.deleteSize; ++index) - // { - // newPoint[0] = cutContour.deleteCurve[ 2 * index + 0 ] - 0.5;//correction is needed because the - // output of the algorithm is center based - // newPoint[1] = cutContour.deleteCurve[ 2 * index + 1 ] - 0.5;//and we want our contour displayed - // corner based. - // newPoint[2] = 0.0; - - // contourInImageIndexCoordinates->AddVertex( newPoint, timestep ); - // } - - // free(cutContour.traceline); - // free(cutContour.deleteCurve); // perhaps visualize this for fun? - // free(cutContour.onGradient); - - // ContourModel::Pointer contourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( - // m_WorkingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true: sub 0.5 for - // ipSegmentation correction - - // FeedbackContourTool::SetFeedbackContour( contourInWorldCoordinates ); - // FeedbackContourTool::SetFeedbackContourVisible(true); - // mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() ); - // m_FillFeedbackContour = true; - // } - // else - // { - // m_FillFeedbackContour = false; - // } - - // } - // else - // { - // m_FillFeedbackContour = false; - // } - - // m_ReferenceSlice = nullptr; - - // return true; } void mitk::RegionGrowingTool::OnMousePressedOutside(StateMachineAction *, InteractionEvent *interactionEvent) { auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (positionEvent) { // Get geometry and indices mitk::BaseGeometry::Pointer workingSliceGeometry; workingSliceGeometry = m_WorkingSlice->GetGeometry(); itk::Index<2> indexInWorkingSlice2D; indexInWorkingSlice2D[0] = m_SeedPoint[0]; indexInWorkingSlice2D[1] = m_SeedPoint[1]; mitk::BaseGeometry::Pointer referenceSliceGeometry; referenceSliceGeometry = m_ReferenceSlice->GetGeometry(); itk::Index<3> indexInReferenceSlice; itk::Index<2> indexInReferenceSlice2D; referenceSliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), indexInReferenceSlice); indexInReferenceSlice2D[0] = indexInReferenceSlice[0]; indexInReferenceSlice2D[1] = indexInReferenceSlice[1]; // Get seed neighborhood ScalarType averageValue(0); AccessFixedDimensionByItk_3(m_ReferenceSlice, GetNeighborhoodAverage, 2, indexInReferenceSlice2D, &averageValue, 1); m_SeedValue = averageValue; MITK_DEBUG << "Seed value is " << m_SeedValue; // Calculate initial thresholds AccessFixedDimensionByItk(m_ReferenceSlice, CalculateInitialThresholds, 2); m_Thresholds[0] = m_InitialThresholds[0]; m_Thresholds[1] = m_InitialThresholds[1]; // Perform region growing mitk::Image::Pointer resultImage = mitk::Image::New(); AccessFixedDimensionByItk_3( m_ReferenceSlice, StartRegionGrowing, 2, indexInWorkingSlice2D, m_Thresholds, resultImage); resultImage->SetGeometry(workingSliceGeometry); // Extract contour if (resultImage.IsNotNull() && m_ConnectedComponentValue >= 1) { float isoOffset = 0.33; mitk::ImageToContourModelFilter::Pointer contourExtractor = mitk::ImageToContourModelFilter::New(); contourExtractor->SetInput(resultImage); contourExtractor->SetContourValue(m_ConnectedComponentValue - isoOffset); contourExtractor->Update(); ContourModel::Pointer resultContour = ContourModel::New(); resultContour = contourExtractor->GetOutput(); // Show contour if (resultContour.IsNotNull()) { ContourModel::Pointer resultContourWorld = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSliceGeometry, FeedbackContourTool::ProjectContourTo2DSlice(m_WorkingSlice, resultContour)); FeedbackContourTool::UpdateCurrentFeedbackContour(resultContourWorld); FeedbackContourTool::SetFeedbackContourVisible(true); mitk::RenderingManager::GetInstance()->RequestUpdate(m_LastEventSender->GetRenderWindow()); } } } } void mitk::RegionGrowingTool::OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent) { // Until OnMousePressedInside() implements a behaviour, we're just returning here whenever m_PaintingPixelValue is 0, // i.e. when the user clicked inside the segmentation if (m_PaintingPixelValue == 0) { return; } auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (m_ReferenceSlice.IsNotNull() && positionEvent) { // Get geometry and indices mitk::BaseGeometry::Pointer workingSliceGeometry; workingSliceGeometry = m_WorkingSlice->GetGeometry(); itk::Index<2> indexInWorkingSlice2D; indexInWorkingSlice2D[0] = m_SeedPoint[0]; indexInWorkingSlice2D[1] = m_SeedPoint[1]; m_ScreenYDifference += positionEvent->GetPointerPositionOnScreen()[1] - m_LastScreenPosition[1]; m_ScreenXDifference += positionEvent->GetPointerPositionOnScreen()[0] - m_LastScreenPosition[0]; m_LastScreenPosition = Point2I(positionEvent->GetPointerPositionOnScreen()); // Moving the mouse up and down adjusts the width of the threshold window, // moving it left and right shifts the threshold window m_Thresholds[0] = std::min(m_SeedValue, m_InitialThresholds[0] - (m_ScreenYDifference - m_ScreenXDifference) * m_MouseDistanceScaleFactor); m_Thresholds[1] = std::max(m_SeedValue, m_InitialThresholds[1] + (m_ScreenYDifference + m_ScreenXDifference) * m_MouseDistanceScaleFactor); // Do not exceed the pixel type extrema of the reference slice, though m_Thresholds[0] = std::max(m_ThresholdExtrema[0], m_Thresholds[0]); m_Thresholds[1] = std::min(m_ThresholdExtrema[1], m_Thresholds[1]); // Perform region growing again and show the result mitk::Image::Pointer resultImage = mitk::Image::New(); AccessFixedDimensionByItk_3( m_ReferenceSlice, StartRegionGrowing, 2, indexInWorkingSlice2D, m_Thresholds, resultImage); resultImage->SetGeometry(workingSliceGeometry); // Update the contour if (resultImage.IsNotNull() && m_ConnectedComponentValue >= 1) { float isoOffset = 0.33; mitk::ImageToContourModelFilter::Pointer contourExtractor = mitk::ImageToContourModelFilter::New(); contourExtractor->SetInput(resultImage); contourExtractor->SetContourValue(m_ConnectedComponentValue - isoOffset); contourExtractor->Update(); ContourModel::Pointer resultContour = ContourModel::New(); resultContour = contourExtractor->GetOutput(); // Show contour if (resultContour.IsNotNull()) { ContourModel::Pointer resultContourWorld = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSliceGeometry, FeedbackContourTool::ProjectContourTo2DSlice(m_WorkingSlice, resultContour)); FeedbackContourTool::UpdateCurrentFeedbackContour(resultContourWorld); FeedbackContourTool::SetFeedbackContourVisible(true); mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(positionEvent->GetSender()->GetRenderWindow()); } } } } void mitk::RegionGrowingTool::OnMouseReleased(StateMachineAction *, InteractionEvent *interactionEvent) { // Until OnMousePressedInside() implements a behaviour, we're just returning here whenever m_PaintingPixelValue is 0, // i.e. when the user clicked inside the segmentation if (m_PaintingPixelValue == 0) { return; } auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (m_WorkingSlice.IsNotNull() && m_FillFeedbackContour && positionEvent) { this->WriteBackFeedbackContourAsSegmentationResult(positionEvent, m_PaintingPixelValue); m_ScreenYDifference = 0; m_ScreenXDifference = 0; } } diff --git a/Modules/Segmentation/Resources/Interactions/LiveWireTool.xml b/Modules/Segmentation/Resources/Interactions/LiveWireTool.xml index e64b4c810b..27d02bc15d 100644 --- a/Modules/Segmentation/Resources/Interactions/LiveWireTool.xml +++ b/Modules/Segmentation/Resources/Interactions/LiveWireTool.xml @@ -1,34 +1,30 @@ <statemachine name="LiveWireTool"> <state name="Start" ID="1" startstate="true"> <transition event_class="MouseDoubleClickEvent" event_variant="PrimaryButtonDoubleClick" target="Active" > <action name="InitObject" ID="5" /> </transition> </state> <state name="Active" ID="2" > <transition event_class="MousePressEvent" event_variant="PrimaryButtonPressed" target="Active" > <action name="AddPoint" ID="10" /> </transition> <transition event_class="MouseMoveEvent" event_variant="MouseMove" target="Active" > <action name="MovePoint" ID="92" /> </transition> <transition event_class="InteractionKeyEvent" event_variant="KeyEscape" target="Active" > <action name="DeletePoint" ID="120"/> </transition> <transition event_class="InteractionKeyEvent" event_variant="KeyDelete" target="Active" > <action name="DeletePoint" ID="120"/> </transition> <transition event_class="MouseDoubleClickEvent" event_variant="PrimaryButtonDoubleClick" target="Start" > - <condition name="CheckContourClosed" /> <action name="FinishContour" ID="44" /> </transition> - <transition event_class="MouseDoubleClickEvent" event_variant="PrimaryButtonDoubleClick" target="Active" > - <condition name="CheckContourClosed" inverted="true"/> - </transition> <transition event_class="MouseMoveEvent" event_variant="CtrlMouseMove" target="Active" > <action name="CtrlMovePoint" ID="12"/> </transition> <transition event_class="MousePressEvent" event_variant="CtrlPrimaryButtonPressed" target="Active" > <action name="CtrlAddPoint" ID="10" /> </transition> </state> </statemachine> diff --git a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp index b7afba8afc..fe9ff8bd3f 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp @@ -1,1014 +1,1014 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkAdaptiveRegionGrowingToolGUI.h" #include <qmessagebox.h> #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" #include "mitkImageTimeSelector.h" #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkTransferFunctionProperty.h" #include "mitkImageStatisticsHolder.h" #include "itkMaskImageFilter.h" #include "itkNumericTraits.h" #include <itkBinaryThresholdImageFilter.h> #include <itkConnectedAdaptiveThresholdImageFilter.h> #include <itkImageIterator.h> #include <itkMinimumMaximumImageCalculator.h> #include "QmitkConfirmSegmentationDialog.h" #include "itkOrImageFilter.h" #include "mitkImageCast.h" #include "mitkImagePixelReadAccessor.h" #include "mitkPixelTypeMultiplex.h" #include "mitkImageCast.h" MITK_TOOL_GUI_MACRO(, QmitkAdaptiveRegionGrowingToolGUI, "") QmitkAdaptiveRegionGrowingToolGUI::QmitkAdaptiveRegionGrowingToolGUI(QWidget *parent) : QmitkToolGUI(), m_DataStorage(nullptr), m_UseVolumeRendering(false), m_UpdateSuggestedThreshold(true), m_SuggestedThValue(0.0) { this->setParent(parent); m_Controls.setupUi(this); m_Controls.m_ThresholdSlider->setDecimals(1); m_Controls.m_ThresholdSlider->setSpinBoxAlignment(Qt::AlignVCenter); m_Controls.m_PreviewSlider->setEnabled(false); m_Controls.m_PreviewSlider->setSingleStep(0.5); // Not yet available // m_Controls.m_PreviewSlider->InvertedAppearance(true); //3D preview doesn't work: T24430. Postponed until reimplementation of segmentation m_Controls.m_cbVolumeRendering->setVisible(false); this->CreateConnections(); this->SetDataNodeNames("labeledRGSegmentation", "RGResult", "RGFeedbackSurface", "maskedSegmentation"); connect(this, SIGNAL(NewToolAssociated(mitk::Tool *)), this, SLOT(OnNewToolAssociated(mitk::Tool *))); } QmitkAdaptiveRegionGrowingToolGUI::~QmitkAdaptiveRegionGrowingToolGUI() { // Removing the observer of the PointSet node if (m_RegionGrow3DTool->GetPointSetNode().IsNotNull()) { m_RegionGrow3DTool->GetPointSetNode()->GetData()->RemoveObserver(m_PointSetAddObserverTag); m_RegionGrow3DTool->GetPointSetNode()->GetData()->RemoveObserver(m_PointSetMoveObserverTag); } this->RemoveHelperNodes(); } void QmitkAdaptiveRegionGrowingToolGUI::OnNewToolAssociated(mitk::Tool *tool) { m_RegionGrow3DTool = dynamic_cast<mitk::AdaptiveRegionGrowingTool *>(tool); if (m_RegionGrow3DTool.IsNotNull()) { SetInputImageNode(this->m_RegionGrow3DTool->GetReferenceData()); this->m_DataStorage = this->m_RegionGrow3DTool->GetDataStorage(); this->EnableControls(true); // Watch for point added or modified itk::SimpleMemberCommand<QmitkAdaptiveRegionGrowingToolGUI>::Pointer pointAddedCommand = itk::SimpleMemberCommand<QmitkAdaptiveRegionGrowingToolGUI>::New(); pointAddedCommand->SetCallbackFunction(this, &QmitkAdaptiveRegionGrowingToolGUI::OnPointAdded); m_PointSetAddObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver(mitk::PointSetAddEvent(), pointAddedCommand); m_PointSetMoveObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver(mitk::PointSetMoveEvent(), pointAddedCommand); } else { this->EnableControls(false); } } void QmitkAdaptiveRegionGrowingToolGUI::RemoveHelperNodes() { mitk::DataNode::Pointer imageNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (imageNode.IsNotNull()) { m_DataStorage->Remove(imageNode); } mitk::DataNode::Pointer maskedSegmentationNode = m_DataStorage->GetNamedNode(m_NAMEFORMASKEDSEGMENTATION); if (maskedSegmentationNode.IsNotNull()) { m_DataStorage->Remove(maskedSegmentationNode); } } void QmitkAdaptiveRegionGrowingToolGUI::CreateConnections() { // Connecting GUI components connect((QObject *)(m_Controls.m_pbRunSegmentation), SIGNAL(clicked()), this, SLOT(RunSegmentation())); connect(m_Controls.m_PreviewSlider, SIGNAL(valueChanged(double)), this, SLOT(ChangeLevelWindow(double))); connect((QObject *)(m_Controls.m_pbConfirmSegementation), SIGNAL(clicked()), this, SLOT(ConfirmSegmentation())); connect( m_Controls.m_ThresholdSlider, SIGNAL(maximumValueChanged(double)), this, SLOT(SetUpperThresholdValue(double))); connect( m_Controls.m_ThresholdSlider, SIGNAL(minimumValueChanged(double)), this, SLOT(SetLowerThresholdValue(double))); } void QmitkAdaptiveRegionGrowingToolGUI::SetDataNodeNames(std::string labledSegmentation, std::string binaryImage, std::string surface, std::string maskedSegmentation) { m_NAMEFORLABLEDSEGMENTATIONIMAGE = labledSegmentation; m_NAMEFORBINARYIMAGE = binaryImage; m_NAMEFORSURFACE = surface; m_NAMEFORMASKEDSEGMENTATION = maskedSegmentation; } void QmitkAdaptiveRegionGrowingToolGUI::SetDataStorage(mitk::DataStorage *dataStorage) { m_DataStorage = dataStorage; } void QmitkAdaptiveRegionGrowingToolGUI::SetInputImageNode(mitk::DataNode *node) { m_InputImageNode = node; mitk::Image *inputImage = dynamic_cast<mitk::Image *>(m_InputImageNode->GetData()); if (inputImage) { mitk::ScalarType max = inputImage->GetStatistics()->GetScalarValueMax(); mitk::ScalarType min = inputImage->GetStatistics()->GetScalarValueMin(); m_Controls.m_ThresholdSlider->setMaximum(max); m_Controls.m_ThresholdSlider->setMinimum(min); // Just for initialization m_Controls.m_ThresholdSlider->setMaximumValue(max); m_Controls.m_ThresholdSlider->setMinimumValue(min); } } template <typename TPixel> static void AccessPixel(mitk::PixelType /*ptype*/, mitk::Image* im, mitk::Point3D p, int& val) { mitk::ImagePixelReadAccessor<TPixel, 3> access(im); val = access.GetPixelByWorldCoordinates(p); } /**Overloaded const verison*/ template <typename TPixel> static void AccessPixel(mitk::PixelType /*ptype*/, const mitk::Image* im, mitk::Point3D p, int& val) { mitk::ImagePixelReadAccessor<TPixel, 3> access(im); val = access.GetPixelByWorldCoordinates(p); } void QmitkAdaptiveRegionGrowingToolGUI::OnPointAdded() { if (m_RegionGrow3DTool.IsNull()) return; mitk::DataNode *node = m_RegionGrow3DTool->GetPointSetNode(); if (node != nullptr) { mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet *>(node->GetData()); if (pointSet.IsNull()) { QMessageBox::critical(nullptr, "QmitkAdaptiveRegionGrowingToolGUI", "PointSetNode does not contain a pointset"); return; } m_Controls.m_lblSetSeedpoint->setText(""); const mitk::Image *image = dynamic_cast<mitk::Image *>(m_InputImageNode->GetData()); const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); auto image3D = GetImageByTimePoint(image, timePoint); if (nullptr == image3D) { MITK_WARN << "Cannot run segementation. Currently selected timepoint is not in the time bounds of the selected " "reference image. Time point: " << timePoint; return; } if (!pointSet->GetTimeGeometry()->IsValidTimePoint(timePoint)) return; mitk::Point3D seedPoint = pointSet ->GetPointSet(static_cast<int>(pointSet->GetTimeGeometry()->TimePointToTimeStep(timePoint))) ->GetPoints() ->ElementAt(0); if (image3D->GetGeometry()->IsInside(seedPoint)) mitkPixelTypeMultiplex3( AccessPixel, image3D->GetChannelDescriptor().GetPixelType(), image3D, seedPoint, m_SeedpointValue) else return; /* In this case the seedpoint is placed e.g. in the lung or bronchialtree * The lowerFactor sets the windowsize depending on the regiongrowing direction */ m_CurrentRGDirectionIsUpwards = true; if (m_SeedpointValue < -500) { m_CurrentRGDirectionIsUpwards = false; } // Initializing the region by the area around the seedpoint m_SeedPointValueMean = 0; itk::Index<3> currentIndex, runningIndex; mitk::ScalarType pixelValues[125]; unsigned int pos(0); image3D->GetGeometry(0)->WorldToIndex(seedPoint, currentIndex); runningIndex = currentIndex; for (int i = runningIndex[0] - 2; i <= runningIndex[0] + 2; i++) { for (int j = runningIndex[1] - 2; j <= runningIndex[1] + 2; j++) { for (int k = runningIndex[2] - 2; k <= runningIndex[2] + 2; k++) { currentIndex[0] = i; currentIndex[1] = j; currentIndex[2] = k; if (image3D->GetGeometry()->IsIndexInside(currentIndex)) { int component = 0; m_InputImageNode->GetIntProperty("Image.Displayed Component", component); mitkPixelTypeMultiplex4(mitk::FastSinglePixelAccess, image3D->GetChannelDescriptor().GetPixelType(), image3D, nullptr, currentIndex, pixelValues[pos]); pos++; } else { pixelValues[pos] = std::numeric_limits<long>::min(); pos++; } } } } // Now calculation mean of the pixelValues // Now calculation mean of the pixelValues unsigned int numberOfValues(0); for (auto &pixelValue : pixelValues) { if (pixelValue > std::numeric_limits<long>::min()) { m_SeedPointValueMean += pixelValue; numberOfValues++; } } m_SeedPointValueMean = m_SeedPointValueMean / numberOfValues; mitk::ScalarType var = 0; if (numberOfValues > 1) { for (auto &pixelValue : pixelValues) { if (pixelValue > std::numeric_limits<mitk::ScalarType>::min()) { var += (pixelValue - m_SeedPointValueMean) * (pixelValue - m_SeedPointValueMean); } } var /= numberOfValues - 1; } mitk::ScalarType stdDev = sqrt(var); /* * Here the upper- and lower threshold is calculated: * The windowSize is 20% of the maximum range of the intensity values existing in the current image * If the RG direction is upwards the lower TH is meanSeedValue-0.15*windowSize and upper TH is * meanSeedValue+0.85*windowsSize * if the RG direction is downwards the lower TH is meanSeedValue-0.85*windowSize and upper TH is * meanSeedValue+0.15*windowsSize */ const auto timeStepOfImage = image->GetTimeGeometry()->TimePointToTimeStep(timePoint); mitk::ScalarType min = image->GetStatistics()->GetScalarValueMin(timeStepOfImage); mitk::ScalarType max = image->GetStatistics()->GetScalarValueMax(timeStepOfImage); mitk::ScalarType windowSize = max - min; windowSize = 0.15 * windowSize; if (m_CurrentRGDirectionIsUpwards) { m_LOWERTHRESHOLD = m_SeedPointValueMean - stdDev; m_UPPERTHRESHOLD = m_SeedpointValue + windowSize; if (m_UPPERTHRESHOLD > max) m_UPPERTHRESHOLD = max; m_Controls.m_ThresholdSlider->setMaximumValue(m_UPPERTHRESHOLD); m_Controls.m_ThresholdSlider->setMinimumValue(m_LOWERTHRESHOLD); } else { m_UPPERTHRESHOLD = m_SeedPointValueMean; if (m_SeedpointValue > m_SeedPointValueMean) m_UPPERTHRESHOLD = m_SeedpointValue; m_LOWERTHRESHOLD = m_SeedpointValue - windowSize; if (m_LOWERTHRESHOLD < min) m_LOWERTHRESHOLD = min; m_Controls.m_ThresholdSlider->setMinimumValue(m_LOWERTHRESHOLD); m_Controls.m_ThresholdSlider->setMaximumValue(m_UPPERTHRESHOLD); } } } mitk::Image::ConstPointer QmitkAdaptiveRegionGrowingToolGUI::GetImageByTimePoint(const mitk::Image *image, mitk::TimePointType timePoint) const { if (nullptr == image) return image; if (!image->GetTimeGeometry()->IsValidTimePoint(timePoint)) return nullptr; if (image->GetDimension() != 4) return image; auto imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(image); imageTimeSelector->SetTimeNr(static_cast<int>(image->GetTimeGeometry()->TimePointToTimeStep(timePoint))); imageTimeSelector->UpdateLargestPossibleRegion(); return imageTimeSelector->GetOutput(); } void QmitkAdaptiveRegionGrowingToolGUI::RunSegmentation() { if (m_InputImageNode.IsNull()) { QMessageBox::information(nullptr, "Adaptive Region Growing functionality", "Please specify the image in Datamanager!"); return; } mitk::DataNode::Pointer node = m_RegionGrow3DTool->GetPointSetNode(); if (node.IsNull()) { QMessageBox::information(nullptr, "Adaptive Region Growing functionality", "Please insert a seed point inside the " "image.\n\nFirst press the \"Define Seed " "Point\" button,\nthen click left mouse " "button inside the image."); return; } // safety if no pointSet or pointSet empty mitk::PointSet::Pointer seedPointSet = dynamic_cast<mitk::PointSet *>(node->GetData()); if (seedPointSet.IsNull()) { m_Controls.m_pbRunSegmentation->setEnabled(true); QMessageBox::information( nullptr, "Adaptive Region Growing functionality", "The seed point is empty! Please choose a new seed point."); return; } mitk::Image::Pointer orgImage = dynamic_cast<mitk::Image *>(m_InputImageNode->GetData()); if (orgImage.IsNotNull()) { const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); if (!seedPointSet->GetTimeGeometry()->IsValidTimePoint(timePoint)) mitkThrow() << "Point set is not defined for specified time point. Time point: " << timePoint; int timeStep = static_cast<int>(seedPointSet->GetTimeGeometry()->TimePointToTimeStep(timePoint)); if (!(seedPointSet->GetSize(timeStep))) { m_Controls.m_pbRunSegmentation->setEnabled(true); QMessageBox::information( nullptr, "Adaptive Region Growing functionality", "The seed point is empty! Please choose a new seed point."); return; } QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); mitk::PointSet::PointType seedPoint = seedPointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value(); auto image3D = GetImageByTimePoint(orgImage, timePoint); if (image3D.IsNotNull()) { // QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); //set the cursor to waiting AccessByItk_2(image3D, StartRegionGrowing, image3D->GetGeometry(), seedPoint); // QApplication::restoreOverrideCursor();//reset cursor } else { QApplication::restoreOverrideCursor(); // reset cursor QMessageBox::information( nullptr, "Adaptive Region Growing functionality", "Only images of dimension 3 or 4 can be processed!"); return; } } EnableControls(true); // Segmentation ran successfully, so enable all controls. node->SetVisibility(true); QApplication::restoreOverrideCursor(); // reset cursor } template <typename TPixel, unsigned int VImageDimension> void QmitkAdaptiveRegionGrowingToolGUI::StartRegionGrowing(const itk::Image<TPixel, VImageDimension> *itkImage, const mitk::BaseGeometry *imageGeometry, const mitk::PointSet::PointType seedPoint) { typedef itk::Image<TPixel, VImageDimension> InputImageType; typedef typename InputImageType::IndexType IndexType; typedef itk::ConnectedAdaptiveThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType; typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); typedef itk::BinaryThresholdImageFilter<InputImageType, InputImageType> ThresholdFilterType; typedef itk::MaskImageFilter<InputImageType, InputImageType, InputImageType> MaskImageFilterType; if (!imageGeometry->IsInside(seedPoint)) { QApplication::restoreOverrideCursor(); // reset cursor to be able to click ok with the regular mouse cursor QMessageBox::information(nullptr, "Segmentation functionality", "The seed point is outside of the image! Please choose a position inside the image!"); return; } IndexType seedIndex; imageGeometry->WorldToIndex(seedPoint, seedIndex); // convert world coordinates to image indices if (m_SeedpointValue > m_UPPERTHRESHOLD || m_SeedpointValue < m_LOWERTHRESHOLD) { QApplication::restoreOverrideCursor(); // reset cursor to be able to click ok with the regular mouse cursor QMessageBox::information( nullptr, "Segmentation functionality", "The seed point is outside the defined thresholds! Please set a new seed point or adjust the thresholds."); MITK_INFO << "Mean: " << m_SeedPointValueMean; return; } // Setting the direction of the regiongrowing. For dark structures e.g. the lung the regiongrowing // is performed starting at the upper value going to the lower one regionGrower->SetGrowingDirectionIsUpwards(m_CurrentRGDirectionIsUpwards); regionGrower->SetInput(itkImage); regionGrower->AddSeed(seedIndex); // In some cases we have to subtract 1 for the lower threshold and add 1 to the upper. // Otherwise no region growing is done. Maybe a bug in the ConnectiveAdaptiveThresholdFilter mitk::ScalarType maxPixelValue = m_Controls.m_ThresholdSlider->maximum(); mitk::ScalarType minPixelValue = m_Controls.m_ThresholdSlider->minimum(); if ((m_LOWERTHRESHOLD - minPixelValue) >= 1) { regionGrower->SetLower(m_LOWERTHRESHOLD - 1); } else { regionGrower->SetLower(m_LOWERTHRESHOLD); } if ((maxPixelValue - m_UPPERTHRESHOLD) >= 1) { regionGrower->SetUpper(m_UPPERTHRESHOLD + 1); } else { regionGrower->SetUpper(m_UPPERTHRESHOLD); } try { regionGrower->Update(); } catch (itk::ExceptionObject &exc) { QMessageBox errorInfo; errorInfo.setWindowTitle("Adaptive RG Segmentation Functionality"); errorInfo.setIcon(QMessageBox::Critical); errorInfo.setText("An error occurred during region growing!"); errorInfo.setDetailedText(exc.what()); errorInfo.exec(); return; // can't work } catch (...) { QMessageBox::critical(nullptr, "Adaptive RG Segmentation Functionality", "An error occurred during region growing!"); return; } mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput())->Clone(); // initialize slider m_Controls.m_PreviewSlider->setMinimum(m_LOWERTHRESHOLD); mitk::ScalarType max = m_SeedpointValue + resultImage->GetStatistics()->GetScalarValueMax(); if (max < m_UPPERTHRESHOLD) m_Controls.m_PreviewSlider->setMaximum(max); else m_Controls.m_PreviewSlider->setMaximum(m_UPPERTHRESHOLD); this->m_DetectedLeakagePoint = regionGrower->GetLeakagePoint(); if (m_CurrentRGDirectionIsUpwards) { m_Controls.m_PreviewSlider->setValue(m_SeedPointValueMean - 1); } else { m_Controls.m_PreviewSlider->setValue(m_SeedPointValueMean + 1); } this->m_SliderInitialized = true; // create new node and then delete the old one if there is one mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetData(resultImage); // set some properties newNode->SetProperty("name", mitk::StringProperty::New(m_NAMEFORLABLEDSEGMENTATIONIMAGE)); newNode->SetProperty("helper object", mitk::BoolProperty::New(true)); newNode->SetProperty("color", mitk::ColorProperty::New(0.0, 1.0, 0.0)); newNode->SetProperty("layer", mitk::IntProperty::New(1)); newNode->SetProperty("opacity", mitk::FloatProperty::New(0.7)); // delete the old image, if there was one: mitk::DataNode::Pointer binaryNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); m_DataStorage->Remove(binaryNode); // now add result to data tree m_DataStorage->Add(newNode, m_InputImageNode); typename InputImageType::Pointer inputImageItk; mitk::CastToItkImage<InputImageType>(resultImage, inputImageItk); // volume rendering preview masking typename ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New(); thresholdFilter->SetInput(inputImageItk); thresholdFilter->SetInsideValue(1); thresholdFilter->SetOutsideValue(0); double sliderVal = this->m_Controls.m_PreviewSlider->value(); if (m_CurrentRGDirectionIsUpwards) { thresholdFilter->SetLowerThreshold(sliderVal); thresholdFilter->SetUpperThreshold(itk::NumericTraits<TPixel>::max()); } else { - thresholdFilter->SetLowerThreshold(itk::NumericTraits<TPixel>::min()); + thresholdFilter->SetLowerThreshold(itk::NumericTraits<TPixel>::NonpositiveMin()); thresholdFilter->SetUpperThreshold(sliderVal); } thresholdFilter->SetInPlace(false); typename MaskImageFilterType::Pointer maskFilter = MaskImageFilterType::New(); maskFilter->SetInput(inputImageItk); maskFilter->SetInPlace(false); maskFilter->SetMaskImage(thresholdFilter->GetOutput()); maskFilter->SetOutsideValue(0); maskFilter->UpdateLargestPossibleRegion(); mitk::Image::Pointer mitkMask; mitk::CastToMitkImage<InputImageType>(maskFilter->GetOutput(), mitkMask); mitk::DataNode::Pointer maskedNode = mitk::DataNode::New(); maskedNode->SetData(mitkMask); // set some properties maskedNode->SetProperty("name", mitk::StringProperty::New(m_NAMEFORMASKEDSEGMENTATION)); maskedNode->SetProperty("helper object", mitk::BoolProperty::New(true)); maskedNode->SetProperty("color", mitk::ColorProperty::New(0.0, 1.0, 0.0)); maskedNode->SetProperty("layer", mitk::IntProperty::New(1)); maskedNode->SetProperty("opacity", mitk::FloatProperty::New(0.0)); // delete the old image, if there was one: mitk::DataNode::Pointer deprecatedMask = m_DataStorage->GetNamedNode(m_NAMEFORMASKEDSEGMENTATION); m_DataStorage->Remove(deprecatedMask); // now add result to data tree m_DataStorage->Add(maskedNode, m_InputImageNode); this->InitializeLevelWindow(); if (m_UseVolumeRendering) this->EnableVolumeRendering(true); m_UpdateSuggestedThreshold = true; // reset first stored threshold value // Setting progress to finished mitk::ProgressBar::GetInstance()->Progress(357); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkAdaptiveRegionGrowingToolGUI::InitializeLevelWindow() { // get the preview from the datatree mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); mitk::LevelWindow tempLevelWindow; newNode->GetLevelWindow(tempLevelWindow, nullptr, "levelwindow"); mitk::ScalarType *level = new mitk::ScalarType(0.0); mitk::ScalarType *window = new mitk::ScalarType(1.0); int upper; if (m_CurrentRGDirectionIsUpwards) { upper = m_UPPERTHRESHOLD - m_SeedpointValue; } else { upper = m_SeedpointValue - m_LOWERTHRESHOLD; } tempLevelWindow.SetRangeMinMax(mitk::ScalarType(0), mitk::ScalarType(upper)); // get the suggested threshold from the detected leakage-point and adjust the slider if (m_CurrentRGDirectionIsUpwards) { this->m_Controls.m_PreviewSlider->setValue(m_SeedpointValue); *level = m_UPPERTHRESHOLD - (m_SeedpointValue) + 0.5; } else { this->m_Controls.m_PreviewSlider->setValue(m_SeedpointValue); *level = (m_SeedpointValue)-m_LOWERTHRESHOLD + 0.5; } tempLevelWindow.SetLevelWindow(*level, *window); newNode->SetLevelWindow(tempLevelWindow, nullptr, "levelwindow"); // update the widgets mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_SliderInitialized = true; // inquiry need to fix bug#1828 static int lastSliderPosition = 0; if ((this->m_SeedpointValue + this->m_DetectedLeakagePoint - 1) == lastSliderPosition) { this->ChangeLevelWindow(lastSliderPosition); } lastSliderPosition = this->m_SeedpointValue + this->m_DetectedLeakagePoint - 1; if (m_UseVolumeRendering) this->UpdateVolumeRenderingThreshold((int)(*level + 0.5)); // lower threshold for labeled image } void QmitkAdaptiveRegionGrowingToolGUI::ChangeLevelWindow(double newValue) { if (m_SliderInitialized) { // do nothing, if no preview exists mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (newNode.IsNull()) return; mitk::LevelWindow tempLevelWindow; newNode->GetLevelWindow(tempLevelWindow, nullptr, "levelwindow"); // get the levelWindow associated with the preview mitk::ScalarType level; // = this->m_UPPERTHRESHOLD - newValue + 0.5; mitk::ScalarType *window = new mitk::ScalarType(1); // adjust the levelwindow according to the position of the slider (newvalue) if (m_CurrentRGDirectionIsUpwards) { level = m_UPPERTHRESHOLD - newValue + 0.5; tempLevelWindow.SetLevelWindow(level, *window); } else { level = newValue - m_LOWERTHRESHOLD + 0.5; tempLevelWindow.SetLevelWindow(level, *window); } newNode->SetLevelWindow(tempLevelWindow, nullptr, "levelwindow"); if (m_UseVolumeRendering) this->UpdateVolumeRenderingThreshold((int)(level - 0.5)); // lower threshold for labeled image newNode->SetVisibility(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkAdaptiveRegionGrowingToolGUI::DecreaseSlider() { // moves the slider one step to the left, when the "-"-button is pressed if (this->m_Controls.m_PreviewSlider->value() != this->m_Controls.m_PreviewSlider->minimum()) { int newValue = this->m_Controls.m_PreviewSlider->value() - 1; this->ChangeLevelWindow(newValue); this->m_Controls.m_PreviewSlider->setValue(newValue); } } void QmitkAdaptiveRegionGrowingToolGUI::IncreaseSlider() { // moves the slider one step to the right, when the "+"-button is pressed if (this->m_Controls.m_PreviewSlider->value() != this->m_Controls.m_PreviewSlider->maximum()) { int newValue = this->m_Controls.m_PreviewSlider->value() + 1; this->ChangeLevelWindow(newValue); this->m_Controls.m_PreviewSlider->setValue(newValue); } } void QmitkAdaptiveRegionGrowingToolGUI::ConfirmSegmentation() { // get image node if (m_InputImageNode.IsNull()) { QMessageBox::critical(nullptr, "Adaptive region growing functionality", "Please specify the image in Datamanager!"); return; } // get image data mitk::Image::Pointer orgImage = dynamic_cast<mitk::Image *>(m_InputImageNode->GetData()); if (orgImage.IsNull()) { QMessageBox::critical(nullptr, "Adaptive region growing functionality", "No Image found!"); return; } // get labeled segmentation mitk::Image::Pointer labeledSeg = (mitk::Image *)m_DataStorage->GetNamedObject<mitk::Image>(m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (labeledSeg.IsNull()) { QMessageBox::critical(nullptr, "Adaptive region growing functionality", "No Segmentation Preview found!"); return; } mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (newNode.IsNull()) return; QmitkConfirmSegmentationDialog dialog; QString segName = QString::fromStdString(m_RegionGrow3DTool->GetCurrentSegmentationName()); dialog.SetSegmentationName(segName); int result = dialog.exec(); switch (result) { case QmitkConfirmSegmentationDialog::CREATE_NEW_SEGMENTATION: m_RegionGrow3DTool->SetOverwriteExistingSegmentation(false); break; case QmitkConfirmSegmentationDialog::OVERWRITE_SEGMENTATION: m_RegionGrow3DTool->SetOverwriteExistingSegmentation(true); break; case QmitkConfirmSegmentationDialog::CANCEL_SEGMENTATION: return; } mitk::Image::Pointer img = dynamic_cast<mitk::Image *>(newNode->GetData()); AccessByItk(img, ITKThresholding); // disable volume rendering preview after the segmentation node was created this->EnableVolumeRendering(false); newNode->SetVisibility(false); m_Controls.m_cbVolumeRendering->setChecked(false); // TODO disable slider etc... if (m_RegionGrow3DTool.IsNotNull()) { m_RegionGrow3DTool->ConfirmSegmentation(); } } template <typename TPixel, unsigned int VImageDimension> void QmitkAdaptiveRegionGrowingToolGUI::ITKThresholding(itk::Image<TPixel, VImageDimension> *itkImage) { mitk::Image::Pointer originalSegmentation = dynamic_cast<mitk::Image *>(this->m_RegionGrow3DTool->GetTargetSegmentationNode()->GetData()); const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); if (!originalSegmentation->GetTimeGeometry()->IsValidTimePoint(timePoint)) mitkThrow() << "Segmentation is not defined for specified time point. Time point: " << timePoint; int timeStep = static_cast<int>(originalSegmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint)); if (originalSegmentation) { typedef itk::Image<TPixel, VImageDimension> InputImageType; typedef itk::Image<mitk::Tool::DefaultSegmentationDataType, VImageDimension> SegmentationType; // select single 3D volume if we have more than one time step typename SegmentationType::Pointer originalSegmentationInITK = SegmentationType::New(); if (originalSegmentation->GetTimeGeometry()->CountTimeSteps() > 1) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(originalSegmentation); timeSelector->SetTimeNr(timeStep); timeSelector->UpdateLargestPossibleRegion(); CastToItkImage(timeSelector->GetOutput(), originalSegmentationInITK); } else // use original { CastToItkImage(originalSegmentation, originalSegmentationInITK); } // Fill current preiview image in segmentation image originalSegmentationInITK->FillBuffer(0); itk::ImageRegionIterator<SegmentationType> itOutput(originalSegmentationInITK, originalSegmentationInITK->GetLargestPossibleRegion()); itk::ImageRegionIterator<InputImageType> itInput(itkImage, itkImage->GetLargestPossibleRegion()); itOutput.GoToBegin(); itInput.GoToBegin(); // calculate threhold from slider value int currentTreshold = 0; if (m_CurrentRGDirectionIsUpwards) { currentTreshold = m_UPPERTHRESHOLD - m_Controls.m_PreviewSlider->value() + 1; } else { currentTreshold = m_Controls.m_PreviewSlider->value() - m_LOWERTHRESHOLD; } // iterate over image and set pixel in segmentation according to thresholded labeled image while (!itOutput.IsAtEnd() && !itInput.IsAtEnd()) { // Use threshold slider to determine if pixel is set to 1 if (itInput.Value() != 0 && itInput.Value() >= static_cast<typename itk::ImageRegionIterator<InputImageType>::PixelType>(currentTreshold)) { itOutput.Set(1); } ++itOutput; ++itInput; } // combine current working segmentation image with our region growing result originalSegmentation->SetVolume((void *)(originalSegmentationInITK->GetPixelContainer()->GetBufferPointer()), timeStep); originalSegmentation->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkAdaptiveRegionGrowingToolGUI::EnableControls(bool enable) { if (m_RegionGrow3DTool.IsNull()) return; // Check if seed point is already set, if not leave RunSegmentation disabled // if even m_DataStorage is nullptr leave node nullptr mitk::DataNode::Pointer node = m_RegionGrow3DTool->GetPointSetNode(); if (node.IsNull()) { this->m_Controls.m_pbRunSegmentation->setEnabled(false); } else { this->m_Controls.m_pbRunSegmentation->setEnabled(enable); } // Check if a segmentation exists, if not leave segmentation dependent disabled. // if even m_DataStorage is nullptr leave node nullptr node = m_DataStorage ? m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE) : nullptr; if (node.IsNull()) { this->m_Controls.m_PreviewSlider->setEnabled(false); this->m_Controls.m_pbConfirmSegementation->setEnabled(false); } else { this->m_Controls.m_PreviewSlider->setEnabled(enable); this->m_Controls.m_pbConfirmSegementation->setEnabled(enable); } this->m_Controls.m_cbVolumeRendering->setEnabled(enable); } void QmitkAdaptiveRegionGrowingToolGUI::EnableVolumeRendering(bool enable) { mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode(m_NAMEFORMASKEDSEGMENTATION); if (node.IsNull()) return; if (enable) { node->SetBoolProperty("volumerendering", enable); node->SetBoolProperty("volumerendering.uselod", true); } else { node->SetBoolProperty("volumerendering", enable); } double val = this->m_Controls.m_PreviewSlider->value(); this->ChangeLevelWindow(val); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkAdaptiveRegionGrowingToolGUI::UpdateVolumeRenderingThreshold(int) { typedef short PixelType; typedef itk::Image<PixelType, 3> InputImageType; typedef itk::BinaryThresholdImageFilter<InputImageType, InputImageType> ThresholdFilterType; typedef itk::MaskImageFilter<InputImageType, InputImageType, InputImageType> MaskImageFilterType; mitk::DataNode::Pointer grownImageNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); mitk::Image::Pointer grownImage = dynamic_cast<mitk::Image *>(grownImageNode->GetData()); if (!grownImage) { MITK_ERROR << "Missing data node for labeled segmentation image."; return; } InputImageType::Pointer itkGrownImage; mitk::CastToItkImage(grownImage, itkGrownImage); ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New(); thresholdFilter->SetInput(itkGrownImage); thresholdFilter->SetInPlace(false); double sliderVal = this->m_Controls.m_PreviewSlider->value(); PixelType threshold = itk::NumericTraits<PixelType>::min(); if (m_CurrentRGDirectionIsUpwards) { threshold = static_cast<PixelType>(m_UPPERTHRESHOLD - sliderVal + 0.5); thresholdFilter->SetLowerThreshold(threshold); thresholdFilter->SetUpperThreshold(itk::NumericTraits<PixelType>::max()); } else { threshold = sliderVal - m_LOWERTHRESHOLD + 0.5; thresholdFilter->SetLowerThreshold(itk::NumericTraits<PixelType>::min()); thresholdFilter->SetUpperThreshold(threshold); } thresholdFilter->UpdateLargestPossibleRegion(); MaskImageFilterType::Pointer maskFilter = MaskImageFilterType::New(); maskFilter->SetInput(itkGrownImage); maskFilter->SetInPlace(false); maskFilter->SetMaskImage(thresholdFilter->GetOutput()); maskFilter->SetOutsideValue(0); maskFilter->UpdateLargestPossibleRegion(); mitk::Image::Pointer mitkMaskedImage; mitk::CastToMitkImage<InputImageType>(maskFilter->GetOutput(), mitkMaskedImage); mitk::DataNode::Pointer maskNode = m_DataStorage->GetNamedNode(m_NAMEFORMASKEDSEGMENTATION); maskNode->SetData(mitkMaskedImage); } void QmitkAdaptiveRegionGrowingToolGUI::UseVolumeRendering(bool on) { m_UseVolumeRendering = on; this->EnableVolumeRendering(on); } void QmitkAdaptiveRegionGrowingToolGUI::SetLowerThresholdValue(double lowerThreshold) { m_LOWERTHRESHOLD = lowerThreshold; } void QmitkAdaptiveRegionGrowingToolGUI::SetUpperThresholdValue(double upperThreshold) { m_UPPERTHRESHOLD = upperThreshold; } void QmitkAdaptiveRegionGrowingToolGUI::Deactivated() { // make the segmentation preview node invisible mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (node.IsNotNull()) { node->SetVisibility(false); } // disable volume rendering preview after the segmentation node was created this->EnableVolumeRendering(false); m_Controls.m_cbVolumeRendering->setChecked(false); } void QmitkAdaptiveRegionGrowingToolGUI::Activated() { } diff --git a/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp b/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp index 72f745d546..22a29d589a 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp @@ -1,1336 +1,1339 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkLabelSetWidget.h" // mitk #include <mitkAutoCropImageFilter.h> #include <mitkCoreObjectFactory.h> #include <mitkIOUtil.h> #include <mitkLabelSetImage.h> #include <mitkLabelSetImageToSurfaceThreadedFilter.h> #include <mitkRenderingManager.h> #include <mitkShowSegmentationAsSurface.h> #include <mitkSliceBasedInterpolationController.h> #include <mitkStatusBar.h> #include <mitkSurfaceBasedInterpolationController.h> #include <mitkToolManagerProvider.h> // Qmitk #include <QmitkDataStorageComboBox.h> #include <QmitkNewSegmentationDialog.h> #include <QmitkStyleManager.h> #include <QmitkSearchLabelDialog.h> // Qt #include <QColorDialog> #include <QCompleter> #include <QDateTime> #include <QFileDialog> #include <QMenu> #include <QMessageBox> #include <QPushButton> #include <QStringListModel> #include <QWidgetAction> // itk #include <itksys/SystemTools.hxx> // todo: // berry //#include <berryIPreferencesService.h> QmitkLabelSetWidget::QmitkLabelSetWidget(QWidget *parent) : QWidget(parent), m_DataStorage(nullptr), m_Completer(nullptr), m_ToolManager(nullptr) { m_Controls.setupUi(this); m_ColorSequenceRainbow.GoToBegin(); m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(mitk::ToolManagerProvider::MULTILABEL_SEGMENTATION); m_Controls.m_LabelSearchBox->setAlwaysShowClearIcon(true); m_Controls.m_LabelSearchBox->setShowSearchIcon(true); QStringList completionList; completionList << ""; m_Completer = new QCompleter(completionList, this); m_Completer->setCaseSensitivity(Qt::CaseInsensitive); m_Controls.m_LabelSearchBox->setCompleter(m_Completer); connect(m_Controls.m_LabelSearchBox, SIGNAL(returnPressed()), this, SLOT(OnSearchLabel())); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(labelListModified(const QStringList&)), this, SLOT( // OnLabelListModified(const QStringList&)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(mergeLabel(int)), this, SLOT( OnMergeLabel(int)) ); QStringListModel *completeModel = static_cast<QStringListModel *>(m_Completer->model()); completeModel->setStringList(GetLabelStringList()); m_Controls.m_LabelSearchBox->setEnabled(false); m_Controls.m_lblCaption->setText(""); InitializeTableWidget(); } QmitkLabelSetWidget::~QmitkLabelSetWidget() {} void QmitkLabelSetWidget::OnTableViewContextMenuRequested(const QPoint & /*pos*/) { int pixelValue = GetPixelValueOfSelectedItem(); if (-1 == pixelValue) return; QMenu *menu = new QMenu(m_Controls.m_LabelSetTableWidget); if (m_Controls.m_LabelSetTableWidget->selectedItems().size() > 1) { QAction *mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge selection on current label", this); mergeAction->setEnabled(true); QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabels(bool))); menu->addAction(mergeAction); QAction *removeLabelsAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove selected labels", this); removeLabelsAction->setEnabled(true); QObject::connect(removeLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabels(bool))); menu->addAction(removeLabelsAction); QAction *eraseLabelsAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase selected labels", this); eraseLabelsAction->setEnabled(true); QObject::connect(eraseLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabels(bool))); menu->addAction(eraseLabelsAction); QAction *combineAndCreateSurfaceAction = new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Combine and create a surface", this); combineAndCreateSurfaceAction->setEnabled(true); QObject::connect( combineAndCreateSurfaceAction, SIGNAL(triggered(bool)), this, SLOT(OnCombineAndCreateSurface(bool))); // menu->addAction(combineAndCreateSurfaceAction); Not implemented QAction *createMasksAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create a mask for each selected label", this); createMasksAction->setEnabled(true); QObject::connect(createMasksAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateMasks(bool))); // menu->addAction(createMasksAction); Not implemented QAction *combineAndCreateMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Combine and create a mask", this); combineAndCreateMaskAction->setEnabled(true); QObject::connect(combineAndCreateMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCombineAndCreateMask(bool))); // menu->addAction(combineAndCreateMaskAction); Not implemented } else { QAction *renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Rename...", this); renameAction->setEnabled(true); QObject::connect(renameAction, SIGNAL(triggered(bool)), this, SLOT(OnRenameLabel(bool))); menu->addAction(renameAction); QAction *removeAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove...", this); removeAction->setEnabled(true); QObject::connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabel(bool))); menu->addAction(removeAction); QAction *eraseAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase...", this); eraseAction->setEnabled(true); QObject::connect(eraseAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabel(bool))); menu->addAction(eraseAction); QAction *mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge...", this); mergeAction->setEnabled(true); QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabel(bool))); menu->addAction(mergeAction); QAction *randomColorAction = new QAction(QIcon(":/Qmitk/RandomColor.png"), "Random color", this); randomColorAction->setEnabled(true); QObject::connect(randomColorAction, SIGNAL(triggered(bool)), this, SLOT(OnRandomColor(bool))); menu->addAction(randomColorAction); QAction *viewOnlyAction = new QAction(QIcon(":/Qmitk/visible.png"), "View only", this); viewOnlyAction->setEnabled(true); QObject::connect(viewOnlyAction, SIGNAL(triggered(bool)), this, SLOT(OnSetOnlyActiveLabelVisible(bool))); menu->addAction(viewOnlyAction); QAction *viewAllAction = new QAction(QIcon(":/Qmitk/visible.png"), "View all", this); viewAllAction->setEnabled(true); QObject::connect(viewAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsVisible(bool))); menu->addAction(viewAllAction); QAction *hideAllAction = new QAction(QIcon(":/Qmitk/invisible.png"), "Hide all", this); hideAllAction->setEnabled(true); QObject::connect(hideAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsInvisible(bool))); menu->addAction(hideAllAction); QAction *lockAllAction = new QAction(QIcon(":/Qmitk/lock.png"), "Lock all", this); lockAllAction->setEnabled(true); QObject::connect(lockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnLockAllLabels(bool))); menu->addAction(lockAllAction); QAction *unlockAllAction = new QAction(QIcon(":/Qmitk/unlock.png"), "Unlock all", this); unlockAllAction->setEnabled(true); QObject::connect(unlockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnUnlockAllLabels(bool))); menu->addAction(unlockAllAction); QAction *createSurfaceAction = new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Create surface", this); createSurfaceAction->setEnabled(true); createSurfaceAction->setMenu(new QMenu()); QAction *tmp1 = createSurfaceAction->menu()->addAction(QString("Detailed")); QAction *tmp2 = createSurfaceAction->menu()->addAction(QString("Smoothed")); QObject::connect(tmp1, SIGNAL(triggered(bool)), this, SLOT(OnCreateDetailedSurface(bool))); QObject::connect(tmp2, SIGNAL(triggered(bool)), this, SLOT(OnCreateSmoothedSurface(bool))); menu->addAction(createSurfaceAction); QAction *createMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create mask", this); createMaskAction->setEnabled(true); QObject::connect(createMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateMask(bool))); menu->addAction(createMaskAction); QAction *createCroppedMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create cropped mask", this); createCroppedMaskAction->setEnabled(true); QObject::connect(createCroppedMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateCroppedMask(bool))); // QAction* importAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Import...", this ); // importAction->setEnabled(true); // QObject::connect( importAction, SIGNAL( triggered(bool) ), this, SLOT( OnImportSegmentationSession(bool) ) ); // menu->addAction(importAction); menu->addAction(createCroppedMaskAction); QSlider *opacitySlider = new QSlider; opacitySlider->setMinimum(0); opacitySlider->setMaximum(100); opacitySlider->setOrientation(Qt::Horizontal); QObject::connect(opacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OnOpacityChanged(int))); QLabel *_OpacityLabel = new QLabel("Opacity: "); QVBoxLayout *_OpacityWidgetLayout = new QVBoxLayout; _OpacityWidgetLayout->setContentsMargins(4, 4, 4, 4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(opacitySlider); QWidget *_OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); QWidgetAction *OpacityAction = new QWidgetAction(this); OpacityAction->setDefaultWidget(_OpacityWidget); // QObject::connect( m_OpacityAction, SIGNAL( changed() ), this, SLOT( OpacityActionChanged() ) ); auto workingImage = this->GetWorkingImage(); auto activeLayer = workingImage->GetActiveLayer(); auto label = workingImage->GetLabel(pixelValue, activeLayer); if (nullptr != label) { auto opacity = label->GetOpacity(); opacitySlider->setValue(static_cast<int>(opacity * 100)); } menu->addAction(OpacityAction); } menu->popup(QCursor::pos()); } void QmitkLabelSetWidget::OnUnlockAllLabels(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsLocked(false); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnLockAllLabels(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsLocked(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnSetAllLabelsVisible(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsVisible(true); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnSetAllLabelsInvisible(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsVisible(false); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnSetOnlyActiveLabelVisible(bool /*value*/) { mitk::LabelSetImage *workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); workingImage->GetActiveLabelSet()->SetAllLabelsVisible(false); workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->SetVisible(true); workingImage->GetActiveLabelSet()->UpdateLookupTable(pixelValue); this->WaitCursorOn(); const mitk::Point3D &pos = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetCenterOfMassCoordinates(); this->WaitCursorOff(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnMergeLabel(bool /*value*/) { QmitkSearchLabelDialog dialog(this); dialog.setWindowTitle("Select a second label.."); dialog.SetLabelSuggestionList(GetLabelStringList()); int dialogReturnValue = dialog.exec(); if (dialogReturnValue == QDialog::Rejected) return; int sourcePixelValue = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); i++) { if (dialog.GetLabelSetWidgetTableCompleteWord() == QString(m_Controls.m_LabelSetTableWidget->item(i, 0)->text())) sourcePixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt(); } if (sourcePixelValue == -1) { MITK_INFO << "unknown label"; return; } int pixelValue = GetPixelValueOfSelectedItem(); GetWorkingImage()->MergeLabel(pixelValue, sourcePixelValue, GetWorkingImage()->GetActiveLayer()); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnEraseLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to erase the contents of label \""; question.append( QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question(this, "Erase label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { this->WaitCursorOn(); GetWorkingImage()->EraseLabel(pixelValue); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnRemoveLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to remove label \""; question.append( QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question(this, "Remove label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { this->WaitCursorOn(); GetWorkingImage()->GetActiveLabelSet()->RemoveLabel(pixelValue); GetWorkingImage()->EraseLabel(pixelValue); this->WaitCursorOff(); } ResetAllTableWidgetItems(); } void QmitkLabelSetWidget::OnRenameLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QmitkNewSegmentationDialog dialog(this); dialog.setWindowTitle("Rename Label"); dialog.SetSuggestionList(m_OrganColors); dialog.SetColor(GetWorkingImage()->GetActiveLabelSet()->GetLabel(pixelValue)->GetColor()); dialog.SetSegmentationName( QString::fromStdString(GetWorkingImage()->GetActiveLabelSet()->GetLabel(pixelValue)->GetName())); if (dialog.exec() == QDialog::Rejected) { return; } QString segmentationName = dialog.GetSegmentationName(); if (segmentationName.isEmpty()) { segmentationName = "Unnamed"; } GetWorkingImage()->GetActiveLabelSet()->RenameLabel(pixelValue, segmentationName.toStdString(), dialog.GetColor()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnCombineAndCreateMask(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ...to do... // } void QmitkLabelSetWidget::OnCreateMasks(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ..to do.. // } void QmitkLabelSetWidget::OnCombineAndCreateSurface(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ..to do.. // } void QmitkLabelSetWidget::OnEraseLabels(bool /*value*/) { QString question = "Do you really want to erase the selected labels?"; QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Erase selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) return; std::vector<mitk::Label::PixelType> VectorOfLablePixelValues; foreach (QTableWidgetSelectionRange a, ranges) for (int i = a.topRow(); i <= a.bottomRow(); i++) VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); this->WaitCursorOn(); GetWorkingImage()->EraseLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnRemoveLabels(bool /*value*/) { QString question = "Do you really want to remove selected labels?"; QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) { return; } std::vector<mitk::Label::PixelType> VectorOfLablePixelValues; foreach (QTableWidgetSelectionRange a, ranges) { for (int i = a.topRow(); i <= a.bottomRow(); ++i) { VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); } } this->WaitCursorOn(); GetWorkingImage()->RemoveLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); } ResetAllTableWidgetItems(); } void QmitkLabelSetWidget::OnMergeLabels(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to merge selected labels into \""; question.append( QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) { return; } std::vector<mitk::Label::PixelType> vectorOfSourcePixelValues; foreach (QTableWidgetSelectionRange a, ranges) { for (int i = a.topRow(); i <= a.bottomRow(); ++i) { vectorOfSourcePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); } } this->WaitCursorOn(); GetWorkingImage()->MergeLabels(pixelValue, vectorOfSourcePixelValues, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnLockedButtonClicked() { int row = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, LOCKED_COL)) { row = i; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt(); GetWorkingImage() ->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer()) ->SetLocked(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetLocked()); } } void QmitkLabelSetWidget::OnVisibleButtonClicked() { int row = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, VISIBLE_COL)) { row = i; break; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { QTableWidgetItem *item = m_Controls.m_LabelSetTableWidget->item(row, 0); int pixelValue = item->data(Qt::UserRole).toInt(); GetWorkingImage() ->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer()) ->SetVisible(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetVisible()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnColorButtonClicked() { int row = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, COLOR_COL)) { row = i; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt(); const mitk::Color &color = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetColor(); QColor initial(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255); QColor qcolor = QColorDialog::getColor(initial, nullptr, QString("Change color")); if (!qcolor.isValid()) { return; } QPushButton *button = static_cast<QPushButton *>(m_Controls.m_LabelSetTableWidget->cellWidget(row, COLOR_COL)); if (!button) { return; } button->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(qcolor.red())); styleSheet.append(","); styleSheet.append(QString::number(qcolor.green())); styleSheet.append(","); styleSheet.append(QString::number(qcolor.blue())); styleSheet.append("); border: 0;"); button->setStyleSheet(styleSheet); mitk::Color newColor; newColor.SetRed(qcolor.red() / 255.0); newColor.SetGreen(qcolor.green() / 255.0); newColor.SetBlue(qcolor.blue() / 255.0); GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetColor(newColor); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } } void QmitkLabelSetWidget::OnRandomColor(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); GetWorkingImage() ->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer()) ->SetColor(m_ColorSequenceRainbow.GetNextColor()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::SetOrganColors(const QStringList &organColors) { m_OrganColors = organColors; } void QmitkLabelSetWidget::OnActiveLabelChanged(int pixelValue) { mitk::LabelSetImage *workingImage = GetWorkingImage(); assert(workingImage); workingImage->GetActiveLabelSet()->SetActiveLabel(pixelValue); // MITK_INFO << "Active Label set to << " << pixelValue; mitk::SurfaceBasedInterpolationController *interpolator = mitk::SurfaceBasedInterpolationController::GetInstance(); if (interpolator) { interpolator->SetActiveLabel(pixelValue); } workingImage->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnItemClicked(QTableWidgetItem *item) { if (!item) return; int pixelValue = item->data(Qt::UserRole).toInt(); QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (!ranges.empty() && ranges.back().rowCount() == 1) { SelectLabelByPixelValue(pixelValue); OnActiveLabelChanged(pixelValue); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnItemDoubleClicked(QTableWidgetItem *item) { if (!item) return; int pixelValue = item->data(Qt::UserRole).toInt(); // OnItemClicked(item); <<-- Double click first call OnItemClicked WaitCursorOn(); mitk::LabelSetImage *workingImage = GetWorkingImage(); workingImage->UpdateCenterOfMass(pixelValue, workingImage->GetActiveLayer()); const mitk::Point3D &pos = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetCenterOfMassCoordinates(); WaitCursorOff(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } workingImage->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::SelectLabelByPixelValue(mitk::Label::PixelType pixelValue) { // MITK_INFO << "QmitkLabelSetWidget::SelectLabelByPixelValue " << pixelValue; if (!GetWorkingImage()->ExistLabel(pixelValue)) return; for (int row = 0; row < m_Controls.m_LabelSetTableWidget->rowCount(); row++) { if (m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt() == pixelValue) { m_Controls.m_LabelSetTableWidget->clearSelection(); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_LabelSetTableWidget->selectRow(row); m_Controls.m_LabelSetTableWidget->scrollToItem(m_Controls.m_LabelSetTableWidget->item(row, 0)); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); // SelectTableWidgetItem(m_Controls.m_LabelSetTableWidget->item(i,0)); // emit resetView(); // GetWorkingImage()->Modified(); return; } } } void QmitkLabelSetWidget::InsertTableWidgetItem(mitk::Label *label) { const mitk::Color &color = label->GetColor(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[1] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[2] * 255)); styleSheet.append("); border: 0;"); QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2; QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth); QTableWidgetItem *nameItem = new QTableWidgetItem(text); nameItem->setTextAlignment(Qt::AlignCenter | Qt::AlignLeft); // ---!--- // IMPORTANT: ADD PIXELVALUE TO TABLEWIDGETITEM.DATA nameItem->setData(Qt::UserRole, QVariant(label->GetValue())); // ---!--- QPushButton *pbColor = new QPushButton(tableWidget); pbColor->setFixedSize(24, 24); pbColor->setCheckable(false); pbColor->setAutoFillBackground(true); pbColor->setToolTip("Change label color"); pbColor->setStyleSheet(styleSheet); connect(pbColor, SIGNAL(clicked()), this, SLOT(OnColorButtonClicked())); QString transparentStyleSheet = QLatin1String("background-color: transparent; border: 0;"); QPushButton *pbLocked = new QPushButton(tableWidget); pbLocked->setFixedSize(24, 24); QIcon *iconLocked = new QIcon(); auto lockIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/lock.svg")); auto unlockIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/unlock.svg")); iconLocked->addPixmap(lockIcon.pixmap(64), QIcon::Normal, QIcon::Off); iconLocked->addPixmap(unlockIcon.pixmap(64), QIcon::Normal, QIcon::On); pbLocked->setIcon(*iconLocked); pbLocked->setIconSize(QSize(24, 24)); pbLocked->setCheckable(true); pbLocked->setToolTip("Lock/unlock label"); pbLocked->setChecked(!label->GetLocked()); pbLocked->setStyleSheet(transparentStyleSheet); connect(pbLocked, SIGNAL(clicked()), this, SLOT(OnLockedButtonClicked())); QPushButton *pbVisible = new QPushButton(tableWidget); pbVisible->setFixedSize(24, 24); pbVisible->setAutoRepeat(false); QIcon *iconVisible = new QIcon(); auto visibleIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/visible.svg")); auto invisibleIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/invisible.svg")); iconVisible->addPixmap(visibleIcon.pixmap(64), QIcon::Normal, QIcon::Off); iconVisible->addPixmap(invisibleIcon.pixmap(64), QIcon::Normal, QIcon::On); pbVisible->setIcon(*iconVisible); pbVisible->setIconSize(QSize(24, 24)); pbVisible->setCheckable(true); pbVisible->setToolTip("Show/hide label"); pbVisible->setChecked(!label->GetVisible()); pbVisible->setStyleSheet(transparentStyleSheet); connect(pbVisible, SIGNAL(clicked()), this, SLOT(OnVisibleButtonClicked())); int row = tableWidget->rowCount(); tableWidget->insertRow(row); tableWidget->setRowHeight(row, 24); tableWidget->setItem(row, 0, nameItem); tableWidget->setCellWidget(row, 1, pbLocked); tableWidget->setCellWidget(row, 2, pbColor); tableWidget->setCellWidget(row, 3, pbVisible); tableWidget->selectRow(row); // m_LabelSetImage->SetActiveLabel(label->GetPixelValue()); // m_ToolManager->WorkingDataModified.Send(); // emit activeLabelChanged(label->GetPixelValue()); if (row == 0) { tableWidget->hideRow(row); // hide exterior label } } void QmitkLabelSetWidget::UpdateAllTableWidgetItems() { mitk::LabelSetImage *workingImage = GetWorkingImage(); if (!workingImage) return; // add all labels QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; m_LabelStringList.clear(); for (int i = 0; i < tableWidget->rowCount(); ++i) { UpdateTableWidgetItem(tableWidget->item(i, 0)); m_LabelStringList.append(tableWidget->item(i, 0)->text()); } OnLabelListModified(m_LabelStringList); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::UpdateTableWidgetItem(QTableWidgetItem *item) { mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Label *label = workingImage->GetLabel(item->data(Qt::UserRole).toInt(), workingImage->GetActiveLayer()); const mitk::Color &color = label->GetColor(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[1] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[2] * 255)); styleSheet.append("); border: 0;"); QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2; QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth); item->setText(text); QPushButton *pbLocked = dynamic_cast<QPushButton *>(tableWidget->cellWidget(item->row(), 1)); pbLocked->setChecked(!label->GetLocked()); QPushButton *pbColor = dynamic_cast<QPushButton *>(tableWidget->cellWidget(item->row(), 2)); pbColor->setStyleSheet(styleSheet); QPushButton *pbVisible = dynamic_cast<QPushButton *>(tableWidget->cellWidget(item->row(), 3)); pbVisible->setChecked(!label->GetVisible()); if (item->row() == 0) { tableWidget->hideRow(item->row()); // hide exterior label } } void QmitkLabelSetWidget::ResetAllTableWidgetItems() { QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; // remove all rows while (tableWidget->rowCount()) { tableWidget->removeRow(0); } - mitk::LabelSetImage *workingImage = GetWorkingImage(); - if (!workingImage) + mitk::DataNode * workingNode = GetWorkingNode(); + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); + if (nullptr == workingImage) + { return; + } // add all labels m_LabelStringList.clear(); mitk::LabelSet::LabelContainerConstIteratorType it = workingImage->GetActiveLabelSet()->IteratorConstBegin(); mitk::LabelSet::LabelContainerConstIteratorType end = workingImage->GetActiveLabelSet()->IteratorConstEnd(); int pixelValue = -1; while (it != end) { InsertTableWidgetItem(it->second); if (workingImage->GetActiveLabel() == it->second) // get active pixelValue = it->first; m_LabelStringList.append(QString(it->second->GetName().c_str())); it++; } SelectLabelByPixelValue(pixelValue); OnLabelListModified(m_LabelStringList); std::stringstream captionText; captionText << "Number of labels: " << workingImage->GetNumberOfLabels(workingImage->GetActiveLayer()) - 1; m_Controls.m_lblCaption->setText(captionText.str().c_str()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } int QmitkLabelSetWidget::GetPixelValueOfSelectedItem() { if (m_Controls.m_LabelSetTableWidget->currentItem()) { return m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt(); } return -1; } QStringList &QmitkLabelSetWidget::GetLabelStringList() { return m_LabelStringList; } void QmitkLabelSetWidget::InitializeTableWidget() { QTableWidget *tableWidged = m_Controls.m_LabelSetTableWidget; tableWidged->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); tableWidged->setTabKeyNavigation(false); tableWidged->setAlternatingRowColors(false); tableWidged->setFocusPolicy(Qt::NoFocus); tableWidged->setColumnCount(4); tableWidged->resizeColumnToContents(NAME_COL); tableWidged->setColumnWidth(LOCKED_COL, 25); tableWidged->setColumnWidth(COLOR_COL, 25); tableWidged->setColumnWidth(VISIBLE_COL, 25); tableWidged->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); tableWidged->setContextMenuPolicy(Qt::CustomContextMenu); tableWidged->horizontalHeader()->hide(); tableWidged->setSortingEnabled(false); tableWidged->verticalHeader()->hide(); tableWidged->setEditTriggers(QAbstractItemView::NoEditTriggers); tableWidged->setSelectionMode(QAbstractItemView::ExtendedSelection); tableWidged->setSelectionBehavior(QAbstractItemView::SelectRows); connect(tableWidged, SIGNAL(itemClicked(QTableWidgetItem *)), this, SLOT(OnItemClicked(QTableWidgetItem *))); connect( tableWidged, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this, SLOT(OnItemDoubleClicked(QTableWidgetItem *))); connect(tableWidged, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(OnTableViewContextMenuRequested(const QPoint &))); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(activeLabelChanged(int)), this, SLOT(OnActiveLabelChanged(int)) // ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(importSegmentation()), this, SLOT( OnImportSegmentation()) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(importLabeledImage()), this, SLOT( OnImportLabeledImage()) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(renameLabel(int, const mitk::Color&, const std::string&)), this, // SLOT(OnRenameLabel(int, const mitk::Color&, const std::string&)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createSurface(int, bool)), this, SLOT(OnCreateSurface(int, bool)) // ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(toggleOutline(bool)), this, SLOT(OnToggleOutline(bool)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(goToLabel(const mitk::Point3D&)), this, SIGNAL(goToLabel(const // mitk::Point3D&)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(combineAndCreateSurface( const QList<QTableWidgetSelectionRange>& // )), // this, SLOT(OnCombineAndCreateSurface( const QList<QTableWidgetSelectionRange>&)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createMask(int)), this, SLOT(OnCreateMask(int)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createCroppedMask(int)), this, SLOT(OnCreateCroppedMask(int)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(combineAndCreateMask( const QList<QTableWidgetSelectionRange>& // )), // this, SLOT(OnCombineAndCreateMask( const QList<QTableWidgetSelectionRange>&)) ); } void QmitkLabelSetWidget::OnOpacityChanged(int value) { int pixelValue = GetPixelValueOfSelectedItem(); float opacity = static_cast<float>(value) / 100.0f; GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetOpacity(opacity); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } void QmitkLabelSetWidget::setEnabled(bool enabled) { QWidget::setEnabled(enabled); UpdateControls(); } void QmitkLabelSetWidget::SetDataStorage(mitk::DataStorage *storage) { m_DataStorage = storage; } void QmitkLabelSetWidget::OnSearchLabel() { std::string text = m_Controls.m_LabelSearchBox->text().toStdString(); int pixelValue = -1; int row = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (m_Controls.m_LabelSetTableWidget->item(i, 0)->text().toStdString().compare(text) == 0) { pixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt(); row = i; break; } } if (pixelValue == -1) { return; } GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue); QTableWidgetItem *nameItem = m_Controls.m_LabelSetTableWidget->item(row, NAME_COL); if (!nameItem) { return; } m_Controls.m_LabelSetTableWidget->clearSelection(); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_LabelSetTableWidget->selectRow(row); m_Controls.m_LabelSetTableWidget->scrollToItem(nameItem); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue); this->WaitCursorOn(); mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetCenterOfMassCoordinates(); m_ToolManager->WorkingDataChanged(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } else { GetWorkingImage()->UpdateCenterOfMass(pixelValue, GetWorkingImage()->GetActiveLayer()); mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetCenterOfMassCoordinates(); emit goToLabel(pos); } this->WaitCursorOff(); } void QmitkLabelSetWidget::OnLabelListModified(const QStringList &list) { QStringListModel *completeModel = static_cast<QStringListModel *>(m_Completer->model()); completeModel->setStringList(list); } mitk::LabelSetImage *QmitkLabelSetWidget::GetWorkingImage() { mitk::DataNode *workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData()); assert(workingImage); return workingImage; } mitk::DataNode *QmitkLabelSetWidget::GetWorkingNode() { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); return workingNode; } void QmitkLabelSetWidget::UpdateControls() { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); bool hasWorkingData = (workingNode != nullptr); m_Controls.m_LabelSetTableWidget->setEnabled(hasWorkingData); m_Controls.m_LabelSearchBox->setEnabled(hasWorkingData); if (!hasWorkingData) return; QStringListModel *completeModel = static_cast<QStringListModel *>(m_Completer->model()); completeModel->setStringList(GetLabelStringList()); } void QmitkLabelSetWidget::OnCreateCroppedMask(bool) { m_ToolManager->ActivateTool(-1); mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Image::Pointer maskImage; int pixelValue = GetPixelValueOfSelectedItem(); try { this->WaitCursorOn(); mitk::AutoCropImageFilter::Pointer cropFilter = mitk::AutoCropImageFilter::New(); cropFilter->SetInput(workingImage->CreateLabelMask(pixelValue)); cropFilter->SetBackgroundValue(0); cropFilter->SetMarginFactor(1.15); cropFilter->Update(); maskImage = cropFilter->GetOutput(); this->WaitCursorOff(); } catch (mitk::Exception &e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } if (maskImage.IsNull()) { QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } mitk::DataNode::Pointer maskNode = mitk::DataNode::New(); std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName(); name += "-mask"; maskNode->SetName(name); maskNode->SetData(maskImage); maskNode->SetBoolProperty("binary", true); maskNode->SetBoolProperty("outline binary", true); maskNode->SetBoolProperty("outline binary shadow", true); maskNode->SetFloatProperty("outline width", 2.0); maskNode->SetColor(workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetColor()); maskNode->SetOpacity(1.0); m_DataStorage->Add(maskNode, GetWorkingNode()); } void QmitkLabelSetWidget::OnCreateMask(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Image::Pointer maskImage; int pixelValue = GetPixelValueOfSelectedItem(); try { this->WaitCursorOn(); maskImage = workingImage->CreateLabelMask(pixelValue); this->WaitCursorOff(); } catch (mitk::Exception &e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } if (maskImage.IsNull()) { QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } mitk::DataNode::Pointer maskNode = mitk::DataNode::New(); std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName(); name += "-mask"; maskNode->SetName(name); maskNode->SetData(maskImage); maskNode->SetBoolProperty("binary", true); maskNode->SetBoolProperty("outline binary", true); maskNode->SetBoolProperty("outline binary shadow", true); maskNode->SetFloatProperty("outline width", 2.0); maskNode->SetColor(workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetColor()); maskNode->SetOpacity(1.0); m_DataStorage->Add(maskNode, GetWorkingNode()); } void QmitkLabelSetWidget::OnToggleOutline(bool value) { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); workingNode->SetBoolProperty("labelset.contour.active", value); workingNode->GetData()->Modified(); // fixme: workaround to force data-type rendering (and not only property-type) mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnCreateSmoothedSurface(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode::Pointer workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); mitk::LabelSetImageToSurfaceThreadedFilter::Pointer surfaceFilter = mitk::LabelSetImageToSurfaceThreadedFilter::New(); itk::SimpleMemberCommand<QmitkLabelSetWidget>::Pointer successCommand = itk::SimpleMemberCommand<QmitkLabelSetWidget>::New(); successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand); itk::SimpleMemberCommand<QmitkLabelSetWidget>::Pointer errorCommand = itk::SimpleMemberCommand<QmitkLabelSetWidget>::New(); errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand); mitk::DataNode::Pointer groupNode = workingNode; surfaceFilter->SetPointerParameter("Group node", groupNode); surfaceFilter->SetPointerParameter("Input", workingImage); surfaceFilter->SetParameter("RequestedLabel", pixelValue); surfaceFilter->SetParameter("Smooth", true); surfaceFilter->SetDataStorage(*m_DataStorage); mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background..."); try { surfaceFilter->StartAlgorithm(); } catch (mitk::Exception &e) { MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Surface", "Could not create a surface mesh out of the selected label. See error log for details.\n"); } } void QmitkLabelSetWidget::OnCreateDetailedSurface(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode::Pointer workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); mitk::LabelSetImageToSurfaceThreadedFilter::Pointer surfaceFilter = mitk::LabelSetImageToSurfaceThreadedFilter::New(); itk::SimpleMemberCommand<QmitkLabelSetWidget>::Pointer successCommand = itk::SimpleMemberCommand<QmitkLabelSetWidget>::New(); successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand); itk::SimpleMemberCommand<QmitkLabelSetWidget>::Pointer errorCommand = itk::SimpleMemberCommand<QmitkLabelSetWidget>::New(); errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand); mitk::DataNode::Pointer groupNode = workingNode; surfaceFilter->SetPointerParameter("Group node", groupNode); surfaceFilter->SetPointerParameter("Input", workingImage); surfaceFilter->SetParameter("RequestedLabel", pixelValue); surfaceFilter->SetParameter("Smooth", false); surfaceFilter->SetDataStorage(*m_DataStorage); mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background..."); try { surfaceFilter->StartAlgorithm(); } catch (mitk::Exception &e) { MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Surface", "Could not create a surface mesh out of the selected label. See error log for details.\n"); } } void QmitkLabelSetWidget::OnImportLabeledImage() { /* m_ToolManager->ActivateTool(-1); mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0); assert(referenceNode); // Ask the user for a list of files to open QStringList fileNames = QFileDialog::getOpenFileNames( this, "Open Image", m_LastFileOpenPath, mitk::CoreObjectFactory::GetInstance()->GetFileExtensions()); if (fileNames.empty()) return; try { this->WaitCursorOn(); mitk::Image::Pointer image = mitk::IOUtil::Load<mitk::Image>( fileNames.front().toStdString() ); if (image.IsNull()) { this->WaitCursorOff(); QMessageBox::information(this, "Import Labeled Image", "Could not load the selected segmentation.\n"); return; } mitk::LabelSetImage::Pointer newImage = mitk::LabelSetImage::New(); newImage->InitializeByLabeledImage(image); this->WaitCursorOff(); mitk::DataNode::Pointer newNode = mitk::DataNode::New(); std::string newName = referenceNode->GetName(); newName += "-labels"; newNode->SetName(newName); newNode->SetData(newImage); m_DataStorage->Add(newNode, referenceNode); } catch (mitk::Exception & e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Import Labeled Image", "Could not load the selected segmentation. See error log for details.\n"); return; } this->UpdateControls(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); */ } void QmitkLabelSetWidget::OnImportSegmentation() { /* m_ToolManager->ActivateTool(-1); mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); mitk::LabelSetImage* workingImage = dynamic_cast<mitk::LabelSetImage*>( workingNode->GetData() ); assert(workingImage); std::string fileExtensions("Segmentation files (*.lset);;"); QString qfileName = QFileDialog::getOpenFileName(this, "Import Segmentation", m_LastFileOpenPath, fileExtensions.c_str() ); if (qfileName.isEmpty() ) return; mitk::NrrdLabelSetImageReader::Pointer reader = mitk::NrrdLabelSetImageReader::New(); reader->SetFileName(qfileName.toLatin1()); try { this->WaitCursorOn(); reader->Update(); mitk::LabelSetImage::Pointer newImage = reader->GetOutput(); workingImage->Concatenate(newImage); this->WaitCursorOff(); } catch ( mitk::Exception& e ) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Import Segmentation", "Could not import the selected segmentation session.\n See error log for details.\n"); } */ mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::WaitCursorOn() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); } void QmitkLabelSetWidget::WaitCursorOff() { this->RestoreOverrideCursor(); } void QmitkLabelSetWidget::RestoreOverrideCursor() { QApplication::restoreOverrideCursor(); } void QmitkLabelSetWidget::OnThreadedCalculationDone() { mitk::StatusBar::GetInstance()->Clear(); } diff --git a/Modules/ToFHardware/CMakeLists.txt b/Modules/ToFHardware/CMakeLists.txt index f6f70f68c1..004d65c850 100644 --- a/Modules/ToFHardware/CMakeLists.txt +++ b/Modules/ToFHardware/CMakeLists.txt @@ -1,32 +1,32 @@ #Define the platform string mitkMacroGetPMDPlatformString(_PLATFORM_STRING) MITK_CREATE_MODULE( - DEPENDS MitkOpenCVVideoSupport MitkIGTBase MitkCameraCalibration MitkIpPic + DEPENDS MitkOpenCVVideoSupport MitkIGTBase MitkCameraCalibration PACKAGE_DEPENDS PRIVATE ITK|IONRRD ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ) # set(tofHardware_srcs ) # usFunctionEmbedResources(tofHardware_srcs # LIBRARY_NAME mitkToFHardware # ROOT_DIR ${MITK_DATA_DIR}/ToF-Data/CalibrationFiles # FILES Default_Parameters.xml Kinect_IR_camera.xml Kinect_RGB_camera.xml Mesa-SR4000_Camera.xml PMDCamBoard_camera.xml PMDCamCube2_camera.xml PMDCamCube3_camera.xml # ) add_subdirectory(Testing) add_subdirectory(Kinect) add_subdirectory(KinectV2) add_subdirectory(PMD) add_subdirectory(MesaSR4000) # Install external libraries which are not directly linked to a MITK module include(${CMAKE_CURRENT_SOURCE_DIR}/mitkToFHardwareInstallRules.cmake) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mitkToFHardwareInstallRules.cmake ${PROJECT_BINARY_DIR}/mitkToFHardwareInstallRules.cmake COPYONLY) CONFIGURE_FILE(mitkToFConfig.h.in ${PROJECT_BINARY_DIR}/mitkToFConfig.h @ONLY) #foreach(tofhardwaresubfolder_dir ${tofhardwaresubfolder_dirs}) # add_subdirectory(${tofhardwaresubfolder_dirs}) #endforeach() diff --git a/Modules/ToFHardware/PMD/Testing/mitkToFCameraPMDMITKPlayerControllerTest.cpp b/Modules/ToFHardware/PMD/Testing/mitkToFCameraPMDMITKPlayerControllerTest.cpp index 0a86e43654..8abfe50ec6 100644 --- a/Modules/ToFHardware/PMD/Testing/mitkToFCameraPMDMITKPlayerControllerTest.cpp +++ b/Modules/ToFHardware/PMD/Testing/mitkToFCameraPMDMITKPlayerControllerTest.cpp @@ -1,61 +1,61 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkTestingMacros.h> #include <mitkToFCameraPMDMITKPlayerController.h> #include <mitkToFConfig.h> /**Documentation * test for the class "ToFCameraPMDMITKPlayerController". */ int mitkToFCameraPMDMITKPlayerControllerTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("ToFCameraPMDMITKPlayerController"); mitk::ToFCameraPMDMITKPlayerController::Pointer testObject = mitk::ToFCameraPMDMITKPlayerController::New(); MITK_TEST_CONDITION_REQUIRED(!(testObject.GetPointer() == nullptr) ,"Testing initialization class"); MITK_TEST_CONDITION_REQUIRED(testObject->GetCaptureHeight()== 200 ,"Testing initialization of CaptureHeight"); MITK_TEST_CONDITION_REQUIRED(testObject->GetCaptureWidth()== 200 ,"Testing initialization of CaptureWidth"); // test empty file behavior std::string testFile = ""; testObject->SetInputFileName(testFile); MITK_TEST_CONDITION_REQUIRED(testObject->OpenCameraConnection(),"Testing open camera without valid data"); //MITK_TEST_CONDITION_REQUIRED(!testObject->CloseCameraConnection(),"Testing closing of connection"); //test valid data behavior //CAVE: The following test cases are valid once rawData recording is fixed. Currently the // functionality is not working therefor the test cases are excluded!! //std::string filePath = MITK_TOF_DATA_DIR; - //testFile = "/aa_raw.pic"; + //testFile = "/aa_raw.nrrd"; //filePath.append(testFile); //testObject->SetInputFileName(filePath); //MITK_TEST_CONDITION_REQUIRED( testObject->OpenCameraConnection(),"Testing open camera with valid data"); //MITK_TEST_CONDITION_REQUIRED( testObject->GetIntegrationTime() == 2500,"Testing correct setting of integration time!"); //MITK_TEST_CONDITION_REQUIRED( testObject->GetModulationFrequency() == 20,"Testing correct setting of modulation frequency!"); // ////test source data passing and updating! //int size = testObject->GetSourceDataStructSize(); //MITK_TEST_CONDITION_REQUIRED( size != 0 , "Testing correct setting of source data size!" ) //char* sourceData = nullptr; //testObject->GetSourceData( sourceData ); //MITK_TEST_CONDITION_REQUIRED( sourceData == nullptr, "Testing setting of source data without update camera!"); //testObject->UpdateCamera(); //sourceData = new char[size]; //testObject->GetSourceData(sourceData); //MITK_TEST_CONDITION_REQUIRED( sourceData != nullptr, "Testing setting of source data with update camera!"); //delete[] sourceData; MITK_TEST_CONDITION( testObject->CloseCameraConnection(),"Closing Connection!"); MITK_TEST_END(); }git st diff --git a/Modules/ToFHardware/Testing/mitkToFCameraMITKPlayerControllerTest.cpp b/Modules/ToFHardware/Testing/mitkToFCameraMITKPlayerControllerTest.cpp index e5f521c196..7ef5d926c1 100644 --- a/Modules/ToFHardware/Testing/mitkToFCameraMITKPlayerControllerTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFCameraMITKPlayerControllerTest.cpp @@ -1,184 +1,180 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkTestingMacros.h> #include <mitkToFCameraMITKPlayerController.h> #include <mitkToFCameraMITKPlayerDevice.h> #include <mitkToFImageGrabber.h> #include <mitkPixelType.h> #include <mitkImageWriter.h> namespace mitk { class ToFCameraMITKPlayerDeviceImpl : public ToFCameraMITKPlayerDevice { public: inline ToFCameraMITKPlayerController::Pointer GetController(){return m_Controller;}; inline ToFCameraMITKPlayerDeviceImpl(){}; inline ~ToFCameraMITKPlayerDeviceImpl(){}; private: }; } // end namespace mitk /**Documentation * test for the class "ToFCameraMITKPlayerController". */ void ReadFileFormatTestCase(std::string extension, mitk::ToFImageGrabber::Pointer grabber) { MITK_INFO<<"Checking image processing with file format " << extension.c_str(); //create some test image unsigned int* dim = new unsigned int[3]; dim[0] = 100; dim[1] = 100; dim[2] = 1; int end = dim[0]*dim[1]*dim[2]; float* data = new float[end]; int index = 0; while(index != end) { data[index] = (float) index; index++; } mitk::Image::Pointer testImage = mitk::Image::New(); mitk::PixelType FloatType = mitk::MakeScalarPixelType<float>(); testImage->Initialize( FloatType, 3, dim); testImage->SetVolume(data); // save image as dist, ampl and inten image to file. std::string distanceImageFileName("distTestImage"); std::string amplitudeImageFileName("amplTestImage"); std::string intensityImageFileName("intenTestImage"); mitk::ImageWriter::Pointer writer = mitk::ImageWriter::New(); writer->SetInput(testImage); writer->SetExtension(extension); writer->SetFileName(distanceImageFileName); writer->Update(); writer->SetFileName(amplitudeImageFileName); writer->Update(); writer->SetFileName(intensityImageFileName); writer->Update(); // load the files from directory grabber->SetStringProperty("DistanceImageFileName", (distanceImageFileName.append(extension)).c_str()); grabber->SetStringProperty("AmplitudeImageFileName", (amplitudeImageFileName.append(extension)).c_str()); grabber->SetStringProperty("IntensityImageFileName", (intensityImageFileName.append(extension)).c_str()); MITK_TEST_CONDITION_REQUIRED(grabber->ConnectCamera() ,"Are the image files loaded correctly?"); mitk::ToFCameraMITKPlayerController::Pointer testObject = static_cast<mitk::ToFCameraMITKPlayerDeviceImpl*>(grabber->GetCameraDevice())->GetController(); // test load image from image grabber testObject->UpdateCamera(); index = 0; bool distOK = true; bool amplOK = true; bool intenOK = true; float* dist = new float[end]; float* ampl = new float[end]; float* inten = new float[end]; testObject->GetDistances( dist ); testObject->GetAmplitudes( ampl ); testObject->GetIntensities( inten ); while( index != end ) { if( dist[index] != data[index]) { distOK = false; } if( ampl[index] != data[index]) { amplOK = false; } if( inten[index] != data[index]) { intenOK = false; } index++; } MITK_TEST_CONDITION_REQUIRED(distOK ,"Testing correct loading and passing of distance image information!"); MITK_TEST_CONDITION_REQUIRED(amplOK ,"Testing correct loading and passing of amplitude image information!"); MITK_TEST_CONDITION_REQUIRED(intenOK ,"Testing correct loading and passing of intensity image information!"); MITK_TEST_CONDITION_REQUIRED(testObject->CloseCameraConnection(),"Testing disconnection of controller"); //clean up and delete saved image files if(remove(distanceImageFileName.c_str())!=0) { MITK_ERROR<<"File: "<<distanceImageFileName<<" not successfully deleted!"; } if(std::remove(amplitudeImageFileName.c_str())!=0) { MITK_ERROR<<"File: "<<amplitudeImageFileName<<" not successfully deleted!"; } if(remove(intensityImageFileName.c_str())!=0) { MITK_ERROR<<"File: "<<intensityImageFileName<<" not successfully deleted!"; } delete[] dist; delete[] ampl; delete[] inten; delete[] dim; } int mitkToFCameraMITKPlayerControllerTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("ToFCameraMITKPlayerController"); mitk::ToFCameraMITKPlayerController::Pointer testObject = mitk::ToFCameraMITKPlayerController::New(); mitk::ToFCameraMITKPlayerDeviceImpl* deviceImpl = new mitk::ToFCameraMITKPlayerDeviceImpl; mitk::ToFImageGrabber::Pointer imageGrabber = mitk::ToFImageGrabber::New(); imageGrabber->SetCameraDevice(deviceImpl); MITK_TEST_CONDITION_REQUIRED(!(testObject.GetPointer() == nullptr) ,"Testing initialization class"); MITK_TEST_CONDITION_REQUIRED(testObject->GetCaptureHeight()== 0 ,"Testing initialization of CaptureHeight"); MITK_TEST_CONDITION_REQUIRED(testObject->GetCaptureWidth()== 0 ,"Testing initialization of CaptureWidth"); //test correct order of file name member testObject->SetDistanceImageFileName("distTest"); testObject->SetAmplitudeImageFileName("amplTest"); testObject->SetIntensityImageFileName("intenTest"); MITK_TEST_CONDITION_REQUIRED(testObject->GetDistanceImageFileName()== "distTest" ,"Testing correct filename passing - Dist"); MITK_TEST_CONDITION_REQUIRED(testObject->GetAmplitudeImageFileName()== "amplTest" ,"Testing correct filename passing - Ampl"); MITK_TEST_CONDITION_REQUIRED(testObject->GetIntensityImageFileName()== "intenTest" ,"Testing correct filename passing - Inten"); //test passing of file name from image grabber imageGrabber->SetStringProperty("DistanceImageFileName", "distPropertyTestName"); imageGrabber->SetStringProperty("AmplitudeImageFileName", "amplPropertyTestName"); imageGrabber->SetStringProperty("IntensityImageFileName", "intenPropertyTestName"); testObject = deviceImpl->GetController(); MITK_TEST_CONDITION_REQUIRED(testObject->GetDistanceImageFileName()== "distPropertyTestName" ,"Testing correct filename passing from Image Grabber- Dist"); MITK_TEST_CONDITION_REQUIRED(testObject->GetAmplitudeImageFileName()== "amplPropertyTestName" ,"Testing correct filename passing from Image Grabber- Ampl"); MITK_TEST_CONDITION_REQUIRED(testObject->GetIntensityImageFileName()== "intenPropertyTestName" ,"Testing correct filename passing from Image Grabber- Inten"); - // PIC Format is deprecated - // ReadFileFormatTestCase(".pic", imageGrabber); ReadFileFormatTestCase(".nrrd", imageGrabber); deviceImpl->Delete(); // end of test MITK_TEST_END(); } - - diff --git a/Modules/ToFHardware/Testing/mitkToFImageGrabberTest.cpp b/Modules/ToFHardware/Testing/mitkToFImageGrabberTest.cpp index 177d50a7a2..3e7858a398 100644 --- a/Modules/ToFHardware/Testing/mitkToFImageGrabberTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFImageGrabberTest.cpp @@ -1,186 +1,186 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkTestingMacros.h> #include <mitkTestingConfig.h> #include <mitkTestFixture.h> #include <mitkIOUtil.h> #include <mitkToFImageGrabber.h> #include <mitkToFCameraMITKPlayerDevice.h> #include <mitkToFConfig.h> #include <mitkImageSliceSelector.h> /** * @brief The mitkToFImageGrabberTestSuite class is a test-suite for mitkToFImageGrabber. * * Test data is retrieved from MITK-Data. */ class mitkToFImageGrabberTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToFImageGrabberTestSuite); MITK_TEST(GetterAndSetterTests); MITK_TEST(ConnectCamera_InvalidFileName_ThrowsException); MITK_TEST(ConnectCamera_ValidFileName_ReturnsTrue); MITK_TEST(IsCameraActive_DifferentStates_ReturnsCorrectResult); MITK_TEST(Update_2DData_ImagesAreEqual); MITK_TEST(Update_CamCubeData_PropertiesAreTrue); CPPUNIT_TEST_SUITE_END(); private: std::string m_KinectDepthImagePath; std::string m_KinectColorImagePath; std::string m_CamCubeDepthImagePath; std::string m_CamCubeIntensityImagePath; std::string m_CamCubeAmplitudeImagePath; mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; public: void setUp() override { std::string dirName = MITK_TOF_DATA_DIR; std::string depthImagePath = dirName + "/" + "Kinect_Lego_Phantom_DistanceImage.nrrd"; std::string colorImagePath = dirName + "/" + "Kinect_Lego_Phantom_RGBImage.nrrd"; - std::string distanceImageP = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_DistanceImage.pic"; - std::string amplitudeImage = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_AmplitudeImage.pic"; - std::string intensityImage = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_IntensityImage.pic"; + std::string distanceImageP = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_DistanceImage.nrrd"; + std::string amplitudeImage = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_AmplitudeImage.nrrd"; + std::string intensityImage = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_IntensityImage.nrrd"; m_KinectDepthImagePath = GetTestDataFilePath(depthImagePath); m_KinectColorImagePath = GetTestDataFilePath(colorImagePath); m_CamCubeDepthImagePath = GetTestDataFilePath(distanceImageP); m_CamCubeIntensityImagePath = GetTestDataFilePath(amplitudeImage); m_CamCubeAmplitudeImagePath = GetTestDataFilePath(intensityImage); m_ToFImageGrabber = mitk::ToFImageGrabber::New(); //The Grabber always needs a device mitk::ToFCameraMITKPlayerDevice::Pointer tofCameraMITKPlayerDevice = mitk::ToFCameraMITKPlayerDevice::New(); m_ToFImageGrabber->SetCameraDevice(tofCameraMITKPlayerDevice); } void tearDown() override { if(m_ToFImageGrabber->IsCameraActive()) { m_ToFImageGrabber->StopCamera(); m_ToFImageGrabber->DisconnectCamera(); } m_ToFImageGrabber = nullptr; } /** * @brief GetterAndSetterTests Testing getters and setters of mitkToFImageGrabber, because * they internally contain logic. */ void GetterAndSetterTests() { int modulationFrequency = 20; m_ToFImageGrabber->SetModulationFrequency(modulationFrequency); CPPUNIT_ASSERT(modulationFrequency==m_ToFImageGrabber->GetModulationFrequency()); int integrationTime = 500; m_ToFImageGrabber->SetIntegrationTime(integrationTime); CPPUNIT_ASSERT(integrationTime==m_ToFImageGrabber->GetIntegrationTime()); } void ConnectCamera_InvalidFileName_ThrowsException() { MITK_TEST_FOR_EXCEPTION(std::logic_error, m_ToFImageGrabber->ConnectCamera()); m_ToFImageGrabber->StartCamera(); m_ToFImageGrabber->StopCamera(); CPPUNIT_ASSERT_MESSAGE("Test DisconnectCamera() with no file name set", !m_ToFImageGrabber->DisconnectCamera()); } void ConnectCamera_ValidFileName_ReturnsTrue() { m_ToFImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_KinectDepthImagePath)); m_ToFImageGrabber->SetProperty("RGBImageFileName",mitk::StringProperty::New(m_KinectColorImagePath)); CPPUNIT_ASSERT(m_ToFImageGrabber->ConnectCamera() == true); } void Update_2DData_ImagesAreEqual() { try { m_ToFImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_KinectDepthImagePath)); m_ToFImageGrabber->ConnectCamera(); m_ToFImageGrabber->StartCamera(); mitk::Image::Pointer expectedResultImage = mitk::IOUtil::Load<mitk::Image>(m_KinectDepthImagePath); m_ToFImageGrabber->Update(); //Select 2D slice to make it comparable in diminsion mitk::ImageSliceSelector::Pointer selector = mitk::ImageSliceSelector::New(); selector->SetSliceNr(0); selector->SetTimeNr(0); selector->SetInput( m_ToFImageGrabber->GetOutput(0) ); selector->Update(); mitk::Image::Pointer distanceImage = selector->GetOutput(0); MITK_ASSERT_EQUAL( expectedResultImage, distanceImage, "Test data is 2D. Results should be equal."); } catch(std::exception &e) { MITK_ERROR << e.what(); } } void IsCameraActive_DifferentStates_ReturnsCorrectResult() { m_ToFImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_KinectDepthImagePath)); m_ToFImageGrabber->SetProperty("RGBImageFileName",mitk::StringProperty::New(m_KinectColorImagePath)); m_ToFImageGrabber->ConnectCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == false); m_ToFImageGrabber->StartCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == true); m_ToFImageGrabber->StopCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == false); m_ToFImageGrabber->StartCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == true); m_ToFImageGrabber->StopCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == false); m_ToFImageGrabber->DisconnectCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == false); } void Update_CamCubeData_PropertiesAreTrue() { m_ToFImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_CamCubeDepthImagePath)); m_ToFImageGrabber->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(m_CamCubeAmplitudeImagePath)); m_ToFImageGrabber->SetProperty("IntensityImageFileName",mitk::StringProperty::New(m_CamCubeIntensityImagePath)); m_ToFImageGrabber->ConnectCamera(); m_ToFImageGrabber->StartCamera(); m_ToFImageGrabber->Update(); CPPUNIT_ASSERT( m_ToFImageGrabber->GetBoolProperty("HasAmplitudeImage") == true); CPPUNIT_ASSERT( m_ToFImageGrabber->GetBoolProperty("HasIntensityImage") == true); CPPUNIT_ASSERT( m_ToFImageGrabber->GetOutput(1) != nullptr ); CPPUNIT_ASSERT( m_ToFImageGrabber->GetOutput(2) != nullptr ); } }; MITK_TEST_SUITE_REGISTRATION(mitkToFImageGrabber) diff --git a/Modules/ToFHardware/Testing/mitkToFImageRecorderFilterTest.cpp b/Modules/ToFHardware/Testing/mitkToFImageRecorderFilterTest.cpp index 1b61990333..0d0930706e 100644 --- a/Modules/ToFHardware/Testing/mitkToFImageRecorderFilterTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFImageRecorderFilterTest.cpp @@ -1,163 +1,163 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkTestingMacros.h> #include <mitkImageDataItem.h> #include <mitkItkImageFileReader.h> #include <mitkToFConfig.h> #include <mitkToFImageRecorderFilter.h> #include <mitkToFImageWriter.h> #include <itkImage.h> #include <itkImageRegionIterator.h> #include <itkMersenneTwisterRandomVariateGenerator.h> mitk::Image::Pointer CreateTestImage(unsigned int dimX, unsigned int dimY) { typedef itk::Image<float,2> ItkImageType2D; typedef itk::ImageRegionIterator<ItkImageType2D> ItkImageRegionIteratorType2D; ItkImageType2D::Pointer image = ItkImageType2D::New(); ItkImageType2D::IndexType start; start[0] = 0; start[1] = 0; ItkImageType2D::SizeType size; size[0] = dimX; size[1] = dimY; ItkImageType2D::RegionType region; region.SetSize(size); region.SetIndex( start); ItkImageType2D::SpacingType spacing; spacing[0] = 1.0; spacing[1] = 1.0; image->SetRegions( region ); image->SetSpacing ( spacing ); image->Allocate(); //Obtaining image data from ToF camera// //Correlate inten values to PixelIndex// ItkImageRegionIteratorType2D imageIterator(image,image->GetLargestPossibleRegion()); imageIterator.GoToBegin(); itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randomGenerator = itk::Statistics::MersenneTwisterRandomVariateGenerator::New(); while (!imageIterator.IsAtEnd()) { double pixelValue = randomGenerator->GetUniformVariate(0.0,1000.0); imageIterator.Set(pixelValue); ++imageIterator; } mitk::Image::Pointer mitkImage = mitk::Image::New(); mitk::CastToMitkImage(image,mitkImage); return mitkImage; } static bool CompareImages(mitk::Image::Pointer image1, mitk::Image::Pointer image2) { //check if epsilon is exceeded unsigned int sliceDimension = image1->GetDimension(0)*image1->GetDimension(1); bool picturesEqual = true; float* floatArray1 = (float*)image1->GetSliceData(0, 0, 0)->GetData(); float* floatArray2 = (float*)image2->GetSliceData(0, 0, 0)->GetData(); for(unsigned int i = 0; i < sliceDimension; i++) { if(!(mitk::Equal(floatArray1[i], floatArray2[i]))) { picturesEqual = false; } } return picturesEqual; } /**Documentation * test for the class "ToFImageRecorderFilter". */ int mitkToFImageRecorderFilterTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("ToFImageRecorder"); mitk::ToFImageRecorderFilter::Pointer tofImageRecorderFilter = mitk::ToFImageRecorderFilter::New(); std::string dirName = MITK_TOF_DATA_DIR; MITK_TEST_OUTPUT(<< "Test SetFileName()"); - std::string testFileName = dirName + "test.pic"; + std::string testFileName = dirName + "test.nrrd"; MITK_TEST_FOR_EXCEPTION_BEGIN(std::logic_error); tofImageRecorderFilter->SetFileName(testFileName); MITK_TEST_FOR_EXCEPTION_END(std::logic_error); testFileName = dirName + "test.nrrd"; tofImageRecorderFilter->SetFileName(testFileName); mitk::ToFImageWriter::Pointer tofImageWriter = tofImageRecorderFilter->GetToFImageWriter(); std::string requiredName = dirName + "test_DistanceImage.nrrd"; std::string name = tofImageWriter->GetDistanceImageFileName(); MITK_TEST_CONDITION_REQUIRED(requiredName==name,"Test for distance image file name"); requiredName = dirName + "test_AmplitudeImage.nrrd"; name = tofImageWriter->GetAmplitudeImageFileName(); MITK_TEST_CONDITION_REQUIRED(requiredName==name,"Test for amplitude image file name"); requiredName = dirName + "test_IntensityImage.nrrd"; name = tofImageWriter->GetIntensityImageFileName(); MITK_TEST_CONDITION_REQUIRED(requiredName==name,"Test for intensity image file name"); mitk::Image::Pointer testDistanceImage = CreateTestImage(200,200); mitk::Image::Pointer testAmplitudeImage = CreateTestImage(200,200); mitk::Image::Pointer testIntensityImage = CreateTestImage(200,200); MITK_TEST_OUTPUT(<< "Apply filter"); tofImageRecorderFilter->StartRecording(); tofImageRecorderFilter->SetInput(0,testDistanceImage); tofImageRecorderFilter->SetInput(1,testAmplitudeImage); tofImageRecorderFilter->SetInput(2,testIntensityImage); tofImageRecorderFilter->Update(); MITK_TEST_OUTPUT(<< "Test outputs of filter"); mitk::Image::Pointer outputDistanceImage = tofImageRecorderFilter->GetOutput(); MITK_TEST_CONDITION_REQUIRED(CompareImages(testDistanceImage,outputDistanceImage),"Test output 0 (distance image)"); mitk::Image::Pointer outputAmplitudeImage = tofImageRecorderFilter->GetOutput(1); MITK_TEST_CONDITION_REQUIRED(CompareImages(testAmplitudeImage,outputAmplitudeImage),"Test output 1 (amplitude image)"); mitk::Image::Pointer outputIntensityImage = tofImageRecorderFilter->GetOutput(2); MITK_TEST_CONDITION_REQUIRED(CompareImages(testIntensityImage,outputIntensityImage),"Test output 2 (intensity image)"); tofImageRecorderFilter->StopRecording(); MITK_TEST_OUTPUT(<< "Test content of written files"); mitk::ItkImageFileReader::Pointer imageReader = mitk::ItkImageFileReader::New(); std::string testDistanceImageName = dirName + "test_DistanceImage.nrrd"; imageReader->SetFileName(testDistanceImageName); imageReader->Update(); mitk::Image::Pointer loadedDistanceImage = imageReader->GetOutput(); MITK_TEST_CONDITION_REQUIRED(CompareImages(testDistanceImage,loadedDistanceImage),"Test loaded image 0 (distance image)"); std::string testAmplitudeImageName = dirName + "test_AmplitudeImage.nrrd"; imageReader->SetFileName(testAmplitudeImageName); imageReader->Update(); mitk::Image::Pointer loadedAmplitudeImage = imageReader->GetOutput(); MITK_TEST_CONDITION_REQUIRED(CompareImages(testAmplitudeImage,loadedAmplitudeImage),"Test loaded image 1 (amplitude image)"); std::string testIntensityImageName = dirName + "test_IntensityImage.nrrd"; imageReader->SetFileName(testIntensityImageName); imageReader->Update(); mitk::Image::Pointer loadedIntensityImage = imageReader->GetOutput(); MITK_TEST_CONDITION_REQUIRED(CompareImages(testIntensityImage,loadedIntensityImage),"Test loaded image 2 (intensity image)"); //clean up and delete saved image files if( remove( testDistanceImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: test_DistanceImage.nrrd not successfully deleted!"; } if( remove( testAmplitudeImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: test_AmplitudeImage.nrrd not successfully deleted!"; } if( remove( testIntensityImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: test_IntensityImage.nrrd not successfully deleted!"; } MITK_TEST_END(); } diff --git a/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp b/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp index aee449e21f..87d6b72f1c 100644 --- a/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp @@ -1,155 +1,155 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkImage.h> #include <mitkTestingMacros.h> #include <mitkImageSliceSelector.h> #include <mitkTestFixture.h> #include <mitkToFImageRecorder.h> #include <mitkToFCameraMITKPlayerDevice.h> #include <mitkToFConfig.h> #include <mitkIOUtil.h> class mitkToFImageRecorderTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToFImageRecorderTestSuite); //See bug #12997 // MITK_TEST(StartRecording_ValidDepthImage_WritesImageToFile); // MITK_TEST(StartRecording_ValidAmplitudeImage_WritesImageToFile); // MITK_TEST(StartRecording_ValidIntensityImage_WritesImageToFile); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different (sub-)tests. All members are initialized via setUp(). * Every recorder needs a device. Here we use a player device. * The player device needs data to load. The ground truth is loaded via IOUtil. */ mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; mitk::ToFCameraMITKPlayerDevice::Pointer m_PlayerDevice; std::string m_DistanceImageName; std::string m_AmplitudeImageName; std::string m_IntensityImageName; mitk::Image::Pointer m_GroundTruthDepthImage; mitk::Image::Pointer m_GroundTruthIntensityImage; mitk::Image::Pointer m_GroundTruthAmplitudeImage; public: /** * @brief Setup a recorder including a device. Here, we use a player, because in an automatic test * hardware is not useful. */ void setUp() override { m_ToFImageRecorder = mitk::ToFImageRecorder::New(); m_DistanceImageName = mitk::IOUtil::CreateTemporaryFile(); m_AmplitudeImageName = mitk::IOUtil::CreateTemporaryFile(); m_IntensityImageName = mitk::IOUtil::CreateTemporaryFile(); //The recorder would automatically append the default extension ".nrrd" //but we have to append it here, because the data is later loaded with //IOUtil which does not know what kind of data to load/look for. m_DistanceImageName.append("Distance.nrrd"); m_AmplitudeImageName.append("Amplitude.nrrd"); m_IntensityImageName.append("Intensity.nrrd"); m_PlayerDevice = mitk::ToFCameraMITKPlayerDevice::New(); m_ToFImageRecorder->SetCameraDevice(m_PlayerDevice); //the test data set has 20 frames, so we record 20 per default m_ToFImageRecorder->SetNumOfFrames(20); m_ToFImageRecorder->SetRecordMode(mitk::ToFImageRecorder::PerFrames); std::string dirName = MITK_TOF_DATA_DIR; - std::string distanceFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_DistanceImage.pic"; - std::string amplitudeFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.pic"; - std::string intensityFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_IntensityImage.pic"; + std::string distanceFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_DistanceImage.nrrd"; + std::string amplitudeFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.nrrd"; + std::string intensityFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_IntensityImage.nrrd"; m_PlayerDevice->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName)); m_PlayerDevice->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName)); m_PlayerDevice->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName)); //comparing against IOUtil seems fair enough m_GroundTruthDepthImage = mitk::IOUtil::Load<mitk::Image>(distanceFileName); m_GroundTruthAmplitudeImage = mitk::IOUtil::Load<mitk::Image>(amplitudeFileName); m_GroundTruthIntensityImage = mitk::IOUtil::Load<mitk::Image>(intensityFileName); m_PlayerDevice->ConnectCamera(); m_PlayerDevice->StartCamera(); } void tearDown() override { m_PlayerDevice->StopCamera(); m_PlayerDevice->DisconnectCamera(); } void StartRecording_ValidDepthImage_WritesImageToFile() { m_ToFImageRecorder->SetDistanceImageFileName(m_DistanceImageName); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); m_ToFImageRecorder->StopRecording(); mitk::Image::Pointer recordedImage = mitk::IOUtil::Load<mitk::Image>(m_DistanceImageName); MITK_ASSERT_EQUAL( m_GroundTruthDepthImage, recordedImage, "Recorded image should be equal to the test data."); //delete the tmp image if( remove( m_DistanceImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: "<< m_DistanceImageName << " not successfully deleted!"; } } void StartRecording_ValidAmplitudeImage_WritesImageToFile() { m_ToFImageRecorder->SetAmplitudeImageFileName(m_AmplitudeImageName); m_ToFImageRecorder->SetAmplitudeImageSelected(true); m_ToFImageRecorder->SetDistanceImageSelected(false); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); m_ToFImageRecorder->StopRecording(); mitk::Image::Pointer recordedImage = mitk::IOUtil::Load<mitk::Image>(m_AmplitudeImageName); MITK_ASSERT_EQUAL( m_GroundTruthAmplitudeImage, recordedImage, "Recorded image should be equal to the test data."); //delete the tmp image if( remove( m_AmplitudeImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: "<< m_AmplitudeImageName << " not successfully deleted!"; } } void StartRecording_ValidIntensityImage_WritesImageToFile() { m_ToFImageRecorder->SetIntensityImageFileName(m_IntensityImageName); m_ToFImageRecorder->SetIntensityImageSelected(true); m_ToFImageRecorder->SetDistanceImageSelected(false); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); m_ToFImageRecorder->StopRecording(); mitk::Image::Pointer recordedImage = mitk::IOUtil::Load<mitk::Image>(m_IntensityImageName); MITK_ASSERT_EQUAL( m_GroundTruthIntensityImage, recordedImage, "Recorded image should be equal to the test data."); //delete the tmp image if( remove( m_IntensityImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: "<< m_IntensityImageName << " not successfully deleted!"; } } }; MITK_TEST_SUITE_REGISTRATION(mitkToFImageRecorder) diff --git a/Modules/ToFHardware/Testing/mitkToFImageWriterTest.cpp b/Modules/ToFHardware/Testing/mitkToFImageWriterTest.cpp index 85aeebe0b0..96fe92b6ee 100644 --- a/Modules/ToFHardware/Testing/mitkToFImageWriterTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFImageWriterTest.cpp @@ -1,78 +1,78 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkTestingMacros.h> #include <mitkToFImageWriter.h> /**Documentation * test for the class "ToFImageWriter". */ int mitkToFImageWriterTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("ToFImageWriter"); //testing initialization of object mitk::ToFImageWriter::Pointer tofWriter = mitk::ToFImageWriter::New(); MITK_TEST_CONDITION_REQUIRED(tofWriter.GetPointer(), "Testing initialization of test object!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetExtension()!= "", "Test initialization of member extension!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetDistanceImageFileName()== "", "Test initialization of member distanceImageFileName!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetAmplitudeImageFileName()== "", "Test initialization of member amplitudeImageFileName!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetIntensityImageFileName()== "", "Test initialization of member intnensityImageFileName!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetDistanceImageSelected()==true, "Test initialization of member distanceImageSelected!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetAmplitudeImageSelected()==false, "Test initialization of member amplitudeImageSelected!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetIntensityImageSelected()==false, "Test initialization of member intensityImageSelected!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetRGBImageSelected()==false, "Test initialization of member rgbImageSelected!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetToFCaptureWidth()== 200, "Test initialization of member captureWidth!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetToFCaptureHeight()== 200, "Test initialization of member captureHeight!"); MITK_TEST_CONDITION_REQUIRED(tofWriter->GetToFImageType()== mitk::ToFImageWriter::ToFImageType3D, "Test initialization of member ToFImageType!"); //set member parameter and test again int dimX = 255; int dimY = 188; - std::string distanceImageFileName("distImg.pic"); - std::string amplitudeImageFileName("amplImg.pic"); - std::string intensityImageFileName("intImg.pic"); - std::string rgbImageFileName("rgbImg.pic"); + std::string distanceImageFileName("distImg.nrrd"); + std::string amplitudeImageFileName("amplImg.nrrd"); + std::string intensityImageFileName("intImg.nrrd"); + std::string rgbImageFileName("rgbImg.nrrd"); std::string fileExtension(".test"); bool distanceImageSelected = false; bool amplitudeImageSelected = false; bool intensityImageSelected = false; bool rgbImageSelected = false; tofWriter->SetToFCaptureWidth(dimX); tofWriter->SetToFCaptureHeight(dimY); tofWriter->SetDistanceImageFileName(distanceImageFileName); tofWriter->SetAmplitudeImageFileName(amplitudeImageFileName); tofWriter->SetIntensityImageFileName(intensityImageFileName); tofWriter->SetRGBImageFileName(rgbImageFileName); tofWriter->SetExtension(fileExtension); tofWriter->SetDistanceImageSelected(distanceImageSelected); tofWriter->SetAmplitudeImageSelected(amplitudeImageSelected); tofWriter->SetIntensityImageSelected(intensityImageSelected); tofWriter->SetRGBImageSelected(rgbImageSelected); tofWriter->SetToFImageType(mitk::ToFImageWriter::ToFImageType2DPlusT); MITK_TEST_CONDITION_REQUIRED(distanceImageFileName==tofWriter->GetDistanceImageFileName(), "Testing set/get distance image file name"); MITK_TEST_CONDITION_REQUIRED(amplitudeImageFileName==tofWriter->GetAmplitudeImageFileName(), "Testing set/get amplitude image file name"); MITK_TEST_CONDITION_REQUIRED(intensityImageFileName==tofWriter->GetIntensityImageFileName(), "Testing set/get intensity image file name"); MITK_TEST_CONDITION_REQUIRED(rgbImageFileName==tofWriter->GetRGBImageFileName(), "Testing set/get rgb image file name"); MITK_TEST_CONDITION_REQUIRED(dimX==tofWriter->GetToFCaptureWidth(), "Testing set/get CaptureWidth"); MITK_TEST_CONDITION_REQUIRED(dimY==tofWriter->GetToFCaptureHeight(), "Testing set/get CaptureHeight"); MITK_TEST_CONDITION_REQUIRED(distanceImageSelected==tofWriter->GetDistanceImageSelected(), "Testing set/get distance image selection"); MITK_TEST_CONDITION_REQUIRED(amplitudeImageSelected==tofWriter->GetAmplitudeImageSelected(), "Testing set/get amplitude image selection"); MITK_TEST_CONDITION_REQUIRED(intensityImageSelected==tofWriter->GetIntensityImageSelected(), "Testing set/get intensity image selection"); MITK_TEST_CONDITION_REQUIRED(rgbImageSelected==tofWriter->GetRGBImageSelected(), "Testing set/get rgb image selection"); MITK_TEST_CONDITION_REQUIRED(fileExtension==tofWriter->GetExtension(), "Testing set/get file extension"); MITK_TEST_CONDITION_REQUIRED(mitk::ToFImageWriter::ToFImageType2DPlusT==tofWriter->GetToFImageType(), "Testing set/get ToFImageType"); MITK_TEST_END(); } diff --git a/Modules/ToFHardware/Testing/mitkToFOpenCVImageGrabberTest.cpp b/Modules/ToFHardware/Testing/mitkToFOpenCVImageGrabberTest.cpp index fec7edbeea..2c650eeab1 100644 --- a/Modules/ToFHardware/Testing/mitkToFOpenCVImageGrabberTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFOpenCVImageGrabberTest.cpp @@ -1,97 +1,97 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkTestingMacros.h> #include <mitkToFOpenCVImageGrabber.h> #include <mitkImageDataItem.h> #include <mitkIOUtil.h> #include <mitkToFCameraMITKPlayerDevice.h> #include <mitkToFConfig.h> #include <mitkImagePixelReadAccessor.h> static bool CompareImages(mitk::Image::Pointer mitkImage, cv::Mat openCVImage) { float equal = true; if (static_cast<int>(mitkImage->GetDimension(0)) != openCVImage.cols || static_cast<int>(mitkImage->GetDimension(1)) != openCVImage.rows) { equal = false; } mitk::ImagePixelReadAccessor<float,2> imageAcces(mitkImage, mitkImage->GetSliceData(0)); for(int i=0; i<openCVImage.cols; i++) { for(int j=0; j<openCVImage.rows; j++) { itk::Index<2> currentIndex; currentIndex[0] = i; currentIndex[1] = j; float mitkImageValue = imageAcces.GetPixelByIndex(currentIndex); float openCVImageValue = openCVImage.at<float>(j,i); if (!mitk::Equal(mitkImageValue,openCVImageValue)) { equal = false; } } } return equal; } /**Documentation * test for the class "ToFOpenCVImageGrabber". */ int mitkToFOpenCVImageGrabberTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("ToFOpenCVImageGrabber"); std::string dirName = MITK_TOF_DATA_DIR; mitk::ToFImageGrabber::Pointer tofImageGrabber = mitk::ToFImageGrabber::New(); tofImageGrabber->SetCameraDevice(mitk::ToFCameraMITKPlayerDevice::New()); - std::string distanceFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_DistanceImage.pic"; + std::string distanceFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_DistanceImage.nrrd"; tofImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName)); - std::string amplitudeFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_AmplitudeImage.pic"; + std::string amplitudeFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_AmplitudeImage.nrrd"; tofImageGrabber->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName)); - std::string intensityFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_IntensityImage.pic"; + std::string intensityFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_IntensityImage.nrrd"; tofImageGrabber->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName)); tofImageGrabber->Update(); mitk::Image::Pointer image = mitk::IOUtil::Load<mitk::Image>(distanceFileName); try { mitk::ToFOpenCVImageGrabber::Pointer tofOpenCVImageGrabber = mitk::ToFOpenCVImageGrabber::New(); tofOpenCVImageGrabber->SetToFImageGrabber(tofImageGrabber); MITK_TEST_CONDITION_REQUIRED(tofImageGrabber==tofOpenCVImageGrabber->GetToFImageGrabber(),"Test Set/GetToFImageGrabber()"); MITK_TEST_OUTPUT(<<"Call StartCapturing()"); tofOpenCVImageGrabber->StartCapturing(); cv::Mat cvImage = tofOpenCVImageGrabber->GetImage(); MITK_TEST_CONDITION_REQUIRED(CompareImages(image,cvImage),"Test distance image"); image = mitk::IOUtil::Load<mitk::Image>(amplitudeFileName); tofOpenCVImageGrabber->SetImageType(1); cvImage = tofOpenCVImageGrabber->GetImage(); MITK_TEST_CONDITION_REQUIRED(CompareImages(image,cvImage),"Test amplitude image"); image = mitk::IOUtil::Load<mitk::Image>(intensityFileName); tofOpenCVImageGrabber->SetImageType(2); cvImage = tofOpenCVImageGrabber->GetImage(); MITK_TEST_CONDITION_REQUIRED(CompareImages(image,cvImage),"Test intensity image"); MITK_TEST_OUTPUT(<<"Call StopCapturing()"); tofOpenCVImageGrabber->StopCapturing(); } catch(std::exception &e) { MITK_INFO << "Exception is: " << e.what(); } MITK_TEST_END(); } diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp index c09e18eaa6..f825a93c61 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp @@ -1,333 +1,332 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include <mitkToFCameraMITKPlayerController.h> #include <itksys/SystemTools.hxx> // mitk includes #include "mitkIOUtil.h" -#include <mitkIpPic.h> #include "mitkImageReadAccessor.h" namespace mitk { ToFCameraMITKPlayerController::ToFCameraMITKPlayerController() : m_PixelNumber(0), m_RGBPixelNumber(0), m_NumberOfBytes(0), m_NumberOfRGBBytes(0), m_CaptureWidth(0), m_CaptureHeight(0), m_RGBCaptureWidth(0), m_RGBCaptureHeight(0), m_ConnectionCheck(false), m_InputFileName(""), m_ToFImageType(ToFImageType3D), m_DistanceImage(nullptr), m_AmplitudeImage(nullptr), m_IntensityImage(nullptr), m_RGBImage(nullptr), m_DistanceInfile(nullptr), m_AmplitudeInfile(nullptr), m_IntensityInfile(nullptr), m_RGBInfile(nullptr), m_IntensityArray(nullptr), m_DistanceArray(nullptr), m_AmplitudeArray(nullptr), m_RGBArray(nullptr), m_DistanceImageFileName(""), m_AmplitudeImageFileName(""), m_IntensityImageFileName(""), m_RGBImageFileName(""), m_PixelStartInFile(0), m_CurrentFrame(-1), m_NumOfFrames(0) { m_ImageStatus = std::vector<bool>(4,true); } ToFCameraMITKPlayerController::~ToFCameraMITKPlayerController() { this->CleanUp(); } void ToFCameraMITKPlayerController::CleanUp() { if(m_DistanceImage.IsNotNull()) { m_DistanceImage->ReleaseData(); m_DistanceImage = nullptr; } if(m_AmplitudeImage.IsNotNull()) { m_AmplitudeImage->ReleaseData(); m_AmplitudeImage = nullptr; } if(m_IntensityImage.IsNotNull()) { m_IntensityImage->ReleaseData(); m_IntensityImage = nullptr; } if(m_RGBImage.IsNotNull()) { m_RGBImage->ReleaseData(); m_RGBImage = nullptr; } delete[] this->m_DistanceArray; this->m_DistanceArray = nullptr; delete[] this->m_AmplitudeArray; this->m_AmplitudeArray = nullptr; delete[] this->m_IntensityArray; this->m_IntensityArray = nullptr; delete[] this->m_RGBArray; this->m_RGBArray = nullptr; this->m_DistanceImageFileName = ""; this->m_AmplitudeImageFileName = ""; this->m_IntensityImageFileName = ""; this->m_RGBImageFileName = ""; } bool ToFCameraMITKPlayerController::OpenCameraConnection() { if(!this->m_ConnectionCheck) { // reset the image status before connection m_ImageStatus = std::vector<bool>(4,true); try { if (this->m_DistanceImageFileName.empty() && this->m_AmplitudeImageFileName.empty() && this->m_IntensityImageFileName.empty() && this->m_RGBImageFileName.empty()) { throw std::logic_error("No image data file names set"); } if (!this->m_DistanceImageFileName.empty()) { m_DistanceImage = mitk::IOUtil::Load<mitk::Image>(this->m_DistanceImageFileName); } else { MITK_ERROR << "ToF distance image data file empty"; } if (!this->m_AmplitudeImageFileName.empty()) { m_AmplitudeImage = mitk::IOUtil::Load<mitk::Image>(this->m_AmplitudeImageFileName); } else { MITK_WARN << "ToF amplitude image data file empty"; } if (!this->m_IntensityImageFileName.empty()) { m_IntensityImage = mitk::IOUtil::Load<mitk::Image>(this->m_IntensityImageFileName); } else { MITK_WARN << "ToF intensity image data file empty"; } if (!this->m_RGBImageFileName.empty()) { m_RGBImage = mitk::IOUtil::Load<mitk::Image>(this->m_RGBImageFileName); } else { MITK_WARN << "ToF RGB image data file empty"; } // check if the opened files contained data if(m_DistanceImage.IsNull()) { m_ImageStatus.at(0) = false; } if(m_AmplitudeImage.IsNull()) { m_ImageStatus.at(1) = false; } if(m_IntensityImage.IsNull()) { m_ImageStatus.at(2) = false; } if(m_RGBImage.IsNull()) { m_ImageStatus.at(3) = false; } // Check for dimension type mitk::Image::Pointer infoImage = nullptr; if(m_ImageStatus.at(0)) { infoImage = m_DistanceImage; } else if (m_ImageStatus.at(1)) { infoImage = m_AmplitudeImage; } else if(m_ImageStatus.at(2)) { infoImage = m_IntensityImage; } else if(m_ImageStatus.at(3)) { infoImage = m_RGBImage; } if (infoImage->GetDimension() == 2) this->m_ToFImageType = ToFImageType2DPlusT; else if (infoImage->GetDimension() == 3) this->m_ToFImageType = ToFImageType3D; else if (infoImage->GetDimension() == 4) this->m_ToFImageType = ToFImageType2DPlusT; else throw std::logic_error("Error opening ToF data file: Invalid dimension."); this->m_CaptureWidth = infoImage->GetDimension(0); this->m_CaptureHeight = infoImage->GetDimension(1); this->m_PixelNumber = this->m_CaptureWidth*this->m_CaptureHeight; this->m_NumberOfBytes = this->m_PixelNumber * sizeof(float); if(m_RGBImage) { m_RGBCaptureWidth = m_RGBImage->GetDimension(0); m_RGBCaptureHeight = m_RGBImage->GetDimension(1); m_RGBPixelNumber = m_RGBCaptureWidth * m_RGBCaptureHeight; m_NumberOfRGBBytes = m_RGBPixelNumber * 3; } if (this->m_ToFImageType == ToFImageType2DPlusT) { this->m_NumOfFrames = infoImage->GetDimension(3); } else { this->m_NumOfFrames = infoImage->GetDimension(2); } // allocate buffer this->m_DistanceArray = new float[this->m_PixelNumber]; for(int i=0; i<this->m_PixelNumber; i++) {this->m_DistanceArray[i]=0.0;} this->m_AmplitudeArray = new float[this->m_PixelNumber]; for(int i=0; i<this->m_PixelNumber; i++) {this->m_AmplitudeArray[i]=0.0;} this->m_IntensityArray = new float[this->m_PixelNumber]; for(int i=0; i<this->m_PixelNumber; i++) {this->m_IntensityArray[i]=0.0;} this->m_RGBArray = new unsigned char[m_NumberOfRGBBytes]; for(int i=0; i<m_NumberOfRGBBytes; i++) {this->m_RGBArray[i]=0.0;} MITK_INFO << "NumOfFrames: " << this->m_NumOfFrames; this->m_ConnectionCheck = true; return this->m_ConnectionCheck; } catch(std::exception& e) { MITK_ERROR << "Error opening ToF data file " << this->m_InputFileName << " " << e.what(); throw std::logic_error("Error opening ToF data file"); return false; } } else return this->m_ConnectionCheck; } bool ToFCameraMITKPlayerController::CloseCameraConnection() { if (this->m_ConnectionCheck) { this->CleanUp(); this->m_ConnectionCheck = false; return true; } return false; } void ToFCameraMITKPlayerController::UpdateCamera() { this->m_CurrentFrame++; if(this->m_CurrentFrame >= this->m_NumOfFrames) { this->m_CurrentFrame = 0; } if(this->m_ImageStatus.at(0)) { this->AccessData(this->m_CurrentFrame, this->m_DistanceImage, this->m_DistanceArray); } if(this->m_ImageStatus.at(1)) { this->AccessData(this->m_CurrentFrame, this->m_AmplitudeImage, this->m_AmplitudeArray); } if(this->m_ImageStatus.at(2)) { this->AccessData(this->m_CurrentFrame, this->m_IntensityImage, this->m_IntensityArray); } if(this->m_ImageStatus.at(3)) { if(!this->m_ToFImageType) { ImageReadAccessor rgbAcc(m_RGBImage, m_RGBImage->GetSliceData(m_CurrentFrame)); memcpy(m_RGBArray, rgbAcc.GetData(), m_NumberOfRGBBytes ); } else if(this->m_ToFImageType) { ImageReadAccessor rgbAcc(m_RGBImage, m_RGBImage->GetVolumeData(m_CurrentFrame)); memcpy(m_RGBArray, rgbAcc.GetData(), m_NumberOfRGBBytes); } } itksys::SystemTools::Delay(50); } void ToFCameraMITKPlayerController::AccessData(int frame, Image::Pointer image, float* &data) { if(!this->m_ToFImageType) { ImageReadAccessor imgAcc(image, image->GetSliceData(frame)); memcpy(data, imgAcc.GetData(), this->m_NumberOfBytes ); } else if(this->m_ToFImageType) { ImageReadAccessor imgAcc(image, image->GetVolumeData(frame)); memcpy(data, imgAcc.GetData(), this->m_NumberOfBytes); } } void ToFCameraMITKPlayerController::GetAmplitudes(float* amplitudeArray) { memcpy(amplitudeArray, this->m_AmplitudeArray, this->m_NumberOfBytes); } void ToFCameraMITKPlayerController::GetIntensities(float* intensityArray) { memcpy(intensityArray, this->m_IntensityArray, this->m_NumberOfBytes); } void ToFCameraMITKPlayerController::GetDistances(float* distanceArray) { memcpy(distanceArray, this->m_DistanceArray, this->m_NumberOfBytes); } void ToFCameraMITKPlayerController::GetRgb(unsigned char* rgbArray) { memcpy(rgbArray, this->m_RGBArray, m_NumberOfRGBBytes); } void ToFCameraMITKPlayerController::SetInputFileName(std::string inputFileName) { this->m_InputFileName = inputFileName; } } diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.h b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.h index 49dbb49184..eb1eb707a6 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.h +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.h @@ -1,142 +1,142 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef __mitkToFCameraMITKPlayerController_h #define __mitkToFCameraMITKPlayerController_h #include <MitkToFHardwareExports.h> #include "mitkCommon.h" #include "mitkFileReader.h" #include "mitkImage.h" #include "itkObject.h" #include "itkObjectFactory.h" namespace mitk { /** - * @brief Controller for playing ToF images saved in MITK (.pic) format + * @brief Controller for playing ToF images saved in NRRD format * * @ingroup ToFHardware */ class MITKTOFHARDWARE_EXPORT ToFCameraMITKPlayerController : public itk::Object { public: mitkClassMacroItkParent( ToFCameraMITKPlayerController , itk::Object ); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /*! \brief opens a connection to the ToF camera \return Returns 'true' if connection could be established and 'false' otherwise */ virtual bool OpenCameraConnection(); /*! \brief closes the connection to the camera \return Returns 'true' if connection could be closed (i.e. only if a connection was established before) and 'false' otherwise */ virtual bool CloseCameraConnection(); /*! \brief gets the current amplitude frame from the input These values can be used to determine the quality of the distance values. The higher the amplitude value, the higher the accuracy of the according distance value */ virtual void GetAmplitudes(float* amplitudeArray); /*! \brief gets the current intensity frame from the input as a greyscale image */ virtual void GetIntensities(float* intensityArray); /*! \brief gets the current distance frame from the inpug measuring the distance between the camera and the different object points in millimeters */ virtual void GetDistances(float* distanceArray); /*! \brief gets the current RGB frame from the input if available */ virtual void GetRgb(unsigned char* rgbArray); /*! \brief updates the current image frames from input */ virtual void UpdateCamera(); virtual void SetInputFileName(std::string inputFileName); itkGetMacro(PixelNumber, int); itkGetMacro(RGBPixelNumber, int); itkGetMacro(CaptureWidth, int); itkGetMacro(CaptureHeight, int); itkGetMacro(RGBCaptureWidth, int); itkGetMacro(RGBCaptureHeight, int); itkGetMacro( DistanceImageFileName, std::string ); itkGetMacro( AmplitudeImageFileName, std::string ); itkGetMacro( IntensityImageFileName, std::string ); itkGetMacro( RGBImageFileName, std::string ); itkSetMacro( DistanceImageFileName, std::string ); itkSetMacro( AmplitudeImageFileName, std::string ); itkSetMacro( IntensityImageFileName, std::string ); itkSetMacro( RGBImageFileName, std::string ); enum ToFImageType{ ToFImageType3D, ToFImageType2DPlusT }; protected: ToFCameraMITKPlayerController(); ~ToFCameraMITKPlayerController() override; int m_PixelNumber; ///< holds the number of pixels contained in the image int m_RGBPixelNumber; ///< same for RGB image int m_NumberOfBytes; ///< holds the number of bytes contained in the image int m_NumberOfRGBBytes; ///< same for RGB image int m_CaptureWidth; ///< holds the width of the image int m_CaptureHeight; ///< holds the height of the image int m_RGBCaptureWidth; ///< same for RGB image which can be different then depth etc. int m_RGBCaptureHeight; ///< same for RGB image which can be different then depth etc. bool m_ConnectionCheck; ///< flag showing whether the camera is connected (true) or not (false) std::string m_InputFileName; ToFImageType m_ToFImageType; ///< type of the ToF image to be played: 3D Volume (ToFImageType3D), temporal 2D image stack (ToFImageType2DPlusT) Image::Pointer m_DistanceImage; Image::Pointer m_AmplitudeImage; Image::Pointer m_IntensityImage; Image::Pointer m_RGBImage; std::vector<bool> m_ImageStatus; FILE* m_DistanceInfile; ///< file holding the distance data FILE* m_AmplitudeInfile; ///< file holding the amplitude data FILE* m_IntensityInfile; ///< file holding the intensity data FILE* m_RGBInfile; ///< file holding the rgb data float* m_IntensityArray; ///< member holding the current intensity frame float* m_DistanceArray; ///< member holding the current distance frame float* m_AmplitudeArray; ///< member holding the current amplitude frame unsigned char* m_RGBArray; ///< member holding the current rgb frame std::string m_DistanceImageFileName; ///< file name of the distance image to be played std::string m_AmplitudeImageFileName; ///< file name of the amplitude image to be played std::string m_IntensityImageFileName; ///< file name of the intensity image to be played std::string m_RGBImageFileName; ///< file name of the rgb image to be played long m_PixelStartInFile; int m_CurrentFrame; int m_NumOfFrames; private: void AccessData(int frame, Image::Pointer image, float* &data); void CleanUp(); }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFImageWriter.h b/Modules/ToFHardware/mitkToFImageWriter.h index 3d499612d5..33e7f49fef 100644 --- a/Modules/ToFHardware/mitkToFImageWriter.h +++ b/Modules/ToFHardware/mitkToFImageWriter.h @@ -1,130 +1,130 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef __mitkToFImageWriter_h #define __mitkToFImageWriter_h #include <MitkToFHardwareExports.h> #include "mitkCommon.h" #include "mitkToFImageGrabber.h" #include "itkObject.h" #include "itkObjectFactory.h" namespace mitk { /** * @brief Writer class for ToF images * - * This writer class allows streaming of ToF data into a file. The .pic file format is used for writing the data. - * Image information is included in the header of the pic file. + * This writer class allows streaming of ToF data into a file. + * Image information is included in the header of the nrrd file. * Writer can simultaneously save "distance", "intensity" and "amplitude" image. * Images can be written as 3D volume (ToFImageType::ToFImageType3D) or temporal image stack (ToFImageType::ToFImageType2DPlusT) * * @ingroup ToFHardware */ class MITKTOFHARDWARE_EXPORT ToFImageWriter : public itk::Object { public: ToFImageWriter(); ~ToFImageWriter() override; mitkClassMacroItkParent( ToFImageWriter , itk::Object ); itkFactorylessNewMacro(Self); itkCloneMacro(Self); itkGetMacro( DistanceImageFileName, std::string ); itkGetMacro( AmplitudeImageFileName, std::string ); itkGetMacro( IntensityImageFileName, std::string ); itkGetMacro( RGBImageFileName, std::string ); itkGetMacro( Extension, std::string ); itkGetMacro( ToFCaptureWidth, int ); itkGetMacro( ToFCaptureHeight, int ); itkGetMacro( RGBCaptureWidth, int ); itkGetMacro( RGBCaptureHeight, int ); itkGetMacro( DistanceImageSelected, bool ); itkGetMacro( AmplitudeImageSelected, bool ); itkGetMacro( IntensityImageSelected, bool ); itkGetMacro( RGBImageSelected, bool ); itkSetMacro( DistanceImageFileName, std::string ); itkSetMacro( AmplitudeImageFileName, std::string ); itkSetMacro( IntensityImageFileName, std::string ); itkSetMacro( RGBImageFileName, std::string ); itkSetMacro( Extension, std::string ); itkSetMacro( ToFCaptureWidth, int ); itkSetMacro( ToFCaptureHeight, int ); itkSetMacro( RGBCaptureWidth, int ); itkSetMacro( RGBCaptureHeight, int ); itkSetMacro( DistanceImageSelected, bool ); itkSetMacro( AmplitudeImageSelected, bool ); itkSetMacro( IntensityImageSelected, bool ); itkSetMacro( RGBImageSelected, bool ); enum ToFImageType{ ToFImageType3D, ToFImageType2DPlusT }; /*! \brief Get the type of image to be written \return ToF image type: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ ToFImageWriter::ToFImageType GetToFImageType(); /*! \brief Set the type of image to be written \param toFImageType type of the ToF image: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ void SetToFImageType(ToFImageWriter::ToFImageType toFImageType); /*! \brief Open file(s) for writing */ virtual void Open(){}; /*! - \brief Close file(s) add .pic header and write + \brief Close file(s) add header and write */ virtual void Close(){}; /*! \brief Add new data to file. */ virtual void Add(float* /*distanceFloatData*/, float* /*amplitudeFloatData*/, float* /*intensityFloatData*/, unsigned char* /*rgbData*/=nullptr){}; protected: /*! \brief Checks file name if file extension exists. If not an error message is returned */ void CheckForFileExtension(std::string& fileName); // member variables std::string m_Extension; ///< file extension used for saving images std::string m_DistanceImageFileName; ///< file name for saving the distance image std::string m_AmplitudeImageFileName; ///< file name for saving the amplitude image std::string m_IntensityImageFileName; ///< file name for saving the intensity image std::string m_RGBImageFileName; ///< file name for saving the RGB image int m_NumOfFrames; ///< number of frames written to the image. Used for pic header. bool m_DistanceImageSelected; ///< flag indicating if distance image should be recorded bool m_AmplitudeImageSelected; ///< flag indicating if amplitude image should be recorded bool m_IntensityImageSelected; ///< flag indicating if intensity image should be recorded bool m_RGBImageSelected; ///< flag indicating if RGB image should be recorded int m_ToFCaptureWidth; ///< width (x-dimension) of the images to record. int m_ToFCaptureHeight; ///< height (y-dimension) of the images to record. int m_RGBCaptureWidth; ///< width (x-dimension) of the images to record. int m_RGBCaptureHeight; ///< height (y-dimension) of the images to record. int m_ToFPixelNumber; ///< number of pixels (widht*height) of the images to record int m_ToFImageSizeInBytes; ///< size of the image to save in bytes int m_RGBPixelNumber; ///< number of pixels (widht*height) of the images to record int m_RGBImageSizeInBytes; ///< size of the image to save in bytes ToFImageWriter::ToFImageType m_ToFImageType; ///< type of image to be recorded: ToFImageType3D (0) or ToFImageType2DPlusT (1) }; } //END mitk namespace #endif // __mitkToFImageWriter_h diff --git a/Modules/ToFHardware/mitkToFNrrdImageWriter.h b/Modules/ToFHardware/mitkToFNrrdImageWriter.h index c6872000c8..f940eaf9d1 100644 --- a/Modules/ToFHardware/mitkToFNrrdImageWriter.h +++ b/Modules/ToFHardware/mitkToFNrrdImageWriter.h @@ -1,77 +1,77 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef __mitkToFNrrdImageWriter_h #define __mitkToFNrrdImageWriter_h #include <MitkToFHardwareExports.h> #include "mitkToFImageWriter.h" #include <fstream> namespace mitk { /** * @brief Writer class for ToF nrrd images * * This writer class allows streaming of ToF data into a nrrd file. This class uses the itkNrrdImageIO class * Writer can simultaneously save "distance", "intensity" and "amplitude" image. * Images can be written as 3D volume (ToFImageType::ToFImageType3D) or temporal image stack (ToFImageType::ToFImageType2DPlusT) * * @ingroup ToFHardware */ class MITKTOFHARDWARE_EXPORT ToFNrrdImageWriter : public ToFImageWriter { public: mitkClassMacro( ToFNrrdImageWriter , ToFImageWriter ); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /*! \brief Open file(s) for writing */ void Open() override; /*! - \brief Close file(s) add .pic header and write + \brief Close file(s) add header and write */ void Close() override; /*! \brief Add new data to file. */ void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData=nullptr) override; protected: std::ofstream m_DistanceOutfile; ///< file for distance image std::ofstream m_AmplitudeOutfile; ///< file for amplitude image std::ofstream m_IntensityOutfile; ///< file for intensity image std::ofstream m_RGBOutfile; ///< file for intensity image private: ToFNrrdImageWriter(); ~ToFNrrdImageWriter() override; /*! \brief Open file by filename to gain write access to it. */ void OpenStreamFile(std::ofstream &outfile, std::string outfileName); /*! \brief Close file after work on it is finished. */ void CloseStreamFile(std::ofstream &outfile, std::string fileName); /*! \brief Write image information to the NrrdFile. */ void ConvertStreamToNrrdFormat( std::string fileName ); }; } //END mitk namespace #endif // __mitkToFNrrdImageWriter_h diff --git a/Modules/ToFProcessing/Testing/CMakeLists.txt b/Modules/ToFProcessing/Testing/CMakeLists.txt index 237d89c83a..201eeca560 100644 --- a/Modules/ToFProcessing/Testing/CMakeLists.txt +++ b/Modules/ToFProcessing/Testing/CMakeLists.txt @@ -1,10 +1,10 @@ MITK_CREATE_MODULE_TESTS() if(TARGET ${TESTDRIVER}) mitkAddCustomModuleTest(mitkKinectReconstructionTest_LegoPhantom mitkKinectReconstructionTest ${MITK_DATA_DIR}/ToF-Data/CalibrationFiles/Kinect_RGB_camera.xml #camera intrinsics ${MITK_DATA_DIR}/ToF-Data/Kinect_Lego_Phantom_DistanceImage.nrrd #kinect distance image ) - #mitkAddCustomModuleTest(mitkToFImageDownsamplingFilterTest_20 mitkToFImageDownsamplingFilterTest PMDCamCube2_MF0_IT0_20Images_DistanceImage.pic) - #mitkAddCustomModuleTest(mitkToFImageDownsamplingFilterTest_1 mitkToFImageDownsamplingFilterTest PMDCamCube2_MF0_IT0_1Images_DistanceImage.pic) + #mitkAddCustomModuleTest(mitkToFImageDownsamplingFilterTest_20 mitkToFImageDownsamplingFilterTest PMDCamCube2_MF0_IT0_20Images_DistanceImage.nrrd) + #mitkAddCustomModuleTest(mitkToFImageDownsamplingFilterTest_1 mitkToFImageDownsamplingFilterTest PMDCamCube2_MF0_IT0_1Images_DistanceImage.nrrd) endif() diff --git a/Modules/ToFProcessing/Testing/mitkToFImageDownsamplingFilterTest.cpp b/Modules/ToFProcessing/Testing/mitkToFImageDownsamplingFilterTest.cpp index 2b2cc6c754..34976928ed 100644 --- a/Modules/ToFProcessing/Testing/mitkToFImageDownsamplingFilterTest.cpp +++ b/Modules/ToFProcessing/Testing/mitkToFImageDownsamplingFilterTest.cpp @@ -1,92 +1,81 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ //mitk includes #include <mitkTestingMacros.h> #include <mitkPicFileReader.h> #include <mitkPicFileWriter.h> #include <mitkToFConfig.h> #include "mitkToFImageDownsamplingFilter.h" // creator class that provides pre-configured ToFCameraDevices int mitkToFImageDownsamplingFilterTest(int argc , char* argv[]) { MITK_TEST_BEGIN("mitkToFImageDownSamplingFilterFilter"); MITK_TEST_CONDITION_REQUIRED(argc>=1, "Missing Parameters"); //Defining constants const int XDIM = 127; const int YDIM = 96; const int ZDIM = 19; // always start with this // create a new instance of filter and new image mitk::ToFImageDownsamplingFilter::Pointer testDownSampler = mitk::ToFImageDownsamplingFilter::New(); // make sure new filter ins't null MITK_TEST_CONDITION_REQUIRED(testDownSampler.IsNotNull(), "Testing instantiation!"); // Load ToF image MITK_INFO<<"Loading test image file: " << argv[1] << "\n"; // update with proper path and figure out how iti s passed from the test driver mitk::PicFileReader::Pointer reader = mitk::PicFileReader::New(); std::string filename = MITK_TOF_DATA_DIR; filename.append("/"); filename.append(argv[1]); reader->SetFileName(filename); reader->Update(); mitk::Image::Pointer image = reader->GetOutput(); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "Testing image reading"); MITK_INFO << "Original image dimensions " << image->GetDimension (0)<<" " << image->GetDimension(1)<< " " << image->GetDimension(2) ; //call filter testDownSampler->SetInput(image); testDownSampler->SetResampledX(XDIM); testDownSampler->SetResampledY(YDIM); testDownSampler->SetResampledZ(ZDIM); if(image->GetDimension(0) >= XDIM && image->GetDimension(1)>=YDIM && image->GetDimension(2)>=ZDIM && (image->GetDimension()==2 || image->GetDimension()==3)) { testDownSampler->Update(); mitk::Image::Pointer resultImage = testDownSampler->GetOutput(); MITK_TEST_CONDITION_REQUIRED(resultImage->GetDimension(0) == XDIM && resultImage->GetDimension(1)==YDIM &&resultImage->GetDimension(2)==ZDIM, "Test result image dimensions with 3D image"); MITK_INFO << "new image dimensions " << resultImage->GetDimension (0)<<" " << resultImage->GetDimension(1)<<" " << resultImage->GetDimension(2) ; } else { MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject); testDownSampler->Update(); MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject); } - - - // Mean for debugging purposes if you want to write the resutling image to a file - //mitk::PicFileWriter::Pointer writer = mitk::PicFileWriter::New(); - //writer->SetInputImage( resultImage); - //writer->SetFileName( "tofResult1.pic" ); - - //writer->Update(); - - // always end with this! MITK_TEST_END(); } - diff --git a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp index 4566a20c8f..611eb548a0 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp @@ -1,393 +1,393 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ //#define _USE_MATH_DEFINES #include <QmitkToFConnectionWidget.h> //QT headers #include <qmessagebox.h> #include <qfiledialog.h> #include <qcombobox.h> //mitk headers #include "mitkToFConfig.h" #include "mitkCameraIntrinsics.h" #include "mitkCameraIntrinsicsProperty.h" //itk headers #include <itksys/SystemTools.hxx> //Setting the View_ID const std::string QmitkToFConnectionWidget::VIEW_ID = "org.mitk.views.qmitktofconnectionwidget2"; //Constructor of QmitkToFConnectionWidget QmitkToFConnectionWidget::QmitkToFConnectionWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) , m_Controls(nullptr) , m_IntegrationTime(0) , m_ModulationFrequency(0) , m_SelectedCameraName("") { this->m_ToFImageGrabber = mitk::ToFImageGrabber::New(); //Calling CreateQtPartControl CreateQtPartControl(this); } //Destructor of QmitkToFConnectionWidget QmitkToFConnectionWidget::~QmitkToFConnectionWidget() { //MitkServiceListWidget must not be deinizialized here. Qmitk methods destroy their children automatically before self-destruction } void QmitkToFConnectionWidget::CreateQtPartControl(QWidget *parent) //Definition of CreateQtPartControll-Methode in QmitkToFConnectionWidget; Input= Pointer { if (!m_Controls) //Define if not alreaddy exists { // create GUI widgets m_Controls = new Ui::QmitkToFConnectionWidgetControls2; m_Controls->setupUi(parent); //and hide them on startup this->HideAllParameterWidgets(); // initzializing MitkServiceListWidget here std::string empty= ""; m_Controls->m_DeviceList->Initialize<mitk::ToFCameraDevice>("ToFDeviceName", empty);// the empty could just be any kind of filter this->CreateConnections(); } } //Creating the SIGNAL-SLOT-Connectuions void QmitkToFConnectionWidget::CreateConnections() { if ( m_Controls ) { //ConnectCameraButton as a trigger for OnConnectCamera() connect( (QObject*)(m_Controls->m_ConnectCameraButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnConnectCamera()) ); //QmitkServiceListWidget::ServiceSelectionChanged as a Signal for the OnSlectCamera() slot connect( m_Controls->m_DeviceList, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnSelectCamera())); /*Creating an other Datanode structur for Kinect is done here: As soon as a Kinect is connected, the KinectParameterWidget is enabled, which can be used to trigger the KinectAcqusitionModeChanged-Method, to create a working Data-Node-structure*/ connect( m_Controls->m_KinectParameterWidget, SIGNAL(AcquisitionModeChanged()), this, SIGNAL(KinectAcquisitionModeChanged()) ); } } mitk::ToFImageGrabber::Pointer QmitkToFConnectionWidget::GetToFImageGrabber() { return m_ToFImageGrabber; } //The OnSelectCamer-Method is in charge of activating the appropiate ParameterWidgets void QmitkToFConnectionWidget::OnSelectCamera() { //Here we are getting our decvie through the QmitkServiceListWidget-Instance m_DeviceList through the GetSelectedService-Method mitk::ToFCameraDevice* device = m_Controls->m_DeviceList->GetSelectedService<mitk::ToFCameraDevice>(); //getting the selectedCamera through a static Method used to transform the device->GetNameOfClass QString selectedCamera = QString::fromStdString(device->GetNameOfClass()); this->HideAllParameterWidgets(); //reactivating the Widgets on slecting a device if (selectedCamera.contains("PMD")) //Check if selectedCamera string contains ".." for each device { this->m_Controls->m_PMDParameterWidget->show(); //and activate the correct widget } else if (selectedCamera.contains("MESA")) { this->m_Controls->m_MESAParameterWidget->show(); } else if (selectedCamera.contains("Kinect")) { this->m_Controls->m_KinectParameterWidget->show(); } else if (selectedCamera.contains("Structure")) { this->m_Controls->m_StructureParameterWidget->show(); } m_Controls->m_ConnectCameraButton->setEnabled(true); //ConnectCameraButton gets enabled m_SelectedCameraName = selectedCamera; } //This Methods hides all Widgets (later each widget is activated on its own) void QmitkToFConnectionWidget::HideAllParameterWidgets() { this->m_Controls->m_PMDParameterWidget->hide(); this->m_Controls->m_MESAParameterWidget->hide(); this->m_Controls->m_KinectParameterWidget->hide(); this->m_Controls->m_StructureParameterWidget->hide(); } //OnConnectCamera-Method; represents one of the main parts of ToFConnectionWidget2. void QmitkToFConnectionWidget::OnConnectCamera() { //After connecting a device if (m_Controls->m_ConnectCameraButton->text()=="Connect") { //Getting the device- and the slectedCamera-variables using the ServiceListWidget as we did it in the CameraSelect-Method mitk::ToFCameraDevice* device = m_Controls->m_DeviceList->GetSelectedService<mitk::ToFCameraDevice>(); if (device) { QString tmpFileName(""); QString fileFilter(""); QString selectedCamera = QString::fromStdString(device->GetNameOfClass()); emit ToFCameraSelected(selectedCamera); //Feeding it with the Info from ServiceListWidget this->m_ToFImageGrabber->SetCameraDevice(device); if (selectedCamera.contains("Kinect") ) { //If the particular property is selected, the suitable data-node will be generated this->m_ToFImageGrabber->SetBoolProperty("RGB", m_Controls->m_KinectParameterWidget->IsAcquisitionModeRGB()); this->m_ToFImageGrabber->SetBoolProperty("IR", m_Controls->m_KinectParameterWidget->IsAcquisitionModeIR()); } if (selectedCamera.contains("Structure") ) { this->m_ToFImageGrabber->SetIntProperty("RGBResolution", m_Controls->m_StructureParameterWidget->GetSelectedResolution()); this->m_ToFImageGrabber->SetIntProperty("DepthResolution", m_Controls->m_StructureParameterWidget->GetSelectedResolution()); } //Activation of "PlayerMode". If the selectedCamera String contains "Player", we start the Player Mode if (selectedCamera.contains("Player")) { //IF PMD-Player selected if (selectedCamera.contains("PMD")) { fileFilter.append("PMD Files (*.pmd)"); //And seting the corresponding fileFilter } else { - fileFilter.append("NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic)"); + fileFilter.append("NRRD Images (*.nrrd)"); } //open a QFileDialog to chose the corresponding file from the disc tmpFileName = QFileDialog::getOpenFileName(nullptr, "Play Image From...", "", fileFilter); //If no fileName is returned by the Dialog,Button and Widget have to return to default(disconnected) + Opening a MessageBox if (tmpFileName.isEmpty()) { m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); //re-enabling the ConnectCameraButton m_Controls->m_DeviceList->setEnabled(true); //Reactivating ServiceListWidget this->OnSelectCamera(); //Calling the OnSelctCamera-Method -> Hides all Widget and just activates the needed ones QMessageBox::information( this, "Template functionality", "Please select a valid image before starting some action."); return; } if(selectedCamera.contains("PMDPlayer")) //If PMD-Player is selected, set ToFImageGrabberProperty correspondingly { this->m_ToFImageGrabber->SetStringProperty("PMDFileName", tmpFileName.toStdString().c_str() ); } else //Default action { std::string msg = ""; try { //get 3 corresponding file names std::string dir = itksys::SystemTools::GetFilenamePath( tmpFileName.toStdString() ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( tmpFileName.toStdString() ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( tmpFileName.toStdString() ); - //"Incorrect format"-warning while using .nrrd or .pic files - if (extension != ".pic" && extension != ".nrrd") + //"Incorrect format"-warning while using .nrrd files + if (extension != ".nrrd") { msg = msg + "Invalid file format, please select a \".nrrd\"-file"; throw std::logic_error(msg.c_str()); } //Checking for npos. If available, check for the Amplitude-, Intensity- and RGBImage int found = baseFilename.rfind("_DistanceImage"); //Defining "found" variable+checking if baseFilname contains "_DistanceImage". If not, found == npos(0) if (found == static_cast<int>(std::string::npos)) //If found =0 { found = baseFilename.rfind("_AmplitudeImage"); //If "_AmplitudeImage" is found, the found variable is 1-> the next if statment is false } if (found == static_cast<int>(std::string::npos)) { found = baseFilename.rfind("_IntensityImage"); //found = true if baseFilename cotains "_IntesityImage" } if (found == static_cast<int>(std::string::npos)) { found = baseFilename.rfind("_RGBImage"); } if (found == static_cast<int>(std::string::npos)) //If none of the Nodes is found, display an error { msg = msg + "Input file name must end with \"_DistanceImage\", \"_AmplitudeImage\", \"_IntensityImage\" or \"_RGBImage\"!"; throw std::logic_error(msg.c_str()); } std::string baseFilenamePrefix = baseFilename.substr(0,found);//Set the baseFilenamePrefix as a substring from baseFilname //Set corresponding FileNames std::string distanceImageFileName = dir + "/" + baseFilenamePrefix + "_DistanceImage" + extension; //Set the name as: directory+FilenamePrefix+""+extension std::string amplitudeImageFileName = dir + "/" + baseFilenamePrefix + "_AmplitudeImage" + extension; std::string intensityImageFileName = dir + "/" + baseFilenamePrefix + "_IntensityImage" + extension; std::string rgbImageFileName = dir + "/" + baseFilenamePrefix + "_RGBImage" + extension; if (!itksys::SystemTools::FileExists(distanceImageFileName.c_str(), true)) { this->m_ToFImageGrabber->SetStringProperty("DistanceImageFileName", ""); } else { this->m_ToFImageGrabber->SetStringProperty("DistanceImageFileName", distanceImageFileName.c_str()); } if (!itksys::SystemTools::FileExists(amplitudeImageFileName.c_str(), true)) { } else { this->m_ToFImageGrabber->SetStringProperty("AmplitudeImageFileName", amplitudeImageFileName.c_str()); } if (!itksys::SystemTools::FileExists(intensityImageFileName.c_str(), true)) { this->m_ToFImageGrabber->SetStringProperty("IntensityImageFileName", ""); } else { this->m_ToFImageGrabber->SetStringProperty("IntensityImageFileName", intensityImageFileName.c_str()); } if (!itksys::SystemTools::FileExists(rgbImageFileName.c_str(), true)) { this->m_ToFImageGrabber->SetStringProperty("RGBImageFileName", ""); } else { this->m_ToFImageGrabber->SetStringProperty("RGBImageFileName", rgbImageFileName.c_str()); } } catch (std::exception &e) { MITK_ERROR << e.what(); QMessageBox::critical( this, "Error", e.what() ); m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_DeviceList->setEnabled(true); this->OnSelectCamera(); return; } } } //End "PlayerMode" //Reset the ConnectCameraButton to disconnected m_Controls->m_ConnectCameraButton->setText("Disconnect"); //if a connection could be established try { if (this->m_ToFImageGrabber->ConnectCamera()) { this->m_Controls->m_PMDParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); this->m_Controls->m_MESAParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); this->m_Controls->m_KinectParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); this->m_Controls->m_StructureParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); //Activating the respective widgets if (selectedCamera.contains("PMD")) { this->m_Controls->m_PMDParameterWidget->ActivateAllParameters(); } else if (selectedCamera.contains("MESA")) { this->m_Controls->m_MESAParameterWidget->ActivateAllParameters(); } else if (selectedCamera.contains("Kinect")) { this->m_Controls->m_KinectParameterWidget->ActivateAllParameters(); } else if (selectedCamera.contains("Structure")) { this->m_Controls->m_StructureParameterWidget->ActivateAllParameters(); } else { this->HideAllParameterWidgets(); } // send connect signal to the caller functionality emit ToFCameraConnected(); } else //##### TODO: Remove this else part once all controllers are throwing exceptions //if they cannot to any device! { //Throw an error if the Connection failed and reset the Widgets <- better catch an exception! QMessageBox::critical( this, "Error", "Connection failed. Check if you have installed the latest driver for your system." ); m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_ConnectCameraButton->setText("Connect"); m_Controls->m_DeviceList->setEnabled(true); //Reactivating ServiceListWidget this->OnSelectCamera(); return; } }catch(std::exception &e) { //catch exceptions of camera which cannot connect give a better reason QMessageBox::critical( this, "Connection failed.", e.what() ); m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_ConnectCameraButton->setText("Connect"); m_Controls->m_DeviceList->setEnabled(true); //Reactivating ServiceListWidget this->OnSelectCamera(); return; } m_Controls->m_ConnectCameraButton->setEnabled(true); // ask wether camera parameters (intrinsics, ...) should be loaded if (QMessageBox::question(this,"Camera parameters","Do you want to specify your own camera intrinsics?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes) { try { QString fileName = QFileDialog::getOpenFileName(this,"Open camera intrinsics","/","*.xml"); mitk::CameraIntrinsics::Pointer cameraIntrinsics = mitk::CameraIntrinsics::New(); cameraIntrinsics->FromXMLFile(fileName.toStdString()); this->m_ToFImageGrabber->SetProperty("CameraIntrinsics",mitk::CameraIntrinsicsProperty::New(cameraIntrinsics)); } catch ( std::exception &e ) { MITK_WARN << "Error loading camera intrinsics: " << e.what(); } } ////Reset the status of some GUI-Elements m_Controls->m_DeviceList->setEnabled(false); //Deactivating the Instance of QmitkServiceListWidget //repaint the widget this->repaint(); } else { QMessageBox::information(this,"Camera connection","No camera selected, please select a range camera"); m_Controls->m_ConnectCameraButton->setChecked(false); } } else if (m_Controls->m_ConnectCameraButton->text()=="Disconnect") { this->m_ToFImageGrabber->StopCamera(); this->m_ToFImageGrabber->DisconnectCamera(); m_Controls->m_ConnectCameraButton->setText("Connect"); m_Controls->m_DeviceList->setEnabled(true); //Reactivating ServiceListWidget this->OnSelectCamera(); // send disconnect signal to the caller functionality emit ToFCameraDisconnected(); } } void QmitkToFConnectionWidget::ConnectCamera() { this->m_Controls->m_ConnectCameraButton->animateClick(); } diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp index db6e4ff9a2..a33addeb80 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp @@ -1,423 +1,415 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #define _USE_MATH_DEFINES #include "QmitkToFRecorderWidget.h" //QT headers #include <QMessageBox> #include <QComboBox> #include <QLabel> #include <QLayout> #include <QGridLayout> #include <QCheckBox> #include <QFileDialog> //mitk headers #include <mitkToFImageWriter.h> //itk headers #pragma GCC visibility push(default) #include <itkEventObject.h> #pragma GCC visibility pop #include <itksys/SystemTools.hxx> struct QFileDialogArgs; class QFileDialogPrivate; const std::string QmitkToFRecorderWidget::VIEW_ID = "org.mitk.views.qmitktofrecorderwidget"; QmitkToFRecorderWidget::QmitkToFRecorderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { this->m_ToFImageRecorder = nullptr; this->m_ToFImageGrabber = nullptr; this->m_RecordMode = mitk::ToFImageRecorder::PerFrames; this-> m_Controls = nullptr; CreateQtPartControl(this); } QmitkToFRecorderWidget::~QmitkToFRecorderWidget() { } void QmitkToFRecorderWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets this->m_Controls = new Ui::QmitkToFRecorderWidgetControls; this->m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkToFRecorderWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_PlayButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPlay()) ); connect( (QObject*)(m_Controls->m_StopButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStop()) ); connect( (QObject*)(m_Controls->m_StartRecordingButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStartRecorder()) ); connect( (QObject*)(m_Controls->m_RecordModeComboBox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnChangeRecordModeComboBox(int)) ); connect(this, SIGNAL(RecordingStopped()), this, SLOT(OnRecordingStopped()), Qt::BlockingQueuedConnection); } } void QmitkToFRecorderWidget::SetParameter(mitk::ToFImageGrabber* toFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder) { this->m_ToFImageGrabber = toFImageGrabber; this->m_ToFImageRecorder = toFImageRecorder; this->m_StopRecordingCommand = CommandType::New(); this->m_StopRecordingCommand->SetCallbackFunction(this, &QmitkToFRecorderWidget::StopRecordingCallback); this->m_ToFImageRecorder->RemoveAllObservers(); this->m_ToFImageRecorder->AddObserver(itk::AbortEvent(), this->m_StopRecordingCommand); m_Controls->m_PlayButton->setChecked(false); m_Controls->m_PlayButton->setEnabled(true); m_Controls->m_StartRecordingButton->setChecked(false); m_Controls->m_RecorderGroupBox->setEnabled(true); } void QmitkToFRecorderWidget::StopRecordingCallback() { emit RecordingStopped(); } void QmitkToFRecorderWidget::ResetGUIToInitial() { m_Controls->m_PlayButton->setChecked(false); m_Controls->m_PlayButton->setEnabled(true); m_Controls->m_RecorderGroupBox->setEnabled(false); } void QmitkToFRecorderWidget::OnRecordingStopped() { m_Controls->m_StartRecordingButton->setChecked(false); m_Controls->m_RecorderGroupBox->setEnabled(true); } void QmitkToFRecorderWidget::OnStop() { StopCamera(); StopRecorder(); ResetGUIToInitial(); emit ToFCameraStopped(); } void QmitkToFRecorderWidget::OnPlay() { m_Controls->m_PlayButton->setChecked(true); m_Controls->m_PlayButton->setEnabled(false); m_Controls->m_RecorderGroupBox->setEnabled(true); this->repaint(); StartCamera(); emit ToFCameraStarted(); } void QmitkToFRecorderWidget::StartCamera() { if (!m_ToFImageGrabber->IsCameraActive()) { m_ToFImageGrabber->StartCamera(); } } void QmitkToFRecorderWidget::StopCamera() { if( m_ToFImageGrabber.IsNotNull() ) m_ToFImageGrabber->StopCamera(); } void QmitkToFRecorderWidget::StopRecorder() { if( m_ToFImageRecorder.IsNotNull() ) { this->m_ToFImageRecorder->StopRecording(); } } void QmitkToFRecorderWidget::OnStartRecorder() { m_Controls->m_StartRecordingButton->setChecked(true); m_Controls->m_RecorderGroupBox->setEnabled(false); this->repaint(); int numOfFrames = m_Controls->m_NumOfFramesSpinBox->value(); try { bool fileOK = true; bool distanceImageSelected = true; bool amplitudeImageSelected = false; bool intensityImageSelected = false; bool rgbImageSelected = false; bool rawDataSelected = false; //Set check boxes in dialog according to device properties m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasAmplitudeImage",amplitudeImageSelected); m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasIntensityImage",intensityImageSelected); m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasRGBImage",rgbImageSelected); QString tmpFileName(""); QString selectedFilter(""); QString imageFileName(""); mitk::ToFImageWriter::ToFImageType tofImageType; tmpFileName = QmitkToFRecorderWidget::getSaveFileName(tofImageType, distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rgbImageSelected, rawDataSelected, - nullptr, "Save Image To...", imageFileName, "NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic);;Text (*.csv)", &selectedFilter); + nullptr, "Save Image To...", imageFileName, "NRRD Images (*.nrrd);;Text (*.csv)", &selectedFilter); if (tmpFileName.isEmpty()) { fileOK = false; } else { imageFileName = tmpFileName; } if (fileOK) { std::string dir = itksys::SystemTools::GetFilenamePath( imageFileName.toStdString() ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( imageFileName.toStdString() ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( imageFileName.toStdString() ); int integrationTime = this->m_ToFImageGrabber->GetIntegrationTime(); int modulationFreq = this->m_ToFImageGrabber->GetModulationFrequency(); QString integrationTimeStr; integrationTimeStr.setNum(integrationTime); QString modulationFreqStr; modulationFreqStr.setNum(modulationFreq); QString numOfFramesStr(""); if (this->m_RecordMode == mitk::ToFImageRecorder::PerFrames) { numOfFramesStr.setNum(numOfFrames); } std::string distImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_DistanceImage"); MITK_INFO << "Save distance data to: " << distImageFileName; std::string amplImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_AmplitudeImage"); MITK_INFO << "Save amplitude data to: " << amplImageFileName; std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_IntensityImage"); MITK_INFO << "Save intensity data to: " << intenImageFileName; std::string rgbImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_RGBImage"); MITK_INFO << "Save intensity data to: " << rgbImageFileName; if (selectedFilter.compare("Text (*.csv)") == 0) { this->m_ToFImageRecorder->SetFileFormat(".csv"); } - else if (selectedFilter.compare("PIC Images - deprecated (*.pic)") == 0) - { - //default - this->m_ToFImageRecorder->SetFileFormat(".pic"); - - QMessageBox::warning(nullptr, "Deprecated File Format!", - "Please note that *.pic file format is deprecated and not longer supported! The suggested file format for images is *.nrrd!"); - } else if (selectedFilter.compare("NRRD Images (*.nrrd)") == 0) { this->m_ToFImageRecorder->SetFileFormat(".nrrd"); } else { QMessageBox::warning(nullptr, "Unsupported file format!", "Please specify one of the supported file formats *.nrrd, *.csv!"); return; } numOfFrames = m_Controls->m_NumOfFramesSpinBox->value(); this->m_ToFImageRecorder->SetDistanceImageFileName(distImageFileName); this->m_ToFImageRecorder->SetAmplitudeImageFileName(amplImageFileName); this->m_ToFImageRecorder->SetIntensityImageFileName(intenImageFileName); this->m_ToFImageRecorder->SetRGBImageFileName(rgbImageFileName); this->m_ToFImageRecorder->SetToFImageType(tofImageType); this->m_ToFImageRecorder->SetDistanceImageSelected(distanceImageSelected); this->m_ToFImageRecorder->SetAmplitudeImageSelected(amplitudeImageSelected); this->m_ToFImageRecorder->SetIntensityImageSelected(intensityImageSelected); this->m_ToFImageRecorder->SetRGBImageSelected(rgbImageSelected); this->m_ToFImageRecorder->SetRecordMode(this->m_RecordMode); this->m_ToFImageRecorder->SetNumOfFrames(numOfFrames); emit RecordingStarted(); this->m_ToFImageRecorder->StartRecording(); } else { this->OnRecordingStopped(); } } catch(std::exception& e) { QMessageBox::critical(nullptr, "Error", QString(e.what())); this->OnRecordingStopped(); } } QString QmitkToFRecorderWidget::getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType, bool& distanceImageSelected, bool& amplitudeImageSelected, bool& intensityImageSelected, bool& rgbImageSelected, bool& rawDataSelected, QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options ) { QString selectedFileName = ""; QComboBox* combo = new QComboBox; combo->addItem("3D"); combo->addItem("2D + t"); QHBoxLayout* checkBoxGroup = new QHBoxLayout(); QCheckBox* distanceImageCheckBox = new QCheckBox; distanceImageCheckBox->setText("Distance image"); distanceImageCheckBox->setChecked(distanceImageSelected); QCheckBox* amplitudeImageCheckBox = new QCheckBox; amplitudeImageCheckBox->setText("Amplitude image"); amplitudeImageCheckBox->setChecked(amplitudeImageSelected); amplitudeImageCheckBox->setEnabled(amplitudeImageSelected); if(!amplitudeImageSelected) amplitudeImageCheckBox->setToolTip(QString("This device does not provide amplitude data.")); QCheckBox* intensityImageCheckBox = new QCheckBox; intensityImageCheckBox->setText("Intensity image"); intensityImageCheckBox->setChecked(intensityImageSelected); intensityImageCheckBox->setEnabled(intensityImageSelected); if(!intensityImageSelected) intensityImageCheckBox->setToolTip(QString("This device does not provide intensity data.")); QCheckBox* rgbImageCheckBox = new QCheckBox; rgbImageCheckBox->setText("RGB image"); rgbImageCheckBox->setChecked(rgbImageSelected); rgbImageCheckBox->setEnabled(rgbImageSelected); if(!rgbImageSelected) rgbImageCheckBox->setToolTip(QString("This device does not provide RGB data.")); QCheckBox* rawDataCheckBox = new QCheckBox; rawDataCheckBox->setText("Raw data"); rawDataCheckBox->setChecked(false); rawDataCheckBox->setEnabled(false); checkBoxGroup->addWidget(distanceImageCheckBox); checkBoxGroup->addWidget(amplitudeImageCheckBox); checkBoxGroup->addWidget(intensityImageCheckBox); checkBoxGroup->addWidget(rgbImageCheckBox); checkBoxGroup->addWidget(rawDataCheckBox); QFileDialog* fileDialog = new QFileDialog(parent, caption, dir, filter); QLayout* layout = fileDialog->layout(); QGridLayout* gridbox = qobject_cast<QGridLayout*>(layout); if (gridbox) { gridbox->addWidget(new QLabel("ToF-Image type:")); gridbox->addWidget(combo); int lastRow = gridbox->rowCount(); gridbox->addLayout(checkBoxGroup, lastRow, 0, 1, -1); } fileDialog->setLayout(gridbox); fileDialog->setAcceptMode(QFileDialog::AcceptSave); if (selectedFilter) { fileDialog->selectNameFilter(*selectedFilter); } if (fileDialog->exec() == QDialog::Accepted) { if (selectedFilter) { *selectedFilter = fileDialog->selectedNameFilter(); } if (combo->currentIndex() == 0) { tofImageType = mitk::ToFImageWriter::ToFImageType3D; } else { tofImageType = mitk::ToFImageWriter::ToFImageType2DPlusT; } distanceImageSelected = distanceImageCheckBox->isChecked(); amplitudeImageSelected = amplitudeImageCheckBox->isChecked(); intensityImageSelected = intensityImageCheckBox->isChecked(); rgbImageSelected = rgbImageCheckBox->isChecked(); rawDataSelected = rawDataCheckBox->isChecked(); selectedFileName = fileDialog->selectedFiles().value(0); } delete fileDialog; return selectedFileName; } std::string QmitkToFRecorderWidget::prepareFilename(std::string dir, std::string baseFilename, std::string modulationFreq, std::string integrationTime, std::string numOfFrames, std::string extension, std::string imageType) { std::string filenName(""); filenName.append(dir); filenName.append("/"); filenName.append(baseFilename); filenName.append("_MF"); filenName.append(modulationFreq); filenName.append("_IT"); filenName.append(integrationTime); filenName.append("_"); filenName.append(numOfFrames); filenName.append("Images"); filenName.append(imageType); filenName.append(extension); return filenName; } void QmitkToFRecorderWidget::OnChangeRecordModeComboBox(int index) { if (index == 0) { this->m_RecordMode = mitk::ToFImageRecorder::PerFrames; m_Controls->m_NumOfFramesSpinBox->setEnabled(true); } else { this->m_RecordMode = mitk::ToFImageRecorder::Infinite; m_Controls->m_NumOfFramesSpinBox->setEnabled(false); } } diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp index 1790e3da27..f6cc560a7e 100644 --- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp +++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp @@ -1,1345 +1,1345 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkBasicImageProcessingView.h" // QT includes (GUI) #include <qlabel.h> #include <qspinbox.h> #include <qpushbutton.h> #include <qcheckbox.h> #include <qgroupbox.h> #include <qradiobutton.h> #include <qmessagebox.h> // MITK includes (general) #include <mitkNodePredicateDataType.h> #include <mitkNodePredicateDimension.h> #include <mitkNodePredicateNot.h> #include <mitkNodePredicateOr.h> #include <mitkNodePredicateProperty.h> #include <mitkImageTimeSelector.h> #include <mitkVectorImageMapper2D.h> #include <mitkProperties.h> #include <mitkLevelWindowProperty.h> #include <mitkImageStatisticsHolder.h> // Includes for image casting between ITK and MITK #include <mitkImageCast.h> #include <mitkITKImageImport.h> // ITK includes (general) #include <itkVectorImage.h> #include <itkImageFileWriter.h> // Morphological Operations #include <itkBinaryBallStructuringElement.h> #include <itkGrayscaleDilateImageFilter.h> #include <itkGrayscaleErodeImageFilter.h> #include <itkGrayscaleMorphologicalOpeningImageFilter.h> #include <itkGrayscaleMorphologicalClosingImageFilter.h> // Smoothing #include <itkMedianImageFilter.h> #include <itkDiscreteGaussianImageFilter.h> #include <itkTotalVariationDenoisingImageFilter.h> // Threshold #include <itkBinaryThresholdImageFilter.h> // Inversion #include <itkInvertIntensityImageFilter.h> // Derivatives #include <itkGradientMagnitudeRecursiveGaussianImageFilter.h> #include <itkLaplacianImageFilter.h> #include <itkSobelEdgeDetectionImageFilter.h> // Resampling #include <itkResampleImageFilter.h> #include <itkNearestNeighborInterpolateImageFunction.h> #include <itkBSplineInterpolateImageFunction.h> #include <itkCastImageFilter.h> #include <itkLinearInterpolateImageFunction.h> // Image Arithmetics #include <itkAddImageFilter.h> #include <itkSubtractImageFilter.h> #include <itkMultiplyImageFilter.h> #include <itkDivideImageFilter.h> // Boolean operations #include <itkOrImageFilter.h> #include <itkAndImageFilter.h> #include <itkXorImageFilter.h> // Flip Image #include <itkFlipImageFilter.h> #include <itkRescaleIntensityImageFilter.h> #include <itkShiftScaleImageFilter.h> // Convenient Definitions typedef itk::Image<short, 3> ImageType; typedef itk::Image<unsigned char, 3> SegmentationImageType; typedef itk::Image<double, 3> DoubleImageType; typedef itk::Image<itk::Vector<float,3>, 3> VectorImageType; typedef itk::BinaryBallStructuringElement<ImageType::PixelType, 3> BallType; typedef itk::GrayscaleDilateImageFilter<ImageType, ImageType, BallType> DilationFilterType; typedef itk::GrayscaleErodeImageFilter<ImageType, ImageType, BallType> ErosionFilterType; typedef itk::GrayscaleMorphologicalOpeningImageFilter<ImageType, ImageType, BallType> OpeningFilterType; typedef itk::GrayscaleMorphologicalClosingImageFilter<ImageType, ImageType, BallType> ClosingFilterType; typedef itk::MedianImageFilter< ImageType, ImageType > MedianFilterType; typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType> GaussianFilterType; typedef itk::TotalVariationDenoisingImageFilter<DoubleImageType, DoubleImageType> TotalVariationFilterType; typedef itk::TotalVariationDenoisingImageFilter<VectorImageType, VectorImageType> VectorTotalVariationFilterType; typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType; typedef itk::InvertIntensityImageFilter< ImageType, ImageType > InversionFilterType; typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType, ImageType > GradientFilterType; typedef itk::LaplacianImageFilter< DoubleImageType, DoubleImageType > LaplacianFilterType; typedef itk::SobelEdgeDetectionImageFilter< DoubleImageType, DoubleImageType > SobelFilterType; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType2; typedef itk::CastImageFilter< ImageType, DoubleImageType > ImagePTypeToFloatPTypeCasterType; typedef itk::AddImageFilter< ImageType, ImageType, ImageType > AddFilterType; typedef itk::SubtractImageFilter< ImageType, ImageType, ImageType > SubtractFilterType; typedef itk::MultiplyImageFilter< ImageType, ImageType, ImageType > MultiplyFilterType; typedef itk::DivideImageFilter< ImageType, ImageType, DoubleImageType > DivideFilterType; typedef itk::OrImageFilter< ImageType, ImageType > OrImageFilterType; typedef itk::AndImageFilter< ImageType, ImageType > AndImageFilterType; typedef itk::XorImageFilter< ImageType, ImageType > XorImageFilterType; typedef itk::FlipImageFilter< ImageType > FlipImageFilterType; typedef itk::LinearInterpolateImageFunction< ImageType, double > LinearInterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction< ImageType, double > NearestInterpolatorType; const std::string QmitkBasicImageProcessing::VIEW_ID = "org.mitk.views.basicimageprocessing"; QmitkBasicImageProcessing::QmitkBasicImageProcessing() : QmitkAbstractView() , m_Controls(new Ui::QmitkBasicImageProcessingViewControls) , m_TimeStepperAdapter(nullptr) { auto isImage = mitk::TNodePredicateDataType<mitk::Image>::New(); auto isNotHelperObject = mitk::NodePredicateNot::New( mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true))); auto dimensionPredicate = mitk::NodePredicateOr::New( mitk::NodePredicateDimension::New(3), mitk::NodePredicateDimension::New(4)); m_IsImagePredicate = mitk::NodePredicateAnd::New( isImage, isNotHelperObject, dimensionPredicate); } QmitkBasicImageProcessing::~QmitkBasicImageProcessing() { } void QmitkBasicImageProcessing::CreateQtPartControl(QWidget *parent) { m_Controls->setupUi(parent); m_Controls->selectedImageWidget->SetDataStorage(this->GetDataStorage()); m_Controls->selectedImageWidget->SetNodePredicate(m_IsImagePredicate); m_Controls->selectedImageWidget->SetSelectionIsOptional(true); m_Controls->selectedImageWidget->SetAutoSelectNewNodes(true); m_Controls->selectedImageWidget->SetEmptyInfo(QString("Please select a 3D / 4D image")); m_Controls->selectedImageWidget->SetPopUpTitel(QString("Select an image")); m_Controls->selectedImageWidget_2->SetDataStorage(this->GetDataStorage()); m_Controls->selectedImageWidget_2->SetNodePredicate(m_IsImagePredicate); m_Controls->selectedImageWidget_2->SetSelectionIsOptional(true); m_Controls->selectedImageWidget_2->SetAutoSelectNewNodes(true); m_Controls->selectedImageWidget_2->SetEmptyInfo(QString("Please select a 3D / 4D image")); m_Controls->selectedImageWidget_2->SetPopUpTitel(QString("Select an image")); m_Controls->gbTwoImageOps->hide(); m_Controls->cbWhat1->clear(); m_Controls->cbWhat1->insertItem(NOACTIONSELECTED, "Please select an operation"); m_Controls->cbWhat1->insertItem(CATEGORY_DENOISING, "--- Denoising ---"); m_Controls->cbWhat1->insertItem(GAUSSIAN, "Gaussian"); m_Controls->cbWhat1->insertItem(MEDIAN, "Median"); m_Controls->cbWhat1->insertItem(TOTALVARIATION, "Total Variation"); m_Controls->cbWhat1->insertItem(CATEGORY_MORPHOLOGICAL, "--- Morphological ---"); m_Controls->cbWhat1->insertItem(DILATION, "Dilation"); m_Controls->cbWhat1->insertItem(EROSION, "Erosion"); m_Controls->cbWhat1->insertItem(OPENING, "Opening"); m_Controls->cbWhat1->insertItem(CLOSING, "Closing"); m_Controls->cbWhat1->insertItem(CATEGORY_EDGE_DETECTION, "--- Edge Detection ---"); m_Controls->cbWhat1->insertItem(GRADIENT, "Gradient"); m_Controls->cbWhat1->insertItem(LAPLACIAN, "Laplacian (2nd Derivative)"); m_Controls->cbWhat1->insertItem(SOBEL, "Sobel Operator"); m_Controls->cbWhat1->insertItem(CATEGORY_MISC, "--- Misc ---"); m_Controls->cbWhat1->insertItem(THRESHOLD, "Threshold"); m_Controls->cbWhat1->insertItem(INVERSION, "Image Inversion"); m_Controls->cbWhat1->insertItem(DOWNSAMPLING, "Downsampling"); m_Controls->cbWhat1->insertItem(FLIPPING, "Flipping"); m_Controls->cbWhat1->insertItem(RESAMPLING, "Resample to"); m_Controls->cbWhat1->insertItem(RESCALE, "Rescale values to interval"); m_Controls->cbWhat1->insertItem(RESCALE2, "Rescale values by scalar"); m_Controls->cbWhat2->clear(); m_Controls->cbWhat2->insertItem(TWOIMAGESNOACTIONSELECTED, "Please select an operation"); m_Controls->cbWhat2->insertItem(CATEGORY_ARITHMETIC, "--- Arithmetric operations ---"); m_Controls->cbWhat2->insertItem(ADD, "Add to Image 1:"); m_Controls->cbWhat2->insertItem(SUBTRACT, "Subtract from Image 1:"); m_Controls->cbWhat2->insertItem(MULTIPLY, "Multiply with Image 1:"); m_Controls->cbWhat2->insertItem(RESAMPLE_TO, "Resample Image 1 to fit geometry:"); m_Controls->cbWhat2->insertItem(DIVIDE, "Divide Image 1 by:"); m_Controls->cbWhat2->insertItem(CATEGORY_BOOLEAN, "--- Boolean operations ---"); m_Controls->cbWhat2->insertItem(AND, "AND"); m_Controls->cbWhat2->insertItem(OR, "OR"); m_Controls->cbWhat2->insertItem(XOR, "XOR"); m_Controls->cbParam4->clear(); m_Controls->cbParam4->insertItem(LINEAR, "Linear"); m_Controls->cbParam4->insertItem(NEAREST, "Nearest neighbor"); m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); m_Controls->cbParam4->hide(); this->CreateConnections(); } void QmitkBasicImageProcessing::CreateConnections() { connect(m_Controls->cbWhat1, QOverload<int>::of(&QComboBox::activated), this, &QmitkBasicImageProcessing::SelectAction); connect(m_Controls->btnDoIt, &QPushButton::clicked, this, &QmitkBasicImageProcessing::StartButtonClicked); connect(m_Controls->cbWhat2, QOverload<int>::of(&QComboBox::activated), this, &QmitkBasicImageProcessing::SelectAction2); connect(m_Controls->btnDoIt2, &QPushButton::clicked, this, &QmitkBasicImageProcessing::StartButton2Clicked); connect(m_Controls->rBOneImOp, &QRadioButton::clicked, this, &QmitkBasicImageProcessing::ChangeGUI); connect(m_Controls->rBTwoImOp, &QRadioButton::clicked, this, &QmitkBasicImageProcessing::ChangeGUI); connect(m_Controls->cbParam4, QOverload<int>::of(&QComboBox::activated), this, &QmitkBasicImageProcessing::SelectInterpolator); connect(m_Controls->selectedImageWidget, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkBasicImageProcessing::OnCurrentSelectionChanged); connect(m_Controls->selectedImageWidget_2, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkBasicImageProcessing::OnCurrentSelectionChanged); } void QmitkBasicImageProcessing::InternalGetTimeNavigationController() { auto renwin_part = GetRenderWindowPart(); if( renwin_part != nullptr ) { auto tnc = renwin_part->GetTimeNavigationController(); if( tnc != nullptr ) { m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->sliceNavigatorTime, tnc->GetTime(), "sliceNavigatorTimeFromBIP"); } } } void QmitkBasicImageProcessing::SetFocus() { m_Controls->rBOneImOp->setFocus(); } void QmitkBasicImageProcessing::OnCurrentSelectionChanged(const QList<mitk::DataNode::Pointer>& nodes) { if (nodes.empty() || nodes.front().IsNull()) { m_Controls->sliceNavigatorTime->setEnabled(false); m_Controls->tlTime->setEnabled(false); m_Controls->tlWhat1->setEnabled(false); m_Controls->cbWhat1->setEnabled(false); m_Controls->tlWhat2->setEnabled(false); m_Controls->cbWhat2->setEnabled(false); return; } auto selectedImage = dynamic_cast<mitk::Image*>(nodes.front()->GetData()); if (nullptr == selectedImage) { return; } if (selectedImage->GetDimension() > 3) { // try to retrieve the TNC (for 4-D Processing ) this->InternalGetTimeNavigationController(); m_Controls->sliceNavigatorTime->setEnabled(true); m_Controls->tlTime->setEnabled(true); } m_Controls->tlWhat1->setEnabled(true); m_Controls->cbWhat1->setEnabled(true); m_Controls->tlWhat2->setEnabled(true); m_Controls->cbWhat2->setEnabled(true); } void QmitkBasicImageProcessing::ChangeGUI() { if(m_Controls->rBOneImOp->isChecked()) { m_Controls->gbTwoImageOps->hide(); m_Controls->gbOneImageOps->show(); } else if(m_Controls->rBTwoImOp->isChecked()) { m_Controls->gbOneImageOps->hide(); m_Controls->gbTwoImageOps->show(); } } void QmitkBasicImageProcessing::ResetParameterPanel() { m_Controls->tlParam->setEnabled(false); m_Controls->tlParam1->setEnabled(false); m_Controls->tlParam2->setEnabled(false); m_Controls->tlParam3->setEnabled(false); m_Controls->tlParam4->setEnabled(false); m_Controls->sbParam1->setEnabled(false); m_Controls->sbParam2->setEnabled(false); m_Controls->dsbParam1->setEnabled(false); m_Controls->dsbParam2->setEnabled(false); m_Controls->dsbParam3->setEnabled(false); m_Controls->cbParam4->setEnabled(false); m_Controls->sbParam1->setValue(0); m_Controls->sbParam2->setValue(0); m_Controls->dsbParam1->setValue(0); m_Controls->dsbParam2->setValue(0); m_Controls->dsbParam3->setValue(0); m_Controls->sbParam1->show(); m_Controls->sbParam2->show(); m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->cbParam4->hide(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); } void QmitkBasicImageProcessing::SelectAction(int action) { auto selectedImage = m_Controls->selectedImageWidget->GetSelectedNode(); if (selectedImage.IsNull()) { return; } // Prepare GUI this->ResetParameterPanel(); m_Controls->btnDoIt->setEnabled(false); m_Controls->cbHideOrig->setEnabled(false); QString text1 = tr("No Parameters"); QString text2 = text1; QString text3 = text1; QString text4 = text1; if (action != 19) { m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->tlParam1->show(); m_Controls->tlParam2->show(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); m_Controls->sbParam1->show(); m_Controls->sbParam2->show(); m_Controls->cbParam4->hide(); } switch (action) { case 2: { m_SelectedAction = GAUSSIAN; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->hide(); m_Controls->dsbParam1->show(); m_Controls->dsbParam1->setEnabled(true); text1 = tr("&Variance:"); m_Controls->tlParam2->hide(); m_Controls->sbParam2->hide(); m_Controls->dsbParam1->setMinimum( 0 ); m_Controls->dsbParam1->setMaximum( 200 ); m_Controls->dsbParam1->setValue( 2 ); break; } case 3: { m_SelectedAction = MEDIAN; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = tr("&Radius:"); m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 4: { m_SelectedAction = TOTALVARIATION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(true); text1 = tr("Number Iterations:"); text2 = tr("Regularization\n(Lambda/1000):"); m_Controls->sbParam1->setMinimum( 1 ); m_Controls->sbParam1->setMaximum( 1000 ); m_Controls->sbParam1->setValue( 40 ); m_Controls->sbParam2->setMinimum( 0 ); m_Controls->sbParam2->setMaximum( 100000 ); m_Controls->sbParam2->setValue( 1 ); break; } case 6: { m_SelectedAction = DILATION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = tr("&Radius:"); m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 7: { m_SelectedAction = EROSION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = tr("&Radius:"); m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 8: { m_SelectedAction = OPENING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = tr("&Radius:"); m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 9: { m_SelectedAction = CLOSING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = tr("&Radius:"); m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 11: { m_SelectedAction = GRADIENT; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->hide(); m_Controls->dsbParam1->show(); m_Controls->dsbParam1->setEnabled(true); text1 = tr("Sigma of Gaussian Kernel:\n(in Image Spacing Units)"); m_Controls->tlParam2->hide(); m_Controls->sbParam2->hide(); m_Controls->dsbParam1->setMinimum( 0 ); m_Controls->dsbParam1->setMaximum( 200 ); m_Controls->dsbParam1->setValue( 2 ); break; } case 12: { m_SelectedAction = LAPLACIAN; break; } case 13: { m_SelectedAction = SOBEL; break; } case 15: { m_SelectedAction = THRESHOLD; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(true); text1 = tr("Lower threshold:"); text2 = tr("Upper threshold:"); m_Controls->sbParam1->setMinimum( -100000 ); m_Controls->sbParam1->setMaximum( 100000 ); m_Controls->sbParam1->setValue( 0 ); m_Controls->sbParam2->setMinimum( -100000 ); m_Controls->sbParam2->setMaximum( 100000 ); m_Controls->sbParam2->setValue( 300 ); break; } case 16: { m_SelectedAction = INVERSION; break; } case 17: { m_SelectedAction = DOWNSAMPLING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = tr("Downsampling by Factor:"); m_Controls->sbParam1->setMinimum( 1 ); m_Controls->sbParam1->setMaximum( 100 ); m_Controls->sbParam1->setValue( 2 ); break; } case 18: { m_SelectedAction = FLIPPING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = tr("Flip across axis:"); m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 2 ); m_Controls->sbParam1->setValue( 1 ); break; } case 19: { m_SelectedAction = RESAMPLING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(false); m_Controls->sbParam1->hide(); m_Controls->dsbParam1->show(); m_Controls->dsbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(false); m_Controls->sbParam2->hide(); m_Controls->dsbParam2->show(); m_Controls->dsbParam2->setEnabled(true); m_Controls->tlParam3->show(); m_Controls->tlParam3->setEnabled(true); m_Controls->dsbParam3->show(); m_Controls->dsbParam3->setEnabled(true); m_Controls->tlParam4->show(); m_Controls->tlParam4->setEnabled(true); m_Controls->cbParam4->show(); m_Controls->cbParam4->setEnabled(true); m_Controls->dsbParam1->setMinimum(0.01); m_Controls->dsbParam1->setMaximum(10.0); m_Controls->dsbParam1->setSingleStep(0.1); m_Controls->dsbParam1->setValue(0.3); m_Controls->dsbParam2->setMinimum(0.01); m_Controls->dsbParam2->setMaximum(10.0); m_Controls->dsbParam2->setSingleStep(0.1); m_Controls->dsbParam2->setValue(0.3); m_Controls->dsbParam3->setMinimum(0.01); m_Controls->dsbParam3->setMaximum(10.0); m_Controls->dsbParam3->setSingleStep(0.1); m_Controls->dsbParam3->setValue(1.5); text1 = tr("x-spacing:"); text2 = tr("y-spacing:"); text3 = tr("z-spacing:"); text4 = tr("Interplation:"); break; } case 20: { m_SelectedAction = RESCALE; m_Controls->dsbParam1->show(); m_Controls->tlParam1->show(); m_Controls->dsbParam1->setEnabled(true); m_Controls->tlParam1->setEnabled(true); m_Controls->dsbParam2->show(); m_Controls->tlParam2->show(); m_Controls->dsbParam2->setEnabled(true); m_Controls->tlParam2->setEnabled(true); text1 = tr("Output minimum:"); text2 = tr("Output maximum:"); break; } case 21: { m_SelectedAction = RESCALE2; m_Controls->dsbParam1->show(); m_Controls->tlParam1->show(); m_Controls->dsbParam1->setEnabled(true); m_Controls->tlParam1->setEnabled(true); text1 = tr("Scaling value:"); break; } default: return; } m_Controls->tlParam->setEnabled(true); m_Controls->tlParam1->setText(text1); m_Controls->tlParam2->setText(text2); m_Controls->tlParam3->setText(text3); m_Controls->tlParam4->setText(text4); m_Controls->btnDoIt->setEnabled(true); m_Controls->cbHideOrig->setEnabled(true); } void QmitkBasicImageProcessing::StartButtonClicked() { auto selectedNode = m_Controls->selectedImageWidget->GetSelectedNode(); if (selectedNode.IsNull()) { return; } this->BusyCursorOn(); mitk::Image::Pointer newImage; try { newImage = dynamic_cast<mitk::Image*>(selectedNode->GetData()); } catch ( std::exception &e ) { QString exceptionString = tr("An error occured during image loading:\n"); exceptionString.append( e.what() ); QMessageBox::warning( nullptr, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton ); this->BusyCursorOff(); return; } // check if input image is valid, casting does not throw exception when casting from 'nullptr-Object' if ( (! newImage) || (newImage->IsInitialized() == false) ) { this->BusyCursorOff(); QMessageBox::warning( nullptr, "Basic Image Processing", tr("Input image is broken or not initialized. Returning."), QMessageBox::Ok, QMessageBox::NoButton ); return; } // check if operation is done on 4D a image time step if(newImage->GetDimension() > 3) { auto timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(newImage); timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() ); timeSelector->Update(); newImage = timeSelector->GetOutput(); } // check if image or vector image auto itkImage = ImageType::New(); auto itkVecImage = VectorImageType::New(); int isVectorImage = newImage->GetPixelType().GetNumberOfComponents(); if(isVectorImage > 1) { CastToItkImage( newImage, itkVecImage ); } else { CastToItkImage( newImage, itkImage ); } std::stringstream nameAddition(""); int param1 = m_Controls->sbParam1->value(); int param2 = m_Controls->sbParam2->value(); double dparam1 = m_Controls->dsbParam1->value(); double dparam2 = m_Controls->dsbParam2->value(); double dparam3 = m_Controls->dsbParam3->value(); try { switch (m_SelectedAction) { case GAUSSIAN: { GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New(); gaussianFilter->SetInput( itkImage ); gaussianFilter->SetVariance( dparam1 ); gaussianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone(); nameAddition << "_Gaussian_var_" << dparam1; std::cout << "Gaussian filtering successful." << std::endl; break; } case MEDIAN: { MedianFilterType::Pointer medianFilter = MedianFilterType::New(); MedianFilterType::InputSizeType size; size.Fill(param1); medianFilter->SetRadius( size ); medianFilter->SetInput(itkImage); medianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone(); nameAddition << "_Median_radius_" << param1; std::cout << "Median Filtering successful." << std::endl; break; } case TOTALVARIATION: { if(isVectorImage > 1) { VectorTotalVariationFilterType::Pointer TVFilter = VectorTotalVariationFilterType::New(); TVFilter->SetInput( itkVecImage.GetPointer() ); TVFilter->SetNumberIterations(param1); TVFilter->SetLambda(double(param2)/1000.); TVFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone(); } else { ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New(); floatCaster->SetInput( itkImage ); floatCaster->Update(); DoubleImageType::Pointer fImage = floatCaster->GetOutput(); TotalVariationFilterType::Pointer TVFilter = TotalVariationFilterType::New(); TVFilter->SetInput( fImage.GetPointer() ); TVFilter->SetNumberIterations(param1); TVFilter->SetLambda(double(param2)/1000.); TVFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone(); } nameAddition << "_TV_Iter_" << param1 << "_L_" << param2; std::cout << "Total Variation Filtering successful." << std::endl; break; } case DILATION: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); DilationFilterType::Pointer dilationFilter = DilationFilterType::New(); dilationFilter->SetInput( itkImage ); dilationFilter->SetKernel( binaryBall ); dilationFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone(); nameAddition << "_Dilated_by_" << param1; std::cout << "Dilation successful." << std::endl; break; } case EROSION: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New(); erosionFilter->SetInput( itkImage ); erosionFilter->SetKernel( binaryBall ); erosionFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone(); nameAddition << "_Eroded_by_" << param1; std::cout << "Erosion successful." << std::endl; break; } case OPENING: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); OpeningFilterType::Pointer openFilter = OpeningFilterType::New(); openFilter->SetInput( itkImage ); openFilter->SetKernel( binaryBall ); openFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone(); nameAddition << "_Opened_by_" << param1; std::cout << "Opening successful." << std::endl; break; } case CLOSING: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); ClosingFilterType::Pointer closeFilter = ClosingFilterType::New(); closeFilter->SetInput( itkImage ); closeFilter->SetKernel( binaryBall ); closeFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone(); nameAddition << "_Closed_by_" << param1; std::cout << "Closing successful." << std::endl; break; } case GRADIENT: { GradientFilterType::Pointer gradientFilter = GradientFilterType::New(); gradientFilter->SetInput( itkImage ); gradientFilter->SetSigma( dparam1 ); gradientFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone(); nameAddition << "_Gradient_sigma_" << dparam1; std::cout << "Gradient calculation successful." << std::endl; break; } case LAPLACIAN: { // the laplace filter requires a float type image as input, we need to cast the itkImage // to correct type ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New(); caster->SetInput( itkImage ); caster->Update(); DoubleImageType::Pointer fImage = caster->GetOutput(); LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New(); laplacianFilter->SetInput( fImage ); laplacianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone(); nameAddition << "_Second_Derivative"; std::cout << "Laplacian filtering successful." << std::endl; break; } case SOBEL: { // the sobel filter requires a float type image as input, we need to cast the itkImage // to correct type ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New(); caster->SetInput( itkImage ); caster->Update(); DoubleImageType::Pointer fImage = caster->GetOutput(); SobelFilterType::Pointer sobelFilter = SobelFilterType::New(); sobelFilter->SetInput( fImage ); sobelFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone(); nameAddition << "_Sobel"; std::cout << "Edge Detection successful." << std::endl; break; } case THRESHOLD: { ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New(); thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2); thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1); thFilter->SetInsideValue(1); thFilter->SetOutsideValue(0); thFilter->SetInput(itkImage); thFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone(); nameAddition << "_Threshold"; std::cout << "Thresholding successful." << std::endl; break; } case INVERSION: { InversionFilterType::Pointer invFilter = InversionFilterType::New(); mitk::ScalarType min = newImage->GetStatistics()->GetScalarValueMin(); mitk::ScalarType max = newImage->GetStatistics()->GetScalarValueMax(); invFilter->SetMaximum( max + min ); invFilter->SetInput(itkImage); invFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone(); nameAddition << "_Inverted"; std::cout << "Image inversion successful." << std::endl; break; } case DOWNSAMPLING: { ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New(); downsampler->SetInput( itkImage ); NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New(); downsampler->SetInterpolator( interpolator ); downsampler->SetDefaultPixelValue( 0 ); ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing(); spacing *= (double) param1; downsampler->SetOutputSpacing( spacing ); downsampler->SetOutputOrigin( itkImage->GetOrigin() ); downsampler->SetOutputDirection( itkImage->GetDirection() ); ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize(); for ( int i = 0; i < 3; ++i ) { size[i] /= param1; } downsampler->SetSize( size ); downsampler->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone(); nameAddition << "_Downsampled_by_" << param1; std::cout << "Downsampling successful." << std::endl; break; } case FLIPPING: { FlipImageFilterType::Pointer flipper = FlipImageFilterType::New(); flipper->SetInput( itkImage ); itk::FixedArray<bool, 3> flipAxes; for(int i=0; i<3; ++i) { if(i == param1) { flipAxes[i] = true; } else { flipAxes[i] = false; } } flipper->SetFlipAxes(flipAxes); flipper->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone(); std::cout << "Image flipping successful." << std::endl; break; } case RESAMPLING: { std::string selectedInterpolator; ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New(); switch (m_SelectedInterpolation) { case LINEAR: { LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Linear"; break; } case NEAREST: { NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Nearest"; break; } default: { LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Linear"; break; } } resampler->SetInput( itkImage ); resampler->SetOutputOrigin( itkImage->GetOrigin() ); ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize(); ImageType::SpacingType input_spacing = itkImage->GetSpacing(); ImageType::SizeType output_size; ImageType::SpacingType output_spacing; output_size[0] = input_size[0] * (input_spacing[0] / dparam1); output_size[1] = input_size[1] * (input_spacing[1] / dparam2); output_size[2] = input_size[2] * (input_spacing[2] / dparam3); output_spacing [0] = dparam1; output_spacing [1] = dparam2; output_spacing [2] = dparam3; resampler->SetSize( output_size ); resampler->SetOutputSpacing( output_spacing ); resampler->SetOutputDirection( itkImage->GetDirection() ); resampler->UpdateLargestPossibleRegion(); ImageType::Pointer resampledImage = resampler->GetOutput(); newImage = mitk::ImportItkImage( resampledImage )->Clone(); nameAddition << "_Resampled_" << selectedInterpolator; std::cout << "Resampling successful." << std::endl; break; } case RESCALE: { DoubleImageType::Pointer floatImage = DoubleImageType::New(); CastToItkImage( newImage, floatImage ); itk::RescaleIntensityImageFilter<DoubleImageType,DoubleImageType>::Pointer filter = itk::RescaleIntensityImageFilter<DoubleImageType,DoubleImageType>::New(); filter->SetInput(0, floatImage); filter->SetOutputMinimum(dparam1); filter->SetOutputMaximum(dparam2); filter->Update(); floatImage = filter->GetOutput(); newImage = mitk::Image::New(); newImage->InitializeByItk(floatImage.GetPointer()); newImage->SetVolume(floatImage->GetBufferPointer()); nameAddition << "_Rescaled"; std::cout << "Rescaling successful." << std::endl; break; } case RESCALE2: { DoubleImageType::Pointer floatImage = DoubleImageType::New(); CastToItkImage( newImage, floatImage ); itk::ShiftScaleImageFilter<DoubleImageType,DoubleImageType>::Pointer filter = itk::ShiftScaleImageFilter<DoubleImageType,DoubleImageType>::New(); filter->SetInput(0, floatImage); filter->SetScale(dparam1); filter->Update(); floatImage = filter->GetOutput(); newImage = mitk::Image::New(); newImage->InitializeByItk(floatImage.GetPointer()); newImage->SetVolume(floatImage->GetBufferPointer()); nameAddition << "_Rescaled"; std::cout << "Rescaling successful." << std::endl; break; } default: this->BusyCursorOff(); return; } } catch (...) { this->BusyCursorOff(); QMessageBox::warning(nullptr, "Warning", "Problem when applying filter operation. Check your input..."); return; } newImage->DisconnectPipeline(); // adjust level/window to new image mitk::LevelWindow levelwindow; levelwindow.SetAuto( newImage ); auto levWinProp = mitk::LevelWindowProperty::New(); levWinProp->SetLevelWindow( levelwindow ); // compose new image name std::string name = selectedNode->GetName(); - if (name.find(".pic.gz") == name.size() -7 ) + if (name.find(".nrrd") == name.size() -5 ) { - name = name.substr(0,name.size() -7); + name = name.substr(0,name.size() -5); } name.append( nameAddition.str() ); // create final result MITK data storage node auto result = mitk::DataNode::New(); result->SetProperty( "levelwindow", levWinProp ); result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) ); result->SetData( newImage ); // for vector images, a different mapper is needed if(isVectorImage > 1) { auto mapper = mitk::VectorImageMapper2D::New(); result->SetMapper(1,mapper); } // add new image to data storage and set as active to ease further processing GetDataStorage()->Add(result, selectedNode); if (m_Controls->cbHideOrig->isChecked() == true) { selectedNode->SetProperty("visible", mitk::BoolProperty::New(false)); } // show the results mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->BusyCursorOff(); } void QmitkBasicImageProcessing::SelectAction2(int operation) { switch (operation) { case 2: m_SelectedOperation = ADD; break; case 3: m_SelectedOperation = SUBTRACT; break; case 4: m_SelectedOperation = MULTIPLY; break; case 5: m_SelectedOperation = DIVIDE; break; case 6: m_SelectedOperation = RESAMPLE_TO; break; case 8: m_SelectedOperation = AND; break; case 9: m_SelectedOperation = OR; break; case 10: m_SelectedOperation = XOR; break; default: return; } m_Controls->selectedImageLabel_2->setEnabled(true); m_Controls->selectedImageWidget_2->setEnabled(true); m_Controls->btnDoIt2->setEnabled(true); } void QmitkBasicImageProcessing::StartButton2Clicked() { auto selectedNode = m_Controls->selectedImageWidget->GetSelectedNode(); if (selectedNode.IsNull()) { return; } auto selectedNode2 = m_Controls->selectedImageWidget_2->GetSelectedNode(); if (selectedNode2.IsNull()) { return; } mitk::Image::Pointer newImage1 = dynamic_cast<mitk::Image*>(selectedNode->GetData()); mitk::Image::Pointer newImage2 = dynamic_cast<mitk::Image*>(selectedNode2->GetData()); // check if images are valid if(newImage1.IsNull() || newImage2.IsNull() || false == newImage1->IsInitialized() || false == newImage2->IsInitialized()) { itkGenericExceptionMacro(<< "At least one of the input images is broken or not initialized."); return; } this->BusyCursorOn(); // check if 4D image and use filter on correct time step if(newImage1->GetDimension() > 3) { auto timeSelector = mitk::ImageTimeSelector::New(); auto sn_widget = static_cast<QmitkSliderNavigatorWidget*>( m_Controls->sliceNavigatorTime ); int time = 0; if( sn_widget != nullptr ) time = sn_widget->GetPos(); timeSelector->SetInput(newImage1); timeSelector->SetTimeNr( time ); timeSelector->UpdateLargestPossibleRegion(); newImage1 = timeSelector->GetOutput(); newImage1->DisconnectPipeline(); timeSelector->SetInput(newImage2); timeSelector->SetTimeNr( time ); timeSelector->UpdateLargestPossibleRegion(); newImage2 = timeSelector->GetOutput(); newImage2->DisconnectPipeline(); } auto itkImage1 = ImageType::New(); auto itkImage2 = ImageType::New(); CastToItkImage( newImage1, itkImage1 ); CastToItkImage( newImage2, itkImage2 ); std::string nameAddition = ""; try { switch (m_SelectedOperation) { case ADD: { AddFilterType::Pointer addFilter = AddFilterType::New(); addFilter->SetInput1( itkImage1 ); addFilter->SetInput2( itkImage2 ); addFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(addFilter->GetOutput())->Clone(); nameAddition = "_Added"; } break; case SUBTRACT: { SubtractFilterType::Pointer subFilter = SubtractFilterType::New(); subFilter->SetInput1( itkImage1 ); subFilter->SetInput2( itkImage2 ); subFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(subFilter->GetOutput())->Clone(); nameAddition = "_Subtracted"; } break; case MULTIPLY: { MultiplyFilterType::Pointer multFilter = MultiplyFilterType::New(); multFilter->SetInput1( itkImage1 ); multFilter->SetInput2( itkImage2 ); multFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(multFilter->GetOutput())->Clone(); nameAddition = "_Multiplied"; } break; case DIVIDE: { DivideFilterType::Pointer divFilter = DivideFilterType::New(); divFilter->SetInput1( itkImage1 ); divFilter->SetInput2( itkImage2 ); divFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage<DoubleImageType>(divFilter->GetOutput())->Clone(); nameAddition = "_Divided"; } break; case AND: { AndImageFilterType::Pointer andFilter = AndImageFilterType::New(); andFilter->SetInput1( itkImage1 ); andFilter->SetInput2( itkImage2 ); andFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(andFilter->GetOutput())->Clone(); nameAddition = "_AND"; break; } case OR: { OrImageFilterType::Pointer orFilter = OrImageFilterType::New(); orFilter->SetInput1( itkImage1 ); orFilter->SetInput2( itkImage2 ); orFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(orFilter->GetOutput())->Clone(); nameAddition = "_OR"; break; } case XOR: { XorImageFilterType::Pointer xorFilter = XorImageFilterType::New(); xorFilter->SetInput1( itkImage1 ); xorFilter->SetInput2( itkImage2 ); xorFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(xorFilter->GetOutput())->Clone(); nameAddition = "_XOR"; break; } case RESAMPLE_TO: { itk::BSplineInterpolateImageFunction<DoubleImageType, double>::Pointer bspl_interpolator = itk::BSplineInterpolateImageFunction<DoubleImageType, double>::New(); bspl_interpolator->SetSplineOrder( 3 ); itk::NearestNeighborInterpolateImageFunction< DoubleImageType >::Pointer nn_interpolator = itk::NearestNeighborInterpolateImageFunction< DoubleImageType>::New(); DoubleImageType::Pointer itkImage1 = DoubleImageType::New(); DoubleImageType::Pointer itkImage2 = DoubleImageType::New(); CastToItkImage( newImage1, itkImage1 ); CastToItkImage( newImage2, itkImage2 ); itk::ResampleImageFilter< DoubleImageType, DoubleImageType >::Pointer resampleFilter = itk::ResampleImageFilter< DoubleImageType, DoubleImageType >::New(); resampleFilter->SetInput( itkImage1 ); resampleFilter->SetReferenceImage( itkImage2 ); resampleFilter->SetUseReferenceImage( true ); // use NN interp with binary images if(selectedNode->GetProperty("binary") ) resampleFilter->SetInterpolator( nn_interpolator ); else resampleFilter->SetInterpolator( bspl_interpolator ); resampleFilter->SetDefaultPixelValue( 0 ); try { resampleFilter->UpdateLargestPossibleRegion(); } catch( const itk::ExceptionObject &e) { MITK_WARN << "Updating resampling filter failed. "; MITK_WARN << "REASON: " << e.what(); } DoubleImageType::Pointer resampledImage = resampleFilter->GetOutput(); newImage1 = mitk::ImportItkImage( resampledImage )->Clone(); nameAddition = "_Resampled"; break; } default: std::cout << "Something went wrong..." << std::endl; this->BusyCursorOff(); return; } } catch (const itk::ExceptionObject& e ) { this->BusyCursorOff(); QMessageBox::warning(nullptr, "ITK Exception", e.what() ); QMessageBox::warning(nullptr, "Warning", tr("Problem when applying arithmetic operation to two images. Check dimensions of input images.")); return; } // disconnect pipeline; images will not be reused newImage1->DisconnectPipeline(); itkImage1 = nullptr; itkImage2 = nullptr; // adjust level/window to new image and compose new image name mitk::LevelWindow levelwindow; levelwindow.SetAuto( newImage1 ); auto levWinProp = mitk::LevelWindowProperty::New(); levWinProp->SetLevelWindow( levelwindow ); std::string name = selectedNode->GetName(); - if (name.find(".pic.gz") == name.size() -7 ) + if (name.find(".nrrd") == name.size() -5 ) { - name = name.substr(0,name.size() -7); + name = name.substr(0,name.size() -5); } // create final result MITK data storage node auto result = mitk::DataNode::New(); result->SetProperty( "levelwindow", levWinProp ); result->SetProperty( "name", mitk::StringProperty::New( (name + nameAddition ).c_str() )); result->SetData( newImage1 ); this->GetDataStorage()->Add(result, selectedNode); if (m_Controls->cbHideOrig->isChecked() == true) { selectedNode->SetProperty("visible", mitk::BoolProperty::New(false)); selectedNode2->SetProperty("visible", mitk::BoolProperty::New(false)); } // show the newly created image mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->BusyCursorOff(); } void QmitkBasicImageProcessing::SelectInterpolator(int interpolator) { switch (interpolator) { case 0: { m_SelectedInterpolation = LINEAR; break; } case 1: { m_SelectedInterpolation = NEAREST; break; } } } diff --git a/Plugins/org.mitk.gui.qt.datamanager/documentation/UserManual/QmitkDatamanager.dox b/Plugins/org.mitk.gui.qt.datamanager/documentation/UserManual/QmitkDatamanager.dox index 505f2ac4bb..f9c36fce44 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/documentation/UserManual/QmitkDatamanager.dox +++ b/Plugins/org.mitk.gui.qt.datamanager/documentation/UserManual/QmitkDatamanager.dox @@ -1,194 +1,194 @@ /** \page org_mitk_views_datamanager The Data Manager View \imageMacro{data-manager-dox.svg,"Icon of the Data Manager", 2.00} \tableofcontents \section DataManagerIntroduction Introduction The Datamanager is the central component to manage medical data like images, segmentation masks, registrations, surfaces, point sets, annotations, measurements, etc..<br> After loading data into the Datamanager the data is shown in the four-view window, the so-called <em>Standard Display</em>. The user can now start working on the data by interacting with the data inside the <em>Standard Display</em>, by using the MITK-plugins such as <em>Segmentation</em> or <em>Basic Image Processing</em> or by using the context menu inside the data manager. \section DataManagerLoadingData Loading Data There are several ways of loading data into the Datamanager as so-called <em>data nodes</em>: <ul> <li> drag and drop data (e.g. from a file explorer or desktop) into the Datamanager <li> drag and drop data (e.g. from a file explorer or desktop) into one of the four windows of the <em>Standard Display</em> <li> use the keyboard shortcut <em>Ctrl + o</em> <li> use the <em>Open File</em> Button in the left upper corner and use the <em>Open</em> Dialog <li> use <em>File -> Open File...</em> from the top menu </ul> A lot of file-formats can be loaded into MITK, for example: <ul> - <li> 2D-images / 3D-volumes with or without several time steps (*.dcm, *.ima, *.pic, *.nrrd, ...) + <li> 2D-images / 3D-volumes with or without several time steps (*.dcm, *.ima, *.nrrd, ...) <li> Surfaces (*.stl, *.vtk, ...) <li> Point sets (*.mps) <li> and many more </ul> The user can also load a series of 2D images (e.g. image001.png, image002.png ...) to a MITK 3D volume. To do this, just drag and drop one of those 2D data files into the Datamanager by holding the ALT key. <em>Note: What really happens is that the data nodes are stored inside a "Data storage" and the Datamanager is just a visual representation of the data inside the "Data storage". That's why the documentation sometimes uses the term "Data storage" instead of "Datamanager".</em> \section DataManagerSavingData Saving Data There are several ways of saving data from the Datamanager: <ul> <li> use the keyboard shortcut <em>Ctrl + s</em> on a single data node <li> use the keyboard shortcut <em>Ctrl + s</em> on multiple data nodes <li> use the context menu <em>right-click -> Save</em> on a single data node <li> use the context menu <em>right-click -> Save</em> on multiple data nodes <li> use <em>File -> Save...</em> from the top menu on a single data node <li> use <em>File -> Save...</em> from the top menu on multiple data nodes </ul> \section DataManagerWorking Working with the Datamanager After loading data into the Datamanager the data appears as data nodes in a sorted list inside the Datamanager. The user can change the order of the data nodes manually by dragging one or multiple data nodes and dropping them at any position inside the Datamanager. Data nodes can also be sorted hierarchically as a parent-child-relation. For example after using the <em>Segmentation-Plugin</em> to create a segmentation on <em>DataNode</em>, the result is created as <em>ChildNode</em>, which is a child of <em>DataNode</em> (see \ref ParentChild "Parent-Child-Relation" screenshot).<br> A parent-child-relation can be changed by dragging a child of a data node and dropping it onto another data node. For this the Property <em>Allow changing of parent nodes</em> needs to be enabled (see \ref DataManagerPreferences "Preferences"). \anchor ParentChild \imageMacro{QmitkDatamanager_ParentChild.png, "Parent-Child-Relation", 16.00} \subsection DataManagerNodeVisibility Visibility of data nodes By default all loaded data nodes are visible in the <em>Standard Display</em>. The visibility is indicated by the checkbox in front of the data node name in the Datamanager. If a data node is visible, the checkbox is filled - an empty checkbox indicates a hidden data node (see \ref ParentChild "Parent-Child-Relation" screenshot). <em>Hint: The data nodes are rendered on top of each other, such that the topmost visible data node is always displayed on top of other data nodes. By hiding the topmost visible data node the next data node becomes the topmost visible data node and the hidden data node is not rendered anymore.</em> <em>Note: "Visible" does not mean that the node is correctly displayed inside the render windows. The user might have to re-initialize a data node to have it correctly displayed.</em> \subsection DataManagerNodeSelection Selection of data nodes Some MITK-plugins contain widgets to control the data nodes that are used for plugin-specific data processing. These widgets can be configured such that they listen to the current selection of the Datamanager. Having such a plugin active each selection change of data nodes inside the data manager will change the respective selection of the plugin. The data node selection widgets can have specific node predicates, which means that only specific data nodes can be controlled by the widgets. It might happen that a selected data node will not be represented in such a selection widget or that the selection widget will be emptied. \subsection DataManagerNodeRenaming Renaming data nodes There are two ways of changing the name of a data node inside the Datamanager: <ul> <li> use the <em>F2</em> key on a single data node <li> double-click on a single data node </ul> In both cases the new name can be accepted by hitting <em>Enter</em> or by clicking somewhere else. \section DataManagerContextMenu Context Menu The Datamanager provides a context menu for each data node that can be opened by right-clicking on a data node. An example of the context-menu can be seen in the \ref ContextMenu "Context menu" screenshot. The context menu allows to quickly perform common actions on data nodes. These actions differ according to the data type. Some of these actions are described here. For more actions see the respective modules and plugins (e.g. <tt>QmitkCreatePolygonModelAction</tt> inside the <tt>org_mitk_gui_qt_segmentation</tt>-plugin. <ul> <li> <em>Global Reinit</em>: Re-initializes the render windows to the common bounding box of all data nodes of the data storage that <ul> <li> have not set <tt>"includeInBoundingBox"</tt> to false <li> are <tt>"visible"</tt>. </ul> In this case it does not matter on which node this action is performed. <li> <em>Reinit</em>: Re-initializes the render windows to the common bounding box of all selected data nodes of the data storage that <ul> <li> have not set <tt>"includeInBoundingBox"</tt> to false <li> are <tt>"visible"</tt>. </ul> <li> <em>Save</em>: see \ref DataManagerSavingData "Saving Data" section <li> <em>Remove</em>: Removes all selected data nodes from the data storage. <li> <em>Show only selected nodes</em>: Enables the visibility of all selected data nodes and hides all other data nodes. <li> <em>Toggle visibility</em>: Shows / hides each selected data node according to each node's current visibility state. <li> <em>Show details</em>: Opens a pop-up window with detailed information about each node, like data type, geometry, DICOM information, file path etc. <li> <em>Opacity</em>: Sets the opacity via a slider for the rendering of the selected data node. <li> <em>Color</em>: Opens a pop-up window that allows to pick an arbitrary color for the rendering of all selected data nodes. <li> <em>Colormap</em>: Opens another submenu with a list of different colormaps that can be chosen for the rendering of all selected data nodes. <li> <em>Component</em>: Sets the currently visible data component for the rendering of this particular component of the selected data node. <li> <em>Texture Interpolation</em>: Smooths the data visualization for rendering of a selected data node. <li> <em>Surface Representation</em>: Opens another submenu with the following entries: <ul> <li> <em>Points</em>: Visually represents a surface (a data type) as a set of points. <li> <em>Wireframe</em>: Visually represents a surface (a data type) as a wireframe model. <li> <em>Surface</em>: Visually represents a surface (a data type) as a solid surface. </ul> </ul> As the description of the actions showed, it is possible to open / use the context menu with a single data node or with a set of selected data nodes. If the data types of multiple selected data nodes differ, the actions might not appear / work as expected. Also some actions are not available for a set of selected data nodes. \anchor ContextMenu \imageMacro{QmitkDatamanager_ContextMenu.png, "Context menu", 16.00} \section DataManagerPreferences Preferences The MITK Workbench provides a <em>preference page</em> for specific plugins. The preference page provided for the Datamanager can be seen in the \ref PreferencePage "Preference page" screenshot. The user can open the preference page by <ul> <li> using the keyboard shortcut <em>Ctrl + p</em> <li> using <em>Window -> Preferences...</em> from the top menu. </ul> It allows to set the following preferences for the Datamanager, which define the behavior of the Datamanager: <ul> <li> <em>Place new nodes on top</em>: If enabled, newly added data nodes will be inserted at the top of the list of data nodes inside the Datamanager. If disabled, newly added nodes will be inserted at the bottom of the list. <li> <em>Show helper objects</em>: If enabled, data nodes that have set <tt>"helper object"</tt> to true will be displayed in the Datamanager. If disabled, data nodes that have set <tt>"helper object"</tt> to true will not be visible in the Datamanager. <li> <em>Show nodes containing no data</em>: If enabled, data nodes that have no underlying base data defined will be displayed in the Datamanager. If disabled, data nodes that have no underlying base data defined will not be visible in the Datamanager. <li> <em>Use surface decimation</em>: If enabled, a newly created surface will be decimated to reduce the number of triangles in the triangle mesh. Such a surface can be created as a polygon model from a segmentation (see \ref DataManagerContextMenu "Context Menu"). If disabled, the surface will have its original number of triangles in the triangle mesh. <li> <em>Allow changing of parent node</em>: If enabled, the user can change the hierarchy of the data nodes manually by dragging one or multiple data nodes and dropping them at any position inside the Datamanager (see \ref DataManagerWorking "Working with the Datamanager") for changing the order of the data nodes manually). </ul> \anchor PreferencePage \imageMacro{QmitkDatamanager_PreferencePage.png, "Preference page", 16.00} \section DataManagerHotkeys Hotkeys The MITK Workbench provides hotkeys for specific plugins. The hotkeys provided for the Datamanager can be seen in the \ref Hotkeys "Hotkeys" screenshot. They allow to expedite common operations in relation to data nodes or the Datamanager. The user can customize the hotkeys by accessing the <em>preference page</em>: <ul> <li> using the keyboard shortcut <em>Ctrl + p</em> <li> useing <em>Window -> Preferences...</em> from the top menu </ul> <ul> <li> <em>Delete selected nodes</em> Removes all selected data nodes from the data storage. <li> <em>Global reinit</em> Re-initializes the render windows to the common bounding box of all data nodes of the data storage that <ul> <li> have not set <tt>"includeInBoundingBox"</tt> to false <li> are <tt>"visible"</tt> </ul> In this case it does not matter on which node this action is performed. <li> <em>Make all nodes invisible</em> Hides all data nodes of the data storage. <li> <em>Reinit selected nodes</em> Re-initializes the render windows to the common bounding box of all selected data nodes of the data storage that <ul> <li> have not set <tt>"includeInBoundingBox"</tt> to false <li> are <tt>"visible"</tt> </ul> <li> <em>Show node information</em> Opens a pop-up window with detailed information about each node, like data type, geometry, DICOM information, file path etc. <li> <em>Toggle visibility of selected nodes</em>: Shows / hides each selected data node according to each node's current visibility state. </ul> \anchor Hotkeys \imageMacro{QmitkDatamanager_Hotkeys.png, "Hotkeys", 16.00} */ diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp index 60f918782e..ada96a36f3 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp @@ -1,473 +1,469 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkImageStatisticsView.h" #include <utility> // berry includes #include <berryIQtStyleManager.h> #include <berryWorkbenchPlugin.h> #include <QmitkChartWidget.h> #include <mitkImageStatisticsContainerNodeHelper.h> #include <mitkImageStatisticsPredicateHelper.h> #include <mitkImageTimeSelector.h> #include <mitkIntensityProfile.h> #include <mitkNodePredicateAnd.h> #include <mitkNodePredicateGeometry.h> #include <mitkNodePredicateSubGeometry.h> #include <mitkNodePredicateOr.h> #include <mitkNodePredicateFunction.h> #include <mitkSliceNavigationController.h> #include <mitkStatusBar.h> #include <mitkPlanarFigure.h> #include "mitkPlanarFigureMaskGenerator.h" #include "QmitkImageStatisticsDataGenerator.h" #include "mitkImageStatisticsContainerManager.h" #include <mitkPlanarFigureInteractor.h> const std::string QmitkImageStatisticsView::VIEW_ID = "org.mitk.views.imagestatistics"; QmitkImageStatisticsView::~QmitkImageStatisticsView() { } void QmitkImageStatisticsView::CreateQtPartControl(QWidget *parent) { m_Controls.setupUi(parent); m_Controls.widget_intensityProfile->SetTheme(GetColorTheme()); m_Controls.groupBox_histogram->setVisible(true); m_Controls.groupBox_intensityProfile->setVisible(false); m_Controls.label_currentlyComputingStatistics->setVisible(false); m_Controls.sliderWidget_histogram->setPrefix("Time: "); m_Controls.sliderWidget_histogram->setDecimals(0); m_Controls.sliderWidget_histogram->setVisible(false); m_Controls.sliderWidget_intensityProfile->setPrefix("Time: "); m_Controls.sliderWidget_intensityProfile->setDecimals(0); m_Controls.sliderWidget_intensityProfile->setVisible(false); ResetGUI(); m_DataGenerator = new QmitkImageStatisticsDataGenerator(parent); m_DataGenerator->SetDataStorage(this->GetDataStorage()); m_DataGenerator->SetAutoUpdate(true); m_Controls.widget_statistics->SetDataStorage(this->GetDataStorage()); m_Controls.imageNodesSelector->SetDataStorage(this->GetDataStorage()); m_Controls.imageNodesSelector->SetNodePredicate(mitk::GetImageStatisticsImagePredicate()); m_Controls.imageNodesSelector->SetSelectionCheckFunction(this->CheckForSameGeometry()); m_Controls.imageNodesSelector->SetSelectionIsOptional(false); m_Controls.imageNodesSelector->SetInvalidInfo(QStringLiteral("Please select images for statistics")); m_Controls.imageNodesSelector->SetPopUpTitel(QStringLiteral("Select input images")); m_Controls.roiNodesSelector->SetPopUpHint(QStringLiteral("You may select multiple images for the statistics computation. But all selected images must have the same geometry.")); m_Controls.roiNodesSelector->SetDataStorage(this->GetDataStorage()); m_Controls.roiNodesSelector->SetNodePredicate(this->GenerateROIPredicate()); m_Controls.roiNodesSelector->SetSelectionIsOptional(true); m_Controls.roiNodesSelector->SetEmptyInfo(QStringLiteral("Please select ROIs")); m_Controls.roiNodesSelector->SetPopUpTitel(QStringLiteral("Select ROIs for statistics computation")); m_Controls.roiNodesSelector->SetPopUpHint(QStringLiteral("You may select ROIs (e.g. planar figures, segmentations) that should be used for the statistics computation. The statistics will only computed for the image parts defined by the ROIs.")); CreateConnections(); this->m_TimePointChangeListener.RenderWindowPartActivated(this->GetRenderWindowPart()); connect(&m_TimePointChangeListener, &QmitkSliceNavigationListener::SelectedTimePointChanged, this, & QmitkImageStatisticsView::OnSelectedTimePointChanged); } void QmitkImageStatisticsView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { this->m_TimePointChangeListener.RenderWindowPartActivated(renderWindowPart); } void QmitkImageStatisticsView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) { this->m_TimePointChangeListener.RenderWindowPartDeactivated(renderWindowPart); } void QmitkImageStatisticsView::CreateConnections() { - connect(m_Controls.checkBox_ignoreZero, &QCheckBox::stateChanged, - this, &QmitkImageStatisticsView::OnCheckBoxIgnoreZeroStateChanged); + connect(m_Controls.widget_statistics, &QmitkImageStatisticsWidget::IgnoreZeroValuedVoxelStateChanged, + this, &QmitkImageStatisticsView::OnIgnoreZeroValuedVoxelStateChanged); connect(m_Controls.buttonSelection, &QAbstractButton::clicked, this, &QmitkImageStatisticsView::OnButtonSelectionPressed); connect(m_Controls.widget_histogram, &QmitkHistogramVisualizationWidget::RequestHistogramUpdate, this, &QmitkImageStatisticsView::OnRequestHistogramUpdate); connect(m_DataGenerator, &QmitkImageStatisticsDataGenerator::DataGenerationStarted, this, &QmitkImageStatisticsView::OnGenerationStarted); connect(m_DataGenerator, &QmitkImageStatisticsDataGenerator::GenerationFinished, this, &QmitkImageStatisticsView::OnGenerationFinished); connect(m_DataGenerator, &QmitkImageStatisticsDataGenerator::JobError, this, &QmitkImageStatisticsView::OnJobError); connect(m_Controls.imageNodesSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkImageStatisticsView::OnImageSelectionChanged); connect(m_Controls.roiNodesSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkImageStatisticsView::OnROISelectionChanged); connect(m_Controls.sliderWidget_intensityProfile, &ctkSliderWidget::valueChanged, this, &QmitkImageStatisticsView::UpdateIntensityProfile); } void QmitkImageStatisticsView::UpdateIntensityProfile() { m_Controls.groupBox_intensityProfile->setVisible(false); const auto selectedImageNodes = m_Controls.imageNodesSelector->GetSelectedNodes(); const auto selectedROINodes = m_Controls.roiNodesSelector->GetSelectedNodes(); if (selectedImageNodes.size()==1 && selectedROINodes.size()==1) { //only supported for one image and roi currently auto image = dynamic_cast<mitk::Image*>(selectedImageNodes.front()->GetData()); auto maskPlanarFigure = dynamic_cast<mitk::PlanarFigure*>(selectedROINodes.front()->GetData()); if (maskPlanarFigure != nullptr) { if (!maskPlanarFigure->IsClosed()) { mitk::Image::Pointer inputImage; if (image->GetDimension() == 4) { m_Controls.sliderWidget_intensityProfile->setVisible(true); unsigned int maxTimestep = image->GetTimeSteps(); m_Controls.sliderWidget_intensityProfile->setMaximum(maxTimestep - 1); // Intensity profile can only be calculated on 3D, so extract if 4D mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); int currentTimestep = static_cast<int>(m_Controls.sliderWidget_intensityProfile->value()); timeSelector->SetInput(image); timeSelector->SetTimeNr(currentTimestep); timeSelector->Update(); inputImage = timeSelector->GetOutput(); } else { m_Controls.sliderWidget_intensityProfile->setVisible(false); inputImage = image; } auto intensityProfile = mitk::ComputeIntensityProfile(inputImage, maskPlanarFigure); m_Controls.groupBox_intensityProfile->setVisible(true); m_Controls.widget_intensityProfile->Reset(); m_Controls.widget_intensityProfile->SetIntensityProfile(intensityProfile.GetPointer(), "Intensity Profile of " + selectedImageNodes.front()->GetName()); } } } } void QmitkImageStatisticsView::UpdateHistogramWidget() { - bool visibility = false; + m_Controls.groupBox_histogram->setVisible(false); const auto selectedImageNodes = m_Controls.imageNodesSelector->GetSelectedNodes(); const auto selectedMaskNodes = m_Controls.roiNodesSelector->GetSelectedNodes(); if (selectedImageNodes.size() == 1 && selectedMaskNodes.size()<=1) { //currently only supported for one image and roi due to histogram widget limitations. auto imageNode = selectedImageNodes.front(); const mitk::DataNode* roiNode = nullptr; const mitk::PlanarFigure* planarFigure = nullptr; if (!selectedMaskNodes.empty()) { roiNode = selectedMaskNodes.front(); planarFigure = dynamic_cast<const mitk::PlanarFigure*>(roiNode->GetData()); } if ((planarFigure == nullptr || planarFigure->IsClosed()) && imageNode->GetData()->GetTimeGeometry()->IsValidTimePoint(m_TimePointChangeListener.GetCurrentSelectedTimePoint())) { //if a planar figure is not closed, we show the intensity profile instead of the histogram. auto statisticsNode = m_DataGenerator->GetLatestResult(imageNode, roiNode, true); if (statisticsNode.IsNotNull()) { auto statistics = dynamic_cast<const mitk::ImageStatisticsContainer*>(statisticsNode->GetData()); if (statistics) { const auto timeStep = imageNode->GetData()->GetTimeGeometry()->TimePointToTimeStep(m_TimePointChangeListener.GetCurrentSelectedTimePoint()); - std::stringstream label; - label << imageNode->GetName(); - if (imageNode->GetData()->GetTimeSteps() > 1) + if (statistics->TimeStepExists(timeStep)) { - label << "["<< timeStep <<"]"; + std::stringstream label; + label << imageNode->GetName(); + if (imageNode->GetData()->GetTimeSteps() > 1) + { + label << "[" << timeStep << "]"; + } + + if (roiNode) + { + label << " with " << roiNode->GetName(); + } + + //Hardcoded labels are currently needed because the current histogram widget (and ChartWidget) + //do not allow correct removal or sound update/insertion of serveral charts. + //only thing that works for now is always to update/overwrite the same data label + //This is a quick fix for T28223 and T28221 + m_Controls.widget_histogram->SetHistogram(statistics->GetHistogramForTimeStep(timeStep), "histogram"); + m_Controls.groupBox_histogram->setVisible(true); } - - if (roiNode) - { - label << " with " << roiNode->GetName(); - } - - //Hardcoded labels are currently needed because the current histogram widget (and ChartWidget) - //do not allow correct removal or sound update/insertion of serveral charts. - //only thing that works for now is always to update/overwrite the same data label - //This is a quick fix for T28223 and T28221 - m_Controls.widget_histogram->SetHistogram(statistics->GetHistogramForTimeStep(timeStep), "histogram"); - - visibility = true; } } } } - - if (visibility != m_Controls.groupBox_histogram->isVisible()) - { - m_Controls.groupBox_histogram->setVisible(visibility); - } - } QmitkChartWidget::ColorTheme QmitkImageStatisticsView::GetColorTheme() const { ctkPluginContext *context = berry::WorkbenchPlugin::GetDefault()->GetPluginContext(); ctkServiceReference styleManagerRef = context->getServiceReference<berry::IQtStyleManager>(); if (styleManagerRef) { auto styleManager = context->getService<berry::IQtStyleManager>(styleManagerRef); if (styleManager->GetStyle().name == "Dark") { return QmitkChartWidget::ColorTheme::darkstyle; } else { return QmitkChartWidget::ColorTheme::lightstyle; } } return QmitkChartWidget::ColorTheme::darkstyle; } void QmitkImageStatisticsView::ResetGUI() { m_Controls.widget_statistics->Reset(); m_Controls.widget_statistics->setEnabled(false); m_Controls.widget_histogram->Reset(); m_Controls.widget_histogram->setEnabled(false); m_Controls.widget_histogram->SetTheme(GetColorTheme()); } void QmitkImageStatisticsView::OnGenerationStarted(const mitk::DataNode* /*imageNode*/, const mitk::DataNode* /*roiNode*/, const QmitkDataGenerationJobBase* /*job*/) { m_Controls.label_currentlyComputingStatistics->setVisible(true); } void QmitkImageStatisticsView::OnGenerationFinished() { m_Controls.label_currentlyComputingStatistics->setVisible(false); mitk::StatusBar::GetInstance()->Clear(); this->UpdateIntensityProfile(); this->UpdateHistogramWidget(); } void QmitkImageStatisticsView::OnSelectedTimePointChanged(const mitk::TimePointType& /*newTimePoint*/) { this->UpdateHistogramWidget(); } void QmitkImageStatisticsView::OnJobError(QString error, const QmitkDataGenerationJobBase* /*failedJob*/) { mitk::StatusBar::GetInstance()->DisplayErrorText(error.toStdString().c_str()); MITK_WARN << "Error when calculating statistics: " << error; } void QmitkImageStatisticsView::OnRequestHistogramUpdate(unsigned int nbins) { m_Controls.widget_statistics->SetHistogramNBins(nbins); m_DataGenerator->SetHistogramNBins(nbins); this->UpdateIntensityProfile(); this->UpdateHistogramWidget(); } -void QmitkImageStatisticsView::OnCheckBoxIgnoreZeroStateChanged(int state) +void QmitkImageStatisticsView::OnIgnoreZeroValuedVoxelStateChanged(int state) { auto ignoreZeroValueVoxel = (state == Qt::Unchecked) ? false : true; m_Controls.widget_statistics->SetIgnoreZeroValueVoxel(ignoreZeroValueVoxel); m_DataGenerator->SetIgnoreZeroValueVoxel(ignoreZeroValueVoxel); this->UpdateIntensityProfile(); this->UpdateHistogramWidget(); } void QmitkImageStatisticsView::OnImageSelectionChanged(QmitkAbstractNodeSelectionWidget::NodeList /*nodes*/) { auto images = m_Controls.imageNodesSelector->GetSelectedNodesStdVector(); m_Controls.widget_statistics->SetImageNodes(images); m_Controls.widget_statistics->setEnabled(!images.empty()); m_Controls.roiNodesSelector->SetNodePredicate(this->GenerateROIPredicate()); m_DataGenerator->SetAutoUpdate(false); m_DataGenerator->SetImageNodes(images); m_DataGenerator->Generate(); m_DataGenerator->SetAutoUpdate(true); this->UpdateHistogramWidget(); this->UpdateIntensityProfile(); } void QmitkImageStatisticsView::OnROISelectionChanged(QmitkAbstractNodeSelectionWidget::NodeList /*nodes*/) { auto rois = m_Controls.roiNodesSelector->GetSelectedNodesStdVector(); m_Controls.widget_statistics->SetMaskNodes(rois); m_DataGenerator->SetAutoUpdate(false); m_DataGenerator->SetROINodes(rois); m_DataGenerator->Generate(); m_DataGenerator->SetAutoUpdate(true); this->UpdateHistogramWidget(); this->UpdateIntensityProfile(); } void QmitkImageStatisticsView::OnButtonSelectionPressed() { QmitkNodeSelectionDialog* dialog = new QmitkNodeSelectionDialog(nullptr, "Select input for the statistic","You may select images and ROIs to compute their statistic. ROIs may be segmentations or planar figures."); dialog->SetDataStorage(GetDataStorage()); dialog->SetSelectionCheckFunction(CheckForSameGeometry()); // set predicates auto isPlanarFigurePredicate = mitk::GetImageStatisticsPlanarFigurePredicate(); auto isMaskPredicate = mitk::GetImageStatisticsMaskPredicate(); auto isImagePredicate = mitk::GetImageStatisticsImagePredicate(); auto isMaskOrPlanarFigurePredicate = mitk::NodePredicateOr::New(isPlanarFigurePredicate, isMaskPredicate); auto isImageOrMaskOrPlanarFigurePredicate = mitk::NodePredicateOr::New(isMaskOrPlanarFigurePredicate, isImagePredicate); dialog->SetNodePredicate(isImageOrMaskOrPlanarFigurePredicate); dialog->SetSelectionMode(QAbstractItemView::MultiSelection); dialog->SetCurrentSelection(m_Controls.imageNodesSelector->GetSelectedNodes()+m_Controls.roiNodesSelector->GetSelectedNodes()); if (dialog->exec()) { auto selectedNodeList = dialog->GetSelectedNodes(); m_Controls.imageNodesSelector->SetCurrentSelection(selectedNodeList); m_Controls.roiNodesSelector->SetCurrentSelection(selectedNodeList); } delete dialog; } QmitkNodeSelectionDialog::SelectionCheckFunctionType QmitkImageStatisticsView::CheckForSameGeometry() const { auto isMaskPredicate = mitk::GetImageStatisticsMaskPredicate(); auto lambda = [isMaskPredicate](const QmitkNodeSelectionDialog::NodeList& nodes) { if (nodes.empty()) { return std::string(); } const mitk::Image* imageNodeData = nullptr; for (auto& node : nodes) { auto castedData = dynamic_cast<const mitk::Image*>(node->GetData()); if (castedData != nullptr && !isMaskPredicate->CheckNode(node)) { imageNodeData = castedData; break; } } if (imageNodeData == nullptr) { std::stringstream ss; ss << "<font class=\"warning\"><p>Select at least one image.</p></font>"; return ss.str(); } auto imageGeoPredicate = mitk::NodePredicateGeometry::New(imageNodeData->GetGeometry()); auto maskGeoPredicate = mitk::NodePredicateSubGeometry::New(imageNodeData->GetGeometry()); for (auto& rightNode : nodes) { if (imageNodeData != rightNode->GetData()) { bool validGeometry = true; if (isMaskPredicate->CheckNode(rightNode)) { validGeometry = maskGeoPredicate->CheckNode(rightNode); } else if (dynamic_cast<const mitk::Image*>(rightNode->GetData())) { validGeometry = imageGeoPredicate->CheckNode(rightNode); } else { const mitk::PlanarFigure* planar2 = dynamic_cast<const mitk::PlanarFigure*>(rightNode->GetData()); if (planar2) { validGeometry = mitk::PlanarFigureMaskGenerator::CheckPlanarFigureIsNotTilted(planar2->GetPlaneGeometry(), imageNodeData->GetGeometry()); } } if (!validGeometry) { std::stringstream ss; ss << "<font class=\"warning\"><p>Invalid selection: All selected nodes must have the same geometry.</p><p>Differing node i.a.: \""; ss << rightNode->GetName() <<"\"</p></font>"; return ss.str(); } } } return std::string(); }; return lambda; } mitk::NodePredicateBase::Pointer QmitkImageStatisticsView::GenerateROIPredicate() const { auto isPlanarFigurePredicate = mitk::GetImageStatisticsPlanarFigurePredicate(); auto isMaskPredicate = mitk::GetImageStatisticsMaskPredicate(); auto isMaskOrPlanarFigurePredicate = mitk::NodePredicateOr::New(isPlanarFigurePredicate, isMaskPredicate); mitk::NodePredicateBase::Pointer result = isMaskOrPlanarFigurePredicate.GetPointer(); if(!m_Controls.imageNodesSelector->GetSelectedNodes().empty()) { auto image = m_Controls.imageNodesSelector->GetSelectedNodes().front()->GetData(); auto imageGeoPredicate = mitk::NodePredicateSubGeometry::New(image->GetGeometry()); auto lambda = [image, imageGeoPredicate](const mitk::DataNode* node) { bool sameGeometry = true; if (dynamic_cast<const mitk::Image*>(node->GetData()) != nullptr) { sameGeometry = imageGeoPredicate->CheckNode(node); } else { const auto planar2 = dynamic_cast<const mitk::PlanarFigure*>(node->GetData()); if (planar2) { sameGeometry = mitk::PlanarFigureMaskGenerator::CheckPlanarFigureIsNotTilted(planar2->GetPlaneGeometry(), image->GetGeometry()); } } return sameGeometry; }; result = mitk::NodePredicateAnd::New(isMaskOrPlanarFigurePredicate, mitk::NodePredicateFunction::New(lambda)).GetPointer(); } return result; } diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h index 3d5e633e39..c6637f5fed 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h @@ -1,95 +1,95 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKIMAGESTATISTICSVIEW_H #define QMITKIMAGESTATISTICSVIEW_H #include "ui_QmitkImageStatisticsViewControls.h" #include <QmitkAbstractView.h> #include <mitkImageStatisticsContainer.h> #include <QmitkNodeSelectionDialog.h> #include <QmitkSliceNavigationListener.h> #include <mitkPropertyRelations.h> #include <mitkIRenderWindowPartListener.h> class QmitkImageStatisticsDataGenerator; class QmitkDataGenerationJobBase; /*! \brief QmitkImageStatisticsView is a bundle that allows statistics calculation from images. Three modes are supported: 1. Statistics of one image, 2. Statistics of an image and a segmentation, 3. Statistics of an image and a Planar Figure. The statistics calculation is realized in a separate thread to keep the gui accessible during calculation. \ingroup Plugins/org.mitk.gui.qt.measurementtoolbox */ class QmitkImageStatisticsView : public QmitkAbstractView, public mitk::IRenderWindowPartListener { Q_OBJECT public: static const std::string VIEW_ID; /*! \brief default destructor */ ~QmitkImageStatisticsView() override; protected: /*! \brief Creates the widget containing the application controls, like sliders, buttons etc.*/ void CreateQtPartControl(QWidget* parent) override; void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override; using HistogramType = mitk::ImageStatisticsContainer::HistogramType; void SetFocus() override { }; virtual void CreateConnections(); void UpdateIntensityProfile(); void UpdateHistogramWidget(); QmitkChartWidget::ColorTheme GetColorTheme() const; void ResetGUI(); void OnGenerationStarted(const mitk::DataNode* imageNode, const mitk::DataNode* roiNode, const QmitkDataGenerationJobBase* job); void OnGenerationFinished(); void OnJobError(QString error, const QmitkDataGenerationJobBase* failedJob); void OnRequestHistogramUpdate(unsigned int); - void OnCheckBoxIgnoreZeroStateChanged(int state); + void OnIgnoreZeroValuedVoxelStateChanged(int state); void OnButtonSelectionPressed(); void OnImageSelectionChanged(QmitkAbstractNodeSelectionWidget::NodeList nodes); void OnROISelectionChanged(QmitkAbstractNodeSelectionWidget::NodeList nodes); void OnSelectedTimePointChanged(const mitk::TimePointType& newTimePoint); // member variable Ui::QmitkImageStatisticsViewControls m_Controls; private: QmitkNodeSelectionDialog::SelectionCheckFunctionType CheckForSameGeometry() const; mitk::NodePredicateBase::Pointer GenerateROIPredicate() const; std::vector<mitk::ImageStatisticsContainer::ConstPointer> m_StatisticsForSelection; QmitkImageStatisticsDataGenerator* m_DataGenerator = nullptr; QmitkSliceNavigationListener m_TimePointChangeListener; }; #endif // QMITKIMAGESTATISTICSVIEW_H diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui index 1a34302c5b..60c490ee6a 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui @@ -1,295 +1,288 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>QmitkImageStatisticsViewControls</class> <widget class="QWidget" name="QmitkImageStatisticsViewControls"> <property name="enabled"> <bool>true</bool> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>419</width> <height>1016</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> <layout class="QVBoxLayout" name="verticalLayout_4"> <property name="leftMargin"> <number>3</number> </property> <property name="topMargin"> <number>3</number> </property> <property name="rightMargin"> <number>3</number> </property> <property name="bottomMargin"> <number>3</number> </property> <item> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> <number>0</number> </property> <widget class="QWidget" name="tabStatistics"> <attribute name="title"> <string>Statistics</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout_7"> <property name="leftMargin"> <number>5</number> </property> <property name="topMargin"> <number>5</number> </property> <property name="rightMargin"> <number>5</number> </property> <property name="bottomMargin"> <number>5</number> </property> <item> <widget class="QPushButton" name="buttonSelection"> <property name="toolTip"> <string>Quick selector button for input data.</string> </property> <property name="text"> <string>+</string> </property> <property name="checkable"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_statistics"> <property name="minimumSize"> <size> <width>0</width> <height>200</height> </size> </property> <property name="title"> <string>Statistics</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <property name="leftMargin"> <number>3</number> </property> <property name="topMargin"> <number>3</number> </property> <property name="rightMargin"> <number>3</number> </property> <property name="bottomMargin"> <number>3</number> </property> <item> <widget class="QmitkImageStatisticsWidget" name="widget_statistics" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QLabel" name="label_currentlyComputingStatistics"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> <string>Calculating statistics...</string> </property> </widget> </item> - <item> - <widget class="QCheckBox" name="checkBox_ignoreZero"> - <property name="text"> - <string>Ignore zero-valued voxels</string> - </property> - </widget> - </item> </layout> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_histogram"> <property name="minimumSize"> <size> <width>0</width> <height>200</height> </size> </property> <property name="title"> <string>Histogram</string> </property> <layout class="QVBoxLayout" name="verticalLayout_6"> <item> <widget class="ctkSliderWidget" name="sliderWidget_histogram" native="true"/> </item> <item> <layout class="QVBoxLayout" name="verticalLayout_5"> <item> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <widget class="QmitkHistogramVisualizationWidget" name="widget_histogram" native="true"/> </item> <item> <spacer name="verticalSpacer_3"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </item> </layout> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_intensityProfile"> <property name="minimumSize"> <size> <width>0</width> <height>200</height> </size> </property> <property name="title"> <string>Intensity Profile</string> </property> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> <widget class="ctkSliderWidget" name="sliderWidget_intensityProfile" native="true"/> </item> <item> <widget class="QmitkIntensityProfileVisualizationWidget" name="widget_intensityProfile" native="true"/> </item> </layout> </widget> </item> </layout> </widget> <widget class="QWidget" name="tabData"> <attribute name="title"> <string>Input data</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout_8"> <property name="leftMargin"> <number>5</number> </property> <property name="topMargin"> <number>5</number> </property> <property name="rightMargin"> <number>5</number> </property> <property name="bottomMargin"> <number>5</number> </property> <item> <widget class="QLabel" name="label"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> <string>Images</string> </property> </widget> </item> <item> <widget class="QmitkMultiNodeSelectionWidget" name="imageNodesSelector" native="true"/> </item> <item> <widget class="QLabel" name="label_2"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> <string>ROIs (segmentations, planarfigures...)</string> </property> </widget> </item> <item> <widget class="QmitkMultiNodeSelectionWidget" name="roiNodesSelector" native="true"/> </item> <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> </widget> </item> </layout> </widget> <customwidgets> <customwidget> <class>QmitkImageStatisticsWidget</class> <extends>QWidget</extends> <header location="global">QmitkImageStatisticsWidget.h</header> <container>1</container> </customwidget> <customwidget> <class>QmitkHistogramVisualizationWidget</class> <extends>QWidget</extends> <header location="global">QmitkHistogramVisualizationWidget.h</header> <container>1</container> </customwidget> <customwidget> <class>QmitkIntensityProfileVisualizationWidget</class> <extends>QWidget</extends> <header location="global">QmitkIntensityProfileVisualizationWidget.h</header> <container>1</container> </customwidget> <customwidget> <class>ctkSliderWidget</class> <extends>QWidget</extends> <header location="global">ctkSliderWidget.h</header> <container>1</container> </customwidget> <customwidget> <class>QmitkMultiNodeSelectionWidget</class> <extends>QWidget</extends> <header location="global">QmitkMultiNodeSelectionWidget.h</header> <container>1</container> </customwidget> </customwidgets> <resources/> <connections/> </ui> diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/QmitkMultiLabelSegmentationPreferencePage.cpp b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/QmitkMultiLabelSegmentationPreferencePage.cpp index ae6433cdce..e384407c7c 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/QmitkMultiLabelSegmentationPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/QmitkMultiLabelSegmentationPreferencePage.cpp @@ -1,151 +1,156 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkMultiLabelSegmentationPreferencePage.h" #include <QLabel> #include <QPushButton> #include <QFormLayout> #include <QCheckBox> #include <QGroupBox> #include <QRadioButton> #include <QMessageBox> #include <QDoubleSpinBox> #include <berryIPreferencesService.h> #include <berryPlatform.h> QmitkMultiLabelSegmentationPreferencePage::QmitkMultiLabelSegmentationPreferencePage() : m_MainControl(nullptr), + m_SlimViewCheckBox(nullptr), m_RadioOutline(nullptr), m_RadioOverlay(nullptr), + m_SelectionModeCheckBox(nullptr), m_SmoothingSpinBox(nullptr), m_DecimationSpinBox(nullptr), - m_SelectionModeCheckBox(nullptr), m_Initializing(false) { } QmitkMultiLabelSegmentationPreferencePage::~QmitkMultiLabelSegmentationPreferencePage() { } void QmitkMultiLabelSegmentationPreferencePage::Init(berry::IWorkbench::Pointer ) { } void QmitkMultiLabelSegmentationPreferencePage::CreateQtControl(QWidget* parent) { m_Initializing = true; - berry::IPreferencesService* prefService - = berry::Platform::GetPreferencesService(); + berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); m_SegmentationPreferencesNode = prefService->GetSystemPreferences()->Node("/org.mitk.views.multilabelsegmentation"); m_MainControl = new QWidget(parent); + QFormLayout *formLayout = new QFormLayout; + formLayout->setHorizontalSpacing(8); + formLayout->setVerticalSpacing(24); + + m_SlimViewCheckBox = new QCheckBox("Hide tool button texts and increase icon size", m_MainControl); + formLayout->addRow("Slim view", m_SlimViewCheckBox); + QVBoxLayout* displayOptionsLayout = new QVBoxLayout; m_RadioOutline = new QRadioButton( "Draw as outline", m_MainControl); displayOptionsLayout->addWidget( m_RadioOutline ); m_RadioOverlay = new QRadioButton( "Draw as transparent overlay", m_MainControl); displayOptionsLayout->addWidget( m_RadioOverlay ); - - QFormLayout *formLayout = new QFormLayout; - formLayout->setHorizontalSpacing(8); - formLayout->setVerticalSpacing(24); formLayout->addRow( "2D display", displayOptionsLayout ); + m_SelectionModeCheckBox = new QCheckBox("Enable auto-selection mode", m_MainControl); + m_SelectionModeCheckBox->setToolTip("If checked the segmentation plugin ensures that only one segmentation and the according greyvalue image are visible at one time."); + formLayout->addRow("Data node selection mode", m_SelectionModeCheckBox); + QFormLayout* surfaceLayout = new QFormLayout; surfaceLayout->setSpacing(8); m_SmoothingSpinBox = new QDoubleSpinBox(m_MainControl); m_SmoothingSpinBox->setMinimum(0.0); m_SmoothingSpinBox->setSingleStep(0.5); m_SmoothingSpinBox->setValue(0.1); m_SmoothingSpinBox->setToolTip("The Smoothing value is used as Sigma for a gaussian blur."); surfaceLayout->addRow("Smoothing value (mm)", m_SmoothingSpinBox); m_DecimationSpinBox = new QDoubleSpinBox(m_MainControl); m_DecimationSpinBox->setMinimum(0.0); m_DecimationSpinBox->setMaximum(0.99); m_DecimationSpinBox->setSingleStep(0.1); m_DecimationSpinBox->setValue(0.5); m_DecimationSpinBox->setToolTip("Valid range is [0, 1). High values increase decimation, especially when very close to 1. A value of 0 disables decimation."); surfaceLayout->addRow("Decimation rate", m_DecimationSpinBox); - m_SelectionModeCheckBox = new QCheckBox("Enable auto-selection mode", m_MainControl); - m_SelectionModeCheckBox->setToolTip("If checked the segmentation plugin ensures that only one segmentation and the according greyvalue image are visible at one time."); - formLayout->addRow("Data node selection mode",m_SelectionModeCheckBox); - formLayout->addRow("Smoothed surface creation", surfaceLayout); m_MainControl->setLayout(formLayout); this->Update(); m_Initializing = false; } QWidget* QmitkMultiLabelSegmentationPreferencePage::GetQtControl() const { return m_MainControl; } bool QmitkMultiLabelSegmentationPreferencePage::PerformOk() { + m_SegmentationPreferencesNode->PutBool("slim view", m_SlimViewCheckBox->isChecked()); m_SegmentationPreferencesNode->PutBool("draw outline", m_RadioOutline->isChecked()); m_SegmentationPreferencesNode->PutDouble("smoothing value", m_SmoothingSpinBox->value()); m_SegmentationPreferencesNode->PutDouble("decimation rate", m_DecimationSpinBox->value()); m_SegmentationPreferencesNode->PutBool("auto selection", m_SelectionModeCheckBox->isChecked()); return true; } void QmitkMultiLabelSegmentationPreferencePage::PerformCancel() { } void QmitkMultiLabelSegmentationPreferencePage::Update() { - //m_EnableSingleEditing->setChecked(m_SegmentationPreferencesNode->GetBool("Single click property editing", true)); + m_SlimViewCheckBox->setChecked(m_SegmentationPreferencesNode->GetBool("slim view", false)); + if (m_SegmentationPreferencesNode->GetBool("draw outline", true) ) { - m_RadioOutline->setChecked( true ); + m_RadioOutline->setChecked(true); } else { - m_RadioOverlay->setChecked( true ); + m_RadioOverlay->setChecked(true); } + m_SelectionModeCheckBox->setChecked(m_SegmentationPreferencesNode->GetBool("auto selection", false)); + if (m_SegmentationPreferencesNode->GetBool("smoothing hint", true)) { m_SmoothingSpinBox->setDisabled(true); } else { m_SmoothingSpinBox->setEnabled(true); } - m_SelectionModeCheckBox->setChecked( m_SegmentationPreferencesNode->GetBool("auto selection", false) ); - m_SmoothingSpinBox->setValue(m_SegmentationPreferencesNode->GetDouble("smoothing value", 0.1)); m_DecimationSpinBox->setValue(m_SegmentationPreferencesNode->GetDouble("decimation rate", 0.5)); } void QmitkMultiLabelSegmentationPreferencePage::OnSmoothingCheckboxChecked(int state) { if (state != Qt::Unchecked) m_SmoothingSpinBox->setDisabled(true); else m_SmoothingSpinBox->setEnabled(true); } diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/QmitkMultiLabelSegmentationPreferencePage.h b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/QmitkMultiLabelSegmentationPreferencePage.h index 6eb6075a4e..ef52b83c76 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/QmitkMultiLabelSegmentationPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/QmitkMultiLabelSegmentationPreferencePage.h @@ -1,75 +1,67 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkMultiLabelSegmentationPreferencePage_h_included #define QmitkMultiLabelSegmentationPreferencePage_h_included #include "berryIQtPreferencePage.h" #include "org_mitk_gui_qt_multilabelsegmentation_Export.h" #include <berryIPreferences.h> class QWidget; class QCheckBox; class QRadioButton; class QDoubleSpinBox; class MITK_QT_SEGMENTATION QmitkMultiLabelSegmentationPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: QmitkMultiLabelSegmentationPreferencePage(); ~QmitkMultiLabelSegmentationPreferencePage() override; void Init(berry::IWorkbench::Pointer workbench) override; void CreateQtControl(QWidget* widget) override; QWidget* GetQtControl() const override; - /// - /// \see IPreferencePage::PerformOk() - /// bool PerformOk() override; - /// - /// \see IPreferencePage::PerformCancel() - /// void PerformCancel() override; - /// - /// \see IPreferencePage::Update() - /// void Update() override; protected slots: void OnSmoothingCheckboxChecked(int); protected: QWidget* m_MainControl; + QCheckBox* m_SlimViewCheckBox; QRadioButton* m_RadioOutline; QRadioButton* m_RadioOverlay; + QCheckBox* m_SelectionModeCheckBox; QDoubleSpinBox* m_SmoothingSpinBox; QDoubleSpinBox* m_DecimationSpinBox; - QCheckBox* m_SelectionModeCheckBox; bool m_Initializing; berry::IPreferences::Pointer m_SegmentationPreferencesNode; }; #endif /* QMITKDATAMANAGERPREFERENCEPAGE_H_ */ diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationControls.ui b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationControls.ui index 7bffe9ff5f..1b1ea78f8e 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationControls.ui +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationControls.ui @@ -1,827 +1,786 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>QmitkMultiLabelSegmentationControls</class> <widget class="QWidget" name="QmitkMultiLabelSegmentationControls"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>459</width> <height>844</height> </rect> </property> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>0</width> <height>0</height> </size> </property> - <property name="font"> - <font> - <family>MS Shell Dlg 2</family> - <pointsize>8</pointsize> - <weight>50</weight> - <italic>false</italic> - <bold>false</bold> - <underline>false</underline> - <strikeout>false</strikeout> - </font> - </property> <property name="windowTitle"> - <string>QmitkSegmentation</string> + <string>QmitkMultiLabelSegmentation</string> </property> <layout class="QVBoxLayout" name="verticalLayout_5"> <item> <widget class="QGroupBox" name="groupBox_DataSelection"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="title"> <string>Data Selection</string> </property> <layout class="QGridLayout" name="gridLayout"> <item row="0" column="0"> <widget class="QLabel" name="label_PatientImage"> <property name="text"> <string>Selected Image</string> </property> </widget> </item> <item row="0" column="1"> <widget class="QmitkSingleNodeSelectionWidget" name="m_ReferenceNodeSelector" native="true"> <property name="minimumSize"> <size> <width>0</width> <height>40</height> </size> </property> </widget> </item> <item row="0" column="2" rowspan="2"> <widget class="QToolButton" name="m_pbNewSegmentationSession"> <property name="toolTip"> <string>Create a new segmentation session</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../resources/multilabelsegmentation.qrc"> <normaloff>:/multilabelsegmentation/NewSegmentationSession_48x48.png</normaloff>:/multilabelsegmentation/NewSegmentationSession_48x48.png</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="shortcut"> <string>N</string> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item row="1" column="0"> <widget class="QLabel" name="label_Segmentation"> <property name="text"> <string>Segmentation</string> </property> </widget> </item> <item row="1" column="1"> <widget class="QmitkSingleNodeSelectionWidget" name="m_WorkingNodeSelector" native="true"> <property name="minimumSize"> <size> <width>0</width> <height>40</height> </size> </property> </widget> + </item> + <item row="2" column="0" colspan="3"> + <widget class="QLabel" name="lblSegmentationWarnings"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_Layer"> <property name="title"> <string>Layers</string> </property> <property name="flat"> <bool>true</bool> </property> <property name="checkable"> <bool>false</bool> </property> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QToolButton" name="m_btAddLayer"> <property name="toolTip"> <string>Add a layer to the current segmentation session</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../../../Modules/SegmentationUI/resources/SegmentationUI.qrc"> <normaloff>:/Qmitk/AddLayer_48x48.png</normaloff>:/Qmitk/AddLayer_48x48.png</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_btDeleteLayer"> <property name="toolTip"> <string>Delete the active layer</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../../../Modules/SegmentationUI/resources/SegmentationUI.qrc"> <normaloff>:/Qmitk/DeleteLayer_48x48.png</normaloff>:/Qmitk/DeleteLayer_48x48.png</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> <spacer name="horizontalSpacer1"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>0</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QToolButton" name="m_btPreviousLayer"> <property name="toolTip"> <string>Change to the previous available layer</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../../../Modules/SegmentationUI/resources/SegmentationUI.qrc"> <normaloff>:/Qmitk/PreviousLayer_48x48.png</normaloff>:/Qmitk/PreviousLayer_48x48.png</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_btNextLayer"> <property name="toolTip"> <string>Change to the next available layer</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../../../Modules/SegmentationUI/resources/SegmentationUI.qrc"> <normaloff>:/Qmitk/NextLayer_48x48.png</normaloff>:/Qmitk/NextLayer_48x48.png</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QComboBox" name="m_cbActiveLayer"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>50</width> <height>30</height> </size> </property> <property name="maximumSize"> <size> <width>40</width> <height>30</height> </size> </property> <property name="font"> <font> <family>MS Shell Dlg 2</family> <pointsize>12</pointsize> <weight>50</weight> <italic>false</italic> <bold>false</bold> <underline>false</underline> <strikeout>false</strikeout> </font> </property> <property name="toolTip"> <string>Switch to a layer</string> </property> <item> <property name="text"> <string>0</string> </property> </item> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_Labels"> <property name="title"> <string>Labels</string> </property> <property name="flat"> <bool>true</bool> </property> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> <widget class="QToolButton" name="m_pbNewLabel"> <property name="toolTip"> <string>Add a new label to the current segmentation session</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../resources/multilabelsegmentation.qrc"> <normaloff>:/multilabelsegmentation/NewLabel_48x48.png</normaloff>:/multilabelsegmentation/NewLabel_48x48.png</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="shortcut"> <string>N</string> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_btLockExterior"> <property name="toolTip"> <string>Lock/Unlock exterior</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../../../Modules/SegmentationUI/resources/SegmentationUI.qrc"> <normaloff>:/Qmitk/UnlockExterior_48x48.png</normaloff> <normalon>:/Qmitk/LockExterior_48x48.png</normalon>:/Qmitk/UnlockExterior_48x48.png</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="checkable"> <bool>true</bool> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_tbSavePreset"> <property name="toolTip"> <string>Save LabelSet Preset</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc"> <normaloff>:/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg</normaloff>:/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_tbLoadPreset"> <property name="toolTip"> <string>Load LabelSet Preset</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc"> <normaloff>:/org_mitk_icons/icons/awesome/scalable/actions/document-open.svg</normaloff>:/org_mitk_icons/icons/awesome/scalable/actions/document-open.svg</iconset> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>0</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QToolButton" name="m_pbShowLabelTable"> <property name="minimumSize"> <size> <width>0</width> <height>34</height> </size> </property> <property name="toolTip"> <string>Show a table with all labels in the current segmentation session</string> </property> <property name="text"> <string>>></string> </property> <property name="iconSize"> <size> <width>28</width> <height>28</height> </size> </property> <property name="checkable"> <bool>true</bool> </property> <property name="autoRaise"> <bool>false</bool> </property> <property name="arrowType"> <enum>Qt::NoArrow</enum> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QmitkLabelSetWidget" name="m_LabelSetWidget" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>0</width> <height>20</height> </size> </property> </widget> </item> <item> <widget class="QTabWidget" name="m_tw2DTools"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="styleSheet"> <string notr="true">QTabWidget::tab-bar { alignment: middle; }</string> </property> <property name="currentIndex"> <number>0</number> </property> - <property name="usesScrollButtons"> - <bool>true</bool> - </property> - <property name="documentMode"> - <bool>false</bool> - </property> <widget class="QWidget" name="m_tb2DTools"> <attribute name="title"> <string>2D Tools</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QmitkToolGUIArea" name="m_ManualToolGUIContainer2D" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> <widget class="QmitkToolSelectionBox" name="m_ManualToolSelectionBox2D" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> - <spacer name="verticalSpacer_2"> + <spacer name="verticalSpacer_1"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="tab_2"> <attribute name="title"> <string>3D Tools</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <widget class="QmitkToolGUIArea" name="m_ManualToolGUIContainer3D" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> <widget class="QmitkToolSelectionBox" name="m_ManualToolSelectionBox3D" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> - <spacer name="verticalSpacer_5"> + <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> </widget> </item> <item> <widget class="QGroupBox" name="m_gbInterpolation"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="title"> <string>Interpolation</string> </property> <layout class="QVBoxLayout" name="verticalLayout_4"> <property name="spacing"> <number>2</number> </property> <property name="sizeConstraint"> <enum>QLayout::SetMinimumSize</enum> </property> <property name="leftMargin"> <number>2</number> </property> <property name="topMargin"> <number>2</number> </property> <property name="rightMargin"> <number>2</number> </property> <property name="bottomMargin"> <number>2</number> </property> <item> <widget class="QComboBox" name="m_cbInterpolation"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <item> <property name="text"> <string>Disabled</string> </property> </item> <item> <property name="text"> <string>2D Interpolation</string> </property> </item> <item> <property name="text"> <string>3D Interpolation</string> </property> </item> </widget> </item> <item> <widget class="QStackedWidget" name="m_swInterpolation"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="currentIndex"> <number>1</number> </property> <widget class="QWidget" name="page_2"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <layout class="QVBoxLayout" name="verticalLayout_6"> <property name="sizeConstraint"> <enum>QLayout::SetMinimumSize</enum> </property> <property name="leftMargin"> <number>0</number> </property> <property name="topMargin"> <number>0</number> </property> <property name="rightMargin"> <number>0</number> </property> <property name="bottomMargin"> <number>0</number> </property> <item> <widget class="QmitkSliceBasedInterpolatorWidget" name="m_SliceBasedInterpolatorWidget" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>0</width> <height>0</height> </size> </property> - <property name="font"> - <font> - <family>MS Shell Dlg 2</family> - <pointsize>8</pointsize> - <weight>50</weight> - <italic>false</italic> - <bold>false</bold> - <underline>false</underline> - <strikeout>false</strikeout> - </font> - </property> </widget> </item> </layout> </widget> <widget class="QWidget" name="page_3"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <layout class="QVBoxLayout" name="verticalLayout_3"> - <property name="sizeConstraint"> - <enum>QLayout::SetMinimumSize</enum> - </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> <item> <widget class="QmitkSurfaceBasedInterpolatorWidget" name="m_SurfaceBasedInterpolatorWidget" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>0</width> <height>50</height> </size> </property> - <property name="font"> - <font> - <family>MS Shell Dlg 2</family> - <pointsize>8</pointsize> - <weight>50</weight> - <italic>false</italic> - <bold>false</bold> - <underline>false</underline> - <strikeout>false</strikeout> - </font> - </property> </widget> </item> </layout> </widget> <widget class="QWidget" name="page"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </widget> </item> </layout> </widget> </item> <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> <zorder>m_LabelSetWidget</zorder> <zorder>groupBox_DataSelection</zorder> <zorder>m_tw2DTools</zorder> <zorder>m_gbInterpolation</zorder> <zorder>groupBox_Layer</zorder> <zorder>groupBox_Labels</zorder> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> <customwidget> <class>QmitkSingleNodeSelectionWidget</class> <extends>QWidget</extends> <header location="global">QmitkSingleNodeSelectionWidget.h</header> <container>1</container> </customwidget> <customwidget> <class>QmitkToolSelectionBox</class> <extends>QWidget</extends> <header location="global">QmitkToolSelectionBox.h</header> </customwidget> <customwidget> <class>QmitkToolGUIArea</class> <extends>QWidget</extends> <header location="global">QmitkToolGUIArea.h</header> </customwidget> <customwidget> <class>QmitkLabelSetWidget</class> <extends>QWidget</extends> <header location="global">Qmitk/QmitkLabelSetWidget.h</header> <container>1</container> </customwidget> <customwidget> <class>QmitkSliceBasedInterpolatorWidget</class> <extends>QWidget</extends> <header location="global">QmitkSliceBasedInterpolatorWidget.h</header> <container>1</container> </customwidget> <customwidget> <class>QmitkSurfaceBasedInterpolatorWidget</class> <extends>QWidget</extends> <header location="global">QmitkSurfaceBasedInterpolatorWidget.h</header> <container>1</container> </customwidget> </customwidgets> <includes> <include location="global">QmitkToolGUIArea.h</include> <include location="global">QmitkToolSelectionBox.h</include> </includes> <resources> <include location="../../../../Modules/SegmentationUI/resources/SegmentationUI.qrc"/> <include location="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc"/> <include location="../../resources/multilabelsegmentation.qrc"/> <include location="../../../../Modules/SegmentationUI/resources/SegmentationUI.qrc"/> <include location="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc"/> <include location="../../resources/multilabelsegmentation.qrc"/> </resources> <connections/> </ui> diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.cpp b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.cpp index 7287bb2cef..0d02206bb5 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.cpp +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.cpp @@ -1,1093 +1,1213 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkMultiLabelSegmentationView.h" +#include "mitkPluginActivator.h" // blueberry -#include <berryConstants.h> #include <berryIWorkbenchPage.h> // mitk -#include "mitkApplicationCursor.h" -#include "mitkLabelSetImage.h" -#include "mitkStatusBar.h" -#include "mitkToolManagerProvider.h" -#include "mitkInteractionEventObserver.h" -#include "mitkPlanePositionManager.h" -#include "mitkPluginActivator.h" -#include "mitkSegTool2D.h" -#include "mitkImageTimeSelector.h" -#include "mitkNodePredicateSubGeometry.h" +#include <mitkApplicationCursor.h> +#include <mitkInteractionEventObserver.h> +#include <mitkImageTimeSelector.h> +#include <mitkLabelSetImage.h> +#include <mitkNodePredicateSubGeometry.h> +#include <mitkPlanePositionManager.h> +#include <mitkStatusBar.h> +#include <mitkToolManagerProvider.h> // Qmitk -#include <QmitkStyleManager.h> -#include "QmitkNewSegmentationDialog.h" -#include "QmitkRenderWindow.h" -#include "QmitkSegmentationOrganNamesHandling.cpp" #include "QmitkCreateMultiLabelPresetAction.h" #include "QmitkLoadMultiLabelPresetAction.h" +#include <QmitkNewSegmentationDialog.h> +#include <QmitkRenderWindow.h> +#include <QmitkSegmentationOrganNamesHandling.cpp> +#include <QmitkStyleManager.h> // us #include <usGetModuleContext.h> #include <usModule.h> #include <usModuleContext.h> #include <usModuleResource.h> #include <usModuleResourceStream.h> // Qt -#include <QDateTime> -#include <QFileDialog> #include <QInputDialog> #include <QMessageBox> #include <QShortcut> #include <itksys/SystemTools.hxx> #include <regex> const std::string QmitkMultiLabelSegmentationView::VIEW_ID = "org.mitk.views.multilabelsegmentation"; QmitkMultiLabelSegmentationView::QmitkMultiLabelSegmentationView() : m_Parent(nullptr), - m_IRenderWindowPart(nullptr), + m_RenderWindowPart(nullptr), m_ToolManager(nullptr), m_ReferenceNode(nullptr), m_WorkingNode(nullptr), m_AutoSelectionEnabled(false), m_MouseCursorSet(false) { - m_SegmentationPredicate = mitk::NodePredicateAnd::New(); - m_SegmentationPredicate->AddPredicate(mitk::TNodePredicateDataType<mitk::LabelSetImage>::New()); - m_SegmentationPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))); - m_SegmentationPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object"))); - - mitk::TNodePredicateDataType<mitk::Image>::Pointer isImage = mitk::TNodePredicateDataType<mitk::Image>::New(); - mitk::NodePredicateProperty::Pointer isBinary = - mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); - mitk::NodePredicateAnd::Pointer isMask = mitk::NodePredicateAnd::New(isBinary, isImage); - mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); - mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); - mitk::NodePredicateDataType::Pointer isOdf = mitk::NodePredicateDataType::New("OdfImage"); + auto isImage = mitk::TNodePredicateDataType<mitk::Image>::New(); + auto isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); + auto isDti = mitk::NodePredicateDataType::New("TensorImage"); + auto isOdf = mitk::NodePredicateDataType::New("OdfImage"); auto isSegment = mitk::NodePredicateDataType::New("Segment"); - mitk::NodePredicateOr::Pointer validImages = mitk::NodePredicateOr::New(); + auto validImages = mitk::NodePredicateOr::New(); validImages->AddPredicate(mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isSegment))); validImages->AddPredicate(isDwi); validImages->AddPredicate(isDti); validImages->AddPredicate(isOdf); + auto isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + auto isMask = mitk::NodePredicateAnd::New(isBinary, isImage); + + auto validSegmentations = mitk::NodePredicateOr::New(); + validSegmentations->AddPredicate(mitk::TNodePredicateDataType<mitk::LabelSetImage>::New()); + validSegmentations->AddPredicate(isMask); + + m_SegmentationPredicate = mitk::NodePredicateAnd::New(); + m_SegmentationPredicate->AddPredicate(validSegmentations); + m_SegmentationPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))); + m_SegmentationPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object"))); + m_ReferencePredicate = mitk::NodePredicateAnd::New(); m_ReferencePredicate->AddPredicate(validImages); m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(m_SegmentationPredicate)); - m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(isMask)); m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))); m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object"))); } QmitkMultiLabelSegmentationView::~QmitkMultiLabelSegmentationView() { - // Loose LabelSetConnections OnLooseLabelSetConnection(); -} - -void QmitkMultiLabelSegmentationView::CreateQtPartControl(QWidget *parent) -{ - // setup the basic GUI of this view - m_Parent = parent; - - m_Controls.setupUi(parent); - - m_Controls.m_tbSavePreset->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg"))); - m_Controls.m_tbLoadPreset->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-open.svg"))); - - // *------------------------ - // * Shortcuts - // *------------------------ - QShortcut* visibilityShortcut = new QShortcut(QKeySequence("CTRL+H"), parent); - connect(visibilityShortcut, &QShortcut::activated, this, &QmitkMultiLabelSegmentationView::OnVisibilityShortcutActivated); - QShortcut* labelToggleShortcut = new QShortcut(QKeySequence("CTRL+L"), parent); - connect(labelToggleShortcut, &QShortcut::activated, this, &QmitkMultiLabelSegmentationView::OnLabelToggleShortcutActivated); - - // *------------------------ - // * DATA SELECTION WIDGETS - // *------------------------ - - m_Controls.m_ReferenceNodeSelector->SetNodePredicate(m_ReferencePredicate); - m_Controls.m_ReferenceNodeSelector->SetDataStorage(this->GetDataStorage()); - m_Controls.m_ReferenceNodeSelector->SetInvalidInfo("Select an image"); - m_Controls.m_ReferenceNodeSelector->SetPopUpTitel("Select an image"); - m_Controls.m_ReferenceNodeSelector->SetPopUpHint("Select an image that should be used to define the geometry and bounds of the segmentation."); - - - m_Controls.m_WorkingNodeSelector->SetNodePredicate(m_SegmentationPredicate); - m_Controls.m_WorkingNodeSelector->SetDataStorage(this->GetDataStorage()); - m_Controls.m_WorkingNodeSelector->SetInvalidInfo("Select a segmentation"); - m_Controls.m_WorkingNodeSelector->SetPopUpTitel("Select a segmentation"); - m_Controls.m_WorkingNodeSelector->SetPopUpHint("Select a segmentation that should be modified. Only segmentation with the same geometry and within the bounds of the reference image are selected."); - - connect(m_Controls.m_ReferenceNodeSelector, - &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, - this,&QmitkMultiLabelSegmentationView::OnReferenceSelectionChanged); - connect(m_Controls.m_WorkingNodeSelector, - &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, - this,&QmitkMultiLabelSegmentationView::OnSegmentationSelectionChanged); - - // *------------------------ - // * ToolManager - // *------------------------ - - m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(mitk::ToolManagerProvider::MULTILABEL_SEGMENTATION); - m_ToolManager->SetDataStorage(*(this->GetDataStorage())); - m_ToolManager->InitializeTools(); - m_Controls.m_ManualToolSelectionBox2D->SetToolManager(*m_ToolManager); - m_Controls.m_ManualToolSelectionBox3D->SetToolManager(*m_ToolManager); - - // *------------------------ - // * LabelSetWidget - // *------------------------ - - m_Controls.m_LabelSetWidget->SetDataStorage(this->GetDataStorage()); - m_Controls.m_LabelSetWidget->SetOrganColors(mitk::OrganNamesHandling::GetDefaultOrganColorString()); - m_Controls.m_LabelSetWidget->hide(); - - // *------------------------ - // * Interpolation - // *------------------------ - - m_Controls.m_SurfaceBasedInterpolatorWidget->SetDataStorage(*(this->GetDataStorage())); - m_Controls.m_SliceBasedInterpolatorWidget->SetDataStorage(*(this->GetDataStorage())); - connect(m_Controls.m_cbInterpolation, SIGNAL(activated(int)), this, SLOT(OnInterpolationSelectionChanged(int))); - - m_Controls.m_cbInterpolation->setCurrentIndex(0); - m_Controls.m_swInterpolation->hide(); - m_Controls.m_gbInterpolation->hide(); // See T27436 - - QString segTools2D = tr("Add Subtract Fill Erase Paint Wipe 'Region Growing' FastMarching2D 'Live Wire'"); - QString segTools3D = tr("Threshold 'Two Thresholds' 'Auto Threshold' 'Multiple Otsu'"); - - std::regex extSegTool2DRegEx("SegTool2D$"); - std::regex extSegTool3DRegEx("SegTool3D$"); - - auto tools = m_ToolManager->GetTools(); - - for (const auto &tool : tools) + // removing all observers + for (NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter) { - if (std::regex_search(tool->GetNameOfClass(), extSegTool2DRegEx)) - { - segTools2D.append(QString(" '%1'").arg(tool->GetName())); - } - else if (std::regex_search(tool->GetNameOfClass(), extSegTool3DRegEx)) - { - segTools3D.append(QString(" '%1'").arg(tool->GetName())); - } + (*dataIter).first->GetProperty("visible")->RemoveObserver((*dataIter).second); } + m_WorkingDataObserverTags.clear(); - // *------------------------ - // * ToolSelection 2D - // *------------------------ - - m_Controls.m_ManualToolSelectionBox2D->SetGenerateAccelerators(true); - m_Controls.m_ManualToolSelectionBox2D->SetToolGUIArea(m_Controls.m_ManualToolGUIContainer2D); - m_Controls.m_ManualToolSelectionBox2D->SetDisplayedToolGroups(segTools2D.toStdString()); // todo: "Correction - // 'Live Wire'" - m_Controls.m_ManualToolSelectionBox2D->SetEnabledMode( - QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); - connect(m_Controls.m_ManualToolSelectionBox2D, SIGNAL(ToolSelected(int)), this, SLOT(OnManualTool2DSelected(int))); - - // *------------------------ - // * ToolSelection 3D - // *------------------------ - - m_Controls.m_ManualToolSelectionBox3D->SetGenerateAccelerators(true); - m_Controls.m_ManualToolSelectionBox3D->SetToolGUIArea(m_Controls.m_ManualToolGUIContainer3D); - m_Controls.m_ManualToolSelectionBox3D->SetDisplayedToolGroups(segTools3D.toStdString()); // todo add : FastMarching3D RegionGrowing Watershed - m_Controls.m_ManualToolSelectionBox3D->SetLayoutColumns(2); - m_Controls.m_ManualToolSelectionBox3D->SetEnabledMode( - QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); - - // *------------------------* - // * Connect PushButtons (pb) - // *------------------------* + mitk::RenderingManager::GetInstance()->RemoveObserver(m_RenderingManagerObserverTag); - connect(m_Controls.m_pbNewLabel, SIGNAL(clicked()), this, SLOT(OnNewLabel())); - connect(m_Controls.m_tbSavePreset, SIGNAL(clicked()), this, SLOT(OnSavePreset())); - connect(m_Controls.m_tbLoadPreset, SIGNAL(clicked()), this, SLOT(OnLoadPreset())); - connect(m_Controls.m_pbNewSegmentationSession, SIGNAL(clicked()), this, SLOT(OnNewSegmentationSession())); - connect(m_Controls.m_pbShowLabelTable, SIGNAL(toggled(bool)), this, SLOT(OnShowLabelTable(bool))); - - // *------------------------* - // * Connect LabelSetWidget - // *------------------------* + m_ToolManager->SetReferenceData(nullptr); + m_ToolManager->SetWorkingData(nullptr); +} - connect(m_Controls.m_LabelSetWidget, - SIGNAL(goToLabel(const mitk::Point3D &)), - this, - SLOT(OnGoToLabel(const mitk::Point3D &))); - connect(m_Controls.m_LabelSetWidget, SIGNAL(resetView()), this, SLOT(OnResetView())); +/**********************************************************************/ +/* private Q_SLOTS */ +/**********************************************************************/ +void QmitkMultiLabelSegmentationView::OnReferenceSelectionChanged(QList<mitk::DataNode::Pointer> nodes) +{ + m_ToolManager->ActivateTool(-1); - // *------------------------* - // * DATA SLECTION WIDGET - // *------------------------* - m_IRenderWindowPart = this->GetRenderWindowPart(); - if (m_IRenderWindowPart) + if (nodes.empty()) { - QList<mitk::SliceNavigationController *> controllers; - controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); - controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); - controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); - m_Controls.m_SliceBasedInterpolatorWidget->SetSliceNavigationControllers(controllers); + m_Controls.m_WorkingNodeSelector->SetNodePredicate(m_SegmentationPredicate); + m_ReferenceNode = nullptr; + m_ToolManager->SetReferenceData(m_ReferenceNode); + this->UpdateGUI(); + return; } - // this->InitializeListeners(); - - connect(m_Controls.m_btAddLayer, SIGNAL(clicked()), this, SLOT(OnAddLayer())); - connect(m_Controls.m_btDeleteLayer, SIGNAL(clicked()), this, SLOT(OnDeleteLayer())); - connect(m_Controls.m_btPreviousLayer, SIGNAL(clicked()), this, SLOT(OnPreviousLayer())); - connect(m_Controls.m_btNextLayer, SIGNAL(clicked()), this, SLOT(OnNextLayer())); - connect(m_Controls.m_btLockExterior, SIGNAL(toggled(bool)), this, SLOT(OnLockExteriorToggled(bool))); - connect(m_Controls.m_cbActiveLayer, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChangeLayer(int))); - - m_Controls.m_btAddLayer->setEnabled(false); - m_Controls.m_btDeleteLayer->setEnabled(false); - m_Controls.m_btNextLayer->setEnabled(false); - m_Controls.m_btPreviousLayer->setEnabled(false); - m_Controls.m_cbActiveLayer->setEnabled(false); + m_ReferenceNode = nodes.first(); + m_ToolManager->SetReferenceData(m_ReferenceNode); - m_Controls.m_pbNewLabel->setEnabled(false); - m_Controls.m_btLockExterior->setEnabled(false); - m_Controls.m_tbSavePreset->setEnabled(false); - m_Controls.m_tbLoadPreset->setEnabled(false); - m_Controls.m_pbShowLabelTable->setEnabled(false); + if (m_ReferenceNode.IsNotNull()) + { + // set a predicate such that a segmentation fits the selected reference image geometry + auto segPredicate = mitk::NodePredicateAnd::New(m_SegmentationPredicate.GetPointer(), + mitk::NodePredicateSubGeometry::New(m_ReferenceNode->GetData()->GetGeometry())); - // Make sure the GUI notices if appropriate data is already present on creation - m_Controls.m_ReferenceNodeSelector->SetAutoSelectNewNodes(true); - m_Controls.m_WorkingNodeSelector->SetAutoSelectNewNodes(true); -} + m_Controls.m_WorkingNodeSelector->SetNodePredicate(segPredicate); -void QmitkMultiLabelSegmentationView::Activated() -{ - m_ToolManager->SetReferenceData(m_Controls.m_ReferenceNodeSelector->GetSelectedNode()); - m_ToolManager->SetWorkingData(m_Controls.m_WorkingNodeSelector->GetSelectedNode()); -} + if (m_AutoSelectionEnabled) + { + // hide all image nodes to later show only the automatically selected ones + mitk::DataStorage::SetOfObjects::ConstPointer imageNodes = + this->GetDataStorage()->GetSubset(m_ReferencePredicate); + for (mitk::DataStorage::SetOfObjects::const_iterator iter = imageNodes->begin(); iter != imageNodes->end(); ++iter) + { + (*iter)->SetVisibility(false); + } + } + m_ReferenceNode->SetVisibility(true); + } -void QmitkMultiLabelSegmentationView::Deactivated() -{ - // Not yet implemented + this->UpdateGUI(); } -void QmitkMultiLabelSegmentationView::Visible() +void QmitkMultiLabelSegmentationView::OnSegmentationSelectionChanged(QList<mitk::DataNode::Pointer> nodes) { - // Not yet implemented -} + m_ToolManager->ActivateTool(-1); -void QmitkMultiLabelSegmentationView::Hidden() -{ - // Not yet implemented -} + if (nodes.empty()) + { + m_WorkingNode = nullptr; + m_ToolManager->SetWorkingData(m_WorkingNode); + this->UpdateGUI(); + return; + } -int QmitkMultiLabelSegmentationView::GetSizeFlags(bool width) -{ - if (!width) + if (m_ReferenceNode.IsNull()) { - return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL; + this->UpdateGUI(); + return; } - else + + mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image *>(m_ReferenceNode->GetData()); + if (referenceImage.IsNull()) { - return 0; + this->UpdateGUI(); + return; } -} -int QmitkMultiLabelSegmentationView::ComputePreferredSize(bool width, - int /*availableParallel*/, - int /*availablePerpendicular*/, - int preferredResult) -{ - if (width == false) + if (m_WorkingNode.IsNotNull()) { - return 100; + this->OnLooseLabelSetConnection(); } - else + + m_WorkingNode = nodes.first(); + m_ToolManager->SetWorkingData(m_WorkingNode); + + if (m_WorkingNode.IsNotNull()) { - return preferredResult; + if (m_AutoSelectionEnabled) + { + // hide all segmentation nodes to later show only the automatically selected ones + mitk::DataStorage::SetOfObjects::ConstPointer segmentationNodes = + this->GetDataStorage()->GetSubset(m_SegmentationPredicate); + for (mitk::DataStorage::SetOfObjects::const_iterator iter = segmentationNodes->begin(); iter != segmentationNodes->end(); ++iter) + { + (*iter)->SetVisibility(false); + } + } + m_WorkingNode->SetVisibility(true); + + this->OnEstablishLabelSetConnection(); + m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems(); + + this->InitializeRenderWindows(referenceImage->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, false); } + + this->UpdateGUI(); } -/************************************************************************/ -/* protected slots */ -/************************************************************************/ void QmitkMultiLabelSegmentationView::OnVisibilityShortcutActivated() { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); bool isVisible = false; workingNode->GetBoolProperty("visible", isVisible); workingNode->SetVisibility(!isVisible); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkMultiLabelSegmentationView::OnLabelToggleShortcutActivated() { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); - mitk::LabelSetImage* workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); - assert(workingImage); + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); + if (nullptr == workingImage) + { + return; + } WaitCursorOn(); workingImage->GetActiveLabelSet()->SetNextActiveLabel(); workingImage->Modified(); WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkMultiLabelSegmentationView::OnManualTool2DSelected(int id) { this->ResetMouseCursor(); mitk::StatusBar::GetInstance()->DisplayText(""); if (id >= 0) { std::string text = "Active Tool: \""; text += m_ToolManager->GetToolById(id)->GetName(); text += "\""; mitk::StatusBar::GetInstance()->DisplayText(text.c_str()); us::ModuleResource resource = m_ToolManager->GetToolById(id)->GetCursorIconResource(); this->SetMouseCursor(resource, 0, 0); } } void QmitkMultiLabelSegmentationView::OnNewLabel() { m_ToolManager->ActivateTool(-1); if (m_ReferenceNode.IsNull()) { QMessageBox::information( - m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action."); + m_Parent, "New Segmentation", "Please load and select an image before starting some action."); return; } mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image *>(m_ReferenceNode->GetData()); if (referenceImage.IsNull()) { QMessageBox::information( - m_Parent, "New Segmentation Session", "Reference data needs to be an image in order to create a new segmentation."); + m_Parent, "New segmentation", "Reference data needs to be an image in order to create a new segmentation."); return; } mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); if (!workingNode) { QMessageBox::information( - m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action."); + m_Parent, "New segmentation", "Please load and select a multilabel segmentation before starting some action."); return; } mitk::LabelSetImage* workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); if (!workingImage) { QMessageBox::information( - m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action."); + m_Parent, "New segmentation", "Please load and select a multilabel segmentation before starting some action."); return; } - QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog(m_Parent); - dialog->SetSuggestionList(mitk::OrganNamesHandling::GetDefaultOrganColorString()); + // ask about the name and organ type of the new segmentation + auto dialog = new QmitkNewSegmentationDialog(m_Parent); + QStringList organColors = mitk::OrganNamesHandling::GetDefaultOrganColorString(); + dialog->SetSuggestionList(organColors); dialog->setWindowTitle("New Label"); int dialogReturnValue = dialog->exec(); if (dialogReturnValue == QDialog::Rejected) { return; } QString segName = dialog->GetSegmentationName(); if (segName.isEmpty()) { segName = "Unnamed"; } workingImage->GetActiveLabelSet()->AddLabel(segName.toStdString(), dialog->GetColor()); - UpdateControls(); + UpdateGUI(); m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems(); this->InitializeRenderWindows(referenceImage->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, false); } void QmitkMultiLabelSegmentationView::OnSavePreset() { QmitkAbstractNodeSelectionWidget::NodeList nodes; nodes.append(m_WorkingNode); QmitkCreateMultiLabelPresetAction action; action.Run(nodes); } void QmitkMultiLabelSegmentationView::OnLoadPreset() { QmitkAbstractNodeSelectionWidget::NodeList nodes; nodes.append(m_WorkingNode); QmitkLoadMultiLabelPresetAction action; action.Run(nodes); } void QmitkMultiLabelSegmentationView::OnShowLabelTable(bool value) { if (value) m_Controls.m_LabelSetWidget->show(); else m_Controls.m_LabelSetWidget->hide(); } void QmitkMultiLabelSegmentationView::OnNewSegmentationSession() { - mitk::DataNode *referenceNode = m_Controls.m_ReferenceNodeSelector->GetSelectedNode(); + mitk::DataNode::Pointer referenceNode = m_ToolManager->GetReferenceData(0); + if (referenceNode.IsNull()) + { + MITK_ERROR << "'Create new segmentation' button should never be clickable unless a reference image is selected."; + return; + } - if (!referenceNode) + mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image *>(referenceNode->GetData()); + if (referenceImage.IsNull()) { QMessageBox::information( - m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action."); + m_Parent, "New segmentation", "Please load and select an image before starting some action."); return; } - m_ToolManager->ActivateTool(-1); - - mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image*>(referenceNode->GetData()); - assert(referenceImage); + if (referenceImage->GetDimension() <= 1) + { + QMessageBox::information(m_Parent, "New segmentation", "Segmentation is currently not supported for 2D images"); + return; + } const auto currentTimePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); unsigned int imageTimeStep = 0; if (referenceImage->GetTimeGeometry()->IsValidTimePoint(currentTimePoint)) { imageTimeStep = referenceImage->GetTimeGeometry()->TimePointToTimeStep(currentTimePoint); } auto segTemplateImage = referenceImage; if (referenceImage->GetDimension() > 3) { - auto result = QMessageBox::question(m_Parent, tr("Create a static or dynamic segmentation?"), tr("The patient image has multiple time steps.\n\nDo you want to create a static segmentation that is identical for all time steps or do you want to create a dynamic segmentation to segment individual time steps?"), tr("Create static segmentation"), tr("Create dynamic segmentation"), QString(), 0, 0); + auto result = QMessageBox::question(m_Parent, + tr("Create a static or dynamic segmentation?"), + tr("The selected image has multiple time steps.\n\nDo you want to create a static " + "segmentation that is identical for all time steps or do you want to create a " + "dynamic segmentation to segment individual time steps?"), + tr("Create static segmentation"), tr("Create dynamic segmentation"), + QString(), 0, 0); if (result == 0) { auto selector = mitk::ImageTimeSelector::New(); selector->SetInput(referenceImage); selector->SetTimeNr(0); selector->Update(); const auto refTimeGeometry = referenceImage->GetTimeGeometry(); auto newTimeGeometry = mitk::ProportionalTimeGeometry::New(); newTimeGeometry->SetFirstTimePoint(refTimeGeometry->GetMinimumTimePoint()); newTimeGeometry->SetStepDuration(refTimeGeometry->GetMaximumTimePoint() - refTimeGeometry->GetMinimumTimePoint()); mitk::Image::Pointer newImage = selector->GetOutput(); newTimeGeometry->SetTimeStepGeometry(referenceImage->GetGeometry(imageTimeStep), 0); newImage->SetTimeGeometry(newTimeGeometry); segTemplateImage = newImage; } } QString newName = QString::fromStdString(referenceNode->GetName()); newName.append("-labels"); bool ok = false; - newName = QInputDialog::getText(m_Parent, "New Segmentation Session", "New name:", QLineEdit::Normal, newName, &ok); + newName = QInputDialog::getText(m_Parent, "New segmentation", "New name:", QLineEdit::Normal, newName, &ok); if (!ok) { return; } + if (newName.isEmpty()) + { + newName = "Unnamed"; + } + this->WaitCursorOn(); mitk::LabelSetImage::Pointer workingImage = mitk::LabelSetImage::New(); try { workingImage->Initialize(segTemplateImage); } catch (mitk::Exception& e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); - QMessageBox::information(m_Parent, "New Segmentation Session", "Could not create a new segmentation session.\n"); + QMessageBox::information(m_Parent, tr("New segmentation"), tr("Could not create a new segmentation.\n")); return; } this->WaitCursorOff(); mitk::DataNode::Pointer workingNode = mitk::DataNode::New(); workingNode->SetData(workingImage); workingNode->SetName(newName.toStdString()); workingImage->GetExteriorLabel()->SetProperty("name.parent", mitk::StringProperty::New(referenceNode->GetName().c_str())); workingImage->GetExteriorLabel()->SetProperty("name.image", mitk::StringProperty::New(newName.toStdString().c_str())); - if (!GetDataStorage()->Exists(workingNode)) - { - GetDataStorage()->Add(workingNode, referenceNode); - } + this->GetDataStorage()->Add(workingNode, referenceNode); m_Controls.m_WorkingNodeSelector->SetCurrentSelectedNode(workingNode); OnNewLabel(); } void QmitkMultiLabelSegmentationView::OnGoToLabel(const mitk::Point3D& pos) { - if (m_IRenderWindowPart) - m_IRenderWindowPart->SetSelectedPosition(pos); + if (m_RenderWindowPart) + m_RenderWindowPart->SetSelectedPosition(pos); } void QmitkMultiLabelSegmentationView::OnResetView() { - if (m_IRenderWindowPart) - m_IRenderWindowPart->ForceImmediateUpdate(); + if (m_RenderWindowPart) + m_RenderWindowPart->ForceImmediateUpdate(); } void QmitkMultiLabelSegmentationView::OnAddLayer() { m_ToolManager->ActivateTool(-1); mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); - mitk::LabelSetImage* workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); - assert(workingImage); + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); + if (nullptr == workingImage) + { + return; + } QString question = "Do you really want to add a layer to the current segmentation session?"; QMessageBox::StandardButton answerButton = QMessageBox::question( m_Controls.m_LabelSetWidget, "Add layer", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton != QMessageBox::Yes) return; try { WaitCursorOn(); workingImage->AddLayer(); WaitCursorOff(); } catch ( mitk::Exception& e ) { WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information( m_Controls.m_LabelSetWidget, "Add Layer", "Could not add a new layer. See error log for details.\n"); return; } OnNewLabel(); } void QmitkMultiLabelSegmentationView::OnDeleteLayer() { m_ToolManager->ActivateTool(-1); mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); - mitk::LabelSetImage* workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); - assert(workingImage); + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); + if (nullptr == workingImage) + { + return; + } if (workingImage->GetNumberOfLayers() < 2) return; QString question = "Do you really want to delete the current layer?"; QMessageBox::StandardButton answerButton = QMessageBox::question( m_Controls.m_LabelSetWidget, "Delete layer", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton != QMessageBox::Yes) { return; } try { this->WaitCursorOn(); workingImage->RemoveLayer(); this->WaitCursorOff(); } catch (mitk::Exception& e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(m_Controls.m_LabelSetWidget, "Delete Layer", "Could not delete the currently active layer. See error log for details.\n"); return; } - UpdateControls(); + UpdateGUI(); m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems(); } void QmitkMultiLabelSegmentationView::OnPreviousLayer() { m_ToolManager->ActivateTool(-1); mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); - mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData()); - assert(workingImage); + + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); + if (nullptr == workingImage) + { + return; + } OnChangeLayer(workingImage->GetActiveLayer() - 1); } void QmitkMultiLabelSegmentationView::OnNextLayer() { m_ToolManager->ActivateTool(-1); mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); - mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData()); - assert(workingImage); + + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); + if (nullptr == workingImage) + { + return; + } OnChangeLayer(workingImage->GetActiveLayer() + 1); } void QmitkMultiLabelSegmentationView::OnChangeLayer(int layer) { m_ToolManager->ActivateTool(-1); mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); - mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData()); - assert(workingImage); + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); + if (nullptr == workingImage) + { + return; + } this->WaitCursorOn(); workingImage->SetActiveLayer(layer); this->WaitCursorOff(); - UpdateControls(); + UpdateGUI(); m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems(); } -void QmitkMultiLabelSegmentationView::OnDeactivateActiveTool() -{ - m_ToolManager->ActivateTool(-1); -} - void QmitkMultiLabelSegmentationView::OnLockExteriorToggled(bool checked) { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); - mitk::LabelSetImage* workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); - assert(workingImage); + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); + if (nullptr == workingImage) + { + return; + } workingImage->GetLabel(0)->SetLocked(checked); } -void QmitkMultiLabelSegmentationView::OnReferenceSelectionChanged(QList<mitk::DataNode::Pointer> /*nodes*/) +void QmitkMultiLabelSegmentationView::OnInterpolationSelectionChanged(int index) { - m_ToolManager->ActivateTool(-1); - - auto refNode = m_Controls.m_ReferenceNodeSelector->GetSelectedNode(); - m_ReferenceNode = refNode; - m_ToolManager->SetReferenceData(m_ReferenceNode); - - if (m_ReferenceNode.IsNotNull()) + if (index == 1) { - auto segPredicate = mitk::NodePredicateAnd::New(m_SegmentationPredicate.GetPointer(), mitk::NodePredicateSubGeometry::New(refNode->GetData()->GetGeometry())); + m_Controls.m_SurfaceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false);//OnToggleWidgetActivation(false); + m_Controls.m_swInterpolation->setCurrentIndex(0); + m_Controls.m_swInterpolation->show(); + } + else if (index == 2) + { + m_Controls.m_SliceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false); + m_Controls.m_swInterpolation->setCurrentIndex(1); + m_Controls.m_swInterpolation->show(); + } + else + { + m_Controls.m_SurfaceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false); + m_Controls.m_SliceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false); + m_Controls.m_swInterpolation->setCurrentIndex(2); + m_Controls.m_swInterpolation->hide(); + } +} - m_Controls.m_WorkingNodeSelector->SetNodePredicate(segPredicate); +/**********************************************************************/ +/* private */ +/**********************************************************************/ +void QmitkMultiLabelSegmentationView::CreateQtPartControl(QWidget *parent) +{ + m_Parent = parent; - if (m_AutoSelectionEnabled) + m_Controls.setupUi(parent); + + m_Controls.m_tbSavePreset->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg"))); + m_Controls.m_tbLoadPreset->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-open.svg"))); + + // *------------------------ + // * Shortcuts + // *------------------------ + QShortcut* visibilityShortcut = new QShortcut(QKeySequence("CTRL+H"), parent); + connect(visibilityShortcut, &QShortcut::activated, this, &QmitkMultiLabelSegmentationView::OnVisibilityShortcutActivated); + QShortcut* labelToggleShortcut = new QShortcut(QKeySequence("CTRL+L"), parent); + connect(labelToggleShortcut, &QShortcut::activated, this, &QmitkMultiLabelSegmentationView::OnLabelToggleShortcutActivated); + + // *------------------------ + // * DATA SELECTION WIDGETS + // *------------------------ + + m_Controls.m_ReferenceNodeSelector->SetDataStorage(this->GetDataStorage()); + m_Controls.m_ReferenceNodeSelector->SetNodePredicate(m_ReferencePredicate); + m_Controls.m_ReferenceNodeSelector->SetInvalidInfo("Select an image"); + m_Controls.m_ReferenceNodeSelector->SetPopUpTitel("Select an image"); + m_Controls.m_ReferenceNodeSelector->SetPopUpHint("Select an image that should be used to define the geometry and bounds of the segmentation."); + + m_Controls.m_WorkingNodeSelector->SetDataStorage(this->GetDataStorage()); + m_Controls.m_WorkingNodeSelector->SetNodePredicate(m_SegmentationPredicate); + m_Controls.m_WorkingNodeSelector->SetInvalidInfo("Select a segmentation"); + m_Controls.m_WorkingNodeSelector->SetPopUpTitel("Select a segmentation"); + m_Controls.m_WorkingNodeSelector->SetPopUpHint("Select a segmentation that should be modified. Only segmentation with the same geometry and within the bounds of the reference image are selected."); + + connect(m_Controls.m_ReferenceNodeSelector, + &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, + this, &QmitkMultiLabelSegmentationView::OnReferenceSelectionChanged); + connect(m_Controls.m_WorkingNodeSelector, + &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, + this, &QmitkMultiLabelSegmentationView::OnSegmentationSelectionChanged); + + // *------------------------ + // * ToolManager + // *------------------------ + + m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(mitk::ToolManagerProvider::MULTILABEL_SEGMENTATION); + m_ToolManager->SetDataStorage(*(this->GetDataStorage())); + m_ToolManager->InitializeTools(); + m_Controls.m_ManualToolSelectionBox2D->SetToolManager(*m_ToolManager); + m_Controls.m_ManualToolSelectionBox3D->SetToolManager(*m_ToolManager); + + // *------------------------ + // * LabelSetWidget + // *------------------------ + + m_Controls.m_LabelSetWidget->SetDataStorage(this->GetDataStorage()); + m_Controls.m_LabelSetWidget->SetOrganColors(mitk::OrganNamesHandling::GetDefaultOrganColorString()); + m_Controls.m_LabelSetWidget->hide(); + + // *------------------------ + // * Interpolation + // *------------------------ + + m_Controls.m_SurfaceBasedInterpolatorWidget->SetDataStorage(*(this->GetDataStorage())); + m_Controls.m_SliceBasedInterpolatorWidget->SetDataStorage(*(this->GetDataStorage())); + connect(m_Controls.m_cbInterpolation, QOverload<int>::of(&QComboBox::activated), this, &QmitkMultiLabelSegmentationView::OnInterpolationSelectionChanged); + + m_Controls.m_cbInterpolation->setCurrentIndex(0); + m_Controls.m_swInterpolation->hide(); + + m_Controls.m_gbInterpolation->hide(); // See T27436 + + QString segTools2D = tr("Add Subtract Fill Erase Paint Wipe 'Region Growing' 'Live Wire'"); + QString segTools3D = tr("Threshold"); + + std::regex extSegTool2DRegEx("SegTool2D$"); + std::regex extSegTool3DRegEx("SegTool3D$"); + + auto tools = m_ToolManager->GetTools(); + for (const auto &tool : tools) + { + if (std::regex_search(tool->GetNameOfClass(), extSegTool2DRegEx)) { - // hide all image nodes to later show only the automatically selected ones - mitk::DataStorage::SetOfObjects::ConstPointer patientNodes = GetDataStorage()->GetSubset(m_ReferencePredicate); - for (mitk::DataStorage::SetOfObjects::const_iterator iter = patientNodes->begin(); iter != patientNodes->end(); ++iter) - { - (*iter)->SetVisibility(false); - } + segTools2D.append(QString(" '%1'").arg(tool->GetName())); + } + else if (std::regex_search(tool->GetNameOfClass(), extSegTool3DRegEx)) + { + segTools3D.append(QString(" '%1'").arg(tool->GetName())); } - m_ReferenceNode->SetVisibility(true); } - UpdateControls(); -} + // *------------------------ + // * ToolSelection 2D + // *------------------------ -void QmitkMultiLabelSegmentationView::OnSegmentationSelectionChanged(QList<mitk::DataNode::Pointer> /*nodes*/) -{ - m_ToolManager->ActivateTool(-1); + m_Controls.m_ManualToolSelectionBox2D->SetGenerateAccelerators(true); + m_Controls.m_ManualToolSelectionBox2D->SetToolGUIArea(m_Controls.m_ManualToolGUIContainer2D); + m_Controls.m_ManualToolSelectionBox2D->SetDisplayedToolGroups(segTools2D.toStdString()); + m_Controls.m_ManualToolSelectionBox2D->SetLayoutColumns(3); + m_Controls.m_ManualToolSelectionBox2D->SetEnabledMode( + QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); + connect(m_Controls.m_ManualToolSelectionBox2D, &QmitkToolSelectionBox::ToolSelected, + this, &QmitkMultiLabelSegmentationView::OnManualTool2DSelected); - if (m_ReferenceNode.IsNull()) - { - QMessageBox::information( - m_Parent, "Selected segmentation changed", "Please load and select a patient image before starting some action."); - return; - } + // *------------------------ + // * ToolSelection 3D + // *------------------------ - mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image *>(m_ReferenceNode->GetData()); - if (referenceImage.IsNull()) - { - QMessageBox::information( - m_Parent, "Selected segmentation changed", "Reference data needs to be an image in order to create a new segmentation."); - return; - } + m_Controls.m_ManualToolSelectionBox3D->SetGenerateAccelerators(true); + m_Controls.m_ManualToolSelectionBox3D->SetToolGUIArea(m_Controls.m_ManualToolGUIContainer3D); + m_Controls.m_ManualToolSelectionBox3D->SetDisplayedToolGroups(segTools3D.toStdString()); // todo add : FastMarching3D RegionGrowing Watershed + m_Controls.m_ManualToolSelectionBox3D->SetLayoutColumns(3); + m_Controls.m_ManualToolSelectionBox3D->SetEnabledMode( + QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); - if (m_WorkingNode.IsNotNull()) - OnLooseLabelSetConnection(); + // *------------------------* + // * Connect Buttons + // *------------------------* - m_WorkingNode = m_Controls.m_WorkingNodeSelector->GetSelectedNode(); - m_ToolManager->SetWorkingData(m_WorkingNode); - if (m_WorkingNode.IsNotNull()) - { - OnEstablishLabelSetConnection(); + connect(m_Controls.m_pbNewLabel, &QToolButton::clicked, this, &QmitkMultiLabelSegmentationView::OnNewLabel); + connect(m_Controls.m_tbSavePreset, &QToolButton::clicked, this, &QmitkMultiLabelSegmentationView::OnSavePreset); + connect(m_Controls.m_tbLoadPreset, &QToolButton::clicked, this, &QmitkMultiLabelSegmentationView::OnLoadPreset); + connect(m_Controls.m_pbNewSegmentationSession, &QToolButton::clicked, this, &QmitkMultiLabelSegmentationView::OnNewSegmentationSession); + connect(m_Controls.m_pbShowLabelTable, &QToolButton::toggled, this, &QmitkMultiLabelSegmentationView::OnShowLabelTable); - if (m_AutoSelectionEnabled) - { - // hide all segmentation nodes to later show only the automatically selected ones - mitk::DataStorage::SetOfObjects::ConstPointer segmentationNodes = GetDataStorage()->GetSubset(m_SegmentationPredicate); - for (mitk::DataStorage::SetOfObjects::const_iterator iter = segmentationNodes->begin(); iter != segmentationNodes->end(); ++iter) - { - (*iter)->SetVisibility(false); - } - } - m_WorkingNode->SetVisibility(true); + // *------------------------* + // * Connect LabelSetWidget + // *------------------------* + + connect(m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::goToLabel, + this, &QmitkMultiLabelSegmentationView::OnGoToLabel); + connect(m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::resetView, + this, &QmitkMultiLabelSegmentationView::OnResetView); + + // *------------------------* + // * DATA SLECTION WIDGET + // *------------------------* + + connect(m_Controls.m_btAddLayer, &QToolButton::clicked, this, &QmitkMultiLabelSegmentationView::OnAddLayer); + connect(m_Controls.m_btDeleteLayer, &QToolButton::clicked, this, &QmitkMultiLabelSegmentationView::OnDeleteLayer); + connect(m_Controls.m_btPreviousLayer, &QToolButton::clicked, this, &QmitkMultiLabelSegmentationView::OnPreviousLayer); + connect(m_Controls.m_btNextLayer, &QToolButton::clicked, this, &QmitkMultiLabelSegmentationView::OnNextLayer); + connect(m_Controls.m_btLockExterior, &QToolButton::toggled, this, &QmitkMultiLabelSegmentationView::OnLockExteriorToggled); + connect(m_Controls.m_cbActiveLayer, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QmitkMultiLabelSegmentationView::OnChangeLayer); + + m_Controls.m_btAddLayer->setEnabled(false); + m_Controls.m_btDeleteLayer->setEnabled(false); + m_Controls.m_btNextLayer->setEnabled(false); + m_Controls.m_btPreviousLayer->setEnabled(false); + m_Controls.m_cbActiveLayer->setEnabled(false); + + m_Controls.m_pbNewLabel->setEnabled(false); + m_Controls.m_btLockExterior->setEnabled(false); + m_Controls.m_tbSavePreset->setEnabled(false); + m_Controls.m_tbLoadPreset->setEnabled(false); + m_Controls.m_pbShowLabelTable->setEnabled(false); + + // set callback function for already existing segmentation nodes + mitk::DataStorage::SetOfObjects::ConstPointer allSegmentations = GetDataStorage()->GetSubset(m_SegmentationPredicate); + for (mitk::DataStorage::SetOfObjects::const_iterator iter = allSegmentations->begin(); iter != allSegmentations->end(); ++iter) + { + mitk::DataNode* node = *iter; + auto command = itk::SimpleMemberCommand<QmitkMultiLabelSegmentationView>::New(); + command->SetCallbackFunction(this, &QmitkMultiLabelSegmentationView::ValidateSelectionInput); + m_WorkingDataObserverTags.insert(std::pair<mitk::DataNode *, unsigned long>( + node, node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command))); } - UpdateControls(); - if (m_WorkingNode.IsNotNull()) + auto command = itk::SimpleMemberCommand<QmitkMultiLabelSegmentationView>::New(); + command->SetCallbackFunction(this, &QmitkMultiLabelSegmentationView::ValidateSelectionInput); + m_RenderingManagerObserverTag = + mitk::RenderingManager::GetInstance()->AddObserver(mitk::RenderingManagerViewsInitializedEvent(), command); + + m_RenderWindowPart = this->GetRenderWindowPart(); + if (nullptr != m_RenderWindowPart) { - m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems(); - this->InitializeRenderWindows(referenceImage->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, false); + this->RenderWindowPartActivated(m_RenderWindowPart); } + + // Make sure the GUI notices if appropriate data is already present on creation. + // Should be done last, if everything else is configured because it triggers the autoselection of data. + m_Controls.m_ReferenceNodeSelector->SetAutoSelectNewNodes(true); + m_Controls.m_WorkingNodeSelector->SetAutoSelectNewNodes(true); + + this->UpdateGUI(); } -void QmitkMultiLabelSegmentationView::OnInterpolationSelectionChanged(int index) +void QmitkMultiLabelSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { - if (index == 1) + if (m_RenderWindowPart != renderWindowPart) { - m_Controls.m_SurfaceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false);//OnToggleWidgetActivation(false); - m_Controls.m_swInterpolation->setCurrentIndex(0); - m_Controls.m_swInterpolation->show(); + m_RenderWindowPart = renderWindowPart; } - else if (index == 2) + + if (m_Parent) { - m_Controls.m_SliceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false); - m_Controls.m_swInterpolation->setCurrentIndex(1); - m_Controls.m_swInterpolation->show(); + m_Parent->setEnabled(true); } - else + + // tell the interpolation about tool manager, data storage and render window part + QList<mitk::SliceNavigationController *> controllers; + controllers.push_back(m_RenderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); + controllers.push_back(m_RenderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); + controllers.push_back(m_RenderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); + m_Controls.m_SliceBasedInterpolatorWidget->SetSliceNavigationControllers(controllers); +} + +void QmitkMultiLabelSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/) +{ + m_RenderWindowPart = nullptr; + if (m_Parent) { - m_Controls.m_SurfaceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false); - m_Controls.m_SliceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false); - m_Controls.m_swInterpolation->setCurrentIndex(2); - m_Controls.m_swInterpolation->hide(); + m_Parent->setEnabled(false); } } -/************************************************************************/ -/* protected */ -/************************************************************************/ void QmitkMultiLabelSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { - m_AutoSelectionEnabled = prefs->GetBool("auto selection", false); + bool slimView = prefs->GetBool("slim view", false); + m_Controls.m_ManualToolSelectionBox2D->SetShowNames(!slimView); + m_Controls.m_ManualToolSelectionBox3D->SetShowNames(!slimView); - mitk::BoolProperty::Pointer drawOutline = mitk::BoolProperty::New(prefs->GetBool("draw outline", true)); - mitk::LabelSetImage* labelSetImage; - mitk::DataNode* segmentation; - - // iterate all segmentations (binary (single label) and LabelSetImages) - mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); - mitk::NodePredicateOr::Pointer allSegmentationsPredicate = mitk::NodePredicateOr::New(isBinaryPredicate, m_SegmentationPredicate); - mitk::DataStorage::SetOfObjects::ConstPointer allSegmentations = GetDataStorage()->GetSubset(allSegmentationsPredicate); + m_AutoSelectionEnabled = prefs->GetBool("auto selection", false); - for (mitk::DataStorage::SetOfObjects::const_iterator it = allSegmentations->begin(); it != allSegmentations->end(); ++it) - { - segmentation = *it; - labelSetImage = dynamic_cast<mitk::LabelSetImage*>(segmentation->GetData()); - if (nullptr != labelSetImage) - { - // segmentation node is a multi label segmentation - segmentation->SetProperty("labelset.contour.active", drawOutline); - //segmentation->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f)); - // force render window update to show outline - segmentation->GetData()->Modified(); - } - else if (nullptr != segmentation->GetData()) - { - // node is actually a 'single label' segmentation, - // but its outline property can be set in the 'multi label' segmentation preference page as well - bool isBinary = false; - segmentation->GetBoolProperty("binary", isBinary); - if (isBinary) - { - segmentation->SetProperty("outline binary", drawOutline); - segmentation->SetProperty("outline width", mitk::FloatProperty::New(2.0)); - //segmentation->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f)); - // force render window update to show outline - segmentation->GetData()->Modified(); - } - } - } + this->ApplyDisplayOptions(); } -void QmitkMultiLabelSegmentationView::NodeRemoved(const mitk::DataNode *node) +void QmitkMultiLabelSegmentationView::NodeAdded(const mitk::DataNode* node) { - bool isHelperObject(false); - node->GetBoolProperty("helper object", isHelperObject); - if (isHelperObject) + if (!m_SegmentationPredicate->CheckNode(node)) { return; } - if (m_ReferenceNode.IsNotNull() && dynamic_cast<mitk::LabelSetImage *>(node->GetData())) + auto command = itk::SimpleMemberCommand<QmitkMultiLabelSegmentationView>::New(); + command->SetCallbackFunction(this, &QmitkMultiLabelSegmentationView::ValidateSelectionInput); + m_WorkingDataObserverTags.insert(std::pair<mitk::DataNode *, unsigned long>( + const_cast<mitk::DataNode *>(node), node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command))); + + ApplyDisplayOptions(const_cast<mitk::DataNode*>(node)); +} + +void QmitkMultiLabelSegmentationView::NodeRemoved(const mitk::DataNode* node) +{ + if (m_SegmentationPredicate->CheckNode(node)) { // remove all possible contour markers of the segmentation mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations( node, mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true))); ctkPluginContext *context = mitk::PluginActivator::getContext(); ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>(); mitk::PlanePositionManagerService *service = context->getService<mitk::PlanePositionManagerService>(ppmRef); for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it) { std::string nodeName = node->GetName(); unsigned int t = nodeName.find_last_of(" "); unsigned int id = atof(nodeName.substr(t + 1).c_str()) - 1; service->RemovePlanePosition(id); this->GetDataStorage()->Remove(it->Value()); } context->ungetService(ppmRef); service = nullptr; } + + mitk::DataNode* tempNode = const_cast<mitk::DataNode*>(node); + //Remove observer if one was registered + auto finding = m_WorkingDataObserverTags.find(tempNode); + if (finding != m_WorkingDataObserverTags.end()) + { + node->GetProperty("visible")->RemoveObserver(m_WorkingDataObserverTags[tempNode]); + m_WorkingDataObserverTags.erase(tempNode); + } +} + +void QmitkMultiLabelSegmentationView::ApplyDisplayOptions() +{ + if (!m_Parent) + { + return; + } + + mitk::DataNode::Pointer workingData = m_ToolManager->GetWorkingData(0); + mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDataStorage()->GetSubset(m_SegmentationPredicate); + for (mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) + { + this->ApplyDisplayOptions(*iter); + } + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkMultiLabelSegmentationView::ApplyDisplayOptions(mitk::DataNode* node) +{ + if (nullptr == node) + { + return; + } + + auto drawOutline = mitk::BoolProperty::New(GetPreferences()->GetBool("draw outline", true)); + auto labelSetImage = dynamic_cast<mitk::LabelSetImage *>(node->GetData()); + if (nullptr != labelSetImage) + { + // node is a multi label segmentation + node->SetProperty("labelset.contour.active", drawOutline); + // force render window update to show outline + node->GetData()->Modified(); + } + else if (nullptr != node->GetData()) + { + // node is actually a 'single label' segmentation, + // but its outline property can be set in the 'multi label' segmentation preference page as well + bool isBinary = false; + node->GetBoolProperty("binary", isBinary); + if (isBinary) + { + node->SetProperty("outline binary", drawOutline); + node->SetProperty("outline width", mitk::FloatProperty::New(2.0)); + // force render window update to show outline + node->GetData()->Modified(); + } + } } void QmitkMultiLabelSegmentationView::OnEstablishLabelSetConnection() { if (m_WorkingNode.IsNull()) { return; } - mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(m_WorkingNode->GetData()); - assert(workingImage); + + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(m_WorkingNode->GetData()); + if (nullptr == workingImage) + { + // node is a "single label" / "binary" image --> no label set + return; + } workingImage->GetActiveLabelSet()->AddLabelEvent += mitk::MessageDelegate<QmitkLabelSetWidget>( m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::ResetAllTableWidgetItems); workingImage->GetActiveLabelSet()->RemoveLabelEvent += mitk::MessageDelegate<QmitkLabelSetWidget>( m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::ResetAllTableWidgetItems); workingImage->GetActiveLabelSet()->ModifyLabelEvent += mitk::MessageDelegate<QmitkLabelSetWidget>( m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::UpdateAllTableWidgetItems); workingImage->GetActiveLabelSet()->AllLabelsModifiedEvent += mitk::MessageDelegate<QmitkLabelSetWidget>( m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::UpdateAllTableWidgetItems); workingImage->GetActiveLabelSet()->ActiveLabelEvent += mitk::MessageDelegate1<QmitkLabelSetWidget, mitk::Label::PixelType>(m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::SelectLabelByPixelValue); // Removed in T27851 to have a chance to react to AfterChangeLayerEvent. Did it brake something? // workingImage->BeforeChangeLayerEvent += mitk::MessageDelegate<QmitkMultiLabelSegmentationView>( // this, &QmitkMultiLabelSegmentationView::OnLooseLabelSetConnection); workingImage->AfterChangeLayerEvent += mitk::MessageDelegate<QmitkMultiLabelSegmentationView>( - this, &QmitkMultiLabelSegmentationView::UpdateControls); + this, &QmitkMultiLabelSegmentationView::UpdateGUI); } void QmitkMultiLabelSegmentationView::OnLooseLabelSetConnection() { if (m_WorkingNode.IsNull()) + { return; + } - auto* workingImage = dynamic_cast<mitk::LabelSetImage *>(m_WorkingNode->GetData()); - + auto workingImage = dynamic_cast<mitk::LabelSetImage*>(m_WorkingNode->GetData()); if (nullptr == workingImage) - return; // data (type) was changed in-place, e.g. LabelSetImage -> Image + { + // data (type) was changed in-place, e.g. LabelSetImage -> (binary) image + return; + } // Reset LabelSetWidget Events workingImage->GetActiveLabelSet()->AddLabelEvent -= mitk::MessageDelegate<QmitkLabelSetWidget>( m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::ResetAllTableWidgetItems); workingImage->GetActiveLabelSet()->RemoveLabelEvent -= mitk::MessageDelegate<QmitkLabelSetWidget>( m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::ResetAllTableWidgetItems); workingImage->GetActiveLabelSet()->ModifyLabelEvent -= mitk::MessageDelegate<QmitkLabelSetWidget>( m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::UpdateAllTableWidgetItems); workingImage->GetActiveLabelSet()->AllLabelsModifiedEvent -= mitk::MessageDelegate<QmitkLabelSetWidget>( m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::UpdateAllTableWidgetItems); workingImage->GetActiveLabelSet()->ActiveLabelEvent -= mitk::MessageDelegate1<QmitkLabelSetWidget, mitk::Label::PixelType>(m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::SelectLabelByPixelValue); // Removed in T27851 to have a chance to react to AfterChangeLayerEvent. Did it brake something? // workingImage->BeforeChangeLayerEvent -= mitk::MessageDelegate<QmitkMultiLabelSegmentationView>( // this, &QmitkMultiLabelSegmentationView::OnLooseLabelSetConnection); workingImage->AfterChangeLayerEvent -= mitk::MessageDelegate<QmitkMultiLabelSegmentationView>( - this, &QmitkMultiLabelSegmentationView::UpdateControls); + this, &QmitkMultiLabelSegmentationView::UpdateGUI); } -void QmitkMultiLabelSegmentationView::SetFocus() +void QmitkMultiLabelSegmentationView::ResetMouseCursor() { + if (m_MouseCursorSet) + { + mitk::ApplicationCursor::GetInstance()->PopCursor(); + m_MouseCursorSet = false; + } } -void QmitkMultiLabelSegmentationView::UpdateControls() +void QmitkMultiLabelSegmentationView::SetMouseCursor(const us::ModuleResource& resource, int hotspotX, int hotspotY) +{ + // Remove previously set mouse cursor + if (m_MouseCursorSet) + this->ResetMouseCursor(); + + if (resource) + { + us::ModuleResourceStream cursor(resource, std::ios::binary); + mitk::ApplicationCursor::GetInstance()->PushCursor(cursor, hotspotX, hotspotY); + m_MouseCursorSet = true; + } +} + +void QmitkMultiLabelSegmentationView::UpdateGUI() { mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0); bool hasReferenceNode = referenceNode != nullptr; mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); - bool hasValidWorkingNode = workingNode != nullptr; + bool hasWorkingNode = workingNode != nullptr; + m_Controls.m_pbNewSegmentationSession->setEnabled(false); m_Controls.m_pbNewLabel->setEnabled(false); m_Controls.m_gbInterpolation->setEnabled(false); m_Controls.m_SliceBasedInterpolatorWidget->setEnabled(false); m_Controls.m_SurfaceBasedInterpolatorWidget->setEnabled(false); m_Controls.m_LabelSetWidget->setEnabled(false); m_Controls.m_btAddLayer->setEnabled(false); m_Controls.m_btDeleteLayer->setEnabled(false); m_Controls.m_cbActiveLayer->setEnabled(false); m_Controls.m_btPreviousLayer->setEnabled(false); m_Controls.m_btNextLayer->setEnabled(false); m_Controls.m_btLockExterior->setChecked(false); m_Controls.m_btLockExterior->setEnabled(false); m_Controls.m_tbSavePreset->setEnabled(false); m_Controls.m_tbLoadPreset->setEnabled(false); m_Controls.m_pbShowLabelTable->setChecked(false); m_Controls.m_pbShowLabelTable->setEnabled(false); - m_Controls.m_ManualToolSelectionBox3D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); - m_Controls.m_ManualToolSelectionBox2D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); + if (hasReferenceNode) + { + m_Controls.m_pbNewSegmentationSession->setEnabled(true); + } - if (hasValidWorkingNode) + if (hasWorkingNode) { - // TODO adapt tool manager so that this check is done there, e.g. convenience function + m_Controls.m_pbNewLabel->setEnabled(true); + m_Controls.m_btLockExterior->setEnabled(true); + m_Controls.m_tbSavePreset->setEnabled(true); + m_Controls.m_tbLoadPreset->setEnabled(true); + m_Controls.m_pbShowLabelTable->setEnabled(true); + m_Controls.m_LabelSetWidget->setEnabled(true); + m_Controls.m_btAddLayer->setEnabled(true); + + m_Controls.m_cbActiveLayer->blockSignals(true); + m_Controls.m_cbActiveLayer->clear(); + mitk::LabelSetImage* workingImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData()); - hasValidWorkingNode = workingImage != nullptr; - if (hasValidWorkingNode) + if (nullptr != workingImage) { - m_Controls.m_pbNewLabel->setEnabled(true); - m_Controls.m_btLockExterior->setEnabled(true); - m_Controls.m_tbSavePreset->setEnabled(true); - m_Controls.m_tbLoadPreset->setEnabled(true); - m_Controls.m_pbShowLabelTable->setEnabled(true); - m_Controls.m_gbInterpolation->setEnabled(true); - m_Controls.m_SliceBasedInterpolatorWidget->setEnabled(true); - m_Controls.m_SurfaceBasedInterpolatorWidget->setEnabled(true); - m_Controls.m_LabelSetWidget->setEnabled(true); - m_Controls.m_btAddLayer->setEnabled(true); - - int activeLayer = workingImage->GetActiveLayer(); int numberOfLayers = workingImage->GetNumberOfLayers(); - - m_Controls.m_cbActiveLayer->blockSignals(true); - m_Controls.m_cbActiveLayer->clear(); for (unsigned int lidx = 0; lidx < workingImage->GetNumberOfLayers(); ++lidx) { m_Controls.m_cbActiveLayer->addItem(QString::number(lidx)); } + + int activeLayer = workingImage->GetActiveLayer(); m_Controls.m_cbActiveLayer->setCurrentIndex(activeLayer); m_Controls.m_cbActiveLayer->blockSignals(false); m_Controls.m_cbActiveLayer->setEnabled(numberOfLayers > 1); m_Controls.m_btDeleteLayer->setEnabled(numberOfLayers > 1); m_Controls.m_btPreviousLayer->setEnabled(activeLayer > 0); m_Controls.m_btNextLayer->setEnabled(activeLayer != numberOfLayers - 1); m_Controls.m_btLockExterior->setChecked(workingImage->GetLabel(0, activeLayer)->GetLocked()); m_Controls.m_pbShowLabelTable->setChecked(workingImage->GetNumberOfLabels() > 1 /*1st is exterior*/); - - //MLI TODO - //m_Controls.m_ManualToolSelectionBox2D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithWorkingDataVisible); } } - if (hasValidWorkingNode && hasReferenceNode) + if (hasWorkingNode && hasReferenceNode) { + m_Controls.m_gbInterpolation->setEnabled(true); + m_Controls.m_SliceBasedInterpolatorWidget->setEnabled(true); + m_Controls.m_SurfaceBasedInterpolatorWidget->setEnabled(true); + int layer = -1; referenceNode->GetIntProperty("layer", layer); workingNode->SetIntProperty("layer", layer + 1); } - this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_ALL); + this->ValidateSelectionInput(); } -void QmitkMultiLabelSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) +void QmitkMultiLabelSegmentationView::ValidateSelectionInput() { - if (m_IRenderWindowPart != renderWindowPart) - { - m_IRenderWindowPart = renderWindowPart; - m_Parent->setEnabled(true); + this->UpdateWarningLabel(""); - QList<mitk::SliceNavigationController*> controllers; - controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); - controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); - controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); - m_Controls.m_SliceBasedInterpolatorWidget->SetSliceNavigationControllers(controllers); - } -} + // the argument is actually not used + // enable status depends on the tool manager selection + m_Controls.m_ManualToolSelectionBox2D->setEnabled(false); + m_Controls.m_ManualToolSelectionBox3D->setEnabled(false); -void QmitkMultiLabelSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/) -{ - m_ToolManager->ActivateTool(-1); - m_IRenderWindowPart = nullptr; - m_Parent->setEnabled(false); -} + mitk::DataNode* referenceNode = m_Controls.m_ReferenceNodeSelector->GetSelectedNode(); + mitk::DataNode* workingNode = m_Controls.m_WorkingNodeSelector->GetSelectedNode(); -void QmitkMultiLabelSegmentationView::ResetMouseCursor() -{ - if (m_MouseCursorSet) + if (nullptr == referenceNode) { - mitk::ApplicationCursor::GetInstance()->PopCursor(); - m_MouseCursorSet = false; + return; } -} -void QmitkMultiLabelSegmentationView::SetMouseCursor(const us::ModuleResource resource, int hotspotX, int hotspotY) -{ - // Remove previously set mouse cursor - if (m_MouseCursorSet) - this->ResetMouseCursor(); + if (nullptr == workingNode) + { + return; + } - if (resource) + mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); + auto referenceNodeIsVisible = renderWindowPart && + referenceNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()); + if (!referenceNodeIsVisible) { - us::ModuleResourceStream cursor(resource, std::ios::binary); - mitk::ApplicationCursor::GetInstance()->PushCursor(cursor, hotspotX, hotspotY); - m_MouseCursorSet = true; + this->UpdateWarningLabel(tr("The selected reference image is currently not visible!")); + return; } -} -void QmitkMultiLabelSegmentationView::InitializeListeners() -{ - if (m_Interactor.IsNull()) + auto workingNodeIsVisible = renderWindowPart && + workingNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()); + if (!workingNodeIsVisible) { - us::Module* module = us::GetModuleContext()->GetModule(); - std::vector<us::ModuleResource> resources = module->FindResources("/", "*", true); - for (std::vector<us::ModuleResource>::iterator iter = resources.begin(); iter != resources.end(); ++iter) - { - MITK_INFO << iter->GetResourcePath(); - } + this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!")); + return; + } - m_Interactor = mitk::SegmentationInteractor::New(); - if (!m_Interactor->LoadStateMachine("SegmentationInteraction.xml", module)) + /* + * Here we check whether the geometry of the selected segmentation image is aligned with the worldgeometry. + * At the moment it is not supported to use a geometry different from the selected image for reslicing. + * For further information see Bug 16063 + */ + const mitk::BaseGeometry *workingNodeGeo = workingNode->GetData()->GetGeometry(); + const mitk::BaseGeometry *worldGeo = + renderWindowPart->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D(); + if (nullptr != workingNodeGeo && nullptr != worldGeo) + { + if (mitk::Equal(*workingNodeGeo->GetBoundingBox(), *worldGeo->GetBoundingBox(), mitk::eps, true)) { - MITK_WARN << "Error loading state machine"; + m_ToolManager->SetReferenceData(referenceNode); + m_ToolManager->SetWorkingData(workingNode); + m_Controls.m_ManualToolSelectionBox2D->setEnabled(true); + m_Controls.m_ManualToolSelectionBox3D->setEnabled(true); + return; } + } - if (!m_Interactor->SetEventConfig("ConfigSegmentation.xml", module)) - { - MITK_WARN << "Error loading state machine configuration"; - } + m_ToolManager->SetReferenceData(referenceNode); + m_ToolManager->SetWorkingData(nullptr); + this->UpdateWarningLabel(tr("Please perform a reinit on the segmentation image!")); +} - // Register as listener via micro services - us::ServiceProperties props; - props["name"] = std::string("SegmentationInteraction"); - m_ServiceRegistration = - us::GetModuleContext()->RegisterService<mitk::InteractionEventObserver>(m_Interactor.GetPointer(), props); +void QmitkMultiLabelSegmentationView::UpdateWarningLabel(QString text) +{ + if (text.size() == 0) + { + m_Controls.lblSegmentationWarnings->hide(); + } + else + { + m_Controls.lblSegmentationWarnings->show(); } + m_Controls.lblSegmentationWarnings->setText("<font color=\"red\">" + text + "</font>"); } diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.h b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.h index afef29785d..e7979bab60 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.h +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.h @@ -1,175 +1,171 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#ifndef QmitkMultiLabelSegmentationView_h -#define QmitkMultiLabelSegmentationView_h - -#include <QmitkAbstractView.h> - -#include "mitkSegmentationInteractor.h" -#include <mitkILifecycleAwarePart.h> +#ifndef QMITKMULTILABELSEGMENTATIONVIEW_H +#define QMITKMULTILABELSEGMENTATIONVIEW_H #include "ui_QmitkMultiLabelSegmentationControls.h" -// berry -#include <berryIBerryPreferences.h> +#include <QmitkAbstractView.h> +#include <mitkIRenderWindowPartListener.h> -class QmitkRenderWindow; +#include <berryIBerryPreferences.h> /** - * \ingroup ToolManagerEtAl - * \ingroup org_mitk_gui_qt_multilabelsegmentation_internal - */ -class QmitkMultiLabelSegmentationView : public QmitkAbstractView, public mitk::ILifecycleAwarePart +* @brief The multilabel segmentation view provides a set of tool to use different segmentation +* algorithms. +* It provides two selection widgets to load an image node and a segmentation node +* on which to perform the segmentation. Creating new segmentation nodes is also possible. +* The available segmentation tools are grouped into "2D"- and "3D"-tools. +* +* Most segmentation tools / algorithms need some kind of user interaction, where the +* user is asked to draw something in the image display or set some seed points / start values. +* The tools also often provide additional propeties so that a user can modify the +* algorithm's behavior. +* +* In contrast to the basic QmitkSegmentationView this class additionally provides options to +* work with different layers (create new layers, switch between layers). +* Moreover, a multilabel widget displays all the existing labels of a multilabel segmentation +* for the currently active layer. +* The multilabel widget allows to control the labels by creatin new one, removing existing ones, +* showing / hiding single labels, merging labels, (re-)naming them etc. +* +* Interpolation for multilabel segmentations is currently not implemented. +*/ +class QmitkMultiLabelSegmentationView : public QmitkAbstractView, public mitk::IRenderWindowPartListener { Q_OBJECT public: + static const std::string VIEW_ID; QmitkMultiLabelSegmentationView(); ~QmitkMultiLabelSegmentationView() override; - typedef std::map<mitk::DataNode *, unsigned long> NodeTagMapType; +private Q_SLOTS: - // GUI setup - void CreateQtPartControl(QWidget *parent) override; - - // ILifecycleAwarePart interface -public: - void Activated() override; - void Deactivated() override; - void Visible() override; - void Hidden() override; - - virtual int GetSizeFlags(bool width); - virtual int ComputePreferredSize(bool width, - int /*availableParallel*/, - int /*availablePerpendicular*/, - int preferredResult); + // reaction to the selection of a new reference image in the selection widget + void OnReferenceSelectionChanged(QList<mitk::DataNode::Pointer> nodes); -protected slots: + // reaction to the selection of a new segmentation image in the selection widget + void OnSegmentationSelectionChanged(QList<mitk::DataNode::Pointer> nodes); // reaction to the shortcut for toggling the visibility of the working node void OnVisibilityShortcutActivated(); // reaction to the shortcut for iterating over all labels void OnLabelToggleShortcutActivated(); // reaction to the selection of any 2D segmentation tool void OnManualTool2DSelected(int id); // reaction to button "New Label" void OnNewLabel(); // reaction to button "Save Preset" void OnSavePreset(); // reaction to button "Load Preset" void OnLoadPreset(); // reaction to button "Show Label Table" void OnShowLabelTable(bool value); // reaction to button "New Segmentation Session" void OnNewSegmentationSession(); // reaction to signal "goToLabel" from labelset widget void OnGoToLabel(const mitk::Point3D &pos); void OnResetView(); // reaction to the button "Add Layer" void OnAddLayer(); // reaction to the button "Delete Layer" void OnDeleteLayer(); // reaction to the button "Previous Layer" void OnPreviousLayer(); // reaction to the button "Next Layer" void OnNextLayer(); // reaction to the combobox change "Change Layer" void OnChangeLayer(int); - // reaction to the button "Deactive Active Tool" - void OnDeactivateActiveTool(); - // reaction to the button "Lock exterior" void OnLockExteriorToggled(bool); - // reaction to the selection of a new patient (reference) image in the DataStorage combobox - void OnReferenceSelectionChanged(QList<mitk::DataNode::Pointer> nodes); - - // reaction to the selection of a new Segmentation (working) image in the DataStorage combobox - void OnSegmentationSelectionChanged(QList<mitk::DataNode::Pointer> nodes); - // reaction to ... void OnInterpolationSelectionChanged(int); -protected: +private: + + void CreateQtPartControl(QWidget *parent) override; + + void SetFocus() override {} + + void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; + void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override; - // reimplemented from QmitkAbstractView void OnPreferencesChanged(const berry::IBerryPreferences* prefs) override; - // reimplemented from QmitkAbstractView + void NodeAdded(const mitk::DataNode *node) override; + void NodeRemoved(const mitk::DataNode* node) override; - void OnEstablishLabelSetConnection(); + // make sure all images / segmentations look according to the user preference settings + void ApplyDisplayOptions(); - void OnLooseLabelSetConnection(); + // decorates a DataNode according to the user preference settings + void ApplyDisplayOptions(mitk::DataNode* node); - void SetFocus() override; + void OnEstablishLabelSetConnection(); - void UpdateControls(); + void OnLooseLabelSetConnection(); - void RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart); + void ResetMouseCursor(); - void RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart); + void SetMouseCursor(const us::ModuleResource&, int hotspotX, int hotspotY); - void ResetMouseCursor(); + void UpdateGUI(); - void SetMouseCursor(const us::ModuleResource, int hotspotX, int hotspotY); + void ValidateSelectionInput(); - void InitializeListeners(); + void UpdateWarningLabel(QString text); - /// \brief the Qt parent of our GUI (NOT of this object) QWidget *m_Parent; - /// \brief Qt GUI file Ui::QmitkMultiLabelSegmentationControls m_Controls; - mitk::IRenderWindowPart *m_IRenderWindowPart; + mitk::IRenderWindowPart *m_RenderWindowPart; mitk::ToolManager *m_ToolManager; mitk::DataNode::Pointer m_ReferenceNode; mitk::DataNode::Pointer m_WorkingNode; + typedef std::map<mitk::DataNode *, unsigned long> NodeTagMapType; + NodeTagMapType m_WorkingDataObserverTags; + unsigned int m_RenderingManagerObserverTag; + mitk::NodePredicateAnd::Pointer m_ReferencePredicate; mitk::NodePredicateAnd::Pointer m_SegmentationPredicate; bool m_AutoSelectionEnabled; bool m_MouseCursorSet; - mitk::SegmentationInteractor::Pointer m_Interactor; - - /** - * Reference to the service registration of the observer, - * it is needed to unregister the observer on unload. - */ - us::ServiceRegistration<mitk::InteractionEventObserver> m_ServiceRegistration; }; -#endif // QmitkMultiLabelSegmentationView_h +#endif // QMITKMULTILABELSEGMENTATIONVIEW_H diff --git a/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.h b/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.h index a0bfedfdbb..2e1b902fc4 100644 --- a/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.h +++ b/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.h @@ -1,60 +1,60 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKMXNMULTIWIDGETEDITOR_H #define QMITKMXNMULTIWIDGETEDITOR_H #include <org_mitk_gui_qt_mxnmultiwidgeteditor_Export.h> #include <QmitkAbstractMultiWidgetEditor.h> // c++ #include <memory> class QmitkMxNMultiWidget; class MXNMULTIWIDGETEDITOR_EXPORT QmitkMxNMultiWidgetEditor final : public QmitkAbstractMultiWidgetEditor { Q_OBJECT public: static const QString EDITOR_ID; QmitkMxNMultiWidgetEditor(); ~QmitkMxNMultiWidgetEditor() override; virtual QmitkLevelWindowWidget* GetLevelWindowWidget() const override { return nullptr; } - void OnLayoutSet(int row, int column); - void OnInteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme); + void OnLayoutSet(int row, int column) override; + void OnInteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme) override; private: /** * @brief Overridden from QmitkAbstractRenderEditor */ void SetFocus() override; /** * @brief Overridden from QmitkAbstractRenderEditor */ void CreateQtPartControl(QWidget* parent) override; /** * @brief Overridden from QmitkAbstractRenderEditor */ void OnPreferencesChanged(const berry::IBerryPreferences* preferences) override; struct Impl; std::unique_ptr<Impl> m_Impl; }; #endif // QMITKMXNMULTIWIDGETEDITOR_H diff --git a/Plugins/org.mitk.gui.qt.preprocessing.resampling/src/internal/QmitkPreprocessingResamplingView.cpp b/Plugins/org.mitk.gui.qt.preprocessing.resampling/src/internal/QmitkPreprocessingResamplingView.cpp index 738ef2b5fb..0befa8495d 100644 --- a/Plugins/org.mitk.gui.qt.preprocessing.resampling/src/internal/QmitkPreprocessingResamplingView.cpp +++ b/Plugins/org.mitk.gui.qt.preprocessing.resampling/src/internal/QmitkPreprocessingResamplingView.cpp @@ -1,457 +1,457 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkPreprocessingResamplingView.h" // QT includes (GUI) #include <qlabel.h> #include <qspinbox.h> #include <qpushbutton.h> #include <qcheckbox.h> #include <qgroupbox.h> #include <qradiobutton.h> #include <qmessagebox.h> // Berry includes (selection service) #include <berryISelectionService.h> #include <berryIWorkbenchWindow.h> // MITK includes (GUI) #include "QmitkStdMultiWidget.h" #include "QmitkDataNodeSelectionProvider.h" #include "mitkDataNodeObject.h" // MITK includes (general) #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateDimension.h" #include "mitkNodePredicateAnd.h" #include "mitkImageTimeSelector.h" #include "mitkVectorImageMapper2D.h" #include "mitkProperties.h" #include "mitkLevelWindowProperty.h" // Includes for image casting between ITK and MITK #include "mitkImageCast.h" #include "mitkITKImageImport.h" // ITK includes (general) #include <itkVectorImage.h> #include <itkImageFileWriter.h> // Resampling #include <itkResampleImageFilter.h> #include <itkNearestNeighborInterpolateImageFunction.h> #include <itkBSplineInterpolateImageFunction.h> #include <itkCastImageFilter.h> #include <itkLinearInterpolateImageFunction.h> #include <itkRescaleIntensityImageFilter.h> #include <itkShiftScaleImageFilter.h> // STD #include <cmath> // Convenient Definitions typedef itk::Image<double, 3> ImageType; typedef itk::Image<unsigned char, 3> SegmentationImageType; typedef itk::Image<double, 3> DoubleImageType; typedef itk::Image<itk::Vector<float,3>, 3> VectorImageType; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType2; typedef itk::CastImageFilter< ImageType, DoubleImageType > ImagePTypeToFloatPTypeCasterType; typedef itk::LinearInterpolateImageFunction< ImageType, double > LinearInterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction< ImageType, double > NearestInterpolatorType; typedef itk::BSplineInterpolateImageFunction<ImageType, double> BSplineInterpolatorType; QmitkPreprocessingResampling::QmitkPreprocessingResampling() : QmitkAbstractView(), m_Controls(nullptr), m_SelectedImageNode(nullptr), m_TimeStepperAdapter(nullptr) { } QmitkPreprocessingResampling::~QmitkPreprocessingResampling() { } void QmitkPreprocessingResampling::CreateQtPartControl(QWidget *parent) { if (m_Controls == nullptr) { m_Controls = new Ui::QmitkPreprocessingResamplingViewControls; m_Controls->setupUi(parent); this->CreateConnections(); mitk::NodePredicateDimension::Pointer dimensionPredicate = mitk::NodePredicateDimension::New(3); mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image"); } m_SelectedImageNode = mitk::DataStorageSelection::New(this->GetDataStorage(), false); // Setup Controls this->m_Controls->cbParam4->clear(); this->m_Controls->cbParam4->insertItem(LINEAR, "Linear"); this->m_Controls->cbParam4->insertItem(NEAREST, "Nearest neighbor"); this->m_Controls->cbParam4->insertItem(SPLINE, "B-Spline"); } void QmitkPreprocessingResampling::CreateConnections() { if ( m_Controls ) { connect((QObject*)(m_Controls->btnDoIt), SIGNAL(clicked()), (QObject*) this, SLOT(StartButtonClicked())); connect((QObject*)(m_Controls->buttonExecuteOnMultipleImages), SIGNAL(clicked()), (QObject*) this, SLOT(StartMultipleImagesButtonClicked())); connect( (QObject*)(m_Controls->cbParam4), SIGNAL( activated(int) ), this, SLOT( SelectInterpolator(int) ) ); } } void QmitkPreprocessingResampling::InternalGetTimeNavigationController() { auto renwin_part = GetRenderWindowPart(); if( renwin_part != nullptr ) { auto tnc = renwin_part->GetTimeNavigationController(); if( tnc != nullptr ) { m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->sliceNavigatorTime, tnc->GetTime(), "sliceNavigatorTimeFromBIP"); } } } void QmitkPreprocessingResampling::SetFocus() { } //datamanager selection changed void QmitkPreprocessingResampling::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList<mitk::DataNode::Pointer>& nodes) { ResetOneImageOpPanel(); //any nodes there? if (!nodes.empty()) { // reset GUI m_Controls->sliceNavigatorTime->setEnabled(false); m_Controls->leImage1->setText(tr("Select an Image in Data Manager")); m_SelectedNodes.clear(); for (mitk::DataNode* _DataNode : nodes) { m_SelectedImageNode->RemoveAllNodes(); *m_SelectedImageNode = _DataNode; mitk::Image::Pointer tempImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData()); //no image if (tempImage.IsNull() || (tempImage->IsInitialized() == false)) { if (m_SelectedNodes.size() < 1) { m_Controls->leImage1->setText(tr("Not an image.")); } continue; } //2D image if (tempImage->GetDimension() < 3) { if (m_SelectedNodes.size() < 1) { m_Controls->leImage1->setText(tr("2D images are not supported.")); } continue; } if (m_SelectedNodes.size() < 1) { m_Controls->leImage1->setText(QString(m_SelectedImageNode->GetNode()->GetName().c_str())); mitk::Vector3D aSpacing = tempImage->GetGeometry()->GetSpacing(); std::string text("x-spacing (" + std::to_string(aSpacing[0]) + ")"); m_Controls->tlParam1->setText(text.c_str()); text = "y-spacing (" + std::to_string(aSpacing[1]) + ")"; m_Controls->tlParam2->setText(text.c_str()); text = "z-spacing (" + std::to_string(aSpacing[2]) + ")"; m_Controls->tlParam3->setText(text.c_str()); if (tempImage->GetDimension() > 3) { // try to retrieve the TNC (for 4-D Processing ) this->InternalGetTimeNavigationController(); m_Controls->sliceNavigatorTime->setEnabled(true); m_Controls->tlTime->setEnabled(true); } } m_SelectedNodes.push_back(_DataNode); } if (m_SelectedNodes.size() > 0) { *m_SelectedImageNode = m_SelectedNodes[0]; } ResetParameterPanel(); } } void QmitkPreprocessingResampling::ResetOneImageOpPanel() { m_Controls->tlTime->setEnabled(false); m_Controls->btnDoIt->setEnabled(false); m_Controls->buttonExecuteOnMultipleImages->setEnabled(false); m_Controls->cbHideOrig->setEnabled(false); m_Controls->leImage1->setText(tr("Select an Image in Data Manager")); m_Controls->tlParam1->setText("x-spacing"); m_Controls->tlParam1->setText("y-spacing"); m_Controls->tlParam1->setText("z-spacing"); } void QmitkPreprocessingResampling::ResetParameterPanel() { m_Controls->btnDoIt->setEnabled(true); m_Controls->buttonExecuteOnMultipleImages->setEnabled(true); m_Controls->cbHideOrig->setEnabled(true); } void QmitkPreprocessingResampling::ResetTwoImageOpPanel() { } void QmitkPreprocessingResampling::StartMultipleImagesButtonClicked() { for (auto currentSelectedNode : m_SelectedNodes) { m_SelectedImageNode->RemoveAllNodes(); *m_SelectedImageNode = currentSelectedNode; StartButtonClicked(); } } void QmitkPreprocessingResampling::StartButtonClicked() { if(!m_SelectedImageNode->GetNode()) return; this->BusyCursorOn(); mitk::Image::Pointer newImage; try { newImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData()); } catch ( std::exception &e ) { QString exceptionString = tr("An error occured during image loading:\n"); exceptionString.append( e.what() ); QMessageBox::warning( nullptr, "Preprocessing - Resampling: ", exceptionString , QMessageBox::Ok, QMessageBox::NoButton ); this->BusyCursorOff(); return; } // check if input image is valid, casting does not throw exception when casting from 'NULL-Object' if ( (! newImage) || (newImage->IsInitialized() == false) ) { this->BusyCursorOff(); QMessageBox::warning( nullptr, "Preprocessing - Resampling", tr("Input image is broken or not initialized. Returning."), QMessageBox::Ok, QMessageBox::NoButton ); return; } // check if operation is done on 4D a image time step if(newImage->GetDimension() > 3) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(newImage); timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() ); timeSelector->Update(); newImage = timeSelector->GetOutput(); } // check if image or vector image ImageType::Pointer itkImage = ImageType::New(); VectorImageType::Pointer itkVecImage = VectorImageType::New(); int isVectorImage = newImage->GetPixelType().GetNumberOfComponents(); if(isVectorImage > 1) { CastToItkImage( newImage, itkVecImage ); } else { CastToItkImage( newImage, itkImage ); } std::stringstream nameAddition(""); double dparam1 = m_Controls->dsbParam1->value(); double dparam2 = m_Controls->dsbParam2->value(); double dparam3 = m_Controls->dsbParam3->value(); try{ std::string selectedInterpolator; ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New(); switch (m_SelectedInterpolation) { case LINEAR: { LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Linear"; break; } case NEAREST: { NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Nearest"; break; } case SPLINE: { BSplineInterpolatorType::Pointer interpolator = BSplineInterpolatorType::New(); interpolator->SetSplineOrder(3); resampler->SetInterpolator(interpolator); selectedInterpolator = "B-Spline"; break; } default: { LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Linear"; break; } } resampler->SetInput( itkImage ); resampler->SetOutputOrigin( itkImage->GetOrigin() ); ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize(); ImageType::SpacingType input_spacing = itkImage->GetSpacing(); ImageType::SizeType output_size; ImageType::SpacingType output_spacing; if (dparam1 > 0) { output_size[0] = std::ceil(input_size[0] * (input_spacing[0] / dparam1)); output_spacing[0] = dparam1; } else { output_size[0] = std::ceil(input_size[0] * (-1.0 / dparam1)); output_spacing[0] = -1.0*input_spacing[0] * dparam1; } if (dparam2 > 0) { output_size[1] = std::ceil(input_size[1] * (input_spacing[1] / dparam2)); output_spacing[1] = dparam2; } else { output_size[1] = std::ceil(input_size[1] * (-1.0 / dparam2)); output_spacing[1] = -1.0*input_spacing[1] * dparam2; } if (dparam3 > 0) { output_size[2] = std::ceil(input_size[2] * (input_spacing[2] / dparam3)); output_spacing[2] = dparam3; } else { output_size[2] = std::ceil(input_size[2] * (-1.0 / dparam3)); output_spacing[2] = -1.0*input_spacing[2] * dparam3; } resampler->SetSize( output_size ); resampler->SetOutputSpacing( output_spacing ); resampler->SetOutputDirection( itkImage->GetDirection() ); resampler->UpdateLargestPossibleRegion(); ImageType::Pointer resampledImage = resampler->GetOutput(); newImage = mitk::ImportItkImage( resampledImage )->Clone(); nameAddition << "_Resampled_" << selectedInterpolator; std::cout << "Resampling successful." << std::endl; } catch (...) { this->BusyCursorOff(); QMessageBox::warning(nullptr, "Warning", "Problem when applying filter operation. Check your input..."); return; } newImage->DisconnectPipeline(); // adjust level/window to new image mitk::LevelWindow levelwindow; levelwindow.SetAuto( newImage ); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); levWinProp->SetLevelWindow( levelwindow ); // compose new image name std::string name = m_SelectedImageNode->GetNode()->GetName(); - if (name.find(".pic.gz") == name.size() -7 ) + if (name.find(".nrrd") == name.size() -5 ) { - name = name.substr(0,name.size() -7); + name = name.substr(0,name.size() -5); } name.append( nameAddition.str() ); // create final result MITK data storage node mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty( "levelwindow", levWinProp ); result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) ); result->SetData( newImage ); // for vector images, a different mapper is needed if(isVectorImage > 1) { mitk::VectorImageMapper2D::Pointer mapper = mitk::VectorImageMapper2D::New(); result->SetMapper(1,mapper); } // add new image to data storage and set as active to ease further processing GetDataStorage()->Add( result, m_SelectedImageNode->GetNode() ); if ( m_Controls->cbHideOrig->isChecked() == true ) m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) ); // show the results mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->BusyCursorOff(); } void QmitkPreprocessingResampling::SelectInterpolator(int interpolator) { switch (interpolator) { case 0: { m_SelectedInterpolation = LINEAR; break; } case 1: { m_SelectedInterpolation = NEAREST; break; } case 2: { m_SelectedInterpolation = SPLINE; } } } diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp index 70bc475007..a6c3dd90d8 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp @@ -1,371 +1,395 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkAddNewPropertyDialog.h" #include "QmitkPropertyItemDelegate.h" #include "QmitkPropertyItemModel.h" #include "QmitkPropertyItemSortFilterProxyModel.h" #include "QmitkPropertyTreeView.h" #include <berryIBerryPreferences.h> #include <berryQtStyleManager.h> #include <mitkIPropertyAliases.h> #include <mitkIPropertyDescriptions.h> #include <mitkIPropertyPersistence.h> #include <QmitkRenderWindow.h> #include <QPainter> #include <memory> +namespace +{ + QmitkAbstractNodeSelectionWidget::NodeList GetInitialSelection(berry::ISelection::ConstPointer selection) + { + if (selection.IsNotNull() && !selection->IsEmpty()) + { + auto* dataNodeSelection = dynamic_cast<const mitk::DataNodeSelection*>(selection.GetPointer()); + + if (nullptr != dataNodeSelection) + { + auto firstSelectedDataNode = dataNodeSelection->GetSelectedDataNodes().front(); + + if (firstSelectedDataNode.IsNotNull()) + { + QmitkAbstractNodeSelectionWidget::NodeList initialSelection; + initialSelection.push_back(firstSelectedDataNode); + + return initialSelection; + } + } + } + + return QmitkAbstractNodeSelectionWidget::NodeList(); + } +} + const std::string QmitkPropertyTreeView::VIEW_ID = "org.mitk.views.properties"; QmitkPropertyTreeView::QmitkPropertyTreeView() : m_PropertyAliases(mitk::CoreServices::GetPropertyAliases(nullptr), nullptr), m_PropertyDescriptions(mitk::CoreServices::GetPropertyDescriptions(nullptr), nullptr), m_PropertyPersistence(mitk::CoreServices::GetPropertyPersistence(nullptr), nullptr), m_ProxyModel(nullptr), m_Model(nullptr), m_Delegate(nullptr), m_Renderer(nullptr) { } QmitkPropertyTreeView::~QmitkPropertyTreeView() { } void QmitkPropertyTreeView::SetFocus() { m_Controls.filterLineEdit->setFocus(); } void QmitkPropertyTreeView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { if (m_Controls.propertyListComboBox->count() == 2) { QHash<QString, QmitkRenderWindow*> renderWindows = renderWindowPart->GetQmitkRenderWindows(); Q_FOREACH(QString renderWindow, renderWindows.keys()) { m_Controls.propertyListComboBox->insertItem(m_Controls.propertyListComboBox->count() - 1, QString("Data node: ") + renderWindow); } } } void QmitkPropertyTreeView::RenderWindowPartDeactivated(mitk::IRenderWindowPart*) { if (m_Controls.propertyListComboBox->count() > 2) { m_Controls.propertyListComboBox->clear(); m_Controls.propertyListComboBox->addItem("Data node: common"); m_Controls.propertyListComboBox->addItem("Base data"); } } void QmitkPropertyTreeView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); m_Controls.propertyListComboBox->addItem("Data node: common"); mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); if (renderWindowPart != nullptr) { QHash<QString, QmitkRenderWindow*> renderWindows = renderWindowPart->GetQmitkRenderWindows(); for(const auto& renderWindow : renderWindows.keys()) { m_Controls.propertyListComboBox->addItem(QString("Data node: ") + renderWindow); } } m_Controls.propertyListComboBox->addItem("Base data"); m_Controls.newButton->setEnabled(false); this->HideAllIcons(); m_ProxyModel = new QmitkPropertyItemSortFilterProxyModel(m_Controls.treeView); m_Model = new QmitkPropertyItemModel(m_ProxyModel); m_ProxyModel->setSourceModel(m_Model); m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setDynamicSortFilter(true); m_Delegate = new QmitkPropertyItemDelegate(m_Controls.treeView); m_Controls.singleSlot->SetDataStorage(GetDataStorage()); m_Controls.singleSlot->SetSelectionIsOptional(true); - m_Controls.singleSlot->SetAutoSelectNewNodes(true); m_Controls.singleSlot->SetEmptyInfo(QString("Please select a data node")); m_Controls.singleSlot->SetPopUpTitel(QString("Select data node")); m_SelectionServiceConnector = std::make_unique<QmitkSelectionServiceConnector>(); SetAsSelectionListener(true); m_Controls.filterLineEdit->setClearButtonEnabled(true); m_Controls.treeView->setItemDelegateForColumn(1, m_Delegate); m_Controls.treeView->setModel(m_ProxyModel); m_Controls.treeView->setColumnWidth(0, 160); m_Controls.treeView->sortByColumn(0, Qt::AscendingOrder); m_Controls.treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.treeView->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked); const int ICON_SIZE = 32; auto icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/tags.svg")); m_Controls.tagsLabel->setPixmap(icon.pixmap(ICON_SIZE)); icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/tag.svg")); m_Controls.tagLabel->setPixmap(icon.pixmap(ICON_SIZE)); icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg")); m_Controls.saveLabel->setPixmap(icon.pixmap(ICON_SIZE)); connect(m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkPropertyTreeView::OnCurrentSelectionChanged); connect(m_Controls.filterLineEdit, &QLineEdit::textChanged, this, &QmitkPropertyTreeView::OnFilterTextChanged); connect(m_Controls.propertyListComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &QmitkPropertyTreeView::OnPropertyListChanged); connect(m_Controls.newButton, &QPushButton::clicked, this, &QmitkPropertyTreeView::OnAddNewProperty); connect(m_Controls.treeView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &QmitkPropertyTreeView::OnCurrentRowChanged); connect(m_Model, &QmitkPropertyItemModel::modelReset, this, &QmitkPropertyTreeView::OnModelReset); + + auto selection = this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection(); + auto currentSelection = GetInitialSelection(selection); + + if (!currentSelection.isEmpty()) + m_Controls.singleSlot->SetCurrentSelection(currentSelection); } void QmitkPropertyTreeView::SetAsSelectionListener(bool checked) { if (checked) { m_SelectionServiceConnector->AddPostSelectionListener(GetSite()->GetWorkbenchWindow()->GetSelectionService()); connect(m_SelectionServiceConnector.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection); } else { m_SelectionServiceConnector->RemovePostSelectionListener(); disconnect(m_SelectionServiceConnector.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection); } } QString QmitkPropertyTreeView::GetPropertyNameOrAlias(const QModelIndex& index) { QString propertyName; if (index.isValid()) { QModelIndex current = index; while (current.isValid()) { QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString(); propertyName.prepend(propertyName.isEmpty() ? name : name.append('.')); current = current.parent(); } } return propertyName; } void QmitkPropertyTreeView::OnCurrentSelectionChanged(QList<mitk::DataNode::Pointer> nodes) { if (nodes.empty() || nodes.front().IsNull()) { m_SelectedNode = nullptr; this->SetPartName("Properties"); m_Model->SetPropertyList(nullptr); m_Delegate->SetPropertyList(nullptr); m_Controls.newButton->setEnabled(false); return; } // node is selected, create tree with node properties m_SelectedNode = nodes.front(); mitk::PropertyList* propertyList = m_Model->GetPropertyList(); if (m_Renderer == nullptr && m_Controls.propertyListComboBox->currentText() == "Base data") { propertyList = m_SelectedNode->GetData() != nullptr ? m_SelectedNode->GetData()->GetPropertyList() : nullptr; } else { propertyList = m_SelectedNode->GetPropertyList(m_Renderer); } QString selectionClassName = m_SelectedNode->GetData() != nullptr ? m_SelectedNode->GetData()->GetNameOfClass() : ""; m_SelectionClassName = selectionClassName.toStdString(); m_Model->SetPropertyList(propertyList, selectionClassName); m_Delegate->SetPropertyList(propertyList); m_Controls.newButton->setEnabled(true); - - if (!m_ProxyModel->filterRegExp().isEmpty()) - { - m_Controls.treeView->expandAll(); - } + m_Controls.treeView->expandAll(); } void QmitkPropertyTreeView::HideAllIcons() { m_Controls.tagLabel->hide(); m_Controls.tagsLabel->hide(); m_Controls.saveLabel->hide(); } void QmitkPropertyTreeView::OnCurrentRowChanged(const QModelIndex& current, const QModelIndex&) { if (current.isValid()) { QString name = this->GetPropertyNameOrAlias(current); if (!name.isEmpty()) { QString alias; bool isTrueName = true; std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString()); if (trueName.empty() && !m_SelectionClassName.empty()) trueName = m_PropertyAliases->GetPropertyName(name.toStdString(), m_SelectionClassName); if (!trueName.empty()) { alias = name; name = QString::fromStdString(trueName); isTrueName = false; } QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString())); std::vector<std::string> aliases; if (!isTrueName) { aliases = m_PropertyAliases->GetAliases(name.toStdString(), m_SelectionClassName); if (aliases.empty() && !m_SelectionClassName.empty()) aliases = m_PropertyAliases->GetAliases(name.toStdString()); } bool isPersistent = m_PropertyPersistence->HasInfo(name.toStdString()); if (!description.isEmpty() || !aliases.empty() || isPersistent) { QString customizedDescription; if (!aliases.empty()) { customizedDescription = "<h3 style=\"margin-bottom:0\">" + name + "</h3>"; std::size_t numAliases = aliases.size(); std::size_t lastAlias = numAliases - 1; for (std::size_t i = 0; i < numAliases; ++i) { customizedDescription += i != lastAlias ? "<h5 style=\"margin-top:0;margin-bottom:0\">" : "<h5 style=\"margin-top:0;margin-bottom:10px\">"; customizedDescription += QString::fromStdString(aliases[i]) + "</h5>"; } } else { customizedDescription = "<h3 style=\"margin-bottom:10px\">" + name + "</h3>"; } if (!description.isEmpty()) customizedDescription += "<p>" + description + "</p>"; m_Controls.tagsLabel->setVisible(!aliases.empty() && aliases.size() > 1); m_Controls.tagLabel->setVisible(!aliases.empty() && aliases.size() == 1); m_Controls.saveLabel->setVisible(isPersistent); m_Controls.descriptionLabel->setText(customizedDescription); m_Controls.descriptionLabel->show(); return; } } } m_Controls.descriptionLabel->hide(); this->HideAllIcons(); } void QmitkPropertyTreeView::OnPropertyListChanged(int index) { if (index == -1) return; QString renderer = m_Controls.propertyListComboBox->itemText(index); if (renderer.startsWith("Data node: ")) renderer = QString::fromStdString(renderer.toStdString().substr(11)); m_Renderer = nullptr; if (renderer != "common" && renderer != "Base data") { auto* renderWindowPart = this->GetRenderWindowPart(); if (nullptr != renderWindowPart) m_Renderer = renderWindowPart->GetQmitkRenderWindow(renderer)->GetRenderer(); } QList<mitk::DataNode::Pointer> nodes; if (m_SelectedNode.IsNotNull()) nodes << m_SelectedNode; this->OnCurrentSelectionChanged(nodes); } void QmitkPropertyTreeView::OnAddNewProperty() { std::unique_ptr<QmitkAddNewPropertyDialog> dialog(m_Controls.propertyListComboBox->currentText() != "Base data" ? new QmitkAddNewPropertyDialog(m_SelectedNode, m_Renderer) : new QmitkAddNewPropertyDialog(m_SelectedNode->GetData())); if (dialog->exec() == QDialog::Accepted) this->m_Model->Update(); } void QmitkPropertyTreeView::OnFilterTextChanged(const QString& filter) { m_ProxyModel->setFilterWildcard(filter); - - if (filter.isEmpty()) - m_Controls.treeView->collapseAll(); - else - m_Controls.treeView->expandAll(); + m_Controls.treeView->expandAll(); } void QmitkPropertyTreeView::OnModelReset() { + m_Controls.treeView->expandAll(); m_Controls.descriptionLabel->hide(); this->HideAllIcons(); } diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp index 7645d8211d..4dfecdd956 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp @@ -1,164 +1,168 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // render window manager plugin #include "QmitkRenderWindowManagerView.h" // mitk core #include <mitkBaseRenderer.h> #include <mitkDataNode.h> #include <QmitkRenderWindow.h> // mitk qt widgets #include <QmitkAbstractMultiWidget.h> #include <QmitkRenderWindowWidget.h> // mitk gui qt common plugin #include <QmitkAbstractMultiWidgetEditor.h> const std::string QmitkRenderWindowManagerView::VIEW_ID = "org.mitk.views.renderwindowmanager"; void QmitkRenderWindowManagerView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { if (m_RenderWindowPart != renderWindowPart) { m_RenderWindowPart = renderWindowPart; - SetControlledRenderer(); + this->SetControlledRenderer(); // if the render window part is an abstract multi widget editor we can receive the abstract multi widget and listen to the signal auto abstractMultiWidgetEditor = dynamic_cast<QmitkAbstractMultiWidgetEditor*>(m_RenderWindowPart); if (nullptr != abstractMultiWidgetEditor) { - connect(abstractMultiWidgetEditor->GetMultiWidget(), &QmitkAbstractMultiWidget::ActiveRenderWindowChanged, this, &QmitkRenderWindowManagerView::RenderWindowChanged); + connect(abstractMultiWidgetEditor->GetMultiWidget(), &QmitkAbstractMultiWidget::ActiveRenderWindowChanged, + this, &QmitkRenderWindowManagerView::RenderWindowChanged); } } } void QmitkRenderWindowManagerView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) { if (m_RenderWindowPart == renderWindowPart) { // if the render window part is an abstract multi widget editor we need to disconnect the signal before release the render window part auto abstractMultiWidgetEditor = dynamic_cast<QmitkAbstractMultiWidgetEditor*>(m_RenderWindowPart); if (nullptr != abstractMultiWidgetEditor) { - disconnect(abstractMultiWidgetEditor->GetMultiWidget(), &QmitkAbstractMultiWidget::ActiveRenderWindowChanged, this, &QmitkRenderWindowManagerView::RenderWindowChanged); + disconnect(abstractMultiWidgetEditor->GetMultiWidget(), &QmitkAbstractMultiWidget::ActiveRenderWindowChanged, + this, &QmitkRenderWindowManagerView::RenderWindowChanged); } m_RenderWindowPart = nullptr; - SetControlledRenderer(); + this->SetControlledRenderer(); } } void QmitkRenderWindowManagerView::RenderWindowPartInputChanged(mitk::IRenderWindowPart* renderWindowPart) { if (m_RenderWindowPart == renderWindowPart) { - SetControlledRenderer(); + this->SetControlledRenderer(); } } -void QmitkRenderWindowManagerView::SetFocus() -{ - // nothing here -} - void QmitkRenderWindowManagerView::CreateQtPartControl(QWidget* parent) { m_Parent = parent; // create GUI widgets m_Controls.setupUi(parent); // add custom render window manager UI widget to the 'renderWindowManagerTab' m_RenderWindowInspector = new QmitkRenderWindowDataStorageInspector(parent); m_RenderWindowInspector->SetDataStorage(GetDataStorage()); m_RenderWindowInspector->setObjectName(QStringLiteral("m_RenderWindowManipulatorWidget")); m_Controls.verticalLayout->addWidget(m_RenderWindowInspector); // data node context menu and menu actions m_InspectorView = m_RenderWindowInspector->GetView(); m_DataNodeContextMenu = new QmitkDataNodeContextMenu(GetSite(), m_InspectorView); m_DataNodeContextMenu->SetDataStorage(GetDataStorage()); //m_DataNodeContextMenu->SetSurfaceDecimation(m_SurfaceDecimation); // connect objects - connect(m_Controls.comboBoxRenderWindowSelection, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged), this, &QmitkRenderWindowManagerView::OnRenderWindowSelectionChanged); - connect(m_InspectorView, &QAbstractItemView::customContextMenuRequested, m_DataNodeContextMenu, &QmitkDataNodeContextMenu::OnContextMenuRequested); + connect(m_Controls.comboBoxRenderWindowSelection, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged), + this, &QmitkRenderWindowManagerView::OnRenderWindowSelectionChanged); + connect(m_InspectorView, &QAbstractItemView::customContextMenuRequested, + m_DataNodeContextMenu, &QmitkDataNodeContextMenu::OnContextMenuRequested); + + auto renderWindowPart = GetRenderWindowPart(); + if (nullptr != renderWindowPart) + { + this->RenderWindowPartActivated(renderWindowPart); + } - m_RenderWindowPart = GetRenderWindowPart(); // also sets the controlled renderer - SetControlledRenderer(); + this->SetControlledRenderer(); } void QmitkRenderWindowManagerView::SetControlledRenderer() { QHash<QString, QmitkRenderWindow*> renderWindows; if (nullptr != m_RenderWindowPart) { renderWindows = m_RenderWindowPart->GetQmitkRenderWindows(); } mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer; QStringList rendererNames; m_Controls.comboBoxRenderWindowSelection->clear(); mitk::BaseRenderer* baseRenderer = nullptr; for (const auto& renderWindow : renderWindows.values()) { baseRenderer = mitk::BaseRenderer::GetInstance(renderWindow->GetVtkRenderWindow()); if (nullptr != baseRenderer) { controlledRenderer.push_back(baseRenderer); rendererNames.append(baseRenderer->GetName()); } } m_RenderWindowInspector->SetControlledRenderer(controlledRenderer); rendererNames.sort(); m_Controls.comboBoxRenderWindowSelection->addItems(rendererNames); } void QmitkRenderWindowManagerView::OnRenderWindowSelectionChanged(const QString& renderWindowId) { m_RenderWindowInspector->SetActiveRenderWindow(renderWindowId); mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(renderWindowId.toStdString()); if (nullptr != selectedRenderer) { m_DataNodeContextMenu->SetBaseRenderer(selectedRenderer); } // if the render window part is an abstract multi widget editor we can set the active render window auto abstractMultiWidgetEditor = dynamic_cast<QmitkAbstractMultiWidgetEditor*>(m_RenderWindowPart); if (nullptr != abstractMultiWidgetEditor) { auto renderWindowWidget = abstractMultiWidgetEditor->GetMultiWidget()->GetRenderWindowWidget(renderWindowId); abstractMultiWidgetEditor->GetMultiWidget()->SetActiveRenderWindowWidget(renderWindowWidget); } } void QmitkRenderWindowManagerView::RenderWindowChanged() { auto abstractMultiWidget = dynamic_cast<QmitkAbstractMultiWidget*>(sender()); if (nullptr != abstractMultiWidget) { auto activeRenderWindowWidget = abstractMultiWidget->GetActiveRenderWindowWidget(); if (nullptr != activeRenderWindowWidget) { m_Controls.comboBoxRenderWindowSelection->setCurrentText(activeRenderWindowWidget->GetWidgetName()); } } } QItemSelectionModel* QmitkRenderWindowManagerView::GetDataNodeSelectionModel() const { return m_InspectorView->selectionModel(); } diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h index 052a1bda3e..3639b3537e 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h @@ -1,79 +1,79 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKRENDERWINDOWMANAGERVIEW_H #define QMITKRENDERWINDOWMANAGERVIEW_H // render window manager plugin #include "ui_QmitkRenderWindowManagerControls.h" // render window manager UI module #include <QmitkRenderWindowDataStorageInspector.h> // mitk gui qt application #include <QmitkDataNodeContextMenu.h> // mitk gui common plugin #include <mitkIRenderWindowPartListener.h> // mitk gui qt common plugin #include <QmitkAbstractView.h> /** * @brief RenderWindowManager */ class QmitkRenderWindowManagerView : public QmitkAbstractView, public mitk::IRenderWindowPartListener { Q_OBJECT public: static const std::string VIEW_ID; void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override; void RenderWindowPartInputChanged(mitk::IRenderWindowPart* renderWindowPart) override; protected: - void SetFocus() override; + void SetFocus() override {} void CreateQtPartControl(QWidget* parent) override; private Q_SLOTS: /** * @brief Called when the user changes the render window selection in the combo box. * * @param renderWindowId The text inside the combo box. */ void OnRenderWindowSelectionChanged(const QString& renderWindowId); private: void SetControlledRenderer(); void RenderWindowChanged(); QWidget* m_Parent; Ui::QmitkRenderWindowManagerControls m_Controls; mitk::IRenderWindowPart* m_RenderWindowPart; QmitkRenderWindowDataStorageInspector* m_RenderWindowInspector; QAbstractItemView* m_InspectorView; QmitkDataNodeContextMenu* m_DataNodeContextMenu; QItemSelectionModel* GetDataNodeSelectionModel() const override; }; #endif // QMITKRENDERWINDOWMANAGERVIEW_H diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/QmitkSegmentationPreferencePage.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/QmitkSegmentationPreferencePage.cpp index 057e60feec..a79f58c5bf 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/QmitkSegmentationPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/QmitkSegmentationPreferencePage.cpp @@ -1,176 +1,175 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkSegmentationPreferencePage.h" #include <QLabel> #include <QPushButton> #include <QFormLayout> #include <QCheckBox> #include <QGroupBox> #include <QRadioButton> #include <QMessageBox> #include <QDoubleSpinBox> #include <berryIPreferencesService.h> #include <berryPlatform.h> QmitkSegmentationPreferencePage::QmitkSegmentationPreferencePage() : m_MainControl(nullptr), m_SlimViewCheckBox(nullptr), m_RadioOutline(nullptr), m_RadioOverlay(nullptr), + m_SelectionModeCheckBox(nullptr), m_SmoothingCheckBox(nullptr), m_SmoothingSpinBox(nullptr), m_DecimationSpinBox(nullptr), m_ClosingSpinBox(nullptr), - m_SelectionModeCheckBox(nullptr), m_Initializing(false) { + } QmitkSegmentationPreferencePage::~QmitkSegmentationPreferencePage() { } void QmitkSegmentationPreferencePage::Init(berry::IWorkbench::Pointer ) { } void QmitkSegmentationPreferencePage::CreateQtControl(QWidget* parent) { m_Initializing = true; berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); m_SegmentationPreferencesNode = prefService->GetSystemPreferences()->Node("/org.mitk.views.segmentation"); m_MainControl = new QWidget(parent); auto formLayout = new QFormLayout; formLayout->setHorizontalSpacing(8); formLayout->setVerticalSpacing(24); m_SlimViewCheckBox = new QCheckBox("Hide tool button texts and increase icon size", m_MainControl); formLayout->addRow("Slim view", m_SlimViewCheckBox); auto displayOptionsLayout = new QVBoxLayout; m_RadioOutline = new QRadioButton( "Draw as outline", m_MainControl); displayOptionsLayout->addWidget( m_RadioOutline ); m_RadioOverlay = new QRadioButton( "Draw as transparent overlay", m_MainControl); displayOptionsLayout->addWidget( m_RadioOverlay ); formLayout->addRow( "2D display", displayOptionsLayout ); + m_SelectionModeCheckBox = new QCheckBox("Enable auto-selection mode", m_MainControl); + m_SelectionModeCheckBox->setToolTip("Automatically select a patient image and a segmentation if available"); + formLayout->addRow("Data node selection mode", m_SelectionModeCheckBox); + auto surfaceLayout = new QFormLayout; surfaceLayout->setSpacing(8); m_SmoothingCheckBox = new QCheckBox("Use image spacing as smoothing value hint", m_MainControl); surfaceLayout->addRow(m_SmoothingCheckBox); connect(m_SmoothingCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnSmoothingCheckboxChecked(int))); m_SmoothingSpinBox = new QDoubleSpinBox(m_MainControl); m_SmoothingSpinBox->setMinimum(0.0); m_SmoothingSpinBox->setSingleStep(0.5); m_SmoothingSpinBox->setValue(1.0); m_SmoothingSpinBox->setToolTip("The Smoothing value is used as variance for a gaussian blur."); surfaceLayout->addRow("Smoothing value (mm)", m_SmoothingSpinBox); m_DecimationSpinBox = new QDoubleSpinBox(m_MainControl); m_DecimationSpinBox->setMinimum(0.0); m_DecimationSpinBox->setMaximum(0.99); m_DecimationSpinBox->setSingleStep(0.1); m_DecimationSpinBox->setValue(0.5); m_DecimationSpinBox->setToolTip("Valid range is [0, 1). High values increase decimation, especially when very close to 1. A value of 0 disables decimation."); surfaceLayout->addRow("Decimation rate", m_DecimationSpinBox); m_ClosingSpinBox = new QDoubleSpinBox(m_MainControl); m_ClosingSpinBox->setMinimum(0.0); m_ClosingSpinBox->setMaximum(1.0); m_ClosingSpinBox->setSingleStep(0.1); m_ClosingSpinBox->setValue(0.0); m_ClosingSpinBox->setToolTip("Valid range is [0, 1]. Higher values increase closing. A value of 0 disables closing."); surfaceLayout->addRow("Closing Ratio", m_ClosingSpinBox); - m_SelectionModeCheckBox = new QCheckBox("Enable auto-selection mode", m_MainControl); - m_SelectionModeCheckBox->setToolTip("Automatically select a patient image and a segmentation if available"); - formLayout->addRow("Data node selection mode",m_SelectionModeCheckBox); - formLayout->addRow("Smoothed surface creation", surfaceLayout); m_MainControl->setLayout(formLayout); this->Update(); m_Initializing = false; } QWidget* QmitkSegmentationPreferencePage::GetQtControl() const { return m_MainControl; } bool QmitkSegmentationPreferencePage::PerformOk() { m_SegmentationPreferencesNode->PutBool("slim view", m_SlimViewCheckBox->isChecked()); m_SegmentationPreferencesNode->PutBool("draw outline", m_RadioOutline->isChecked()); m_SegmentationPreferencesNode->PutBool("smoothing hint", m_SmoothingCheckBox->isChecked()); m_SegmentationPreferencesNode->PutDouble("smoothing value", m_SmoothingSpinBox->value()); m_SegmentationPreferencesNode->PutDouble("decimation rate", m_DecimationSpinBox->value()); m_SegmentationPreferencesNode->PutDouble("closing ratio", m_ClosingSpinBox->value()); m_SegmentationPreferencesNode->PutBool("auto selection", m_SelectionModeCheckBox->isChecked()); return true; } void QmitkSegmentationPreferencePage::PerformCancel() { } void QmitkSegmentationPreferencePage::Update() { - //m_EnableSingleEditing->setChecked(m_SegmentationPreferencesNode->GetBool("Single click property editing", true)); - m_SlimViewCheckBox->setChecked(m_SegmentationPreferencesNode->GetBool("slim view", false)); if (m_SegmentationPreferencesNode->GetBool("draw outline", true) ) { - m_RadioOutline->setChecked( true ); + m_RadioOutline->setChecked(true); } else { - m_RadioOverlay->setChecked( true ); + m_RadioOverlay->setChecked(true); } + m_SelectionModeCheckBox->setChecked(m_SegmentationPreferencesNode->GetBool("auto selection", true)); + if (m_SegmentationPreferencesNode->GetBool("smoothing hint", true)) { m_SmoothingCheckBox->setChecked(true); m_SmoothingSpinBox->setDisabled(true); } else { m_SmoothingCheckBox->setChecked(false); m_SmoothingSpinBox->setEnabled(true); } - m_SelectionModeCheckBox->setChecked( m_SegmentationPreferencesNode->GetBool("auto selection", true) ); - m_SmoothingSpinBox->setValue(m_SegmentationPreferencesNode->GetDouble("smoothing value", 1.0)); m_DecimationSpinBox->setValue(m_SegmentationPreferencesNode->GetDouble("decimation rate", 0.5)); m_ClosingSpinBox->setValue(m_SegmentationPreferencesNode->GetDouble("closing ratio", 0.0)); } void QmitkSegmentationPreferencePage::OnSmoothingCheckboxChecked(int state) { if (state != Qt::Unchecked) m_SmoothingSpinBox->setDisabled(true); else m_SmoothingSpinBox->setEnabled(true); } diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/QmitkSegmentationPreferencePage.h b/Plugins/org.mitk.gui.qt.segmentation/src/QmitkSegmentationPreferencePage.h index 9d7e1100e9..5b38f81271 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/QmitkSegmentationPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.segmentation/src/QmitkSegmentationPreferencePage.h @@ -1,79 +1,70 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkSegmentationPreferencePage_h_included #define QmitkSegmentationPreferencePage_h_included #include "org_mitk_gui_qt_segmentation_Export.h" #include <berryIPreferences.h> #include "berryIQtPreferencePage.h" class QWidget; class QCheckBox; class QRadioButton; class QDoubleSpinBox; class MITK_QT_SEGMENTATION QmitkSegmentationPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: QmitkSegmentationPreferencePage(); ~QmitkSegmentationPreferencePage() override; void Init(berry::IWorkbench::Pointer workbench) override; void CreateQtControl(QWidget* widget) override; QWidget* GetQtControl() const override; - /// - /// \see IPreferencePage::PerformOk() - /// bool PerformOk() override; - /// - /// \see IPreferencePage::PerformCancel() - /// void PerformCancel() override; - /// - /// \see IPreferencePage::Update() - /// void Update() override; protected slots: void OnSmoothingCheckboxChecked(int); protected: QWidget* m_MainControl; QCheckBox* m_SlimViewCheckBox; QRadioButton* m_RadioOutline; QRadioButton* m_RadioOverlay; + QCheckBox* m_SelectionModeCheckBox; QCheckBox* m_SmoothingCheckBox; QDoubleSpinBox* m_SmoothingSpinBox; QDoubleSpinBox* m_DecimationSpinBox; QDoubleSpinBox* m_ClosingSpinBox; - QCheckBox* m_SelectionModeCheckBox; bool m_Initializing; berry::IPreferences::Pointer m_SegmentationPreferencesNode; }; #endif /* QMITKDATAMANAGERPREFERENCEPAGE_H_ */ diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/Common/QmitkDataSelectionWidget.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/Common/QmitkDataSelectionWidget.cpp index 936217f330..9035c9faa8 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/Common/QmitkDataSelectionWidget.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/Common/QmitkDataSelectionWidget.cpp @@ -1,236 +1,242 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkDataSelectionWidget.h" #include "../mitkPluginActivator.h" #include <berryIWorkbench.h> #include <mitkContourModel.h> #include <mitkContourModelSet.h> #include <mitkIDataStorageService.h> #include <mitkLabelSetImage.h> #include <mitkNodePredicateAnd.h> #include <mitkNodePredicateDataType.h> #include <mitkNodePredicateNot.h> #include <mitkNodePredicateOr.h> #include <mitkNodePredicateProperty.h> #include <mitkProperties.h> #include <mitkSurface.h> #include <QmitkSingleNodeSelectionWidget.h> #include <QLabel> #include <algorithm> #include <cassert> #include <iterator> static mitk::NodePredicateBase::Pointer CreatePredicate(QmitkDataSelectionWidget::Predicate predicate) { auto imageType = mitk::TNodePredicateDataType<mitk::Image>::New(); auto labelSetImageType = mitk::TNodePredicateDataType<mitk::LabelSetImage>::New(); auto surfaceType = mitk::TNodePredicateDataType<mitk::Surface>::New(); auto contourModelType = mitk::TNodePredicateDataType<mitk::ContourModel>::New(); auto contourModelSetType = mitk::TNodePredicateDataType<mitk::ContourModelSet>::New(); auto nonLabelSetImageType = mitk::NodePredicateAnd::New(imageType, mitk::NodePredicateNot::New(labelSetImageType)); auto nonHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateOr::New( mitk::NodePredicateProperty::New("helper object"), mitk::NodePredicateProperty::New("hidden object"))); auto isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); auto isSegmentation = mitk::NodePredicateProperty::New("segmentation", mitk::BoolProperty::New(true)); auto isBinaryOrSegmentation = mitk::NodePredicateOr::New(isBinary, isSegmentation); mitk::NodePredicateBase::Pointer returnValue; switch(predicate) { case QmitkDataSelectionWidget::ImagePredicate: returnValue = mitk::NodePredicateAnd::New( mitk::NodePredicateNot::New(isBinaryOrSegmentation), nonLabelSetImageType).GetPointer(); break; case QmitkDataSelectionWidget::SegmentationPredicate: returnValue = mitk::NodePredicateOr::New( mitk::NodePredicateAnd::New(imageType, isBinaryOrSegmentation), labelSetImageType).GetPointer(); break; case QmitkDataSelectionWidget::SurfacePredicate: returnValue = surfaceType.GetPointer(); break; case QmitkDataSelectionWidget::ImageAndSegmentationPredicate: returnValue = imageType.GetPointer(); break; case QmitkDataSelectionWidget::ContourModelPredicate: returnValue = mitk::NodePredicateOr::New( contourModelSetType, contourModelSetType).GetPointer(); break; case QmitkDataSelectionWidget::SegmentationOrSurfacePredicate: returnValue = mitk::NodePredicateOr::New( mitk::NodePredicateAnd::New(imageType, isBinaryOrSegmentation), labelSetImageType).GetPointer(); returnValue = mitk::NodePredicateOr::New(returnValue, surfaceType).GetPointer(); break; default: assert(false && "Unknown predefined predicate!"); return nullptr; } return mitk::NodePredicateAnd::New(returnValue, nonHelperObject).GetPointer(); } QmitkDataSelectionWidget::QmitkDataSelectionWidget(QWidget* parent) : QWidget(parent) { m_Controls.setupUi(this); m_Controls.helpLabel->hide(); } QmitkDataSelectionWidget::~QmitkDataSelectionWidget() { } unsigned int QmitkDataSelectionWidget::AddDataSelection(QmitkDataSelectionWidget::Predicate predicate) { QString hint = "Select node"; switch (predicate) { case QmitkDataSelectionWidget::ImagePredicate: hint = "Select an image"; break; case QmitkDataSelectionWidget::SegmentationPredicate: hint = "Select a segmentation"; break; case QmitkDataSelectionWidget::SurfacePredicate: hint = "Select a surface"; break; case QmitkDataSelectionWidget::ImageAndSegmentationPredicate: hint = "Select an image or segmentation"; break; case QmitkDataSelectionWidget::ContourModelPredicate: hint = "Select a contour model"; break; case QmitkDataSelectionWidget::SegmentationOrSurfacePredicate: hint = "Select a segmentation or surface"; break; } return this->AddDataSelection("", hint, hint, "", predicate); } unsigned int QmitkDataSelectionWidget::AddDataSelection(mitk::NodePredicateBase* predicate) { return this->AddDataSelection("", "Select a node", "Select a node", "", predicate); } unsigned int QmitkDataSelectionWidget::AddDataSelection(const QString &labelText, const QString &info, const QString &popupTitel, const QString &popupHint, QmitkDataSelectionWidget::Predicate predicate) { return this->AddDataSelection(labelText, info, popupHint, popupTitel, CreatePredicate(predicate)); } unsigned int QmitkDataSelectionWidget::AddDataSelection(const QString &labelText, const QString &info, const QString &popupTitel, const QString &popupHint, mitk::NodePredicateBase* predicate) { int row = m_Controls.gridLayout->rowCount(); if (!labelText.isEmpty()) { QLabel* label = new QLabel(labelText, m_Controls.dataSelectionWidget); label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); m_Controls.gridLayout->addWidget(label, row, 0); } QmitkSingleNodeSelectionWidget* nodeSelection = new QmitkSingleNodeSelectionWidget(m_Controls.dataSelectionWidget); nodeSelection->SetSelectionIsOptional(false); nodeSelection->SetInvalidInfo(info); nodeSelection->SetPopUpTitel(popupTitel); nodeSelection->SetPopUpHint(popupHint); nodeSelection->SetDataStorage(this->GetDataStorage()); nodeSelection->SetNodePredicate(predicate); nodeSelection->SetAutoSelectNewNodes(true); nodeSelection->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); nodeSelection->setMinimumSize(0, 40); connect(nodeSelection, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkDataSelectionWidget::OnSelectionChanged); m_Controls.gridLayout->addWidget(nodeSelection, row, 1); m_NodeSelectionWidgets.push_back(nodeSelection); return static_cast<unsigned int>(m_NodeSelectionWidgets.size() - 1); } mitk::DataStorage::Pointer QmitkDataSelectionWidget::GetDataStorage() const { ctkServiceReference ref = mitk::PluginActivator::getContext()->getServiceReference<mitk::IDataStorageService>(); assert(ref == true); mitk::IDataStorageService* service = mitk::PluginActivator::getContext()->getService<mitk::IDataStorageService>(ref); assert(service); return service->GetDefaultDataStorage()->GetDataStorage(); } mitk::DataNode::Pointer QmitkDataSelectionWidget::GetSelection(unsigned int index) { assert(index < m_NodeSelectionWidgets.size()); return m_NodeSelectionWidgets[index]->GetSelectedNode(); } void QmitkDataSelectionWidget::SetPredicate(unsigned int index, Predicate predicate) { this->SetPredicate(index, CreatePredicate(predicate)); } -void QmitkDataSelectionWidget::SetPredicate(unsigned int index, mitk::NodePredicateBase* predicate) +void QmitkDataSelectionWidget::SetPredicate(unsigned int index, const mitk::NodePredicateBase* predicate) { assert(index < m_NodeSelectionWidgets.size()); m_NodeSelectionWidgets[index]->SetNodePredicate(predicate); } +const mitk::NodePredicateBase *QmitkDataSelectionWidget::GetPredicate(unsigned int index) const +{ + assert(index < m_NodeSelectionWidgets.size()); + return m_NodeSelectionWidgets[index]->GetNodePredicate(); +} + void QmitkDataSelectionWidget::SetHelpText(const QString& text) { if (!text.isEmpty()) { m_Controls.helpLabel->setText(text); if (!m_Controls.helpLabel->isVisible()) m_Controls.helpLabel->show(); } else { m_Controls.helpLabel->hide(); } } void QmitkDataSelectionWidget::OnSelectionChanged(QList<mitk::DataNode::Pointer> selection) { std::vector<QmitkSingleNodeSelectionWidget*>::iterator it = std::find(m_NodeSelectionWidgets.begin(), m_NodeSelectionWidgets.end(), sender()); assert(it != m_NodeSelectionWidgets.end()); const mitk::DataNode* result = nullptr; if (!selection.empty()) { result = selection.front(); } emit SelectionChanged(std::distance(m_NodeSelectionWidgets.begin(), it), result); } diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/Common/QmitkDataSelectionWidget.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/Common/QmitkDataSelectionWidget.h index f702654857..2586454d2d 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/Common/QmitkDataSelectionWidget.h +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/Common/QmitkDataSelectionWidget.h @@ -1,68 +1,69 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkDataSelectionWidget_h #define QmitkDataSelectionWidget_h #include <ui_QmitkDataSelectionWidgetControls.h> #include <mitkDataNode.h> #include <mitkDataStorage.h> #include <vector> namespace mitk { class NodePredicateBase; } class QmitkSingleNodeSelectionWidget; class QmitkDataSelectionWidget : public QWidget { Q_OBJECT public: enum Predicate { ImagePredicate, SegmentationPredicate, SurfacePredicate, ImageAndSegmentationPredicate, ContourModelPredicate, SegmentationOrSurfacePredicate }; explicit QmitkDataSelectionWidget(QWidget* parent = nullptr); ~QmitkDataSelectionWidget() override; unsigned int AddDataSelection(Predicate predicate); unsigned int AddDataSelection(mitk::NodePredicateBase* predicate = nullptr); unsigned int AddDataSelection(const QString &labelText, const QString &info, const QString &popupTitel, const QString &popupHint, Predicate predicate); unsigned int AddDataSelection(const QString &labelText, const QString &info, const QString &popupTitel, const QString &popupHint, mitk::NodePredicateBase* predicate = nullptr); mitk::DataStorage::Pointer GetDataStorage() const; mitk::DataNode::Pointer GetSelection(unsigned int index); void SetPredicate(unsigned int index, Predicate predicate); - void SetPredicate(unsigned int index, mitk::NodePredicateBase* predicate); + void SetPredicate(unsigned int index, const mitk::NodePredicateBase* predicate); + const mitk::NodePredicateBase *GetPredicate(unsigned int index) const; void SetHelpText(const QString& text); signals: void SelectionChanged(unsigned int index, const mitk::DataNode* selection); private slots: void OnSelectionChanged(QList<mitk::DataNode::Pointer> selection); private: Ui::QmitkDataSelectionWidgetControls m_Controls; std::vector<QmitkSingleNodeSelectionWidget*> m_NodeSelectionWidgets; }; #endif diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationControls.ui b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationControls.ui index 09ab641aa5..cbe3ef5e96 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationControls.ui +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationControls.ui @@ -1,529 +1,289 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>QmitkSegmentationControls</class> <widget class="QWidget" name="QmitkSegmentationControls"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>237</width> <height>591</height> </rect> </property> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>0</width> <height>0</height> </size> </property> - <property name="font"> - <font> - <family>MS Shell Dlg 2</family> - <pointsize>8</pointsize> - <weight>50</weight> - <italic>false</italic> - <bold>false</bold> - <underline>false</underline> - <strikeout>false</strikeout> - </font> - </property> <property name="windowTitle"> <string>QmitkSegmentation</string> </property> <layout class="QVBoxLayout" name="verticalLayout_6"> - <property name="sizeConstraint"> - <enum>QLayout::SetMinimumSize</enum> - </property> - <property name="leftMargin"> - <number>6</number> - </property> - <property name="topMargin"> - <number>6</number> - </property> - <property name="rightMargin"> - <number>6</number> - </property> - <property name="bottomMargin"> - <number>6</number> - </property> <item> <widget class="QGroupBox" name="groupBox"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="title"> <string>Data Selection</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <property name="leftMargin"> - <number>6</number> - </property> - <property name="topMargin"> - <number>6</number> - </property> - <property name="rightMargin"> - <number>6</number> - </property> - <property name="bottomMargin"> - <number>6</number> - </property> - <item> - <layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,0"> - <property name="sizeConstraint"> - <enum>QLayout::SetMinimumSize</enum> - </property> - <property name="spacing"> - <number>4</number> - </property> + <layout class="QGridLayout" name="gridLayout"> <item row="0" column="0"> <widget class="QLabel" name="lblPatientImage"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> <property name="text"> <string>Selected Image</string> </property> </widget> </item> - <item row="1" column="0"> - <widget class="QLabel" name="lblSegmentation"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <item row="0" column="1"> + <widget class="QmitkSingleNodeSelectionWidget" name="patImageSelector" native="true"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>40</height> + </size> </property> - <property name="text"> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="lblSegmentation"> + <property name="text"> <string>Segmentation</string> </property> </widget> + </item> + <item row="1" column="1"> + <widget class="QmitkSingleNodeSelectionWidget" name="segImageSelector" native="true"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>40</height> + </size> + </property> + </widget> </item> <item row="1" column="2"> <widget class="QToolButton" name="btnNewSegmentation"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Minimum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> <property name="toolTip"> <string>Create a new segmentation</string> </property> <property name="text"> <string>&New...</string> </property> - <property name="icon"> - <iconset resource="../../resources/segmentation.qrc"> - <normaloff>:/segmentation/btnNew.png</normaloff>:/segmentation/btnNew.png</iconset> - </property> <property name="toolButtonStyle"> <enum>Qt::ToolButtonTextOnly</enum> </property> </widget> </item> - <item row="1" column="1"> - <widget class="QmitkSingleNodeSelectionWidget" name="segImageSelector" native="true"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>40</height> - </size> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QmitkSingleNodeSelectionWidget" name="patImageSelector" native="true"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>40</height> - </size> + <item row="2" column="0" colspan="3"> + <widget class="QLabel" name="lblSegmentationWarnings"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> + <property name="wordWrap"> + <bool>true</bool> + </property> </widget> </item> </layout> - </item> - <item> - <widget class="QLabel" name="lblSegmentationWarnings"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="palette"> - <palette> - <active> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - <colorrole role="Text"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - <colorrole role="ButtonText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - <colorrole role="PlaceholderText"> - <brush brushstyle="NoBrush"> - <color alpha="128"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </active> - <inactive> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - <colorrole role="Text"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - <colorrole role="ButtonText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - <colorrole role="PlaceholderText"> - <brush brushstyle="NoBrush"> - <color alpha="128"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </inactive> - <disabled> - <colorrole role="WindowText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>84</red> - <green>82</green> - <blue>78</blue> - </color> - </brush> - </colorrole> - <colorrole role="Text"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>84</red> - <green>82</green> - <blue>78</blue> - </color> - </brush> - </colorrole> - <colorrole role="ButtonText"> - <brush brushstyle="SolidPattern"> - <color alpha="255"> - <red>84</red> - <green>82</green> - <blue>78</blue> - </color> - </brush> - </colorrole> - <colorrole role="PlaceholderText"> - <brush brushstyle="NoBrush"> - <color alpha="128"> - <red>200</red> - <green>0</green> - <blue>0</blue> - </color> - </brush> - </colorrole> - </disabled> - </palette> - </property> - <property name="font"> - <font> - <family>MS Shell Dlg 2</family> - <pointsize>8</pointsize> - <weight>50</weight> - <italic>false</italic> - <bold>false</bold> - <underline>false</underline> - <strikeout>false</strikeout> - </font> - </property> - <property name="text"> - <string>Please load an image!</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> </widget> </item> <item> <widget class="QTabWidget" name="tabWidgetSegmentationTools"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> <property name="styleSheet"> <string notr="true">QTabWidget::tab-bar { alignment: middle; }</string> </property> - <property name="tabPosition"> - <enum>QTabWidget::North</enum> - </property> - <property name="tabShape"> - <enum>QTabWidget::Triangular</enum> - </property> <property name="currentIndex"> <number>0</number> </property> <widget class="QWidget" name="tab2DTools"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="autoFillBackground"> - <bool>false</bool> - </property> <attribute name="title"> <string>2D Tools</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout"> - <property name="leftMargin"> - <number>6</number> - </property> - <property name="topMargin"> - <number>6</number> - </property> - <property name="rightMargin"> - <number>6</number> - </property> - <property name="bottomMargin"> - <number>6</number> - </property> <item> <widget class="QmitkToolGUIArea" name="m_ManualToolGUIContainer2D" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> <widget class="QmitkToolSelectionBox" name="m_ManualToolSelectionBox2D" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> <widget class="QmitkSlicesInterpolator" name="m_SlicesInterpolator" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> - <spacer name="verticalSpacer_2"> + <spacer name="verticalSpacer_1"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="tab3DTools"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> <attribute name="title"> <string>3D Tools</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout_2"> - <property name="leftMargin"> - <number>6</number> - </property> - <property name="topMargin"> - <number>6</number> - </property> - <property name="rightMargin"> - <number>6</number> - </property> - <property name="bottomMargin"> - <number>6</number> - </property> <item> <widget class="QmitkToolGUIArea" name="m_ManualToolGUIContainer3D" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> <widget class="QmitkToolSelectionBox" name="m_ManualToolSelectionBox3D" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="font"> <font> <weight>50</weight> <bold>false</bold> </font> </property> </widget> </item> <item> - <spacer name="verticalSpacer"> + <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> </widget> </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> </layout> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> <customwidget> <class>QmitkSingleNodeSelectionWidget</class> <extends>QWidget</extends> <header location="global">QmitkSingleNodeSelectionWidget.h</header> <container>1</container> </customwidget> <customwidget> <class>QmitkToolSelectionBox</class> <extends>QWidget</extends> <header location="global">QmitkToolSelectionBox.h</header> </customwidget> <customwidget> - <class>QmitkSlicesInterpolator</class> + <class>QmitkToolGUIArea</class> <extends>QWidget</extends> - <header location="global">QmitkSlicesInterpolator.h</header> + <header location="global">QmitkToolGUIArea.h</header> </customwidget> <customwidget> - <class>QmitkToolGUIArea</class> + <class>QmitkSlicesInterpolator</class> <extends>QWidget</extends> - <header location="global">QmitkToolGUIArea.h</header> + <header location="global">QmitkSlicesInterpolator.h</header> </customwidget> </customwidgets> <includes> <include location="global">QmitkToolGUIArea.h</include> <include location="global">QmitkToolSelectionBox.h</include> <include location="global">QmitkSlicesInterpolator.h</include> </includes> <resources> <include location="../../resources/segmentation.qrc"/> <include location="../../resources/segmentation.qrc"/> </resources> <connections/> </ui> diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp index a724c68e04..8fdf537329 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp @@ -1,912 +1,824 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#include <QObject> - -#include "mitkProperties.h" -#include "mitkSegTool2D.h" -#include "mitkStatusBar.h" - -#include "QmitkNewSegmentationDialog.h" -#include <QmitkSegmentationOrganNamesHandling.cpp> - -#include <QMessageBox> - -#include <berryIWorkbenchPage.h> - #include "QmitkSegmentationView.h" +#include "mitkPluginActivator.h" -#include <mitkSurfaceToImageFilter.h> - -#include "mitkVtkResliceInterpolationProperty.h" +// blueberry +#include <berryIWorkbenchPage.h> -#include "mitkApplicationCursor.h" -#include "mitkSegmentationObjectFactory.h" -#include "mitkPluginActivator.h" -#include "mitkCameraController.h" -#include "mitkLabelSetImage.h" -#include "mitkImageTimeSelector.h" -#include "mitkNodePredicateSubGeometry.h" +// mitk +#include <mitkApplicationCursor.h> +#include <mitkCameraController.h> +#include <mitkImageTimeSelector.h> +#include <mitkLabelSetImage.h> +#include <mitkNodePredicateSubGeometry.h> +#include <mitkSegmentationObjectFactory.h> +#include <mitkSegTool2D.h> +#include <mitkStatusBar.h> +#include <mitkToolManagerProvider.h> +#include <mitkVtkResliceInterpolationProperty.h> +#include <mitkWorkbenchUtil.h> +// Qmitk +#include <QmitkNewSegmentationDialog.h> #include <QmitkRenderWindow.h> +#include <QmitkSegmentationOrganNamesHandling.cpp> -#include "usModuleResource.h" -#include "usModuleResourceStream.h" +// us +#include <usModuleResource.h> +#include <usModuleResourceStream.h> -//micro service to get the ToolManager instance -#include "mitkToolManagerProvider.h" +// Qt +#include <QMessageBox> -#include <mitkWorkbenchUtil.h> #include <regex> const std::string QmitkSegmentationView::VIEW_ID = "org.mitk.views.segmentation"; QmitkSegmentationView::QmitkSegmentationView() : m_Parent(nullptr) , m_Controls(nullptr) , m_RenderWindowPart(nullptr) + , m_ToolManager(nullptr) + , m_ReferenceNode(nullptr) + , m_WorkingNode(nullptr) + , m_AutoSelectionEnabled(false) , m_MouseCursorSet(false) - , m_DataSelectionChanged(false) { mitk::TNodePredicateDataType<mitk::Image>::Pointer isImage = mitk::TNodePredicateDataType<mitk::Image>::New(); - mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); - mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); - mitk::NodePredicateDataType::Pointer isOdf = mitk::NodePredicateDataType::New("OdfImage"); + auto isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); + auto isDti = mitk::NodePredicateDataType::New("TensorImage"); + auto isOdf = mitk::NodePredicateDataType::New("OdfImage"); auto isSegment = mitk::NodePredicateDataType::New("Segment"); mitk::NodePredicateOr::Pointer validImages = mitk::NodePredicateOr::New(); validImages->AddPredicate(mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isSegment))); validImages->AddPredicate(isDwi); validImages->AddPredicate(isDti); validImages->AddPredicate(isOdf); - m_IsNotAHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true))); - - m_IsOfTypeImagePredicate = mitk::NodePredicateAnd::New(validImages, m_IsNotAHelperObject); + auto isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + auto isMask = mitk::NodePredicateAnd::New(isBinary, isImage); - mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); - mitk::NodePredicateNot::Pointer isNotBinaryPredicate = mitk::NodePredicateNot::New(isBinaryPredicate); + auto validSegmentations = mitk::NodePredicateOr::New(); + validSegmentations->AddPredicate(mitk::TNodePredicateDataType<mitk::LabelSetImage>::New()); + validSegmentations->AddPredicate(isMask); - mitk::NodePredicateAnd::Pointer isABinaryImagePredicate = mitk::NodePredicateAnd::New(m_IsOfTypeImagePredicate, isBinaryPredicate); - mitk::NodePredicateAnd::Pointer isNotABinaryImagePredicate = mitk::NodePredicateAnd::New(m_IsOfTypeImagePredicate, isNotBinaryPredicate); + m_SegmentationPredicate = mitk::NodePredicateAnd::New(); + m_SegmentationPredicate->AddPredicate(validSegmentations); + m_SegmentationPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))); + m_SegmentationPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object"))); - auto isMLImageType = mitk::TNodePredicateDataType<mitk::LabelSetImage>::New(); - mitk::NodePredicateAnd::Pointer isAMLImagePredicate = mitk::NodePredicateAnd::New(isMLImageType, m_IsNotAHelperObject); - mitk::NodePredicateAnd::Pointer isNotAMLImagePredicate = mitk::NodePredicateAnd::New(mitk::NodePredicateNot::New(isMLImageType), m_IsNotAHelperObject); - - m_IsASegmentationImagePredicate = mitk::NodePredicateOr::New(isABinaryImagePredicate, isAMLImagePredicate); - m_IsAPatientImagePredicate = mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, isNotAMLImagePredicate); + m_ReferencePredicate = mitk::NodePredicateAnd::New(); + m_ReferencePredicate->AddPredicate(validImages); + m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(m_SegmentationPredicate)); + m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))); + m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object"))); } QmitkSegmentationView::~QmitkSegmentationView() { if (m_Controls) { - SetToolSelectionBoxesEnabled(false); // deactivate all tools - mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1); + m_ToolManager->ActivateTool(-1); // removing all observers for (NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter) { (*dataIter).first->GetProperty("visible")->RemoveObserver((*dataIter).second); } m_WorkingDataObserverTags.clear(); mitk::RenderingManager::GetInstance()->RemoveObserver(m_RenderingManagerObserverTag); ctkPluginContext* context = mitk::PluginActivator::getContext(); ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>(); mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef); service->RemoveAllPlanePositions(); context->ungetService(ppmRef); - SetToolManagerSelection(nullptr, nullptr); + + m_ToolManager->SetReferenceData(nullptr); + m_ToolManager->SetWorkingData(nullptr); } delete m_Controls; } -void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes) +/**********************************************************************/ +/* private Q_SLOTS */ +/**********************************************************************/ +void QmitkSegmentationView::OnReferenceSelectionChanged(QList<mitk::DataNode::Pointer> nodes) { - if (!nodes) return; + m_ToolManager->ActivateTool(-1); - mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - if (!toolManager) return; - for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter) - { - this->FireNodeSelected( *iter ); - // only last iteration meaningful, multiple generated objects are not taken into account here - } + if (nodes.empty()) + { + m_Controls->segImageSelector->SetNodePredicate(m_SegmentationPredicate); + m_ReferenceNode = nullptr; + m_ToolManager->SetReferenceData(m_ReferenceNode); + this->UpdateGUI(); + return; + } + + m_ReferenceNode = nodes.first(); + m_ToolManager->SetReferenceData(m_ReferenceNode); + if (m_ReferenceNode.IsNotNull()) + { + // set a predicate such that a segmentation fits the selected reference image geometry + auto segPredicate = mitk::NodePredicateAnd::New(m_SegmentationPredicate.GetPointer(), + mitk::NodePredicateSubGeometry::New(m_ReferenceNode->GetData()->GetGeometry())); + + m_Controls->segImageSelector->SetNodePredicate(segPredicate); + + if (m_AutoSelectionEnabled) + { + // hide all image nodes to later show only the automatically selected ones + mitk::DataStorage::SetOfObjects::ConstPointer imageNodes = + this->GetDataStorage()->GetSubset(m_ReferencePredicate); + for (mitk::DataStorage::SetOfObjects::const_iterator iter = imageNodes->begin(); iter != imageNodes->end(); ++iter) + { + (*iter)->SetVisibility(false); + } + } + m_ReferenceNode->SetVisibility(true); + } + + this->UpdateGUI(); } -void QmitkSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) +void QmitkSegmentationView::OnSegmentationSelectionChanged(QList<mitk::DataNode::Pointer> nodes) { - if (m_RenderWindowPart != renderWindowPart) + m_ToolManager->ActivateTool(-1); + + if (nodes.empty()) { - m_RenderWindowPart = renderWindowPart; + m_WorkingNode = nullptr; + m_ToolManager->SetWorkingData(m_WorkingNode); + this->UpdateGUI(); + return; } - if (m_Parent) + if (m_ReferenceNode.IsNull()) { - m_Parent->setEnabled(true); + this->UpdateGUI(); + return; } - // tell the interpolation about tool manager, data storage and render window part - if (m_Controls) + mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image *>(m_ReferenceNode->GetData()); + if (referenceImage.IsNull()) { - mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - m_Controls->m_SlicesInterpolator->SetDataStorage(this->GetDataStorage()); - QList<mitk::SliceNavigationController*> controllers; - controllers.push_back(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); - controllers.push_back(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); - controllers.push_back(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); - m_Controls->m_SlicesInterpolator->Initialize(toolManager, controllers); + this->UpdateGUI(); + return; } -} -void QmitkSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/) -{ - m_RenderWindowPart = nullptr; - if (m_Parent) + m_WorkingNode = nodes.first(); + m_ToolManager->SetWorkingData(m_WorkingNode); + if (m_WorkingNode.IsNotNull()) { - m_Parent->setEnabled(false); + if (m_AutoSelectionEnabled) + { + // hide all segmentation nodes to later show only the automatically selected ones + mitk::DataStorage::SetOfObjects::ConstPointer segmentationNodes = + this->GetDataStorage()->GetSubset(m_SegmentationPredicate); + for (mitk::DataStorage::SetOfObjects::const_iterator iter = segmentationNodes->begin(); iter != segmentationNodes->end(); ++iter) + { + (*iter)->SetVisibility(false); + } + } + m_WorkingNode->SetVisibility(true); + this->InitializeRenderWindows(referenceImage->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, false); } -} -void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) -{ - if (m_Controls != nullptr) - { - bool slimView = prefs->GetBool("slim view", false); - m_Controls->m_ManualToolSelectionBox2D->SetShowNames(!slimView); - m_Controls->m_ManualToolSelectionBox3D->SetShowNames(!slimView); - m_Controls->btnNewSegmentation->setToolButtonStyle(slimView - ? Qt::ToolButtonIconOnly - : Qt::ToolButtonTextOnly); - } - - auto autoSelectionEnabled = prefs->GetBool("auto selection", true); - m_Controls->patImageSelector->SetAutoSelectNewNodes(autoSelectionEnabled); - m_Controls->segImageSelector->SetAutoSelectNewNodes(autoSelectionEnabled); - this->ForceDisplayPreferencesUponAllImages(); + this->UpdateGUI(); } void QmitkSegmentationView::CreateNewSegmentation() { - mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0); - if (node.IsNull()) + mitk::DataNode::Pointer referenceNode = m_ToolManager->GetReferenceData(0); + if (referenceNode.IsNull()) { MITK_ERROR << "'Create new segmentation' button should never be clickable unless a reference image is selected."; return; } - mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image *>(node->GetData()); + mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image *>(referenceNode->GetData()); if (referenceImage.IsNull()) { - MITK_ERROR << "Reference data needs to be an image in order to create a new segmentation."; + QMessageBox::information( + m_Parent, "New segmentation", "Please load and select an image before starting some action."); return; } if (referenceImage->GetDimension() <= 1) { - QMessageBox::information(nullptr, tr("Segmentation"), tr("Segmentation is currently not supported for 2D images")); + QMessageBox::information(m_Parent, "New segmentation", "Segmentation is currently not supported for 2D images"); return; } - // ask about the name and organ type of the new segmentation - auto dialog = new QmitkNewSegmentationDialog(m_Parent); // needs a QWidget as parent, "this" is not QWidget - QStringList organColors = mitk::OrganNamesHandling::GetDefaultOrganColorString(); - dialog->SetSuggestionList(organColors); - - int dialogReturnValue = dialog->exec(); - if (dialogReturnValue == QDialog::Rejected) - { - // user clicked Cancel or pressed Esc or something similar - return; - } + m_ToolManager->ActivateTool(-1); const auto currentTimePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); unsigned int imageTimeStep = 0; if (referenceImage->GetTimeGeometry()->IsValidTimePoint(currentTimePoint)) { imageTimeStep = referenceImage->GetTimeGeometry()->TimePointToTimeStep(currentTimePoint); } auto segTemplateImage = referenceImage; if (referenceImage->GetDimension() > 3) { auto result = QMessageBox::question(m_Parent, tr("Create a static or dynamic segmentation?"), - tr("The patient image has multiple time steps.\n\nDo you want to create a static " + tr("The selected image has multiple time steps.\n\nDo you want to create a static " "segmentation that is identical for all time steps or do you want to create a " "dynamic segmentation to segment individual time steps?"), - tr("Create static segmentation"), - tr("Create dynamic segmentation"), + tr("Create static segmentation"), tr("Create dynamic segmentation"), QString(), 0, 0); if (result == 0) { auto selector = mitk::ImageTimeSelector::New(); selector->SetInput(referenceImage); selector->SetTimeNr(0); selector->Update(); const auto refTimeGeometry = referenceImage->GetTimeGeometry(); auto newTimeGeometry = mitk::ProportionalTimeGeometry::New(); newTimeGeometry->SetFirstTimePoint(refTimeGeometry->GetMinimumTimePoint()); newTimeGeometry->SetStepDuration(refTimeGeometry->GetMaximumTimePoint() - refTimeGeometry->GetMinimumTimePoint()); mitk::Image::Pointer newImage = selector->GetOutput(); newTimeGeometry->SetTimeStepGeometry(referenceImage->GetGeometry(imageTimeStep), 0); newImage->SetTimeGeometry(newTimeGeometry); segTemplateImage = newImage; } } - // create a new image of the same dimensions and smallest possible pixel type - auto toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - auto firstTool = toolManager->GetToolById(0); - if (nullptr == firstTool) + QString newName = QString::fromStdString(referenceNode->GetName()); + newName.append("-labels"); + + // ask about the name and organ type of the new segmentation + auto dialog = new QmitkNewSegmentationDialog(m_Parent); + QStringList organColors = mitk::OrganNamesHandling::GetDefaultOrganColorString(); + dialog->SetSuggestionList(organColors); + dialog->SetSegmentationName(newName); + + int dialogReturnValue = dialog->exec(); + if (dialogReturnValue == QDialog::Rejected) { return; } std::string newNodeName = dialog->GetSegmentationName().toStdString(); if (newNodeName.empty()) { - newNodeName = "no_name"; + newNodeName = "Unnamed"; + } + + // create a new image of the same dimensions and smallest possible pixel type + auto firstTool = m_ToolManager->GetToolById(0); + if (nullptr == firstTool) + { + return; } mitk::DataNode::Pointer emptySegmentation = nullptr; try { emptySegmentation = firstTool->CreateEmptySegmentationNode(segTemplateImage, newNodeName, dialog->GetColor()); } catch (const std::bad_alloc &) { - QMessageBox::warning(nullptr, tr("Create new segmentation"), tr("Could not allocate memory for new segmentation")); + QMessageBox::warning(m_Parent, tr("New segmentation"), tr("Could not allocate memory for new segmentation")); } if (nullptr == emptySegmentation) { return; // could have been aborted by user } // initialize "showVolume"-property to false to prevent recalculating the volume while working on the segmentation emptySegmentation->SetProperty("showVolume", mitk::BoolProperty::New(false)); mitk::OrganNamesHandling::UpdateOrganList(organColors, dialog->GetSegmentationName(), dialog->GetColor()); // escape ';' here (replace by '\;') QString stringForStorage = organColors.replaceInStrings(";", "\\;").join(";"); MITK_DEBUG << "Will store: " << stringForStorage; this->GetPreferences()->Put("Organ-Color-List", stringForStorage); this->GetPreferences()->Flush(); - this->GetDataStorage()->Add(emptySegmentation, node); + this->GetDataStorage()->Add(emptySegmentation, referenceNode); - if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)) + if (m_ToolManager->GetWorkingData(0)) { - mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)->SetSelected(false); + m_ToolManager->GetWorkingData(0)->SetSelected(false); } emptySegmentation->SetSelected(true); m_Controls->segImageSelector->SetCurrentSelectedNode(emptySegmentation); this->InitializeRenderWindows(referenceImage->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, false); } -void QmitkSegmentationView::OnVisiblePropertyChanged() +void QmitkSegmentationView::OnManualTool2DSelected(int id) { - this->CheckRenderingState(); -} + this->ResetMouseCursor(); + mitk::StatusBar::GetInstance()->DisplayText(""); -void QmitkSegmentationView::NodeAdded(const mitk::DataNode *node) -{ - if (!m_IsASegmentationImagePredicate->CheckNode(node)) + if (id >= 0) { - return; - } - - itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command = itk::SimpleMemberCommand<QmitkSegmentationView>::New(); - command->SetCallbackFunction(this, &QmitkSegmentationView::OnVisiblePropertyChanged); - m_WorkingDataObserverTags.insert(std::pair<mitk::DataNode*, unsigned long>(const_cast<mitk::DataNode*>(node), node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command))); + std::string text = "Active Tool: \""; + text += m_ToolManager->GetToolById(id)->GetName(); + text += "\""; + mitk::StatusBar::GetInstance()->DisplayText(text.c_str()); - ApplyDisplayOptions(const_cast<mitk::DataNode*>(node)); + us::ModuleResource resource = m_ToolManager->GetToolById(id)->GetCursorIconResource(); + this->SetMouseCursor(resource, 0, 0); + } } -void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node) +void QmitkSegmentationView::OnShowMarkerNodes(bool state) { - if (m_IsASegmentationImagePredicate->CheckNode(node)) - { - //First of all remove all possible contour markers of the segmentation - mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations(node, mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true))); + mitk::SegTool2D::Pointer manualSegmentationTool; - ctkPluginContext* context = mitk::PluginActivator::getContext(); - ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>(); - mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef); - - for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it) - { - std::string nodeName = node->GetName(); - unsigned int t = nodeName.find_last_of(" "); - unsigned int id = atof(nodeName.substr(t + 1).c_str()) - 1; - - service->RemovePlanePosition(id); - - this->GetDataStorage()->Remove(it->Value()); - } + unsigned int numberOfExistingTools = m_ToolManager->GetTools().size(); - context->ungetService(ppmRef); - service = nullptr; + for (unsigned int i = 0; i < numberOfExistingTools; i++) + { + manualSegmentationTool = dynamic_cast<mitk::SegTool2D*>(m_ToolManager->GetToolById(i)); - if ((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) && m_Controls->patImageSelector->GetSelectedNode().IsNotNull()) + if (manualSegmentationTool) { - this->SetToolManagerSelection(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0), nullptr); - this->UpdateWarningLabel(tr("Select or create a segmentation")); + if (state == true) + { + manualSegmentationTool->SetShowMarkerNodes(true); + } + else + { + manualSegmentationTool->SetShowMarkerNodes(false); + } } - - mitk::Image* image = dynamic_cast<mitk::Image*>(node->GetData()); - mitk::SurfaceInterpolationController::GetInstance()->RemoveInterpolationSession(image); - } - - mitk::DataNode* tempNode = const_cast<mitk::DataNode*>(node); - //Remove observer if one was registered - auto finding = m_WorkingDataObserverTags.find(tempNode); - if (finding != m_WorkingDataObserverTags.end()) - { - node->GetProperty("visible")->RemoveObserver(m_WorkingDataObserverTags[tempNode]); - m_WorkingDataObserverTags.erase(tempNode); } } -void QmitkSegmentationView::OnPatientSelectionChanged(QList<mitk::DataNode::Pointer> nodes) +/**********************************************************************/ +/* private */ +/**********************************************************************/ +void QmitkSegmentationView::CreateQtPartControl(QWidget* parent) { - if(! nodes.empty()) - { - this->UpdateWarningLabel(""); - auto node = nodes.first(); + m_Parent = parent; - auto segPredicate = mitk::NodePredicateAnd::New(m_IsASegmentationImagePredicate.GetPointer(), mitk::NodePredicateSubGeometry::New(node->GetData()->GetGeometry())); + m_Controls = new Ui::QmitkSegmentationControls; + m_Controls->setupUi(parent); - m_Controls->segImageSelector->SetNodePredicate(segPredicate); + m_Controls->patImageSelector->SetDataStorage(GetDataStorage()); + m_Controls->patImageSelector->SetNodePredicate(m_ReferencePredicate); + m_Controls->patImageSelector->SetInvalidInfo("Select an image"); + m_Controls->patImageSelector->SetPopUpTitel("Select an image"); + m_Controls->patImageSelector->SetPopUpHint("Select an image that should be used to define the geometry and bounds of the segmentation."); - mitk::DataNode* segNode = m_Controls->segImageSelector->GetSelectedNode(); - this->SetToolManagerSelection(node, segNode); - if (segNode) - { - //Doing this we can assure that the segmentation is always visible if the segmentation and the patient image are - //loaded separately - int layer(10); - node->GetIntProperty("layer", layer); - layer++; - segNode->SetProperty("layer", mitk::IntProperty::New(layer)); - this->CheckRenderingState(); - } - else - { - this->SetToolSelectionBoxesEnabled( false ); - this->UpdateWarningLabel(tr("Select or create a segmentation")); - } - } - else - { - m_Controls->segImageSelector->SetNodePredicate(m_IsASegmentationImagePredicate); - this->UpdateWarningLabel(tr("Please select an image!")); - this->SetToolSelectionBoxesEnabled( false ); - } -} + m_Controls->segImageSelector->SetDataStorage(GetDataStorage()); + m_Controls->segImageSelector->SetNodePredicate(m_SegmentationPredicate); + m_Controls->segImageSelector->SetInvalidInfo("Select a segmentation"); + m_Controls->segImageSelector->SetPopUpTitel("Select a segmentation"); + m_Controls->segImageSelector->SetPopUpHint("Select a segmentation that should be modified. Only segmentation with the same geometry and within the bounds of the reference image are selected."); -void QmitkSegmentationView::OnSegmentationSelectionChanged(QList<mitk::DataNode::Pointer> nodes) -{ - if (nodes.empty()) - { - this->UpdateWarningLabel(tr("Select or create a segmentation")); - this->SetToolSelectionBoxesEnabled( false ); - return; - } + connect(m_Controls->patImageSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, + this, &QmitkSegmentationView::OnReferenceSelectionChanged); + connect(m_Controls->segImageSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, + this, &QmitkSegmentationView::OnSegmentationSelectionChanged); - auto refNode = m_Controls->patImageSelector->GetSelectedNode(); - auto segNode = nodes.front(); + m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); + m_ToolManager->SetDataStorage(*(this->GetDataStorage())); + m_ToolManager->InitializeTools(); - if (!refNode) + QString segTools2D = tr("Add Subtract Fill Erase Paint Wipe 'Region Growing' 'Live Wire' '2D Fast Marching'"); + QString segTools3D = tr("Threshold 'UL Threshold' Otsu 'Fast Marching 3D' 'Region Growing 3D' Watershed Picking"); +#ifdef __linux__ + segTools3D.append(" nnUNet"); // plugin not enabled for MacOS / Windows +#endif + std::regex extSegTool2DRegEx("SegTool2D$"); + std::regex extSegTool3DRegEx("SegTool3D$"); + + auto tools = m_ToolManager->GetTools(); + for (const auto &tool : tools) { - this->UpdateWarningLabel(tr("Please select the matching patient image!")); - this->SetToolSelectionBoxesEnabled(false); - this->SetToolManagerSelection(nullptr, segNode); - return; + if (std::regex_search(tool->GetNameOfClass(), extSegTool2DRegEx)) + { + segTools2D.append(QString(" '%1'").arg(tool->GetName())); + } + else if (std::regex_search(tool->GetNameOfClass(), extSegTool3DRegEx)) + { + segTools3D.append(QString(" '%1'").arg(tool->GetName())); + } } - this->CheckRenderingState(); - if ( m_Controls->lblSegmentationWarnings->isVisible()) // "this->CheckRenderingState()" caused a warning. we do not need to go any further - return; + // all part of open source MITK + m_Controls->m_ManualToolSelectionBox2D->SetToolManager(*m_ToolManager); + m_Controls->m_ManualToolSelectionBox2D->SetGenerateAccelerators(true); + m_Controls->m_ManualToolSelectionBox2D->SetToolGUIArea(m_Controls->m_ManualToolGUIContainer2D); + m_Controls->m_ManualToolSelectionBox2D->SetDisplayedToolGroups(segTools2D.toStdString()); + m_Controls->m_ManualToolSelectionBox2D->SetLayoutColumns(3); + m_Controls->m_ManualToolSelectionBox2D->SetEnabledMode( + QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); + connect(m_Controls->m_ManualToolSelectionBox2D, &QmitkToolSelectionBox::ToolSelected, + this, &QmitkSegmentationView::OnManualTool2DSelected); - this->SetToolManagerSelection(refNode, segNode); + //setup 3D Tools + m_Controls->m_ManualToolSelectionBox3D->SetToolManager(*m_ToolManager); + m_Controls->m_ManualToolSelectionBox3D->SetGenerateAccelerators(true); + m_Controls->m_ManualToolSelectionBox3D->SetToolGUIArea(m_Controls->m_ManualToolGUIContainer3D); + m_Controls->m_ManualToolSelectionBox3D->SetDisplayedToolGroups(segTools3D.toStdString()); + m_Controls->m_ManualToolSelectionBox3D->SetLayoutColumns(3); + m_Controls->m_ManualToolSelectionBox3D->SetEnabledMode( + QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); - if (segNode) - { - //Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are - //loaded separately - int layer(10); - refNode->GetIntProperty("layer", layer); - layer++; - segNode->SetProperty("layer", mitk::IntProperty::New(layer)); - } - else - { - this->SetToolSelectionBoxesEnabled(false); - this->UpdateWarningLabel(tr("Select or create a segmentation")); - } + // create signal/slot connections + connect(m_Controls->btnNewSegmentation, &QToolButton::clicked, this, &QmitkSegmentationView::CreateNewSegmentation); + connect(m_Controls->m_SlicesInterpolator, &QmitkSlicesInterpolator::SignalShowMarkerNodes, this, &QmitkSegmentationView::OnShowMarkerNodes); - mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); - if (!renderWindowPart || !segNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer())) + // set callback function for already existing segmentation nodes + mitk::DataStorage::SetOfObjects::ConstPointer allSegmentations = GetDataStorage()->GetSubset(m_SegmentationPredicate); + for (mitk::DataStorage::SetOfObjects::const_iterator iter = allSegmentations->begin(); iter != allSegmentations->end(); ++iter) { - this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!")); - this->SetToolSelectionBoxesEnabled( false ); + mitk::DataNode* node = *iter; + auto command = itk::SimpleMemberCommand<QmitkSegmentationView>::New(); + command->SetCallbackFunction(this, &QmitkSegmentationView::ValidateSelectionInput); + m_WorkingDataObserverTags.insert(std::pair<mitk::DataNode *, unsigned long>( + node, node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command))); } -} - -void QmitkSegmentationView::OnShowMarkerNodes (bool state) -{ - mitk::SegTool2D::Pointer manualSegmentationTool; - unsigned int numberOfExistingTools = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetTools().size(); + auto command = itk::SimpleMemberCommand<QmitkSegmentationView>::New(); + command->SetCallbackFunction(this, &QmitkSegmentationView::ValidateSelectionInput); + m_RenderingManagerObserverTag = + mitk::RenderingManager::GetInstance()->AddObserver(mitk::RenderingManagerViewsInitializedEvent(), command); - for(unsigned int i = 0; i < numberOfExistingTools; i++) + m_RenderWindowPart = this->GetRenderWindowPart(); + if (nullptr != m_RenderWindowPart) { - manualSegmentationTool = dynamic_cast<mitk::SegTool2D*>(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetToolById(i)); - - if (manualSegmentationTool) - { - if(state == true) - { - manualSegmentationTool->SetShowMarkerNodes( true ); - } - else - { - manualSegmentationTool->SetShowMarkerNodes( false ); - } - } + this->RenderWindowPartActivated(m_RenderWindowPart); } + + // Make sure the GUI notices if appropriate data is already present on creation. + // Should be done last, if everything else is configured because it triggers the autoselection of data. + m_Controls->patImageSelector->SetAutoSelectNewNodes(true); + m_Controls->segImageSelector->SetAutoSelectNewNodes(true); + + this->UpdateGUI(); } -void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node) +void QmitkSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { - QmitkRenderWindow* selectedRenderWindow = nullptr; - auto* renderWindowPart = this->GetRenderWindowPart(mitk::WorkbenchUtil::OPEN); - auto* axialRenderWindow = renderWindowPart->GetQmitkRenderWindow("axial"); - auto* sagittalRenderWindow = renderWindowPart->GetQmitkRenderWindow("sagittal"); - auto* coronalRenderWindow = renderWindowPart->GetQmitkRenderWindow("coronal"); - auto* _3DRenderWindow = renderWindowPart->GetQmitkRenderWindow("3d"); - bool PlanarFigureInitializedWindow = false; - - // find initialized renderwindow - if (node->GetBoolProperty("PlanarFigureInitializedWindow", - PlanarFigureInitializedWindow, axialRenderWindow->GetRenderer())) - { - selectedRenderWindow = axialRenderWindow; - } - if (!selectedRenderWindow && node->GetBoolProperty( - "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, - sagittalRenderWindow->GetRenderer())) - { - selectedRenderWindow = sagittalRenderWindow; - } - if (!selectedRenderWindow && node->GetBoolProperty( - "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, - coronalRenderWindow->GetRenderer())) - { - selectedRenderWindow = coronalRenderWindow; - } - if (!selectedRenderWindow && node->GetBoolProperty( - "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, - _3DRenderWindow->GetRenderer())) - { - selectedRenderWindow = _3DRenderWindow; - } - - // make node visible - if (selectedRenderWindow) - { - std::string nodeName = node->GetName(); - unsigned int t = nodeName.find_last_of(" "); - unsigned int id = atof(nodeName.substr(t+1).c_str())-1; + if (m_RenderWindowPart != renderWindowPart) + { + m_RenderWindowPart = renderWindowPart; + } - { - ctkPluginContext* context = mitk::PluginActivator::getContext(); - ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>(); - mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef); - selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id)); - context->ungetService(ppmRef); - } + if (m_Parent) + { + m_Parent->setEnabled(true); + } - selectedRenderWindow->GetRenderer()->GetCameraController()->Fit(); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } + // tell the interpolation about tool manager, data storage and render window part + if (m_Controls) + { + m_Controls->m_SlicesInterpolator->SetDataStorage(this->GetDataStorage()); + QList<mitk::SliceNavigationController*> controllers; + controllers.push_back(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); + controllers.push_back(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); + controllers.push_back(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); + m_Controls->m_SlicesInterpolator->Initialize(m_ToolManager, controllers); + } } -void QmitkSegmentationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer> &nodes) +void QmitkSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/) { - if (nodes.size() != 0) + m_RenderWindowPart = nullptr; + if (m_Parent) { - std::string markerName = "Position"; - unsigned int numberOfNodes = nodes.size(); - std::string nodeName = nodes.at(0)->GetName(); - if ((numberOfNodes == 1) && (nodeName.find(markerName) == 0)) - { - this->OnContourMarkerSelected(nodes.at(0)); - return; - } + m_Parent->setEnabled(false); } } -void QmitkSegmentationView::OnTabWidgetChanged(int id) +void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { - //always disable tools on tab changed - mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1); + if (m_Controls != nullptr) + { + bool slimView = prefs->GetBool("slim view", false); + m_Controls->m_ManualToolSelectionBox2D->SetShowNames(!slimView); + m_Controls->m_ManualToolSelectionBox3D->SetShowNames(!slimView); + } - //2D Tab ID = 0 - //3D Tab ID = 1 - if (id == 0) - { - //Hide 3D selection box, show 2D selection box - m_Controls->m_ManualToolSelectionBox3D->hide(); - m_Controls->m_ManualToolSelectionBox2D->show(); - //Deactivate possible active tool + m_AutoSelectionEnabled = prefs->GetBool("auto selection", false); - //TODO Remove possible visible interpolations -> Maybe changes in SlicesInterpolator - } - else - { - //Hide 3D selection box, show 2D selection box - m_Controls->m_ManualToolSelectionBox2D->hide(); - m_Controls->m_ManualToolSelectionBox3D->show(); - //Deactivate possible active tool - } + this->ApplyDisplayOptions(); } -void QmitkSegmentationView::SetToolManagerSelection(mitk::DataNode* referenceData, mitk::DataNode* workingData) +void QmitkSegmentationView::NodeAdded(const mitk::DataNode* node) { - // called as a result of new BlueBerry selections - // tells the ToolManager for manual segmentation about new selections - // updates GUI information about what the user should select - mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - toolManager->SetReferenceData(const_cast<mitk::DataNode*>(referenceData)); - toolManager->SetWorkingData(const_cast<mitk::DataNode*>(workingData)); - - m_Controls->btnNewSegmentation->setEnabled(referenceData != nullptr); + if (!m_SegmentationPredicate->CheckNode(node)) + { + return; + } + + auto command = itk::SimpleMemberCommand<QmitkSegmentationView>::New(); + command->SetCallbackFunction(this, &QmitkSegmentationView::ValidateSelectionInput); + m_WorkingDataObserverTags.insert(std::pair<mitk::DataNode *, unsigned long>( + const_cast<mitk::DataNode *>(node), node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command))); + + this->ApplyDisplayOptions(const_cast<mitk::DataNode*>(node)); } -void QmitkSegmentationView::ForceDisplayPreferencesUponAllImages() +void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node) { - if (!m_Parent) - { - return; - } + if (m_SegmentationPredicate->CheckNode(node)) + { + // remove all possible contour markers of the segmentation + mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations( + node, mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true))); - // check all images and segmentations in DataStorage: - // (items in brackets are implicitly done by previous steps) - // 1. - // if a reference image is selected, - // show the reference image - // and hide all other images (orignal and segmentation), - // (and hide all segmentations of the other original images) - // and show all the reference's segmentations - // if no reference image is selected, do do nothing - // - // 2. - // if a segmentation is selected, - // show it - // (and hide all all its siblings (childs of the same parent, incl, nullptr parent)) - // if no segmentation is selected, do nothing - - if (!m_Controls) - { - return; // might happen on initialization (preferences loaded) - } + ctkPluginContext* context = mitk::PluginActivator::getContext(); + ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>(); + mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef); - mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - mitk::DataNode::Pointer referenceData = toolManager->GetReferenceData(0); - mitk::DataNode::Pointer workingData = toolManager->GetWorkingData(0); + for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it) + { + std::string nodeName = node->GetName(); + unsigned int t = nodeName.find_last_of(" "); + unsigned int id = atof(nodeName.substr(t + 1).c_str()) - 1; - // 1. - if (referenceData.IsNotNull()) - { - // iterate all images - mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDataStorage()->GetSubset(m_IsASegmentationImagePredicate); + service->RemovePlanePosition(id); - for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) + this->GetDataStorage()->Remove(it->Value()); + } - { - mitk::DataNode* node = *iter; - // apply display preferences - ApplyDisplayOptions(node); + context->ungetService(ppmRef); + service = nullptr; - // set visibility - node->SetVisibility(node == referenceData); - } - } + mitk::Image* image = dynamic_cast<mitk::Image*>(node->GetData()); + mitk::SurfaceInterpolationController::GetInstance()->RemoveInterpolationSession(image); + } - // 2. - if (workingData.IsNotNull()) - workingData->SetVisibility(true); + mitk::DataNode* tempNode = const_cast<mitk::DataNode*>(node); + //Remove observer if one was registered + auto finding = m_WorkingDataObserverTags.find(tempNode); + if (finding != m_WorkingDataObserverTags.end()) + { + node->GetProperty("visible")->RemoveObserver(m_WorkingDataObserverTags[tempNode]); + m_WorkingDataObserverTags.erase(tempNode); + } +} + +void QmitkSegmentationView::ApplyDisplayOptions() +{ + if (!m_Parent) + { + return; + } - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + if (!m_Controls) + { + return; // might happen on initialization (preferences loaded) + } + + mitk::DataNode::Pointer workingData = m_ToolManager->GetWorkingData(0); + mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDataStorage()->GetSubset(m_SegmentationPredicate); + for (mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) + { + this->ApplyDisplayOptions(*iter); + } + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node) { - if (!node) + if (nullptr == node) { return; } - mitk::BoolProperty::Pointer drawOutline = mitk::BoolProperty::New(GetPreferences()->GetBool("draw outline", true)); - mitk::LabelSetImage* labelSetImage = dynamic_cast<mitk::LabelSetImage*>(node->GetData()); + auto drawOutline = mitk::BoolProperty::New(GetPreferences()->GetBool("draw outline", true)); + auto labelSetImage = dynamic_cast<mitk::LabelSetImage*>(node->GetData()); if (nullptr != labelSetImage) { // node is actually a multi label segmentation, // but its outline property can be set in the 'single label' segmentation preference page as well node->SetProperty("labelset.contour.active", drawOutline); - //node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f)); // force render window update to show outline node->GetData()->Modified(); } else { // node is a 'single label' segmentation bool isBinary = false; node->GetBoolProperty("binary", isBinary); if (isBinary) { node->SetProperty("outline binary", drawOutline); node->SetProperty("outline width", mitk::FloatProperty::New(2.0)); - //node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f)); // force render window update to show outline node->GetData()->Modified(); } } } -void QmitkSegmentationView::CheckRenderingState() +void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode* node) { - mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); - mitk::DataNode* workingNode = m_Controls->segImageSelector->GetSelectedNode(); - - if (!workingNode) + QmitkRenderWindow* selectedRenderWindow = nullptr; + auto* renderWindowPart = this->GetRenderWindowPart(mitk::WorkbenchUtil::OPEN); + auto* axialRenderWindow = renderWindowPart->GetQmitkRenderWindow("axial"); + auto* sagittalRenderWindow = renderWindowPart->GetQmitkRenderWindow("sagittal"); + auto* coronalRenderWindow = renderWindowPart->GetQmitkRenderWindow("coronal"); + auto* _3DRenderWindow = renderWindowPart->GetQmitkRenderWindow("3d"); + bool PlanarFigureInitializedWindow = false; + + // find initialized renderwindow + if (node->GetBoolProperty("PlanarFigureInitializedWindow", + PlanarFigureInitializedWindow, axialRenderWindow->GetRenderer())) { - this->SetToolSelectionBoxesEnabled(false); - this->UpdateWarningLabel(tr("Select or create a segmentation")); - return; + selectedRenderWindow = axialRenderWindow; + } + if (!selectedRenderWindow && node->GetBoolProperty( + "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, + sagittalRenderWindow->GetRenderer())) + { + selectedRenderWindow = sagittalRenderWindow; + } + if (!selectedRenderWindow && node->GetBoolProperty( + "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, + coronalRenderWindow->GetRenderer())) + { + selectedRenderWindow = coronalRenderWindow; + } + if (!selectedRenderWindow && node->GetBoolProperty( + "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, + _3DRenderWindow->GetRenderer())) + { + selectedRenderWindow = _3DRenderWindow; } - bool selectedNodeIsVisible = renderWindowPart && workingNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()); - if (!selectedNodeIsVisible) + // make node visible + if (selectedRenderWindow) { - this->SetToolSelectionBoxesEnabled(false); - this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!")); - return; + std::string nodeName = node->GetName(); + unsigned int t = nodeName.find_last_of(" "); + unsigned int id = atof(nodeName.substr(t + 1).c_str()) - 1; + + { + ctkPluginContext* context = mitk::PluginActivator::getContext(); + ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>(); + mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef); + selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id)); + context->ungetService(ppmRef); + } + + selectedRenderWindow->GetRenderer()->GetCameraController()->Fit(); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } +} - /* - * Here we check whether the geometry of the selected segmentation image if aligned with the worldgeometry - * At the moment it is not supported to use a geometry different from the selected image for reslicing. - * For further information see Bug 16063 - */ - const mitk::BaseGeometry *workingNodeGeo = workingNode->GetData()->GetGeometry(); - const mitk::BaseGeometry* worldGeo = renderWindowPart->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D(); - if (nullptr != workingNodeGeo && nullptr != worldGeo) +void QmitkSegmentationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer>& nodes) +{ + if (nodes.size() != 0) { - if (mitk::Equal(*workingNodeGeo->GetBoundingBox(), *worldGeo->GetBoundingBox(), mitk::eps, true)) + std::string markerName = "Position"; + unsigned int numberOfNodes = nodes.size(); + std::string nodeName = nodes.at(0)->GetName(); + if ((numberOfNodes == 1) && (nodeName.find(markerName) == 0)) { - this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), workingNode); - this->SetToolSelectionBoxesEnabled(true); - this->UpdateWarningLabel(""); + this->OnContourMarkerSelected(nodes.at(0)); return; } } - - this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), nullptr); - this->SetToolSelectionBoxesEnabled(false); - this->UpdateWarningLabel(tr("Please perform a reinit on the segmentation image!")); } -void QmitkSegmentationView::UpdateWarningLabel(QString text) +void QmitkSegmentationView::ResetMouseCursor() { - if (text.size() == 0) - m_Controls->lblSegmentationWarnings->hide(); - else - m_Controls->lblSegmentationWarnings->show(); - m_Controls->lblSegmentationWarnings->setText("<font color=\"red\">" + text + "</font>"); + if (m_MouseCursorSet) + { + mitk::ApplicationCursor::GetInstance()->PopCursor(); + m_MouseCursorSet = false; + } } -void QmitkSegmentationView::CreateQtPartControl(QWidget* parent) +void QmitkSegmentationView::SetMouseCursor(const us::ModuleResource& resource, int hotspotX, int hotspotY) { - // setup the basic GUI of this view - m_Parent = parent; + // Remove previously set mouse cursor + if (m_MouseCursorSet) + this->ResetMouseCursor(); - m_Controls = new Ui::QmitkSegmentationControls; - m_Controls->setupUi(parent); - - m_Controls->patImageSelector->SetDataStorage(GetDataStorage()); - m_Controls->patImageSelector->SetNodePredicate(m_IsAPatientImagePredicate); - m_Controls->patImageSelector->SetSelectionIsOptional(false); - m_Controls->patImageSelector->SetInvalidInfo("Select an image."); - m_Controls->patImageSelector->SetPopUpTitel("Select an image."); - m_Controls->patImageSelector->SetPopUpHint("Select an image that should be used to define the geometry and bounds of the segmentation."); - - UpdateWarningLabel(tr("Please select an image")); - - if (m_Controls->patImageSelector->GetSelectedNode().IsNotNull()) - { - UpdateWarningLabel(tr("Select or create a new segmentation")); - } - - m_Controls->segImageSelector->SetDataStorage(GetDataStorage()); - m_Controls->segImageSelector->SetNodePredicate(m_IsASegmentationImagePredicate); - m_Controls->segImageSelector->SetSelectionIsOptional(false); - m_Controls->segImageSelector->SetInvalidInfo("Select a segmentation."); - m_Controls->segImageSelector->SetPopUpTitel("Select a segmentation."); - m_Controls->segImageSelector->SetPopUpHint("Select a segmentation that should be modified. Only segmentation with the same geometry and within the bounds of the reference image are selected."); - - if (m_Controls->segImageSelector->GetSelectedNode().IsNotNull()) - { - UpdateWarningLabel(""); - } - - mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - assert(toolManager); - - toolManager->SetDataStorage(*(GetDataStorage())); - toolManager->InitializeTools(); - - QString segTools2D = tr("Add Subtract Paint Wipe 'Region Growing' Fill Erase 'Live Wire' '2D Fast Marching'"); - QString segTools3D = tr("Threshold 'UL Threshold' Otsu 'Fast Marching 3D' 'Region Growing 3D' Watershed Picking"); -#ifdef __linux__ - segTools3D.append(" nnUNet"); // plugin not enabled for MacOS -#endif - - std::regex extSegTool2DRegEx("SegTool2D$"); - std::regex extSegTool3DRegEx("SegTool3D$"); - - auto tools = toolManager->GetTools(); - - for (const auto &tool : tools) - { - if (std::regex_search(tool->GetNameOfClass(), extSegTool2DRegEx)) - { - segTools2D.append(QString(" '%1'").arg(tool->GetName())); - } - else if (std::regex_search(tool->GetNameOfClass(), extSegTool3DRegEx)) - { - segTools3D.append(QString(" '%1'").arg(tool->GetName())); - } - } - - // all part of open source MITK - m_Controls->m_ManualToolSelectionBox2D->setEnabled(true); - m_Controls->m_ManualToolSelectionBox2D->SetGenerateAccelerators(true); - m_Controls->m_ManualToolSelectionBox2D->SetToolGUIArea(m_Controls->m_ManualToolGUIContainer2D); - - m_Controls->m_ManualToolSelectionBox2D->SetDisplayedToolGroups(segTools2D.toStdString()); - m_Controls->m_ManualToolSelectionBox2D->SetLayoutColumns(3); - m_Controls->m_ManualToolSelectionBox2D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); - connect(m_Controls->m_ManualToolSelectionBox2D, &QmitkToolSelectionBox::ToolSelected, this, &QmitkSegmentationView::OnManualTool2DSelected); - - //setup 3D Tools - m_Controls->m_ManualToolSelectionBox3D->setEnabled(true); - m_Controls->m_ManualToolSelectionBox3D->SetGenerateAccelerators(true); - m_Controls->m_ManualToolSelectionBox3D->SetToolGUIArea(m_Controls->m_ManualToolGUIContainer3D); - //specify tools to be added to 3D Tool area - m_Controls->m_ManualToolSelectionBox3D->SetDisplayedToolGroups(segTools3D.toStdString()); - m_Controls->m_ManualToolSelectionBox3D->SetLayoutColumns(3); - m_Controls->m_ManualToolSelectionBox3D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible); + if (resource) + { + us::ModuleResourceStream cursor(resource, std::ios::binary); + mitk::ApplicationCursor::GetInstance()->PushCursor(cursor, hotspotX, hotspotY); + m_MouseCursorSet = true; + } +} - //Hide 3D selection box, show 2D selection box - m_Controls->m_ManualToolSelectionBox3D->hide(); - m_Controls->m_ManualToolSelectionBox2D->show(); +void QmitkSegmentationView::UpdateGUI() +{ + mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0); + bool hasReferenceNode = referenceNode != nullptr; - // update the list of segmentations - toolManager->NewNodeObjectsGenerated += mitk::MessageDelegate1<QmitkSegmentationView, mitk::ToolManager::DataVectorType*>(this, &QmitkSegmentationView::NewNodeObjectsGenerated); + mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); + bool hasWorkingNode = workingNode != nullptr; - // create signal/slot connections - connect(m_Controls->patImageSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkSegmentationView::OnPatientSelectionChanged); - connect(m_Controls->segImageSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkSegmentationView::OnSegmentationSelectionChanged); + m_Controls->btnNewSegmentation->setEnabled(false); + m_Controls->m_SlicesInterpolator->setEnabled(false); - connect(m_Controls->btnNewSegmentation, &QToolButton::clicked, this, &QmitkSegmentationView::CreateNewSegmentation); - connect(m_Controls->tabWidgetSegmentationTools, &QTabWidget::currentChanged, this, &QmitkSegmentationView::OnTabWidgetChanged); - connect(m_Controls->m_SlicesInterpolator, &QmitkSlicesInterpolator::SignalShowMarkerNodes, this, &QmitkSegmentationView::OnShowMarkerNodes); + if (hasReferenceNode) + { + m_Controls->btnNewSegmentation->setEnabled(true); + } - // set callback function for already existing nodes (images & segmentations) - mitk::DataStorage::SetOfObjects::ConstPointer allImages = GetDataStorage()->GetSubset(m_IsOfTypeImagePredicate); - for (mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) - { - mitk::DataNode* node = *iter; - itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command = itk::SimpleMemberCommand<QmitkSegmentationView>::New(); - command->SetCallbackFunction(this, &QmitkSegmentationView::OnVisiblePropertyChanged); - m_WorkingDataObserverTags.insert(std::pair<mitk::DataNode*, unsigned long>(node, node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command))); - } + if (hasWorkingNode && hasReferenceNode) + { + m_Controls->m_SlicesInterpolator->setEnabled(true); - itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command = itk::SimpleMemberCommand<QmitkSegmentationView>::New(); - command->SetCallbackFunction(this, &QmitkSegmentationView::CheckRenderingState); - m_RenderingManagerObserverTag = mitk::RenderingManager::GetInstance()->AddObserver(mitk::RenderingManagerViewsInitializedEvent(), command); + int layer = -1; + referenceNode->GetIntProperty("layer", layer); + workingNode->SetIntProperty("layer", layer + 1); + } - SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), m_Controls->segImageSelector->GetSelectedNode()); + this->ValidateSelectionInput(); +} - m_RenderWindowPart = this->GetRenderWindowPart(); +void QmitkSegmentationView::ValidateSelectionInput() +{ + this->UpdateWarningLabel(""); - if (nullptr != m_RenderWindowPart) - this->RenderWindowPartActivated(m_RenderWindowPart); + // the argument is actually not used + // enable status depends on the tool manager selection + m_Controls->m_ManualToolSelectionBox2D->setEnabled(false); + m_Controls->m_ManualToolSelectionBox3D->setEnabled(false); - //Should be done last, if everything else is configured because it triggers the autoselection of data. - m_Controls->patImageSelector->SetAutoSelectNewNodes(true); - m_Controls->segImageSelector->SetAutoSelectNewNodes(true); -} + mitk::DataNode* referenceNode = m_Controls->patImageSelector->GetSelectedNode(); + mitk::DataNode* workingNode = m_Controls->segImageSelector->GetSelectedNode(); -void QmitkSegmentationView::SetFocus() -{ - m_Controls->btnNewSegmentation->setFocus(); -} + if (nullptr == referenceNode) + { + return; + } -void QmitkSegmentationView::OnManualTool2DSelected(int id) -{ - if (id >= 0) - { - std::string text = "Active Tool: \""; - mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - text += toolManager->GetToolById(id)->GetName(); - text += "\""; - mitk::StatusBar::GetInstance()->DisplayText(text.c_str()); - - us::ModuleResource resource = toolManager->GetToolById(id)->GetCursorIconResource(); - this->SetMouseCursor(resource, 0, 0); - } - else - { - this->ResetMouseCursor(); - mitk::StatusBar::GetInstance()->DisplayText(""); - } -} + if (nullptr == workingNode) + { + return; + } -void QmitkSegmentationView::ResetMouseCursor() -{ - if ( m_MouseCursorSet ) - { - mitk::ApplicationCursor::GetInstance()->PopCursor(); - m_MouseCursorSet = false; - } -} + mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); + auto workingNodeIsVisible = renderWindowPart && + workingNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()); + if (!workingNodeIsVisible) + { + this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!")); + return; + } -void QmitkSegmentationView::SetMouseCursor( const us::ModuleResource& resource, int hotspotX, int hotspotY ) -{ - // Remove previously set mouse cursor - if (m_MouseCursorSet) - this->ResetMouseCursor(); + /* + * Here we check whether the geometry of the selected segmentation image is aligned with the worldgeometry. + * At the moment it is not supported to use a geometry different from the selected image for reslicing. + * For further information see Bug 16063 + */ + const mitk::BaseGeometry *workingNodeGeo = workingNode->GetData()->GetGeometry(); + const mitk::BaseGeometry *worldGeo = + renderWindowPart->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D(); + if (nullptr != workingNodeGeo && nullptr != worldGeo) + { + if (mitk::Equal(*workingNodeGeo->GetBoundingBox(), *worldGeo->GetBoundingBox(), mitk::eps, true)) + { + m_ToolManager->SetReferenceData(referenceNode); + m_ToolManager->SetWorkingData(workingNode); + m_Controls->m_ManualToolSelectionBox2D->setEnabled(true); + m_Controls->m_ManualToolSelectionBox3D->setEnabled(true); + return; + } + } - if (resource) - { - us::ModuleResourceStream cursor(resource, std::ios::binary); - mitk::ApplicationCursor::GetInstance()->PushCursor(cursor, hotspotX, hotspotY); - m_MouseCursorSet = true; - } + m_ToolManager->SetReferenceData(referenceNode); + m_ToolManager->SetWorkingData(nullptr); + this->UpdateWarningLabel(tr("Please perform a reinit on the segmentation image!")); } -void QmitkSegmentationView::SetToolSelectionBoxesEnabled(bool status) +void QmitkSegmentationView::UpdateWarningLabel(QString text) { - if (status) + if (text.size() == 0) { - m_Controls->m_ManualToolSelectionBox2D->RecreateButtons(); - m_Controls->m_ManualToolSelectionBox3D->RecreateButtons(); + m_Controls->lblSegmentationWarnings->hide(); } - - m_Controls->m_ManualToolSelectionBox2D->setEnabled(status); - m_Controls->m_ManualToolSelectionBox3D->setEnabled(status); - m_Controls->m_SlicesInterpolator->setEnabled(status); + else + { + m_Controls->lblSegmentationWarnings->show(); + } + m_Controls->lblSegmentationWarnings->setText("<font color=\"red\">" + text + "</font>"); } diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.h index 3ea9d5b5dc..7b3187260b 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.h +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.h @@ -1,133 +1,122 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKSEGMENTATIONVIEW_H #define QMITKSEGMENTATIONVIEW_H +#include "ui_QmitkSegmentationControls.h" + #include <QmitkAbstractView.h> -#include <mitkILifecycleAwarePart.h> #include <mitkIRenderWindowPartListener.h> #include <berryIBerryPreferences.h> -#include "ui_QmitkSegmentationControls.h" - -class QmitkRenderWindow; - /** -* @brief +* @brief The segmentation view provides a set of tool to use different segmentation algorithms. +* It provides two selection widgets to load an image node and a segmentation node +* on which to perform the segmentation. Creating new segmentation nodes is also possible. +* The available segmentation tools are grouped into "2D"- and "3D"-tools. * +* Most segmentation tools / algorithms need some kind of user interaction, where the +* user is asked to draw something in the image display or set some seed points / start values. +* The tools also often provide additional propeties so that a user can modify the +* algorithm's behavior. * +* Additionally the view provides an option to create "2D"- and "3D"-interpolations between +* neighboring segmentation masks on unsegmented slices. */ class QmitkSegmentationView : public QmitkAbstractView, public mitk::IRenderWindowPartListener { Q_OBJECT public: - QmitkSegmentationView(); + static const std::string VIEW_ID; + QmitkSegmentationView(); ~QmitkSegmentationView() override; - typedef std::map<mitk::DataNode*, unsigned long> NodeTagMapType; - - void NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType*); - - void SetFocus() override; - - void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; - - void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override; - - // BlueBerry's notification about preference changes (e.g. from a dialog) - void OnPreferencesChanged(const berry::IBerryPreferences* prefs) override; - - // observer to mitk::RenderingManager's RenderingManagerViewsInitializedEvent event - void CheckRenderingState(); +private Q_SLOTS: - static const std::string VIEW_ID; - - protected slots: + // reaction to the selection of a new reference image in the selection widget + void OnReferenceSelectionChanged(QList<mitk::DataNode::Pointer> nodes); - void OnPatientSelectionChanged(QList<mitk::DataNode::Pointer> nodes); + // reaction to the selection of a new segmentation image in the selection widget void OnSegmentationSelectionChanged(QList<mitk::DataNode::Pointer> nodes); // reaction to the button "New segmentation" void CreateNewSegmentation(); void OnManualTool2DSelected(int id); - void OnVisiblePropertyChanged(); - void OnShowMarkerNodes(bool); - void OnTabWidgetChanged(int); +private: -protected: - - // a type for handling lists of DataNodes - typedef std::vector<mitk::DataNode*> NodeList; - - // GUI setup void CreateQtPartControl(QWidget* parent) override; - // propagate BlueBerry selection to ToolManager for manual segmentation - void SetToolManagerSelection(mitk::DataNode* referenceData, mitk::DataNode* workingData); + void SetFocus() override {} + + void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; + void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override; - // make sure all images/segmentations look as selected by the users in this view's preferences - void ForceDisplayPreferencesUponAllImages(); + void OnPreferencesChanged(const berry::IBerryPreferences* prefs) override; - // decorates a DataNode according to the user preference settings - void ApplyDisplayOptions(mitk::DataNode* node); + void NodeAdded(const mitk::DataNode *node) override; - void ResetMouseCursor(); + void NodeRemoved(const mitk::DataNode* node) override; - void SetMouseCursor(const us::ModuleResource&, int hotspotX, int hotspotY); + // make sure all images / segmentations look according to the user preference settings + void ApplyDisplayOptions(); - void SetToolSelectionBoxesEnabled(bool); + // decorates a DataNode according to the user preference settings + void ApplyDisplayOptions(mitk::DataNode* node); // If a contourmarker is selected, the plane in the related widget will be reoriented according to the marker`s geometry void OnContourMarkerSelected(const mitk::DataNode* node); void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList<mitk::DataNode::Pointer> &nodes) override; - void NodeRemoved(const mitk::DataNode* node) override; + void ResetMouseCursor(); - void NodeAdded(const mitk::DataNode *node) override; + void SetMouseCursor(const us::ModuleResource&, int hotspotX, int hotspotY); - void UpdateWarningLabel(QString text/*, bool overwriteExistingText = true*/); + void UpdateGUI(); + + void ValidateSelectionInput(); + + void UpdateWarningLabel(QString text); - // the Qt parent of our GUI (NOT of this object) QWidget* m_Parent; - // our GUI Ui::QmitkSegmentationControls* m_Controls; mitk::IRenderWindowPart* m_RenderWindowPart; - unsigned long m_VisibilityChangedObserverTag; - - bool m_MouseCursorSet; + mitk::ToolManager* m_ToolManager; - bool m_DataSelectionChanged; + mitk::DataNode::Pointer m_ReferenceNode; + mitk::DataNode::Pointer m_WorkingNode; + typedef std::map<mitk::DataNode*, unsigned long> NodeTagMapType; NodeTagMapType m_WorkingDataObserverTags; - unsigned int m_RenderingManagerObserverTag; - mitk::NodePredicateNot::Pointer m_IsNotAHelperObject; - mitk::NodePredicateAnd::Pointer m_IsOfTypeImagePredicate; - mitk::NodePredicateOr::Pointer m_IsASegmentationImagePredicate; - mitk::NodePredicateAnd::Pointer m_IsAPatientImagePredicate; + mitk::NodePredicateAnd::Pointer m_ReferencePredicate; + mitk::NodePredicateAnd::Pointer m_SegmentationPredicate; + + bool m_AutoSelectionEnabled; + bool m_MouseCursorSet; + }; #endif // QMITKSEGMENTATIONVIEW_H diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp index 0ee6636348..86a5468a8c 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp @@ -1,356 +1,382 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkImageMaskingWidget.h" #include "mitkImage.h" #include "../../Common/QmitkDataSelectionWidget.h" #include <mitkException.h> #include <mitkExceptionMacro.h> #include <mitkImageStatisticsHolder.h> #include <mitkMaskImageFilter.h> #include <mitkProgressBar.h> #include <mitkSliceNavigationController.h> #include <mitkSurfaceToImageFilter.h> #include <mitkImageAccessByItk.h> +#include <mitkNodePredicateAnd.h> +#include <mitkNodePredicateDimension.h> +#include <mitkNodePredicateGeometry.h> +#include <mitkNodePredicateNot.h> #include <QMessageBox> #include <limits> namespace { bool IsSurface(const mitk::DataNode* dataNode) { if (nullptr != dataNode) { if (nullptr != dynamic_cast<const mitk::Surface*>(dataNode->GetData())) return true; } return false; } } static const char* const HelpText = "Select an image and a segmentation or surface"; QmitkImageMaskingWidget::QmitkImageMaskingWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent) : QmitkSegmentationUtilityWidget(timeNavigationController, parent) { m_Controls.setupUi(this); m_Controls.dataSelectionWidget->AddDataSelection(QmitkDataSelectionWidget::ImagePredicate); m_Controls.dataSelectionWidget->AddDataSelection(QmitkDataSelectionWidget::SegmentationOrSurfacePredicate); m_Controls.dataSelectionWidget->SetHelpText(HelpText); + // T28795: Disable 2-d reference images since they do not work yet (segmentations are at least 3-d images with a single slice) + m_Controls.dataSelectionWidget->SetPredicate(0, mitk::NodePredicateAnd::New( + mitk::NodePredicateNot::New(mitk::NodePredicateDimension::New(2)), + m_Controls.dataSelectionWidget->GetPredicate(0))); + this->EnableButtons(false); connect(m_Controls.btnMaskImage, SIGNAL(clicked()), this, SLOT(OnMaskImagePressed())); connect(m_Controls.rbnCustom, SIGNAL(toggled(bool)), this, SLOT(OnCustomValueButtonToggled(bool))); connect(m_Controls.dataSelectionWidget, SIGNAL(SelectionChanged(unsigned int, const mitk::DataNode*)), this, SLOT(OnSelectionChanged(unsigned int, const mitk::DataNode*))); if( m_Controls.dataSelectionWidget->GetSelection(0).IsNotNull() && m_Controls.dataSelectionWidget->GetSelection(1).IsNotNull() ) { this->OnSelectionChanged(0, m_Controls.dataSelectionWidget->GetSelection(0)); } } QmitkImageMaskingWidget::~QmitkImageMaskingWidget() { } -void QmitkImageMaskingWidget::OnSelectionChanged(unsigned int index, const mitk::DataNode* selection) +void QmitkImageMaskingWidget::OnSelectionChanged(unsigned int index, const mitk::DataNode *selection) { - QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; - mitk::DataNode::Pointer node0 = dataSelectionWidget->GetSelection(0); - mitk::DataNode::Pointer node1 = dataSelectionWidget->GetSelection(1); + auto *dataSelectionWidget = m_Controls.dataSelectionWidget; + auto node0 = dataSelectionWidget->GetSelection(0); + + if (index == 0) + { + dataSelectionWidget->SetPredicate(1, QmitkDataSelectionWidget::SegmentationOrSurfacePredicate); + + if (node0.IsNotNull()) + { + dataSelectionWidget->SetPredicate(1, mitk::NodePredicateAnd::New( + mitk::NodePredicateGeometry::New(node0->GetData()->GetGeometry()), + dataSelectionWidget->GetPredicate(1))); + } + } - if (node0.IsNull() || node1.IsNull() ) + auto node1 = dataSelectionWidget->GetSelection(1); + + if (node0.IsNull() || node1.IsNull()) { dataSelectionWidget->SetHelpText(HelpText); this->EnableButtons(false); } else { this->SelectionControl(index, selection); } } void QmitkImageMaskingWidget::SelectionControl(unsigned int index, const mitk::DataNode* selection) { QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(index); //if Image-Masking is enabled, check if image-dimension of reference and binary image is identical if( !IsSurface(dataSelectionWidget->GetSelection(1)) ) { if( dataSelectionWidget->GetSelection(0) == dataSelectionWidget->GetSelection(1) ) { dataSelectionWidget->SetHelpText("Select two different images above"); this->EnableButtons(false); return; } else if( node.IsNotNull() && selection ) { mitk::Image::Pointer referenceImage = dynamic_cast<mitk::Image*> ( dataSelectionWidget->GetSelection(0)->GetData() ); mitk::Image::Pointer maskImage = dynamic_cast<mitk::Image*> ( dataSelectionWidget->GetSelection(1)->GetData() ); - if( maskImage.IsNull() || referenceImage->GetLargestPossibleRegion().GetSize() != maskImage->GetLargestPossibleRegion().GetSize() ) + if (maskImage.IsNull()) { dataSelectionWidget->SetHelpText("Different image sizes cannot be masked"); this->EnableButtons(false); return; } } else { dataSelectionWidget->SetHelpText(HelpText); return; } } dataSelectionWidget->SetHelpText(""); this->EnableButtons(); } void QmitkImageMaskingWidget::EnableButtons(bool enable) { m_Controls.grpBackgroundValue->setEnabled(enable); m_Controls.btnMaskImage->setEnabled(enable); } template<typename TPixel, unsigned int VImageDimension> void GetRange(const itk::Image<TPixel, VImageDimension>*, double& bottom, double& top) { bottom = std::numeric_limits<TPixel>::lowest(); top = std::numeric_limits<TPixel>::max(); } void QmitkImageMaskingWidget::OnCustomValueButtonToggled(bool checked) { m_Controls.txtCustom->setEnabled(checked); } void QmitkImageMaskingWidget::OnMaskImagePressed() { //Disable Buttons during calculation and initialize Progressbar this->EnableButtons(false); mitk::ProgressBar::GetInstance()->AddStepsToDo(4); mitk::ProgressBar::GetInstance()->Progress(); QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; //create result image, get mask node and reference image mitk::Image::Pointer resultImage(nullptr); mitk::DataNode::Pointer maskingNode = dataSelectionWidget->GetSelection(1); mitk::Image::Pointer referenceImage = static_cast<mitk::Image*>(dataSelectionWidget->GetSelection(0)->GetData()); if(referenceImage.IsNull() || maskingNode.IsNull() ) { MITK_ERROR << "Selection does not contain an image"; QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain an image", QMessageBox::Ok ); m_Controls.btnMaskImage->setEnabled(true); return; } //Do Image-Masking if (!IsSurface(maskingNode)) { mitk::ProgressBar::GetInstance()->Progress(); mitk::Image::Pointer maskImage = dynamic_cast<mitk::Image*> ( maskingNode->GetData() ); if(maskImage.IsNull() ) { MITK_ERROR << "Selection does not contain a segmentation"; QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain a segmentation", QMessageBox::Ok ); this->EnableButtons(); return; } - if( referenceImage->GetLargestPossibleRegion().GetSize() == maskImage->GetLargestPossibleRegion().GetSize() ) - { - resultImage = this->MaskImage( referenceImage, maskImage ); - } + resultImage = this->MaskImage(referenceImage, maskImage); } //Do Surface-Masking else { mitk::ProgressBar::GetInstance()->Progress(); //1. convert surface to image mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface*> ( maskingNode->GetData() ); //TODO Get 3D Surface of current time step if(surface.IsNull()) { MITK_ERROR << "Selection does not contain a surface"; QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain a surface", QMessageBox::Ok ); this->EnableButtons(); return; } mitk::Image::Pointer maskImage = this->ConvertSurfaceToImage( referenceImage, surface ); //2. mask reference image with mask image if(maskImage.IsNotNull() && referenceImage->GetLargestPossibleRegion().GetSize() == maskImage->GetLargestPossibleRegion().GetSize() ) { resultImage = this->MaskImage( referenceImage, maskImage ); } } mitk::ProgressBar::GetInstance()->Progress(); if( resultImage.IsNull() ) { MITK_ERROR << "Masking failed"; QMessageBox::information( this, "Image and Surface Masking", "Masking failed. For more information please see logging window.", QMessageBox::Ok ); this->EnableButtons(); mitk::ProgressBar::GetInstance()->Progress(4); return; } //Add result to data storage this->AddToDataStorage( dataSelectionWidget->GetDataStorage(), resultImage, dataSelectionWidget->GetSelection(0)->GetName() + "_" + dataSelectionWidget->GetSelection(1)->GetName(), dataSelectionWidget->GetSelection(0)); this->EnableButtons(); mitk::ProgressBar::GetInstance()->Progress(); } mitk::Image::Pointer QmitkImageMaskingWidget::MaskImage(mitk::Image::Pointer referenceImage, mitk::Image::Pointer maskImage ) { mitk::ScalarType backgroundValue = 0.0; if (m_Controls.rbnMinimum->isChecked()) { backgroundValue = referenceImage->GetStatistics()->GetScalarValueMin(); } else if (m_Controls.rbnCustom->isChecked()) { auto warningTitle = QStringLiteral("Invalid custom pixel value"); bool ok = false; auto originalBackgroundValue = m_Controls.txtCustom->text().toDouble(&ok); if (!ok) { // Input is not even a number QMessageBox::warning(nullptr, warningTitle, "Please enter a valid number as custom pixel value."); return nullptr; } else { // Clamp to the numerical limits of the pixel/component type double bottom, top; - AccessByItk_n(referenceImage, GetRange, (bottom, top)); + if (referenceImage->GetDimension() == 4) + { + AccessFixedDimensionByItk_n(referenceImage, GetRange, 4, (bottom, top)); + } + else + { + AccessByItk_n(referenceImage, GetRange, (bottom, top)); + } backgroundValue = std::max(bottom, std::min(originalBackgroundValue, top)); // Get rid of decimals for integral numbers auto type = referenceImage->GetPixelType().GetComponentType(); if (type != itk::ImageIOBase::FLOAT && type != itk::ImageIOBase::DOUBLE) backgroundValue = std::round(backgroundValue); } // Ask the user for permission before correcting their input if (std::abs(originalBackgroundValue - backgroundValue) > 1e-4) { auto warningText = QString( "<p>The custom pixel value <b>%1</b> lies not within the range of valid pixel values for the selected image.</p>" "<p>Apply the closest valid pixel value <b>%2</b> instead?</p>").arg(originalBackgroundValue).arg(backgroundValue); auto ret = QMessageBox::warning( nullptr, warningTitle, warningText, QMessageBox::StandardButton::Apply | QMessageBox::StandardButton::Cancel, QMessageBox::StandardButton::Apply); if (QMessageBox::StandardButton::Apply != ret) return nullptr; m_Controls.txtCustom->setText(QString("%1").arg(backgroundValue)); } } auto maskFilter = mitk::MaskImageFilter::New(); maskFilter->SetInput(referenceImage); maskFilter->SetMask(maskImage); maskFilter->OverrideOutsideValueOn(); maskFilter->SetOutsideValue(backgroundValue); try { maskFilter->Update(); } catch(const itk::ExceptionObject& e) { MITK_ERROR << e.GetDescription(); return nullptr; } return maskFilter->GetOutput(); } mitk::Image::Pointer QmitkImageMaskingWidget::ConvertSurfaceToImage( mitk::Image::Pointer image, mitk::Surface::Pointer surface ) { mitk::ProgressBar::GetInstance()->AddStepsToDo(2); mitk::ProgressBar::GetInstance()->Progress(); mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New(); surfaceToImageFilter->MakeOutputBinaryOn(); surfaceToImageFilter->SetInput(surface); surfaceToImageFilter->SetImage(image); try { surfaceToImageFilter->Update(); } catch(itk::ExceptionObject& excpt) { MITK_ERROR << excpt.GetDescription(); return nullptr; } mitk::ProgressBar::GetInstance()->Progress(); mitk::Image::Pointer resultImage = mitk::Image::New(); resultImage = surfaceToImageFilter->GetOutput(); return resultImage; } void QmitkImageMaskingWidget::AddToDataStorage(mitk::DataStorage::Pointer dataStorage, mitk::Image::Pointer segmentation, const std::string& name, mitk::DataNode::Pointer parent ) { auto dataNode = mitk::DataNode::New(); dataNode->SetName(name); dataNode->SetData(segmentation); if (parent.IsNotNull()) { mitk::LevelWindow levelWindow; parent->GetLevelWindow(levelWindow); dataNode->SetLevelWindow(levelWindow); } dataStorage->Add(dataNode, parent); } diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.h b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.h index 044114fbda..d63c876a90 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.h +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.h @@ -1,125 +1,125 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKSTDMULTIWIDGETEDITOR_H #define QMITKSTDMULTIWIDGETEDITOR_H // mitk gui qt common plugin #include <QmitkAbstractMultiWidgetEditor.h> #include <mitkILinkedRenderWindowPart.h> #include <org_mitk_gui_qt_stdmultiwidgeteditor_Export.h> // c++ #include <memory> class QmitkStdMultiWidget; class QmitkStdMultiWidgetEditorPrivate; /** * @brief */ class ORG_MITK_GUI_QT_STDMULTIWIDGETEDITOR QmitkStdMultiWidgetEditor final : public QmitkAbstractMultiWidgetEditor, public mitk::ILinkedRenderWindowPart { Q_OBJECT public: static const QString EDITOR_ID; QmitkStdMultiWidgetEditor(); virtual ~QmitkStdMultiWidgetEditor() override; virtual QmitkLevelWindowWidget* GetLevelWindowWidget() const override; /** * @brief Overridden from mitk::ILinkedRenderWindowPart */ virtual void EnableSlicingPlanes(bool enable) override; /** * @brief Overridden from mitk::ILinkedRenderWindowPart */ virtual bool IsSlicingPlanesEnabled() const override; /** * @brief Overridden from berry::IPartListener */ virtual berry::IPartListener::Events::Types GetPartEventTypes() const override; /** * @brief Overridden from berry::IPartListener */ virtual void PartClosed(const berry::IWorkbenchPartReference::Pointer& partRef) override; /** * @brief Overridden from berry::IPartListener */ virtual void PartOpened(const berry::IWorkbenchPartReference::Pointer& partRef) override; /** * @brief Overridden from berry::IPartListener */ virtual void PartHidden(const berry::IWorkbenchPartReference::Pointer& partRef) override; /** * @brief Overridden from berry::IPartListener */ virtual void PartVisible(const berry::IWorkbenchPartReference::Pointer& partRef) override; - void OnInteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme); + void OnInteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme) override; void ShowLevelWindowWidget(bool show); private: /** * @brief Overridden from QmitkAbstractRenderEditor */ virtual void SetFocus() override; /** * @brief Overridden from QmitkAbstractRenderEditor */ virtual void CreateQtPartControl(QWidget* parent) override; /** * @brief Overridden from QmitkAbstractRenderEditor */ virtual void OnPreferencesChanged(const berry::IBerryPreferences* preferences) override; /** * @brief InitializePreferences Internal helper method to set default preferences. * This method is used to show the current preferences in the first call of * the preference page (the GUI). * * @param preferences berry preferences. */ void InitializePreferences(berry::IBerryPreferences *preferences); /** * @brief GetPreferenceDecorations Getter to fill internal members with values of preferences. * @param preferences The berry preferences. * * If a preference is set, the value will overwrite the current value. If it does not exist, * the value will not change. */ void GetPreferenceDecorations(const berry::IBerryPreferences *preferences); /** * @brief GetColorForWidget helper method to convert a saved color string to mitk::Color. * @param hexColor color in hex format (#12356) where each digit is in the form (0-F). * @return the color in mitk format. */ mitk::Color HexColorToMitkColor(const QString& hexColor); /** * @brief MitkColorToHex Convert an mitk::Color to hex string. * @param color mitk format. * @return String in hex (#RRGGBB). */ QString MitkColorToHex(const mitk::Color& color); struct Impl; std::unique_ptr<Impl> m_Impl; }; #endif // QMITKSTDMULTIWIDGETEDITOR_H diff --git a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp index add81e5aca..c2984e620e 100644 --- a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp +++ b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp @@ -1,183 +1,183 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // Blueberry #include <berryISelectionService.h> #include <berryIWorkbenchWindow.h> // Qmitk #include "QmitkToFTutorialView.h" // Qt #include <QMessageBox> // mitk includes #include <mitkCameraIntrinsics.h> // class holding the intrinsic parameters of the according camera #include <mitkSurface.h> // MITK-ToF related includes #include <mitkToFCameraMITKPlayerDevice.h> #include <mitkToFConfig.h> // configuration file holding e.g. plugin paths or path to test file directory #include <mitkToFDistanceImageToSurfaceFilter.h> // filter from module ToFProcessing that calculates a surface from the given range image #include <mitkToFImageGrabber.h> // allows access to images provided by the ToF camera const std::string QmitkToFTutorialView::VIEW_ID = "org.mitk.views.toftutorial"; QmitkToFTutorialView::QmitkToFTutorialView() : QmitkAbstractView() , m_Controls( nullptr ) { } QmitkToFTutorialView::~QmitkToFTutorialView() { } void QmitkToFTutorialView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkToFTutorialViewControls; m_Controls->setupUi( parent ); connect( m_Controls->step1Button, SIGNAL(clicked()), this, SLOT(OnStep1()) ); connect( m_Controls->step2Button, SIGNAL(clicked()), this, SLOT(OnStep2()) ); } } void QmitkToFTutorialView::SetFocus() { m_Controls->step1Button->setFocus(); } void QmitkToFTutorialView::OnStep1() { // clean up data storage RemoveAllNodesFromDataStorage(); // Create an instance of ToFImageGrabber that holds a ToFCameraMITKPlayerDevice for playing ToF data mitk::ToFImageGrabber::Pointer tofImageGrabber = mitk::ToFImageGrabber::New(); tofImageGrabber->SetCameraDevice(mitk::ToFCameraMITKPlayerDevice::New()); // set paths to test data std::string distanceFileName = MITK_TOF_DATA_DIR; - distanceFileName.append("/PMDCamCube2_MF0_IT0_20Images_DistanceImage.pic"); + distanceFileName.append("/PMDCamCube2_MF0_IT0_20Images_DistanceImage.nrrd"); std::string amplitudeFileName = MITK_TOF_DATA_DIR; - amplitudeFileName.append("/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.pic"); + amplitudeFileName.append("/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.nrrd"); std::string intensityFileName = MITK_TOF_DATA_DIR; - intensityFileName.append("/PMDCamCube2_MF0_IT0_20Images_IntensityImage.pic"); + intensityFileName.append("/PMDCamCube2_MF0_IT0_20Images_IntensityImage.nrrd"); // set file name property in image grabber. This will be propagated to the corresponding device and controller class tofImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName)); tofImageGrabber->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName)); tofImageGrabber->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName)); // connect to device if (tofImageGrabber->ConnectCamera()) { //// start camera (internally starts thread that continuously grabs images from the camera) tofImageGrabber->StartCamera(); // update image grabber which itself represents the source of a MITK filter pipeline tofImageGrabber->Update(); // grab distance image mitk::Image::Pointer distanceImage = tofImageGrabber->GetOutput(); // grab amplitude image mitk::Image::Pointer amplitudeImage = tofImageGrabber->GetOutput(1); // grab intensity image mitk::Image::Pointer intensityImage = tofImageGrabber->GetOutput(2); //add distance image to data storage mitk::DataNode::Pointer distanceNode = mitk::DataNode::New(); distanceNode->SetName("Distance Image"); distanceNode->SetData(distanceImage); this->GetDataStorage()->Add(distanceNode); //add amplitude image to data storage mitk::DataNode::Pointer amplitudeNode = mitk::DataNode::New(); amplitudeNode->SetName("Amplitude Image"); amplitudeNode->SetData(amplitudeImage); this->GetDataStorage()->Add(amplitudeNode); //add intensity image to data storage mitk::DataNode::Pointer intensityNode = mitk::DataNode::New(); intensityNode->SetName("Intensity Image"); intensityNode->SetData(intensityImage); this->GetDataStorage()->Add(intensityNode); // stop camera (terminate internally used thread) tofImageGrabber->StopCamera(); //// disconnect from camera tofImageGrabber->DisconnectCamera(); // adjust views to new data in DataStorage mitk::RenderingManager::GetInstance()->InitializeViews(distanceImage->GetGeometry()); } else { MITK_ERROR<<"Connection to ToF camera could not be established"; } } void QmitkToFTutorialView::OnStep2() { // Check if distance image is available mitk::DataNode::Pointer distanceNode = this->GetDataStorage()->GetNamedNode("Distance Image"); if (distanceNode.IsNotNull()) { // get distance image from node and check if node contains image mitk::Image::Pointer distanceImage = dynamic_cast<mitk::Image*>(distanceNode->GetData()); if (distanceImage.IsNotNull()) { // create object of CameraIntrinsics that holds intrinsic parameters of the ToF camera mitk::CameraIntrinsics::Pointer cameraIntrinsics = mitk::CameraIntrinsics::New(); // set focal length in pixel cameraIntrinsics->SetFocalLength(295.8,296.1); // set principal point in pixel cameraIntrinsics->SetPrincipalPoint(113.2,97.1); // set up filter for surface calculation mitk::ToFDistanceImageToSurfaceFilter::Pointer surfaceFilter = mitk::ToFDistanceImageToSurfaceFilter::New(); // apply intrinsic parameters to filter surfaceFilter->SetCameraIntrinsics(cameraIntrinsics); // set distance between pixels on chip in mm (in this example squared pixel) mitk::ToFProcessingCommon::ToFPoint2D interPixelDistance; interPixelDistance[0] = 0.045; interPixelDistance[1] = 0.045; surfaceFilter->SetInterPixelDistance(interPixelDistance); // set distance image as input surfaceFilter->SetInput(distanceImage); // update the filter surfaceFilter->Update(); // get surface from filter mitk::Surface::Pointer surface = surfaceFilter->GetOutput(); // add surface to data storage mitk::DataNode::Pointer surfaceNode = mitk::DataNode::New(); surfaceNode->SetName("ToF surface"); surfaceNode->SetData(surface); this->GetDataStorage()->Add(surfaceNode); // adjust views to new data in DataStorage mitk::RenderingManager::GetInstance()->InitializeViews(surface->GetGeometry()); mitk::RenderingManager::GetInstance()->InitializeViews(surface->GetGeometry()); } else { QMessageBox::warning(nullptr,"ToF Tutorial","Node 'Distance Image' contains no image"); } } else { QMessageBox::warning(nullptr,"ToF Tutorial","Perform Step 1 first to acquire a distance image"); } } void QmitkToFTutorialView::RemoveAllNodesFromDataStorage() { mitk::DataStorage::SetOfObjects::ConstPointer allNodes = this->GetDataStorage()->GetAll(); this->GetDataStorage()->Remove(allNodes); } diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp index b9b80e8e0b..8cfa70dc4b 100755 --- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp +++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp @@ -1,293 +1,314 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkVolumeVisualizationView.h" #include <vtkSmartVolumeMapper.h> #include <mitkImage.h> #include <mitkTransferFunction.h> #include <mitkTransferFunctionInitializer.h> #include <mitkTransferFunctionProperty.h> #include <mitkNodePredicateDataType.h> #include <mitkNodePredicateDimension.h> #include <mitkNodePredicateAnd.h> #include <mitkNodePredicateNot.h> #include <mitkNodePredicateOr.h> #include <mitkNodePredicateProperty.h> #include <mitkProperties.h> const std::string QmitkVolumeVisualizationView::VIEW_ID = "org.mitk.views.volumevisualization"; enum { DEFAULT_RENDERMODE = 0, RAYCAST_RENDERMODE = 1, GPU_RENDERMODE = 2 }; QmitkVolumeVisualizationView::QmitkVolumeVisualizationView() : QmitkAbstractView() , m_Controls(nullptr) { } void QmitkVolumeVisualizationView::SetFocus() { + UpdateInterface(); } void QmitkVolumeVisualizationView::CreateQtPartControl(QWidget* parent) { m_Controls = new Ui::QmitkVolumeVisualizationViewControls; m_Controls->setupUi(parent); m_Controls->volumeSelectionWidget->SetDataStorage(GetDataStorage()); m_Controls->volumeSelectionWidget->SetNodePredicate(mitk::NodePredicateAnd::New( mitk::TNodePredicateDataType<mitk::Image>::New(), mitk::NodePredicateOr::New(mitk::NodePredicateDimension::New(3), mitk::NodePredicateDimension::New(4)), mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")))); m_Controls->volumeSelectionWidget->SetSelectionIsOptional(true); - m_Controls->volumeSelectionWidget->SetAutoSelectNewNodes(true); m_Controls->volumeSelectionWidget->SetEmptyInfo(QString("Please select a 3D / 4D image volume")); m_Controls->volumeSelectionWidget->SetPopUpTitel(QString("Select image volume")); // Fill the transfer function presets in the generator widget std::vector<std::string> names; mitk::TransferFunctionInitializer::GetPresetNames(names); for (const auto& name : names) { m_Controls->transferFunctionGeneratorWidget->AddPreset(QString::fromStdString(name)); } // see enum in vtkSmartVolumeMapper m_Controls->renderMode->addItem("Default"); m_Controls->renderMode->addItem("RayCast"); m_Controls->renderMode->addItem("GPU"); // see vtkVolumeMapper::BlendModes m_Controls->blendMode->addItem("Comp"); m_Controls->blendMode->addItem("Max"); m_Controls->blendMode->addItem("Min"); m_Controls->blendMode->addItem("Avg"); m_Controls->blendMode->addItem("Add"); connect(m_Controls->volumeSelectionWidget, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkVolumeVisualizationView::OnCurrentSelectionChanged); connect(m_Controls->enableRenderingCB, SIGNAL(toggled(bool)), this, SLOT(OnEnableRendering(bool))); connect(m_Controls->renderMode, SIGNAL(activated(int)), this, SLOT(OnRenderMode(int))); connect(m_Controls->blendMode, SIGNAL(activated(int)), this, SLOT(OnBlendMode(int))); connect(m_Controls->transferFunctionGeneratorWidget, SIGNAL(SignalUpdateCanvas()), m_Controls->transferFunctionWidget, SLOT(OnUpdateCanvas())); connect(m_Controls->transferFunctionGeneratorWidget, SIGNAL(SignalTransferFunctionModeChanged(int)), SLOT(OnMitkInternalPreset(int))); m_Controls->enableRenderingCB->setEnabled(false); m_Controls->blendMode->setEnabled(false); m_Controls->renderMode->setEnabled(false); m_Controls->transferFunctionWidget->setEnabled(false); m_Controls->transferFunctionGeneratorWidget->setEnabled(false); m_Controls->volumeSelectionWidget->SetAutoSelectNewNodes(true); + + this->m_TimePointChangeListener.RenderWindowPartActivated(this->GetRenderWindowPart()); + connect(&m_TimePointChangeListener, + &QmitkSliceNavigationListener::SelectedTimePointChanged, + this, + &QmitkVolumeVisualizationView::OnSelectedTimePointChanged); +} + +void QmitkVolumeVisualizationView::RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart) +{ + this->m_TimePointChangeListener.RenderWindowPartActivated(renderWindowPart); +} + +void QmitkVolumeVisualizationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart) +{ + this->m_TimePointChangeListener.RenderWindowPartDeactivated(renderWindowPart); } void QmitkVolumeVisualizationView::OnMitkInternalPreset(int mode) { if (m_SelectedNode.IsExpired()) { return; } auto node = m_SelectedNode.Lock(); mitk::TransferFunctionProperty::Pointer transferFuncProp; if (node->GetProperty(transferFuncProp, "TransferFunction")) { // first item is only information if (--mode == -1) return; // -- Creat new TransferFunction mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(transferFuncProp->GetValue()); tfInit->SetTransferFunctionMode(mode); RequestRenderWindowUpdate(); m_Controls->transferFunctionWidget->OnUpdateCanvas(); } } void QmitkVolumeVisualizationView::OnCurrentSelectionChanged(QList<mitk::DataNode::Pointer> nodes) { m_SelectedNode = nullptr; if (nodes.empty() || nodes.front().IsNull()) { UpdateInterface(); return; } auto selectedNode = nodes.front(); auto image = dynamic_cast<mitk::Image*>(selectedNode->GetData()); if (nullptr != image) { m_SelectedNode = selectedNode; } UpdateInterface(); } void QmitkVolumeVisualizationView::OnEnableRendering(bool state) { if (m_SelectedNode.IsExpired()) { return; } m_SelectedNode.Lock()->SetProperty("volumerendering", mitk::BoolProperty::New(state)); UpdateInterface(); RequestRenderWindowUpdate(); } void QmitkVolumeVisualizationView::OnRenderMode(int mode) { if (m_SelectedNode.IsExpired()) { return; } auto selectedNode = m_SelectedNode.Lock(); bool usegpu = false; bool useray = false; if (DEFAULT_RENDERMODE == mode) { useray = true; usegpu = true; } else if (GPU_RENDERMODE == mode) { usegpu = true; } else if (RAYCAST_RENDERMODE == mode) { useray = true; } selectedNode->SetProperty("volumerendering.usegpu", mitk::BoolProperty::New(usegpu)); selectedNode->SetProperty("volumerendering.useray", mitk::BoolProperty::New(useray)); RequestRenderWindowUpdate(); } void QmitkVolumeVisualizationView::OnBlendMode(int mode) { if (m_SelectedNode.IsExpired()) { return; } auto selectedNode = m_SelectedNode.Lock(); bool usemip = false; if (vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND == mode) { usemip = true; } selectedNode->SetProperty("volumerendering.usemip", mitk::BoolProperty::New(usemip)); selectedNode->SetProperty("volumerendering.blendmode", mitk::IntProperty::New(mode)); RequestRenderWindowUpdate(); } +void QmitkVolumeVisualizationView::OnSelectedTimePointChanged(const mitk::TimePointType & /*newTimePoint*/) +{ + this->UpdateInterface(); +} + void QmitkVolumeVisualizationView::UpdateInterface() { if (m_SelectedNode.IsExpired()) { // turnoff all m_Controls->enableRenderingCB->setChecked(false); m_Controls->enableRenderingCB->setEnabled(false); m_Controls->blendMode->setCurrentIndex(0); m_Controls->blendMode->setEnabled(false); m_Controls->renderMode->setCurrentIndex(0); m_Controls->renderMode->setEnabled(false); m_Controls->transferFunctionWidget->SetDataNode(nullptr); m_Controls->transferFunctionWidget->setEnabled(false); m_Controls->transferFunctionGeneratorWidget->SetDataNode(nullptr); m_Controls->transferFunctionGeneratorWidget->setEnabled(false); return; } bool enabled = false; auto selectedNode = m_SelectedNode.Lock(); selectedNode->GetBoolProperty("volumerendering", enabled); m_Controls->enableRenderingCB->setEnabled(true); m_Controls->enableRenderingCB->setChecked(enabled); if (!enabled) { // turnoff all except volumerendering checkbox m_Controls->blendMode->setCurrentIndex(0); m_Controls->blendMode->setEnabled(false); m_Controls->renderMode->setCurrentIndex(0); m_Controls->renderMode->setEnabled(false); m_Controls->transferFunctionWidget->SetDataNode(nullptr); m_Controls->transferFunctionWidget->setEnabled(false); m_Controls->transferFunctionGeneratorWidget->SetDataNode(nullptr); m_Controls->transferFunctionGeneratorWidget->setEnabled(false); return; } // otherwise we can activate em all m_Controls->blendMode->setEnabled(true); m_Controls->renderMode->setEnabled(true); // Determine Combo Box mode { bool usegpu = false; bool useray = false; bool usemip = false; selectedNode->GetBoolProperty("volumerendering.usegpu", usegpu); selectedNode->GetBoolProperty("volumerendering.useray", useray); selectedNode->GetBoolProperty("volumerendering.usemip", usemip); int blendMode; if (selectedNode->GetIntProperty("volumerendering.blendmode", blendMode)) m_Controls->blendMode->setCurrentIndex(blendMode); if (usemip) m_Controls->blendMode->setCurrentIndex(vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND); int mode = DEFAULT_RENDERMODE; if (useray) mode = RAYCAST_RENDERMODE; else if (usegpu) mode = GPU_RENDERMODE; m_Controls->renderMode->setCurrentIndex(mode); } - - m_Controls->transferFunctionWidget->SetDataNode(selectedNode); + auto time = this->GetRenderWindowPart()->GetTimeNavigationController()->GetSelectedTimeStep(); + m_Controls->transferFunctionWidget->SetDataNode(selectedNode, time); m_Controls->transferFunctionWidget->setEnabled(true); - m_Controls->transferFunctionGeneratorWidget->SetDataNode(selectedNode); + m_Controls->transferFunctionGeneratorWidget->SetDataNode(selectedNode, time); m_Controls->transferFunctionGeneratorWidget->setEnabled(true); } diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.h b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.h index 5d413576f2..658d5fc133 100755 --- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.h +++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.h @@ -1,61 +1,69 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKVOLUMEVISUALIZATIONVIEW_H #define QMITKVOLUMEVISUALIZATIONVIEW_H #include "ui_QmitkVolumeVisualizationViewControls.h" // mitk core #include <mitkDataStorage.h> #include <mitkWeakPointer.h> #include <QmitkAbstractView.h> +#include <QmitkSliceNavigationListener.h> +#include <mitkIRenderWindowPartListener.h> /** * @brief */ -class QmitkVolumeVisualizationView : public QmitkAbstractView +class QmitkVolumeVisualizationView : public QmitkAbstractView, public mitk::IRenderWindowPartListener { Q_OBJECT public: static const std::string VIEW_ID; QmitkVolumeVisualizationView(); ~QmitkVolumeVisualizationView() override = default; void SetFocus() override; private Q_SLOTS: void OnCurrentSelectionChanged(QList<mitk::DataNode::Pointer> nodes); void OnMitkInternalPreset(int mode); void OnEnableRendering(bool state); void OnRenderMode(int mode); void OnBlendMode(int mode); + void OnSelectedTimePointChanged(const mitk::TimePointType &); + +protected: + void RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart) override; + void RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart) override; private: void CreateQtPartControl(QWidget* parent) override; void UpdateInterface(); Ui::QmitkVolumeVisualizationViewControls* m_Controls; mitk::WeakPointer<mitk::DataNode> m_SelectedNode; + QmitkSliceNavigationListener m_TimePointChangeListener; }; #endif // QMITKVOLUMEVISUALIZATIONVIEW_H diff --git a/README.md b/README.md index 8e65813fa5..148c0572c2 100644 --- a/README.md +++ b/README.md @@ -1,108 +1,110 @@ ![MITK Logo][logo] The [Medical Imaging Interaction Toolkit][mitk] (MITK) is a free open-source software system for development of interactive medical image processing software. MITK combines the [Insight Toolkit][itk] (ITK) and the [Visualization Toolkit][vtk] (VTK) with an application framework. The links below provide high-level and reference documentation targeting different usage scenarios: - Get a [high-level overview][mitk-overview] about MITK with pointers to further documentation - End-users looking for help with MITK applications should read the [MITK User Manual][mitk-usermanual] - Developers contributing to or using MITK, please see the [MITK Developer Manual][mitk-devmanual] as well as the [MITK API Reference][mitk-apiref] See the [MITK homepage][mitk] for details. Supported platforms ------------------- MITK is a cross-platform C++ toolkit and officially supports: - Windows - Linux - macOS For details, please read the [Supported Platforms][platforms] page. ### Build status of develop branch [![Windows][windows-build-status]][cdash] [![Ubuntu 18.04][ubuntu-18.04-build-status]][cdash] [![Ubuntu 20.04][ubuntu-20.04-build-status]][cdash] -[![macOS 10.14 Mojave][macos-10.14-build-status]][cdash] +[![macOS 10.15 Catalina][macos-10.15-build-status]][cdash] +[![macOS 11 Big Sur][macos-11-build-status]][cdash] We highly recommend to use the stable **master** branch instead. It is updated 1-2 times per month accompanied by curated [changelogs][changelog] and [snapshot installers][snapshot-installers]. License ------- Copyright (c) [German Cancer Research Center (DKFZ)][dkfz]. All rights reserved. MITK is available as free open-source software under a [3-clause BSD license][license]. Download -------- The MITK source code and binaries for the *MitkWorkbench* application are released regularly according to the [MITK release cycle][release-cycle]. See the [Download][download] page for a list of releases. The official MITK source code is available in the [MITK Git repository][phab_repo]. The Git clone command is git clone https://phabricator.mitk.org/source/mitk.git MITK Active development takes place in the MITK develop branch and its usage is advised for advanced users only. How to contribute ----------------- Contributions of all kind are happily accepted. However, to make the contribution process as smooth as possible, please read the [How to contribute to MITK][contribute] page if you plan to contribute to MITK. Build instructions ------------------ MITK uses [CMake][cmake] to configure a build tree. The following is a crash course about cloning, configuring, and building MITK on a Linux/Unix system: git clone https://phabricator.mitk.org/source/mitk.git MITK mkdir MITK-build cd MITK-build cmake ../MITK make -j4 Read the comprehensive [build instructions][build] page for details. Useful links ------------ - [Homepage][mitk] - [Download][download] - [Mailing list][mailinglist] - [Issue tracker][bugs] [logo]: https://github.com/MITK/MITK/raw/master/mitk.png [mitk]: http://mitk.org [itk]: https://itk.org [vtk]: https://vtk.org [mitk-overview]: http://docs.mitk.org/nightly/Overview.html [mitk-usermanual]: http://docs.mitk.org/nightly/UserManualPortal.html [mitk-devmanual]: http://docs.mitk.org/nightly/DeveloperManualPortal.html [mitk-apiref]: http://docs.mitk.org/nightly/usergroup0.html [platforms]: http://docs.mitk.org/nightly/SupportedPlatformsPage.html [dkfz]: https://www.dkfz.de [license]: https://github.com/MITK/MITK/blob/master/LICENSE [release-cycle]: http://mitk.org/MitkReleaseCycle [download]: http://mitk.org/Download [phab_repo]: https://phabricator.mitk.org/source/mitk/ [contribute]: http://mitk.org/How_to_contribute [cmake]: https://www.cmake.org [build]: http://docs.mitk.org/nightly/BuildInstructionsPage.html [mailinglist]: http://mitk.org/Mailinglist [bugs]: https://phabricator.mitk.org/maniphest/ [cdash]: https://cdash.mitk.org/index.php?project=MITK [changelog]: https://phabricator.mitk.org/w/mitk/changelog/ [snapshot-installers]: https://www.mitk.org/download/ci/snapshots/ [windows-build-status]: https://ci.mitk.org/buildStatus/icon?job=MITK%2FContinuous%2FWindows&subject=Windows [ubuntu-18.04-build-status]: https://ci.mitk.org/buildStatus/icon?job=MITK%2FContinuous%2FUbuntu+18.04&subject=Ubuntu+18.04 [ubuntu-20.04-build-status]: https://ci.mitk.org/buildStatus/icon?job=MITK%2FContinuous%2FUbuntu+20.04&subject=Ubuntu+20.04 -[macOS-10.14-build-status]: https://ci.mitk.org/buildStatus/icon?job=MITK%2FContinuous%2FmacOS+Mojave&subject=macOS+10.14+Mojave +[macOS-10.15-build-status]: https://ci.mitk.org/buildStatus/icon?job=MITK%2FContinuous%2FmacOS+Catalina&subject=macOS+10.15+Catalina +[macOS-11-build-status]: https://ci.mitk.org/buildStatus/icon?job=MITK%2FContinuous%2FmacOS+Big+Sur&subject=macOS+11+Big+Sur diff --git a/SuperBuild.cmake b/SuperBuild.cmake index b83484ef43..d4fddd04f6 100644 --- a/SuperBuild.cmake +++ b/SuperBuild.cmake @@ -1,499 +1,498 @@ #----------------------------------------------------------------------------- # Convenient macro allowing to download a file #----------------------------------------------------------------------------- if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL) set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL http://mitk.org/download/thirdparty) endif() macro(downloadFile url dest) file(DOWNLOAD ${url} ${dest} STATUS status) list(GET status 0 error_code) list(GET status 1 error_msg) if(error_code) message(FATAL_ERROR "error: Failed to download ${url} - ${error_msg}") endif() endmacro() #----------------------------------------------------------------------------- # MITK Prerequisites #----------------------------------------------------------------------------- if(UNIX AND NOT APPLE) include(mitkFunctionCheckPackageHeader) # Check for libxt-dev mitkFunctionCheckPackageHeader(StringDefs.h libxt-dev /usr/include/X11/) # Check for libtiff4-dev mitkFunctionCheckPackageHeader(tiff.h libtiff4-dev) endif() # We need a proper patch program. On Linux and MacOS, we assume # that "patch" is available. On Windows, we download patch.exe # if not patch program is found. find_program(PATCH_COMMAND patch) if((NOT PATCH_COMMAND OR NOT EXISTS ${PATCH_COMMAND}) AND WIN32) downloadFile(${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/patch.exe ${CMAKE_CURRENT_BINARY_DIR}/patch.exe) find_program(PATCH_COMMAND patch ${CMAKE_CURRENT_BINARY_DIR}) endif() if(NOT PATCH_COMMAND) message(FATAL_ERROR "No patch program found.") endif() #----------------------------------------------------------------------------- # ExternalProjects #----------------------------------------------------------------------------- get_property(external_projects GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS) if(MITK_CTEST_SCRIPT_MODE) # Write a file containing the list of enabled external project targets. # This file can be read by a ctest script to separately build projects. set(SUPERBUILD_TARGETS ) foreach(proj ${external_projects}) if(MITK_USE_${proj}) list(APPEND SUPERBUILD_TARGETS ${proj}) endif() endforeach() file(WRITE "${CMAKE_BINARY_DIR}/SuperBuildTargets.cmake" "set(SUPERBUILD_TARGETS ${SUPERBUILD_TARGETS})") endif() # A list of "nice" external projects, playing well together with CMake set(nice_external_projects ${external_projects}) list(REMOVE_ITEM nice_external_projects Boost) foreach(proj ${nice_external_projects}) if(MITK_USE_${proj}) set(EXTERNAL_${proj}_DIR "${${proj}_DIR}" CACHE PATH "Path to ${proj} build directory") mark_as_advanced(EXTERNAL_${proj}_DIR) if(EXTERNAL_${proj}_DIR) set(${proj}_DIR ${EXTERNAL_${proj}_DIR}) endif() endif() endforeach() set(EXTERNAL_BOOST_ROOT "${BOOST_ROOT}" CACHE PATH "Path to Boost directory") mark_as_advanced(EXTERNAL_BOOST_ROOT) if(EXTERNAL_BOOST_ROOT) set(BOOST_ROOT ${EXTERNAL_BOOST_ROOT}) endif() if(BUILD_TESTING) set(EXTERNAL_MITK_DATA_DIR "${MITK_DATA_DIR}" CACHE PATH "Path to the MITK data directory") mark_as_advanced(EXTERNAL_MITK_DATA_DIR) if(EXTERNAL_MITK_DATA_DIR) set(MITK_DATA_DIR ${EXTERNAL_MITK_DATA_DIR}) endif() endif() #----------------------------------------------------------------------------- # External project settings #----------------------------------------------------------------------------- include(ExternalProject) include(mitkMacroQueryCustomEPVars) include(mitkFunctionInstallExternalCMakeProject) include(mitkFunctionCleanExternalProject) option(MITK_AUTOCLEAN_EXTERNAL_PROJECTS "Experimental: Clean external project builds if updated" ON) set(ep_prefix "${CMAKE_BINARY_DIR}/ep") set_property(DIRECTORY PROPERTY EP_PREFIX ${ep_prefix}) # Compute -G arg for configuring external projects with the same CMake generator: if(CMAKE_EXTRA_GENERATOR) set(gen "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}") else() set(gen "${CMAKE_GENERATOR}") endif() set(gen_platform ${CMAKE_GENERATOR_PLATFORM}) # Use this value where semi-colons are needed in ep_add args: set(sep "^^") ## if(MSVC_VERSION) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj /MP") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /MP") endif() # This is a workaround for passing linker flags # actually down to the linker invocation set(_cmake_required_flags_orig ${CMAKE_REQUIRED_FLAGS}) set(CMAKE_REQUIRED_FLAGS "-Wl,-rpath") mitkFunctionCheckCompilerFlags(${CMAKE_REQUIRED_FLAGS} _has_rpath_flag) set(CMAKE_REQUIRED_FLAGS ${_cmake_required_flags_orig}) set(_install_rpath_linkflag ) if(_has_rpath_flag) if(APPLE) set(_install_rpath_linkflag "-Wl,-rpath,@loader_path/../lib") else() set(_install_rpath_linkflag "-Wl,-rpath='$ORIGIN/../lib'") endif() endif() set(_install_rpath) if(APPLE) set(_install_rpath "@loader_path/../lib") elseif(UNIX) # this work for libraries as well as executables set(_install_rpath "\$ORIGIN/../lib") endif() set(ep_common_args -DCMAKE_POLICY_DEFAULT_CMP0091:STRING=OLD -DCMAKE_CXX_EXTENSIONS:STRING=${CMAKE_CXX_EXTENSIONS} -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED} -DCMAKE_MACOSX_RPATH:BOOL=TRUE "-DCMAKE_INSTALL_RPATH:STRING=${_install_rpath}" -DBUILD_TESTING:BOOL=OFF -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_CXX14_FLAG}" #debug flags -DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} -DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} #release flags -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} -DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} #relwithdebinfo -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} #link flags -DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ) if(MSVC_VERSION) list(APPEND ep_common_args -DCMAKE_DEBUG_POSTFIX:STRING=d ) set(DCMTK_CMAKE_DEBUG_POSTFIX d) endif() set(ep_common_cache_args ) set(ep_common_cache_default_args "-DCMAKE_PREFIX_PATH:PATH=<INSTALL_DIR>;${CMAKE_PREFIX_PATH}" "-DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH}" "-DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH}" ) # Pass the CMAKE_OSX variables to external projects if(APPLE) set(MAC_OSX_ARCHITECTURE_ARGS -DCMAKE_OSX_ARCHITECTURES:PATH=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET:PATH=${CMAKE_OSX_DEPLOYMENT_TARGET} -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT} ) set(ep_common_args ${MAC_OSX_ARCHITECTURE_ARGS} ${ep_common_args} ) endif() set(mitk_superbuild_ep_args) set(mitk_depends ) # Include external projects include(CMakeExternals/MITKData.cmake) foreach(p ${external_projects}) set(p_hash "") set(p_file "${CMAKE_SOURCE_DIR}/CMakeExternals/${p}.cmake") if(EXISTS ${p_file}) file(MD5 ${p_file} p_hash) else() foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) set(MITK_CMAKE_EXTERNALS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/CMakeExternals") set(p_file "${MITK_CMAKE_EXTERNALS_EXTENSION_DIR}/${p}.cmake") if(EXISTS "${p_file}") file(MD5 "${p_file}" p_hash) break() endif() endforeach() endif() if(p_hash) set(p_hash_file "${ep_prefix}/tmp/${p}-hash.txt") if(MITK_AUTOCLEAN_EXTERNAL_PROJECTS) if(EXISTS "${p_hash_file}") file(READ "${p_hash_file}" p_prev_hash) if(NOT p_hash STREQUAL p_prev_hash) mitkCleanExternalProject(${p}) endif() endif() endif() file(WRITE "${p_hash_file}" ${p_hash}) endif() include("${p_file}" OPTIONAL) list(APPEND mitk_superbuild_ep_args -DMITK_USE_${p}:BOOL=${MITK_USE_${p}} ) get_property(_package GLOBAL PROPERTY MITK_${p}_PACKAGE) if(_package) list(APPEND mitk_superbuild_ep_args -D${p}_DIR:PATH=${${p}_DIR}) endif() list(APPEND mitk_depends ${${p}_DEPENDS}) endforeach() if (SWIG_EXECUTABLE) list(APPEND mitk_superbuild_ep_args -DSWIG_EXECUTABLE=${SWIG_EXECUTABLE}) endif() #----------------------------------------------------------------------------- # Set superbuild boolean args #----------------------------------------------------------------------------- set(mitk_cmake_boolean_args BUILD_SHARED_LIBS WITH_COVERAGE BUILD_TESTING MITK_BUILD_ALL_PLUGINS MITK_BUILD_ALL_APPS MITK_BUILD_EXAMPLES MITK_USE_Qt5 MITK_USE_SYSTEM_Boost MITK_USE_BLUEBERRY MITK_USE_OpenCL MITK_USE_OpenMP - MITK_ENABLE_PIC_READER ) #----------------------------------------------------------------------------- # Create the final variable containing superbuild boolean args #----------------------------------------------------------------------------- set(mitk_superbuild_boolean_args) foreach(mitk_cmake_arg ${mitk_cmake_boolean_args}) list(APPEND mitk_superbuild_boolean_args -D${mitk_cmake_arg}:BOOL=${${mitk_cmake_arg}}) endforeach() if(MITK_BUILD_ALL_PLUGINS) list(APPEND mitk_superbuild_boolean_args -DBLUEBERRY_BUILD_ALL_PLUGINS:BOOL=ON) endif() #----------------------------------------------------------------------------- # MITK Utilities #----------------------------------------------------------------------------- set(proj MITK-Utilities) ExternalProject_Add(${proj} DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS ${mitk_depends} ) #----------------------------------------------------------------------------- # Additional MITK CXX/C Flags #----------------------------------------------------------------------------- set(MITK_ADDITIONAL_C_FLAGS "" CACHE STRING "Additional C Flags for MITK") set(MITK_ADDITIONAL_C_FLAGS_RELEASE "" CACHE STRING "Additional Release C Flags for MITK") set(MITK_ADDITIONAL_C_FLAGS_DEBUG "" CACHE STRING "Additional Debug C Flags for MITK") mark_as_advanced(MITK_ADDITIONAL_C_FLAGS MITK_ADDITIONAL_C_FLAGS_DEBUG MITK_ADDITIONAL_C_FLAGS_RELEASE) set(MITK_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX Flags for MITK") set(MITK_ADDITIONAL_CXX_FLAGS_RELEASE "" CACHE STRING "Additional Release CXX Flags for MITK") set(MITK_ADDITIONAL_CXX_FLAGS_DEBUG "" CACHE STRING "Additional Debug CXX Flags for MITK") mark_as_advanced(MITK_ADDITIONAL_CXX_FLAGS MITK_ADDITIONAL_CXX_FLAGS_DEBUG MITK_ADDITIONAL_CXX_FLAGS_RELEASE) set(MITK_ADDITIONAL_EXE_LINKER_FLAGS "" CACHE STRING "Additional exe linker flags for MITK") set(MITK_ADDITIONAL_SHARED_LINKER_FLAGS "" CACHE STRING "Additional shared linker flags for MITK") set(MITK_ADDITIONAL_MODULE_LINKER_FLAGS "" CACHE STRING "Additional module linker flags for MITK") mark_as_advanced(MITK_ADDITIONAL_EXE_LINKER_FLAGS MITK_ADDITIONAL_SHARED_LINKER_FLAGS MITK_ADDITIONAL_MODULE_LINKER_FLAGS) #----------------------------------------------------------------------------- # MITK Configure #----------------------------------------------------------------------------- if(MITK_INITIAL_CACHE_FILE) set(mitk_initial_cache_arg -C "${MITK_INITIAL_CACHE_FILE}") endif() set(mitk_optional_cache_args ) foreach(type RUNTIME ARCHIVE LIBRARY) if(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY) list(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}) endif() endforeach() # Optional python variables if(MITK_USE_Python3) list(APPEND mitk_optional_cache_args -DMITK_USE_Python3:BOOL=${MITK_USE_Python3} "-DPython3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE}" "-DPython3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIRS}" "-DPython3_LIBRARY:FILEPATH=${Python3_LIBRARY}" "-DPython3_STDLIB:FILEPATH=${Python3_STDLIB}" "-DPython3_SITELIB:FILEPATH=${Python3_SITELIB}" ) endif() if(OPENSSL_ROOT_DIR) list(APPEND mitk_optional_cache_args "-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}" ) endif() if(CMAKE_FRAMEWORK_PATH) list(APPEND mitk_optional_cache_args "-DCMAKE_FRAMEWORK_PATH:PATH=${CMAKE_FRAMEWORK_PATH}" ) endif() if(Eigen_INCLUDE_DIR) list(APPEND mitk_optional_cache_args -DEigen_INCLUDE_DIR:PATH=${Eigen_INCLUDE_DIR} ) endif() # Optional pass through of Doxygen if(DOXYGEN_EXECUTABLE) list(APPEND mitk_optional_cache_args -DDOXYGEN_EXECUTABLE:FILEPATH=${DOXYGEN_EXECUTABLE} ) endif() if(MITK_DOXYGEN_BUILD_ALWAYS) list(APPEND mitk_optional_cache_args -DMITK_DOXYGEN_BUILD_ALWAYS:BOOL=${MITK_DOXYGEN_BUILD_ALWAYS} ) endif() set(proj MITK-Configure) ExternalProject_Add(${proj} LIST_SEPARATOR ${sep} DOWNLOAD_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_GENERATOR_PLATFORM ${gen_platform} CMAKE_CACHE_ARGS # --------------- Build options ---------------- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} "-DCMAKE_PREFIX_PATH:PATH=${ep_prefix};${CMAKE_PREFIX_PATH}" "-DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH}" "-DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH}" # --------------- Compile options ---------------- -DCMAKE_CXX_EXTENSIONS:STRING=${CMAKE_CXX_EXTENSIONS} -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED} -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${MITK_ADDITIONAL_C_FLAGS}" "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_ADDITIONAL_CXX_FLAGS}" # debug flags "-DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} ${MITK_ADDITIONAL_CXX_FLAGS_DEBUG}" "-DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} ${MITK_ADDITIONAL_C_FLAGS_DEBUG}" # release flags "-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} ${MITK_ADDITIONAL_CXX_FLAGS_RELEASE}" "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} ${MITK_ADDITIONAL_C_FLAGS_RELEASE}" # relwithdebinfo -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} # link flags "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} ${MITK_ADDITIONAL_EXE_LINKER_FLAGS}" "-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} ${MITK_ADDITIONAL_SHARED_LINKER_FLAGS}" "-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ${MITK_ADDITIONAL_MODULE_LINKER_FLAGS}" # Output directories -DMITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY} -DMITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY} -DMITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY} # ------------- Boolean build options -------------- ${mitk_superbuild_boolean_args} ${mitk_optional_cache_args} -DMITK_USE_SUPERBUILD:BOOL=OFF -DMITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION} -DMITK_FAST_TESTING:BOOL=${MITK_FAST_TESTING} -DMITK_XVFB_TESTING:BOOL=${MITK_XVFB_TESTING} -DMITK_XVFB_TESTING_COMMAND:STRING=${MITK_XVFB_TESTING_COMMAND} -DCTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS} # ----------------- Miscellaneous --------------- -DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH} -DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH} -DMITK_CTEST_SCRIPT_MODE:STRING=${MITK_CTEST_SCRIPT_MODE} -DMITK_SUPERBUILD_BINARY_DIR:PATH=${MITK_BINARY_DIR} -DMITK_MODULES_TO_BUILD:INTERNAL=${MITK_MODULES_TO_BUILD} -DMITK_WHITELIST:STRING=${MITK_WHITELIST} -DMITK_WHITELISTS_EXTERNAL_PATH:STRING=${MITK_WHITELISTS_EXTERNAL_PATH} -DMITK_WHITELISTS_INTERNAL_PATH:STRING=${MITK_WHITELISTS_INTERNAL_PATH} -DMITK_EXTENSION_DIRS:STRING=${MITK_EXTENSION_DIRS} -DMITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES} -DMITK_ACCESSBYITK_FLOATING_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES} -DMITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES} -DMITK_ACCESSBYITK_VECTOR_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} -DMITK_ACCESSBYITK_DIMENSIONS:STRING=${MITK_ACCESSBYITK_DIMENSIONS} -DMITK_CUSTOM_REVISION_DESC:STRING=${MITK_CUSTOM_REVISION_DESC} # --------------- External project options --------------- -DMITK_DATA_DIR:PATH=${MITK_DATA_DIR} -DMITK_EXTERNAL_PROJECT_PREFIX:PATH=${ep_prefix} -DCppMicroServices_DIR:PATH=${CppMicroServices_DIR} -DDCMTK_CMAKE_DEBUG_POSTFIX:STRING=${DCMTK_CMAKE_DEBUG_POSTFIX} -DBOOST_ROOT:PATH=${BOOST_ROOT} -DBOOST_LIBRARYDIR:PATH=${BOOST_LIBRARYDIR} -DMITK_USE_Boost_LIBRARIES:STRING=${MITK_USE_Boost_LIBRARIES} -DQt5_DIR:PATH=${Qt5_DIR} CMAKE_ARGS ${mitk_initial_cache_arg} ${MAC_OSX_ARCHITECTURE_ARGS} ${mitk_superbuild_ep_args} SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} BINARY_DIR ${CMAKE_BINARY_DIR}/MITK-build BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS MITK-Utilities ) mitkFunctionInstallExternalCMakeProject(${proj}) #----------------------------------------------------------------------------- # MITK #----------------------------------------------------------------------------- if(CMAKE_GENERATOR MATCHES ".*Makefiles.*") set(mitk_build_cmd "$(MAKE)") else() set(mitk_build_cmd ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/MITK-build --config ${CMAKE_CFG_INTDIR}) endif() if(NOT DEFINED SUPERBUILD_EXCLUDE_MITKBUILD_TARGET OR NOT SUPERBUILD_EXCLUDE_MITKBUILD_TARGET) set(MITKBUILD_TARGET_ALL_OPTION "ALL") else() set(MITKBUILD_TARGET_ALL_OPTION "") endif() add_custom_target(MITK-build ${MITKBUILD_TARGET_ALL_OPTION} COMMAND ${mitk_build_cmd} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build DEPENDS MITK-Configure ) #----------------------------------------------------------------------------- # Custom target allowing to drive the build of the MITK project itself #----------------------------------------------------------------------------- add_custom_target(MITK COMMAND ${mitk_build_cmd} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build ) diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt index 1b090440c7..c1f812e720 100644 --- a/Utilities/CMakeLists.txt +++ b/Utilities/CMakeLists.txt @@ -1,20 +1,7 @@ SUPPRESS_ALL_WARNINGS() -# most stuff of these uses itk_zlib.h (via mitkIpPic.h) -find_package(ITK) -set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) -include(${ITK_USE_FILE}) - -# some legacy util files include in the old style with prefixed directory, -# like #include <ipPic/mitkIpPic.h> -include_directories(.) - -add_subdirectory(IpPic) -add_subdirectory(IpFunc) -add_subdirectory(IpSegmentation) - set(MITK_MODULE_NAME_REGEX_MATCH ) set(MITK_MODULE_NAME_REGEX_NOT_MATCH ) set(MITK_MODULE_NAME_PREFIX ) add_subdirectory(mbilog) add_subdirectory(qtsingleapplication) diff --git a/Utilities/IpFunc/AddC.c b/Utilities/IpFunc/AddC.c deleted file mode 100644 index a86c56448d..0000000000 --- a/Utilities/IpFunc/AddC.c +++ /dev/null @@ -1,250 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function adds a constant to an image - */ - -/** @brief adds a constant to an image - * @param pic_old pointer to the first image - * @param value constant which is added to image - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c mitkIpFuncNoKeep : image data type could be changed - * @arg @c mitkIpFuncKeep : image data type of original pictures - * is kept (if there will be an - * over-/underflow the max. or min. - * possible greyvalue is taken) - * @param pic_return - memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the new image - * - * @author Antje Schroeder - * @date 01.08.95 - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncAddC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define ADDC( type_1, pic_1, pic_new, value ) \ -{ \ - mitkIpPicFORALL_3 ( ADDC2, pic_new, pic_1, type_1, value ); \ -} \ - - -#define ADDC2( type_n, pic_new, pic_1, type_1, value ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type_n * ) pic_new->data ) [i] = ( type_n ) \ - ( value + (( type_1 * ) pic_1->data ) [i] ); \ - } \ -} - -#define ADDC3( type_n, pic_1, pic_new, value ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - type_n help; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = (( type_n * ) pic_1->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( max_gv > ( mitkIpFloat8_t ) help + value ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help + value ) ? \ - ( (type_n)help + (type_n)value ) : ( type_n ) min_gv ) :\ - ( type_n ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncAddC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check value */ - - if ( value == 0. ) return ( pic_old ); - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_old, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = max1 + value; - smin = min1 + value; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_old->type == mitkIpPicInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicUInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || smin < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - if ( keep == mitkIpFuncNoKeep ) - mitkIpPicFORALL_2 ( ADDC, pic_old, pic_new, value ) - else if ( keep == mitkIpFuncKeep ) - mitkIpPicFORALL_2 ( ADDC3, pic_old, pic_new, value ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/AddI.c b/Utilities/IpFunc/AddI.c deleted file mode 100644 index bc082023ed..0000000000 --- a/Utilities/IpFunc/AddI.c +++ /dev/null @@ -1,279 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file -* this function adds two images -*/ - -/** @brief adds two images - * @param pic_1 pointer to the first image - * @param pic_2 pointer to the second image - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c mitkIpFuncNoKeep : image data type could be changed - * @arg @c mitkIpFuncKeep : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncAddI ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncAddI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/* definition of macros */ - -#define ADDI( type_1, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpPicFORALL_3 ( ADDI2, pic_new, pic_1, pic_2, type_1 ); \ -} \ - - -#define ADDI2( type_n, pic_new, pic_1, pic_2, type_1 ) \ -{ \ - mitkIpUInt4_t i; \ - mitkIpUInt4_t no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type_n * ) pic_new->data ) [i] = ( type_n ) \ - ( (( type_1 * ) pic_1->data ) [i] + \ - (( type_1 * ) pic_2->data ) [i] ); \ - } \ -} - -#define ADDI3( type_n, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpUInt4_t i; \ - mitkIpUInt4_t no_elem; \ - type_n help; \ - type_n help2; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = (( type_n * ) pic_1->data ) [i]; \ - help2 = (( type_n * ) pic_2->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( max_gv > ( mitkIpFloat8_t ) help + ( mitkIpFloat8_t ) help2 ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help + ( mitkIpFloat8_t ) help2 ) ? \ - ( (type_n)help + (type_n)help2 ) : ( type_n ) min_gv ) :\ - ( type_n ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncAddI ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t min2, max2; /* extreme greyvalues of 2. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - - - /* ckeck whether data are correct */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check whether images have the same size */ - - if ( ( pic_1->type != pic_2->type ) || ( pic_1->bpe != pic_2->bpe ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - if ( pic_1->dim == pic_2->dim ) - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - { - if ( pic_1->n[i] != pic_2->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_1->type, pic_1->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( mitkIpFuncExtr ( pic_2, &min2, &max2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = max1 + max2; - smin = min1 + min2; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_1->type == mitkIpPicInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicUInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || smin < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - if ( keep == mitkIpFuncNoKeep ) - mitkIpPicFORALL_2 ( ADDI, pic_1, pic_2, pic_new ) - else if ( keep == mitkIpFuncKeep ) - mitkIpPicFORALL_2 ( ADDI3, pic_1, pic_2, pic_new ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_1); - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/AddSl.c b/Utilities/IpFunc/AddSl.c deleted file mode 100644 index 2c8ca6a6cd..0000000000 --- a/Utilities/IpFunc/AddSl.c +++ /dev/null @@ -1,251 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file -* this function adds all slices of an image -*/ - -/**this function adds all slices of an image - * @param pic pointer to the 3D image - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c mitkIpFuncNoKeep : image data type could be changed - * @arg @c mitkIpFuncKeep: image data type of original pictures - * is kept (if there will be an - * over-/underflow the max. or min. - * possible greyvalue is taken) - * - * @RETURN pointer to the new 2D image - * - * @AUTHOR Antje Schroeder - * @DATE 01.08.95 - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncAddSl( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t keep ); - -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define ADDSL( type_old, pic_old, pic_new ) \ -{ \ - mitkIpPicFORALL_2 ( ADDSL2, pic_new, pic_old, type_old ); \ -} - -#define ADDSL2( type_new, pic_new, pic_old, type_old ) \ -{ \ - mitkIpUInt4_t i, j; /* loop counter */ \ - mitkIpUInt4_t off_old; /* offset in 3D image */ \ - mitkIpUInt4_t slice_size; /* size of one image slice */ \ - \ - slice_size = _mitkIpPicElements ( pic_new ); \ - for ( i = 0; i < pic_old->n[2]; i++ ) \ - { \ - off_old = i * slice_size; \ - for ( j = 0; j < slice_size; j++ ) \ - (( type_new *)pic_new->data)[j] = \ - (( type_new *)pic_new->data)[j] + \ - ( type_new )(( type_old *)pic_old->data)[j+off_old]; \ - } \ -} - -#define ADDSL3( type, pic_old, pic_new ) \ -{ \ - mitkIpUInt4_t i, j; /* loop counter */ \ - mitkIpUInt4_t off_old; /* offset in 3D image */ \ - mitkIpUInt4_t slice_size; /* size of one image slice */ \ - type help, help2; \ - \ - slice_size = _mitkIpPicElements ( pic_new ); \ - for ( i = 0; i < pic_old->n[2]; i++ ) \ - { \ - off_old = i * slice_size; \ - for ( j = 0; j < slice_size; j++ ) \ - { \ - help = (( type *)pic_old->data)[j+off_old]; \ - help2 = (( type *)pic_new->data)[j]; \ - (( type *)pic_new->data)[j] = \ - ( max_gv > ( mitkIpFloat8_t ) help + help2 ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help + help2 ) ? \ - ( (type)help + (type)help2 ) : (type) min_gv ) : \ - (type) max_gv; \ - } \ - } \ -} - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncAddSl( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t keep ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_old, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = pic_old->n[2] * max1; - smin = pic_old->n[2] * min1; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_old->type == mitkIpPicInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicUInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || smin < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_new->dim = 2; - pic_new->n[2] = 0; - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe/8 ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - if ( keep == mitkIpFuncNoKeep ) - mitkIpPicFORALL_1 ( ADDSL, pic_old, pic_new ) - else if ( keep == mitkIpFuncKeep ) - mitkIpPicFORALL_1 ( ADDSL3, pic_old, pic_new ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/And.c b/Utilities/IpFunc/And.c deleted file mode 100644 index 32a380eed2..0000000000 --- a/Utilities/IpFunc/And.c +++ /dev/null @@ -1,145 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file -* this function connects two images using AND -*/ - -/** @brief connects two images using AND - * @param pic_1 pointer to the first image - * @param pic_2 pointer to the second image - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the new image - * - * @author Antje Schroeder - * @date 08.06.95 - * - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - - mitkIpPicDescriptor *mitkIpFuncAnd ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncAnd\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of invert-macro */ - -#define AND( type, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpUInt4_t i; \ - \ - \ - for ( i = 0; i < _mitkIpPicElements ( pic_1 ); i++ ) \ - { \ - (( type * ) pic_new->data ) [i] = \ - ( (( type * ) pic_1->data ) [i] && \ - (( type * ) pic_2->data ) [i] ); \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - - - mitkIpPicDescriptor *mitkIpFuncAnd ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpPicDescriptor *pic_return ) - { - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt4_t i; /* loop index */ - - /* check whether images have the same size */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( ( pic_1->type != pic_2->type ) || ( pic_1->bpe != pic_2->bpe ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - if ( pic_1->dim == pic_2->dim ) - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - { - if ( pic_1->n[i] != pic_2->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - - /* allocate new iumage */ - - pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to connect two images using AND */ - - mitkIpPicFORALL_2 ( AND, pic_1, pic_2, pic_new ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_1); - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/Border.c b/Utilities/IpFunc/Border.c deleted file mode 100644 index c8667782c2..0000000000 --- a/Utilities/IpFunc/Border.c +++ /dev/null @@ -1,235 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * This function sets all border pixels to zero. - */ - -/** @brief sets all border pixels to zero. - * - * The size of the border is calculated using the size of the single - * dimensions of the mask (dim/2). - * - * @param pic_old input image - * @param mask mask which is used to calculate the border size - * @param pic_rtn memory used for result image (if pic_rtn == NULL new - * memory is allocated. - * - * @return pic_new result image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncBorder ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - mitkIpPicDescriptor *pic_rtn ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - /* definition of macros */ - - -#define BORDER( type, pic, size ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t anf[_mitkIpPicNDIM]; /* */ \ - mitkIpUInt4_t end[_mitkIpPicNDIM]; /* */ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - \ - \ - for ( i = 0; i < pic->dim; i++ ) \ - { \ - anf[i] = 0; \ - end[i] = pic->n[i]; \ - } \ - for ( i = pic->dim; i < _mitkIpPicNDIM; i++ ) \ - { \ - anf[i] = 0; \ - end[i] = 1; \ - pic->n[i] = 1; \ - } \ - for ( i = 0; i < pic->dim; i++ ) \ - { \ - anf[i] = pic->n[i] - mask->n[i]/2; \ - end[i] = mask->n[i]/2; \ - for ( ind[7] = 0; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = 0; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = 0; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = 0; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = 0; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = 0; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = 0; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - for ( ind[0] = 0; ind[0] < end[0]; ind[0]++ ) \ - { \ - (( type * ) pic_new->data )[off[1]] = 0; \ - off[1]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - for ( ind[7] = anf[7]; ind[7] < pic->n[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = anf[6]; ind[6] < pic->n[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = anf[5]; ind[5] < pic->n[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = anf[4]; ind[4] < pic->n[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = anf[3]; ind[3] < pic->n[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = anf[2]; ind[2] < pic->n[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = anf[1]; ind[1] < pic->n[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1] + anf[0]; \ - for ( ind[0] = anf[0]; ind[0] < pic->n[0]; ind[0]++ ) \ - { \ - (( type * ) pic_new->data )[off[0]] = 0; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - end[i] = pic->n[i]; \ - anf[i] = 0; \ - } \ -} - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncBorder ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - mitkIpPicDescriptor *pic_rtn ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - - /* check whEther data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( mask ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim != mask->dim ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < pic_old->dim; i++ ) - { - if ( pic_old->n[i] <= mask->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - - /* create a new picture, copy the header, allocate memory */ - -/* pic_new = _mitkIpFuncMalloc ( pic_old, pic_rtn, mitkIpOVERWRITE );*/ - if ( pic_rtn == NULL ) - pic_new = mitkIpPicClone ( pic_old ); - else - pic_new = pic_old; - - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - size[pic_old->dim] = 0; - - mitkIpPicFORALL_1 ( BORDER, pic_old, size ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif diff --git a/Utilities/IpFunc/BorderX.c b/Utilities/IpFunc/BorderX.c deleted file mode 100644 index 2fbe4d386d..0000000000 --- a/Utilities/IpFunc/BorderX.c +++ /dev/null @@ -1,251 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * This function sets all border pixels to a spezified value. - */ - -/** @brief sets all border pixels to a spezified value. - * - * The size of the border is calculated using the size of the single - * dimensions of the mask (dim/2) - * - * - * @param pic_old input image - * @param mask mask which is used to calculate the border size - * @param value border value - * @param pic_rtn memory used for result image (if pic_rtn == NULL new - * memory is allocated. - * - * @return pic_new result image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncBorderX ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - mitkIpFloat8_t value, - mitkIpPicDescriptor *pic_rtn ); - - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - -#define BORDER( type, pic, size, value ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t anf[_mitkIpPicNDIM]; /* */ \ - mitkIpUInt4_t end[_mitkIpPicNDIM]; /* */ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - \ - \ - for ( i = 0; i < pic->dim; i++ ) \ - { \ - anf[i] = 0; \ - end[i] = pic->n[i]; \ - } \ - for ( i = pic->dim; i < _mitkIpPicNDIM; i++ ) \ - { \ - anf[i] = 0; \ - end[i] = 1; \ - pic->n[i] = 1; \ - } \ - for ( i = 0; i < pic->dim; i++ ) \ - { \ - anf[i] = pic->n[i] - mask->n[i]/2; \ - end[i] = mask->n[i]/2; \ - for ( ind[7] = 0; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = 0; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = 0; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = 0; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = 0; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = 0; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = 0; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - for ( ind[0] = 0; ind[0] < end[0]; ind[0]++ ) \ - { \ - (( type * ) pic_new->data )[off[1]] = ( type ) value; \ - off[1]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - for ( ind[7] = anf[7]; ind[7] < pic->n[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = anf[6]; ind[6] < pic->n[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = anf[5]; ind[5] < pic->n[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = anf[4]; ind[4] < pic->n[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = anf[3]; ind[3] < pic->n[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = anf[2]; ind[2] < pic->n[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = anf[1]; ind[1] < pic->n[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1] + anf[0]; \ - for ( ind[0] = anf[0]; ind[0] < pic->n[0]; ind[0]++ ) \ - { \ - (( type * ) pic_new->data )[off[0]] = ( type ) value; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - end[i] = pic->n[i]; \ - anf[i] = 0; \ - }\ -} - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncBorderX ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - mitkIpFloat8_t value, - mitkIpPicDescriptor *pic_rtn ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - mitkIpFloat8_t max_gv, min_gv; - - /* check whEther data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( mask ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( ( pic_old->dim != mask->dim ) || ( mask->dim > 3 ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < pic_old->dim; i++ ) - { - if ( pic_old->n[i] <= mask->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( ( value > max_gv ) || ( value < min_gv ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* create a new picture, copy the header, allocate memory */ - - /* pic_new = _mitkIpFuncMalloc ( pic_old, pic_rtn, mitkIpOVERWRITE );*/ - if ( pic_rtn == NULL ) - pic_new = mitkIpPicClone ( pic_old ); - else - pic_new = pic_old; - - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - size[pic_old->dim] = 0; - - mitkIpPicFORALL_2 ( BORDER, pic_old, size, value ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/Box.c b/Utilities/IpFunc/Box.c deleted file mode 100644 index 465d8b810e..0000000000 --- a/Utilities/IpFunc/Box.c +++ /dev/null @@ -1,98 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * This Function calulates the bounding box - */ - - -/** This Function calulates the bounding box - * - * @param pic_old binary image: contains the region of interest - * @param beg pointer to left upper corner - * @param end pointer to right lower corner - * - * @return @arg @c mitkIpFuncOK no error occured - * @arg @c mitkIpFuncERROR error occured (description of error in mitkIpFuncErrno) - * - * @warning this version could only be used for 2D and 3D images, in - * later version it should be possible to use it for every dimension - * - * AUTHOR & DATE - */ - -#include "mitkIpFuncP.h" - -mitkIpUInt4_t mitkIpFuncBox ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ) ; - -#ifndef DOXYGEN_IGNORE - -mitkIpUInt4_t mitkIpFuncBox ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ) -{ - - /* check data */ - - if ( pic_old->dim == 2 ) - { - _mitkIpFuncBox2d ( pic_old, beg, end ); - if ( mitkIpFuncErrno > mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - } - else if ( pic_old->dim == 3 ) - { - _mitkIpFuncBox3d ( pic_old, beg, end ); - if ( mitkIpFuncErrno > mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - return ( mitkIpFuncOK ); -} - -#endif - diff --git a/Utilities/IpFunc/Box2d.c b/Utilities/IpFunc/Box2d.c deleted file mode 100644 index 3ea0276657..0000000000 --- a/Utilities/IpFunc/Box2d.c +++ /dev/null @@ -1,169 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * _mitkIpFuncBox2d - *--------------------------------------------------------------------- - * DESCRIPTION - * This Function calulates the bounding box - * - * FUNCTION DECLARATION - * - * PARAMETERS - * pic_old - binary image: contains the region of interest - * beg - pointer to left upper corner - * end - pointer to right lower corner - * - * RETURN VALUES - * mitkIpFuncOK - no error occured - * mitkIpFuncERROR - error occured (description of error in mitkIpFuncErrno) - * - * UPDATES - * this version could only be used for 3D images, in later version - * it should be possible to use it for every dimension - * - * AUTHOR & DATE - * Antje Schroeder 08.01.97 - * - *--------------------------------------------------------------------- - */ -/* include Files */ - -#include "mitkIpFuncP.h" - -/* definition of Box-macro */ - -#define BOX( type, pic, help_beg, help_end ) \ -{ \ - mitkIpInt4_t i, j, l; \ - mitkIpUInt4_t offset; \ - mitkIpInt4_t end_x, end_y; \ - mitkIpBool_t found; \ - \ - for ( l = 0; l < (mitkIpInt4_t) pic->dim; l++ ) \ - { \ - i = 0; \ - found = mitkIpFalse; \ - end_y = pic->n[order[l*pic->dim+1]]; \ - while (( i < end_y ) && ( !found ) ) \ - { \ - j = 0; \ - end_x = pic->n[order[l*pic->dim]]; \ - while (( j < end_x ) && ( !found ) ) \ - { \ - offset = j * size[order[l * pic->dim]] + \ - i * size[order[l * pic->dim + 1]]; \ - if ( (( type * )pic->data )[ offset ] ) \ - { \ - found = mitkIpTrue; \ - help_beg[1-l] = i; \ - } \ - j++; \ - } \ - i++; \ - } \ - \ - i = pic->n[order[l*pic->dim+1]] -1; \ - found = mitkIpFalse; \ - while (( i >= 0 ) && ( !found ) ) \ - { \ - j = pic->n[order[l*pic->dim]] -1; \ - while (( j >= 0 ) && ( !found ) ) \ - { \ - offset = j * size[order[l * pic->dim]] + \ - i * size[order[l * pic->dim + 1]]; \ - if ( (( type * )pic->data )[ offset ] ) \ - { \ - found = mitkIpTrue; \ - help_end[1-l] = i; \ - } \ - j--; \ - } \ - i--; \ - } \ - } \ - \ - \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpUInt4_t _mitkIpFuncBox2d ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ) -{ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* size of each direction */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t *help_beg, *help_end; - mitkIpUInt4_t order[] = { 0, 1, - 1, 0 }; - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( pic_old->dim > 2 ) /* just in for the first version */ - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialization of vectors */ - - size[0] = 1; - for ( i = 1; i < pic_old->dim; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - - /* allocation of result vectors */ - - *beg = ( mitkIpUInt4_t * ) malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - help_beg = *beg; - *end = ( mitkIpUInt4_t * ) malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - help_end = *end; - - mitkIpPicFORALL_2 ( BOX, pic_old, help_beg, help_end ); - - return ( mitkIpFuncOK ); -} diff --git a/Utilities/IpFunc/Box3d.c b/Utilities/IpFunc/Box3d.c deleted file mode 100644 index 30eb31558f..0000000000 --- a/Utilities/IpFunc/Box3d.c +++ /dev/null @@ -1,186 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * _mitkIpFuncBox3d - *--------------------------------------------------------------------- - * DESCRIPTION - * This Function calulates the bounding box - * - * FUNCTION DECLARATION - * - * PARAMETERS - * pic_old - binary image: contains the region of interest - * beg - pointer to left upper corner - * end - pointer to right lower corner - * - * RETURN VALUES - * mitkIpFuncOK - no error occured - * mitkIpFuncERROR - error occured (description of error in mitkIpFuncErrno) - * - * UPDATES - * this version could only be used for 3D images, in later version - * it should be possible to use it for every dimension - * - * AUTHOR & DATE - * Antje Schroeder 08.01.97 - * - *--------------------------------------------------------------------- - */ -/* include Files */ - -#include "mitkIpFuncP.h" - -/* definition of Box-macro */ - -#define BOX3( type, pic, help_beg, help_end, n, size ) \ -{ \ - mitkIpUInt4_t offset1, offset2; \ - \ - for ( l = 0; l < pic->dim; l++ ) \ - { \ - n[l] = pic->n[l]; \ - } \ - \ - for ( l = 0; l < pic->dim; l++ ) \ - { \ - stop = mitkIpFalse; \ - stop_beg = mitkIpFalse; \ - stop_end = mitkIpFalse; \ - k = 0; \ - while ( k < n[order[2+pic_old->dim*l]] && ( !stop ) ) \ - { \ - j = 0; \ - while ( j < n[order[1+pic_old->dim*l]] && ( !stop ) ) \ - { \ - i = 0; \ - while ( i < n[order[pic_old->dim*l]] && ( !stop ) ) \ - { \ - offset1 = i * size[order[0+pic_old->dim*l]] + \ - j * size[order[1+pic_old->dim*l]] + \ - k * size[order[2+pic_old->dim*l]]; \ - \ - offset2 = ( n[order[0+pic_old->dim*l]] - i - 1 ) * \ - size[order[0+pic_old->dim*l]] + \ - ( n[order[1+pic_old->dim*l]] - j - 1 ) * \ - size[order[1+pic_old->dim*l]] + \ - ( n[order[2+pic_old->dim*l]] - k - 1 ) * \ - size[order[2+pic_old->dim*l]]; \ - \ - if ( ( stop_beg == mitkIpFalse ) && \ - ( ( type * )pic->data )[offset1] ) \ - { \ - help_beg[order[2+pic->dim*l]] = k; \ - stop_beg = mitkIpTrue; \ - } \ - if ( ( stop_end == mitkIpFalse ) && \ - ( ( type * )pic->data )[offset2] ) \ - { \ - help_end[order[2+pic->dim*l]] = \ - n[order[2+pic->dim*l]] - k; \ - stop_end = mitkIpTrue; \ - } \ - if ( stop_beg && stop_end ) stop = mitkIpTrue; \ - i++; \ - } \ - j++; \ - } \ - k++; \ - } \ - } \ - \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpUInt4_t _mitkIpFuncBox3d ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ) -{ - - mitkIpUInt4_t n[_mitkIpPicNDIM]; /* number of pixels in each */ - /* dimension */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* size of each direction */ - mitkIpUInt4_t i, j, k, l; /* loop index */ - mitkIpUInt4_t order[] = { 0, 1, 2, /* order of indizes for each */ - 2, 1, 0, /* direction */ - 0, 2, 1 }; - mitkIpBool_t stop, stop_beg, stop_end;/* finish calculation? */ - mitkIpUInt4_t *help_beg, *help_end; - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( pic_old->dim > 3 ) /* just in for the first version */ - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of vectors */ - - size[0] = 1; - n[0] = pic_old->n[0]; - for ( i = 1; i < pic_old->dim; i++ ) - { - n[i] = pic_old->n[i]; - size[i] = size[i-1] * pic_old->n[i-1]; - } - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 1; - - /* allocation of result vectors */ - - *beg = ( mitkIpUInt4_t * ) malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - help_beg = *beg; - *end = ( mitkIpUInt4_t * ) malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - help_end = *end; - - mitkIpPicFORALL_4 ( BOX3, pic_old, help_beg, help_end, n, size ); - - return ( mitkIpFuncOK ); -} diff --git a/Utilities/IpFunc/CMakeLists.txt b/Utilities/IpFunc/CMakeLists.txt deleted file mode 100644 index ba6d890100..0000000000 --- a/Utilities/IpFunc/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(_options NO_INIT GCC_DEFAULT_VISIBILITY) -if(MITK_WIN32_FORCE_STATIC) - list(APPEND _options FORCE_STATIC) -endif() - -mitk_create_module( - DEPENDS PUBLIC MitkIpPic - ${_options} - C_MODULE - WARNINGS_NO_ERRORS -) - -if(UNIX) - target_link_libraries(${MODULE_TARGET} PRIVATE m) -endif(UNIX) diff --git a/Utilities/IpFunc/Canny.c b/Utilities/IpFunc/Canny.c deleted file mode 100644 index 8f33cf1c42..0000000000 --- a/Utilities/IpFunc/Canny.c +++ /dev/null @@ -1,525 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function performs an edge detection using the Canny operator - */ - -/** @brief performs an edge detection using the Canny operator. - * - * The Canny-operator needs quite a lot memory. This can cause problems - * with large images. - * - * @param pic_old pointer to original image - * @param dim_mask dimension of mask - * @param len_mask length of filtering mask - * @param threshold threshold to decide whether an edge belongs to - * the image or not - * @param border tells how the edge is transformed - * - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to minimal greyvalue - * - * @return pointer to transformed iamge ( of type mitkIpFloat8_t ) - * - * AUTHOR & DATE - - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncCanny( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpUInt4_t len_mask, - mitkIpFloat8_t threshold, - mitkIpFuncFlagI_t border ) ; - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncCanny\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/* definition of macros */ - -#define CANNY0( type_o, pic_old, pic_help1, pic_help2, pic_help3, m ) \ -{ \ - mitkIpPicFORALL_5( CANNY1, pic_help1, pic_old, pic_help2, pic_help3, m, type_o );\ -} - -#define CANNY1( type_h, pic_help1, pic_old, pic_help2, pic_help3, m, type_o )\ -{ \ - mitkIpUInt4_t i, j; /* loop index */ \ - mitkIpUInt4_t len_m; \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* offset vector */ \ - mitkIpUInt4_t off_m; /* offset in mask */ \ - mitkIpFloat8_t help[_mitkIpPicNDIM]; \ - mitkIpFloat8_t help2; \ - \ - \ - /* transformation of image */ \ - \ - len_m = m->length / dim_mask; \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = ind[7] * size[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = ind[6] * size[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = ind[5] * size[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = ind[4] * size[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = ind[3] * size[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = ind[2] * size[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = ind[1] * size[1] + off[2]; \ - off[0] = beg[0] + off[1]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - for ( i = 0; i < dim_mask; i++ ) help[i] = 0; \ - off_m = 0; \ - for ( i = 0; i < dim_mask; i++ ) \ - for ( j = 0; j < len_m; j++ ) \ - { \ - help[i] = ( mitkIpFloat8_t )m->mask_vekt[off_m] * \ - (( type_o * ) pic_old->data ) \ - [off[0]+m->off_vekt[off_m]] + help[i];\ - off_m++; \ - } \ - help2 = 0; \ - for ( i = 0; i < dim_mask; i++ ) \ - { \ - (( type_h * )pic_help1->data )[off[0]+off_p[i]] = \ - ( type_h ) help[i];\ - help2 = help2 + help[i] * help[i]; \ - } \ - (( type_h * ) pic_help2->data )[off[0]] = \ - ( type_h ) help2; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - -#define CANNY2( type_h, pic_help2, pic_help3, pic_help1, m ) \ -{ \ - mitkIpUInt4_t i, j; /* loop index */ \ - mitkIpUInt4_t len_m; \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* offset vector */ \ - mitkIpUInt4_t off_m; /* offset in mask */ \ - mitkIpFloat8_t help[_mitkIpPicNDIM]; \ - mitkIpFloat8_t help2; \ - \ - \ - /* transformation of image */ \ - \ - len_m = m->length / dim_mask; \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = ind[7] * size[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = ind[6] * size[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = ind[5] * size[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = ind[4] * size[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = ind[3] * size[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = ind[2] * size[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = ind[1] * size[1] + off[2]; \ - off[0] = beg[0] + off[1]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - for ( i = 0; i < dim_mask; i++ ) help[i] = 0; \ - off_m = 0; \ - for ( i = 0; i < dim_mask; i++ ) \ - for ( j = 0; j < len_m; j++ ) \ - { \ - help[i] = help[i] + ( mitkIpFloat8_t )m->mask_vekt[off_m] *\ - (( type_h * ) pic_help2->data ) \ - [off[0]+m->off_vekt[off_m]];\ - off_m++; \ - } \ - help2 = 0; \ - for ( i = 0; i < dim_mask; i++ ) \ - { \ - help2 = help[i] * (( type_h * )pic_help1->data ) \ - [off[0]+ off_p[i]] + help2;\ - } \ - (( type_h * ) pic_help3->data )[off[0]] = ( type_h )help2;\ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - -#define CANNY3( type_h, pic_help2, pic_help3, threshold ) \ -{ \ - mitkIpUInt4_t i; /* loop variable */ \ - mitkIpUInt4_t no_elem; /* number of pixels */ \ - \ - no_elem = _mitkIpPicElements ( pic_help2 ); \ - for ( i = 0; i < no_elem; i++ ) \ - (( type_h * )pic_help3->data )[i] = \ - ( ( (( type_h * ) pic_help3->data )[i] != 0 ) && \ - ( (( type_h * ) pic_help2->data )[i] > threshold ) ) ? \ - 1 : 0; \ -} - -/* ----------------------------------------------------------------- */ -/* -** mitkIpFuncCanny -*/ -/* ----------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncCanny( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpUInt4_t len_mask, - mitkIpFloat8_t threshold, - mitkIpFuncFlagI_t border ) -{ - #include "gradient.h" - - mitkIpPicDescriptor *pic_help1; /* pointer to image */ - mitkIpPicDescriptor *pic_help2; /* pointer to image */ - mitkIpPicDescriptor *pic_help3; /* pointer to image */ - mitkIpPicDescriptor *pic_help4; /* pointer to image */ - mitkIpPicDescriptor *pic_new; /* pointer to image */ - mitkIpPicDescriptor *pic_mask; /* sobel mask */ - mitkIpUInt4_t pos; /* position in m->off_vekt */ - mitkIpUInt4_t i, j; /* loopindex */ - mitkIpUInt4_t off_mask; /* loopindex */ - mitkIpFuncMasc_t *m; /* compressed mask */ - mitkIpInt4_t offset; - mitkIpInt4_t beg[_mitkIpPicNDIM]; - mitkIpInt4_t end[_mitkIpPicNDIM]; - mitkIpInt4_t ind[_mitkIpPicNDIM]; - mitkIpUInt4_t size[_mitkIpPicNDIM]; - mitkIpInt4_t n[_mitkIpPicNDIM]; - mitkIpUInt4_t off_p[_mitkIpPicNDIM]; /* offsets to calculate help1 */ - mitkIpUInt4_t offset_h; /* offset in pic_help1 */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( ( dim_mask < 1 ) || ( dim_mask > 4 ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_old->dim < dim_mask ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of pic_mask */ - - pic_mask = mitkIpPicNew (); - if ( pic_mask == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_mask->type = mitkIpPicInt; - pic_mask->bpe = 16; - pic_mask->dim = dim_mask+1; - for ( i = 0; i < dim_mask; i++ ) - pic_mask->n[i] = 3; - pic_mask->n[dim_mask] = dim_mask; - - if ( dim_mask == 4 ) - pic_mask->data = mask4; - else if ( dim_mask == 3 ) - pic_mask->data = mask3; - else if ( dim_mask == 2 ) - pic_mask->data = mask2; - - /* initialisation of vectors */ - - size [0] = 1; - for ( i = 1; i < pic_old->dim; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - size[i] = 0; - - offset_h = size[pic_old->dim-1] * pic_old->n[pic_old->dim-1]; - - for ( i = 0; i < dim_mask; i++ ) - n[i] = pic_mask->n[i] / 2 + 1; - for ( i = dim_mask; i < _mitkIpPicNDIM; i++ ) - n[i] = 0; - - for ( i = 0; i < dim_mask; i++ ) - { - end[i] = pic_old->n[i] - pic_mask->n[i] / 2; - beg[i] = ( ( pic_mask->n[i] % 2 ) == 1 ) ? - ( pic_mask->n[i] / 2 ) : ( pic_mask->n[i] / 2 - 1 ); - off_p[i] = i * offset_h; - } - for ( i = dim_mask; i < _mitkIpPicNDIM; i++ ) - beg[i] = 0; - - for ( i = dim_mask; i < pic_old->dim; i++ ) - end[i] = pic_old->n[i]; - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - end[i] = beg[i] + 1; - - /* create a new picture, copy the header, allocate memory */ - - pic_help2 = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_help2 == NULL ) - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( pic_old->type == mitkIpPicUInt || pic_old->type == mitkIpPicInt ) - { - pic_help2->type = mitkIpPicFloat; - pic_help2->bpe = 64; - } - pic_help2->data = calloc ( _mitkIpPicElements ( pic_help2 ), pic_help2->bpe / 8 ); - if ( pic_help2->data == NULL ) - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_help1 = mitkIpPicCopyHeader ( pic_help2, NULL ); - if ( pic_help1 == NULL ) - { - pic_help2->data = NULL; - mitkIpPicFree ( pic_help2); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_help1->dim = pic_help2->dim + 1; - pic_help1->n[pic_help1->dim-1] = dim_mask; - pic_help1->data = calloc ( _mitkIpPicElements ( pic_help1 ), pic_help1->bpe / 8 ); - if ( pic_help1->data == NULL ) - { - pic_help2->data = NULL; - mitkIpPicFree ( pic_help2); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_help3 = mitkIpPicCopyHeader ( pic_help2, NULL ); - if ( pic_help3 == NULL ) - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - pic_help1->data = NULL; - mitkIpPicFree ( pic_help1 ); - pic_help2->data = NULL; - mitkIpPicFree ( pic_help2 ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_help3->data = calloc ( _mitkIpPicElements ( pic_help3 ), pic_help3->bpe / 8 ); - if ( pic_help3->data == NULL ) - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - pic_help1->data = NULL; - mitkIpPicFree ( pic_help1 ); - pic_help2->data = NULL; - mitkIpPicFree ( pic_help2 ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate mask-structure */ - - m = malloc ( sizeof ( mitkIpFuncMasc_t ) ); - if ( m == NULL ) - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - pic_help1->data = NULL; - mitkIpPicFree ( pic_help1 ); - pic_help2->data = NULL; - mitkIpPicFree ( pic_help2 ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - m->off_vekt = malloc ( _mitkIpPicElements( pic_mask ) * sizeof ( mitkIpInt4_t ) ); - if ( m->off_vekt == NULL ) - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - pic_help1->data = NULL; - mitkIpPicFree ( pic_help1 ); - pic_help2->data = NULL; - mitkIpPicFree ( pic_help2 ); - pic_help3->data = NULL; - mitkIpPicFree ( pic_help3 ); - free ( m ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - m->mask_vekt = malloc ( _mitkIpPicElements( pic_mask ) * sizeof ( mitkIpFloat8_t ) ); - if ( m->mask_vekt == NULL ) - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - pic_help1->data = NULL; - mitkIpPicFree ( pic_help1 ); - pic_help2->data = NULL; - mitkIpPicFree ( pic_help2 ); - pic_help3->data = NULL; - mitkIpPicFree ( pic_help3 ); - free ( m->off_vekt ); - free ( m ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate offset vector for the compressed mask */ - - m->length = 0; - - off_mask = 0; - for ( i = 0; i < pic_mask->n[dim_mask] ; i++ ) - for ( ind[3] = -1; ind[3] < n[3]; ind[3]++ ) - for ( ind[2] = -1; ind[2] < n[2]; ind[2]++ ) - for ( ind[1] = -1; ind[1] < n[1]; ind[1]++ ) - for ( ind[0] = -1; ind[0] < n[0]; ind[0]++ ) - { - if ( (( mitkIpInt2_t * )pic_mask->data)[off_mask] != 0 ) - { - offset = 0; - for ( j = 0; j < dim_mask; j++ ) - offset = offset + ind[j] * size[j]; - m->off_vekt[m->length] = offset; - m->length++; - } - off_mask++; - } - - /* remove elements that are zero from mask */ - - pos = 0; - for ( i = 0; i < m->length; i++ ) - { - while ( (( mitkIpInt2_t * )pic_mask->data)[pos] == 0 ) pos++; - m->mask_vekt[i] = ( mitkIpFloat8_t )(( mitkIpInt2_t * )pic_mask->data)[pos]; - pos++; - } - - /* smooth image using a binomial filter */ - - pic_new = mitkIpFuncGausF ( pic_old, len_mask, dim_mask, border ); - - /* calculate second derivation */ - - mitkIpPicFORALL_4 ( CANNY0, pic_new, pic_help1, pic_help2, pic_help3, m ); - /* project second derivation to gradient */ - - mitkIpPicFORALL_3 ( CANNY2, pic_help2, pic_help3, pic_help1, m ); - - /* zero crossing */ - - pic_help4 = mitkIpFuncZeroCr ( pic_help3 ); - - mitkIpPicFORALL_2 ( CANNY3, pic_help2, pic_help4, threshold ); - - /* free memory */ - - free ( m->off_vekt ); - free ( m->mask_vekt ); - free ( m ); - mitkIpPicFree ( pic_new ); - mitkIpPicFree ( pic_help1 ); - mitkIpPicFree ( pic_help2 ); - mitkIpPicFree ( pic_help3 ); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_help4, pic_old); - - return ( pic_help4 ); -} - -#endif diff --git a/Utilities/IpFunc/Close.c b/Utilities/IpFunc/Close.c deleted file mode 100644 index db15b68a35..0000000000 --- a/Utilities/IpFunc/Close.c +++ /dev/null @@ -1,95 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function performs the morphological closing operation - */ - -/** @brief performs the morphological closing operation - * - * Closing is a dilation followed by an erosion. - * - * @param pic_old pointer to the original image - * @param mask pointer to the kernel - * @param border tells how the edge is transformed - * - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to zero - * - * @return pointer to transformed iamge - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncClose ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -mitkIpPicDescriptor *mitkIpFuncClose ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new; - - pic_new = _mitkIpFuncOpCl ( pic_old, pic_mask, mitkIpFuncCloseF, border ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - - return ( pic_new ); -} - -#endif - diff --git a/Utilities/IpFunc/CompressM.c b/Utilities/IpFunc/CompressM.c deleted file mode 100644 index d2d0db9532..0000000000 --- a/Utilities/IpFunc/CompressM.c +++ /dev/null @@ -1,231 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - /**@file - * this function removes all elements which are zero and - * calculates the offsets of the non-zero elements - * which are nonzero - */ -/** @brief removes all elements which are zero from the mask and - * calculates the offsets (relative to the actual pixel) for all elements - * which are nonzero - * - * @param mask pointer to mask structure - * @param pic_old pointer to original image - * @param kind tells whether mask should be reflected - * @arg @c mitkIpNOREFLECT : original mask is used - * @arg @c mitkIpREFLECT : reflected mask is used - * @param beg pixel number where convolution begins ( return value ) - * @param end pixel number where convolution ends ( return value ) - * - * @return m pointer to compressed mask structure - * - * - * AUTHOR & DATE - */ - -#include "mitkIpFuncP.h" - -mitkIpFuncMasc_t *_mitkIpFuncCompressM ( mitkIpPicDescriptor *mask, - mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpInt4_t beg[_mitkIpPicNDIM], - mitkIpInt4_t end[_mitkIpPicNDIM] ) ; - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncCompressM\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -#define OFF_M( type, pic_mask, pic, beg, size, m, kind ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t pos; /* */ \ - mitkIpInt4_t off_mask; /* offset for mask elements */ \ - mitkIpInt4_t offset; /* offset for picture elements */ \ - mitkIpInt4_t incr; \ - mitkIpUInt4_t size_m[_mitkIpPicNDIM]; \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpInt4_t ind_m[_mitkIpPicNDIM]; /* loop index vector */ \ - \ - /* initialization of vectors */ \ - \ - size_m[0] = 1; \ - size[0] = 1; \ - for ( i = 1; i < _mitkIpPicNDIM; i++ ) \ - { \ - size_m[i] = size_m[i-1] * pic_mask->n[i-1]; \ - size[i] = size[i-1] * pic->n[i-1]; \ - } \ - \ - /* calculate offsets from actual pixel for each mask element */ \ - \ - if ( kind == mitkIpFuncNoReflect ) \ - { \ - off_mask = 0; \ - incr = 1; \ - } \ - else if ( kind == mitkIpFuncReflect ) \ - { \ - off_mask = size_m[pic_mask->dim] -1; \ - incr = -1; \ - } \ - else return ( mitkIpFuncERROR ); \ - \ - m->length = 0; \ - \ - for ( ind[7] = 0, ind_m[7] = -beg[7]; ind[7] < pic_mask->n[7]; \ - ind[7]++, ind_m[7]++ ) \ - for ( ind[6] = 0, ind_m[6] = -beg[6]; ind[6] < pic_mask->n[6]; \ - ind[6]++, ind_m[6]++ ) \ - for ( ind[5] = 0, ind_m[5] = -beg[5]; ind[5] < pic_mask->n[5]; \ - ind[5]++, ind_m[5]++ ) \ - for ( ind[4] = 0, ind_m[4] = -beg[4]; ind[4] < pic_mask->n[4]; \ - ind[4]++, ind_m[4]++ ) \ - for ( ind[3] = 0, ind_m[3] = -beg[3]; ind[3] < pic_mask->n[3]; \ - ind[3]++, ind_m[3]++ ) \ - for ( ind[2] = 0, ind_m[2] = -beg[2]; \ - ind[2] < pic_mask->n[2]; ind[2]++, ind_m[2]++ ) \ - for ( ind[1] = 0, ind_m[1] = -beg[1]; \ - ind[1] < pic_mask->n[1]; ind[1]++, ind_m[1]++ ) \ - for ( ind[0] = 0, ind_m[0] = -beg[0]; \ - ind[0] < pic_mask->n[0]; ind[0]++, ind_m[0]++ ) \ - { \ - if ( (( type * )pic_mask->data )[off_mask] != 0 ) \ - { \ - offset = 0; \ - for ( i = 0; i < pic_mask->dim; i++ ) \ - offset = offset + ind_m[i] * size[i]; \ - \ - m->off_vekt[m->length] = offset; \ - m->length++; \ - } \ - off_mask = off_mask + incr; \ - } \ - \ - /* remove elements that are zero from mask */ \ - \ - pos = 0; \ - for ( i = 0; i < m->length; i++ ) \ - { \ - while ( (( type * )pic_mask->data )[pos] == 0 ) pos++; \ - m->mask_vekt[i] = ( mitkIpFloat8_t ) (( type * )pic_mask->data )[pos]; \ - pos++; \ - } \ - \ -} - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpFuncMasc_t *_mitkIpFuncCompressM ( mitkIpPicDescriptor *mask, - mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpInt4_t beg[_mitkIpPicNDIM], - mitkIpInt4_t end[_mitkIpPicNDIM] ) -{ - mitkIpUInt4_t i; /* loop index */ - mitkIpFuncMasc_t *m; /* length of mask and offsets */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; - - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( mask ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* initialization of vectors */ - - for ( i = 0; i < mask->dim; i++ ) - { - end[i] = pic_old->n[i] - mask->n[i] / 2; - beg[i] = ( ( mask->n[i] % 2 ) == 1 ) ? - ( mask->n[i] / 2 ) : ( mask->n[i] / 2 - 1 ); - } - - for ( i = mask->dim; i < _mitkIpPicNDIM; i++ ) - { - beg[i] = 0; - mask->n[i] = 1; - } - - for ( i = mask->dim; i < pic_old->dim; i++ ) - end[i] = pic_old->n[i]; - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - end[i] = beg[i] + 1; - - /* allocate mask structure */ - - m = malloc ( sizeof ( mitkIpFuncMasc_t ) ); - if ( m == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - m->off_vekt = malloc ( _mitkIpPicElements( mask ) * sizeof ( mitkIpInt4_t ) ); - if ( m->off_vekt == NULL ) - { - free ( m ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - m->mask_vekt = malloc ( _mitkIpPicElements( mask ) * sizeof ( mitkIpFloat8_t ) ); - if ( m->mask_vekt == NULL ) - { - free ( m->off_vekt ); - free ( m ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to compress mask (for all data types) */ - - mitkIpPicFORALL_5 ( OFF_M, mask, pic_old, beg, size, m, kind ); - - return ( m ); - -} -#endif diff --git a/Utilities/IpFunc/Conv.c b/Utilities/IpFunc/Conv.c deleted file mode 100644 index 199fdddc76..0000000000 --- a/Utilities/IpFunc/Conv.c +++ /dev/null @@ -1,236 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function convolves an image with a mask - */ - -/** this function convolves an image with a mask - * @param pic_old pointer to the image that should be convolved - * @param mask pointer to the mask that is used for convolution - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncFlagBorderOld : original greyvalues - * @arg @c mitkIpFuncFlagBorderZero : edge is set to minimal greyvalue - * - * @return pointer to the convolved image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncConv( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncConv\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - -#define CONV( typ, pic, size, mask, beg, end, m) \ -{ \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; \ - mitkIpInt4_t off[_mitkIpPicNDIM]; \ - mitkIpUInt4_t i; \ - mitkIpInt4_t offset; \ - mitkIpFloat8_t help, min_gv, max_gv; \ - typ *data, *data_new; \ - \ - /* calculate max. and min. possible greyvalues */ \ - \ - _mitkIpFuncExtT ( pic->type, pic->bpe, &min_gv, &max_gv ); \ - data = pic->data; \ - data_new = pic_new->data; \ - \ - /* convolve image with compressed mask */ \ - \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - offset = off[1] + beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - \ - /* calculate new greyvalue */ \ - \ - help = 0; \ - for ( i = 0; i < m->length; i++ ) \ - help = help + m->mask_vekt[i] * \ - data[offset + m->off_vekt[i]]; \ - \ - data_new[offset] = \ - ( help < max_gv )? \ - ( ( help < min_gv ) ? ( typ )min_gv : help ) : \ - ( typ ) max_gv; \ - /* \ - help = help + m->mask_vekt[i] * \ - (( typ * )pic->data)[offset + m->off_vekt[i]]; \ - \ - (( typ * )pic_new->data )[offset] = \ - ( help < max_gv )? \ - ( ( help < min_gv ) ? ( typ )min_gv : help ) : \ - ( typ ) max_gv; \ - */ \ - offset++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncConv( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ) -{ - - mitkIpPicDescriptor *pic_new; /* convolved image */ - mitkIpUInt4_t i; /* loopindex */ - mitkIpInt4_t beg[_mitkIpPicNDIM]; - mitkIpInt4_t end[_mitkIpPicNDIM]; - mitkIpFuncMasc_t *m; /* length of mask and offsets */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; - - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_mask ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( ( pic_mask->dim > pic_old->dim ) || ( pic_mask->dim < 1 ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < pic_old->dim; i++ ) - { - if ( pic_mask->n[i] > pic_old->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - /* create a new picture, copy the header, allocate memory */ - - if ( border == mitkIpFuncBorderOld ) - { - /*pic_new = _mitkIpFuncBorder ( pic_old, pic_mask, mitkIpFuncBorderOld );*/ - pic_new = mitkIpPicClone ( pic_old ); - } - else if ( border == mitkIpFuncBorderZero ) - { - /* pic_new = _mitkIpFuncBorder ( pic_old, pic_mask, mitkIpFuncBorderZero ); */ - pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe/8 ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialize vectors */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) size[i] = size[i-1] * pic_old->n[i-1]; - - /* compress mask */ - - m = _mitkIpFuncCompressM ( pic_mask, pic_old, mitkIpFuncReflect, beg, end ); - if ( m == NULL ) return ( mitkIpFuncERROR ); - - /* macro to convolve an image (for all data types) */ - - mitkIpPicFORALL_5 ( CONV, pic_old, size, pic_mask, beg, end, m ); - /* free memory */ - - free ( m->off_vekt ); - free ( m->mask_vekt ); - free ( m ); - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/Convert.c b/Utilities/IpFunc/Convert.c deleted file mode 100644 index c022f51687..0000000000 --- a/Utilities/IpFunc/Convert.c +++ /dev/null @@ -1,196 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/** @file - * this function converts one image to an image of another data type - * (at the moment only datatype mitkIpUInt1_t, mitkIpInt2_t, mitkIpFloat8_t ) are - * supported. - */ - - /** this function converts one image to an image of another data type - * (at the moment only datatype mitkIpUInt1_t, mitkIpInt2_t, mitkIpFloat8_t ) are - * supported. - * - * @param pic_old pointer to input image - * @param type image data type - * 3 mitkIpPicInt - * 4 mitkIpPicUInt - * 5 mitkIpPicFloat - * @param bpe bits per element representing on pixel - * - * qreturn pointer to converted image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - - -mitkIpPicDescriptor *mitkIpFuncConvert ( mitkIpPicDescriptor *pic_old, - mitkIpPicType_t type, - mitkIpUInt4_t bpe ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncConvert\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/* definition of macros */ - -#define CONV_1( type_old, pic_old, pic_new, min_gv, max_gv ) \ -{ \ - mitkIpPicFORALL_4( CONV_2, pic_new, pic_old, type_old, min_gv, max_gv ) \ -} - -#define CONV_3( type_old, pic_old, pic_new ) \ -{ \ - mitkIpPicFORALL_2( CONV_4, pic_new, pic_old, type_old ) \ -} - - -#define CONV_4( type_new, pic_new, pic_old, type_old ) \ -{ \ - size_t i; \ - size_t no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_old ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type_new * ) pic_new->data ) [i] = ( type_new ) \ - (( type_old * ) pic_old->data ) [i]; \ - } \ -} - -#define CONV_2( type_new, pic_new, pic_old, type_old, min_gv, max_gv ) \ -{ \ - size_t i; \ - size_t no_elem; \ - type_old help; \ - \ - no_elem = _mitkIpPicElements ( pic_new ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = (( type_old * ) pic_old->data ) [i]; \ - (( type_new * ) pic_new->data ) [i] = \ - ( max_gv > ( mitkIpFloat8_t ) help ) ? \ - ( min_gv < ( mitkIpFloat8_t ) help ? \ - ( type_new )help : ( type_new ) min_gv ) : \ - ( type_new ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncConvert ( mitkIpPicDescriptor *pic_old, - mitkIpPicType_t type, - mitkIpUInt4_t bpe ) - -{ - mitkIpFloat8_t min, max; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t max_gv; - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - - - /* ckeck whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( ! ( ( type == mitkIpPicFloat && ( bpe == 32 || bpe == 64 ) ) || - ( type == mitkIpPicUInt && ( bpe == 8 || bpe == 16 || bpe == 32 ) ) || - ( type == mitkIpPicInt && ( bpe == 8 || bpe == 16 || bpe == 32 ) ) ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate max. and min. possible greyvalues for output image */ - - if ( _mitkIpFuncExtT ( type, bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* calculate extreme greyvalues in input image */ - - if ( mitkIpFuncExtr ( pic_old, &min, &max ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* allocate output image */ - - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_new->type = type; - pic_new->bpe = bpe; - - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to convert the picture (for all data types) */ - - if ( ( min < min_gv ) || ( max > max_gv ) ) - mitkIpPicFORALL_3 ( CONV_1, pic_old, pic_new, min_gv, max_gv ) - else - mitkIpPicFORALL_1 ( CONV_3, pic_old, pic_new ) - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/CopyTags.c b/Utilities/IpFunc/CopyTags.c deleted file mode 100644 index fdbd9c6648..0000000000 --- a/Utilities/IpFunc/CopyTags.c +++ /dev/null @@ -1,66 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function copies the tags of one image to another - */ - -/** @brief copies the tags of one image to another - * @param pic_new pointer to the destination image - * @param pic_old pointer to the source image - * - * @author Carlos and Ivo - * @date 14.04.2000 - */ - -#include "mitkIpFuncP.h" - -void mitkIpFuncCopyTags(mitkIpPicDescriptor *pic_new, mitkIpPicDescriptor *pic_old) -{ - /* Copy Tags */ - - if(pic_new!=NULL) - { - strncpy( pic_new->info->version, pic_old->info->version, _mitkIpPicTAGLEN ); - pic_new->info->tags_head = _mitkIpPicCloneTags( pic_old->info->tags_head ); - pic_new->info->write_protect = pic_old->info->write_protect; - } -} - diff --git a/Utilities/IpFunc/Curtosis.c b/Utilities/IpFunc/Curtosis.c deleted file mode 100644 index fa21d63b67..0000000000 --- a/Utilities/IpFunc/Curtosis.c +++ /dev/null @@ -1,116 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the curtosis of all - * greyvalues in an image - */ - -/** @brief calculates the curtosis of all - * greyvalues in an image - * - * @param pic pointer to the image - * - * @return curtosis of image - * - * @author Steffen Gundel - */ - - -/* include-files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncCurtosis ( mitkIpPicDescriptor *pic ); - -/* definition of extreme value macro */ - -#ifndef DOXYGEN_IGNORE - -/* include-files */ - -#include "mitkIpFuncP.h" - -/* definition of extreme value macro */ - -#define CURTOSIS( type, pic, mean, excess ) \ - { \ - mitkIpUInt4_t i, no_elem; \ - \ - excess = 0.; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - excess = ( ( ( type * ) pic->data ) [i] - mean ) * \ - ( ( ( type * ) pic->data ) [i] - mean ) * \ - ( ( ( type * ) pic->data ) [i] - mean ) * \ - ( ( ( type * ) pic->data ) [i] - mean ) + \ - excess; \ - } \ - } - -mitkIpFloat8_t mitkIpFuncCurtosis ( mitkIpPicDescriptor *pic ) -{ - - mitkIpFloat8_t curt; - mitkIpFloat8_t mean, std; - - - /* check image data */ - - if ( _mitkIpFuncError ( pic ) != mitkIpOK ) return ( mitkIpFuncERROR ); - - curt = 0.0; - if ( _mitkIpPicElements ( pic ) != 1 ) - { - - mean = mitkIpFuncMean ( pic ); - std = mitkIpFuncSDev( pic ); - - mitkIpPicFORALL_2( CURTOSIS, pic, mean, curt ); - - curt = curt / ((( mitkIpFloat8_t )(_mitkIpPicElements ( pic ) - 1 )) *std*std*std*std) -3; - } - - return( curt ); -} -#endif - diff --git a/Utilities/IpFunc/CurtosisR.c b/Utilities/IpFunc/CurtosisR.c deleted file mode 100644 index 636d385b6c..0000000000 --- a/Utilities/IpFunc/CurtosisR.c +++ /dev/null @@ -1,87 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the curtosis of all - * greyvalues included by a rectangle - */ - -/** @brief calculates the curtosis of all - * greyvalues included by a rectangle - * - * The rectangle is described by a vector with the coordinates of the - * upper left corner and a vector of its length in each direction - * - * @param pic_old pointer to the image - * @param begin vector with the beginning coordinates of the window - * @param length vector with the length of the window in each direction - * - * @return curtosis in window - * - * @author Steffen Gundel - */ - -/* include-files */ - -#include "mitkIpFuncP.h" - - -/* ========================================================== */ -/* -** function picVar : calculates the mean value (mean) -** of an image (pic) -*/ -/* ========================================================== */ - -double mitkIpFuncCurtosisR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ) { - - mitkIpFloat8_t var; - mitkIpPicDescriptor *pic_help; - - pic_help = mitkIpFuncWindow ( pic_old, begin, length ); - - var = mitkIpFuncCurtosis ( pic_help ); - - mitkIpPicFree ( pic_help ); - - return ( var ); -} diff --git a/Utilities/IpFunc/Dila.c b/Utilities/IpFunc/Dila.c deleted file mode 100644 index 298fea7540..0000000000 --- a/Utilities/IpFunc/Dila.c +++ /dev/null @@ -1,95 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file -* this function performs a dilation. If the original - * image is a binary image each pixel is connected with the surrounding - * pixels which are non zero in the kernel by using logical operations - * ( and for erosion, or for dilation ). Greylevel images are transformed - * by taking the minimum (erosion) of the surrounding pixels or the - * maximum (dilation). - */ - - /** @brief performs a dilation. If the original - * image is a binary image each pixel is connected with the surrounding - * pixels which are non zero in the kernel by using logical operations - * ( and for erosion, or for dilation ). Greylevel images are transformed - * by taking the minimum (erosion) of the surrounding pixels or the - * maximum (dilation). - * - * @param pic_old pointer to the original image - * @param mask pointer to the kernel - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to zero - * - * @return pointer to the transformed image - * - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncDila ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); -#ifndef DOXYGEN_IGNORE - -mitkIpPicDescriptor *mitkIpFuncDila ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new; - - pic_new = _mitkIpFuncMorph ( pic_old, pic_mask, mitkIpFuncDilaF, border ); - if ( border == mitkIpFuncBorderZero ) - pic_new = mitkIpFuncBorder ( pic_new, pic_mask, pic_new ); - - - mitkIpFuncCopyTags(pic_new, pic_old); - - return ( pic_new ); -} - -#endif - diff --git a/Utilities/IpFunc/DivC.c b/Utilities/IpFunc/DivC.c deleted file mode 100644 index 94a22b32c7..0000000000 --- a/Utilities/IpFunc/DivC.c +++ /dev/null @@ -1,258 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file -* this function divides the greyvalues of an image by a value -*/ - -/** @brief divides the greyvalues of an image by a value - * - * @param pic_1 pointer to the first image - * @param value constant which is multiplied to image - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c mitkIpFuncNoKeep : image data type could be changed - * @arg @c mitkIpFuncKeep : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory which could be used for pic_new. If - * pic_retrun == NULL new memory is allocated - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncDivC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncDivC\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* definition of macros */ - -#define DIVC( type_1, pic_1, pic_new, value ) \ -{ \ - mitkIpPicFORALL_3 ( DIVC2, pic_new, pic_1, type_1, value ); \ -} \ - -#define DIVC2( type_n, pic_new, pic_1, type_1, value ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type_n * ) pic_new->data ) [i] = ( type_n ) \ - ( ( mitkIpFloat8_t )(( type_1 * ) pic_1->data ) [i] / value );\ - } \ -} - -#define DIVC3( type_n, pic_1, pic_new, value ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - mitkIpFloat8_t help; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = ( mitkIpFloat8_t )(( type_n * ) pic_1->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( max_gv > ( mitkIpFloat8_t ) help / value ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help / value ) ? \ - ( (type_n)( help / value ) ) : ( type_n ) min_gv ) : \ - ( type_n ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncDivC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check value */ - - if ( value == 0. ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_old, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = max1 / value; - smin = min1 / value; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_old->type == mitkIpPicInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicUInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || smin < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - - /* macro to invert the picture (for all data types) */ - - if ( keep == mitkIpFuncNoKeep ) - mitkIpPicFORALL_2 ( DIVC, pic_old, pic_new, value ) - else if ( keep == mitkIpFuncKeep ) - mitkIpPicFORALL_2 ( DIVC3, pic_old, pic_new, value ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/DivI.c b/Utilities/IpFunc/DivI.c deleted file mode 100644 index ad3531d50e..0000000000 --- a/Utilities/IpFunc/DivI.c +++ /dev/null @@ -1,295 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function divides corresponding greyvalues of two images -*/ - -/** this function divides corresponding greyvalues of two images - * - * @param pic_1 pointer to the first image - * @param pic_2 pointer to the second image - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c mitkIpFuncNoKeep : image data type could be changed - * @arg @c mitkIpFuncKeep : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncDivI ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - - -#ifndef lint - static char *what = { "@(#)mitkIpFuncDivI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* definition of macros */ - -#define DIVI( type_1, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpPicFORALL_3 ( DIVI2, pic_new, pic_1, pic_2, type_1 ); \ -} \ - -#define DIVI2( type_n, pic_new, pic_1, pic_2, type_1 ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - type_1 help2; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help2 = (( type_1 * ) pic_2->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( help2 == ( type_1) 0 ) ? \ - ( type_1) 0 : \ - (( type_1 * ) pic_1->data ) [i] / help2; \ - } \ -} - -#define DIVI3( type_n, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - type_n help; \ - type_n help2; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = (( type_n * ) pic_1->data ) [i]; \ - help2 = (( type_n * ) pic_2->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( help2 == ( type_n) 0 ) ? ( type_n) 0 : \ - (( max_gv > ( mitkIpFloat8_t ) help / ( mitkIpFloat8_t ) help2 ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help / ( mitkIpFloat8_t ) help2 ) ? \ - ((type_n)help / (type_n)help2 ) : ( type_n ) min_gv ) :\ - ( type_n ) max_gv ); \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncDivI ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t min2, max2; /* extreme greyvalues of 2. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - mitkIpFloat8_t min_max12; /* product of min1 and max2 */ - mitkIpFloat8_t min_max21; /* product of min2 and max1 */ - - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check whether images have the same size */ - - if ( ( pic_1->type != pic_2->type ) || ( pic_1->bpe != pic_2->bpe ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - if ( pic_1->dim == pic_2->dim ) - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - { - if ( pic_1->n[i] != pic_2->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_1->type, pic_1->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( mitkIpFuncExtr ( pic_2, &min2, &max2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = max1 / max2; - smin = min1 / min2; - min_max12 = min1 / max2; - min_max21 = max1 / min2; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_1->type == mitkIpPicInt ) - { - if ( smax < max_gv && min_max12 < max_gv && min_max21 < max_gv && - smin > min_gv && min_max12 > min_gv && min_max21 > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicUInt ) - { - if ( smax < max_gv && min_max12 < max_gv && min_max21 < max_gv && - smin > min_gv && min_max12 > min_gv && min_max21 > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || min_max12 > max_gv || min_max21 > max_gv || - smin < min_gv || min_max12 < min_gv || min_max21 < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - if ( keep == mitkIpFuncNoKeep ) - { - mitkIpPicFORALL_2 ( DIVI, pic_1, pic_2, pic_new ) - } - else if ( keep == mitkIpFuncKeep ) - { - mitkIpPicFORALL_2 ( DIVI3, pic_1, pic_2, pic_new ) - } - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_1); - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/DrawPoly.c b/Utilities/IpFunc/DrawPoly.c deleted file mode 100644 index 0578829cec..0000000000 --- a/Utilities/IpFunc/DrawPoly.c +++ /dev/null @@ -1,388 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file -* this function draws the edge of an ROI in an image -*/ - -/** this function draws the edge of an ROI in an image - * @param pic_old pointer to original image - * @param pol_x vector with the x-coordinates of the points which - * form the roi - * @param pol_y vector with the y-coordinates of the points which - * form the roi - * @param no_pts number of points used to describe ROI - * - * @arg @c this function could just be used for 2D images - * - * @return image with roi - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncDrawPoly ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncDrawPoly\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - -#define MAX( x, y ) ( x > y ) ? x : y -#define MIN( x, y ) ( x < y ) ? x : y - -#define DRAW( type, pic_help, a, b, pol_x, pol_y ) \ -{ \ - mitkIpUInt4_t beg; \ - mitkIpUInt4_t end; \ - mitkIpUInt4_t i, j; \ - mitkIpUInt4_t y; \ - type max; \ - \ - max = ( type ) max_gv; \ - /* draw polygon to pic_help */\ - \ - for ( i = 0; i < no_pts-1; i++ ) \ - { \ - if ( pol_x[i] == pol_x[i+1] ) \ - { \ - if ( pol_y[i] < pol_y[i+1] ) \ - { \ - beg = pol_y[i]; \ - end = pol_y[i+1]; \ - } \ - else \ - { \ - end = pol_y[i]; \ - beg = pol_y[i+1]; \ - } \ - for ( j = beg; j < end; j++ ) \ - (( type * )pic_help->data )[ j * pic_help->n[1] + pol_x[i]] = max;\ - } \ - else \ - { \ - if ( pol_x[i] < pol_x[i+1] ) \ - { \ - beg = pol_x[i]; \ - end = pol_x[i+1]; \ - } \ - else \ - { \ - end = pol_x[i]; \ - beg = pol_x[i+1]; \ - } \ - if ( pol_y[i] == pol_y[i+1] ) end = beg -1; \ - \ - for ( j = beg; j <= end; j++ ) \ - { \ - y = a[i] * j + b[i]; \ - (( type * )pic_help->data )[ y * pic_help->n[1] + j ] = max;\ - } \ - } \ - \ - if ( pol_y[i] == pol_y[i+1] ) \ - { \ - if ( pol_x[i] < pol_x[i+1] ) \ - { \ - beg = pol_x[i]; \ - end = pol_x[i+1]; \ - } \ - else \ - { \ - end = pol_x[i]; \ - beg = pol_x[i+1]; \ - } \ - \ - for ( j = beg; j < end; j++ ) \ - (( type * )pic_help->data )[ j + pic_help->n[1] * pol_y[i]] = max;\ - } \ - else \ - { \ - if ( pol_y[i] < pol_y[i+1] ) \ - { \ - beg = pol_y[i]; \ - end = pol_y[i+1]; \ - } \ - else \ - { \ - end = pol_y[i+1]; \ - beg = pol_y[i]; \ - } \ - if ( pol_x[i] == pol_x[i+1] ) end = beg - 1; \ - \ - for ( j = beg; j <= end; j++ ) \ - { \ - y = ( j - b[i] ) / a[i]; \ - (( type * )pic_help->data )[ j * pic_help->n[1] + y ] = max;\ - } \ - } \ - } \ - \ - if ( pol_x[no_pts-1] == pol_x[0] ) \ - { \ - if ( pol_y[no_pts-1] < pol_y[0] ) \ - { \ - beg = pol_y[no_pts-1]; \ - end = pol_y[0]; \ - } \ - else \ - { \ - end = pol_y[no_pts-1]; \ - beg = pol_y[0]; \ - } \ - \ - for ( j = beg; j < end; j++ ) \ - (( type * )pic_help->data )[ j * pic_help->n[1] + pol_x[no_pts-1]] = max;\ - } \ - else \ - { \ - if ( pol_x[no_pts-1] < pol_x[0] ) \ - { \ - beg = pol_x[no_pts-1]; \ - end = pol_x[0]; \ - } \ - else \ - { \ - end = pol_x[no_pts-1]; \ - beg = pol_x[0]; \ - } \ - if ( pol_y[no_pts-1] == pol_y[0] ) end = beg -1; \ - \ - for ( j = beg; j <= end; j++ ) \ - { \ - y = a[no_pts-1] * j + b[no_pts-1]; \ - (( type * )pic_help->data )[ y * pic_help->n[1] + j ] = max;\ - } \ - } \ - \ - if ( pol_y[no_pts-1] == pol_y[0] ) \ - { \ - if ( pol_x[no_pts-1] < pol_x[0] ) \ - { \ - beg = pol_x[no_pts-1]; \ - end = pol_x[0]; \ - } \ - else \ - { \ - end = pol_x[no_pts-1]; \ - beg = pol_x[0]; \ - } \ - \ - for ( j = beg; j < end; j++ ) \ - (( type * )pic_help->data )[ j + pic_help->n[1] * pol_y[no_pts-1]] = max;\ - } \ - else \ - { \ - if ( pol_y[no_pts-1] < pol_y[0] ) \ - { \ - beg = pol_y[no_pts-1]; \ - end = pol_y[0]; \ - } \ - else \ - { \ - end = pol_y[no_pts-1]; \ - beg = pol_y[0]; \ - } \ - if ( pol_x[no_pts-1] == pol_x[0] ) end = beg - 1; \ - \ - for ( j = beg; j <= end; j++ ) \ - { \ - y = ( j - b[no_pts-1] ) / a[no_pts-1]; \ - (( type * )pic_help->data )[ j * pic_help->n[1] + y ] = max;\ - } \ - } \ -} - -/* -------------------------------------------------------------------- */ - -/* -** mitkIpFuncDrawPoly -*/ - -mitkIpPicDescriptor *mitkIpFuncDrawPoly ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) -{ - - mitkIpUInt4_t min_x, max_x; /* min, max x-coordinate of ROI */ - mitkIpUInt4_t min_y, max_y; /* min, max y-coordinate of ROI */ - mitkIpFloat8_t min_gv, max_gv; - mitkIpFloat8_t *a, *b; /* Gerade y = ax+b */ - mitkIpFloat8_t diff; /* difference between two points */ - mitkIpPicDescriptor *pic_help; - mitkIpUInt4_t i; - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim > 2 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* calculate min. and max. coordiantes of ROI */ - - min_x = pol_x[0]; - min_y = pol_y[0]; - max_x = pol_x[0]; - max_y = pol_y[0]; - for ( i = 1; i < no_pts; i++ ) - { - min_x = MIN ( min_x, pol_x[i] ); - min_y = MIN ( min_y, pol_y[i] ); - max_x = MAX ( max_x, pol_x[i] ); - max_y = MAX ( max_y, pol_y[i] ); - } - - /* check whether ROI is in image */ - - /* Expression is always false. - if ( min_x < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - - if ( max_x > pic_old->n[0] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Expression is always false. - if ( min_y < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - - if ( max_y > pic_old->n[1] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory for a and b */ - - a = ( mitkIpFloat8_t * ) malloc ( no_pts * sizeof ( mitkIpFloat8_t ) ); - if ( !a ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - b = ( mitkIpFloat8_t * ) malloc ( no_pts * sizeof ( mitkIpFloat8_t ) ); - if ( !b ) - { - free ( a ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Geraden zwischen zwei benachbarten Punkten berechnen */ - - for ( i = 0; i < no_pts-1; i++ ) - { - diff = ( mitkIpFloat8_t ) pol_x[i+1] - ( mitkIpFloat8_t ) pol_x[i]; - if ( diff ) - { - a[i] = ( ( mitkIpFloat8_t ) pol_y[i+1] - ( mitkIpFloat8_t ) pol_y[i] ) / diff; - - b[i] = ( ( mitkIpFloat8_t ) pol_y[i] - a[i] * ( mitkIpFloat8_t )pol_x[i] ); - } - else - { - b[i] = 0.; - a[i] = 0.; - } - } - diff = ( mitkIpFloat8_t ) pol_x[no_pts-1] - ( mitkIpFloat8_t ) pol_x[0]; - if ( diff ) - { - a[no_pts-1] = ( ( mitkIpFloat8_t ) pol_y[no_pts-1] - ( mitkIpFloat8_t ) pol_y[0] ) / diff; - b[no_pts-1] = ( pol_y[no_pts-1] - a[no_pts-1] * pol_x[no_pts-1] ); - } - else - { - b[no_pts-1] = 0.; - a[no_pts-1] = 0.; - } - - - /* allocate memory for pic help */ - - pic_help = mitkIpPicClone ( pic_old ); - if ( pic_help == NULL ) - { - free ( a ); - free ( b ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - mitkIpPicFORALL_4 ( DRAW, pic_help, a, b, pol_x, pol_y ); - - free ( a ); - free ( b ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_help, pic_old); - - return ( pic_help ); -} -#endif diff --git a/Utilities/IpFunc/Equal.c b/Utilities/IpFunc/Equal.c deleted file mode 100644 index ab04954e33..0000000000 --- a/Utilities/IpFunc/Equal.c +++ /dev/null @@ -1,222 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file -* this function equalizes a greyvalue histogram -*/ - - -/** this function equalizes a greyvalue histogram - * - * @param pic_old pointer to the image that should be equalized - * @param kind intervall of transformation - * @arg @c mitkIpFuncMinMax (extreme greyvalues) - * @arg @c mitkIpFuncTotal (max. and min. possible - * greyvalues) - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the egalized image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncEqual ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ) ; - -#ifndef DOXYGEN_IGNORE - - -#ifndef lint - static char *what = { "@(#)mitkIpFuncEqual\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* definition of EQUAL-macro */ - -#define EQUAL( type, pic, pic_new, kind, factor, hist, help, size_hist ) \ -{ \ - type *hist_cp; \ - mitkIpUInt4_t i, no_elem; \ - mitkIpUInt4_t index; \ - mitkIpFloat8_t a, b; \ - mitkIpFloat8_t min, max; /* intervall for transformation */ \ - \ - /* allocate memory for the transformed histogram */ \ - \ - hist_cp = calloc( size_hist + 1, sizeof( type ) ); \ - if ( hist_cp == NULL ) \ - { \ - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); \ - return ( NULL ); \ - } \ - \ - /* cumulative greylevel histogram */ \ - \ - for ( i = 1; i <= size_hist; i++ ) \ - { \ - hist[i] = hist[i] + hist[i-1]; \ - } \ - \ - /* check wether linerisation in [min_gv, max_gv] or in [min_max] */ \ - \ - if ( kind == mitkIpFuncMinMax ) \ - { \ - if ( mitkIpFuncExtr ( pic_old, &min, &max ) != mitkIpFuncOK ) \ - return ( mitkIpFuncERROR ); \ - } \ - else if ( kind == mitkIpFuncTotal ) \ - { \ - max = max_gv; \ - min = min_gv; \ - } \ - else \ - { \ - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); \ - free ( hist_cp ); \ - free ( hist ); \ - return ( mitkIpFuncERROR ); \ - } \ - \ - /* transformation of histogram */ \ - \ - a = ( mitkIpFloat8_t ) _mitkIpPicElements ( pic ) / ( max - min ); \ - b = - a * min; \ - for ( i = 0; i <= size_hist; i++ ) \ - hist_cp[i] = ( type ) ( ( ( mitkIpFloat8_t )hist[i] - b ) / a ); \ - \ - /* transform greyvalues */ \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - index = ( mitkIpUInt4_t ) \ - ( factor * ((( type * ) pic->data )[i] + ( type )help ) );\ - ( ( type * ) pic_new->data )[i] = ( type ) hist_cp[index]; \ - } \ - free ( hist_cp ); \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncEqual ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpUInt4_t *hist; /* greylevel histogram */ - mitkIpUInt4_t size_hist; /* no. of elements in histogram */ - mitkIpFloat4_t factor; - mitkIpFloat8_t help; - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* create a new picture, copy the header, allocate memory */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - { - mitkIpPicFree ( pic_new ); - return ( NULL ); - } - - /* calculate greylevel histogram */ - - mitkIpFuncHist ( pic_old, min_gv, max_gv, &hist, &size_hist ); - if ( hist == 0 ) - { - mitkIpPicFree ( pic_new ); - return ( NULL ); - } - - /* help variables to calculate histogram */ - - help = fabs ( min_gv ); - - if ( pic_old->type == mitkIpPicFloat ) - factor = 1000.; - else if ( pic_old->type == mitkIpPicInt || pic_old->type == mitkIpPicUInt ) - factor = 1.; - else - { - mitkIpPicFree ( pic_new ); - free ( hist ); - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( NULL ); - } - - /* macro to change image (for all data types) */ - - mitkIpPicFORALL_6 ( EQUAL, pic_old, pic_new, kind, factor, hist, help, size_hist ); - - free ( hist ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/Ero.c b/Utilities/IpFunc/Ero.c deleted file mode 100644 index 1d7b96f0a4..0000000000 --- a/Utilities/IpFunc/Ero.c +++ /dev/null @@ -1,97 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs an erosion - */ - -/** @brief this function performs an erosion - * - * If the original image is a binary image each pixel is connected with - * the surrounding - * pixels which are non zero in the kernel by using logical operations - * ( and for erosion, or for dilation ). Greylevel images are transformed - * by taking the minimum (erosion) of the surrounding pixels or the - * maximum (dilation). - * - * @param pic_old pointer to the original image - * @param mask pointer to the kernel - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to zero - * - * @return pointer to the transformed image - * - * @par Uses - * @arg _mitkIpFuncError() - check the image data - * @arg _mitkIpFuncCompressM() - compress filtering mask - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncEro ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -#ifndef DOXYGEN_IGNORE - -mitkIpPicDescriptor *mitkIpFuncEro ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new; - - pic_new = _mitkIpFuncMorph ( pic_old, pic_mask, mitkIpFuncEroF, border ); - if ( border == mitkIpFuncBorderZero ) - pic_new = mitkIpFuncBorder ( pic_new, pic_mask, pic_new ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif diff --git a/Utilities/IpFunc/Error.c b/Utilities/IpFunc/Error.c deleted file mode 100644 index a45e0c80b1..0000000000 --- a/Utilities/IpFunc/Error.c +++ /dev/null @@ -1,134 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this functions checks, whether the information of the image header - * are correct - */ - - /** @briefs checks, whether the information of the image header - * are correct - * - * @param pic pointer to the image - * - * @return mitkIpFuncOK - if data are correct - * @return mitkIpFuncERROR - if data aren't correct - * - * AUTHOR & DATE - */ - -/* include files */ - -# include "mitkIpFuncP.h" - -mitkIpUInt4_t _mitkIpFuncError ( mitkIpPicDescriptor *pic ); - - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/*-------------------------------------------------------------------*/ -/* -*/ -/*-------------------------------------------------------------------*/ - -mitkIpUInt4_t _mitkIpFuncError ( mitkIpPicDescriptor *pic ) -{ - mitkIpUInt4_t i; /* loop index */ - - /* is image existing ? */ - - if ( !pic ) - { - _mitkIpFuncSetErrno ( mitkIpFuncNOPIC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* is dimension correct ? */ - - if ( pic->dim < 1 || pic->dim > _mitkIpPicNDIM ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* is size correct ? */ - - for ( i = 0; i < pic->dim; i++ ) - if ( pic->n[i] < 1 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncSIZE_ERROR ); - return ( mitkIpFuncERROR ); - } - for ( i = pic->dim; i < _mitkIpPicNDIM; i++ ) - pic->n[i] = 0; - - /* is image data type correct ? */ - - if ( pic->type == mitkIpPicInt || pic->type == mitkIpPicUInt ) - { - if ( pic->bpe != 8 && pic->bpe != 16 && pic->bpe != 32 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - } - else if ( pic->type == mitkIpPicFloat ) - { - if ( pic->bpe != 32 && pic->bpe != 64 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - return ( mitkIpFuncOK ); -} -#endif - diff --git a/Utilities/IpFunc/Exp.c b/Utilities/IpFunc/Exp.c deleted file mode 100644 index beff407d92..0000000000 --- a/Utilities/IpFunc/Exp.c +++ /dev/null @@ -1,154 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * transforms the greyvalues by an exponential function (y = exp (ax) + b) -*/ - -/** transforms the greyvalues by an exponential function (y = exp (ax) + b) - * - * @param pic_old pointer to the image that should be inverted - * @param kind determines - * mitkIpFuncTotal => transformation of all greyvalues - * mitkIpFuncMinMax=> transformation of greyvalues between min and max - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the image after exponential transformation - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncExp ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - - -#ifndef lint - static char *what = { "@(#)mitkIpFuncExp\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* definition of macro for normalisation */ - -#define EXP( type, pic, min_gv, max_gv ) \ -{ \ - mitkIpUInt4_t no_elem; \ - mitkIpFloat8_t a; \ - \ - a = log ( max_gv - min_gv + 1 ) / ( max_gv - min_gv ); \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type * ) pic_new->data ) [i] = \ - ( type ) ( exp ( a * ((( type * ) pic->data ) [i] - min_gv)) \ - -1 + min_gv ); \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -** function mitkIpFuncExp: -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncExp ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - mitkIpUInt4_t i; /* loopindex */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - - - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. or min possible greyvalue for datatype */ - - if ( kind == mitkIpFuncTotal ) - { - if ( _mitkIpFuncExtT( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - } - else if ( kind == mitkIpFuncMinMax ) - { - if ( mitkIpFuncExtr ( pic_old, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* create a new picture, copy the header, allocate memory */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to invert the picture (for all data types) */ - - mitkIpPicFORALL_2( EXP, pic_old, min_gv, max_gv ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/ExtT.c b/Utilities/IpFunc/ExtT.c deleted file mode 100644 index 134a6304f8..0000000000 --- a/Utilities/IpFunc/ExtT.c +++ /dev/null @@ -1,140 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function returns the allowed greyvalue range for a specific data-type - */ - -/** @brief this function returns the allowed greyvalue range for a - * specific data-type - * - * @param type data-type of image data - * @param bpe number of bits per element - * @param max_gv max. possible greyvalue - * @param min_gv min. possible greyvalue - * - * @return mitkIpFuncERROR if an error occured - * @return mitkIpFuncOK when no error occured - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpInt4_t _mitkIpFuncExtT ( mitkIpPicType_t type, - mitkIpUInt4_t bpe, - mitkIpFloat8_t *min_gv, - mitkIpFloat8_t *max_gv ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)_mitkIpFuncExtT\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -#ifdef _WIN32 -#include <float.h> -#endif - -/* definition of EXP-macro */ - -#define EXP( max_gv, bpe ) \ -{ \ - mitkIpUInt4_t i; \ - \ - *max_gv = 1; \ - for ( i = 1; i <= bpe; i++ ) \ - *max_gv = *max_gv * 2; \ -} - -/* ------------------------------------------------------------------- */ -/* -** function _picExtT: calculates the max. and min. possible greyvalues for -** a certain datatype -*/ -/* ------------------------------------------------------------------- */ - -mitkIpInt4_t _mitkIpFuncExtT ( mitkIpPicType_t type, - mitkIpUInt4_t bpe, - mitkIpFloat8_t *min_gv, - mitkIpFloat8_t *max_gv ) -{ - - /* calculate max. or min possible greyvalue for datatype */ - - if ( type == mitkIpPicInt ) - { - EXP( max_gv, bpe - 1 ) - *max_gv = *max_gv - 1; - *min_gv = - *max_gv; - } - else if ( type == mitkIpPicUInt ) - { - EXP (max_gv, bpe ) - *max_gv = *max_gv - 1; - *min_gv = 0; - } - else if ( type == mitkIpPicFloat ) - { - if ( bpe = 32 ) - { - *max_gv = FLT_MAX; - *min_gv = - FLT_MAX; - } - else if ( bpe = 64 ) - { - *max_gv = DBL_MAX; - *min_gv = - DBL_MAX; - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - return ( mitkIpFuncOK ); -} -#endif diff --git a/Utilities/IpFunc/ExtrC.c b/Utilities/IpFunc/ExtrC.c deleted file mode 100644 index a92fbe9518..0000000000 --- a/Utilities/IpFunc/ExtrC.c +++ /dev/null @@ -1,220 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function calculates the extreme greyvalues of all greyvalues which are - * included by a circle. - */ - -/** @brief calculates the extreme greyvalues of all greyvalues which are - * included by a circle. - * - * The circle is described by its center and radius. - * - * @param pic_old pointer to the original image - * @param min` pointer to minimal greyvalue in circle ( return value ) - * @param max pointer to maximal greyvalue in circle ( return value ) - * @param center pointer to an array that contains the coordinates - * of the center - * of the circle - * @param radius radius of the circle - * - * @return mitkIpFuncOK - if no error occured - * @return mitkIpFuncERROR - if an error occured - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpUInt4_t mitkIpFuncExtrC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncExtrC\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - - -#define EXTR( type, pic, beg, end, size, center, radius ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t offset; /* offset of pixels in pic_new */ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - mitkIpUInt4_t dist[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - mitkIpFloat8_t help; \ - \ - offset = 0; \ - for ( i = 0; i < pic->dim; i++ ) \ - offset = offset + center[i] * size[i]; \ - *max = ( mitkIpFloat8_t )( ( type * ) pic->data ) [offset]; \ - *min = ( mitkIpFloat8_t )( ( type * ) pic->data ) [offset]; \ - \ - for ( ind[7] = beg[7] ; ind[7] < end[7]; ind[7]++ ) \ - { \ - dist[7] = ( ind[7] - center[7] ) * ( ind[7] - center[7] ); \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6] ; ind[6] < end[6]; ind[6]++ ) \ - { \ - dist[6] = ( ind[6] - center[6] ) * ( ind[6] - center[6] ) + dist[7]; \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5] ; ind[5] < end[5]; ind[5]++ ) \ - { \ - dist[5] = ( ind[5] - center[5] ) * ( ind[5] - center[5] ) + dist[6]; \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4] ; ind[4] < end[4]; ind[4]++ ) \ - { \ - dist[4] = ( ind[4] - center[4] ) * ( ind[4] - center[4] ) + dist[5]; \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3] ; ind[3] < end[3]; ind[3]++ ) \ - { \ - dist[3] = ( ind[3] - center[3] ) * ( ind[3] - center[3] ) + dist[4]; \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2] ; ind[2] < end[2]; ind[2]++ ) \ - { \ - dist[2] = ( ind[2] - center[2] ) * ( ind[2] - center[2] ) + dist[3]; \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1] ; ind[1] < end[1]; ind[1]++ ) \ - { \ - dist[1] = ( ind[1] - center[1] ) * ( ind[1] - center[1] ) +dist[2];\ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1]+beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - dist[0] = ( ind[0] - center[0] ) * ( ind[0] - center[0] )+dist[1];\ - if ( sqrt ( ( mitkIpFloat8_t ) dist[0] ) <= radius ) \ - { \ - help = ( mitkIpFloat8_t )( ( type * ) pic->data ) [off[0]]; \ - *max = ( help > *max ) ? help : *max; \ - *min = ( help < *min ) ? help : *min; \ - } \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpUInt4_t mitkIpFuncExtrC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ) -{ - mitkIpInt4_t help; - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t end[_mitkIpPicNDIM]; /* end of window */ - mitkIpUInt4_t begin[_mitkIpPicNDIM]; /* beginning of window */ - mitkIpUInt4_t centr[_mitkIpPicNDIM]; /* beginning of window */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( radius <= 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < pic_old->dim; i++ ) - { - help = center[i] - radius; - if ( help < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - else begin[i] = ( mitkIpUInt4_t )help; - - help = center[i] + radius; - if ( (mitkIpUInt4_t) help > pic_old->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - else end[i] = ( mitkIpUInt4_t )help + 1; - centr[i] = center[i]; - } - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - size[pic_old->dim] = 0; - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - { - centr[i] = 0; - begin[i] = 0; - end[i] = 1; - } - - /* allocate image structure */ - - mitkIpPicFORALL_5 ( EXTR, pic_old, begin, end, size, centr, radius ); - - return ( mitkIpFuncOK ); -} - -#endif - diff --git a/Utilities/IpFunc/ExtrR.c b/Utilities/IpFunc/ExtrR.c deleted file mode 100644 index 9e01811b66..0000000000 --- a/Utilities/IpFunc/ExtrR.c +++ /dev/null @@ -1,98 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the extreme values of all greyvalues included by a rectangle - */ - - -/** @brief calculates the extreme values of all greyvalues included by a rectangle - * - * The rectangle is described by a vector with the coordinates of the - * upper left corner and a vector of its length in each direction - * - * @param pic_old pointer to original image - * @param min pointer to minimal greyvalue ( return value ) - * @param max pointer to maximal greyvalue ( return value ) - * @param begin vector with the beginning coordinates of the window - * @param length vector with the length of the window in each direction - * - * @return mitkIpFuncOK if no error occured - * @return mitkIpFuncERROR if an error occured - * - * AUTHOR & DATE - */ -#include "mitkIpFuncP.h" - -mitkIpUInt4_t mitkIpFuncExtrR ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncExtrR\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -mitkIpUInt4_t mitkIpFuncExtrR ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ) -{ - - mitkIpPicDescriptor *pic_help; - mitkIpInt4_t error; - - pic_help = mitkIpFuncWindow ( pic_old, begin, length ); - - if ( pic_help ) - error = mitkIpFuncExtr ( pic_help, min, max ); - else - return ( mitkIpFuncERROR ); - - mitkIpPicFree ( pic_help ); - - return ( error ); -} -#endif diff --git a/Utilities/IpFunc/ExtrROI.c b/Utilities/IpFunc/ExtrROI.c deleted file mode 100644 index 9fcabb8c34..0000000000 --- a/Utilities/IpFunc/ExtrROI.c +++ /dev/null @@ -1,251 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the extreme greyvalues - * of all pixels which are included by a polygon which - * is described by a sequence of points - */ - -/** @brief calculates the extreme greyvalues - * of all pixels which are included by a polygon which - * is described by a sequence of points - * - * @param pic_old pointer to original image - * @param min minimal greyvalue in ROI ( return value ) - * @param max maximal greyvalue in ROI ( return value ) - * @param pol_x vector with the x-coordinates of the points which form - * form the roi - * @param pol_y vector with the y-coordinates of the points which form - * form the roi - * @param no_pts number of points used to describe ROI - * - * REMARKS - * this function could just be used for 2D images - * - * @return mitkIpFuncOK when no error occured - * @return mitkIpFuncERROR when an error occured - * - * AUTHOR & DATE - */ -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpUInt4_t mitkIpFuncExtrROI ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) ; - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncExtrROI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/*definition of macros */ - -#define MAX( x, y ) ( x > y ) ? x : y -#define MIN( x, y ) ( x < y ) ? x : y -#define ROI( type, pic, pic_help ) \ -{ \ - mitkIpBool_t in; \ - mitkIpUInt4_t i, j; \ - mitkIpUInt4_t offset; \ - mitkIpFloat8_t help; \ - \ - *max = (( type * )pic->data )[pol_x[0] + pol_y[0] * pic->n[0]]; \ - *min = (( type * )pic->data )[pol_x[0] + pol_y[0] * pic->n[0]]; \ - for ( i = min_y; i <= max_y; i++ ) \ - { \ - in = mitkIpFalse; \ - offset = i * pic->n[0] + min_x; \ - for ( j = min_x; j <= max_x; j++ ) \ - { \ - if ( (( mitkIpUInt1_t * )pic_help->data )[offset] && ( !in ) ) \ - in = mitkIpTrue; \ - else if ( (( mitkIpUInt1_t * )pic_help->data )[offset] && ( in ) ) \ - { \ - in = mitkIpFalse; \ - help = ( mitkIpFloat8_t ) (( type * )pic->data )[offset]; \ - *max = MAX ( help, *max ); \ - *min = MIN ( help, *min ); \ - } \ - \ - if ( in ) \ - { \ - help = ( mitkIpFloat8_t ) (( type * )pic->data )[offset]; \ - *max = MAX ( help, *max ); \ - *min = MIN ( help, *min ); \ - } \ - offset++; \ - } \ - } \ -} - -/* -** mitkIpFuncMeanROI -*/ - -mitkIpUInt4_t mitkIpFuncExtrROI ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) -{ - mitkIpFloat8_t *a, *b; /* Gerade y = ax+b */ - mitkIpPicDescriptor *pic_help; /* contains edge of ROI */ - mitkIpUInt4_t min_x, max_x; /* min, max x-coordinate of ROI */ - mitkIpUInt4_t min_y, max_y; /* min, max y-coordinate of ROI */ - mitkIpUInt4_t i; /* loop variable */ - mitkIpFloat8_t diff; /* difference between two points */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim > 2 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate min. and max. coordiantes of ROI */ - - min_x = pol_x[0]; - min_y = pol_y[0]; - max_x = pol_x[0]; - max_y = pol_y[0]; - for ( i = 1; i < no_pts; i++ ) - { - min_x = MIN ( min_x, pol_x[i] ); - min_y = MIN ( min_y, pol_y[i] ); - max_x = MAX ( max_x, pol_x[i] ); - max_y = MAX ( max_y, pol_y[i] ); - } - - /* check whether ROI is in image */ - - /* Expression is always false! - if ( min_x < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - if ( max_x > pic_old->n[0] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - /* Expression is always false! - if ( min_y < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - if ( max_y > pic_old->n[1] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory for a and b */ - - a = ( mitkIpFloat8_t * ) malloc ( no_pts * sizeof ( mitkIpFloat8_t ) ); - b = ( mitkIpFloat8_t * ) malloc ( no_pts * sizeof ( mitkIpFloat8_t ) ); - - /* Geraden zwischen zwei benachbarten Punkten berechnen */ - - for ( i = 0; i < no_pts-1; i++ ) - { - diff = ( mitkIpFloat8_t ) pol_x[i+1] - ( mitkIpFloat8_t ) pol_x[i]; - if ( diff ) - { - a[i] = ( ( mitkIpFloat8_t ) pol_y[i+1] - ( mitkIpFloat8_t ) pol_y[i] ) / diff; - b[i] = ( ( mitkIpFloat8_t ) pol_y[i] - a[i] * ( mitkIpFloat8_t )pol_x[i] ); - } - else - { - b[i] = 0.; - a[i] = 0.; - } - } - diff = ( mitkIpFloat8_t ) pol_x[no_pts-1] - ( mitkIpFloat8_t ) pol_x[0]; - if ( diff ) - { - a[no_pts-1] = ( ( mitkIpFloat8_t ) pol_y[no_pts-1] - ( mitkIpFloat8_t ) pol_y[0] ) / diff; - b[no_pts-1] = ( pol_y[no_pts-1] - a[no_pts-1] * pol_x[no_pts-1] ); - } - else - { - b[no_pts-1] = 0.; - a[no_pts-1] = 0.; - } - - /* draw polygon to image */ - - pic_help = _mitkIpFuncDrawPoly ( pic_old, pol_x, pol_y, no_pts, a, b ); - if ( ! pic_help ) - { - free ( a ); - free ( b ); - return ( mitkIpFuncERROR ); - } - - /* macro to calculate mean */ - - mitkIpPicFORALL_1 ( ROI, pic_old, pic_help ); - - - free ( a ); - free ( b ); - mitkIpPicFree ( pic_help ); - - return ( mitkIpFuncOK ); - -} - -#endif diff --git a/Utilities/IpFunc/Extrema.c b/Utilities/IpFunc/Extrema.c deleted file mode 100644 index eb80a033bc..0000000000 --- a/Utilities/IpFunc/Extrema.c +++ /dev/null @@ -1,123 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the extreme greyvalues of an image - */ - - -/** this function calculates the extreme greyvalues of an image - * @param pic pointer to the image - * @param &min result variable: minimum - * @param &max result variable: maximum - * - * @return mitkIpFuncOK no error occured - * @return mitkIpFuncERROR an error occured - * - * AUTHOR - */ - -/* include-files */ - -#include "mitkIpFuncP.h" - -mitkIpInt4_t mitkIpFuncExtr ( mitkIpPicDescriptor *pic, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max ); - -#ifndef DOXYGEN_IGNORE - - -#ifndef lint - static char *what = { "@(#)mitkIpFuncExtr\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* definition of extreme value macro */ - -#define EXTR( type, pic, min_c, max_c ) \ - { \ - mitkIpUInt4_t i; \ - mitkIpUInt4_t no_elem; \ - mitkIpFloat8_t help; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - max_c = ( mitkIpFloat8_t )( ( type * ) pic->data ) [0]; \ - min_c = ( mitkIpFloat8_t )( ( type * ) pic->data ) [0]; \ - \ - for ( i = 1; i < no_elem; i++ ) \ - { \ - help = ( mitkIpFloat8_t )( ( type * ) pic->data ) [i]; \ - max_c = ( help > max_c ) ? help : max_c; \ - min_c = ( help < min_c ) ? help : min_c; \ - \ - } \ - } - -/* ========================================================== */ -/* -*/ -/* ========================================================== */ - -mitkIpInt4_t mitkIpFuncExtr ( mitkIpPicDescriptor *pic, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max ) -{ - - mitkIpFloat8_t min_c = 0.0; - mitkIpFloat8_t max_c = 0.0; - - /* check data */ - - if ( _mitkIpFuncError ( pic ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* macro to calculate extreme values ( for all data types */ - - mitkIpPicFORALL_2( EXTR, pic, min_c, max_c) - - *min = min_c; - *max = max_c; - - return( mitkIpFuncOK ); -} -#endif - diff --git a/Utilities/IpFunc/FillArea.c b/Utilities/IpFunc/FillArea.c deleted file mode 100644 index c2efe084e3..0000000000 --- a/Utilities/IpFunc/FillArea.c +++ /dev/null @@ -1,201 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/**@file - * this function fills an area - */ - -/** @brief fills an area - * - * @warning not tested - * - * AUTHOR & DATE - */ - -#ifndef lint - static char *what = { "@(#)\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include-Files */ - -#include "mitkIpFuncP.h" - -/* definition of macros and constants */ - -#define KL < -#define GR > - -#define MAX( x, y ) ( x > y ) ? x : y -#define MIN( x, y ) ( x < y ) ? x : y - -#define RECT( type, pic, beg, end, value ) \ -{ \ - mitkIpUInt4_t i, j, n; \ - mitkIpUInt4_t offset; \ - \ - n = pic->n[0]; \ - for ( j = beg[1]; j < end[1]; j++ ) \ - { \ - offset = j * n; \ - for ( i = beg[0]; i < end[0]; i++ ) \ - (( type * )pic->data )[i + offset] = ( type ) value; \ - } \ -} -#define TRI( type, pic, beg, end, value, a, b, OP ) \ -{ \ - mitkIpUInt4_t i, j, n; \ - mitkIpUInt4_t offset; \ - mitkIpFloat8_t help; \ - \ - n = pic->n[0]; \ - for ( j = beg[1]; j < end[1]; j++ ) \ - { \ - offset = j * n; \ - for ( i = beg[0]; i < end[0]; i++ ) \ - { \ - help = a * i + b; \ - if ( j OP help ) \ - { \ - (( type * )pic->data )[i + offset] = ( type ) value; \ - } \ - } \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncFillArea ( mitkIpPicDescriptor *pic_old, - mitkIpFuncBox_t box, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t over, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - mitkIpFloat8_t a, b; /* parameter der Gerade y = ax + b */ - mitkIpUInt4_t beg[2]; /* Anfangswerte */ - mitkIpUInt4_t end[2]; /* Endwerte */ - - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* create a new picture, copy the header, allocate memory */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - if ( pic_new != pic_old ) - { - memmove ( pic_new->data, pic_old->data, _mitkIpPicElements ( pic_old ) * pic_old->bpe /8 ); - } - - /* Gerade durch die beiden Punkte */ - - a = ( ( mitkIpFloat8_t ) box.y1 - ( mitkIpFloat8_t ) box.y0 ) / - ( ( mitkIpFloat8_t ) box.x1 - ( mitkIpFloat8_t ) box.x0 ); - - b = ( mitkIpFloat8_t ) box.y0 - a * box.x0; - - /* check which region (above/beneath) has to be changed */ - - if ( over == mitkIpFuncAbove ) - { - beg[0] = 0; end[0] = pic_old->n[0]; - beg[1] = 0; end[1] = MIN ( box.y0, box.y1 ); - /* printf ( "1.Rechteck: beg %d %d end: %d %d \n", beg[0], beg[1], end[0], end[1] ); */ - mitkIpPicFORALL_3 ( RECT, pic_new, beg, end, value ); - - beg[0] = ( box.y0 < box.y1 ) ? box.x1 : 0; - end[0] = ( box.y0 < box.y1 ) ? pic_old->n[0] : box.x0; - beg[1] = MIN ( box.y0, box.y1 ); - end[1] = MAX ( box.y0, box.y1 ); -/* printf ( "2.Rechteck: beg %d %d end: %d %d \n", beg[0], beg[1], end[0], end[1] ); */ - mitkIpPicFORALL_3 ( RECT, pic_new, beg, end, value ); - - beg[0] = box.x0; end[0] = box.x1; - beg[1] = MIN ( box.y0, box.y1 ); - end[1] = MAX ( box.y0, box.y1 ); -/* printf ( "1.Dreieck: beg %d %d end: %d %d \n", beg[0], beg[1], end[0], end[1] ); */ - mitkIpPicFORALL_6 ( TRI, pic_new, beg, end, value, a, b, KL ); - } - else if ( over == mitkIpFuncBeneath ) - { - beg[0] = 0; end[0] = pic_old->n[0]; - beg[1] = MAX ( box.y0, box.y1 ); end[1] = pic_old->n[1]; -/* printf ( "1.Rechteck: beg %d %d end: %d %d \n", beg[0], beg[1], end[0], end[1] ); */ - mitkIpPicFORALL_3 ( RECT, pic_new, beg, end, value ); - - beg[0] = ( box.y0 < box.y1 ) ? 0 : box.x1; - end[0] = ( box.y0 < box.y1 ) ? box.x0 : pic_old->n[0]; - beg[1] = MIN ( box.y0, box.y1 ); - end[1] = MAX ( box.y0, box.y1 ); -/* printf ( "2.Rechteck: beg %d %d end: %d %d \n", beg[0], beg[1], end[0], end[1] ); */ - mitkIpPicFORALL_3 ( RECT, pic_new, beg, end, value ); - - beg[0] = box.x0; end[0] = box.x1; - beg[1] = MIN ( box.y0, box.y1 ); - end[1] = MAX ( box.y0, box.y1 ); -/* printf ( "1.Dreieck: beg %d %d end: %d %d \n", beg[0], beg[1], end[0], end[1] ); */ - mitkIpPicFORALL_6 ( TRI, pic_new, beg, end, value, a, b, GR ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - - - return pic_new; -} - diff --git a/Utilities/IpFunc/Frame.c b/Utilities/IpFunc/Frame.c deleted file mode 100644 index 5d1393039b..0000000000 --- a/Utilities/IpFunc/Frame.c +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function adds a frame around an image - */ - -/** @brief adds a frame around an image - * - * The thickness of the frame can be chosen separately for each dimension - * (parameter edge). The original image will not be changed, instead a - * new one will be returned. - * - * @param pic_old image to which the frame will be added - * @param edge vector with the thichness' of the frame in each direction - * @param value this greyvalue is used for the frame - * - * $Log$ - * Revision 1.3 2005/10/05 16:31:55 nolden - * FIX: added newline to avoid warning - * - * Revision 1.2 2000/05/24 15:29:42 tobiask - * Changed the installation paths of the package. - * - * Revision 1.4 2000/05/04 12:52:10 ivo - * inserted BSD style license - * - * Revision 1.3 2000/03/06 17:02:39 ivo - * ipFunc now with doxygen documentation. - * - * Revision 1.2 2000/02/18 14:58:02 ivo - * Tags are now copied into newly allocated images. - * Bugs fixed in mitkIpFuncFrame, mitkIpFuncRegGrow, _mitkIpFuncBorderX and mitkIpFuncHitMiss. - * - * Revision 1.1.1.1 2000/02/18 15:30:50 ivo - * memory leak removed: mitkIpFuncKeep in call of mitkIpFuncWindowR substituted - * by mitkIpFuncKeep (pic_new is already a new image!). - * - * - * AUTHOR & DATE - */ - -#include "mitkIpFuncP.h" -mitkIpPicDescriptor *mitkIpFuncFrame ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *edge, - mitkIpFloat8_t value ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - - - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncFrame ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *edge, - mitkIpFloat8_t value ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - - pic_new = _mitkIpFuncBorderX ( pic_old, edge, value ); - if ( mitkIpFuncErrno > mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - else - pic_new = mitkIpFuncWindowR ( pic_new, pic_old, edge, mitkIpFuncNoKeep ); - - /* Copy Tags */ - - strncpy( pic_new->info->version, pic_old->info->version, _mitkIpPicTAGLEN ); - pic_new->info->tags_head = _mitkIpPicCloneTags( pic_old->info->tags_head ); - pic_new->info->write_protect = pic_old->info->write_protect; - - return ( pic_new ); -} -#endif diff --git a/Utilities/IpFunc/GaussF.c b/Utilities/IpFunc/GaussF.c deleted file mode 100644 index d45dbbef11..0000000000 --- a/Utilities/IpFunc/GaussF.c +++ /dev/null @@ -1,213 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function smoothes an image using a filtering mask which consists - * of elements calculated from a Gausian distribution - */ - -/** this function smoothes an image using a filtering mask which consists - * of elements calculated from a Gausian distribution - * - * @param pic_old pointer to original image - * @param len_mask number of mask elements for each dimension - * @param dim_mask dimension of mask - * @param border handling of the edge - * @arg @c mitkIpFuncBorderZero : set edge pixels to zero - * @arg @c mitkIpFuncBorderOld : keep greyvalues of original image - * - * @return pointer to smoothed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" -mitkIpPicDescriptor *mitkIpFuncGausF ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t len_mask, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncGaussF\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* --------------------------------------------------------------------- */ -/* -** function mitkIpFuncGausF -*/ -/* --------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncGausF ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t len_mask, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to new image structure */ - mitkIpPicDescriptor *pic_mask; /* pointer to mask */ - mitkIpUInt4_t n[_mitkIpPicNDIM]; /* size of each dimension */ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ - mitkIpUInt4_t i, k; /* loop index */ - mitkIpUInt4_t no_elem; /* number of mask elements */ - mitkIpUInt4_t offset; /* offset of pixels */ - mitkIpUInt4_t element; /* used to calculate mask elements */ - mitkIpUInt4_t sum; /* sum of all mask elements */ - mitkIpUInt4_t nn, nfac, kfac; /* used to calculate bin. coeff */ - mitkIpUInt4_t *bin; /* binomial coeffizients */ - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim < dim_mask || dim_mask < 1 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( len_mask % 2 != 1 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate binomial coefficient */ - - bin = malloc ( len_mask * sizeof ( mitkIpUInt4_t ) ); - if ( bin == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - nn = len_mask; - bin[0] = 1; - bin[nn-1] = 1; - nfac = 1; - kfac = 1; - - for ( k = 1; k < nn-1; k++ ) - { - kfac = k * kfac; - nfac = nfac * ( nn - k ); - bin[k] = nfac / kfac; - } - - /* initialize mask */ - - pic_mask = mitkIpPicNew(); - - if ( pic_mask == NULL ) - { - free ( bin ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_mask->type = mitkIpPicFloat; - pic_mask->bpe = 64; - pic_mask->dim = dim_mask; - - for ( i = 0; i < dim_mask; i++ ) pic_mask->n[i] = len_mask; - - pic_mask->data = malloc ( _mitkIpPicSize ( pic_mask ) ); - - if ( pic_mask->data == NULL ) - { - free ( bin ); - mitkIpPicFree ( pic_mask ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialize vectors */ - - for ( i = 0; i < pic_mask->dim; i++ ) - n[i] = len_mask; - for ( i = pic_mask->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 1; - - /* calculate mask */ - - offset = 0; - sum = 0; - for ( ind[7] = 0; ind[7] < n[7]; ind[7]++ ) - for ( ind[6] = 0; ind[6] < n[6]; ind[6]++ ) - for ( ind[5] = 0; ind[5] < n[5]; ind[5]++ ) - for ( ind[4] = 0; ind[4] < n[4]; ind[4]++ ) - for ( ind[3] = 0; ind[3] < n[3]; ind[3]++ ) - for ( ind[2] = 0; ind[2] < n[2]; ind[2]++ ) - for ( ind[1] = 0; ind[1] < n[1]; ind[1]++ ) - for ( ind[0] = 0; ind[0] < n[0]; ind[0]++ ) - { - element = 1; - for ( i = 0; i < pic_mask->dim; i++ ) - element = element * bin[ind[i]]; - - (( mitkIpFloat8_t * )pic_mask->data)[offset] = - ( mitkIpFloat8_t ) element; - sum = sum + element; - offset++; - } - - no_elem = _mitkIpPicElements ( pic_mask ); - for ( i = 0; i < no_elem; i++ ) - (( mitkIpFloat8_t * ) pic_mask->data ) [i] = - (( mitkIpFloat8_t * ) pic_mask->data ) [i] / ( mitkIpFloat8_t ) sum; - - /* convolve image with Gausian mask */ - - pic_new = mitkIpFuncConv ( pic_old, pic_mask, border ); - - mitkIpPicFree ( pic_mask ); - free ( bin ); - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} - -#endif - diff --git a/Utilities/IpFunc/Grad.c b/Utilities/IpFunc/Grad.c deleted file mode 100644 index 29881ff2f7..0000000000 --- a/Utilities/IpFunc/Grad.c +++ /dev/null @@ -1,358 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs an absolute gradient to extract - * edges of an image - */ - -/** @brief performs an absolute gradient to extract - * edges of an image - * - * @param pic_old pointer to original image - * @param dim_mask dimension of mask - * @param border tells how the edge is transformed - * mitkIpFuncBorderOld: original greyvalues - * mitkIpFuncBorderZero: edge is set to minimal greyvalue - * - * @return pointer to transformed iamge - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncGrad ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ) ; -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncGrad\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/* definition of macros */ - -#define GRAD( type, pic, pic_new, pic_mask, m, beg, end, dim_mask ) \ -{ \ - mitkIpUInt4_t i, j; /* loop index */ \ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* offset vector */ \ - mitkIpUInt4_t begin[_mitkIpPicNDIM]; \ - mitkIpFloat8_t help, help2; \ - \ - /* initialisation of vectors */ \ - \ - size [0] = 1; \ - for ( i = 1; i < pic->dim; i++ ) \ - size[i] = size[i-1] * pic_old->n[i-1]; \ - for ( i = pic->dim; i < _mitkIpPicNDIM; i++ ) \ - size[i] = 0; \ - \ - begin[0] = 0; \ - for ( i = 1; i <= dim_mask; i++ ) \ - begin[i] = begin[i-1] + m->length / dim_mask; \ - \ - /* transformation of image */ \ - \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = ind[7] * size[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = ind[6] * size[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = ind[5] * size[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = ind[4] * size[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = ind[3] * size[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = ind[2] * size[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = ind[1] * size[1] + off[2]; \ - off[0] = beg[0] + off[1]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - help2 = 0; \ - for ( j = 0; j < dim_mask; j++ ) \ - { \ - help = 0; \ - for ( i = begin[j]; i < begin[j+1]; i++ ) \ - { \ - help = help + m->mask_vekt[i] / sum * ( mitkIpFloat8_t )\ - (( type * )pic->data )[off[0]+m->off_vekt[i]];\ - } \ - help2 = help2 + help * help; \ - } \ - (( type * )pic_new->data)[off[0]] = \ - ( type ) sqrt ( help2 / dim_mask ) / 2.; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - -/* ----------------------------------------------------------------- */ -/* -** mitkIpFuncGrad -*/ -/* ----------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncGrad ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ) -{ - #include "gradient.h" - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpPicDescriptor *pic_mask; /* sobel mask */ - mitkIpUInt4_t pos; /* position in m->off_vekt */ - mitkIpUInt4_t i, j; /* loopindex */ - mitkIpUInt4_t off_mask; /* loopindex */ - mitkIpFuncMasc_t *m; /* compressed mask */ - mitkIpInt4_t offset; - mitkIpInt4_t beg[_mitkIpPicNDIM]; - mitkIpInt4_t end[_mitkIpPicNDIM]; - mitkIpInt4_t ind[_mitkIpPicNDIM]; - mitkIpUInt4_t size[_mitkIpPicNDIM]; - mitkIpInt4_t n[_mitkIpPicNDIM]; - mitkIpFloat8_t sum; - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( ( dim_mask > 4 ) || ( dim_mask < 1 ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( pic_old->dim < dim_mask ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* create a new picture, copy the header, allocate memory */ - - if ( border == mitkIpFuncBorderOld ) - pic_new = mitkIpPicClone ( pic_old ); - else if ( border == mitkIpFuncBorderZero ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe/8 ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new->data == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of pic_mask */ - - pic_mask = mitkIpPicNew (); - if ( pic_mask == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_mask->type = mitkIpPicInt; - pic_mask->bpe = 16; - pic_mask->dim = dim_mask+1; - for ( i = 0; i < dim_mask; i++ ) - pic_mask->n[i] = 3; - pic_mask->n[dim_mask] = dim_mask; - - if ( dim_mask == 4 ) - pic_mask->data = mask4; - else if ( dim_mask == 3 ) - pic_mask->data = mask3; - else if ( dim_mask == 2 ) - pic_mask->data = mask2; - else - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of vectors */ - - - for ( i = 0; i < dim_mask; i++ ) - n[i] = pic_mask->n[i] / 2 + 1; - for ( i = dim_mask; i < _mitkIpPicNDIM; i++ ) - n[i] = 0; - - for ( i = 0; i < dim_mask; i++ ) - { - end[i] = pic_old->n[i] - pic_mask->n[i] / 2; - beg[i] = ( ( pic_mask->n[i] % 2 ) == 1 ) ? - ( pic_mask->n[i] / 2 ) : ( pic_mask->n[i] / 2 - 1 ); - } - for ( i = dim_mask; i < _mitkIpPicNDIM; i++ ) - beg[i] = 0; - - for ( i = dim_mask; i < pic_old->dim; i++ ) - end[i] = pic_old->n[i]; - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - end[i] = beg[i] + 1; - - size [0] = 1; - for ( i = 1; i < pic_old->dim; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - - - /* allocate mask-structure */ - - m = malloc ( sizeof ( mitkIpFuncMasc_t ) ); - if ( m == NULL ) - { - mitkIpPicFree ( pic_new ); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - m->off_vekt = malloc ( _mitkIpPicElements( pic_mask ) * sizeof ( mitkIpInt4_t ) ); - if ( m->off_vekt == NULL ) - { - mitkIpPicFree ( pic_new ); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - free ( m ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - m->mask_vekt = malloc ( _mitkIpPicElements( pic_mask ) * sizeof ( mitkIpFloat8_t ) ); - if ( m->mask_vekt == NULL ) - { - mitkIpPicFree ( pic_new ); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - free ( m->off_vekt ); - free ( m ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate offset vector for the compressed mask */ - - m->length = 0; - - off_mask = 0; - for ( i = 0; i < pic_mask->n[dim_mask] ; i++ ) - for ( ind[3] = -1; ind[3] < n[3]; ind[3]++ ) - for ( ind[2] = -1; ind[2] < n[2]; ind[2]++ ) - for ( ind[1] = -1; ind[1] < n[1]; ind[1]++ ) - for ( ind[0] = -1; ind[0] < n[0]; ind[0]++ ) - { - if ( (( mitkIpInt2_t * )pic_mask->data)[off_mask] != 0 ) - { - offset = 0; - for ( j = 0; j < dim_mask; j++ ) - offset = offset + ind[j] * size[j]; - m->off_vekt[m->length] = offset; - m->length++; - } - off_mask++; - } - - /* remove elements that are zero from mask */ - - pos = 0; - sum = 0; - for ( i = 0; i < m->length; i++ ) - { - while ( (( mitkIpInt2_t * )pic_mask->data)[pos] == 0 ) pos++; - m->mask_vekt[i] = ( mitkIpFloat8_t )(( mitkIpInt2_t * )pic_mask->data)[pos]; - sum = sum + fabs ( m->mask_vekt[i] ); - pos++; - } - - sum = sum / ( 2 * dim_mask ); - - mitkIpPicFORALL_6 ( GRAD, pic_old, pic_new, pic_mask, m, beg, end, dim_mask ); - - free ( m->off_vekt ); - free ( m->mask_vekt ); - free ( m ); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/Grav.c b/Utilities/IpFunc/Grav.c deleted file mode 100644 index 623ce9243f..0000000000 --- a/Utilities/IpFunc/Grav.c +++ /dev/null @@ -1,159 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * This Function calculates the center of gravity of an region of - * interest in an binary image - */ - -/** @brief calculates the center of gravity of an region of - * interest in an binary image - * - * @param pic binary image: contains the region of interest - * - * @return pointer to the vector which contains the coordinates - * of the center of gravity - * - * AUTHOR & DATE - */ - - - -/* include Files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t *mitkIpFuncGrav ( mitkIpPicDescriptor *pic_old ); - -#ifndef DOXYGEN_IGNORE - -/* definition of reflect-macro */ - -#define GRAV( type, pic, index ) \ -{ \ - mitkIpUInt4_t i; \ - mitkIpUInt4_t no; \ - mitkIpUInt4_t offset_refl; \ - mitkIpInt4_t n[_mitkIpPicNDIM]; \ - \ - for ( i = 0; i < pic_old->dim; i++ ) \ - n[i] = pic_old->n[i]; \ - \ - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) \ - n[i] = 1; \ - \ - no = 0; \ - offset_refl = 0; \ - for ( index[7] = 0; index[7] < n[7]; index[7]++ ) \ - \ - for ( index[6] = 0; index[6] < n[6]; index[6]++ ) \ - \ - for ( index[5] = 0; index[5] < n[5]; index[5]++ ) \ - \ - for ( index[4] = 0; index[4] < n[4]; index[4]++ ) \ - \ - for ( index[3] = 0; index[3] < n[3]; index[3]++ ) \ - \ - for ( index[2] = 0; index[2] < n[2]; index[2]++ ) \ - \ - for ( index[1] = 0; index[1] < n[1]; index[1]++ ) \ - \ - for ( index[0] = 0; index[0] < n[0]; index[0]++ ) \ - { \ - if ( (( type * )pic->data )[offset_refl] ) \ - { \ - for ( i = 0; i < pic->dim; i++ ) \ - { \ - gravity[i] = gravity[i] + index[i]; \ - } \ - no++; \ - } \ - offset_refl++; \ - } \ - \ - for ( i = 0; i < pic->dim; i++ ) gravity[i] = gravity[i]/no; \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpFloat8_t *mitkIpFuncGrav ( mitkIpPicDescriptor *pic_old ) -{ - - mitkIpUInt4_t index_vect[_mitkIpPicNDIM]; /* loopindex-vector */ - mitkIpInt4_t n[_mitkIpPicNDIM]; /* number of pixels in each */ - /* dimension */ - mitkIpUInt4_t i; /* loop index */ - mitkIpFloat8_t *gravity; - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* initialisation of vectors */ - - for ( i = 0; i < pic_old->dim; i++ ) - n[i] = pic_old->n[i]; - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 1; - - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - index_vect[i] = 0; - - gravity = ( mitkIpFloat8_t * ) malloc ( 8 * sizeof ( mitkIpFloat8_t ) ); - if ( gravity == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - gravity[i] = 0.; - - mitkIpPicFORALL_1 ( GRAV, pic_old, index_vect ) - - return gravity; -} -#endif diff --git a/Utilities/IpFunc/Hist.c b/Utilities/IpFunc/Hist.c deleted file mode 100644 index c7ce45a968..0000000000 --- a/Utilities/IpFunc/Hist.c +++ /dev/null @@ -1,174 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function calculates the greyvalue histogram of an image - */ - -/** this function calculates the greyvalue histogram of an image - * - * @param pic_old pointer to the image that should be inverted - * @param min_gv min. greyvalue in histogram - * @param max_gv max. greyvalue in histogram - * @param hist pointer to the greyvalue histogram ( return value ) - * @param size_hist pointer to the number of elements in the histogram - * ( result value ) - * - * @return @arg @c mitkIpFuncERROR - if an error occured - * @return @arg @c mitkIpFuncOK - if no error occured - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpInt4_t mitkIpFuncHist ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t min_gv, - mitkIpFloat8_t max_gv, - mitkIpUInt4_t **hist, - mitkIpUInt4_t *size_hist ) ; - -#ifndef DOXYGEN_IGNORE - - -#ifndef lint - static char *what = { "@(#)mitkIpFuncHist\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* definition of HIST-macro */ - -#define HIST( type, pic, help, factor ) \ -{ \ - mitkIpUInt4_t i; \ - mitkIpUInt4_t no_elem; \ - mitkIpUInt4_t index; \ - \ - /* calculate histogram */ \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - index = ( mitkIpUInt4_t ) \ - ( factor * ( (( type * ) pic->data)[i] + ( type ) help) );\ - ( hist_help[index] )++; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpInt4_t mitkIpFuncHist ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t min_gv, - mitkIpFloat8_t max_gv, - mitkIpUInt4_t **hist, - mitkIpUInt4_t *size_hist ) -{ - mitkIpUInt4_t *hist_help; - mitkIpFloat8_t help; /* absolute of min_gv */ - mitkIpFloat8_t min, max; /* extreme greyvalues */ - mitkIpUInt4_t factor; /* factor to calculate histogram of */ - /* float images */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( min_gv == 0 && max_gv == 0 ) - { - if ( mitkIpFuncExtr ( pic_old, &min_gv, &max_gv ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - } - else - { - if ( min_gv > max_gv ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( mitkIpFuncExtr ( pic_old, &min, &max ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( min_gv > min || max_gv < max ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - /* calculate variables which are necessary to calculate histogram */ - /* index */ - - help = fabs ( min_gv ); - - if ( pic_old->type == mitkIpPicInt || pic_old->type == mitkIpPicUInt ) - factor = 1; - else if ( pic_old->type == mitkIpPicFloat ) - factor = 1000; - else - { - _mitkIpFuncSetErrno (mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory */ - - *size_hist = factor * ( ( mitkIpUInt4_t ) max_gv + ( mitkIpUInt4_t ) help ); - -/*hist = ( mitkIpUInt4_t ** ) malloc ( sizeof ( mitkIpUInt4_t * ) );*/ - *hist = ( mitkIpUInt4_t * ) calloc ( *size_hist+1, sizeof ( mitkIpUInt4_t ) ); - hist_help = *hist; - if ( hist_help == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to calculate the histogram */ - - mitkIpPicFORALL_2 ( HIST, pic_old, help, factor ); - - return ( mitkIpFuncOK ); -} -#endif diff --git a/Utilities/IpFunc/Histo.c b/Utilities/IpFunc/Histo.c deleted file mode 100644 index 5c3644ec4f..0000000000 --- a/Utilities/IpFunc/Histo.c +++ /dev/null @@ -1,180 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function calculates the greyvalue histogram of an image - */ - -/** this function calculates the greyvalue histogram of an image - * - * @param pic_old pointer to the image that should be inverted - * @param min_gv min. greyvalue in histogram; if min_gv==max_gv==0 - * the min/max greyvalues are calculated - * @param max_gv max. greyvalue in histogram - * @param hist pointer to the greyvalue histogram ( return value ) - * @param size_hist pointer to the number of elements in the histogram - * ( result value ) - * - * @return @arg @c mitkIpFuncERROR - if an error occured - * @return @arg @c mitkIpFuncOK - if no error occured - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpInt4_t mitkIpFuncHisto( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min_gv, - mitkIpFloat8_t *max_gv, - mitkIpUInt4_t **hist, - mitkIpUInt4_t *size_hist ) ; - -#ifndef DOXYGEN_IGNORE - -/* definition of HIST-macro */ - -#define HIST( type, pic, help, factor ) \ -{ \ - mitkIpUInt4_t i; \ - mitkIpUInt4_t no_elem; \ - mitkIpUInt4_t index; \ - \ - /* calculate histogram */ \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - index = ( mitkIpUInt4_t ) \ - ( factor * ( (( type * ) pic->data)[i] - ( type )*min_gv ) );\ - if ( ( index <= *size_hist ) ) \ - ( hist_help[index] )++; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpInt4_t mitkIpFuncHisto( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min_gv, - mitkIpFloat8_t *max_gv, - mitkIpUInt4_t **hist, - mitkIpUInt4_t *size_hist ) -{ - mitkIpUInt4_t *hist_help; - mitkIpFloat8_t help; /* absolute of min_gv */ - mitkIpFloat8_t min, max; /* extreme greyvalues */ - mitkIpUInt4_t factor; /* factor to calculate histogram of */ - /* float images */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( *min_gv == 0 && *max_gv == 0 ) - { - if ( mitkIpFuncExtr ( pic_old, min_gv, max_gv ) != mitkIpFuncOK ) - { - printf("ipFunc: Probleme mit dem eingegebenen Intervall\n"); - return ( mitkIpFuncERROR ); - } - } - else - { - if ( *min_gv > *max_gv ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - printf("ipFunc: Probleme mit dem eingegebenen Intervall\n"); - return ( mitkIpFuncERROR ); - } - if ( mitkIpFuncExtr ( pic_old, &min, &max ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( *min_gv < min || *max_gv > max ) - { - printf("ipFunc: Probleme mit dem von ipFunc Extrema berechnete Intervall\n"); - printf("ipFunc: Von Extrema: %f %f \n", *min_gv, *max_gv); - /* - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - */ - } - } - - /* calculate variables which are necessary to calculate histogram */ - /* index */ - - help = fabs ( *min_gv ); - - if ( pic_old->type == mitkIpPicInt || pic_old->type == mitkIpPicUInt ) - factor = 1; - else if ( pic_old->type == mitkIpPicFloat ) - factor = 1000; - else - { - printf("ipFunc: Probleme mit dem von ipFunc Extrema berechnete Intervall\n"); - _mitkIpFuncSetErrno (mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory */ - - *size_hist = 1 + factor * (mitkIpUInt4_t ) ( ( mitkIpInt4_t ) *max_gv - ( mitkIpInt4_t ) *min_gv ); - -/*hist = ( mitkIpUInt4_t ** ) malloc ( sizeof ( mitkIpUInt4_t * ) );*/ - *hist = ( mitkIpUInt4_t * ) calloc ( *size_hist+1, sizeof ( mitkIpUInt4_t ) ); - hist_help = *hist; - if ( hist_help == NULL ) - { - printf("ipFunc: Probleme mit dem Allokieren von Platz\n"); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to calculate the histogram */ - - mitkIpPicFORALL_2 ( HIST, pic_old, help, factor ); - - return ( mitkIpFuncOK ); -} -#endif - diff --git a/Utilities/IpFunc/HitMiss.c b/Utilities/IpFunc/HitMiss.c deleted file mode 100644 index 1c358fe2c1..0000000000 --- a/Utilities/IpFunc/HitMiss.c +++ /dev/null @@ -1,132 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs the morphological hit and miss operation - */ - -/** @brief performs the morphological hit and miss operation - * - * @param pic_old pointer to original image - * @param pic_masks pointer to a set of hit and miss masks - * ( if pic_masks = NULL -> default masks are used ) - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to minimal greyvalue - * - * @return pointer to image after hit and miss operation - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncHitMiss ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_masks, - mitkIpFuncFlagI_t border ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncHitMiss\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* ------------------------------------------------------------------ */ -/* -** mitkIpFuncHitMiss -*/ -/* ------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncHitMiss ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_masks, - mitkIpFuncFlagI_t border ) -{ - mitkIpBool_t allocated=mitkIpFalse; - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt1_t mask[] = /* hit and miss mask (edge detection) */ - { 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0 }; - - if ( pic_masks == NULL ) - { - allocated = mitkIpTrue; - pic_masks = mitkIpPicNew (); - if ( pic_masks == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_masks->dim = 3; - pic_masks->type = mitkIpPicUInt; - pic_masks->bpe = 8; - pic_masks->n[0] = 3; - pic_masks->n[1] = 3; - pic_masks->n[2] = 8; - pic_masks->data = mask; - } - pic_new = _mitkIpFuncHitMissI ( pic_old, pic_masks, border ); - - if ( allocated ) - { - pic_masks->data = NULL; - mitkIpPicFree ( pic_masks ); - } - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/HitMissI.c b/Utilities/IpFunc/HitMissI.c deleted file mode 100644 index 834a412fe8..0000000000 --- a/Utilities/IpFunc/HitMissI.c +++ /dev/null @@ -1,314 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* performs the morphological hit and miss operator - * - * FUNCTION DECLARATION - * mitkIpPicDescriptor *_mitkIpFuncHitMissI( mitkIpPicDescriptor *pic_old, - * mitkIpPicDescriptor *pic_masks, - * mitkIpFuncFlagI_t border ) - * - * PARAMETERS - * - * RETURN VALUES - * - * AUTHOR & DATE - * Antje Schroeder 05.09.95 - * - * UPDATES - * a short history of the file - * - *--------------------------------------------------------------------- - */ -#ifndef lint - static char *what = { "@(#)mitkIpFuncHitMissI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - -#include "mitkIpFuncP.h" - -/* definition of macros */ - -#define C_MASC( typ, pic_masks, m1, m2, end_m, beg_m1, beg_m2 ) \ -{ \ - mitkIpUInt4_t no_elem; \ - mitkIpUInt4_t i; /* loop variable */ \ - \ - /* copy pic_masks to mask_1 and mask_2 */ \ - \ - for ( i = 0; i < end_m; i++ ) \ - { \ - (( typ * )mask_1->data )[i] = (( typ * )pic_masks->data )[i + beg_m1]; \ - (( typ * )mask_2->data )[i] = (( typ * )pic_masks->data )[i + beg_m2]; \ - } \ - \ - /* check mask data */ \ - \ - no_elem = _mitkIpPicElements ( mask_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - if ( (( typ * )mask_1->data )[i] != 0 && \ - (( typ * )mask_2->data )[i] != 0 ) \ - { \ - mitkIpPicFree ( mask_1 ); \ - mitkIpPicFree ( mask_2 ); \ - mitkIpPicFree ( pic_1 ); \ - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); \ - return ( mitkIpFuncERROR ); \ - } \ - \ - /* compress masks */ \ - \ - m1 = _mitkIpFuncCompressM ( mask_1, pic_old, mitkIpFuncNoReflect, beg, end ); \ - m2 = _mitkIpFuncCompressM ( mask_2, pic_old, mitkIpFuncNoReflect, beg, end ); \ - \ -} - -#define HITMISS( type_i, pic_old, pic_new, pic_inv ) \ -{ \ - type_i help; \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t end_m; /* loop index */ \ - mitkIpUInt4_t beg_m1; /* */ \ - mitkIpUInt4_t beg_m2; /* */ \ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* offset vector */ \ - mitkIpFloat8_t max, min; /* max and min possible greyvalue */ \ - \ - /* initialisation of vectors */ \ - \ - size [0] = 1; \ - for ( i = 1; i < _mitkIpPicNDIM; i++ ) \ - size[i] = size[i-1] * pic_old->n[i-1]; \ - size[pic_old->dim] = 0; \ - \ - \ - /* calculate max. and min. possible greyvalues */ \ - \ - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min, &max ) != mitkIpFuncOK ) \ - { \ - mitkIpPicFree ( mask_1 ); \ - mitkIpPicFree ( mask_2 ); \ - mitkIpPicFree ( pic_1 ); \ - return ( mitkIpFuncERROR ); \ - } \ - \ - /* transformation of image */ \ - \ - end_m = _mitkIpPicElements ( pic_masks ) / pic_masks->n[dim] ; \ - for ( j = 0; j < pic_masks->n[dim] / 2; j++ ) \ - { \ - /* copy masks and compress them */ \ - \ - beg_m1 = 2 * j * end_m; \ - beg_m2 = beg_m1 + end_m; \ - mitkIpPicFORALL_5 ( C_MASC, pic_masks, m1, m2, end_m, beg_m1, beg_m2 ); \ - \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = ind[7] * size[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = ind[6] * size[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = ind[5] * size[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = ind[4] * size[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = ind[3] * size[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = ind[2] * size[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = ind[1] * size[1] + off[2]; \ - off[0] = beg[0] + off[1]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - help = (( type_i * ) \ - pic_old->data )[off[0]+ m1->off_vekt[0]]; \ - for ( i = 1; i < m1->length; i++ ) \ - { \ - help = help && \ - (( type_i * )pic_old->data ) \ - [m1->off_vekt[i]+off[0]]; \ - } \ - for ( i = 0; i < m2->length; i++ ) \ - { \ - help = help && \ - (( type_i * )pic_inv->data ) \ - [m2->off_vekt[i]+off[0]]; \ - } \ - (( type_i * )pic_new->data )[off[0]] = ( (( type_i * ) \ - pic_new->data )[off[0]] || ( type_i ) help ) * max;\ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - free ( m1->off_vekt ); \ - free ( m1->mask_vekt ); \ - free ( m1 ); \ - free ( m2->off_vekt ); \ - free ( m2->mask_vekt ); \ - free ( m2 ); \ - } \ -} - - -/* ------------------------------------------------------------------------- */ -/* -** mitkIpFuncHitMissI -*/ -/* ------------------------------------------------------------------------- */ - - mitkIpPicDescriptor *_mitkIpFuncHitMissI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_masks, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_inv; /* pointer to the inverted image */ - mitkIpPicDescriptor *pic_1; /* image after hit and miss */ - mitkIpPicDescriptor *mask_1; /* hit mask */ - mitkIpPicDescriptor *mask_2; /* miss mask */ - mitkIpInt4_t beg[_mitkIpPicNDIM]; /* */ - mitkIpInt4_t end[_mitkIpPicNDIM]; /* */ - mitkIpFuncMasc_t *m1, *m2; /* compressed masks */ - mitkIpUInt4_t dim; /* dimension of mask */ - mitkIpUInt4_t j; /* loop variable */ - - /* check image data and mask data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_masks ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* allocate memory for masks */ - - dim = pic_masks->dim - 1; - mask_1 = mitkIpPicCopyHeader ( pic_masks, NULL ); - mask_1->dim = dim; - if ( mask_1 == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - mask_1->data = malloc ( _mitkIpPicSize ( mask_1 ) ); - if ( mask_1->data == NULL ) - { - mitkIpPicFree ( mask_1 ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - mask_2 = mitkIpPicCopyHeader ( mask_1, NULL ); - if ( mask_2 == NULL ) - { - mitkIpPicFree ( mask_1 ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - mask_2->data = malloc ( _mitkIpPicSize ( mask_2 ) ); - if ( mask_2->data == NULL ) - { - mitkIpPicFree ( mask_1 ); - mitkIpPicFree ( mask_2 ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate images */ - - if ( border == mitkIpFuncBorderOld ) - { - pic_1 = mitkIpPicClone ( pic_old ); - memset ( pic_1->data, 0, _mitkIpPicElements ( pic_1 ) ); - } - else if ( border == mitkIpFuncBorderZero ) - { - pic_1 = mitkIpPicCopyHeader ( pic_old, 0 ); - pic_1->data = calloc ( _mitkIpPicElements ( pic_1 ), pic_1->bpe/8 ); - } - else - { - mitkIpPicFree ( mask_1 ); - mitkIpPicFree ( mask_2 ); - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_1 == NULL ) - { - mitkIpPicFree ( mask_1 ); - mitkIpPicFree ( mask_2 ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_1->data == NULL ) - { - mitkIpPicFree ( mask_1 ); - mitkIpPicFree ( mask_2 ); - mitkIpPicFree ( pic_1 ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_inv = mitkIpFuncInv ( pic_old, NULL ); - if ( pic_inv == NULL ) - { - mitkIpPicFree ( mask_1 ); - mitkIpPicFree ( mask_2 ); - mitkIpPicFree ( pic_1 ); - } - - mitkIpPicFORALL_2 ( HITMISS, pic_old, pic_1, pic_inv ); - - mitkIpPicFree ( pic_inv ); - mitkIpPicFree ( mask_1 ); - mitkIpPicFree ( mask_2 ); - - return ( pic_1 ); -} diff --git a/Utilities/IpFunc/Inertia.c b/Utilities/IpFunc/Inertia.c deleted file mode 100644 index 86a0afc0fe..0000000000 --- a/Utilities/IpFunc/Inertia.c +++ /dev/null @@ -1,299 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * mitkIpFuncInertia - *--------------------------------------------------------------------- - * DESCRIPTION - * function to calculate the moments of inertia of a region of - * interest - * - * FUNCTION DECLARATION - * mitkIpInt4_t mitkIpFuncInertia ( mitkIpPicDescriptor *pic_old, - * mitkIpFloat8_t **eigen_vekt, - * mitkIpFloat8_t **eigen_val ) - * - * PARAMETERS - * pic_old - pointer to an image structure which contains the ROI - * eigen_vekt - contains the axis of inertia (spaltenweise) - * eigen_val - eigenvalues of the tensor of inertia - * - * RETURN VALUES - * mitkIpFuncOK - no error occured - * mitkIpFuncERROR - an error occured - * - * UPDATES - * update of Manu's program to calculate axis of inertia. It's a - * function now, which can be used for images of different data - * types and for images up to 8 dimensions now - * - * AUTHOR & DATE - * Antje Schroeder 08.06.95 - * - *--------------------------------------------------------------------- - */ -/* include Files */ - -#include "mitkIpFuncP.h" - -#ifdef MESCHACH -#include <float.h> - -/* definition of reflect-macro */ - -#define GRAV( type, pic, index, s, s_diag, dist ) \ -{ \ - mitkIpUInt4_t i; \ - mitkIpUInt4_t no; \ - mitkIpUInt4_t offset_refl; \ - mitkIpInt4_t n[_mitkIpPicNDIM]; \ - \ - for ( i = 0; i < pic_old->dim; i++ ) \ - n[i] = pic_old->n[i]; \ - \ - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) \ - n[i] = 1; \ - \ - offset_refl = 0; \ - for ( index[7] = 0; index[7] < n[7]; index[7]++ ) \ - \ - for ( index[6] = 0; index[6] < n[6]; index[6]++ ) \ - \ - for ( index[5] = 0; index[5] < n[5]; index[5]++ ) \ - \ - for ( index[4] = 0; index[4] < n[4]; index[4]++ ) \ - \ - for ( index[3] = 0; index[3] < n[3]; index[3]++ ) \ - \ - for ( index[2] = 0; index[2] < n[2]; index[2]++ ) \ - \ - for ( index[1] = 0; index[1] < n[1]; index[1]++ ) \ - \ - for ( index[0] = 0; index[0] < n[0]; index[0]++ ) \ - { \ - if ( (( type * )pic->data )[offset_refl] ) \ - { \ - for ( i = 0; i < pic->dim; i++ ) \ - { \ - dist[i] = index[i] - gravity[i]; \ - s_diag[i] = s_diag[i] + dist[i] * dist[i]; \ - } \ - \ - for ( i = 0; i < pic->dim; i++ ) \ - for ( j = 0; j < pic->dim; j++ ) \ - s[i*pic->dim+j] = s[i*pic->dim+j] - dist[i] * dist[j];\ - } \ - offset_refl++; \ - } \ - \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpInt4_t mitkIpFuncInertia ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t **eigen_vekt, - mitkIpFloat8_t **eigen_val ) -{ - - mitkIpUInt4_t index_vect[_mitkIpPicNDIM]; /* loopindex-vector */ - mitkIpInt4_t n[_mitkIpPicNDIM]; /* number of pixels in each */ - /* dimension */ - mitkIpUInt4_t i, j; /* loop index */ - mitkIpFloat8_t *gravity; /* center of gravity */ - mitkIpFloat8_t *help_vekt; /* pointer to eigen_vekt */ - mitkIpFloat8_t *help_val; /* pointer to eigen_val */ - MAT *ev; /* eigenvector */ - MAT *tt; /* tensor of inertia */ - VEC *ew; /* eigenvalue */ - mitkIpFloat8_t *s, *s_diag, *dist; /* used to calculate tt */ - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* initialisation of vectors */ - - for ( i = 0; i < pic_old->dim; i++ ) - n[i] = pic_old->n[i]; - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 1; - - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - index_vect[i] = 0; - - /* memory allocation */ - - gravity = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * sizeof ( mitkIpFloat8_t ) ); - if ( gravity == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - dist = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * sizeof ( mitkIpFloat8_t ) ); - if ( dist == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - free ( gravity ); - return ( mitkIpFuncERROR ); - } - - s_diag = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * sizeof ( mitkIpFloat8_t ) ); - if ( s_diag == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - free ( gravity ); - free ( dist ); - return ( mitkIpFuncERROR ); - } - - s = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * pic_old->dim * sizeof ( mitkIpFloat8_t ) ); - if ( s == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - free ( gravity ); - free ( dist ); - free ( s_diag ); - return ( mitkIpFuncERROR ); - } - - tt = m_get ( pic_old->dim, pic_old->dim ); - if ( tt == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - free ( gravity ); - free ( dist ); - free ( s_diag ); - free ( s ); - return ( mitkIpFuncERROR ); - } - - ev = m_get ( pic_old->dim, pic_old->dim ); - if ( ev == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - free ( gravity ); - free ( dist ); - free ( s_diag ); - free ( s ); - M_FREE ( tt ); - return ( mitkIpFuncERROR ); - } - - ew = v_get ( pic_old->dim-1 ); - if ( ew == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - free ( gravity ); - free ( dist ); - free ( s_diag ); - free ( s ); - M_FREE ( tt ); - M_FREE ( ev ); - return ( mitkIpFuncERROR ); - } - - /* calculate center of gravity */ - - gravity = mitkIpFuncGrav ( pic_old ); - - /* Initialization of vectors */ - - for ( i = 0; i < pic_old->dim; i++ ) - { - s_diag[i] = 0.; - dist[i] = 0.; - for ( j = 0; j < pic_old->dim; j++ ) - s[i*pic_old->dim+j] = 0.; - } - - /* preparation for calculating the tensor of inertia */ - - mitkIpPicFORALL_4 ( GRAV, pic_old, index_vect, s, s_diag, dist ) - - /* calculate tensor of inertia */ - - for ( i = 0; i < pic_old->dim; i++ ) - { - tt->me[i][i] = 0.; - for ( j = 0; j < pic_old->dim; j++ ) - { - if ( i < j ) - tt->me[i][j] = s[i*pic_old->dim+j]; - else if ( j < i ) - tt->me[i][j] = s[j*pic_old->dim+i]; - if ( i != j ) - tt->me[i][i] = tt->me[i][i] + s_diag[j]; - } - } - - /* calculate eigenvectors and eigenvalues of the tensor of inertia */ - - ew = symmeig ( tt, ev, ew ); - - *eigen_vekt = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * pic_old->dim * sizeof ( mitkIpFloat8_t ) ); - help_vekt = *eigen_vekt; - *eigen_val = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * sizeof ( mitkIpFloat8_t ) ); - help_val = *eigen_val; - - for ( i = 0; i < pic_old->dim; i++ ) - { - help_val[i] = ew->ve[i]; - for ( j = 0; j < pic_old->dim; j++ ) - help_vekt[i*pic_old->dim+j] = ev->me[i][j]; - } - - M_FREE ( tt ); - M_FREE ( ev ); - V_FREE ( ew ); - free ( s ); - free ( dist ); - free ( s_diag ); - free ( gravity ); - - return mitkIpFuncOK; -} -#endif diff --git a/Utilities/IpFunc/Inv.c b/Utilities/IpFunc/Inv.c deleted file mode 100644 index f498a9514c..0000000000 --- a/Utilities/IpFunc/Inv.c +++ /dev/null @@ -1,133 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file -* this function inverts the greyvalues of an image -*/ - -/** @brief inverts the greyvalues of an image - * - * @param pic_old pointer to the image that should be inverted - * @param pic_return memory which could be used for pic_new. If - * pic_retrun == NULL new memory is allocated - * - * @return pointer to the inverted image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncInv ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncInv\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of invert-macro */ - -#define INV( type, pic ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - type help; \ - \ - /* calculate min. and max. */\ - \ - type max = ( ( type * ) pic->data ) [0]; \ - type min = ( ( type * ) pic->data ) [0]; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 1; i < no_elem; i++ ) \ - { \ - help = ( ( type * ) pic->data ) [i]; \ - max = ( help > max ) ? help : max; \ - min = ( help < min ) ? help : min; \ - } \ - \ - /* invert greyvalues */\ - \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type * ) pic_new->data ) [i] = \ - max + min - (( type * ) pic->data ) [i]; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncInv ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* create a new picture, copy the header, allocate memory */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to invert the picture (for all data types) */ - - mitkIpPicFORALL ( INV, pic_old ); - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/LN.c b/Utilities/IpFunc/LN.c deleted file mode 100644 index a5c73ce5ef..0000000000 --- a/Utilities/IpFunc/LN.c +++ /dev/null @@ -1,222 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function transforms the greyvalues by a ln-function - * (y = a ln (x+1)) - */ - -/** @brief transforms the greyvalues by a ln-function - * (y = a ln (x+1)) - * - * @param pic_old pointer to the original image - * - * @return pointer to the transformed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncLN ( mitkIpPicDescriptor *pic_old ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncLN\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/* definition of macros */ - -#define LN( type, pic, max_gv ) \ -{ \ - mitkIpUInt4_t i; /* loopindex */\ - mitkIpUInt4_t no_elem; /* number of pixels */\ - mitkIpFloat8_t a; /* factor to calculate the logaritm */\ - \ - a = max_gv / log ( max_gv + 1. ); \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - (( type * )pic_new->data )[i] = \ - ( type ) ( a * log ( 1. + (( type * )pic->data )[i] ) ); \ -} - -/* ------------------------------------------------------------------------ */ -/* -** function mitkIpFuncLN -*/ -/* ------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncLN ( mitkIpPicDescriptor *pic_old ) -{ - mitkIpFloat8_t min_gv, max_gv; /* max and min posiible greyvalues */ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t no_elem; /* loop index */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* check datatype of image */ - - no_elem = _mitkIpPicElements ( pic_old ); - if ( pic_old->type == mitkIpPicUInt ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->data = malloc ( _mitkIpPicSize ( pic_old ) ); - - if ( ( pic_new != NULL ) && ( pic_new->data != NULL ) ) - { - mitkIpPicFORALL_1 ( LN, pic_old, max_gv ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - /* mitkIpPicInt images are copied to mitkIpPicUInt iamges to avoid negative */ - /* greyvalues */ - - else if ( pic_old->type == mitkIpPicInt ) - { - pic_new = mitkIpPicNew (); - if ( pic_new != NULL ) - { - pic_new->type = mitkIpPicUInt; - pic_new->bpe = pic_old->bpe; - pic_new->dim = pic_old->dim; - for ( i = 0; i < pic_new->dim; i++ ) pic_new->n[i] = pic_old->n[i]; - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* transform integer image to unsigned integer image */ - - if ( pic_new->bpe == 8 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpUInt1_t * )pic_new->data )[i] = - (( mitkIpInt1_t * )pic_old->data )[i] - min_gv; - } - - else if ( pic_new->bpe == 16 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpUInt2_t * )pic_new->data )[i] = - (( mitkIpInt2_t * )pic_old->data )[i] - min_gv; - } - - else if ( pic_new->bpe == 32 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpUInt4_t * )pic_new->data )[i] = - (( mitkIpInt4_t * )pic_old->data )[i] - min_gv; - } - - else - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - max_gv = max_gv - min_gv; - - mitkIpPicFORALL_1 ( LN, pic_new, max_gv ); - - /* transform unsigned integer image to an integer image */ - - pic_new->type = mitkIpPicInt; - - if ( pic_new->bpe == 8 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpInt1_t * )pic_new->data )[i] = - (( mitkIpUInt1_t * )pic_new->data )[i] + min_gv; - } - - else if ( pic_new->bpe == 16 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpInt2_t * )pic_new->data )[i] = - (( mitkIpUInt2_t * )pic_new->data )[i] + min_gv; - } - - else if ( pic_new->bpe == 32 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpInt4_t * )pic_new->data )[i] = - (( mitkIpUInt4_t * )pic_new->data )[i] + min_gv; - } - - } - - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif diff --git a/Utilities/IpFunc/Label.c b/Utilities/IpFunc/Label.c deleted file mode 100644 index 27e163fd5e..0000000000 --- a/Utilities/IpFunc/Label.c +++ /dev/null @@ -1,363 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * This functions looks for areas in an image with the same greyvalue. - * Each of these areas gets it's own greyvalue. - */ - -/** This functions looks for areas in an image with the same greyvalue. - * Each of these areas gets it's own greyvalue. - * - * CAUTION! In case of many small regions to label, the routine may - * break down without exception handling, if the number of labels is - * running out. - * - * @param pic_old pointer to original image structure - * @param no_label number of different labels (return value) - * - * @return pointer to new image - * - * USES - * function _mitkIpFuncError - checks image data - * function _mitkIpFuncExtr - calculates extreme greyvalues - * function _mitkIpFuncHist - calculates greyvalue histogram - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncLabel ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *no_lab ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncLabel\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - -#define LABEL1( type, pic_old, pic_new, no_label, type_new ) \ -{ \ - mitkIpUInt4_t i, j; /* loop index */ \ - mitkIpUInt4_t offset; /* offset of actual pixel */ \ - mitkIpBool_t in_lab; /* currently in label flag */ \ - mitkIpUInt4_t end; \ - \ - offset = 0; \ - no_label = 0; \ - \ - end = _mitkIpPicElements ( pic_old ) / pic_old->n[0]; \ - for ( j = 0; j < end; j++ ) \ - for ( i = 0, in_lab = mitkIpFalse; i < pic_old->n[0]; i++ ) \ - { \ - /*if ( (( type * )pic_old->data )[offset] == max ) */ \ - if ( (( type * )pic_old->data )[offset] ) \ - { \ - if ( in_lab ) \ - (( type_new * )pic_new->data )[offset] = \ - (type_new) no_label; \ - else \ - { \ - in_lab = mitkIpTrue; \ - no_label++; \ - (( type_new * )pic_new->data )[offset] = \ - (type_new) no_label; \ - } \ - } \ - else in_lab = mitkIpFalse; \ - offset++; \ - } \ -} - -#define LABEL2( type, pic_new, a, a_new, a_sort, size ) \ -{ \ - mitkIpUInt4_t aa; /* actual anchestor */ \ - mitkIpUInt4_t al; /* actual label */ \ - mitkIpUInt4_t i, j, k, l; /* loop index */ \ - mitkIpUInt4_t end; \ - mitkIpInt4_t off; /* offset of actual pixel */ \ - mitkIpInt4_t dist; /* distnace between actual and */ \ - /* neighbour pixel */ \ - \ - for ( l = 1; l < pic_new->dim; l++ ) \ - { \ - dist = size[l]; \ - end = _mitkIpPicElements ( pic_new ) / size[l+1]; \ - for ( k = 0; k < end; k++ ) \ - for ( j = 1; j < pic_new->n[l]; j++ ) \ - { \ - off = j * size[l] + k * size[l+1]; \ - for ( i = 0; i < size[l]; i++ ) \ - { \ - /* calculate actual ancestors */ \ - \ - al = (( type * )pic_new->data ) [off]; \ - aa = (( type * )pic_new->data ) [off - dist]; \ - \ - off++; \ - \ - /* if this is a line label */ \ - \ - if ( al ) \ - { \ - if ( aa ) \ - { \ - /* test whether anchestor found */ \ - if ( a[al] == al ) \ - a[al] = a_new[a[aa]]; \ - else if ( a[al] != a[a[al]] ) \ - a[al] = a[a[al]]; \ - else if ( a[al] != a_new[a[aa]] ) \ - a_new[a[aa]] = a[al]; \ - } \ - } \ - } \ - } \ - } \ -} - -#define LABEL3( type, pic_new, a, a_sort ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_new ); \ - for ( i = 0; i < no_elem; i++ ) \ - (( type * )pic_new->data )[i] = \ - ( type ) a_sort[a[( mitkIpUInt4_t ) (( type * )pic_new->data )[i]]]; \ -} - - -/* ------------------------------------------------------------------- */ -/* -** mitkIpFuncLabel -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncLabel ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *no_lab ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to new image structure */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t *a; /* pointer to list with all anchestors*/ - mitkIpUInt4_t *a_new; /* look up table for new labels */ - mitkIpUInt4_t *a_sort; /* pointer to list of sorted anchest. */ - mitkIpUInt4_t no_label; /* number of labels */ - mitkIpUInt4_t new_label; /* */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; - mitkIpFloat8_t min, max; /* extreme greyvalues in image */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate extreme greyvalues in image */ - if ( mitkIpFuncExtr ( pic_old, &min, &max ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check whether image is binary */ - /* - mitkIpFuncHist ( pic_old, min, max, &hist, &size_hist ); - if ( hist == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - i = 0; - no_gv = 0; - while ( i <= ( mitkIpUInt4_t ) ( fabs ( min ) + max ) && no_gv < 3 ) - { - if ( hist [i] != 0 ) no_gv++; - i++; - } - - if ( no_gv != 2 ) - { - free ( hist ); - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - - /* allocate memory for new image */ - - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe / 8 ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* preparation of image */ - - mitkIpPicFORALL_3 ( LABEL1, pic_old, pic_new, no_label, mitkIpInt2_t ); - - if(no_label>SHRT_MAX) - { - mitkIpPicFree(pic_new); - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicUInt; - pic_new->bpe = 32; - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe / 8 ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - mitkIpPicFORALL_3 ( LABEL1, pic_old, pic_new, no_label, mitkIpUInt4_t ); - } - - /* allocation and initialisation of vectors */ - - a = malloc ( ( no_label + 1 ) * sizeof ( mitkIpUInt4_t ) ); - if ( a == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - a_new = malloc ( ( no_label + 1 ) * sizeof ( mitkIpUInt4_t ) ); - if ( a_new == NULL ) - { - free ( a ); - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - a_sort = malloc ( ( no_label + 1 ) * sizeof ( mitkIpUInt4_t ) ); - if ( a_sort == NULL ) - { - free ( a ); - free ( a_new ); - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i <= no_label; i++ ) - { - a[i] = i; - a_new[i] = i; - a_sort[i] = 0; - } - - size[0] = 1; - for ( i = 1; i <= pic_old->dim; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - for ( i = pic_old->dim + 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[pic_old->dim]; - - /* change anchestor list */ - - mitkIpPicFORALL_4 ( LABEL2, pic_new, a, a_new, a_sort, size ); - - /* replace anchestors with new anchestors */ - - for ( i = 0; i <= no_label; i++ ) - { - a[i] = a_new[a[i]]; - } - for ( i = 0; i <= no_label; i++ ) - { - a[i] = _ipGetANew ( a_new, a[i] ); - } - - /* - ** replace image with new labels - */ - - /* hit used labels with 1 */ - - for ( i = 0; i < no_label; i++ ) a_sort[a[i]] = 1; - - /* write new ascending labels to a_sort */ - - for ( i = 0, new_label = 0; i <= no_label; i++ ) - { - if ( a_sort[i] ) - { - new_label++; - a_sort[i] = new_label; - } - } - - /* renumber pixels with new labels */ - - mitkIpPicFORALL_2 ( LABEL3, pic_new, a, a_sort ); - - /**no_lab = no_label;*/ - - *no_lab = new_label; - - if((new_label<=SHRT_MAX) && ( pic_new->bpe != 16 )) - { - mitkIpPicDescriptor * tmp; - tmp=mitkIpFuncConvert(pic_new, mitkIpPicInt, 16); - mitkIpPicFree(pic_new); - pic_new=tmp; - } - - /* free memory */ - - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - free ( a ); - free ( a_new ); - free ( a_sort ); - return ( pic_new ); - -} -#endif - diff --git a/Utilities/IpFunc/Laplace.c b/Utilities/IpFunc/Laplace.c deleted file mode 100644 index c1c0ff67a9..0000000000 --- a/Utilities/IpFunc/Laplace.c +++ /dev/null @@ -1,150 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * This function performs a filtering with a 2D or 3D Laplace filtering - * mask - */ - -/** This function performs a filtering with a 2D or 3D Laplace filtering - * mask - * - * @param pic_old pointer to the image that should be convolved - * @param dim_mask dimension of filtering mask - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to minimal greyvalue - * - * @return pointer to the transformed image - * - * USES - * function mitkIpFuncConv: convolves image with mask - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncLaplace( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncLaplace\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -mitkIpPicDescriptor *mitkIpFuncLaplace( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ) -{ - - mitkIpPicDescriptor *pic_new; /* convolved image */ - mitkIpPicDescriptor *pic_mask; /* laplace mask */ - mitkIpUInt4_t i; /* loop index */ - mitkIpInt2_t laplace2[] = /* 2D laplace-mask */ - { 0, -1, 0, -1, 4, -1, 0, -1, 0 }; - mitkIpInt2_t laplace3[] = /* 3D laplace-mask */ - { 0, 0, 0, 0, -1, 0, 0, 0, 0, - 0, -1, 0, -1, 6, -1, 0, -1, 0, - 0, 0, 0, 0, -1, 0, 0, 0, 0 }; - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim < dim_mask || dim_mask < 2 || dim_mask > 3 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of pic_mask */ - - pic_mask = mitkIpPicNew (); - if ( pic_mask == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_mask->type = mitkIpPicInt; - pic_mask->bpe = 16; - pic_mask->dim = dim_mask; - for ( i = 0; i < dim_mask; i++ ) - pic_mask->n[i] = 3; - - if ( dim_mask == 3 ) - { - pic_mask->data = laplace3; - } - else if ( dim_mask == 2 ) - { - pic_mask->data = laplace2; - } - else - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* function to convolve image with mask */ - - pic_new = mitkIpFuncConv ( pic_old, pic_mask, border ); - - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/LevWind.c b/Utilities/IpFunc/LevWind.c deleted file mode 100644 index 07174c8534..0000000000 --- a/Utilities/IpFunc/LevWind.c +++ /dev/null @@ -1,137 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs a level-window operation - */ - -/** @brief this function performs a level-window operation - * - * All greyvalues which are not included in the - * intervall [level-0.5*window, level+0.5*window] are set to - * the minimal (if greyvalue<level-0.5*window) or maximal - * greyvalue (if greyvalue>level-0.5*window), respectively. - * - * @param pic_old pointer to original image - * @param level greyvalue that forms center of the window - * @param window length of window - * @param pic_return memory which could be used for pic_new. If - * pic_retrun == NULL new memory is allocated - * - * @return pointer to the transformed image - * - * @par Uses - * @arg mitkIpFuncSelMM - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncLevWin ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t level, - mitkIpFloat8_t window, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncLevWin\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* ------------------------------------------------------------------------- */ -/* -** mitkIpFunclevWin -*/ -/* ------------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncLevWin ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t level, - mitkIpFloat8_t window, - mitkIpPicDescriptor *pic_return ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpFloat8_t gv_low; /* lower greyvalue of range */ - mitkIpFloat8_t gv_up; /* upper greyvalue of range */ - mitkIpFloat8_t max_gv, min_gv; /* max and min possible greyvalues */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max and min possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - /* calculate lower and upper greyvalue of range with level and window */ - - gv_low = level - 0.5 * window; - - if ( gv_low < min_gv ) - gv_low = min_gv; - else if ( gv_low > max_gv ) - gv_low = max_gv; - - gv_up = level + 0.5 * window; - - if ( gv_up < min_gv ) - gv_up = min_gv; - else if ( gv_up > max_gv ) - gv_up = max_gv; - - /* calculate new image in Function mitkIpFuncSelect */ - - pic_new = mitkIpFuncSelMM ( pic_old, gv_low, gv_up, pic_return ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/Log.c b/Utilities/IpFunc/Log.c deleted file mode 100644 index 79429e9119..0000000000 --- a/Utilities/IpFunc/Log.c +++ /dev/null @@ -1,213 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this functions transforms the greyvalues of an image with a lg-function - * (y = a lg (x+1)) - */ - -/** this functions transforms the greyvalues of an image with a lg-function - * (y = a lg (x+1)) - * @param pic_old pointer to original image - * - * @return pointer to transformed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncLog ( mitkIpPicDescriptor *pic_old ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncLog\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/* definition of macros */ - -#define LOG( type, pic, max_gv ) \ -{ \ - mitkIpUInt4_t i; /* loopindex */\ - mitkIpUInt4_t no_elem; /* */\ - mitkIpFloat8_t a; /* factor to calculate the logaritm */\ - \ - a = ( max_gv ) / log10 ( max_gv + 1 ); \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - (( type * )pic_new->data )[i] = \ - ( type ) ( a * log10 ( 1. + (( type * )pic->data )[i] ) ); \ -} - -/* ------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncLog ( mitkIpPicDescriptor *pic_old ) -{ - mitkIpFloat8_t min_gv, max_gv; /* max and min posiible greyvalues */ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t no_elem; /* loop index */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* check datatype of image */ - - no_elem = _mitkIpPicElements ( pic_old ); - if ( pic_old->type == mitkIpPicUInt ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->data = malloc ( _mitkIpPicSize ( pic_old ) ); - - if ( ( pic_new != NULL ) && ( pic_new->data != NULL ) ) - { - mitkIpPicFORALL_1 ( LOG, pic_old, max_gv ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - /* copy integer image to usigned integer image to avoid negative greyvalues*/ - - else if ( pic_old->type == mitkIpPicInt ) - { - pic_new = mitkIpPicNew (); - if ( pic_new != NULL ) - { - pic_new->type = mitkIpPicUInt; - pic_new->bpe = pic_old->bpe; - pic_new->dim = pic_old->dim; - for ( i = 0; i < pic_new->dim; i++ ) pic_new->n[i] = pic_old->n[i]; - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* transform integer image to unsigned integer image */ - - if ( pic_new->bpe == 8 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpUInt1_t * )pic_new->data )[i] = - (( mitkIpInt1_t * )pic_old->data )[i] - min_gv; - } - - else if ( pic_new->bpe == 16 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpUInt2_t * )pic_new->data )[i] = - (( mitkIpInt2_t * )pic_old->data )[i] - min_gv; - } - - else if ( pic_new->bpe == 32 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpUInt4_t * )pic_new->data )[i] = - (( mitkIpInt4_t * )pic_old->data )[i] - min_gv; - } - - else - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - max_gv = max_gv - min_gv; - - mitkIpPicFORALL_1 ( LOG, pic_new, max_gv ); - - /* transform unsigned integer image to an integer image */ - - pic_new->type = mitkIpPicInt; - if ( pic_new->bpe == 8 ) - { - for ( i = 0; i < no_elem; i++ ); - (( mitkIpInt1_t * )pic_new->data )[i] = - (( mitkIpUInt1_t * )pic_new->data )[i] + min_gv; - } - - else if ( pic_new->bpe == 16 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpInt2_t * )pic_new->data )[i] = - (( mitkIpUInt2_t * )pic_new->data )[i] + min_gv; - } - - else if ( pic_new->bpe == 32 ) - { - for ( i = 0; i < no_elem; i++ ) - (( mitkIpInt4_t * )pic_new->data )[i] = - (( mitkIpUInt4_t * )pic_new->data )[i] + min_gv; - } - - } - - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/MakePicName.c b/Utilities/IpFunc/MakePicName.c deleted file mode 100644 index ef91a62910..0000000000 --- a/Utilities/IpFunc/MakePicName.c +++ /dev/null @@ -1,100 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function inserts an extension into a filename - */ - -/** @brief inserts an extension into a filename - * - * @warning not tested - * - * @param pic_name file name of input image - * @param extension extension which shoulb be inserted into the filename - - * @return name for the file for the output image - * - * AUTHOR & DATE - */ -char *mitkIpFuncMakePicName ( char *pic_name, char *extension ); - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#define NAME_MAX 40 - - -/* ===================================================================*/ -/* */ -/* MakePicName */ -/* */ -/* ===================================================================*/ - - -char *mitkIpFuncMakePicName ( char *pic_name, char *extension ) -{ - - char *result_name; - int length, pos; - - if ( pic_name == NULL || extension == NULL ) - return NULL; - - length = strlen ( pic_name ) + strlen ( extension ) + 5; - - result_name = ( char * ) malloc ( length * sizeof ( char ) ); - if ( result_name == NULL ) return NULL; - - pos = strstr ( pic_name, ".pic" ) - pic_name; - if ( pos >= 0 ) - strncpy ( result_name, pic_name, pos ); - else - strcpy ( result_name, pic_name ); - - strcat ( result_name, extension ); - strcat ( result_name, ".pic" ); - - return ( result_name ); -} diff --git a/Utilities/IpFunc/Makefile.am b/Utilities/IpFunc/Makefile.am deleted file mode 100644 index 871facdbbc..0000000000 --- a/Utilities/IpFunc/Makefile.am +++ /dev/null @@ -1,127 +0,0 @@ -INCLUDES = -I../ipPic - -EXTRA_DIST = libipFunc.dsp ipFunc.dsp ipFunc.dox - -bin_PROGRAMS = ipFunc -lib_LIBRARIES = libipFunc.a -pkginclude_HEADERS = mitkIpFunc.h -noinst_HEADERS = \ - gradient.h \ - ipArithmeticAndLogical.h \ - mitkIpFuncP.h \ - ipGeometrical.h \ - ipLocal.h \ - ipMorphological.h \ - ipPointOperators.h \ - ipStatistical.h \ - ipAdministrative.h - -ipFunc_LDADD = ./libipFunc.a ../ipPic/libipPic.a - -ipFunc_SOURCES = \ - ipFunc.c - -libipFunc_a_SOURCES = \ - AddC.c \ - AddI.c \ - AddSl.c \ - And.c \ - Border.c \ - BorderX.c \ - _BorderX.c \ - Box.c \ - Box2d.c \ - Box3d.c \ - Canny.c \ - Close.c \ - CompressM.c \ - Conv.c \ - Convert.c \ - CopyTags.c \ - Curtosis.c \ - CurtosisR.c \ - Dila.c \ - DivC.c \ - DivI.c \ - _DrawPoly.c \ - DrawPoly.c \ - Ero.c \ - Equal.c \ - Error.c \ - Exp.c \ - Extrema.c \ - ExtrC.c \ - ExtrROI.c \ - ExtrR.c \ - ExtT.c \ - Frame.c \ - GaussF.c \ - Grad.c \ - Grav.c \ - Hist.c \ - Histo.c \ - HitMiss.c \ - HitMissI.c \ - Inertia.c \ - Inv.c \ - LN.c \ - Label.c \ - Laplace.c \ - LevWind.c \ - Log.c \ - Mean.c \ - MeanC.c \ - MeanF.c \ - MeanROI.c \ - MeanR.c \ - Median.c \ - Morph.c \ - MultC.c \ - MultI.c \ - Norm.c \ - NormXY.c \ - Not.c \ - Open.c \ - OpCl.c \ - Or.c \ - Malloc.c \ - Pot.c \ - Range.c \ - Rank.c \ - Refl.c \ - RegGrow.c \ - Roberts.c \ - Rotate.c \ - Scale.c \ - ScNN.c \ - ScFact.c \ - ScBl.c \ - SDev.c \ - SDevC.c \ - SDevROI.c \ - SDevR.c \ - Select.c \ - SelInv.c \ - SelMM.c \ - SetErrno.c \ - SetTag.c \ - Skewness.c \ - SkewnessR.c \ - Shp.c \ - Sobel.c \ - Sqrt.c \ - SubC.c \ - SubI.c \ - Thresh.c \ - Transpose.c \ - Var.c \ - VarC.c \ - VarROI.c \ - VarR.c \ - Window.c \ - WindowR.c \ - Xchange.c \ - ZeroCr.c \ - ipGetANew.c \ - FillArea.c \ - MakePicName.c diff --git a/Utilities/IpFunc/Makefile.in b/Utilities/IpFunc/Makefile.in deleted file mode 100644 index fa04faac2a..0000000000 --- a/Utilities/IpFunc/Makefile.in +++ /dev/null @@ -1,427 +0,0 @@ -# Makefile.in generated automatically by automake 1.4 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -AWK = @AWK@ -CC = @CC@ -CXX = @CXX@ -LN_S = @LN_S@ -MAKEINFO = @MAKEINFO@ -PACKAGE = @PACKAGE@ -RANLIB = @RANLIB@ -VERSION = @VERSION@ -htmldir = @htmldir@ -piano_cv_prog_doxygen = @piano_cv_prog_doxygen@ - -INCLUDES = -I../ipPic - -EXTRA_DIST = libipFunc.dsp ipFunc.dsp ipFunc.dox - -bin_PROGRAMS = ipFunc -lib_LIBRARIES = libipFunc.a -pkginclude_HEADERS = mitkIpFunc.h -noinst_HEADERS = gradient.h ipArithmeticAndLogical.h mitkIpFuncP.h ipGeometrical.h ipLocal.h ipMorphological.h ipPointOperators.h ipStatistical.h ipAdministrative.h - - -ipFunc_LDADD = ./libipFunc.a ../ipPic/libipPic.a - -ipFunc_SOURCES = ipFunc.c - - -libipFunc_a_SOURCES = AddC.c AddI.c AddSl.c And.c Border.c BorderX.c _BorderX.c Box.c Box2d.c Box3d.c Canny.c Close.c CompressM.c Conv.c Convert.c CopyTags.c Curtosis.c CurtosisR.c Dila.c DivC.c DivI.c _DrawPoly.c DrawPoly.c Ero.c Equal.c Error.c Exp.c Extrema.c ExtrC.c ExtrROI.c ExtrR.c ExtT.c Frame.c GaussF.c Grad.c Grav.c Hist.c Histo.c HitMiss.c HitMissI.c Inertia.c Inv.c LN.c Label.c Laplace.c LevWind.c Log.c Mean.c MeanC.c MeanF.c MeanROI.c MeanR.c Median.c Morph.c MultC.c MultI.c Norm.c NormXY.c Not.c Open.c OpCl.c Or.c Malloc.c Pot.c Range.c Rank.c Refl.c RegGrow.c Roberts.c Rotate.c Scale.c ScNN.c ScFact.c ScBl.c SDev.c SDevC.c SDevROI.c SDevR.c Select.c SelInv.c SelMM.c SetErrno.c SetTag.c Skewness.c SkewnessR.c Shp.c Sobel.c Sqrt.c SubC.c SubI.c Thresh.c Transpose.c Var.c VarC.c VarROI.c VarR.c Window.c WindowR.c Xchange.c ZeroCr.c ipGetANew.c FillArea.c MakePicName.c - -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -LIBRARIES = $(lib_LIBRARIES) - - -DEFS = @DEFS@ -I. -I$(srcdir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -libipFunc_a_LIBADD = -libipFunc_a_OBJECTS = AddC.o AddI.o AddSl.o And.o Border.o BorderX.o \ -_BorderX.o Box.o Box2d.o Box3d.o Canny.o Close.o CompressM.o Conv.o \ -Convert.o CopyTags.o Curtosis.o CurtosisR.o Dila.o DivC.o DivI.o \ -_DrawPoly.o DrawPoly.o Ero.o Equal.o Error.o Exp.o Extrema.o ExtrC.o \ -ExtrROI.o ExtrR.o ExtT.o Frame.o GaussF.o Grad.o Grav.o Hist.o Histo.o \ -HitMiss.o HitMissI.o Inertia.o Inv.o LN.o Label.o Laplace.o LevWind.o \ -Log.o Mean.o MeanC.o MeanF.o MeanROI.o MeanR.o Median.o Morph.o MultC.o \ -MultI.o Norm.o NormXY.o Not.o Open.o OpCl.o Or.o Malloc.o Pot.o Range.o \ -Rank.o Refl.o RegGrow.o Roberts.o Rotate.o Scale.o ScNN.o ScFact.o \ -ScBl.o SDev.o SDevC.o SDevROI.o SDevR.o Select.o SelInv.o SelMM.o \ -SetErrno.o SetTag.o Skewness.o SkewnessR.o Shp.o Sobel.o Sqrt.o SubC.o \ -SubI.o Thresh.o Transpose.o Var.o VarC.o VarROI.o VarR.o Window.o \ -WindowR.o Xchange.o ZeroCr.o ipGetANew.o FillArea.o MakePicName.o -AR = ar -PROGRAMS = $(bin_PROGRAMS) - -ipFunc_OBJECTS = ipFunc.o -ipFunc_DEPENDENCIES = ./libipFunc.a ../ipPic/libipPic.a -ipFunc_LDFLAGS = -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS) - -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = tar -GZIP_ENV = --best -DEP_FILES = .deps/AddC.P .deps/AddI.P .deps/AddSl.P .deps/And.P \ -.deps/Border.P .deps/BorderX.P .deps/Box.P .deps/Box2d.P .deps/Box3d.P \ -.deps/Canny.P .deps/Close.P .deps/CompressM.P .deps/Conv.P \ -.deps/Convert.P .deps/CopyTags.P .deps/Curtosis.P .deps/CurtosisR.P \ -.deps/Dila.P .deps/DivC.P .deps/DivI.P .deps/DrawPoly.P .deps/Equal.P \ -.deps/Ero.P .deps/Error.P .deps/Exp.P .deps/ExtT.P .deps/ExtrC.P \ -.deps/ExtrR.P .deps/ExtrROI.P .deps/Extrema.P .deps/FillArea.P \ -.deps/Frame.P .deps/GaussF.P .deps/Grad.P .deps/Grav.P .deps/Hist.P \ -.deps/Histo.P .deps/HitMiss.P .deps/HitMissI.P .deps/Inertia.P \ -.deps/Inv.P .deps/LN.P .deps/Label.P .deps/Laplace.P .deps/LevWind.P \ -.deps/Log.P .deps/MakePicName.P .deps/Malloc.P .deps/Mean.P \ -.deps/MeanC.P .deps/MeanF.P .deps/MeanR.P .deps/MeanROI.P \ -.deps/Median.P .deps/Morph.P .deps/MultC.P .deps/MultI.P .deps/Norm.P \ -.deps/NormXY.P .deps/Not.P .deps/OpCl.P .deps/Open.P .deps/Or.P \ -.deps/Pot.P .deps/Range.P .deps/Rank.P .deps/Refl.P .deps/RegGrow.P \ -.deps/Roberts.P .deps/Rotate.P .deps/SDev.P .deps/SDevC.P .deps/SDevR.P \ -.deps/SDevROI.P .deps/ScBl.P .deps/ScFact.P .deps/ScNN.P .deps/Scale.P \ -.deps/SelInv.P .deps/SelMM.P .deps/Select.P .deps/SetErrno.P \ -.deps/SetTag.P .deps/Shp.P .deps/Skewness.P .deps/SkewnessR.P \ -.deps/Sobel.P .deps/Sqrt.P .deps/SubC.P .deps/SubI.P .deps/Thresh.P \ -.deps/Transpose.P .deps/Var.P .deps/VarC.P .deps/VarR.P .deps/VarROI.P \ -.deps/Window.P .deps/WindowR.P .deps/Xchange.P .deps/ZeroCr.P \ -.deps/_BorderX.P .deps/_DrawPoly.P .deps/ipFunc.P .deps/ipGetANew.P -SOURCES = $(libipFunc_a_SOURCES) $(ipFunc_SOURCES) -OBJECTS = $(libipFunc_a_OBJECTS) $(ipFunc_OBJECTS) - -all: all-redirect -.SUFFIXES: -.SUFFIXES: .S .c .o .s -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu ipFunc/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -mostlyclean-libLIBRARIES: - -clean-libLIBRARIES: - -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) - -distclean-libLIBRARIES: - -maintainer-clean-libLIBRARIES: - -install-libLIBRARIES: $(lib_LIBRARIES) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(libdir) - @list='$(lib_LIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \ - $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \ - else :; fi; \ - done - @$(POST_INSTALL) - @list='$(lib_LIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ - $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ - else :; fi; \ - done - -uninstall-libLIBRARIES: - @$(NORMAL_UNINSTALL) - list='$(lib_LIBRARIES)'; for p in $$list; do \ - rm -f $(DESTDIR)$(libdir)/$$p; \ - done - -.s.o: - $(COMPILE) -c $< - -.S.o: - $(COMPILE) -c $< - -mostlyclean-compile: - -rm -f *.o core *.core - -clean-compile: - -distclean-compile: - -rm -f *.tab.c - -maintainer-clean-compile: - -libipFunc.a: $(libipFunc_a_OBJECTS) $(libipFunc_a_DEPENDENCIES) - -rm -f libipFunc.a - $(AR) cru libipFunc.a $(libipFunc_a_OBJECTS) $(libipFunc_a_LIBADD) - $(RANLIB) libipFunc.a - -mostlyclean-binPROGRAMS: - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) - -distclean-binPROGRAMS: - -maintainer-clean-binPROGRAMS: - -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - list='$(bin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - done - -ipFunc: $(ipFunc_OBJECTS) $(ipFunc_DEPENDENCIES) - @rm -f ipFunc - $(LINK) $(ipFunc_LDFLAGS) $(ipFunc_OBJECTS) $(ipFunc_LDADD) $(LIBS) - -install-pkgincludeHEADERS: $(pkginclude_HEADERS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(pkgincludedir) - @list='$(pkginclude_HEADERS)'; for p in $$list; do \ - if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ - echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(pkgincludedir)/$$p"; \ - $(INSTALL_DATA) $$d$$p $(DESTDIR)$(pkgincludedir)/$$p; \ - done - -uninstall-pkgincludeHEADERS: - @$(NORMAL_UNINSTALL) - list='$(pkginclude_HEADERS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(pkgincludedir)/$$p; \ - done - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = ipFunc - -distdir: $(DISTFILES) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(top_distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu ipFunc/Makefile - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done - -DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) - --include $(DEP_FILES) - -mostlyclean-depend: - -clean-depend: - -distclean-depend: - -rm -rf .deps - -maintainer-clean-depend: - -%.o: %.c - @echo '$(COMPILE) -c $<'; \ - $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< - @-cp .deps/$(*F).pp .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm .deps/$(*F).pp - -%.lo: %.c - @echo '$(LTCOMPILE) -c $<'; \ - $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< - @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ - < .deps/$(*F).pp > .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm -f .deps/$(*F).pp -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: install-libLIBRARIES install-binPROGRAMS -install-exec: install-exec-am - -install-data-am: install-pkgincludeHEADERS -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-libLIBRARIES uninstall-binPROGRAMS \ - uninstall-pkgincludeHEADERS -uninstall: uninstall-am -all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) \ - $(DESTDIR)$(pkgincludedir) - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-libLIBRARIES mostlyclean-compile \ - mostlyclean-binPROGRAMS mostlyclean-tags \ - mostlyclean-depend mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-libLIBRARIES clean-compile clean-binPROGRAMS clean-tags \ - clean-depend clean-generic mostlyclean-am - -clean: clean-am - -distclean-am: distclean-libLIBRARIES distclean-compile \ - distclean-binPROGRAMS distclean-tags distclean-depend \ - distclean-generic clean-am - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-libLIBRARIES \ - maintainer-clean-compile maintainer-clean-binPROGRAMS \ - maintainer-clean-tags maintainer-clean-depend \ - maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: mostlyclean-libLIBRARIES distclean-libLIBRARIES \ -clean-libLIBRARIES maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \ -install-libLIBRARIES mostlyclean-compile distclean-compile \ -clean-compile maintainer-clean-compile mostlyclean-binPROGRAMS \ -distclean-binPROGRAMS clean-binPROGRAMS maintainer-clean-binPROGRAMS \ -uninstall-binPROGRAMS install-binPROGRAMS uninstall-pkgincludeHEADERS \ -install-pkgincludeHEADERS tags mostlyclean-tags distclean-tags \ -clean-tags maintainer-clean-tags distdir mostlyclean-depend \ -distclean-depend clean-depend maintainer-clean-depend info-am info \ -dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ -install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/Utilities/IpFunc/Malloc.c b/Utilities/IpFunc/Malloc.c deleted file mode 100644 index fab1b3a4f8..0000000000 --- a/Utilities/IpFunc/Malloc.c +++ /dev/null @@ -1,135 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function allocates the memory for a new image depending on the - * parameter pic_return. If pic_return is equal NULL, new memory is - * allocated otherwise it is reused. - */ - -/** this function allocates the memory for a new image depending on the - * parameter pic_return. If pic_return is equal NULL, new memory is - * allocated otherwise it is reused. - * - * @param pic_old pointer to original image - * @param pic_return pointer to the memory which should be reused - * @param over_write tells whether the memory could be reused - * @arg @c mitkIpTrue => memory could be reused - * @arg @c mitkIpFalse => new memory must be allocated - * - * @return pointer to the memory for transformed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *_mitkIpFuncMalloc ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return, - mitkIpBool_t over_write ); - -#ifndef DOXYGEN_IGNORE - - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* -** mitkIpFuncMalloc -*/ - -mitkIpPicDescriptor *_mitkIpFuncMalloc ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return, - mitkIpBool_t over_write ) -{ - mitkIpBool_t okay=mitkIpTrue; - mitkIpUInt4_t i; - - if ( pic_return == NULL || ( !over_write ) ) - { - pic_return = mitkIpPicCopyHeader ( pic_old, 0 ); - if ( pic_return == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_return->data = calloc ( _mitkIpPicElements ( pic_old ), pic_old->bpe/8 ); - if ( pic_return->data == NULL ) - { - mitkIpPicFree ( pic_return ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - } - else - { - if ( pic_old->type != pic_return->type ) okay = mitkIpFalse; - if ( pic_old->bpe != pic_return->bpe ) okay = mitkIpFalse; - if ( pic_old->dim != pic_return->dim ) okay = mitkIpFalse; - for ( i = 0; i < pic_old->dim; i++ ) - if ( pic_old->n[i] != pic_return->n[i] ) okay = mitkIpFalse; - } - - if ( !okay ) - { - mitkIpPicFree ( pic_return ); - pic_return = mitkIpPicCopyHeader ( pic_old, 0 ); - if ( pic_return == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_return->data = calloc ( _mitkIpPicElements ( pic_old ), pic_old->bpe/8 ); - if ( pic_return->data == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - return ( pic_return ); -} -#endif - diff --git a/Utilities/IpFunc/Mean.c b/Utilities/IpFunc/Mean.c deleted file mode 100644 index 9c17e35637..0000000000 --- a/Utilities/IpFunc/Mean.c +++ /dev/null @@ -1,106 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the mean greyvalue of all greyvalues - * in an image - */ - -/** this function calculates the mean greyvalue of all greyvalues - * in an image - * - * - * @param pic pointer to the image - * - * @return mean greyvalue - * - * AUTHOR & DATE - */ - -/* include-files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncMean ( mitkIpPicDescriptor *pic ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncMean\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of extreme value macro */ - -#define MEAN( type, pic, mean ) \ - { \ - mitkIpUInt4_t i, no_elem; \ - \ - mean = 0.; \ - no_elem = _mitkIpPicElements ( pic ); \ - \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - mean = ( ( type * ) pic->data ) [i] + mean; \ - } \ - mean = mean / _mitkIpPicElements ( pic ); \ - } - -/* ========================================================== */ -/* -*/ -/* ========================================================== */ - -mitkIpFloat8_t mitkIpFuncMean ( mitkIpPicDescriptor *pic ) -{ - - mitkIpFloat8_t mean = 0.0; - - /* check data */ - - if ( _mitkIpFuncError ( pic ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - mitkIpPicFORALL_1( MEAN, pic, mean ) - - return( mean ); -} -#endif - diff --git a/Utilities/IpFunc/MeanC.c b/Utilities/IpFunc/MeanC.c deleted file mode 100644 index 5c4928ca00..0000000000 --- a/Utilities/IpFunc/MeanC.c +++ /dev/null @@ -1,202 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the mean of all greyvalues which are included - * by a circle - * - * @param pic_old pointer to riginal image - * @param center coordiantest of the center of the circle - * @param radius radius of the circle - * - * qreturn mean of all greyvalues included by the circle - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncMeanC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncMeanC\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - - -#define MEAN( type, pic, beg, end, size, center, radius ) \ -{ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - mitkIpUInt4_t dist[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - \ - for ( ind[7] = beg[7] ; ind[7] < end[7]; ind[7]++ ) \ - { \ - dist[7] = ( ind[7] - center[7] ) * ( ind[7] - center[7] ); \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6] ; ind[6] < end[6]; ind[6]++ ) \ - { \ - dist[6] = ( ind[6] - center[6] ) * ( ind[6] - center[6] ) + dist[7]; \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5] ; ind[5] < end[5]; ind[5]++ ) \ - { \ - dist[5] = ( ind[5] - center[5] ) * ( ind[5] - center[5] ) + dist[6]; \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4] ; ind[4] < end[4]; ind[4]++ ) \ - { \ - dist[4] = ( ind[4] - center[4] ) * ( ind[4] - center[4] ) + dist[5]; \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3] ; ind[3] < end[3]; ind[3]++ ) \ - { \ - dist[3] = ( ind[3] - center[3] ) * ( ind[3] - center[3] ) + dist[4]; \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2] ; ind[2] < end[2]; ind[2]++ ) \ - { \ - dist[2] = ( ind[2] - center[2] ) * ( ind[2] - center[2] ) + dist[3]; \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1] ; ind[1] < end[1]; ind[1]++ ) \ - { \ - dist[1] = ( ind[1] - center[1] ) * ( ind[1] - center[1] ) +dist[2];\ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1]+beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - dist[0] = ( ind[0] - center[0] ) * ( ind[0] - center[0] )+dist[1];\ - if ( ( mitkIpUInt4_t ) sqrt ( ( mitkIpFloat8_t ) dist[0] ) <= radius ) \ - { \ - mean = mean + (( type * )pic->data )[off[0]]; \ - count++; \ - } \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpFloat8_t mitkIpFuncMeanC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ) -{ - mitkIpInt4_t help; - mitkIpUInt4_t i; /* loop index */ - mitkIpFloat8_t mean; - mitkIpUInt4_t count; - mitkIpUInt4_t end[_mitkIpPicNDIM]; /* end of window */ - mitkIpUInt4_t centr[_mitkIpPicNDIM]; /* end of window */ - mitkIpUInt4_t begin[_mitkIpPicNDIM]; /* beginning of window */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( radius <= 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < pic_old->dim; i++ ) - { - help = (mitkIpInt4_t *) center[i] - (mitkIpInt4_t *) radius; - if ( help < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - else begin[i] = help; - - help = center[i] + radius; - if ( (mitkIpUInt4_t) help > pic_old->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - else end[i] = help + 1; - centr[i] = center[i]; - } - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - size[pic_old->dim] = 0; - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - { - centr[i] = 0; - begin[i] = 0; - end[i] = 1; - } - - /* allocate image structure */ - - mean = 0; - count = 0; - - mitkIpPicFORALL_5 ( MEAN, pic_old, begin, end, size, centr, radius ); - - mean = mean / count; - - return ( mean ); -} - -#endif diff --git a/Utilities/IpFunc/MeanF.c b/Utilities/IpFunc/MeanF.c deleted file mode 100644 index cfd8e0497e..0000000000 --- a/Utilities/IpFunc/MeanF.c +++ /dev/null @@ -1,153 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs a smoothing by a mean-value filter - */ - -/** @brief performs a smoothing by a mean-value filter - * - * @param pic_old pointer to original image - * @param len_mask number of pixels for each dimension - * @param dim_mask number of dimensions of filter in mask - * @param border handling of the edge - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge pixels are set to zero - * - * @return pointer to the smoothed image - * - * @par Uses @arg mitkIpFuncConv() convolve image with mask - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncMeanF ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t len_mask, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* --------------------------------------------------------------------- */ -/* -*/ -/* --------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncMeanF ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t len_mask, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to new image structure */ - mitkIpPicDescriptor *pic_mask; /* pointer to mask */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t no_elem; - mitkIpFloat8_t help; - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim < dim_mask || dim_mask < 1 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( len_mask % 2 != 1 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialize mask */ - - pic_mask = mitkIpPicNew(); - - if ( pic_mask == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_mask->type = mitkIpPicFloat; - pic_mask->bpe = 64; - pic_mask->dim = dim_mask; - - for ( i = 0; i < dim_mask; i++ ) pic_mask->n[i] = len_mask; - - pic_mask->data = malloc ( _mitkIpPicSize ( pic_mask ) ); - if ( pic_mask->data == NULL ) - { - mitkIpPicFree ( pic_mask->data ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - no_elem = _mitkIpPicElements ( pic_mask ); - help = 1. / ( mitkIpFloat8_t ) no_elem; - for ( i = 0; i < no_elem; i++ ) - (( mitkIpFloat8_t * ) pic_mask->data ) [i] = help; - - /* convolve image with filtering mask */ - - pic_new = mitkIpFuncConv ( pic_old, pic_mask, border ); - - mitkIpPicFree ( pic_mask ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} - -#endif diff --git a/Utilities/IpFunc/MeanR.c b/Utilities/IpFunc/MeanR.c deleted file mode 100644 index ef8710927f..0000000000 --- a/Utilities/IpFunc/MeanR.c +++ /dev/null @@ -1,87 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * calculates the mean value of all greyvalues included by a rectangle - */ - -/** @brief calculates the mean value of all greyvalues included by a rectangle - * - * The rectangle is described by a vector with the coordinates of the - * upper left corner and a vector of its length in each direction - * - * @param pic_old pointer to original image - * @param begin vector with the beginning coordinates of the window - * @param length vector with the length of the window in each direction - * - * @return mean value in window - * - * AUTHOR & DATE - */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncMeanR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)ipFUncMeanR\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -mitkIpFloat8_t mitkIpFuncMeanR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ) -{ - mitkIpFloat8_t mean; /* mean value */ - mitkIpPicDescriptor *pic_help; - - pic_help = mitkIpFuncWindow ( pic_old, begin, length ); - - mean = mitkIpFuncMean ( pic_help ); - - mitkIpPicFree ( pic_help ); - - return ( mean ); -} -#endif - diff --git a/Utilities/IpFunc/MeanROI.c b/Utilities/IpFunc/MeanROI.c deleted file mode 100644 index 0c99645e95..0000000000 --- a/Utilities/IpFunc/MeanROI.c +++ /dev/null @@ -1,246 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the mean of all pixels inside of a polygon - */ - -/** @brief calculates the mean of all pixels inside of a polygon - * - * The polygon is described by a sequence of points - * - * @param pic_old pointer to original image - * @param pol_x vector with the x-coordinates of the points which form - * form the roi - * @param pol_y vector with the y-coordinates of the points which form - * form the roi - * @param no_pts number of points used to describe ROI - * - * REMARKS - * this function could just be used for 2D images - * - * @return mean of all greyvalues in ROI - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncMeanROI ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) ; -#ifndef DOXYGEN_IGNORE - - -#ifndef lint - static char *what = { "@(#)mitkIpFuncMeanROI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/*definition of macros */ - -#define MAX( x, y ) ( x > y ) ? x : y -#define MIN( x, y ) ( x < y ) ? x : y -#define ROI( type, pic, pic_help, sum, count ) \ -{ \ - mitkIpBool_t in; \ - mitkIpUInt4_t i, j; \ - mitkIpUInt4_t offset; \ - \ - for ( i = min_y; i <= max_y; i++ ) \ - { \ - in = mitkIpFalse; \ - offset = i * pic->n[0] + min_x; \ - for ( j = min_x; j <= max_x; j++ ) \ - { \ - if ( (( mitkIpUInt1_t * )pic_help->data )[offset] && ( !in ) ) \ - in = mitkIpTrue; \ - else if ( (( mitkIpUInt1_t * )pic_help->data )[offset] && ( in ) ) \ - { \ - in = mitkIpFalse; \ - sum = sum + (( type * )pic->data )[offset]; \ - count++; \ - } \ - \ - if ( in ) \ - { \ - sum = sum + (( type * )pic->data )[offset]; \ - count++; \ - } \ - \ - offset++; \ - } \ - } \ -} - -/* -** mitkIpFuncMeanROI -*/ - -mitkIpFloat8_t mitkIpFuncMeanROI ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) -{ - mitkIpFloat8_t mean; /* mean of greyvalues in ROI */ - mitkIpFloat8_t sum=0; /* sum of greyvalues in ROI */ - mitkIpFloat8_t *a, *b; /* Gerade y = ax+b */ - mitkIpPicDescriptor *pic_help; /* contains edge of ROI */ - mitkIpUInt4_t min_x, max_x; /* min, max x-coordinate of ROI */ - mitkIpUInt4_t min_y, max_y; /* min, max y-coordinate of ROI */ - mitkIpUInt4_t i; /* loop variable */ - mitkIpUInt4_t count=0; /* number of pixels in ROI */ - mitkIpFloat8_t diff; /* difference between two points */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim > 2 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate min. and max. coordiantes of ROI */ - - min_x = pol_x[0]; - min_y = pol_y[0]; - max_x = pol_x[0]; - max_y = pol_y[0]; - for ( i = 1; i < no_pts; i++ ) - { - min_x = MIN ( min_x, pol_x[i] ); - min_y = MIN ( min_y, pol_y[i] ); - max_x = MAX ( max_x, pol_x[i] ); - max_y = MAX ( max_y, pol_y[i] ); - } - - - /* check whether ROI is in image */ - - /* Expression is always false. - if ( min_x < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - - if ( max_x > pic_old->n[0] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Expression is always false. - if ( min_y < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - - if ( max_y > pic_old->n[1] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory for a and b */ - - a = ( mitkIpFloat8_t * ) malloc ( no_pts * sizeof ( mitkIpFloat8_t ) ); - b = ( mitkIpFloat8_t * ) malloc ( no_pts * sizeof ( mitkIpFloat8_t ) ); - - /* Geraden zwischen zwei benachbarten Punkten berechnen */ - - for ( i = 0; i < no_pts-1; i++ ) - { - diff = ( mitkIpFloat8_t ) pol_x[i+1] - ( mitkIpFloat8_t ) pol_x[i]; - if ( diff ) - { - a[i] = ( ( mitkIpFloat8_t ) pol_y[i+1] - ( mitkIpFloat8_t ) pol_y[i] ) / diff; - b[i] = ( ( mitkIpFloat8_t ) pol_y[i] - a[i] * ( mitkIpFloat8_t )pol_x[i] ); - } - else - { - b[i] = 0.; - a[i] = 0.; - } - } - diff = ( mitkIpFloat8_t ) pol_x[no_pts-1] - ( mitkIpFloat8_t ) pol_x[0]; - if ( diff ) - { - a[no_pts-1] = ( ( mitkIpFloat8_t ) pol_y[no_pts-1] - ( mitkIpFloat8_t ) pol_y[0] ) / diff; - b[no_pts-1] = ( pol_y[no_pts-1] - a[no_pts-1] * pol_x[no_pts-1] ); - } - else - { - b[no_pts-1] = 0.; - a[no_pts-1] = 0.; - } - - /* draw polygon to image */ - - pic_help = _mitkIpFuncDrawPoly ( pic_old, pol_x, pol_y, no_pts, a, b ); - if ( ! pic_help ) - { - free ( a ); - free ( b ); - return ( mitkIpFuncERROR ); - } - - /* macro to calculate mean */ - - mitkIpPicFORALL_3 ( ROI, pic_old, pic_help, sum, count ); - - mean = sum / count; - - free ( a ); - free ( b ); - mitkIpPicFree ( pic_help ); - - return ( mean ); - -} -#endif diff --git a/Utilities/IpFunc/Median.c b/Utilities/IpFunc/Median.c deleted file mode 100644 index 58cc6f49e7..0000000000 --- a/Utilities/IpFunc/Median.c +++ /dev/null @@ -1,132 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the median of the image data -*/ - -/** @brief calculates the median of the image data - * - * @param pic_old pointer to the image - * - * @return median of the image data - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncMedI ( mitkIpPicDescriptor *pic_old ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncMedI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* ------------------------------------------------------------------- */ -/* -** function mitkIpFuncMedI: -*/ -/* ------------------------------------------------------------------- */ - -mitkIpFloat8_t mitkIpFuncMedI ( mitkIpPicDescriptor *pic_old ) -{ - - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpUInt4_t *hist; /* greylevel histogram */ - mitkIpUInt4_t size_hist; /* no. of elements in histogram */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t sum; /* sum of histogram elements */ - mitkIpUInt4_t limit; /* */ - mitkIpFloat4_t factor; - mitkIpFloat8_t median; /* median of image data */ - - /* check whether image data are ok */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) == mitkIpFuncERROR ) - { - return ( mitkIpFuncERROR ); - } - - /* calculate greylevel histogram */ - - mitkIpFuncHist ( pic_old, min_gv, max_gv, &hist, &size_hist ); - if ( hist == 0 ) - { - return ( mitkIpFuncERROR ); - } - - /* factor to calculate the greyvalue belonging to an histogram index */ - - if ( pic_old->type == mitkIpPicFloat ) - factor = 0.001; - else if ( pic_old->type == mitkIpPicInt || pic_old->type == mitkIpPicUInt ) - factor = 1.; - else - { - free ( hist ); - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* find median */ - - limit = _mitkIpPicElements ( pic_old ) / 2; - for ( i = 0, sum = 0; sum < limit; i++ ) - sum = sum + hist [i]; - - median = i * factor - fabs ( min_gv ); - - free ( hist ); - - return ( median ); -} -#endif - diff --git a/Utilities/IpFunc/Morph.c b/Utilities/IpFunc/Morph.c deleted file mode 100644 index 6bd8df9b58..0000000000 --- a/Utilities/IpFunc/Morph.c +++ /dev/null @@ -1,388 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs a morphological operation - */ - -/** @brief performs a morphological operation. - * - * Depending on the parameter kind a erosion or dilation is performed. If the original - * image is an binary image each pixel is connected with the surrounding - * pixels which are non zero in the kernel by using logical operations - * ( and for erosion, or for dilation ). Greylevel images are transformed - * by taking the minimum (erosion) of the surrounding pixels or the - * maximum (dilation). - * - * @param pic_old pointer to the original image - * @param mask pointer to the kernel - * @param kind tells whether erosion or dilation is performed - * 0 (mitkIpERO) : erosion - * 1 (mitkIpDILA) : dilation - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to zero - * - * @return pointer to the transformed image - * - * @par Uses - * @arg _mitkIpFuncError() - check the image data - * @arg mitkIpFuncHist() - calculate the greylevel histogram - * @arg _mitkIpFuncCompressM() - compress filtering mask - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *_mitkIpFuncMorph ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - _mitkIpFuncFlagF_t kind, - mitkIpFuncFlagI_t border ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncMorph\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - -#include "mitkIpFuncP.h" - -/* definition of macros and constants */ - -#define ERO_B && -#define DILA_B || -#define ERO_G < -#define DILA_G > - -#define INIT( type, pic_new ) \ -{ \ - mitkIpUInt4_t i; /* loop variable */ \ - mitkIpUInt4_t no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_new ); \ - for ( i = 0; i < no_elem; i++ ) \ - (( type * )pic_new->data )[i] = 1; \ -} - - -#define MORPH_B( type, pic_old, pic_new, m, beg, end, OP ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t offset; /* offset */ \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* offset vector */ \ - \ - /* transformation of image */ \ - \ - for ( i = 0; i < m->length; i++ ) \ - { \ - offset = m->off_vekt[i]; \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = ind[7] * size[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = ind[6] * size[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = ind[5] * size[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = ind[4] * size[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = ind[3] * size[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = ind[2] * size[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = ind[1] * size[1] + off[2]; \ - off[0] = beg[0] + off[1]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - (( type * )pic_new->data )[off[0]] = \ - (( type * )pic_new->data)[off[0]] OP \ - (( type * )pic_old->data)[off[0] + offset]; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - -#define MORPH_G( type, pic_old, pic_new, m, beg, end, OP ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* offset vector */ \ - type help, help2; \ - \ - \ - /* transformation of image */ \ - \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = ind[7] * size[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = ind[6] * size[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = ind[5] * size[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = ind[4] * size[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = ind[3] * size[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = ind[2] * size[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = ind[1] * size[1] + off[2]; \ - off[0] = beg[0] + off[1]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - help = (( type* )pic_old->data)[off[0]]; \ - for ( i = 0; i < m->length; i++ ) \ - { \ - help2 = (( type * )pic_old->data)[m->off_vekt[i]+off[0]];\ - help = ( help OP help2 ) ? help : help2; \ - } \ - (( type * )pic_new->data)[off[0]] = help; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - \ -} - -/* ---------------------------------------------------------------------- */ -/* -** function _mitkIpFuncMorph -*/ -/* ---------------------------------------------------------------------- */ - -mitkIpPicDescriptor *_mitkIpFuncMorph ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - _mitkIpFuncFlagF_t kind, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpFuncMasc_t *m; /* compressed mask and belonging offsets*/ - mitkIpInt4_t beg[_mitkIpPicNDIM]; - mitkIpInt4_t end[_mitkIpPicNDIM]; - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - mitkIpUInt4_t no_gv; /* number of different greyvalues */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t size_hist; /* number of elements in histogram */ - mitkIpUInt4_t *hist; /* pointer to greyvalue histogram */ - mitkIpFloat8_t min, max; /* extreme greyvalues in image */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( mask ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( mask->dim > pic_old->dim ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < mask->dim; i++ ) - if ( mask->n[i] > pic_old->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_new = NULL; - - /* initialisation of vectors */ - - size [0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - size[pic_old->dim] = 0; - - /* compress filtering mask */ - - m = _mitkIpFuncCompressM ( mask, pic_old, mitkIpFuncNoReflect, beg, end ); - if ( m == NULL ) - { - free ( hist ); - mitkIpPicFree ( pic_new ); - return ( mitkIpFuncERROR ); - } - - /* allocate and initialize pic_new */ - - if ( border == mitkIpFuncBorderOld ) - pic_new = mitkIpPicClone ( pic_old ); - else if ( border == mitkIpFuncBorderZero ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe / 8 ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( kind == mitkIpFuncEroF ) - { - mitkIpPicFORALL ( INIT, pic_new ); - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* check whether binary or greylevel image */ - - if ( mitkIpFuncExtr ( pic_old, &min, &max ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - mitkIpFuncHist ( pic_old, min, max, &hist, &size_hist ); - if ( hist == NULL ) - { - mitkIpPicFree ( pic_new ); - return ( mitkIpFuncERROR ); - } - - i = 0; - no_gv = 0; - while ( i <= ( mitkIpUInt4_t ) ( fabs ( min ) + max ) && no_gv < 3 ) - { - if ( hist [i] != 0 ) no_gv++; - i++; - } - - - /* transform image (depending on kind and no_gv) */ - - if ( kind == mitkIpFuncEroF ) /* erosion */ - { - if ( no_gv == 2 ) /* binary image */ - { - mitkIpPicFORALL_5 ( MORPH_B, pic_old, pic_new, m, beg, end, ERO_B ); - } - else if ( no_gv > 2 ) /* greylevel image */ - { - mitkIpPicFORALL_5 ( MORPH_G, pic_old, pic_new, m, beg, end, ERO_G ); - } - else - { - free ( hist ); - free ( m->off_vekt ); - free ( m->mask_vekt ); - free ( m ); - /*_mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR );*/ - return ( pic_new ); - } - } - else if ( kind == mitkIpFuncDilaF ) /* dilation */ - { - if ( no_gv == 2 ) /* binary image */ - { - mitkIpPicFORALL_5 ( MORPH_B, pic_old, pic_new, m, beg, end, DILA_B ); - } - else if ( no_gv > 2 ) /* greylevel image */ - { - mitkIpPicFORALL_5 ( MORPH_G, pic_old, pic_new, m, beg, end, DILA_G ); - } - else - { - free ( hist ); - free ( m->off_vekt ); - free ( m->mask_vekt ); - free ( m ); - /*_mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR );*/ - return ( pic_new ); - } - } - else - { - mitkIpPicFree ( pic_new ); - free ( hist ); - free ( m->off_vekt ); - free ( m->mask_vekt ); - free ( m ); - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* free memory */ - free ( m->off_vekt ); - free ( m->mask_vekt ); - free ( m ); - free ( hist ); - - return ( pic_new ); -} -#endif diff --git a/Utilities/IpFunc/MultC.c b/Utilities/IpFunc/MultC.c deleted file mode 100644 index cfffd817fe..0000000000 --- a/Utilities/IpFunc/MultC.c +++ /dev/null @@ -1,264 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function multiplies two images - */ - -/** @brief multiplies two images - * - * @param pic_1 pointer to the first image - * @param value constant which is multiplied to image - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c mitkIpFuncNoKeep : image data type could be changed - * @arg @c mitkIpFuncKeep : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory which could be used for pic_new. If - * pic_retrun == NULL new memory is allocated - * - * @retrun pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncMultC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncMultI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* definition of macros */ - -#define MULTC( type_1, pic_1, pic_new, value ) \ -{ \ - mitkIpPicFORALL_3 ( MULTC2, pic_new, pic_1, type_1, value ); \ -} \ - - -#define MULTC2( type_n, pic_new, pic_1, type_1, value ) \ -{ \ - mitkIpUInt4_t i; /* loop index */\ - mitkIpUInt4_t no_elem; \ - \ - \ - /* multiply greyvalues of both images */\ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type_n * ) pic_new->data ) [i] = ( type_n ) \ - ( ( mitkIpFloat8_t ) (( type_1 * ) pic_1->data ) [i] * \ - value ); \ - } \ -} - -#define MULTC3( type_n, pic_1, pic_new, value ) \ -{ \ - mitkIpUInt4_t i; /* loop index */\ - mitkIpFloat8_t help; /* greyvalue of actual pixel */\ - mitkIpUInt4_t no_elem; \ - \ - \ - /* multiply greyvalues of both images */\ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = ( mitkIpFloat8_t ) (( type_n * ) pic_1->data ) [i] * value; \ - (( type_n * ) pic_new->data ) [i] = \ - ( max_gv > ( mitkIpFloat8_t ) help ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help ) ? \ - ( (type_n) ( help ) ) : ( type_n ) min_gv ) : \ - ( type_n ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncMultC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check value */ - - /* if ( value == 0. ) return ( mitkIpFuncERROR ); */ - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_old, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = max1 * value; - smin = min1 * value; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_old->type == mitkIpPicInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicUInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || smin < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - - /* macro to invert the picture (for all data types) */ - - - if ( keep == mitkIpFuncNoKeep ) - mitkIpPicFORALL_2 ( MULTC, pic_old, pic_new, value ) - else if ( keep == mitkIpFuncKeep ) - mitkIpPicFORALL_2 ( MULTC3, pic_old, pic_new, value ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/MultI.c b/Utilities/IpFunc/MultI.c deleted file mode 100644 index f939d2b243..0000000000 --- a/Utilities/IpFunc/MultI.c +++ /dev/null @@ -1,279 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function multiplies two images - */ - -/** this function multiplies two images - * - * @param pic_1 pointer to the first image - * @param pic_2 pointer to the second image - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c mitkIpFuncNoKeep : image data type could be changed - * @arg @c mitkIpFuncKeep : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncMultI ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define MULTI( type_1, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpPicFORALL_3 ( MULTI2, pic_new, pic_1, pic_2, type_1 ); \ -} \ - - -#define MULTI2( type_n, pic_new, pic_1, pic_2, type_1 ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type_n * ) pic_new->data ) [i] = \ - (( type_1 * ) pic_1->data ) [i] * \ - (( type_1 * ) pic_2->data ) [i]; \ - } \ -} - -#define MULTI3( type_n, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - type_n help; \ - type_n help2; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = (( type_n * ) pic_1->data ) [i]; \ - help2 = (( type_n * ) pic_2->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( max_gv > ( mitkIpFloat8_t ) help * ( mitkIpFloat8_t ) help2 ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help * ( mitkIpFloat8_t ) help2 ) ? \ - ( (type_n)help * (type_n)help2 ) : ( type_n ) min_gv ) :\ - ( type_n ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncMultI ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t min2, max2; /* extreme greyvalues of 2. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - mitkIpFloat8_t min_max12; /* product of min1 and max2 */ - mitkIpFloat8_t min_max21; /* product of min2 and max1 */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check whether images have the same size */ - - if ( ( pic_1->type != pic_2->type ) || ( pic_1->bpe != pic_2->bpe ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - if ( pic_1->dim == pic_2->dim ) - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - { - if ( pic_1->n[i] != pic_2->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_1->type, pic_1->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( mitkIpFuncExtr ( pic_2, &min2, &max2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = max1 * max2; - smin = min1 * min2; - min_max12 = min1 * max2; - min_max21 = min2 * max1; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_1->type == mitkIpPicInt ) - { - if ( smax < max_gv && min_max12 < max_gv && min_max21 < max_gv && - smin > min_gv && min_max12 > min_gv && min_max21 > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicUInt ) - { - if ( smax < max_gv && min_max12 < max_gv && min_max21 < max_gv && - smin > min_gv && min_max12 > min_gv && min_max21 > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || min_max12 > max_gv || min_max21 > max_gv || - smin < min_gv || min_max12 < min_gv || min_max21 < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - if ( keep == mitkIpFuncNoKeep ) - mitkIpPicFORALL_2 ( MULTI, pic_1, pic_2, pic_new ) - else if ( keep == mitkIpFuncKeep ) - mitkIpPicFORALL_2 ( MULTI3, pic_1, pic_2, pic_new ) - - mitkIpFuncCopyTags(pic_new, pic_1); - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/Norm.c b/Utilities/IpFunc/Norm.c deleted file mode 100644 index e266e60fa5..0000000000 --- a/Utilities/IpFunc/Norm.c +++ /dev/null @@ -1,137 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function normalizes an image - */ - -/** @brief normalizes an image - * @param pic_old pointer to the image that should be inverted - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the normalized image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncNorm ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - - -/* definition of macro for normalisation */ - -#define NORM( type, pic, min, max, min_gv, max_gv ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - mitkIpFloat8_t a, b; \ - \ - a = ( mitkIpFloat8_t ) ( max_gv - min_gv ) / ( max - min ); \ - b = ( mitkIpFloat8_t ) ( max_gv ) - a * max; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type * ) pic_new->data ) [i] = \ - ( type ) ( a * (( type * ) pic->data ) [i] + b ); \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -** function picNorm: normalizes the greyvalues of the picture (pic_old) -** and returns the normalized picture (pic_new) -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncNorm ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - mitkIpFloat8_t max, min; /* extreme greyvalues in the image */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate extreme grevalues of the image */ - - if ( mitkIpFuncExtr ( pic_old, &min, &max ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. or min possible greyvalue for datatype */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* test whether normalisation is necessary */ - - if ( ( max_gv == max ) && ( min_gv == min ) ) - return ( pic_old ); - - /* create a new picture, copy the header, allocate memory */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to invert the picture (for all data types) */ - - mitkIpPicFORALL_4( NORM, pic_old, min, max, min_gv, max_gv ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/NormXY.c b/Utilities/IpFunc/NormXY.c deleted file mode 100644 index 929dfa9440..0000000000 --- a/Utilities/IpFunc/NormXY.c +++ /dev/null @@ -1,164 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function normalizes an image to a specified range -*/ - -/** @brief normalizes an image to a specified range - * - * @param pic_old pointer to the image to normalize - * @param low lower border of range - * @param up upper border of range - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the noRmalized image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncNormXY ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t low, - mitkIpFloat8_t up, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -/* definition of macro for normalisation */ - -#define NORM( type, pic, min, max, min_gv, max_gv ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - mitkIpFloat8_t a, b; \ - \ - a = ( mitkIpFloat8_t ) ( max_gv - min_gv ) / ( max - min ); \ - b = ( mitkIpFloat8_t ) ( max_gv ) - a * max; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type * ) pic_new->data ) [i] = \ - ( type ) ( a * (( type * ) pic->data ) [i] + b ); \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -** function picNorm: normalizes the greyvalues of the picture (pic_old) -** and returns the normalized picture (pic_new) -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncNormXY ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t low, - mitkIpFloat8_t up, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - mitkIpFloat8_t max, min; /* extreme greyvalues in the image */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - - - /* check whether data are ok */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate extreme grevalues of the image */ - - if ( mitkIpFuncExtr ( pic_old, &min, &max ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max and min. possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* check data */ - - if ( max == min ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( low >= up ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( low < min_gv || up > max_gv ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* test whether normalisation is necessary */ - - if ( ( up == max ) && ( low == min ) ) - return ( pic_old ); - - /* create a new picture, copy the header, allocate memory */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to invert the picture (for all data types) */ - - mitkIpPicFORALL_4( NORM, pic_old, min, max, low, up ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/Not.c b/Utilities/IpFunc/Not.c deleted file mode 100644 index b2b4d2e3a1..0000000000 --- a/Utilities/IpFunc/Not.c +++ /dev/null @@ -1,114 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs the logical not operation on an image - */ - -/** @brief performs the logical not operation on an image - * - * @param pic_old pointer to the image that should be inverted - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the inverted image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncNot ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -/* definition of invert-macro */ - -#define NOT( type, pic ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type * ) pic_new->data ) [i] = ! ( (( type * ) pic->data ) [i] ); \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncNot ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* create a new picture, copy the header, allocate memory */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to invert the picture (for all data types) */ - - mitkIpPicFORALL ( NOT, pic_old ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/OpCl.c b/Utilities/IpFunc/OpCl.c deleted file mode 100644 index 9c742d9ea2..0000000000 --- a/Utilities/IpFunc/OpCl.c +++ /dev/null @@ -1,147 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this functions performs the morphological operations opening and - * closing. - */ - -/** @briefs performs the morphological operations opening and - * closing. - * - * Opening is an erosion followed by a dilation and a - * closing is a dilation followed by an erosion. - * - * @param pic_old pointer to the original image - * @param mask pointer to the kernel - * @param kind tells whether opening or closing is performed - * @arg @c 0 (mitkIpOPEN) : opening - * @arg @c 1 (mitkIpCLOSE) : closing - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to zero - * - * @return pointer to the transformed image - * - * USES - * function _mitkIpFuncError - checks the image data - * function _mitkIpFuncMorph - performs morphological operations - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *_mitkIpFuncOpCl ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - _mitkIpFuncFlagF_t kind, - mitkIpFuncFlagI_t border ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* ---------------------------------------------------------------------- */ -/* -** function mitkIpFuncOpCl -*/ -/* ---------------------------------------------------------------------- */ - -mitkIpPicDescriptor *_mitkIpFuncOpCl ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - _mitkIpFuncFlagF_t kind, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new1; /* pointer to transformed image */ - mitkIpPicDescriptor *pic_new2; /* pointer to transformed image */ - mitkIpUInt4_t i; /* loop index */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( mask ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( mask->dim > pic_old->dim ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - for ( i = 0; i < mask->dim; i++ ) - if ( mask->n[i] > pic_old->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncSIZE_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* check whether opening or closing operation should be performed */ - - if ( kind == mitkIpFuncOpenF ) - { - pic_new1 = _mitkIpFuncMorph ( pic_old, mask, mitkIpFuncEroF, border ); - if ( border == mitkIpFuncBorderZero ) - pic_new1 = mitkIpFuncBorder ( pic_new1, mask, pic_new1 ); - pic_new2 = _mitkIpFuncMorph ( pic_new1, mask, mitkIpFuncDilaF, border ); - if ( border == mitkIpFuncBorderZero ) - pic_new2 = mitkIpFuncBorder ( pic_new2, mask, pic_new2 ); - } - else if ( kind == mitkIpFuncCloseF ) - { - pic_new1 = _mitkIpFuncMorph ( pic_old, mask, mitkIpFuncDilaF, border ); - if ( border == mitkIpFuncBorderZero ) - pic_new1 = mitkIpFuncBorder ( pic_new1, mask, pic_new1 ); - pic_new2 = _mitkIpFuncMorph ( pic_new1, mask, mitkIpFuncEroF, border ); - if ( border == mitkIpFuncBorderZero ) - pic_new2 = mitkIpFuncBorder ( pic_new2, mask, pic_new2 ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - mitkIpPicFree ( pic_new1 ); - - return ( pic_new2 ); -} -#endif diff --git a/Utilities/IpFunc/Open.c b/Utilities/IpFunc/Open.c deleted file mode 100644 index f0469bed67..0000000000 --- a/Utilities/IpFunc/Open.c +++ /dev/null @@ -1,91 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this functions performs the morphological opening operation - */ - -/** @briefs performs the morphological opening operation - * - * Opening is an erosion followed by a dilation - * @param pic_old pointer to the original image - * @param mask pointer to the kernel - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to zero - * - * @return pointer to transformed iamge - * - * AUTHOR & DATE - */ - -/* include /files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncOpen ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -mitkIpPicDescriptor *mitkIpFuncOpen ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new; - - pic_new = _mitkIpFuncOpCl ( pic_old, pic_mask, mitkIpFuncOpenF, border ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} - -#endif diff --git a/Utilities/IpFunc/Or.c b/Utilities/IpFunc/Or.c deleted file mode 100644 index 9ae4277775..0000000000 --- a/Utilities/IpFunc/Or.c +++ /dev/null @@ -1,135 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function connects two images using the OR - */ - -/** @brief connects two images using the OR - * - * @param pic_1 pointer to the first image - * @param pic_2 pointer to the second image - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncOr ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpPicDescriptor *pic_return ) ; -#ifndef DOXYGEN_IGNORE - -/* definition of invert-macro */ - -#define OR( type, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type * ) pic_new->data ) [i] = \ - (( type * ) pic_1->data ) [i] || \ - (( type * ) pic_2->data ) [i]; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncOr ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt4_t i; /* loop index */ - - /* check whether images have the same size */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( ( pic_1->type != pic_2->type ) || ( pic_1->bpe != pic_2->bpe ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - if ( pic_1->dim == pic_2->dim ) - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - { - if ( pic_1->n[i] != pic_2->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - - /* allocate new iumage */ - - pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to connect two images using AND */ - - mitkIpPicFORALL_2 ( OR, pic_1, pic_2, pic_new ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_1); - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/Pot.c b/Utilities/IpFunc/Pot.c deleted file mode 100644 index 43c2aa3345..0000000000 --- a/Utilities/IpFunc/Pot.c +++ /dev/null @@ -1,227 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * This function takes all greyvalues of the image to the power of the exponent. - */ - -/** @brief takes all greyvalues of the image to the power of the exponent. - * - * @param pic_1 pointer to the first image - * @param exponent exponent - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c mitkIpFuncNoKeep : image data type could be changed - * @arg @c mitkIpFuncKeep : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory which could be used for pic_new. If - * pic_retrun == NULL new memory is allocated - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncPot ( mitkIpPicDescriptor *pic_1, - mitkIpFloat8_t exponent, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define POT1( type_1, pic_1, exponent, pic_new ) \ -{ \ - mitkIpPicFORALL_3 ( POT2, pic_new, pic_1, exponent, type_1 ); \ -} \ - - -#define POT2( type_n, pic_new, pic_1, exponent, type_1 ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - mitkIpFloat8_t help; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = pow( ( mitkIpFloat8_t) (( type_1 * ) pic_1->data ) [i], \ - exponent ); \ - (( type_n * ) pic_new->data ) [i] = \ - ( max_gv > help ) ? \ - (( min_gv < help ) ? (type_n)help : ( type_n )min_gv ) : \ - ( type_n ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncPot ( mitkIpPicDescriptor *pic_1, - mitkIpFloat8_t exponent, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_1->type, pic_1->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - smax = pow ( max1, exponent ); - smin = pow ( min1, exponent ); - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_1->type == mitkIpPicInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicUInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || smin < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - mitkIpPicFORALL_2 ( POT1, pic_1, exponent, pic_new ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_1); - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/README b/Utilities/IpFunc/README deleted file mode 100644 index 8b037b6649..0000000000 --- a/Utilities/IpFunc/README +++ /dev/null @@ -1,12 +0,0 @@ -Kompilieren von libipFunc.a: - -cp ipFuncLib.pro ipFunc.pro -qmake ipFunc.pro -make - - - -Kompilieren von ipFunc: -cp ipFuncMain.pro ipFunc.pro -qmake ipFunc.pro -make diff --git a/Utilities/IpFunc/Range.c b/Utilities/IpFunc/Range.c deleted file mode 100644 index a14b66ed90..0000000000 --- a/Utilities/IpFunc/Range.c +++ /dev/null @@ -1,107 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function checks whether the greyvalues of the image are in the - * spezified range - */ - -/** @brief checks whether the greyvalues of the image are in the - * spezified range - * - * @param pic_old pointer to original image - * @param gv_low lower end of range - * @param gv_up upper end of range - * - * @return mitkIpFuncOK when greyvalues are in specified range - * @return mitkIpFuncERROR when greyvalues are not in specigfied range or an error - * occured - * - * USES - * function mitkIpFuncExtr : to calculate extreme greyvalues of the image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpUInt4_t mitkIpFuncRange ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/* ------------------------------------------------------------------------ */ -/* -** function mitkIpFuncRange -*/ -/* ------------------------------------------------------------------------ */ - -mitkIpUInt4_t mitkIpFuncRange ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up ) -{ - mitkIpFloat8_t min, max; /* extreme greyvalues */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( gv_low > gv_up ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate max. and min. possible greyvalues */ - - if ( mitkIpFuncExtr ( pic_old, &min, &max) == mitkIpFuncERROR ) return ( mitkIpFuncERROR ); - - if ( min > gv_low || max < gv_up ) return ( mitkIpFuncOK ); - else return ( mitkIpFuncERROR ); - -} -#endif - diff --git a/Utilities/IpFunc/Rank.c b/Utilities/IpFunc/Rank.c deleted file mode 100644 index 5ac4cb530a..0000000000 --- a/Utilities/IpFunc/Rank.c +++ /dev/null @@ -1,323 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs a filtering of the image. The new greyvalue of - * the image is calculated by taking the greyvalue belonging to the - * specified range after having sorted the greyvalues included by the mask - */ - -/** @brief performs a filtering of the image. The new greyvalue of - * the image is calculated by taking the greyvalue belonging to the - * specified range after having sorted the greyvalues included by the mask - * - * @param pic_old pointer to original image - * @param rank rank (number of pixel which is taken after having sorted - * the pixels under the mask) - * rank = 0 : Median - * @param mask_dim dimension of mask - * @param mask_size number of pixel in each dimension of the mask - * @param border tells how the edge is handled - * @arg @c mitkIpFuncBorderOld : greyvalue of pic_old is kept - * @arg @c mitkIpFuncBorderZero : greyvalue of edge pixels is set to zero - * - * @return pointer to transformed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncRank ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t rank, - mitkIpUInt4_t mask_dim, - mitkIpUInt4_t mask_size, - mitkIpFuncFlagI_t border ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - -#include "mitkIpFuncP.h" - -/* definition of macros */ - -#define INDEX0( typ, pic ) ( mitkIpUInt4_t ) ( factor * (( typ * ) pic->data ) \ - [off_vekt[i] + off[0]] + help ) -#define INDEX2( typ, pic ) ( mitkIpUInt4_t ) ( factor * (( typ * ) pic->data ) \ - [off_vekt[i] + off[0]] + help ) -#define INDEX3( typ, pic ) ( mitkIpUInt4_t ) ( factor * (( typ * ) pic->data ) \ - [off[0] - off_vekt[i]] + help ) -#define RANK( typ, pic, begin, no_elem, size, rank ) \ -{ \ - mitkIpUInt4_t n[_mitkIpPicNDIM]; /* size of each dimension */ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t *hist; /* greyvalue histogram */ \ - mitkIpUInt4_t sum; /* used to calculate rank */ \ - mitkIpUInt4_t end; /* number of elements that change */ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t beg; /* beginning of the loops */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - mitkIpFloat8_t min_gv, max_gv; /* min./max. possible greyvalues */ \ - mitkIpFloat8_t help, factor; \ - mitkIpUInt4_t hist_size; \ - \ - /* initialize vectors */ \ - \ - beg = ( mitkIpUInt4_t ) begin; \ - for ( i = 0; i < _mitkIpPicNDIM; i++ ) off[i] = 0; \ - for ( i = 0; i < pic->dim; i++ ) n[i] = pic->n[i] - beg; \ - for ( i = pic->dim; i < _mitkIpPicNDIM; i++ ) \ - { \ - n[i] = 1 + beg; \ - size[i] = 0; \ - } \ - \ - /* calculate max. and min. possible greyvalues */ \ - \ - if ( mitkIpFuncExtr( pic, &min_gv, &max_gv ) == mitkIpFuncERROR ) \ - { \ - free ( off_vekt ); \ - mitkIpPicFree ( pic_new ); \ - return ( mitkIpFuncERROR ); \ - } \ - \ - /* allocate memory for histogram and calculate variables which are needed for */ \ - /* allocation */ \ - \ - end = no_elem / mask_size; \ - factor = ( pic->type == mitkIpPicFloat ) ? 1000. : 1.; \ - help = fabs ( min_gv ); \ - hist_size = ( mitkIpUInt4_t ) ( factor * ( fabs ( max_gv ) + help ) ); \ - help = help * factor; \ -/*hist = calloc ( hist_size+1, sizeof ( mitkIpUInt4_t ) ); \ - if ( hist == NULL ) \ - { \ - free ( off_vekt ); \ - mitkIpPicFree ( pic_new ); \ - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); \ - return ( mitkIpFuncERROR ); \ - } \ - */ \ - /* transform pixels */ \ - \ - for ( ind[7] = beg ; ind[7] < n[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg ; ind[6] < n[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg ; ind[5] < n[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg ; ind[4] < n[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg ; ind[3] < n[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg ; ind[2] < n[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg ; ind[1] < n[1]; ind[1]++ ) \ - { \ - /* calculate histogram with pixels under mask */ \ - /* (complete histogram for new rows) */ \ - \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1] + beg; \ - /*memset ( hist, 0, hist_size );*/ \ - hist = calloc ( hist_size+1, sizeof ( mitkIpUInt4_t ) ); \ - for ( i = 0; i < no_elem; i++ ) hist[INDEX0 ( typ, pic )]++; \ - for ( i = 0, sum = 0; sum < rank; i++ ) sum = sum + hist[i]; \ - (( typ * ) pic_new->data )[off[0]] = ( typ ) \ - ( ( ( mitkIpFloat8_t ) i - help ) / factor ); \ - for ( ind[0] = beg+1; ind[0] < n[0]; ind[0]++ ) \ - { \ - /* change histogram for each column */ \ - \ - for ( i = 0; i < end; i++ ) hist[INDEX2 ( typ, pic )]--; \ - off[0]++; \ - for ( i = 0; i < end; i++ ) hist[INDEX3 ( typ, pic )]++; \ - for ( i = 0, sum = 0; sum < rank; i++ ) sum = sum + hist[i]; \ - (( typ * ) pic_new->data )[off[0]] = ( typ ) \ - ( ( ( mitkIpFloat8_t ) i - help -1.) / factor );\ - } \ - free ( hist );\ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -/*free ( hist ); */ \ -} - - -/* ------------------------------------------------------------------------------ */ -/* -** function mitkIpFuncRank -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncRank ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t rank, - mitkIpUInt4_t mask_dim, - mitkIpUInt4_t mask_size, - mitkIpFuncFlagI_t border ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpInt4_t i; /* loop index */ - mitkIpInt4_t offset; /* offset of image */ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ - mitkIpInt4_t *off_vekt; /* pointer to offset vector */ - mitkIpInt4_t begin; /* 0.5 * mask_size */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - mitkIpInt4_t n[_mitkIpPicNDIM]; /* size of each dimension */ - mitkIpUInt4_t no_elem; /* number of elements in mask */ - mitkIpUInt4_t len; /* length of offset vector */ - - /* calculate number of elements in mask */ - - no_elem = mask_size; - for ( i = 1; i < mask_dim; i++ ) - no_elem = no_elem * mask_size; - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( mask_dim < 1 || mask_dim > pic_old->dim ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( rank > no_elem ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( mask_size % 2 != 1 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncSIZE_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - - len = 0; - begin = mask_size / 2; - - for ( i = 0; i < mask_dim; i++ ) - n[i] = begin + 1; - for ( i = mask_dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 1 - begin; - - /* allocate image structure */ - - if ( border == mitkIpFuncBorderOld ) - pic_new = mitkIpPicClone ( pic_old ); - else if ( border == mitkIpFuncBorderZero ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe/8 ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate offset vector */ - - off_vekt = malloc ( no_elem * sizeof ( mitkIpUInt4_t ) ); - if ( off_vekt == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate offset vector */ - - for ( ind[0] = -begin; ind[0] < n[0]; ind[0]++ ) - for ( ind[7] = -begin; ind[7] < n[7]; ind[7]++ ) - for ( ind[6] = -begin; ind[6] < n[6]; ind[6]++ ) - for ( ind[5] = -begin; ind[5] < n[5]; ind[5]++ ) - for ( ind[4] = -begin; ind[4] < n[4]; ind[4]++ ) - for ( ind[3] = -begin; ind[3] < n[3]; ind[3]++ ) - for ( ind[2] = -begin; ind[2] < n[2]; ind[2]++ ) - for ( ind[1] = -begin; ind[1] < n[1]; ind[1]++ ) - { - offset = 0; - for ( i = 0; i < pic_old->dim; i++ ) - offset = offset + ind[i] * size[i]; - off_vekt[len] = offset; - len++; - } - if ( rank == 0 ) rank = no_elem / 2 + 1; - mitkIpPicFORALL_4 ( RANK, pic_old, begin, no_elem, size, rank ); - - free ( off_vekt ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif diff --git a/Utilities/IpFunc/Refl.c b/Utilities/IpFunc/Refl.c deleted file mode 100644 index 1fc3d89560..0000000000 --- a/Utilities/IpFunc/Refl.c +++ /dev/null @@ -1,202 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function reflects an image along one axis - */ - -/** @brief reflects an image along one axis - * - * @param pic_old pointer to the image that should be inverted - * @param axis reflection axis: 1 => x-axis - * 2 => y-axis - * 3 => z-axis - * 4 => t-axis - * - * @return pointer to the reflected image - * - * AUTHOR & DATE - */ -/* include Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncRefl ( mitkIpPicDescriptor *pic_old, int axis ); - -#ifndef DOXYGEN_IGNORE - -/* definition of reflect-macro */ - -#define ForLoop( type, pic, pic_new, index, offset_orig, offset_func ) \ -{ \ - mitkIpUInt4_t i; \ - mitkIpUInt4_t offset_refl; \ - mitkIpInt4_t n[_mitkIpPicNDIM]; \ - \ - for ( i = 0; i < pic_old->dim; i++ ) \ - n[i] = pic_old->n[i]; \ - \ - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) \ - n[i] = 1; \ - \ - offset_refl = 0; \ - for ( index[7] = 0; index[7] < n[7]; index[7]++ ) \ - \ - for ( index[6] = 0; index[6] < n[6]; index[6]++ ) \ - \ - for ( index[5] = 0; index[5] < n[5]; index[5]++ ) \ - \ - for ( index[4] = 0; index[4] < n[4]; index[4]++ ) \ - \ - for ( index[3] = 0; index[3] < n[3]; index[3]++ ) \ - \ - for ( index[2] = 0; index[2] < n[2]; index[2]++ ) \ - \ - for ( index[1] = 0; index[1] < n[1]; index[1]++ ) \ - \ - for ( index[0] = 0; index[0] < n[0]; index[0]++ ) \ - { \ - offset_func; \ - (( type * ) pic_new->data ) [offset_refl] = \ - (( type * ) pic->data ) [offset_orig]; \ - offset_refl++; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -** function picRefl : reflects a picture (pic_old) along one axis -** (axis) -** axis: 1 => x-axis -** 2 => y-axis -** 3 => z-axis -** 4 => t-axis -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncRefl ( mitkIpPicDescriptor *pic_old, int axis ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - mitkIpUInt4_t index_vect[_mitkIpPicNDIM]; /* loop index vector */ - mitkIpUInt4_t length_vect[_mitkIpPicNDIM]; - mitkIpUInt4_t axis_vect[_mitkIpPicNDIM]; - mitkIpInt4_t n[_mitkIpPicNDIM]; /* number of pixels in each */ - /* dimension */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t offset_orig; - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( axis < 1 || axis > pic_old->dim ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of vectors */ - - for ( i = 0; i < pic_old->dim; i++ ) - n[i] = pic_old->n[i]; - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 1; - - - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - { - index_vect[i] = 0; - axis_vect[i] = 0; - } - - /* change index for x and y axis */ - - if ( axis == 1 ) - axis = 2; - else if ( axis == 2 ) - axis = 1; - axis_vect[axis - 1] = n[axis - 1] - 1; - - length_vect[0] = 1; - for ( i = 1; i < pic_old->dim; i++ ) - { - length_vect[i] = n[i-1] * length_vect[i-1]; - } - - /* create a new picture, copy the header, allocate memory */ - - pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to reflect image (for all image data types) */ - mitkIpPicFORALL_4 ( ForLoop, pic_old, pic_new, index_vect, offset_orig, - offset_orig = 0; - for ( i = 0; i < pic_old->dim; i++ ) - { - offset_orig = offset_orig + length_vect [i] * - (( axis_vect [i] == 0 ) ? - index_vect [i] : - ( axis_vect [i] - index_vect[i] )); - } - ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/RegGrow.c b/Utilities/IpFunc/RegGrow.c deleted file mode 100644 index 7fb62631af..0000000000 --- a/Utilities/IpFunc/RegGrow.c +++ /dev/null @@ -1,593 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs a region growing by mean and standard deviation. - */ - -/** @brief performs a region growing by mean and standard deviation. - * - * The growing criteria is, that the new pixels greyvalue must be in the - * standard deviation of the seed region. - * After calculating the mean and standard deviation of the seed region, all - * pixels of this region are investigated whether they belong to a region - * or not. All accepted pixels are marked with a region_label. In the next - * step the neigbours of all accepted pixels are investigated whether they - * belong to the region or to the border or to none of them. At the end all - * pixels which belong to the boder (which contains the first pixel of the - * outside region) are marked. - * - * @param pic_old pointer to original image - * @param dim_seed dimension of seed region - * @param beg_seed array with start pixels of seed_region - * @param end_seed array with end pixels of seed_region - * @param border_label greyvalue for border pixels - * @param region_label greyvalue for pixels in region - * @param std_fact factor ( to multiply standard deviation with ) - * @param kind tells wether region or border should be shown - * 0 : border of region is shown - * 1 : region is shown - * - * @return pointer to new image - * - * USES - * function _mitkIpFuncError - check image data - * - * AUTHOR & DATE - * UPDATES - * - * $Log$ - * Revision 1.2 2000/05/24 15:29:43 tobiask - * Changed the installation paths of the package. - * - * Revision 1.4 2000/05/04 12:52:10 ivo - * inserted BSD style license - * - * Revision 1.3 2000/03/06 17:02:44 ivo - * ipFunc now with doxygen documentation. - * - * Revision 1.2 2000/02/18 14:58:06 ivo - * Tags are now copied into newly allocated images. - * Bugs fixed in mitkIpFuncFrame, mitkIpFuncRegGrow, _mitkIpFuncBorderX and mitkIpFuncHitMiss. - * - * Revision 1.1.1.1 2000/02/18 15:22:50 ivo - * in macro REGGROW line if(diff<std_win) changed to if ( diff <= std_win ), - * because otherwise a standard deviation of zero will result in an emty - * image. - * - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncRegGrow ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_seed, - mitkIpUInt4_t *beg_seed, - mitkIpUInt4_t *end_seed, - mitkIpUInt4_t border_label, - mitkIpUInt4_t region_label, - mitkIpFloat8_t std_fact, - mitkIpUInt4_t kind ) ; - -#ifndef DOXYGEN_IGNORE - - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - -#include "mitkIpFuncP.h" - -/* definition of macros */ - -#define STAT( type, pic_old, pic_new, mean, std_win, size_seed, beg, end ) \ -{ \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset vector */ \ - mitkIpFloat8_t sum; /* sum of greyvalues in seed region */ \ - mitkIpFloat8_t saq; /* sum of deviation squares */ \ - mitkIpFloat8_t diff; /* used to calculate saq */ \ - mitkIpFloat8_t std_dev; /* standard deviation */ \ - \ - \ - /* calculate mean */ \ - \ - sum = 0.; \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1] + beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - sum = sum + \ - ( mitkIpFloat8_t ) (( type * ) pic_old->data) [off[0]]; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - mean = sum / ( mitkIpFloat8_t ) size_seed; \ - \ - \ - /* standard deviation */ \ - \ - saq = 0.; \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1] + beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - diff = ( mitkIpFloat8_t ) (( type * ) pic_old->data )[off[0]] - \ - mean; \ - saq = saq + diff * diff; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - std_dev = sqrt ( saq / ( mitkIpFloat8_t ) ( size_seed - 1 ) ); \ - std_win = std_dev * std_fact; \ - printf ( "mean: %lf std_win: %lf \n", mean, std_win);\ -} - -#define ACPT( type, pic_old, pic_new, acpt, acpt_len, region_label, std_win ) \ -{ \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset */ \ - mitkIpFloat8_t diff; /* difference between pixel and mean */ \ - \ - /* find pixels in seed region which are accepted */ \ - \ - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1] + beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - diff = fabs ( ( mitkIpFloat8_t ) \ - (( type * )pic_old->data )[off[0]] - mean ); \ - \ - /* pixel accepted */ \ - \ - if ( diff <= std_win ) \ - { \ - acpt[acpt_len] = off[0]; \ - acpt_len++; \ - (( type * ) pic_new->data )[off[0]] = \ - ( type ) region_label; \ - } \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - -#define REGGROW( type, pic_old, pic_new, acpt, acpt_len, \ - border, border_len, std_win ) \ -{ \ - mitkIpUInt4_t i, j; /* loop variables */ \ - mitkIpInt4_t k; /* loop variable */ \ - mitkIpInt4_t rest; /* */ \ - mitkIpInt4_t z2; /* */ \ - mitkIpInt4_t z[_mitkIpPicNDIM]; /* */ \ - mitkIpBool_t found; /* found flag */ \ - mitkIpBool_t out; /* offset out of image flag */ \ - mitkIpFloat8_t diff; /* difference between pixel and mean */ \ - mitkIpUInt4_t offset; /* offset of pixel in image */ \ - \ - while ( acpt_len > 0 ) \ - { \ - for ( i = 0; i < acpt_len; i++ ) \ - { \ - rest = ( mitkIpInt4_t ) acpt[i]; \ - for ( k = pic_old->dim-1; k >= 0; k-- ) \ - { \ - z[k] = rest / ( mitkIpInt4_t )size[k]; \ - rest = rest % ( mitkIpInt4_t )size[k]; \ - } \ - \ - for ( j = 0; j < no_neigh; j++ ) \ - { \ - rest = off_vekt[j]; \ - out = mitkIpFalse; \ - for ( k = pic_old->dim-1; k >= 0; k-- ) \ - { \ - z2 = rest / ( mitkIpInt4_t )size[k] + z[k]; \ - rest = rest % ( mitkIpInt4_t )size[k]; \ - if ( z2 >= ( mitkIpInt4_t ) pic_old->n[k] || z2 < 0 ) out = mitkIpTrue; \ - } \ - \ - offset = ( mitkIpUInt4_t )( ( mitkIpInt4_t ) acpt[i] + off_vekt[j] ); \ - if ( ( !out ) && \ - (( type * )pic_new->data )[offset] != ( type ) region_label ) \ - { \ - diff = fabs ( ( mitkIpFloat8_t ) \ - (( type * )pic_old->data )[offset] - mean ); \ - if ( diff <= std_win ) \ - { \ - (( type * )pic_new->data )[offset] = ( type ) region_label;\ - next[next_len] = offset; \ - next_len++; \ - } \ - else \ - { \ - found = mitkIpFalse; \ - k = 0; \ - while ( ( !found ) && k < border_len ) \ - { \ - if ( border[k] == offset ) found = mitkIpTrue; \ - k++; \ - } \ - if ( !found ) \ - { \ - border[border_len] = offset; \ - border_len++; \ - } \ - } \ - } \ - } \ - } \ - acpt_len = next_len; \ - next_len = 0; \ - help = acpt; \ - acpt = next; \ - next = help; \ - } \ - if ( kind == 0 ) \ - { \ - mitkIpPicFree ( pic_new ); \ - pic_new = mitkIpPicClone ( pic_old ); \ - for ( i = 0; i < border_len; i++ ) \ - (( type * )pic_new->data )[border[i]] = border_label; \ - } \ -} -/* -------------------------------------------------------------------------- */ -/* -** mitkIpFuncRegGrow -*/ -/* -------------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncRegGrow ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_seed, - mitkIpUInt4_t *beg_seed, - mitkIpUInt4_t *end_seed, - mitkIpUInt4_t border_label, - mitkIpUInt4_t region_label, - mitkIpFloat8_t std_fact, - mitkIpUInt4_t kind ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ - mitkIpInt4_t beg[_mitkIpPicNDIM]; /* beginning and end of seed region */ - mitkIpInt4_t end[_mitkIpPicNDIM]; /* for each dimension */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - mitkIpInt4_t off[_mitkIpPicNDIM]; /* used to calculate offsets */ - mitkIpInt4_t offset_v; /* offset */ - mitkIpInt4_t *off_vekt; /* offsets of all neighbour pixels */ - mitkIpUInt4_t no_neigh; /* number of neighbour pixels */ - - /* parameters of seed region */ - - mitkIpFloat8_t mean; /* mean of greyvalues in seed region */ - /*mitkIpFloat8_t std_dev; */ /* standard deviation */ - mitkIpFloat8_t std_win; /* value for growing criteria */ - /*mitkIpFloat8_t sum; */ /* sum of greyvalues in seed region */ - /*mitkIpFloat8_t diff; */ /* difference between greyvalue, mean */ - /*mitkIpFloat8_t saq; */ /* sum of deviation squares */ - mitkIpUInt4_t size_seed; /* number of pixels in seed region */ - - /* variables for region growing */ - - mitkIpUInt4_t acpt_len; /* number of accepted pixels */ - mitkIpUInt4_t next_len; /* number of acc. pixels for next step */ - mitkIpUInt4_t border_len; /* number of border pixels */ - mitkIpUInt4_t *acpt; /* offsets of all accepted pixels */ - mitkIpUInt4_t *next; /* offsets of acc. pixels for next step*/ - mitkIpUInt4_t *help; /* */ - mitkIpUInt4_t *border; /* offsets of all border pixels */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check parameters */ - - if ( dim_seed > pic_old->dim ) return ( mitkIpFuncERROR ); - for ( i = 0; i < dim_seed; i++ ) - { - if ( end_seed[i] <= beg_seed[i] || end_seed[i] > pic_old->n[i] || - beg_seed[i] < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - /* allocate vectors */ - - no_neigh = ( mitkIpUInt4_t ) pow ( 3., pic_old->dim ); - - off_vekt = malloc ( no_neigh * sizeof ( mitkIpInt4_t ) ); - if ( off_vekt == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - acpt = malloc ( _mitkIpPicElements ( pic_old ) * sizeof ( mitkIpUInt4_t ) ); - if ( acpt == NULL ) - { - free ( off_vekt ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - next = malloc ( _mitkIpPicElements ( pic_old ) * sizeof ( mitkIpUInt4_t ) ); - if ( next == NULL ) - { - free ( off_vekt ); - free ( acpt ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* - help = malloc ( _mitkIpPicElements ( pic_old ) * sizeof ( mitkIpUInt4_t ) ); - if ( help == NULL ) - { - free ( off_vekt ); - free ( acpt ); - free ( next ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - - border = malloc ( _mitkIpPicElements ( pic_old ) * sizeof ( mitkIpUInt4_t ) ); - if ( border == NULL ) - { - free ( off_vekt ); - free ( acpt ); - free ( next ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate pic_new and initialize it to zero */ - - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_new == NULL ) - { - free ( off_vekt ); - free ( acpt ); - free ( next ); - free ( border ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_new->data = calloc ( _mitkIpPicElements (pic_new), pic_new->bpe / 8 ); - if ( pic_new->data == NULL ) - { - free ( off_vekt ); - free ( acpt ); - free ( next ); - free ( border ); - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialize variables and vectors */ - - size[0] = 1; - for ( i = 1; i < pic_old->dim; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - size[i] = 0; - - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - { - beg[i] = ( i < pic_old->n[i] ) ? -1 : 0 ; - end[i] = ( i < pic_old->n[i] ) ? 2 : 1 ; - } - - acpt_len = 0; - next_len = 0; - border_len = 0; - - /* calculate offset vector */ - - offset_v = 0; - for ( ind[7] = beg[7]; ind[7] < end[7]; ind[7]++ ) - { - off[7] = size[7] * ind[7]; - for ( ind[6] = beg[6]; ind[6] < end[6]; ind[6]++ ) - { - off[6] = size[6] * ind[6] + off[7]; - for ( ind[5] = beg[5]; ind[5] < end[5]; ind[5]++ ) - { - off[5] = size[5] * ind[5] + off[6]; - for ( ind[4] = beg[4]; ind[4] < end[4]; ind[4]++ ) - { - off[4] = size[4] * ind[4] + off[5]; - for ( ind[3] = beg[3]; ind[3] < end[3]; ind[3]++ ) - { - off[3] = size[3] * ind[3] + off[4]; - for ( ind[2] = beg[2]; ind[2] < end[2]; ind[2]++ ) - { - off[2] = size[2] * ind[2] + off[3]; - for ( ind[1] = beg[1]; ind[1] < end[1]; ind[1]++ ) - { - off[1] = size[1] * ind[1] + off[2]; - off[0] = off[1] + beg[0]; - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) - { - off_vekt[offset_v] = off[0]; - off[0]++; - offset_v++; - } - } - } - } - } - } - } - } - - /* calculate parameters of seed region */ - - size_seed = 1; - - for ( i = 0; i < dim_seed; i++ ) - { - beg[i] = beg_seed[i]; - end[i] = end_seed[i]; - size_seed = size_seed * ( end[i] - beg[i] ); - } - - for ( i = dim_seed; i < _mitkIpPicNDIM; i++ ) - { - beg[i] = 0; - end[i] = 1; - } - - mitkIpPicFORALL_6 ( STAT, pic_old, pic_new, mean, std_win, size_seed, beg, end ); - - /* find accepted pixels in seed region */ - - mitkIpPicFORALL_5 ( ACPT, pic_old, pic_new, acpt, acpt_len, region_label, std_win ); - - /* region growing */ - - mitkIpPicFORALL_6 ( REGGROW, pic_old, pic_new, acpt, acpt_len, - border, border_len, std_win ); - - /* free memory */ - - free ( off_vekt ); - free ( acpt ); - free ( next ); - /* free ( help );*/ - free ( border ); - - /* Copy Tags */ - - strncpy( pic_new->info->version, pic_old->info->version, _mitkIpPicTAGLEN ); - pic_new->info->tags_head = _mitkIpPicCloneTags( pic_old->info->tags_head ); - pic_new->info->write_protect = pic_old->info->write_protect; - - return ( pic_new ); - -} - -#endif - diff --git a/Utilities/IpFunc/Roberts.c b/Utilities/IpFunc/Roberts.c deleted file mode 100644 index b952142c15..0000000000 --- a/Utilities/IpFunc/Roberts.c +++ /dev/null @@ -1,256 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs an edge detection by the Roberts gradient - */ - -/** @brief performs an edge detection by the Roberts gradient - * - * This gradient uses a 2x2 or 2x2x2 mask and calculates the maximum - * of the difference of all diagonal elements - * - * @param pic_old pointer to original image - * @param dim_mask dimension of mask (2 or 3) - * @param border tells how the edge is handled - * @arg @c mitkIpFuncBorderOld : keep greyvalues - * @arg @c mitkIpFuncBorderZero : set greyvalues to zero - * - * @return pointer to transformed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncRoberts ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - -#define ROBERTS( type, pic, msize, n, off, size ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t end; /* */ \ - mitkIpUInt4_t off_imag; /* offset of pixels */ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - type help, help2; /* used to calculate new greyvalue */ \ - \ - end = msize / 2; \ - msize = msize - 1; \ - for ( ind[7] = 0; ind[7] < n[7]; ind[7]++ ) \ - for ( ind[6] = 0; ind[6] < n[6]; ind[6]++ ) \ - for ( ind[5] = 0; ind[5] < n[5]; ind[5]++ ) \ - for ( ind[4] = 0; ind[4] < n[4]; ind[4]++ ) \ - for ( ind[3] = 0; ind[3] < n[3]; ind[3]++ ) \ - for ( ind[2] = 0; ind[2] < n[2]; ind[2]++ ) \ - for ( ind[1] = 0; ind[1] < n[1]; ind[1]++ ) \ - for ( ind[0] = 0; ind[0] < n[0]; ind[0]++ ) \ - { \ - /* offset of actual pixel */ \ - \ - off_imag = 0; \ - for ( i = 0; i < pic->dim; i++ ) \ - off_imag = off_imag + ind[i] * size[i]; \ - \ - /* find out maximum of all diagonal differences */ \ - \ - help = 0; \ - for ( i = 0; i < end; i++ ) \ - { \ - help2 = ( type ) fabs ( ( mitkIpFloat8_t ) ( \ - ((type *)pic->data)[off_imag+off[i]] - \ - ((type *)pic->data)[off_imag+off[msize-i]])); \ - help = ( help > help2 ) ? help : help2; \ - } \ - (( type * )pic_new->data )[off_imag] = help; \ - } \ - \ -} \ - -/* --------------------------------------------------------------------- */ -/* -** function mitkIpFuncRoberts -*/ -/* --------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncRoberts ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to new image structure */ - mitkIpInt4_t *off_vekt; /* offsets for the image pixels that*/ - /* are needed for the operation */ - mitkIpInt4_t offset; /* used to calculate off_vekt */ - mitkIpUInt4_t off_mask; /* offset of mask elements */ - mitkIpUInt4_t mask_size; /* number of elements in mask */ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - mitkIpUInt4_t n[_mitkIpPicNDIM]; /* size of each dimension */ - mitkIpUInt4_t i; /* loop index */ - - /* check data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( ( pic_old->dim < dim_mask ) || ( dim_mask < 1 ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of vectors */ - - for ( i = 0; i < dim_mask; i++ ) - n[i] = 2; - - for ( i = dim_mask; i < _mitkIpPicNDIM; i++ ) - n[i] = 1; - - size[0] = 1; - ind[0] = 0; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - { - ind[i] = 0; - size[i] = size[i-1] * pic_old->n[i-1]; - } - - /* calculate offset vector */ - - mask_size = ( mitkIpUInt4_t ) pow ( 2., ( mitkIpFloat8_t ) dim_mask ); - off_vekt = calloc ( mask_size, sizeof( mitkIpInt4_t ) ); - off_mask = 0; - if ( off_vekt == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - switch ( dim_mask ) - { - case 8: - for ( ind[7] = 0; ind[7] < n[7]; ind[7]++ ) - case 7: - for ( ind[6] = 0; ind[6] < n[6]; ind[6]++ ) - case 6: - for ( ind[5] = 0; ind[5] < n[5]; ind[5]++ ) - case 5: - for ( ind[4] = 0; ind[4] < n[4]; ind[4]++ ) - case 4: - for ( ind[3] = 0; ind[3] < n[3]; ind[3]++ ) - case 3: - for ( ind[2] = 0; ind[2] < n[2]; ind[2]++ ) - case 2: - for ( ind[1] = 0; ind[1] < n[1]; ind[1]++ ) - case 1: - for ( ind[0] = 0; ind[0] < n[0]; ind[0]++ ) - { - offset = 0; - for ( i = 0; i < dim_mask; i++ ) - offset = offset + ind[i] * size[i]; - off_vekt[off_mask] = offset; - off_mask++; - } - } - - /* allocate new image */ - - if ( border == mitkIpFuncBorderOld ) - pic_new = mitkIpPicClone ( pic_old ); - else if ( border == mitkIpFuncBorderZero ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - } - else - { - free ( off_vekt ); - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - free ( off_vekt ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new->data == NULL ) - { - free ( off_vekt ); - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro */ - - for ( i = 0; i < pic_old->dim; i++ ) - n[i] = pic_old->n[i] - 1; - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 1; - - mitkIpPicFORALL_4 ( ROBERTS, pic_old, mask_size, n, off_vekt, size ); - - free ( off_vekt ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} - -#endif - diff --git a/Utilities/IpFunc/Rotate.c b/Utilities/IpFunc/Rotate.c deleted file mode 100644 index 469947f9d1..0000000000 --- a/Utilities/IpFunc/Rotate.c +++ /dev/null @@ -1,298 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * Rotates image by a given angle - */ - -/** @brief Rotates image by a given angle. - * - * The angle has to be a multiple of 90 degrees. - * - * @param pic pointer to picture - * @param pic_old pointer to picture old, which is not used in this version - * @param grad angle array for every axes - * @param order order of the axes - * parameter example: grad: 90 270 90 - * order: 3 1 2 - * means: first step: the third axis is rotated with 90 degrees - * second step: the first axis is rotated with 90 degrees - * third step: the second axis is rotated with 270 degrees - * - * @return image - * - * @author Judith Dilo @date 5.5.1990 - * @author Ulrike Guennel @date 18.3.1994 - * - * - * This a total rewritten version of 'ipRot' written by Judith Dilo - * 7.6.1990 by J.D. (small improvements) - * 18.3.1994 by U.G. (new pic format) - * $Log$ - * Revision 1.3 2003/08/21 08:20:06 tobiask - * Removed warnings. - * - * Revision 1.2 2000/05/24 15:29:43 tobiask - * Changed the installation paths of the package. - * - * Revision 1.4 2000/05/04 12:52:11 ivo - * inserted BSD style license - * - * Revision 1.3 2000/03/06 17:02:45 ivo - * ipFunc now with doxygen documentation. - * - * Revision 1.2 2000/02/18 14:58:06 ivo - * Tags are now copied into newly allocated images. - * Bugs fixed in mitkIpFuncFrame, mitkIpFuncRegGrow, _mitkIpFuncBorderX and mitkIpFuncHitMiss. - * - * Revision 1.1.1.1 1998/07/16 12:04:49 antje - * initial import - * - * Revision 1.1 1995/03/07 16:42:15 uli - * Initial revision - */ - -/* -** ipFunc includefiles -*/ -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncRotate( mitkIpPicDescriptor *pic, - mitkIpPicDescriptor *pic_old, - int *grad, int *order ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncRotate\tGerman Cancer Research Center (DKFZ) $Revision$ "__DATE__ }; -#endif - - -/* -** private macros -*/ -#define COEFF_DEF( x,i ) (( (x) > (0)) ? ((x) - *p_index[i]) : (*p_index[i]) ) - - -/* -** the action starts here -*/ -mitkIpPicDescriptor *mitkIpFuncRotate( mitkIpPicDescriptor *pic, - mitkIpPicDescriptor *pic_old, - int *grad, int *order ) - -{ - mitkIpPicDescriptor *pic_return; - mitkIpUInt4_t *p_index[_mitkIpPicNDIM]; - mitkIpUInt4_t index[_mitkIpPicNDIM]; - mitkIpUInt4_t coeff_sum[_mitkIpPicNDIM]; - mitkIpUInt1_t coefficient[_mitkIpPicNDIM]; - mitkIpUInt4_t r_size[_mitkIpPicNDIM]; - mitkIpUInt4_t r_offset,i; - int order_alloc = 0; - - /* - ** - */ - if( !pic ) return( NULL ); - if( pic->dim < 2 || pic->dim > _mitkIpPicNDIM ) return( NULL ); - - /* take over image header structure and allocate memory */ - mitkIpPicFree( pic_old ); - pic_return = mitkIpPicCopyHeader( pic, NULL ); - if( !pic_return ) return( NULL ); - pic_return->data = malloc( _mitkIpPicSize(pic_return) ); - if( !pic_return->data ) - { - mitkIpPicFree( pic_return ); - return( NULL ); - } - - - /* - ** init pic_return->n, pointer to index and calculated_coeff - ** init coefficient matrix, r_size - */ - for( i = 0; i< _mitkIpPicNDIM; i++ ) - { - pic_return->n[i] = pic->n[i]; - p_index[i] = &index[i]; - coeff_sum[i] = 0; - coefficient[i] = 0; - r_size[i] = 0; - } - - /* - ** init the order array if NULL - */ - if( !order ) - { - order = (int *) malloc( pic->dim * sizeof( int ) ); - if( !order ) - { - mitkIpPicFree( pic_return ); - return( NULL ); - } - order_alloc = 1; - for( i=0; i<_mitkIpPicNDIM; i++ ) - order[i] = i+1; - } - else - { - /* - ** test if order correct - */ - int tt[_mitkIpPicNDIM]; - for( i=0; i<_mitkIpPicNDIM; i++ ) tt[i] = 0; - for( i=0; i< pic->dim; i++ ) - { - if( order[i] > 0 && order[i]<= (mitkIpInt4_t) pic->dim ) - tt[ order[i]-1 ]++; - else - i = _mitkIpPicNDIM + 1; - } - if( i == pic->dim ) - { - for( i=0; i< pic->dim; i++ ) - { - if( tt[i] != 1 ) - i = _mitkIpPicNDIM + 1; - } - } - if( i > _mitkIpPicNDIM ) - { - mitkIpPicFree( pic_return ); - return( NULL ); - } - } - - /* - ** fill of the coefficient array and change the p_index array - */ - for( i = 0; i<pic->dim; i++ ) - { - int d1,d2; - mitkIpUInt4_t *tmp; - - d1 = order [i]-1; - d2 = (d1+1 >= (mitkIpInt4_t) pic->dim ) ? ( 0 ) : ( d1+1 ); - - switch( grad[d1] ) - { - case 0: - break; - case 90: - tmp = p_index[d2]; - p_index[d2] = p_index[d1]; - p_index[d1] = tmp; - - coefficient[ p_index[d2] - index ] = - (coefficient[ p_index[d2] - index ] == 1 ) ? 0 : 1; - break; - case 180: - coefficient[ p_index[d1] - index ] = - (coefficient[ p_index[d1] - index ] == 1 ) ? 0 : 1; - coefficient[ p_index[d2] - index ] = - (coefficient[ p_index[d2] - index ] == 1 ) ? 0 : 1; - break; - case 270: - tmp = p_index[d2]; - p_index[d2] = p_index[d1]; - p_index[d1] = tmp; - - coefficient[ p_index[d1] - index ] = - (coefficient[ p_index[d1] - index ] == 1 ) ? 0 : 1; - break; - default: - { - if( order_alloc == 1 ) - free( (void *) order ); - mitkIpPicFree( pic_return ); - return( NULL ); - break; - } - } - } - - - /* - ** calculate coefficient, and pic_return->n[i] - */ - for( i=0; i<pic->dim; i++ ) - { - coeff_sum[ i ] = (pic->n[p_index[i] - index]-1) - * coefficient[ p_index[i] - index]; - pic_return->n[i] = pic->n[p_index[i] - index]; - } - - /* - ** calc multiplier for coefficients - */ - r_size[0] = 1; - for( i=1; i<pic->dim; i++ ) - { - r_size[i] = r_size[i-1] * pic_return->n[i-1]; - } - - - /* - ** Makro for all for-loops and switches for all dimensions (1-8) - ** FOR ALL: dimensions, indizes, data types - */ - mitkIpPicFORALL_4( mitkIpFuncFORALL, pic, pic_return, index, r_offset, - for( r_offset = COEFF_DEF( coeff_sum[0],0) , i=1; i<pic->dim; i++ ) - r_offset += COEFF_DEF( coeff_sum[i],i ) * r_size[i]; - ) - - /* - ** free allocated memory - */ - if( order_alloc == 1 ) - free( (void *) order ); - - /* Copy Tags */ - - strncpy( pic_return->info->version, pic->info->version, _mitkIpPicTAGLEN ); - pic_return->info->tags_head = _mitkIpPicCloneTags( pic->info->tags_head ); - pic_return->info->write_protect = pic->info->write_protect; - - return( pic_return ); -} -#endif diff --git a/Utilities/IpFunc/SDev.c b/Utilities/IpFunc/SDev.c deleted file mode 100644 index 2ed9ce8d3f..0000000000 --- a/Utilities/IpFunc/SDev.c +++ /dev/null @@ -1,81 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the standard deviation of all greyvalues - * in an image - */ - -/** this function calculates the standard deviation of all greyvalues - * in an image - * - * @param pic pointer to the image - * - * @return standard deviation - * - * USES - * function mitkIpFuncVar: to calculate the variance of an image - * - * AUTHOR - */ - -/* include-files */ - -#include "mitkIpFuncP.h" - - mitkIpFloat8_t mitkIpFuncSDev ( mitkIpPicDescriptor *pic ); - -#ifndef DOXYGEN_IGNORE - -mitkIpFloat8_t mitkIpFuncSDev ( mitkIpPicDescriptor *pic ) -{ - - mitkIpFloat8_t s_der; /* standard deviation */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - s_der = sqrt ( mitkIpFuncVar ( pic ) ); - - return( s_der ); -} -#endif - diff --git a/Utilities/IpFunc/SDevC.c b/Utilities/IpFunc/SDevC.c deleted file mode 100644 index df9982879b..0000000000 --- a/Utilities/IpFunc/SDevC.c +++ /dev/null @@ -1,99 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the standrad deviation of all grey- - * values included by a circle. This circle is described by - * its center and radius - */ - -/** this function calculates the standrad deviation of all grey- - * values included by a circle. This circle is described by - * its center and radius - * - * @param pic_old pointer to image structure - * @param center pointer to an array with the coordinates of - * the center of the circle - * @param radius radius of the circle - * - * @return standard deviation of all pixels included by a - * circle - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncSDevC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - -#include "mitkIpFuncP.h" - - -/* -** mitkIpFuncSDevC -*/ -mitkIpFloat8_t mitkIpFuncSDevC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ) -{ - mitkIpFloat8_t s_dev; - mitkIpFloat8_t var; - - var = mitkIpFuncVarC ( pic_old, center, radius ); - - if ( var < 0 ) return ( mitkIpFuncERROR ); - - s_dev = sqrt ( var ); - - return ( s_dev ); -} -#endif diff --git a/Utilities/IpFunc/SDevR.c b/Utilities/IpFunc/SDevR.c deleted file mode 100644 index 9ec28db369..0000000000 --- a/Utilities/IpFunc/SDevR.c +++ /dev/null @@ -1,91 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the standard deviation of all greyvalues included by a rectangle - */ - -/** calculates the standard deviation of all greyvalues included by a rectangle - * - * The rectangle is described by a vector with the coordinates of the - * upper left corner and a vector of its length in each direction - * - * @param pic_old pointer to original image - * @param begin vector with the beginning coordinates of the window - * @param length vector with the length of the window in each direction - * - * @return standard deviation in window - * - * AUTHOR & DATE - */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncSDevR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -mitkIpFloat8_t mitkIpFuncSDevR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ) -{ - mitkIpFloat8_t sder; /* standard deviation */ - - mitkIpPicDescriptor *pic_help; - - pic_help = mitkIpFuncWindow ( pic_old, begin, length ); - - sder = mitkIpFuncSDev ( pic_help ); - - mitkIpPicFree ( pic_help ); - - return ( sder ); -} - -#endif - diff --git a/Utilities/IpFunc/SDevROI.c b/Utilities/IpFunc/SDevROI.c deleted file mode 100644 index fd9e337278..0000000000 --- a/Utilities/IpFunc/SDevROI.c +++ /dev/null @@ -1,105 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the standard deviation of all pixels - * inside of a polygon - */ - -/** @brief calculates the standard deviation of all pixels - * inside of a polygon - * - * The polygon is described by a sequence of points - * - * @param pic_old pointer to original image - * @param pol_x vector with the x-coordinates of the points which form - * form the roi - * @param pol_y vector with the y-coordinates of the points which form - * form the roi - * @param no_pts number of points used to describe ROI - * - * REMARKS - * this function could just be used for 2D images - * - * @return standard deviation of all greyvalues in ROI - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncSDevROI ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) ; - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncSDevROI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - - -/* -** mitkIpFuncSDevROI -*/ - -mitkIpFloat8_t mitkIpFuncSDevROI ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) -{ - mitkIpFloat8_t var; /* variance of greyvalues in ROI */ - mitkIpFloat8_t s_dev; /* standard dev.of greyvalues in ROI*/ - - var = mitkIpFuncVarROI ( pic_old, pol_x, pol_y, no_pts ); - - s_dev = sqrt ( var ); - - return ( s_dev ); - -} - -#endif - diff --git a/Utilities/IpFunc/ScBl.c b/Utilities/IpFunc/ScBl.c deleted file mode 100644 index 067270fae3..0000000000 --- a/Utilities/IpFunc/ScBl.c +++ /dev/null @@ -1,392 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* -* internal only. used by Scale.c -*/ - -/*@file - * this function scales the first image to the size of the second image - * using bilinear interpolation - */ - -/* @brief scales the first image to the size of the second image - * using bilinear interpolation - * - * @param pic_old pointer to the image that should be scaled - * @param pic_new pointer to the scaled image ( contains the information - * for the scaling in th header ) - * !!! All Header Information necessary when calling function !!! - * - * @return pointer to the scaled image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *_mitkIpFuncScBL( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new ) ; - -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define SCBL4ALL( type, pic_old, pic_new, size, scale, n, shift, step, RND ) \ -{ \ - mitkIpFloat8_t factor[_mitkIpPicNDIM]; /* */\ - mitkIpFloat8_t help1[_mitkIpPicNDIM]; /* */\ - size_t help2[_mitkIpPicNDIM]; /* */\ - size_t offset[_mitkIpPicNDIM]; /* offset vector */\ - mitkIpFloat8_t weights[_mitkIpPicNDIM*2];/* */\ - size_t i; /* loop index */\ - size_t off_new; /* offset of scaled image */\ - size_t off_weights; /* offset of orig. image */\ - size_t ind_o[_mitkIpPicNDIM]; /* loop index (outer loops) */\ - size_t ind_i[_mitkIpPicNDIM]; /* loop index (inner loops) */\ - size_t n_i[_mitkIpPicNDIM]; /* loop index (inner loops) */\ - size_t pic_elements; /* number of elements of pic_old */ \ - type help; \ - /* initialize vectors */\ - \ - for ( i = 0; i < _mitkIpPicNDIM; i++ ) \ - { \ - ind_o[i] = 0; \ - ind_i[i] = 0; \ - factor[i] = 1.; \ - weights[i] = 1.; \ - weights[15-i] = 1.; \ - help2[i] = 0; \ - } \ - \ - for ( i = 0; i < pic_new->dim; i++ ) \ - n_i[i] = 2; \ - \ - for ( i = pic_new->dim; i < _mitkIpPicNDIM; i++ ) \ - n_i[i] = 1; \ - \ - pic_elements = _mitkIpPicElements(pic_old)*step; \ - off_new = 0; \ - switch ( pic_new->dim ) \ - { \ - default: printf ( " only 8 dimensions supported \n" ); \ - case 8: \ - for ( ind_o[7] = 0; ind_o[7] < n[7]; ind_o[7]++ ) \ - { \ - help1[7] = ( mitkIpFloat8_t ) ind_o[7] * scale[7]; \ - weights[7] = 1. - (help1 [7] - ( mitkIpFloat8_t ) \ - (( size_t ) help1[7] )); \ - weights[15] = 1. - weights[7]; \ - help2[7] = ( size_t ) help1[7] * size[7]; \ - case 7: \ - for ( ind_o[6] = 0; ind_o[6] < n[6]; ind_o[6]++ ) \ - { \ - help1[6] = ( mitkIpFloat8_t ) ind_o[6] * scale[6]; \ - weights[6] = 1. - (help1 [6] - ( mitkIpFloat8_t ) \ - (( size_t ) help1[6] )); \ - weights[14] = 1. - weights[6]; \ - help2[6] = ( size_t ) help1[6] * size[6]; \ - case 6: \ - for ( ind_o[5] = 0; ind_o[5] < n[5]; ind_o[5]++ ) \ - { \ - help1[5] = ( mitkIpFloat8_t ) ind_o[5] * scale[5]; \ - weights[5] = 1. - (help1 [5] - ( mitkIpFloat8_t ) \ - (( size_t ) help1[5] )); \ - weights[13] = 1. - weights[5]; \ - help2[5] = ( size_t ) help1[5] * size[5]; \ - case 5: \ - for ( ind_o[4] = 0; ind_o[4] < n[4]; ind_o[4]++ ) \ - { \ - help1[4] = ( mitkIpFloat8_t ) ind_o[4] * scale[4]; \ - weights[4] = 1. - (help1 [4] - ( mitkIpFloat8_t ) \ - (( size_t ) help1[4] )); \ - weights[12] = 1. - weights[4]; \ - help2[4] = ( size_t ) help1[4] * size[4]; \ - case 4: \ - for ( ind_o[3] = 0; ind_o[3] < n[3]; ind_o[3]++ ) \ - { \ - help1[3] = ( mitkIpFloat8_t ) ind_o[3] * scale[3]; \ - weights[3] = 1. - (help1 [3] - ( mitkIpFloat8_t ) \ - (( size_t ) help1[3] )); \ - weights[11] = 1. - weights[3]; \ - help2[3] = ( size_t ) help1[3] * size[3]; \ - case 3: \ - for ( ind_o[2] = 0; ind_o[2] < n[2]; ind_o[2]++ ) \ - { \ - help1[2] = ( mitkIpFloat8_t ) ind_o[2] * scale[2]; \ - weights[2] = 1. - (help1 [2] - ( mitkIpFloat8_t ) \ - (( size_t ) help1[2] )); \ - weights[10] = 1. - weights[2]; \ - help2[2] = ( size_t ) help1[2] * size[2]; \ - case 2: \ - for ( ind_o[1] = 0; ind_o[1] < n[1]; ind_o[1]++ ) \ - { \ - help1[1] = ( mitkIpFloat8_t ) ind_o[1] * scale[1]; \ - weights[1] = 1. - (help1 [1] - ( mitkIpFloat8_t ) \ - (( size_t ) help1[1] )); \ - weights[9] = 1. - weights[1]; \ - help2[1] = ( size_t ) help1[1] * size[1]; \ - case 1: \ - for ( ind_o[0] = 0; ind_o[0] < n[0]; ind_o[0]++ ) \ - { \ - help1[0] = ( mitkIpFloat8_t ) ind_o[0] * scale[0]; \ - weights[0] = 1. - (help1 [0] - ( mitkIpFloat8_t ) \ - (( size_t ) help1[0] )); \ - weights[8] = 1. - weights[0]; \ - help2[0] = ( size_t ) help1[0] * size[0]; \ - \ - help = ( type ) 0; \ - \ - for ( ind_i[7] = 0; ind_i[7] < n_i[7]; ind_i[7]++)\ - { \ - factor[7] = weights[ind_i[7]*_mitkIpPicNDIM+7]; \ - offset[7] = ( size_t )help2[7] + \ - ind_i[7] * size[7]; \ - \ - for ( ind_i[6] = 0; ind_i[6] < n_i[6]; \ - ind_i[6]++ ) \ - { \ - factor[6] = weights[ind_i[6]*_mitkIpPicNDIM+6] * \ - factor[7]; \ - offset[6] = ( size_t )help2[6] + \ - ind_i[6] * size[6] + offset[7]; \ - \ - for ( ind_i[5] = 0; ind_i[5] < n_i[5]; \ - ind_i[5]++ ) \ - { \ - factor[5] = weights[ind_i[5]*_mitkIpPicNDIM+5] *\ - factor[6]; \ - offset[5] = ( size_t )help2[5] + \ - ind_i[5] * size[5] + offset[6]; \ - \ - for ( ind_i[4] = 0; ind_i[4] < n_i[4]; \ - ind_i[4]++ ) \ - { \ - factor[4] = weights[ind_i[4]*_mitkIpPicNDIM+4]*\ - factor[5]; \ - offset[4] = ( size_t )help2[4] + \ - ind_i[4] * size[4] + offset[5];\ - \ - for ( ind_i[3] = 0; ind_i[3] < n_i[3]; \ - ind_i[3]++ ) \ - { \ - factor[3] = weights[ind_i[3]*_mitkIpPicNDIM+3]*\ - factor[4]; \ - offset[3] = ( size_t )help2[3] + \ - ind_i[3] * size[3] + offset[4];\ - \ - for ( ind_i[2] = 0; ind_i[2] < n_i[2]; \ - ind_i[2]++ ) \ - { \ - factor[2] = weights[ind_i[2]*_mitkIpPicNDIM + 2]*\ - factor[3]; \ - offset[2] = ( size_t )help2[2] + \ - ind_i[2] * size[2] + \ - offset[3]; \ - \ - for ( ind_i[1] = 0; ind_i[1] < n_i[1];\ - ind_i[1]++ ) \ - { \ - factor[1] = weights[ind_i[1]*_mitkIpPicNDIM+1] *\ - factor[2]; \ - offset[1] = ( size_t )help2[1] + \ - ind_i[1] * size[1] + \ - offset[2]; \ - \ - for ( ind_i[0] = 0; ind_i[0] < n_i[0];\ - ind_i[0]++ ) \ - { \ - offset[0] = ( size_t )(help2[0]+\ - ind_i[0] * size[0] + \ - offset[1])*(( size_t )step)+shift;\ - if(pic_elements<=offset[0]) continue; \ - factor[0] = weights[ind_i[0]*_mitkIpPicNDIM] * \ - factor[1]; \ - help = help + factor[0] * \ - ((( type * ) pic_old->data )\ - [offset[0]]+RND); \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - off_new = 0; \ - for ( i = 0; i < pic_old->dim; i++ ) \ - off_new = off_new + ind_o[i] * sizeo[i]; \ - off_new = off_new*step+shift; \ - (( type * ) pic_new->data )[off_new] = help; \ - off_weights = 0; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} -#define SCBL( type, pic_old, pic_new, size, scale, n ) \ - SCBL4ALL( type, pic_old, pic_new, size, scale, n, 0, 1, 0 ) -#define SCBLCOLOR( type, pic_old, pic_new, size, scale, n ) \ - SCBL4ALL( type, pic_old, pic_new, size, scale, n, 0, 3, 0 ) \ - SCBL4ALL( type, pic_old, pic_new, size, scale, n, 1, 3, 0 ) \ - SCBL4ALL( type, pic_old, pic_new, size, scale, n, 2, 3, 0 ) - -#define SCBL_INT( type, pic_old, pic_new, size, scale, n ) \ - SCBL4ALL( type, pic_old, pic_new, size, scale, n, 0, 1, 0.5 ) -#define SCBLCOLOR_INT( type, pic_old, pic_new, size, scale, n ) \ - SCBL4ALL( type, pic_old, pic_new, size, scale, n, 0, 3, 0.5 ) \ - SCBL4ALL( type, pic_old, pic_new, size, scale, n, 1, 3, 0.5 ) \ - SCBL4ALL( type, pic_old, pic_new, size, scale, n, 2, 3, 0.5 ) - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *_mitkIpFuncScBL( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new ) -{ - - mitkIpUInt4_t i; /* loopindex */ - mitkIpUInt4_t n[_mitkIpPicNDIM]; /* no. of pixels in each dimension*/ - mitkIpFloat8_t scale[_mitkIpPicNDIM]; /* scaling factors */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; - mitkIpUInt4_t sizeo[_mitkIpPicNDIM]; - char is_color=0; - - - /* check whether data are correct */ - - if(pic_old->bpe==24) - { - is_color=1; - pic_old->bpe=pic_new->bpe=8; - } - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_new ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim != pic_new->dim ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of vectors */ - - for ( i = 0; i < pic_new->dim; i++ ) -// if(pic_new->n[i]>=pic_old->n[i]) - n[i] = pic_new->n[i];//ivo - 2; -// else -// n[i] = pic_new->n[i]-1; - - for ( i = pic_new->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 0; - - sizeo[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - sizeo[i] = sizeo[i-1] * pic_new->n[i-1]; - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - - /* calculate scaling factors */ - - for ( i = 0; i < pic_old->dim; i++ ) - scale[i] = ( mitkIpFloat8_t ) ( pic_old->n[i] - 1 ) / - ( mitkIpFloat8_t ) ( pic_new->n[i] - 1 ); - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - scale[i] = 1.; - - /* add header information for pic_new and allocate memory */ - - pic_new->bpe = pic_old->bpe*(is_color!=0?3:1); - pic_new->type = pic_old->type; - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to scale an image ( for all data types )s) */ - - if(pic_old->type==mitkIpPicFloat) - { - if(is_color==0) - { - mitkIpPicFORALL_4 ( SCBL, pic_old, pic_new, size, scale, n ); - } - else - { - mitkIpPicFORALL_4 ( SCBLCOLOR, pic_old, pic_new, size, scale, n ); - } - } - else - { - if(is_color==0) - { - mitkIpPicFORALL_4 ( SCBL_INT, pic_old, pic_new, size, scale, n ); - } - else - { - mitkIpPicFORALL_4 ( SCBLCOLOR_INT, pic_old, pic_new, size, scale, n ); - } - } - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/ScFact.c b/Utilities/IpFunc/ScFact.c deleted file mode 100644 index ddc1d85501..0000000000 --- a/Utilities/IpFunc/ScFact.c +++ /dev/null @@ -1,115 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function scales an image with a factor for all directions - */ - -/** this function scales an image with a factor for all directions - * - * @param pic_old pointer to the image - * @param sc_fact vector that contains the scaling factors - * @param sc_kind parameter for the kind of interpolation - * @arg @c mitkIpFuncScaleNN: next neighbour interpolation - * qarg @c mitkIpFuncScaleBl: bilinear interpolation - * - * @return pointer to the scaled image - * - * AUTHOR & DATE - */ - -/* include-files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncScFact ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t factor, - mitkIpFuncFlagI_t sc_kind ) ; - -#ifndef DOXYGEN_IGNORE - -mitkIpPicDescriptor *mitkIpFuncScFact ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t factor, - mitkIpFuncFlagI_t sc_kind ) -{ - - mitkIpUInt4_t i; /* loop index */ - mitkIpPicDescriptor *pic_new; /* pointer to scaled image */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* allocate pic_new */ - - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* copy scaling information to header of pic_new */ - - pic_new->dim = pic_old->dim; - for ( i = 0; i < pic_old->dim; i++ ) - pic_new->n[i] = pic_old->n[i] * factor; - - /* call scaling routines */ - - if ( sc_kind == mitkIpFuncScaleNN ) - pic_new = _mitkIpFuncScNN ( pic_old, pic_new ); - else if ( sc_kind == mitkIpFuncScaleBl ) - pic_new = _mitkIpFuncScBL ( pic_old, pic_new ); - else - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/ScNN.c b/Utilities/IpFunc/ScNN.c deleted file mode 100644 index 243ddb4af3..0000000000 --- a/Utilities/IpFunc/ScNN.c +++ /dev/null @@ -1,222 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* -* internal only. used by Scale.c -*/ -/*@file - * this function scales the first image to the size of the second image - * using next-neighbour interpolation - */ - -/* @brief scales the first image to the size of the second image - * using next-neighbour interpolation - * - * @param pic_old pointer to the image that should be scaled - * @param pic_new pointer to the scaled image ( contains the information - * for the scaling in th header ) - * !!! Header must contain all information when calling !!! - * !!! function !!! - * - * @return pointer to the scaled image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *_mitkIpFuncScNN( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new ) ; - -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define SCNN4ALL( type, pic_old, pic_new, size, weights, n, shift, step )\ -{ \ - size_t ind[_mitkIpPicNDIM]; /* loop index vector */\ - size_t offset[_mitkIpPicNDIM]; /* offset vector */\ - size_t i; /* loop index */\ - size_t off_new; /* offset of scaled image */\ - size_t off_orig; /* offset of orig. image */\ - \ - \ - /* calculate offsets for scaling an image */ \ - \ - off_new = 0; \ - for ( ind[7] = 0; ind[7] < n[7]; ind[7]++ ) \ - { \ - offset[7] = ( mitkIpUInt4_t ) ( ( mitkIpFloat8_t ) ind[7] * \ - weights[7] + 0.5 ) * size[7]; \ - for ( ind[6] = 0; ind[6] < n[6]; ind[6]++ ) \ - { \ - offset[6] = ( mitkIpUInt4_t ) ( ( mitkIpFloat8_t ) ind[6] * \ - weights[6] + 0.5 ) * size[6]; \ - for ( ind[5] = 0; ind[5] < n[5]; ind[5]++ ) \ - { \ - offset[5] = ( mitkIpUInt4_t ) ( ( mitkIpFloat8_t ) ind[5] * \ - weights[5] + 0.5 ) * size[5]; \ - for ( ind[4] = 0; ind[4] < n[4]; ind[4]++ ) \ - { \ - offset[4] = ( mitkIpUInt4_t ) ( ( mitkIpFloat8_t ) ind[4] * \ - weights[4] + 0.5 ) * size[4]; \ - for ( ind[3] = 0; ind[3] < n[3]; ind[3]++ ) \ - { \ - offset[3] = ( mitkIpUInt4_t ) ( ( mitkIpFloat8_t ) ind[3]*\ - weights[3] + 0.5 ) * size[3]; \ - for ( ind[2] = 0; ind[2] < n[2]; ind[2]++ ) \ - { \ - offset[2] = ( mitkIpUInt4_t ) \ - ( ( mitkIpFloat8_t ) ind[2] * \ - weights[2] + 0.5 ) * size[2]; \ - for ( ind[1] = 0; ind[1] < n[1]; ind[1]++ ) \ - { \ - offset[1] = ( mitkIpUInt4_t ) \ - ( ( mitkIpFloat8_t ) ind[1] * \ - weights[1]+0.5 ) * size[1]; \ - for ( ind[0] = 0; ind[0] < n[0]; ind[0]++)\ - { \ - offset[0] = ( mitkIpUInt4_t ) \ - ( ( mitkIpFloat8_t ) ind[0] * \ - weights[0] + 0.5)*size[0];\ - off_orig = 0; \ - for ( i = 0; i < pic_old->dim; i++ ) \ - off_orig = off_orig + offset[i]; \ - \ - (( type * )pic_new->data)[off_new+shift]=\ - (( type * )pic_old->data)[off_orig+shift];\ - \ - off_new+=step; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - -#define SCNN( type, pic_old, pic_new, size, weights, n ) \ - SCNN4ALL( type, pic_old, pic_new, size, weights, n, 0, 1 ) -#define SCNNCOLOR( type, pic_old, pic_new, size, weights, n ) \ - SCNN4ALL( type, pic_old, pic_new, size, weights, n, 0, 3 ) \ - SCNN4ALL( type, pic_old, pic_new, size, weights, n, 1, 3 ) \ - SCNN4ALL( type, pic_old, pic_new, size, weights, n, 2, 3 ) -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *_mitkIpFuncScNN( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new ) -{ - - mitkIpUInt4_t i; /* loopindex */ - mitkIpUInt4_t n[_mitkIpPicNDIM]; /* no. of pixels in each dimension*/ - mitkIpFloat8_t weights[_mitkIpPicNDIM]; - mitkIpUInt4_t size[_mitkIpPicNDIM]; - char is_color=0; - - - /* check whether data are correct */ - - if(pic_old->bpe==24) - { - is_color=1; - pic_old->bpe=pic_new->bpe=8; - } - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_new ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim != pic_new->dim ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of vectors */ - - for ( i = 0; i < pic_new->dim; i++ ) - n[i] = pic_new->n[i]; - - for ( i = pic_new->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 1; - - size[0] = 1*(is_color!=0?3:1); - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - - for ( i = 0; i < pic_old->dim; i++ ) - weights[i] = ( mitkIpFloat8_t ) ( pic_old->n[i] - 1 ) / - ( mitkIpFloat8_t ) ( pic_new->n[i] - 1 ); - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - weights[i] = 0.; - - /* add header information for pic_new and allocate memory */ - - pic_new->bpe = pic_old->bpe*(is_color!=0?3:1); - pic_new->type = pic_old->type; - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to scale an image */ - if(is_color==0) - { - mitkIpPicFORALL_4 ( SCNN, pic_old, pic_new, size, weights, n ); - } - else - { - mitkIpPicFORALL_4 ( SCNNCOLOR, pic_old, pic_new, size, weights, n ); - pic_old->bpe=pic_new->bpe=24; - } - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/Scale.c b/Utilities/IpFunc/Scale.c deleted file mode 100644 index 396aff12a4..0000000000 --- a/Utilities/IpFunc/Scale.c +++ /dev/null @@ -1,133 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function scales an image - */ - -/** @brief this function scales an image - * - * @param pic_old pointer to the image - * @param sc_fact vector that contains the scaling factors for each dimension - * @param sc_kind parameter for the kind of interpolation - * @arg @c mitkIpFuncScaleNN: next neighbour interpolation - * @arg @c mitkIpFuncScaleBl: bilinear interpolation - * - * @return pointer to the scaled image - * - * AUTHOR AND DATE - */ - -/* include-files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncScale ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t sc_fact[_mitkIpPicNDIM], - mitkIpFuncFlagI_t sc_kind ) ; -#ifndef DOXYGEN_IGNORE - -mitkIpPicDescriptor *mitkIpFuncScale ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t sc_fact[_mitkIpPicNDIM], - mitkIpFuncFlagI_t sc_kind ) -{ - - mitkIpUInt4_t i; /* loop index */ - mitkIpPicDescriptor *pic_new; /* pointer to scaled image */ - - char is_color=0; - - - /* check whether data are correct */ - - if(pic_old->bpe==24) - { - pic_old->bpe=8; - is_color=1; - } - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if(is_color) - pic_old->bpe=24; - - /* allocate pic_new */ - - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* copy scaling information to header of pic_new */ - - pic_new->dim = pic_old->dim; - for ( i = 0; i < pic_old->dim; i++ ) - pic_new->n[i] = - ( sc_fact[i] == 0 ) ? - pic_old->n[i] : - ( mitkIpUInt4_t ) ( sc_fact[i] * pic_old->n[i] ); - - /* call scaling routines */ - - if ( sc_kind == mitkIpFuncScaleNN ) - pic_new = _mitkIpFuncScNN ( pic_old, pic_new ); - else if ( sc_kind == mitkIpFuncScaleBl ) { - pic_new = _mitkIpFuncScBL ( pic_old, pic_new ); - /*printf("using NN due to error in _mitkIpFuncScaleBL ... "); - pic_new = _mitkIpFuncScNN ( pic_old, pic_new );*/ - } - else - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return( pic_new ); -} -#endif diff --git a/Utilities/IpFunc/SelInv.c b/Utilities/IpFunc/SelInv.c deleted file mode 100644 index 4635635678..0000000000 --- a/Utilities/IpFunc/SelInv.c +++ /dev/null @@ -1,159 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function sets the greyvalues of all pixels @e inside a given - * range to a new greyvalue - */ - -/** @brief sets the greyvalues of all pixels @e inside a given - * range to a new greyvalue - * - * The greyvalues of all pixels which are included - * in [gv_low, gv_up] are set to a new greyvalue (gv). - * - * @param pic_old pointer to original image - * @param gv_low lower greyvalue of range - * @param gv_up upper greyvalue of range - * @param gv new greyvalue - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to transformed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncSelInv ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpFloat8_t gv, - mitkIpPicDescriptor *pic_return ) ; -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - -#include "mitkIpFuncP.h" - -/* definition of macros */ - -#define SELECT( type, pic, gv_low, gv_up, gv ) \ -{ \ - mitkIpUInt4_t i; /* loopindex */\ - type help; /* element that should be transformed */\ - \ - /* transform greyvalues */\ - \ - for ( i = 0; i < _mitkIpPicElements ( pic ); i++ ) \ - { \ - help = (( type * )pic->data )[i]; \ - (( type * )pic_new->data )[i] = \ - ( help < ( type ) gv_low || help > ( type )gv_up ) ? \ - ( type ) help : gv; \ - } \ - \ -} \ - -/* ------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncSelInv ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpFloat8_t gv, - mitkIpPicDescriptor *pic_return ) -{ - mitkIpFloat8_t min_gv, max_gv; /* max and min posiible greyvalues */ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - - - /* calculate max. and min. possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) == mitkIpFuncERROR ) - return ( mitkIpFuncERROR ); - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( gv_low > gv_up ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( min_gv > gv_low || max_gv < gv_up ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( min_gv > gv || max_gv < gv ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory for the transformed image */ - - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to transform the image */ - - mitkIpPicFORALL_3 ( SELECT, pic_old, gv_low, gv_up, gv ); - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/SelMM.c b/Utilities/IpFunc/SelMM.c deleted file mode 100644 index 0c5a994271..0000000000 --- a/Utilities/IpFunc/SelMM.c +++ /dev/null @@ -1,153 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function sets the greyvalues of all pixels outside a given - * range to the an extremal greyvalue - */ - -/** @brief sets the greyvalues of all pixels outside a given - * range to the an extremal greyvalue - - * Sets the greyvalue of pixels that are smaller than gv_low to this value and - * those larger than gv_up to that value. Very similar to - * and used by mitkIpFuncLevWin(). - * - * @param pic_old pointer to original image - * @param gv_low lower greyvalue of range - * @param gv_up upper greyvalue of range - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to transformed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncSelMM ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpPicDescriptor *pic_return ) ; - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - -#define SELECT( type, pic, gv_low, gv_up, min_gv, max_gv ) \ -{ \ - mitkIpUInt4_t i; /* loopindex */\ - mitkIpUInt4_t no_elem; /* loopindex */\ - type help; /* element that should be transformed */\ - \ - /* transform greyvalues */\ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = (( type * )pic->data )[i]; \ - (( type * )pic_new->data )[i] = \ - ( help < ( type ) gv_up ) ? \ - (( help > ( type ) gv_low ) ? help : ( type ) gv_low ) : \ - ( type ) gv_up ; \ - } \ -} - -/* ------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncSelMM ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpPicDescriptor *pic_return ) -{ - mitkIpFloat8_t min_gv, max_gv; /* max and min possible greyvalues */ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - - - /* calculate max. and min. possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) == mitkIpFuncERROR ) - return ( mitkIpFuncERROR ); - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( gv_low >= gv_up ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( min_gv > gv_low || max_gv < gv_up ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory for the transformed image */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to transform the image */ - - mitkIpPicFORALL_4 ( SELECT, pic_old, gv_low, gv_up, min_gv, max_gv ); - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/Select.c b/Utilities/IpFunc/Select.c deleted file mode 100644 index c720c793d7..0000000000 --- a/Utilities/IpFunc/Select.c +++ /dev/null @@ -1,160 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function sets the greyvalues of all pixels @e outside a given - * range to a new greyvalue - */ - -/** @brief sets the greyvalues of all pixels @e outside a given - * range to a new greyvalue - * - * The greyvalues of all pixels which are @e not included - * in [gv_low, gv_up] are set to a new greyvalue (gv). - * - * @param pic_old pointer to original image - * @param gv_low lower greyvalue of range - * @param gv_up upper greyvalue of range - * @param gv new greyvalue - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to transformed image - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncSelect ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpFloat8_t gv, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - -#define SELECT( type, pic, gv_low, gv_up, gv ) \ -{ \ - mitkIpUInt4_t i; /* loopindex */\ - type help; /* element that should be transformed */\ - \ - /* transform greyvalues */\ - \ - for ( i = 0; i < _mitkIpPicElements ( pic ); i++ ) \ - { \ - help = (( type * )pic->data )[i]; \ - (( type * )pic_new->data )[i] = \ - ( help < gv_low || help > gv_up ) ? \ - /*( help < ( type ) gv_low || help > ( type )gv_up ) ? iw-3.8.2000*/ \ - ( type ) gv : help; \ - } \ - \ -} \ - -/* ------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncSelect ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpFloat8_t gv, - mitkIpPicDescriptor *pic_return ) -{ - mitkIpFloat8_t min_gv, max_gv; /* max and min possible greyvalues */ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - - - /* calculate max. and min. possible greyvalues */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) == mitkIpFuncERROR ) - return ( mitkIpFuncERROR ); - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( gv_low > gv_up ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } -/* iw - commented out on 3.8.2000 - if ( min_gv > gv_low || max_gv < gv_up ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } -*/ - if ( min_gv > gv || max_gv < gv ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory for the transformed image */ - - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to transform the image */ - - mitkIpPicFORALL_3 ( SELECT, pic_old, gv_low, gv_up, gv ); - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} -#endif diff --git a/Utilities/IpFunc/SetErrno.c b/Utilities/IpFunc/SetErrno.c deleted file mode 100644 index a19276cd0e..0000000000 --- a/Utilities/IpFunc/SetErrno.c +++ /dev/null @@ -1,138 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this functions sets a global error-number (mitkIpFuncErrno) if an error - * occured - */ - -/** this functions sets a global error-number (mitkIpFuncErrno) if an error - * occured - * - * @param error_no number which describes the error - * - * @return none - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)_mitkIpFuncSetErrno\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/* gloabal variables */ - -int mitkIpFuncErrno; - -/* ------------------------------------------------------------------- */ - -/* -** _mitkIpFuncSetErrno -*/ - -void _mitkIpFuncSetErrno ( int error_no ) -{ - mitkIpFuncErrno = error_no; - - return; -} - -/* ------------------------------------------------------------------- */ - -/* -** mitkIpFuncPError -*/ - - -void mitkIpFuncPError ( char *string ) -{ - char *err_string=NULL; - - switch ( mitkIpFuncErrno ) - { - case mitkIpFuncOK : - err_string = "ipFunc: no error occured"; - break; - case mitkIpFuncNOPIC_ERROR : - err_string = "no image"; - break; - case mitkIpFuncDIM_ERROR : - err_string = "ipFunc: incorrect dimension of image"; - break; - case mitkIpFuncSIZE_ERROR : - err_string = "ipFunc: incorrect image size"; - break; - case mitkIpFuncFLAG_ERROR : - err_string = "ipFunc: incorrect flag"; - break; - case mitkIpFuncMALLOC_ERROR : - err_string = "ipFunc: no memory allocated"; - break; - case mitkIpFuncPICNEW_ERROR : - err_string = "ipFunc: can't create pic_new"; - break; - case mitkIpFuncTYPE_ERROR : - err_string = "ipFunc: incorrect image data type "; - break; - case mitkIpFuncUNFIT_ERROR : - err_string = "ipFunc: image data sizeis don't correspond"; - break; - case mitkIpFuncDIMMASC_ERROR : - err_string = "ipFunc: incorrect mask dimension"; - break; - case mitkIpFuncDATA_ERROR : - err_string = "ipFunc: incorrect value of parameter"; - break; - default : - err_string = "ipFunc: unknown error"; - } - fprintf ( stderr, "error message: %s \n", err_string ); -} - -#endif - diff --git a/Utilities/IpFunc/SetTag.c b/Utilities/IpFunc/SetTag.c deleted file mode 100644 index 557f532d57..0000000000 --- a/Utilities/IpFunc/SetTag.c +++ /dev/null @@ -1,113 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * this function sets a tag into an image - */ - -/** @brief sets a tag into an image - * If the tag does not exist, it is created. Otherwise the existing - * tag is replaced by the new one. If type==mitkIpPicASCII and the last - * byte is not \0, a \0 is added. - * - * @param pic image into which the tag is set - * @param name name of this tag - * @param size size of the whole data - * @param el_size size of one element of the data - * @param data pointer to the data - * @return - * @arg 0 : error (pic==NULL or data==NULL) - * @arg 1 : new tag added - * @arg 2 : tag replaced - * - * @b Examples: - * @code - * mitkIpFuncSetTag(pic, "OUTSIDE_VALUE", mitkIpPicInt, sizeof(mitkIpInt4_t), 1, &outside_value); - * - * char startpoint[11]; - * memset(startpoint, 0, 11); - * sprintf(startpoint,"(%u/%u)",*x,*y); - * mitkIpFuncSetTag(p, "STARTPOINT", mitkIpPicASCII, 11, 1, startpoint); - * @endcode - * @warning not yet extensively tested. - * - * @author Ivo (based on Gerald's NewTag) - * @date 26.06.2000 - */ - -#include "mitkIpFuncP.h" - -int mitkIpFuncSetTag( mitkIpPicDescriptor *pic, char *name, int type, int size, - int el_size, void *data ) -{ - mitkIpPicTSV_t *tsv; - int alloc_size; - int add_new; - - if((pic==NULL) || (data==NULL)) return 0; - - alloc_size=size; - if((type==mitkIpPicASCII) && (((char*)data)[size-1]!=0)) alloc_size++; - - tsv = mitkIpPicQueryTag(pic, name); - if (tsv != NULL) - { - tsv->value = realloc(tsv->value, alloc_size * el_size ); - add_new = 0; - } - else - { - tsv = malloc( sizeof(mitkIpPicTSV_t) ); - tsv->value = malloc( alloc_size * el_size ); - strcpy( tsv->tag, name); - add_new = 1; - } - tsv->type = type; - tsv->bpe = 8*el_size; - tsv->dim = 1; - tsv->n[0] = alloc_size; - tsv->value = memmove( tsv->value, data, size * el_size ); - if(alloc_size!=size) ((char*)tsv->value)[size]=0; - - if(add_new==1) - mitkIpPicAddTag( pic, tsv ); - - return add_new+1; -} diff --git a/Utilities/IpFunc/ShapeInterpolation.c b/Utilities/IpFunc/ShapeInterpolation.c deleted file mode 100644 index eb8bbe11da..0000000000 --- a/Utilities/IpFunc/ShapeInterpolation.c +++ /dev/null @@ -1,257 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -#include <assert.h> -#include <math.h> -#include "mitkIpFuncP.h" - -/*! -The algorithm implements the shape-based interpolation technique. -Further detailed information can be found in: - -G.T. Herman, J. Zheng, C.A. Bucholtz: "Shape-based interpolation" -IEEE Computer Graphics & Applications, pp. 69-79,May 1992 -*/ - -#define MAX 2048 - -extern float truncf (float x); -static mitkIpPicDescriptor* setup (mitkIpPicDescriptor* pic_old, const mitkIpFloat4_t threshold); -static mitkIpInt2_t distance (const mitkIpInt2_t* const old_distance, const mitkIpInt2_t* mask_dist, const mitkIpInt2_t* mask_offset, const mitkIpUInt4_t mask_elements); - -#define INTERPOLATE(TYPE, RESULT, PIC0, PIC1) \ -{ \ - mitkIpInt4_t x, y; \ - mitkIpUInt4_t i; /* loop counters */ \ - mitkIpFloat4_t weight[] = {1.0f-ratio, ratio}; /* weights of the interpolants */ \ - mitkIpInt2_t mask_width = 1; /* mask width from center to border */ \ - mitkIpInt2_t mask_x[] = {0, -1, +1, 0, -1}; /* relativ position in x-axis of mask */ \ - mitkIpInt2_t mask_y[] = {0, 0, -1, -1, -1}; /* relativ position in y-axis of mask */ \ - /* mitkIpInt2_t mask_dist[] = {0, 3, 4, 3, 4}; */ \ - mitkIpInt2_t mask_dist[] = {0, 10, 14, 10, 14};/* distance to central element */ \ - mitkIpInt2_t mask_offset [5]; /* relative start position in given image */ \ - mitkIpUInt4_t mask_elements = 5; /* elements in distance mask */ \ - mitkIpInt2_t first_x, first_y; /* first pixel for distance calculation \ - in enlarged image version */ \ - mitkIpInt2_t last_x, last_y; /* last pixel for distance calculation \ - in enlarged image version */ \ - mitkIpInt2_t *pixel[2]; /* pointer to the current pixels */ \ - TYPE* pixel_out; \ - \ - /* apply the mask in both directions */ \ - for (i=0; i< mask_elements; i++) { \ - mask_offset [i] = mask_x[i] + mask_y[i]*(PIC0)->n[0]; \ - } \ - first_x = mask_width; \ - first_y = mask_width; \ - last_x = (PIC0)->n[0] - mask_width-1; \ - last_y = (PIC0)->n[1] - mask_width-1; \ - /* top-left to bottom-right, borders are neglected */ \ - for (y = first_y; y <= last_y; y++) { \ - pixel [0] = (mitkIpInt2_t *) (PIC0)->data + (first_x + y * (PIC0)->n [0]); \ - pixel [1] = (mitkIpInt2_t *) (PIC1)->data + (first_x + y * (PIC1)->n [0]); \ - for (x = first_x; x <= last_x; x++) { \ - *(pixel [0])++ = distance (pixel [0], mask_dist, mask_offset, mask_elements); \ - *(pixel [1])++ = distance (pixel [1], mask_dist, mask_offset, mask_elements); \ - } \ - } \ - /* bottom-right to top-left, borders are neglected */ \ - for (i=0; i< mask_elements; i++) { \ - mask_offset [i] = -mask_offset [i]; \ - } \ - pixel_out = (TYPE *) result->data + _mitkIpPicElements(result) - 1; \ - for (y = last_y; y >= first_y; y--) { \ - pixel [0] = (mitkIpInt2_t *) (PIC0)->data + (last_x + y * (PIC0)->n [0]); \ - pixel [1] = (mitkIpInt2_t *) (PIC1)->data + (last_x + y * (PIC1)->n [0]); \ - for (x = last_x; x >= first_x; x--) { \ - *(pixel [0]) = distance (pixel [0], mask_dist, mask_offset, mask_elements); \ - *(pixel [1]) = distance (pixel [1], mask_dist, mask_offset, mask_elements); \ - *pixel_out-- = (weight [0] * *(pixel [0]) + weight [1] * *(pixel[1]) > 0 ? 1 : 0); \ - pixel[0]--; \ - pixel[1]--; \ - } \ - } \ -} - -/*! -\brief Computes an intermediate image by linear shape-based interpolation. -@param pic1,pic2 the images which enclose the intermediate image -@param threshold the threshold which extracts the shape in the images -@param ratio the ratio the ratio specifies the weights for interpolation, i.e. the intermediate -image equals to pic1 or pic2 if the ratio is zero and one, respectively -@returns the intermediate image -*/ -mitkIpPicDescriptor* -mitkIpFuncShapeInterpolation (mitkIpPicDescriptor* pic1, mitkIpPicDescriptor* pic2, const mitkIpFloat4_t threshold, const mitkIpFloat4_t ratio, mitkIpPicDescriptor* result) -{ - mitkIpPicDescriptor *pic[2]; /* pointer to image data */ - - /* prepare the images */ - result = mitkIpPicCopyHeader(pic1, NULL); - if (result == NULL) { - return NULL; - } - result->data = malloc (_mitkIpPicSize (result)); - if (result->data == NULL) { - _mitkIpFuncSetErrno (mitkIpFuncMALLOC_ERROR); - mitkIpPicFree (result); - return NULL; - } - pic[0] = setup (pic1, threshold); - pic[1] = setup (pic2, threshold); - - mitkIpPicFORALL_2(INTERPOLATE, result, pic[0], pic[1]); - - mitkIpPicFree(pic [0]); - mitkIpPicFree(pic [1]); - return result; -} - -#define COPY(TYPE, SRC, DST, THRESH) \ -{ \ - TYPE* src; \ - mitkIpInt2_t* dst; \ - src = (TYPE *) (SRC)->data; \ - dst = (mitkIpInt2_t *) (DST)->data + (1 + (DST)->n[0]); \ - for (y = 0; y < (SRC)->n[1]; y++) { \ - for (x = 0; x < (SRC)->n[0]; x++) { \ - *dst++ = (*src++ > (THRESH) ? MAX : -MAX); \ - } \ - dst += 2; \ - } \ -} - -static mitkIpPicDescriptor* -setup (mitkIpPicDescriptor* pic_old, const mitkIpFloat4_t threshold) -{ - mitkIpPicDescriptor* pic; - mitkIpInt2_t* dst; - mitkIpUInt4_t x, y; - - /* Allocate new image for distance transform */ - - pic = mitkIpPicCopyHeader (pic_old, NULL); - pic->type = mitkIpPicInt; - pic->bpe = 16; - pic->n[0] += 2; - pic->n[1] += 2; - pic->data = malloc (_mitkIpPicSize (pic)); - - /* Set the frame to -1 */ - - dst = (mitkIpInt2_t *) pic->data; - for (x = 0; x < pic->n[0]; x++) { - *dst++ = -MAX; - } - dst = (mitkIpInt2_t *) pic->data + _mitkIpPicElements (pic) - pic->n[0]; - for (x = 0; x < pic->n[0]; x++) { - *dst++ = -MAX; - } - dst = (mitkIpInt2_t *) pic->data; - for (y = 0; y < pic->n[1]; y++) { - *dst = -MAX; - dst += pic->n[0]; - } - dst = (mitkIpInt2_t *) pic->data + (pic->n[0] - 1); - for (y = 0; y < pic->n[1]; y++) { - *dst = -MAX; - dst += pic->n[0]; - } - - /* Set the image data to initial values */ - - mitkIpPicFORALL_2(COPY, pic_old, pic, threshold); - dst = (mitkIpInt2_t *) pic->data + (1 + pic->n[0]); - for (y = 0; y < pic_old->n[1]; y++) { - for (x = 0; x < pic_old->n[0]; x++) { - if ((dst[0] < dst[1]) || (dst[0] < dst[pic->n[0]])) { - *dst = -5; - } else if ((dst[0] > dst[1]) || (dst[0] > dst[pic->n[0]])) { - *dst = 5; - } - dst++; - } - dst += 2; - } - dst -= 2; - for (y = 0; y < pic_old->n[1]; y++) { - for (x = 0; x < pic_old->n[0]; x++) { - dst--; - if (abs (dst[0]) > 5) { - if ((dst[0] < dst[-1]) || (dst[0] < dst[-pic->n[0]])) { - *dst = -5; - } else if ((dst[0] > dst[-1]) || (dst[0] > dst[-pic->n[0]])) { - *dst = 5; - } - } - } - } - return pic; -} - -static mitkIpInt2_t distance (const mitkIpInt2_t* const old_distance, const mitkIpInt2_t* mask_dist, const mitkIpInt2_t* mask_offset, const mitkIpUInt4_t mask_elements) -{ - mitkIpInt2_t cur_distance, new_distance; - mitkIpUInt4_t i; - - cur_distance = old_distance [0]; - if (abs (cur_distance) != 5) { - if (cur_distance > 0) { - for (i = 0; i < mask_elements; i++) { - new_distance = *mask_dist + old_distance [*mask_offset]; - if (new_distance < cur_distance) { - cur_distance = new_distance; - } - mask_dist++; - mask_offset++; - } - } else if (cur_distance < 0) { - for (i = 0; i < mask_elements; i++) { - new_distance = old_distance [*mask_offset] - *mask_dist; - if (new_distance > cur_distance) { - cur_distance = new_distance; - } - mask_dist++; - mask_offset++; - } - } - } - return cur_distance; -} diff --git a/Utilities/IpFunc/Shp.c b/Utilities/IpFunc/Shp.c deleted file mode 100644 index 7361bc744f..0000000000 --- a/Utilities/IpFunc/Shp.c +++ /dev/null @@ -1,165 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs a high pass filter using 2D or 3D filtering - * masks - */ - -/** @brief performs a high pass filter using 2D or 3D filtering - * masks - * - * @param pic_old pointer to the image that should be convolved - * @param dim_mask dimension of filtering mask - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to zero - * @param mask_nr tells which mask should be taken - * - * @return pointer to the tranformed image - * - * USES - * function mitkIpFuncConv: convolves image with mask - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncShp ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border, - mitkIpUInt4_t mask_nr ) ; -#ifndef DOXYGEN_IGNORE - -mitkIpPicDescriptor *mitkIpFuncShp ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border, - mitkIpUInt4_t mask_nr ) -{ - - mitkIpPicDescriptor *pic_new; /* convolved image */ - mitkIpPicDescriptor *pic_mask; /* high pass mask */ - mitkIpUInt4_t i; /* loop index */ - mitkIpInt2_t mask2[] = /* 2D masks */ - { 0, -1, 0, -1, 5, -1, 0, -1, 0, /* mask 0 */ - - 1, -2, 1, -2, 5, -2, 1, -2, 1, /* mask 1 */ - - -1, -1, -1, -1, 9, -1, -1, -1, -1 }; /* mask 2 */ - - mitkIpInt2_t mask3[] = /* 3D masks */ - { 0, 0, 0, 0, -1, 0, 0, 0, 0, /* mask 0 */ - 0, -1, 0, -1, 7, -1, 0, -1, 0, - 0, 0, 0, 0, -1, 0, 0, 0, 0, - - 1, 1, 1, 1, -4, 1, 1, 1, 1, /* mask 1 */ - 1, -4, 1, -4, 5, -4, 1, -4, 1, - 1, 1, 1, 1, -4, 1, 1, 1, 1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, /* mask 2 */ - -1, -1, -1, -1, 27, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1 }; - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim < dim_mask || dim_mask < 2 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( /* mask_nr < 0 || */ mask_nr > 2 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of pic_mask */ - - pic_mask = mitkIpPicNew (); - if ( pic_mask == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_mask->type = mitkIpPicInt; - pic_mask->bpe = 16; - pic_mask->dim = dim_mask; - for ( i = 0; i < dim_mask; i++ ) - pic_mask->n[i] = 3; - - if ( dim_mask == 3 ) - { - pic_mask->data = mask3 + mask_nr * 27; - } - else if ( dim_mask == 2 ) - { - pic_mask->data = mask2 + mask_nr * 9; - } - else - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* function to convolve image with mask */ - - pic_new = mitkIpFuncConv ( pic_old, pic_mask, border ); - - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/Skewness.c b/Utilities/IpFunc/Skewness.c deleted file mode 100644 index e0ca5872c7..0000000000 --- a/Utilities/IpFunc/Skewness.c +++ /dev/null @@ -1,116 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the skewness (Schiefe) of all - * greyvalues in an image - */ - -/** @brief calculates the skewness (Schiefe) of all - * greyvalues in an image - * - * @param pic pointer to the image - * - * @return skewness of image - * - * @author Steffen Gundel - */ - - -/* include-files */ - -#include "mitkIpFuncP.h" - -/* definition of extreme value macro */ - -mitkIpFloat8_t mitkIpFuncSkewness ( mitkIpPicDescriptor *pic ); - -#ifndef DOXYGEN_IGNORE - -#define SKEWNESS( type, pic, mean, skew ) \ - { \ - mitkIpUInt4_t i, no_elem; \ - \ - skew = 0.; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - skew = ( ( ( type * ) pic->data ) [i] - mean ) * \ - ( ( ( type * ) pic->data ) [i] - mean ) * \ - ( ( ( type * ) pic->data ) [i] - mean ) + \ - skew; \ - } \ - } - -/* ========================================================== */ -/* -** function picVar : calculates the mean value (mean) -** of an image (pic) -*/ -/* ========================================================== */ - -mitkIpFloat8_t mitkIpFuncSkewness ( mitkIpPicDescriptor *pic ) -{ - - mitkIpFloat8_t var; - mitkIpFloat8_t mean, std; - mitkIpFloat8_t skew; - - - /* check image data */ - - if ( _mitkIpFuncError ( pic ) != mitkIpOK ) return ( mitkIpFuncERROR ); - - if ( _mitkIpPicElements ( pic ) == 1 ) var = 0; - else - { - - mean = mitkIpFuncMean ( pic ); - std = mitkIpFuncSDev( pic ); - - mitkIpPicFORALL_2( SKEWNESS, pic, mean, skew ); - - var = skew / (( mitkIpFloat8_t ) (( _mitkIpPicElements ( pic ) - 1 ) *std*std*std)); - } - - return( var ); -} -#endif diff --git a/Utilities/IpFunc/SkewnessR.c b/Utilities/IpFunc/SkewnessR.c deleted file mode 100644 index e132e6d9de..0000000000 --- a/Utilities/IpFunc/SkewnessR.c +++ /dev/null @@ -1,87 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the skewness (Schiefe) of all - * greyvalues included by a rectangle - */ - -/** @brief calculates the skewness (Schiefe) of all - * greyvalues included by a rectangle - * - * The rectangle is described by a vector with the coordinates of the - * upper left corner and a vector of its length in each direction - * - * @param pic_old pointer to the image - * @param begin vector with the beginning coordinates of the window - * @param length vector with the length of the window in each direction - * - * @return skewness in window - * - * @author Steffen Gundel - */ - -/* include-files */ - -#include "mitkIpFuncP.h" - - -/* ========================================================== */ -/* -** function picVar : calculates the mean value (mean) -** of an image (pic) -*/ -/* ========================================================== */ - -mitkIpFloat8_t mitkIpFuncSkewnessR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ) { - - mitkIpFloat8_t var; - mitkIpPicDescriptor *pic_help; - - pic_help = mitkIpFuncWindow ( pic_old, begin, length ); - - var = mitkIpFuncSkewness ( pic_help ); - - mitkIpPicFree ( pic_help ); - - return var ; -} diff --git a/Utilities/IpFunc/Sobel.c b/Utilities/IpFunc/Sobel.c deleted file mode 100644 index c54dc7b7fb..0000000000 --- a/Utilities/IpFunc/Sobel.c +++ /dev/null @@ -1,348 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs a 3*3 nonlinear edge enhancement operation - * using a sobel operator. The operator could be used with 2D and 3D - * filtering masks. - */ - -/** @brief performs a 3*3 nonlinear edge enhancement operation - * using a sobel operator. The operator could be used with 2D and 3D - * filtering masks. - * - * @param pic_old pointer to the image that should be convolved - * @param mask pointer to the mask that is used for convolution - * @param border tells how the edge is transformed - * @arg @c mitkIpFuncBorderOld : original greyvalues - * @arg @c mitkIpFuncBorderZero : edge is set to minimal greyvalue - * - * @return pointer to the transformed image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncSobel ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define SOBEL( typ, pic, size, mask_anz, m ) \ -{ \ - mitkIpInt4_t ind[_mitkIpPicNDIM]; \ - mitkIpInt4_t n[_mitkIpPicNDIM]; \ - mitkIpUInt4_t i,j; \ - mitkIpInt4_t offset; \ - mitkIpInt4_t *beg; \ - mitkIpFloat8_t help, help2, min_gv, max_gv; \ - \ - /* calculate begin and end of the single masks */ \ - \ - beg = malloc ( ( mask_anz + 1 ) * sizeof ( mitkIpInt4_t ) ); \ - \ - beg[0] = 0; \ - for ( i = 1; i <= mask_anz; i++ ) \ - beg[i] = beg[i-1] + m->length / mask_anz; \ - \ - /* initialization of index vector */ \ - \ - for ( i = 0; i < pic->dim; i++ ) \ - n[i] = pic->n[i] - 1; \ - \ - for ( i = pic->dim; i < _mitkIpPicNDIM; i++ ) \ - n[i] = 2; \ - \ - /* calculate max. and min. possible greyvalues */ \ - \ - _mitkIpFuncExtT ( pic->type, pic->bpe, &min_gv, &max_gv ); \ - \ - /* convolve image with compressed mask */ \ - \ - for ( ind[7] = 1; ind[7] < n[7]; ind[7]++ ) \ - for ( ind[6] = 1; ind[6] < n[6]; ind[6]++ ) \ - for ( ind[5] = 1; ind[5] < n[5]; ind[5]++ ) \ - for ( ind[4] = 1; ind[4] < n[4]; ind[4]++ ) \ - for ( ind[3] = 1; ind[3] < n[3]; ind[3]++ ) \ - for ( ind[2] = 1; ind[2] < n[2]; ind[2]++ ) \ - for ( ind[1] = 1; ind[1] < n[1]; ind[1]++ ) \ - for ( ind[0] = 1; ind[0] < n[0]; ind[0]++ ) \ - { \ - offset = 0; \ - for ( i = 0; i < pic->dim; i++ ) \ - offset = offset + size[i] * ind[i]; \ - \ - help2 = 0.; \ - for ( j = 0; j < mask_anz; j++ ) \ - { \ - help = 0; \ - for ( i = beg[j]; i < beg[j+1] ; i++ ) \ - help = help + m->mask_vekt[i] * \ - (( typ * )pic->data)[offset+m->off_vekt[i]];\ - help2 = help2 + fabs ( help ); \ - } \ - \ - (( typ * )pic_new->data )[offset] = \ - ( help2 < max_gv )? \ - ( ( help2 < min_gv ) ? ( typ )min_gv : help2 ) : \ - ( typ ) max_gv; \ - } \ - free ( beg ); \ -} - -/* ------------------------------------------------------------------- */ -/* -** function mitkIpFuncSobel: -** -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncSobel ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ) -{ - - mitkIpPicDescriptor *pic_new; /* convolved image */ - mitkIpPicDescriptor *pic_mask; /* sobel mask */ - mitkIpInt4_t offset, off_mask; - mitkIpUInt4_t i, j; /* loopindex */ - mitkIpUInt4_t pos; - mitkIpUInt1_t mask_anz; /* number of masks */ - mitkIpInt4_t n[_mitkIpPicNDIM]; - mitkIpInt4_t ind[_mitkIpPicNDIM]; /* vector of loop indices (image) */ - mitkIpFuncMasc_t *m; /* length of mask and offsets */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; - mitkIpInt2_t sobel2[] = /* 2D Sobel mask */ - { 1, 0, -1, 2, 0, -2, 1, 0, -1, - 1, 2, 1, 0, 0, 0, -1, -2, -1 }; - mitkIpInt2_t sobel3[] = /* 3D Sobel mask */ - { 1, 0, -1, 2, 0, -2, 1, 0, -1, - 1, 0, -1, 2, 0, -2, 1, 0, -1, - 1, 0, -1, 2, 0, -2, 1, 0, -1, - - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 2, 0, -2, 2, 0, -2, 2, 0, -2, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - - 1, 2, 1, 0, 0, 0, -1, -2, -1, - 1, 2, 1, 0, 0, 0, -1, -2, -1, - 1, 2, 1, 0, 0, 0, -1, -2, -1, - - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 2, 2, 2, 0, 0, 0, -2, -2, -2, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - - 1, 2, 1, 1, 2, 1, 1, 2, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, -2, -1, -1, -2, -1, -1, -2, -1, - - 1, 1, 1, 2, 2, 2, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, -1, -1, -2, -2, -2, -1, -1, -1 }; - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( ( pic_old->dim < dim_mask ) || ( dim_mask < 1 ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of pic_mask */ - - pic_mask = mitkIpPicNew (); - if ( pic_mask == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_mask->type = mitkIpPicInt; - pic_mask->bpe = 16; - pic_mask->dim = dim_mask+1; - for ( i = 0; i < dim_mask; i++ ) - pic_mask->n[i] = 3; - - if ( dim_mask == 3 ) - { - mask_anz = 6; - pic_mask->n[dim_mask] = mask_anz; - pic_mask->data = sobel3; - } - else if ( dim_mask == 2 ) - { - mask_anz = 2; - pic_mask->n[dim_mask] = mask_anz; - pic_mask->data = sobel2; - } - else - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* initialisation of vectors */ - - for ( i = 0; i < dim_mask; i++ ) - n[i] = 2; - - for ( i = dim_mask; i < _mitkIpPicNDIM; i++ ) - n[i] = 0; - - /* allocate mask structure */ - - m = malloc ( sizeof ( mitkIpFuncMasc_t ) ); - if ( m == NULL ) - { - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return NULL; - } - m->off_vekt = malloc ( _mitkIpPicElements( pic_mask ) * sizeof ( mitkIpInt4_t ) ); - if ( m->off_vekt == NULL ) - { - free ( m ); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return NULL; - } - m->mask_vekt = malloc ( _mitkIpPicElements( pic_mask ) * sizeof ( mitkIpFloat8_t ) ); - if ( m->mask_vekt == NULL ) - { - free ( m->off_vekt ); - free ( m ); - mitkIpPicFree ( pic_mask ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return NULL; - } - - /* create a new picture, copy the header, allocate memory */ - - if ( border == mitkIpFuncBorderOld ) - pic_new = mitkIpPicClone ( pic_old ); - else if ( border == mitkIpFuncBorderZero ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - free ( m->off_vekt ); - free ( m ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - free ( m->off_vekt ); - free ( m ); - return ( mitkIpFuncERROR ); - } - - /* calculate offset vector for the compressed mask */ - - m->length = 0; - size[0] = 1; - for ( i = 1; i < pic_old->dim; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - - off_mask = 0; - for ( i = 0; i < mask_anz; i++ ) - for ( ind[2] = -1; ind[2] < n[2]; ind[2]++ ) - for ( ind[1] = -1; ind[1] < n[1]; ind[1]++ ) - for ( ind[0] = -1; ind[0] < n[0]; ind[0]++ ) - { - if ( (( mitkIpInt2_t * )pic_mask->data)[off_mask] != 0 ) - { - offset = 0; - for ( j = 0; j < dim_mask; j++ ) - offset = offset + ind[j] * size[j]; - m->off_vekt[m->length] = offset; - m->length++; - } - off_mask++; - } - - /* remove elements that are zero from mask */ - - pos = 0; - for ( i = 0; i < m->length; i++ ) - { - while ( (( mitkIpInt2_t * )pic_mask->data)[pos] == 0 ) pos++; - m->mask_vekt[i] = ( mitkIpFloat8_t )(( mitkIpInt2_t * )pic_mask->data)[pos]; - pos++; - } - - - /* macro for the sobel operator */ - - mitkIpPicFORALL_3 ( SOBEL, pic_old, size, mask_anz, m ); - - pic_mask->data = NULL; - mitkIpPicFree ( pic_mask ); - free ( m->off_vekt ); - free ( m->mask_vekt ); - free ( m ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/Sqrt.c b/Utilities/IpFunc/Sqrt.c deleted file mode 100644 index 2cc5b7d7c7..0000000000 --- a/Utilities/IpFunc/Sqrt.c +++ /dev/null @@ -1,166 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this functions calculates the square root of all pixels - */ - -/** @brief calculates the square root of all pixels - * - * @param pic_1 pointer to the first image - * @param keep tells whether the image type could be changed to mitkIpPicFloat - * keep = : image data type could be changed - * keep = : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory which could be used for pic_new. If - * pic_retrun == NULL new memory is allocated - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncSqrt ( mitkIpPicDescriptor *pic_1, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define SQRT1( type_1, pic_1, pic_new ) \ -{ \ - mitkIpPicFORALL_2 ( SQRT2, pic_new, pic_1, type_1 ); \ -} \ - - -#define SQRT2( type_n, pic_new, pic_1, type_1 ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - mitkIpFloat8_t help; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = ( mitkIpFloat8_t ) (( type_1 * ) pic_1->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( help < 0. ) ? 0 : ( type_n ) sqrt ( help ); \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncSqrt ( mitkIpPicDescriptor *pic_1, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. and min. possible greyvalues for data type of images*/ - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - pic_new = mitkIpPicNew (); - pic_new->dim = pic_1->dim; - pic_new->bpe = 64; - pic_new->type = mitkIpPicFloat; - for ( i = 0; i < pic_new->dim; i++ ) - pic_new->n[i] = pic_1->n[i]; - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - mitkIpPicFORALL_1 ( SQRT1, pic_1, pic_new ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_1); - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/SubC.c b/Utilities/IpFunc/SubC.c deleted file mode 100644 index 79bb2c42ae..0000000000 --- a/Utilities/IpFunc/SubC.c +++ /dev/null @@ -1,254 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function subtracts an constant from an image - */ - -/** @brief subtracts an constant from an image - * - * @param pic_1 pointer to the first image - * @param value constant which is subtracted from the image - * @param keep tells whether the image type could be changed when - * necessary - * @arg @c iFuncNoKeep : image data type could be changed - * @arg @c iFuncKeep : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory which could be used for pic_new. If - * pic_retrun == NULL new memory is allocated - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncSubC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define SUBC( type_1, pic_1, pic_new, value ) \ -{ \ - mitkIpPicFORALL_3 ( SUBC2, pic_new, pic_1, type_1, value ); \ -} \ - -#define SUBC2( type_n, pic_new, pic_1, type_1, value ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type_n * ) pic_new->data ) [i] = ( type_n ) \ - ( ( mitkIpFloat8_t ) (( type_1 * ) pic_1->data ) [i] - \ - value ); \ - } \ -} - -#define SUBC3( type_n, pic_1, pic_new, value ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - type_n help; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = (( type_n * ) pic_1->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( max_gv > ( mitkIpFloat8_t ) help - value ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help - value ) ? \ - ( (type_n)help - (type_n)value ) : ( type_n ) min_gv ) :\ - ( type_n ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncSubC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check value */ - - if ( value == 0. ) return ( pic_old ); - /* - else if ( value == 0. ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_old, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = max1 - value; - smin = min1 - value; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_old->type == mitkIpPicInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicUInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || smin < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_old->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - if ( keep == mitkIpFuncNoKeep ) - mitkIpPicFORALL_2 ( SUBC, pic_old, pic_new, value ) - if ( keep == mitkIpFuncKeep ) - mitkIpPicFORALL_2 ( SUBC3, pic_old, pic_new, value ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/SubI.c b/Utilities/IpFunc/SubI.c deleted file mode 100644 index 3912d08d91..0000000000 --- a/Utilities/IpFunc/SubI.c +++ /dev/null @@ -1,269 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function subtracts two images - */ - -/** @brief subtracts two images - * - * @param pic_1 pointer to the first image - * @param pic_2 pointer to the second image - * @param keep tells whether the image type could be changed when - * necessary - * keep = : image data type could be changed - * keep = : image data type of original pictures is - * kept (if there will be an over-/underflow - * the max. or min. possible greyvalue is taken) - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the new image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncSubI ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define SUBI( type_1, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpPicFORALL_3 ( SUBI2, pic_new, pic_1, pic_2, type_1 ); \ -} \ - -#define SUBI2( type_n, pic_new, pic_1, pic_2, type_1 ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type_n * ) pic_new->data ) [i] = \ - (( type_1 * ) pic_1->data ) [i] - \ - (( type_1 * ) pic_2->data ) [i]; \ - } \ -} - -#define SUBI3( type_n, pic_1, pic_2, pic_new ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - type_n help; \ - type_n help2; \ - \ - no_elem = _mitkIpPicElements ( pic_1 ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - help = (( type_n * ) pic_1->data ) [i]; \ - help2 = (( type_n * ) pic_2->data ) [i]; \ - (( type_n * ) pic_new->data ) [i] = \ - ( max_gv > ( mitkIpFloat8_t ) help - ( mitkIpFloat8_t ) help2 ) ? \ - (( min_gv < ( mitkIpFloat8_t ) help - ( mitkIpFloat8_t ) help2 ) ? \ - ( (type_n)help - (type_n)help2 ) : ( type_n ) min_gv ) :\ - ( type_n ) max_gv; \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncSubI ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* pointer to new image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ - mitkIpFloat8_t min2, max2; /* extreme greyvalues of 2. image */ - mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ - - - /* ckeck whether data are correct */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* check whether images have the same size */ - - if ( ( pic_1->type != pic_2->type ) || ( pic_1->bpe != pic_2->bpe ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - if ( pic_1->dim == pic_2->dim ) - for ( i = 0; i < _mitkIpPicNDIM; i++ ) - { - if ( pic_1->n[i] != pic_2->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); - return NULL; - } - - /* calculate max. and min. possible greyvalues for data type of images*/ - - if ( _mitkIpFuncExtT ( pic_1->type, pic_1->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - return ( mitkIpFuncERROR ); - - /* find out data type of new iamge */ - - if ( keep == mitkIpFuncKeep ) - { - pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - } - else if ( keep == mitkIpFuncNoKeep ) - { - /* calculate max. and min. greyvalues of both images */ - - if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( mitkIpFuncExtr ( pic_2, &min2, &max2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - smax = max1 - max2; - smin = min1 - min2; - - /* change image type of images of type mitkIpPicInt */ - - if ( pic_1->type == mitkIpPicInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicUInt ) - { - if ( smax < max_gv && smin > min_gv ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - pic_new->type = mitkIpPicInt; - pic_new->bpe = 16; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - if ( smax > max_gv || smin < min_gv ) - { - pic_new->type = mitkIpPicFloat; - pic_new->bpe = 64; - _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); - } - } - } - - /* change image type of images of type mitkIpPicUInt */ - - else if ( pic_1->type == mitkIpPicFloat ) - { - pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - } - else - { - _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - if ( keep == mitkIpFuncNoKeep ) - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* macro to invert the picture (for all data types) */ - - if ( keep == mitkIpFuncNoKeep ) - mitkIpPicFORALL_2 ( SUBI, pic_1, pic_2, pic_new ) - else if ( keep == mitkIpFuncKeep ) - mitkIpPicFORALL_2 ( SUBI3, pic_1, pic_2, pic_new ) - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_1); - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/Thresh.c b/Utilities/IpFunc/Thresh.c deleted file mode 100644 index c2edfc4f9e..0000000000 --- a/Utilities/IpFunc/Thresh.c +++ /dev/null @@ -1,138 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function performs a thresholding operation with a single theshold - */ - -/** @brief performs a thresholding operation with a single theshold - - * All greyvalues above the threshold are set to the maximal possible - * greyvalue and all greyvalues below this threshold to the minimal greyvalue. - * @param pic_old pointer to the image that should be transformed - * @param threshold threshold - * @param pic_return memory used to store return image ( if pic_return == NULL - * new memory is allocated ) - * - * @return pointer to the transformed image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncThresh ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t threshold, - mitkIpPicDescriptor *pic_return ); - -#ifndef DOXYGEN_IGNORE - -/* definition of macro for normalisation */ - -#define THRESH( type, pic ) \ -{ \ - mitkIpUInt4_t i, no_elem; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - (( type * ) pic_new->data ) [i] = \ - ( (( type * ) pic->data ) [i] > ( type ) threshold ) ? \ - ( type ) 1 : ( type ) 0; \ - } \ -} - - -/* ------------------------------------------------------------------- */ -/* -** function picThresh: -** -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncThresh ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t threshold, - mitkIpPicDescriptor *pic_return ) -{ - - mitkIpPicDescriptor *pic_new; /* inverted picture */ - mitkIpFloat8_t max_gv; /* max. possible greyvalue */ - mitkIpFloat8_t min_gv; /* min. possible greyvalue */ - - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* calculate max. or min possible greyvalue for datatype */ - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) == mitkIpFuncERROR ) - return ( mitkIpFuncERROR ); - - /* test whether threshold is ok */ - - if ( threshold < min_gv || threshold > max_gv ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* create a new picture, copy the header, allocate memory */ - - pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); - - if ( pic_new == NULL ) return ( mitkIpFuncERROR ); - - /* macro to invert the picture (for all data types) */ - - mitkIpPicFORALL( THRESH, pic_old ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return pic_new; -} -#endif - diff --git a/Utilities/IpFunc/Transpose.c b/Utilities/IpFunc/Transpose.c deleted file mode 100644 index 2eefa02b81..0000000000 --- a/Utilities/IpFunc/Transpose.c +++ /dev/null @@ -1,244 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this funtion transposes the image - */ - -/** @brief transposes the image, i.e. a permutation of the axes is performed - * - * - * @param pic pointer to picture - * @param pic_old pointer to old picture, which is not used in this version - * @param permutations_vector indicates the permutation - * @par Example 3 1 2 - * @arg third axis will be the first axis - * @arg first axis will be the second - * @arg second axis will be the third - * - * @return transposed image - * - * $Log$ - * Revision 1.3 2003/01/30 14:30:53 mark - * in Scale.c _mitkIpFuncScaleBL auskommentiert, wegen Fehler - * - * Revision 1.2 2000/05/24 15:29:43 tobiask - * Changed the installation paths of the package. - * - * Revision 1.4 2000/05/04 12:52:11 ivo - * inserted BSD style license - * - * Revision 1.3 2000/03/06 17:02:48 ivo - * ipFunc now with doxygen documentation. - * - * Revision 1.2 2000/02/18 14:58:08 ivo - * Tags are now copied into newly allocated images. - * Bugs fixed in mitkIpFuncFrame, mitkIpFuncRegGrow, _mitkIpFuncBorderX and mitkIpFuncHitMiss. - * - * Revision 1.1.1.1 1998/07/16 12:04:50 antje - * initial import - * - * Revision 1.1 1995/04/06 12:04:30 uli - * Initial revision - */ - -/* -** ipFunc includefiles -*/ -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncTranspose( mitkIpPicDescriptor *pic, - mitkIpPicDescriptor *pic_old, - int *permutations_vector ) -; -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncTranspose\tGerman Cancer Research Center (DKFZ) $Revision$ "__DATE__ }; -#endif - - - - -/* -** the action starts here -*/ -mitkIpPicDescriptor *mitkIpFuncTranspose( mitkIpPicDescriptor *pic, - mitkIpPicDescriptor *pic_old, - int *permutations_vector ) - -{ - mitkIpPicDescriptor *pic_return; - mitkIpUInt4_t size [_mitkIpPicNDIM]; - mitkIpUInt4_t r_size[_mitkIpPicNDIM]; - mitkIpUInt4_t index [_mitkIpPicNDIM]; - mitkIpUInt4_t **r_index; - mitkIpUInt4_t i; - mitkIpUInt4_t r_offset; - int default_perm = 0; - - - /* - ** - */ - if( !pic ) return( NULL ); - if ( pic->dim < 1 || pic->dim > _mitkIpPicNDIM) - return (NULL); - - - /* - ** create and initialize help vectors - */ - - /* - ** permutations_vector == NULL - ** default permutation (1234 -> 4321) - */ - if( permutations_vector == NULL ) - { - permutations_vector = (int *) malloc( - pic->dim * sizeof( int )); - if (!permutations_vector) - return (0); - - for(i=0; i<pic->dim; i++ ) - permutations_vector[i] = pic->dim - i; - } - else - { - - int tmp[8]; - int error = 0; - for (i = 0; i < pic->dim; i++) - tmp[i] = 0; - for (i = 0; error == 0 && i < pic->dim; i++) - { - if( permutations_vector[i] > 0 ) - tmp[permutations_vector[i] - 1]++; - else - error = 1; - } - for (i = 0; error == 0 && i < pic->dim; i++) - if (tmp[i] != 1) - error = 1; - if (error == 1) - return (0); - } - - - /* - ** take over image header structure and allocate memory - */ - mitkIpPicFree( pic_old ); - pic_return = mitkIpPicCopyHeader( pic, NULL ); - if (!pic_return) - { - if (default_perm) - free ((void *) permutations_vector); - return (0); - } - - pic_return->data = malloc( _mitkIpPicSize(pic_return) ); - if (!pic_return->data) - { - if (default_perm) - free ((void *) permutations_vector); - mitkIpPicFree (pic_return); - return (0); - } - - - - /* - ** fill new dimension to pic_return - */ - for( i=0; i<pic->dim; i++ ) - pic_return->n[i] = pic->n[ ( permutations_vector[i] - 1 ) ]; - - /* - ** fill size vectors for multiplication - */ - for( i=0; i<_mitkIpPicNDIM; i++) - { - size[i] = 0; - r_size[i] = 0; - } - r_size[0] = 1; - size[0] = 1; - for( i=1; i<pic->dim; i++ ) - { - size[i] = size[i-1] * pic->n[i-1]; - r_size[i] = r_size[i-1] * pic_return->n[i-1]; - } - - - /* - ** index vectors - */ - r_index = (mitkIpUInt4_t **) malloc( _mitkIpPicNDIM * sizeof( mitkIpUInt4_t * ) ); - for( i=0; i<_mitkIpPicNDIM; i++) - r_index[i] = &( index[i] ); - for( i=0; i<pic->dim; i++ ) - r_index[i] = &( index[ ( permutations_vector[i] - 1 ) ]); - - - /* - ** Makro for all for-loops and switches for all dimensions (1-8) - ** FOR ALL: dimensions, indizes, data types - */ - mitkIpPicFORALL_4( mitkIpFuncFORALL, pic, pic_return, index, r_offset, - for( r_offset = *(r_index[0]), i=1; i<pic->dim; i++ ) - r_offset += *(r_index[i]) * r_size[i]; - ) - - - - - free( (void *) r_index ); - if (default_perm) free ((void *) permutations_vector); - - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_return, pic); - - return( pic_return ); -} -#endif diff --git a/Utilities/IpFunc/Var.c b/Utilities/IpFunc/Var.c deleted file mode 100644 index 229ccd7089..0000000000 --- a/Utilities/IpFunc/Var.c +++ /dev/null @@ -1,116 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the variance of all greyvalues - * in an image - */ - -/** this function calculates the variance of all greyvalues - * in an image - * - * @param pic pointer to the image - * @param &max result variable: mean greyvalue - * - * @return mitkIpFuncERROR - if an error occured - * @return mitkIpFuncOK - if no error occures - * - * AUTHOR & DATE - */ - -/* include-files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncVar ( mitkIpPicDescriptor *pic ); - -#ifndef DOXYGEN_IGNORE - -/* definition of extreme value macro */ - -#define MEAN_2( type, pic, mean, mean_2 ) \ - { \ - mitkIpUInt4_t i, no_elem; \ - \ - mean_2 = 0.; \ - \ - no_elem = _mitkIpPicElements ( pic ); \ - for ( i = 0; i < no_elem; i++ ) \ - { \ - mean_2 = ( ( ( type * ) pic->data ) [i] - mean ) * \ - ( ( ( type * ) pic->data ) [i] - mean ) + \ - mean_2; \ - } \ - } - -/* ========================================================== */ -/* -** function picVar : calculates the mean value (mean) -** of an image (pic) -*/ -/* ========================================================== */ - -mitkIpFloat8_t mitkIpFuncVar ( mitkIpPicDescriptor *pic ) -{ - - mitkIpFloat8_t var; - mitkIpFloat8_t mean; - mitkIpFloat8_t mean_2; - - /* check image data */ - - if ( _mitkIpFuncError ( pic ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( _mitkIpPicElements ( pic ) == 1 ) - var = 0; - else - { - /* calculate mean value */ - - mean = mitkIpFuncMean ( pic ); - - mitkIpPicFORALL_2( MEAN_2, pic, mean, mean_2 ); - - var = mean_2 / ( mitkIpFloat8_t ) ( _mitkIpPicElements ( pic ) - 1 ); - } - - return( var ); -} -#endif diff --git a/Utilities/IpFunc/VarC.c b/Utilities/IpFunc/VarC.c deleted file mode 100644 index 959bd1c19c..0000000000 --- a/Utilities/IpFunc/VarC.c +++ /dev/null @@ -1,217 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the variance of all greyvalues which are in - * a circle - */ - -/** @brief calculates the variance of all greyvalues which are in - * a circle - * - * @param pic_old pointer to the original image - * @param center pointer to an array that contains the coordinates of the center - * of the circle - * @param radius radius of the circle - * - * @return variance of the greyvalues which are included by the circle - * - * AUTHOR & DATE - */ -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncVarC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - - -#define VAR( type, pic, beg, end, size, center, radius ) \ -{ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - mitkIpUInt4_t dist[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - \ - for ( ind[7] = beg[7] ; ind[7] < end[7]; ind[7]++ ) \ - { \ - dist[7] = ( ind[7] - center[7] ) * ( ind[7] - center[7] ); \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6] ; ind[6] < end[6]; ind[6]++ ) \ - { \ - dist[6] = ( ind[6] - center[6] ) * ( ind[6] - center[6] ) + dist[7]; \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5] ; ind[5] < end[5]; ind[5]++ ) \ - { \ - dist[5] = ( ind[5] - center[5] ) * ( ind[5] - center[5] ) + dist[6]; \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4] ; ind[4] < end[4]; ind[4]++ ) \ - { \ - dist[4] = ( ind[4] - center[4] ) * ( ind[4] - center[4] ) + dist[5]; \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3] ; ind[3] < end[3]; ind[3]++ ) \ - { \ - dist[3] = ( ind[3] - center[3] ) * ( ind[3] - center[3] ) + dist[4]; \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2] ; ind[2] < end[2]; ind[2]++ ) \ - { \ - dist[2] = ( ind[2] - center[2] ) * ( ind[2] - center[2] ) + dist[3]; \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1] ; ind[1] < end[1]; ind[1]++ ) \ - { \ - dist[1] = ( ind[1] - center[1] ) * ( ind[1] - center[1] ) +dist[2];\ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1]+beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - dist[0] = ( ind[0] - center[0] ) * ( ind[0] - center[0] )+dist[1];\ - if ( sqrt ( ( mitkIpFloat8_t ) dist[0] ) <= radius ) \ - { \ - mean2 = ( ( mitkIpFloat8_t )(( type * )pic->data )[off[0]] - mean ) *\ - ( ( mitkIpFloat8_t )(( type * )pic->data )[off[0]] - mean ) +\ - mean2; \ - count++; \ - } \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpFloat8_t mitkIpFuncVarC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ) -{ - mitkIpInt4_t help; - mitkIpUInt4_t i; /* loop index */ - mitkIpFloat8_t mean; - mitkIpFloat8_t mean2; - mitkIpFloat8_t var; - mitkIpUInt4_t count; - mitkIpUInt4_t end[_mitkIpPicNDIM]; /* end of window */ - mitkIpUInt4_t begin[_mitkIpPicNDIM]; /* beginning of window */ - mitkIpUInt4_t centr[_mitkIpPicNDIM]; /* beginning of window */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( radius <= 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < pic_old->dim; i++ ) - { - help = center[i] - radius; - if ( help < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - else begin[i] = help; - - help = center[i] + radius; - if ( (mitkIpUInt4_t) help > pic_old->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - else end[i] = help + 1; - - centr[i] = center[i]; - } - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - size[pic_old->dim] = 0; - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - { - centr[i] = 0; - begin[i] = 0; - end[i] = 1; - } - - /* allocate image structure */ - - mean = mitkIpFuncMeanC ( pic_old, centr, radius ); - mean2 = 0; - count = 0; - - mitkIpPicFORALL_5 ( VAR, pic_old, begin, end, size, centr, radius ); - - if ( count == 1 ) - var = 0; - else - var = mean2 / ( count - 1 ); - - return ( var ); -} - -#endif diff --git a/Utilities/IpFunc/VarR.c b/Utilities/IpFunc/VarR.c deleted file mode 100644 index 796aa71542..0000000000 --- a/Utilities/IpFunc/VarR.c +++ /dev/null @@ -1,88 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the variance of all greyvalues included by a rectangle - */ - -/** @brief calculates the variance of all greyvalues included by a rectangle - * - * The rectangle is described by a vector with the coordinates of the - * upper left corner and a vector of its length in each direction - * - * @param pic_old pointer to original image - * @param begin vector with the beginning coordinates of the window - * @param length vector with the length of the window in each direction - * - * @return variance in window - * - * AUTHOR & DATE - */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncVarR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -mitkIpFloat8_t mitkIpFuncVarR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ) -{ - - mitkIpFloat8_t var; /* variance */ - mitkIpPicDescriptor *pic_help; - - pic_help = mitkIpFuncWindow ( pic_old, begin, length ); - - var = mitkIpFuncVar ( pic_help ); - - mitkIpPicFree ( pic_help ); - - return ( var ); -} -#endif - diff --git a/Utilities/IpFunc/VarROI.c b/Utilities/IpFunc/VarROI.c deleted file mode 100644 index 2e7b087d3c..0000000000 --- a/Utilities/IpFunc/VarROI.c +++ /dev/null @@ -1,263 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function calculates the variance of all pixels inside of a polygon - */ - -/** @brief calculates the variance of all pixels inside of a polygon - * - * The polygon is described by a sequence of points - * - * @param pic_old pointer to original image - * @param pol_x vector with the x-coordinates of the points which form - * form the roi - * @param pol_y vector with the y-coordinates of the points which form - * form the roi - * @param no_pts number of points used to describe ROI - * - * REMARKS - * this function could just be used for 2D images - * - * @return variance of all greyvalues in ROI - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpFloat8_t mitkIpFuncVarROI ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) ; - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncVarROI\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - -/*definition of macros */ - -#define MAX( x, y ) ( x > y ) ? x : y -#define MIN( x, y ) ( x < y ) ? x : y -#define ROI( type, pic, pic_help, sum, sum2, count ) \ -{ \ - mitkIpBool_t in; \ - mitkIpUInt4_t i, j; \ - mitkIpUInt4_t offset; \ - \ - for ( i = min_y; i <= max_y; i++ ) \ - { \ - in = mitkIpFalse; \ - offset = i * pic->n[0] + min_x; \ - for ( j = min_x; j <= max_x; j++ ) \ - { \ - if ( (( mitkIpUInt1_t * )pic_help->data )[offset] && ( !in ) ) \ - in = mitkIpTrue; \ - else if ( (( mitkIpUInt1_t * )pic_help->data )[offset] && ( in ) ) \ - { \ - in = mitkIpFalse; \ - sum2 = sum2 + ((( type * )pic->data )[offset] - sum) *\ - ((( type * )pic->data )[offset] - sum); \ - count++; \ - } \ - \ - if ( in ) \ - { \ - sum2 = sum2 + ((( type * )pic->data )[offset] - sum) *\ - ((( type * )pic->data )[offset] - sum) +\ - count++; \ - } \ - offset++; \ - } \ - } \ -} - -/* -** mitkIpFuncMeanROI -*/ - -mitkIpFloat8_t mitkIpFuncVarROI ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ) -{ - mitkIpFloat8_t var; /* variance of greyvalues in ROI */ - mitkIpFloat8_t sum=0; /* sum of greyvalues in ROI */ - mitkIpFloat8_t sum2=0; /* sum of squared greyvalues in ROI*/ - mitkIpFloat8_t *a, *b; /* Gerade y = ax+b */ - mitkIpPicDescriptor *pic_help; /* contains edge of ROI */ - mitkIpUInt4_t min_x, max_x; /* min, max x-coordinate of ROI */ - mitkIpUInt4_t min_y, max_y; /* min, max y-coordinate of ROI */ - mitkIpUInt4_t i; /* loop variable */ - mitkIpUInt4_t count=0; /* number of pixels in ROI */ - mitkIpFloat8_t diff; /* difference between two points */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( pic_old->dim > 2 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* calculate min. and max. coordiantes of ROI */ - - min_x = pol_x[0]; - min_y = pol_y[0]; - max_x = pol_x[0]; - max_y = pol_y[0]; - for ( i = 1; i < no_pts; i++ ) - { - min_x = MIN ( min_x, pol_x[i] ); - min_y = MIN ( min_y, pol_y[i] ); - max_x = MAX ( max_x, pol_x[i] ); - max_y = MAX ( max_y, pol_y[i] ); - } - - /* check whether ROI is in image */ - - /* Expression is always false. - if ( min_x < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - - if ( max_x > pic_old->n[0] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Expression is always false. - if ( min_y < 0 ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - */ - - if ( max_y > pic_old->n[1] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* allocate memory for a and b */ - - a = ( mitkIpFloat8_t * ) malloc ( no_pts * sizeof ( mitkIpFloat8_t ) ); - if ( !a ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - b = ( mitkIpFloat8_t * ) malloc ( no_pts * sizeof ( mitkIpFloat8_t ) ); - if ( !b ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* Geraden zwischen zwei benachbarten Punkten berechnen */ - - for ( i = 0; i < no_pts-1; i++ ) - { - diff = ( mitkIpFloat8_t ) pol_x[i+1] - ( mitkIpFloat8_t ) pol_x[i]; - if ( diff ) - { - a[i] = ( ( mitkIpFloat8_t ) pol_y[i+1] - ( mitkIpFloat8_t ) pol_y[i] ) / diff; - b[i] = ( ( mitkIpFloat8_t ) pol_y[i] - a[i] * ( mitkIpFloat8_t )pol_x[i] ); - } - else - { - b[i] = 0.; - a[i] = 0.; - } - } - diff = ( mitkIpFloat8_t ) pol_x[no_pts-1] - ( mitkIpFloat8_t ) pol_x[0]; - if ( diff ) - { - a[no_pts-1] = ( ( mitkIpFloat8_t ) pol_y[no_pts-1] - ( mitkIpFloat8_t ) pol_y[0] ) / diff; - b[no_pts-1] = ( pol_y[no_pts-1] - a[no_pts-1] * pol_x[no_pts-1] ); - } - else - { - b[no_pts-1] = 0.; - a[no_pts-1] = 0.; - } - - /* Function to calculate mean */ - - sum = mitkIpFuncMeanROI ( pic_old, pol_x, pol_y, no_pts ); - - /* draw polygon to image */ - - pic_help = _mitkIpFuncDrawPoly ( pic_old, pol_x, pol_y, no_pts, a, b ); - if ( !pic_help ) - { - free ( a ); - free ( b ); - return ( mitkIpFuncERROR ); - } - - mitkIpPicFORALL_4 ( ROI, pic_old, pic_help, sum, sum2, count ); - - if ( count == 1 ) - var = 0; - else - var = sum2 / ( count - 1 ); - - free ( a ); - free ( b ); - mitkIpPicFree ( pic_help ); - - return ( var ); - -} - -#endif - diff --git a/Utilities/IpFunc/Window.c b/Utilities/IpFunc/Window.c deleted file mode 100644 index 7266665371..0000000000 --- a/Utilities/IpFunc/Window.c +++ /dev/null @@ -1,204 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function copies a rectangular section of an image to a new one - */ - -/** @brief copies a rectangular section of an image to a new one - * - * @param pic_old pointer to the original image - * @param begin pointer to an array that contains the beginning of the - * section in each direction - * @param length pointer to an array that contains the length of the section - * in each direction - * - * @return pointer to the iamge with the section of the iamge - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncWindow ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* definition of macros */ - - -#define WIND( type, pic, beg, end, size ) \ -{ \ - mitkIpUInt4_t offset; /* offset of pixels in pic_new */ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - \ - offset = 0; \ - for ( ind[7] = beg[7] ; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6] ; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5] ; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4] ; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3] ; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2] ; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1] ; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1]+beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - (( type * ) pic_new->data )[offset] = \ - (( type * ) pic->data ) [off[0]]; \ - off[0]++; \ - offset++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncWindow ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t end[_mitkIpPicNDIM]; /* end of image */ - mitkIpUInt4_t beg[_mitkIpPicNDIM]; /* end of image */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - for ( i = 0; i < pic_old->dim; i++ ) - { - if ( begin[i] < 0 || begin[i] > pic_old->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - beg[i] = begin[i]; - end[i] = begin[i] + length[i]; - if ( length[i] < 0 || end[i] > pic_old->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - size[pic_old->dim] = 0; - - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - { - beg[i] = 0; - end[i] = 1; - } - - /* allocate image structure */ - - pic_new = mitkIpPicNew ( ); - - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - - pic_new->dim = pic_old->dim; - pic_new->type = pic_old->type; - pic_new->bpe = pic_old->bpe; - for ( i = 0; i < pic_new->dim; i++ ) - pic_new->n[i] = length[i]; - pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); - if ( pic_new->data == NULL ) - { - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - mitkIpPicFORALL_3 ( WIND, pic_old, beg, end, size ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - return ( pic_new ); -} - -#endif - diff --git a/Utilities/IpFunc/WindowR.c b/Utilities/IpFunc/WindowR.c deleted file mode 100644 index 6857acca5c..0000000000 --- a/Utilities/IpFunc/WindowR.c +++ /dev/null @@ -1,204 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function copies an image to a specified position in another image - */ - -/** @brief copies an image to a specified position in another image - * - * @param pic_1 pointer to the image into which @a pic_2 should be inserted - * @param pic_2 pointer to image that should be inserted - * @param begin pointer to an array that contains the position at which - * @a pic_2 ist inserted to @a pic_1 - * - * @return pointer to the new iamge - * - * AUTHOR & DATE - */ - -/* include files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncWindowR ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpUInt4_t *begin, - mitkIpFuncFlagI_t keep ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - - - -/* definition of macros */ - - -#define WINDR( type, pic, beg, end, size ) \ -{ \ - mitkIpUInt4_t offset; /* offset of pixels in pic_new */ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - \ - offset = 0; \ - for ( ind[7] = beg[7] ; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = beg[6] ; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = beg[5] ; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = beg[4] ; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = beg[3] ; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = beg[2] ; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = beg[1] ; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1]+beg[0]; \ - for ( ind[0] = beg[0]; ind[0] < end[0]; ind[0]++ ) \ - { \ - (( type * ) pic_new->data )[off[0]] = \ - (( type * ) pic->data ) [offset]; \ - off[0]++; \ - offset++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ -} - - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *mitkIpFuncWindowR ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpUInt4_t *begin, - mitkIpFuncFlagI_t keep ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpInt4_t i; /* loop index */ - mitkIpUInt4_t end[_mitkIpPicNDIM]; /* end of image */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - if ( pic_1->dim != pic_2->dim ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( pic_1->type != pic_2->type ) - { - _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( pic_1->bpe != pic_2->bpe ) - { - _mitkIpFuncSetErrno ( mitkIpFuncSIZE_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < pic_1->dim; i++ ) - { - if ( begin[i] < 0 || begin[i] > pic_1->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - end[i] = begin[i] + pic_2->n[i]; - if ( end[i] > pic_1->n[i] ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - } - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_1->n[i-1]; - size[pic_1->dim] = 0; - - - for ( i = pic_1->dim; i < _mitkIpPicNDIM; i++ ) - { - begin[i] = 0; - end[i] = 1; - } - - /* allocate image structure */ - - if ( keep == mitkIpFuncKeep ) - pic_new = mitkIpPicClone ( pic_1 ); - else - pic_new = pic_1; - - mitkIpPicFORALL_3 ( WINDR, pic_2, begin, end, size ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_1); - - return ( pic_new ); -} -#endif - diff --git a/Utilities/IpFunc/Xchange.c b/Utilities/IpFunc/Xchange.c deleted file mode 100644 index 954529c7ee..0000000000 --- a/Utilities/IpFunc/Xchange.c +++ /dev/null @@ -1,116 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * exchange of two image buffers - */ - -/** exchange of two image buffers - * - * @param pic1 pointer to pic descriptor - * @param pic2 pointer to pic descriptor - * - * - * @author Ulrike Guennel @date 07.7.1995 - * - * $Log$ - * Revision 1.3 2003/08/21 08:44:44 tobiask - * Removed warnings. - * - * Revision 1.2 2000/05/24 15:29:43 tobiask - * Changed the installation paths of the package. - * - * Revision 1.4 2000/05/04 12:52:11 ivo - * inserted BSD style license - * - * Revision 1.3 2000/04/04 11:57:10 ivo - * no message - * - * Revision 1.2 2000/02/18 14:58:09 ivo - * Tags are now copied into newly allocated images. - * Bugs fixed in mitkIpFuncFrame, mitkIpFuncRegGrow, _mitkIpFuncBorderX and mitkIpFuncHitMiss. - * - * Revision 1.1.1.1 1998/07/16 12:04:50 antje - * initial import - * - * Revision 1.1 1995/03/07 17:01:02 uli - * Initial revision - * - */ - - - /* -** ipFunc includefiles -*/ -#include "mitkIpFuncP.h" - -void mitkIpFuncXchange( mitkIpPicDescriptor **pic1, - mitkIpPicDescriptor **pic2 ); - -#ifndef DOXYGEN_IGNORE - -#ifndef lint - static char *what = { "@(#)mitkIpFuncXchange\tGerman Cancer Research Center (DKFZ) $Revision$ "__DATE__ }; -#endif - - -/* -** private macros -*/ - - -/* -** the action starts here -*/ -void mitkIpFuncXchange( mitkIpPicDescriptor **pic1, - mitkIpPicDescriptor **pic2 ) - -{ - - mitkIpPicDescriptor *tmp_pic; - - tmp_pic = *pic1; - *pic1 = *pic2; - *pic2 = tmp_pic; - - return; -} -#endif - diff --git a/Utilities/IpFunc/ZeroCr.c b/Utilities/IpFunc/ZeroCr.c deleted file mode 100644 index 16cbe59f43..0000000000 --- a/Utilities/IpFunc/ZeroCr.c +++ /dev/null @@ -1,201 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/**@file - * this function detects zero-crossings - */ - -/** @brief detects zero-crossings - * - * @param pic_old pointer to the image that should be transformed - * - * @return pointer to the transformed image - * - * AUTHOR & DATE - */ - -/* include-Files */ - -#include "mitkIpFuncP.h" - -mitkIpPicDescriptor *mitkIpFuncZeroCr ( mitkIpPicDescriptor *pic_old ) ; - -#ifndef DOXYGEN_IGNORE - -/* definition of macros */ - -#define ZERO( type, pic, size, off, n ) \ -{ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; \ - mitkIpUInt4_t i, j; \ - mitkIpInt4_t offset; \ - type help1, help2, help3, help; \ - \ - /* test whether there is a zero crossing in each direction */ \ - \ - for ( ind[7] = 1; ind[7] < n[7]; ind[7]++ ) \ - for ( ind[6] = 1; ind[6] < n[6]; ind[6]++ ) \ - for ( ind[5] = 1; ind[5] < n[5]; ind[5]++ ) \ - for ( ind[4] = 1; ind[4] < n[4]; ind[4]++ ) \ - for ( ind[3] = 1; ind[3] < n[3]; ind[3]++ ) \ - for ( ind[2] = 1; ind[2] < n[2]; ind[2]++ ) \ - for ( ind[1] = 1; ind[1] < n[1]; ind[1]++ ) \ - for ( ind[0] = 1; ind[0] < n[0]; ind[0]++ ) \ - { \ - offset = 0; \ - for ( i = 0; i < pic->dim; i++ ) \ - offset = offset + size[i] * ind[i]; \ - \ - i = 0; \ - help = (( type * )pic_new->data )[offset]; \ - help2 = ((type *)pic->data)[offset]; \ - while ( help == 0 && i < pic->dim ) \ - { \ - j = 2 * i; \ - help1 = ((type *)pic->data)[offset + off[j]];\ - help3 = ((type *)pic->data)[offset+off[j+1]];\ - \ - if ( help1 < 0 && help3 > 0 ) \ - { \ - if ( help2 > 0 && (help1 + help2) <=0 ) \ - help = ( type ) 1; \ - else if ( help2<=0 && (help2+help3) >0 )\ - help = ( type ) 1; \ - } \ - else if ( help1 > 0 && help3 < 0 ) \ - { \ - if ( help2 >= 0 && (help2 + help3) <0 ) \ - help = ( type ) 1; \ - else if ( help2<0 && (help1+help2) >=0 )\ - help = ( type ) 1; \ - } \ - i++; \ - } \ - (( type * )pic_new->data )[offset] = help; \ - \ - } \ -} - - - -/* ------------------------------------------------------------------- */ -/* -*/ -/* ------------------------------------------------------------------- */ - -mitkIpPicDescriptor *mitkIpFuncZeroCr ( mitkIpPicDescriptor *pic_old ) -{ - - mitkIpPicDescriptor *pic_new; /* convoluted image */ - mitkIpUInt4_t i, j; /* loopindex */ - mitkIpInt4_t size[_mitkIpPicNDIM]; - mitkIpUInt4_t n[_mitkIpPicNDIM]; - mitkIpInt4_t *off_vekt; /* offset vector */ - - /* check image data */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - /* initialisation of vectors */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_old->n[i-1]; - - for ( i = 0; i < pic_old->dim; i++ ) - n[i] = pic_old->n[i] - 1; - - for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ ) - n[i] = 2; - - /* allocate and calculate offset vector */ - - off_vekt = malloc ( 2 * pic_old->dim * sizeof ( mitkIpInt4_t ) ); - if ( off_vekt == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - for ( i = 0; i < pic_old->dim; i++ ) - { - j = 2 * i; - off_vekt[j] = - size[i]; - off_vekt[j+1] = size[i]; - } - - - /* create a new picture, copy the header, allocate memory */ - - pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); - if ( pic_new == NULL ) - { - free ( off_vekt ); - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - free ( off_vekt ); - return ( mitkIpFuncERROR ); - } - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe/8 ); - if ( pic_new->data == NULL ) - { - free ( off_vekt ); - mitkIpPicFree ( pic_new ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - free ( off_vekt ); - return ( mitkIpFuncERROR ); - } - - - /* macro to convolute an image (for all data types) */ - - mitkIpPicFORALL_3 ( ZERO, pic_old, size, off_vekt, n ); - - free ( off_vekt ); - - /* Copy Tags */ - - mitkIpFuncCopyTags(pic_new, pic_old); - - - - - return pic_new; -} -#endif diff --git a/Utilities/IpFunc/_BorderX.c b/Utilities/IpFunc/_BorderX.c deleted file mode 100644 index a797a3f39f..0000000000 --- a/Utilities/IpFunc/_BorderX.c +++ /dev/null @@ -1,258 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * mitkIpFuncBorder - *--------------------------------------------------------------------- - * DESCRIPTION - * - * FUNCTION DECLARATION - * - * PARAMETERS - * - * RETURN VALUES - * - * AUTHOR & DATE - * Antje Schroeder 27.07.95 - * - * UPDATES - * $Log$ - * Revision 1.4 2000/08/02 20:09:05 tobiask - * Made some corrections in _BorderX.c - * - * Revision 1.3 2000/07/24 13:06:26 ivo - * June 26, 2000 - * iw - function mitkIpFuncSetTag added. - * - * July 8, 2000 - * iw - Visual C++ 6.0 SP3 compiler crashes at "static char *what..." lines. - * Workaround: "lint" defined in project files for all configurations. - * - * July 11, 2000 - * iw - ipFunc.exe Scale crashed, if last parameter was missing. Corrected. - * - * Revision 1.2 2000/05/24 15:29:44 tobiask - * Changed the installation paths of the package. - * - * Revision 1.3 2000/05/04 12:52:11 ivo - * inserted BSD style license - * - * Revision 1.2 2000/02/18 14:58:09 ivo - * Tags are now copied into newly allocated images. - * Bugs fixed in mitkIpFuncFrame, mitkIpFuncRegGrow, _mitkIpFuncBorderX and mitkIpFuncHitMiss. - * - * Revision 1.1.1.1 2000/02/18 15:40:34 ivo - * the dimension sizes n[i] that are not used must be set to zero, - * otherwise the macro BORDER may crash. This is now done in the else- - * part of "if ( pic_new == NULL )" (first two rows). - * - *--------------------------------------------------------------------- - */ -#ifndef lint - static char *what = { "@(#)????????\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - -#include "mitkIpFuncP.h" - -/* definition of macros */ - - -#define BORDER( type, pic, size, value ) \ -{ \ - mitkIpUInt4_t i; /* loop index */ \ - mitkIpUInt4_t anf[_mitkIpPicNDIM]; /* */ \ - mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ \ - mitkIpUInt4_t off[_mitkIpPicNDIM]; /* used to calculate offset of image pixels */ \ - \ - \ - for ( i = 0; i < pic->dim; i++ ) \ - { \ - anf[i] = 0; \ - end[i] = pic->n[i]; \ - } \ - for ( i = pic->dim; i < _mitkIpPicNDIM; i++ ) \ - { \ - anf[i] = 0; \ - end[i] = 1; \ - pic->n[i] = 1; \ - } \ - for ( i = 0; i < pic->dim; i++ ) \ - { \ - anf[i] = pic->n[i] - edge[i]; \ - end[i] = edge[i]; \ - for ( ind[7] = 0; ind[7] < end[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = 0; ind[6] < end[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = 0; ind[5] < end[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = 0; ind[4] < end[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = 0; ind[3] < end[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = 0; ind[2] < end[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = 0; ind[1] < end[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - for ( ind[0] = 0; ind[0] < end[0]; ind[0]++ ) \ - { \ - (( type * ) pic_new->data )[off[1]] = ( type ) value; \ - off[1]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - for ( ind[7] = anf[7]; ind[7] < pic->n[7]; ind[7]++ ) \ - { \ - off[7] = size[7] * ind[7]; \ - for ( ind[6] = anf[6]; ind[6] < pic->n[6]; ind[6]++ ) \ - { \ - off[6] = size[6] * ind[6] + off[7]; \ - for ( ind[5] = anf[5]; ind[5] < pic->n[5]; ind[5]++ ) \ - { \ - off[5] = size[5] * ind[5] + off[6]; \ - for ( ind[4] = anf[4]; ind[4] < pic->n[4]; ind[4]++ ) \ - { \ - off[4] = size[4] * ind[4] + off[5]; \ - for ( ind[3] = anf[3]; ind[3] < pic->n[3]; ind[3]++ ) \ - { \ - off[3] = size[3] * ind[3] + off[4]; \ - for ( ind[2] = anf[2]; ind[2] < pic->n[2]; ind[2]++ ) \ - { \ - off[2] = size[2] * ind[2] + off[3]; \ - for ( ind[1] = anf[1]; ind[1] < pic->n[1]; ind[1]++ ) \ - { \ - off[1] = size[1] * ind[1] + off[2]; \ - off[0] = off[1] + anf[0]; \ - for ( ind[0] = anf[0]; ind[0] < pic->n[0]; ind[0]++ ) \ - { \ - (( type * ) pic_new->data )[off[0]] = ( type ) value; \ - off[0]++; \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - end[i] = pic->n[i]; \ - anf[i] = 0; \ - } \ -} - -/* ------------------------------------------------------------------------------ */ -/* -*/ -/* ------------------------------------------------------------------------------ */ - -mitkIpPicDescriptor *_mitkIpFuncBorderX ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *edge, - mitkIpFloat8_t value ) -{ - mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ - mitkIpUInt4_t i; /* loop index */ - mitkIpUInt4_t end[_mitkIpPicNDIM]; /* end of image */ - mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ - mitkIpFloat8_t max_gv, min_gv; - - /* check whether data are correct */ - - if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); - - pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_new == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - else - { - for ( i = pic_new->dim; i < _mitkIpPicNDIM; i++ ) - pic_new->n[i] = 0; - - for ( i = 0; i < pic_old->dim; i++ ) - pic_new->n[i] = pic_old->n[i] + 2 * edge[i]; - pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe/8 ); - if ( pic_new->data == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - mitkIpPicFree ( pic_new ); - return ( mitkIpFuncERROR ); - } - } - - - if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - if ( ( value > max_gv ) || ( value < min_gv ) ) - { - _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); - return ( mitkIpFuncERROR ); - } - - - /* initialize vectors and variables */ - - size[0] = 1; - for ( i = 1; i < _mitkIpPicNDIM; i++ ) - size[i] = size[i-1] * pic_new->n[i-1]; - size[pic_new->dim] = 0; - - mitkIpPicFORALL_2 ( BORDER, pic_new, size, value ) - - return ( pic_new ); -} diff --git a/Utilities/IpFunc/_DrawPoly.c b/Utilities/IpFunc/_DrawPoly.c deleted file mode 100644 index dedc848416..0000000000 --- a/Utilities/IpFunc/_DrawPoly.c +++ /dev/null @@ -1,278 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * - *--------------------------------------------------------------------- - * DESCRIPTION - * this function draws the edge of an ROI to an image - * - * FUNCTION DECLARATION - * mitkIpPicDescriptor *_mitkIpFuncDrawPoly( mitkIpPicDescriptor *pic_old, - * mitkIpUInt4_t *pol_x, - * mitkIpUInt4_t *pol_y, - * mitkIpUInt4_t no_pts, - * mitkIpFloat8_t *a, - * mitkIpFloat8_t *b); - * - * PARAMETERS - * pic_old - pointer to original image - * pol_x - vector with the x-coordinates of the points which form - * form the roi - * pol_y - vector with the y-coordinates of the points which form - * form the roi - * no_pts - number of points used to describe ROI - * a - - * b - - * - * REMARKS - * this function could just be used for 2D images - * - * RETURN VALUES - * pic_help - image with roi - * - * AUTHOR & DATE - * Antje Schroeder 08.11.95 - * - * UPDATES - * a short history of the file - * - *--------------------------------------------------------------------- - */ -#ifndef lint - static char *what = { "@(#)_mitkIpFuncDrawPoly\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__ }; -#endif - -/* include files */ - -#include "mitkIpFuncP.h" - - -/* -------------------------------------------------------------------- */ - -/* -** mitkIpFuncDrawPoly -*/ - -mitkIpPicDescriptor *_mitkIpFuncDrawPoly ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts, - mitkIpFloat8_t *a, - mitkIpFloat8_t *b ) -{ - - mitkIpPicDescriptor *pic_help; - mitkIpUInt4_t i, j; - mitkIpUInt4_t y; - mitkIpUInt4_t beg, end; - - /* allocate memory for pic help */ - - pic_help = mitkIpPicCopyHeader ( pic_old, NULL ); - if ( pic_help == NULL ) - { - _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); - return ( mitkIpFuncERROR ); - } - pic_help->type = mitkIpPicUInt; - pic_help->bpe = 8; - pic_help->data = calloc ( _mitkIpPicElements ( pic_help ), pic_help->bpe / 8 ); - if ( pic_help->data == NULL ) - { - mitkIpPicFree ( pic_help ); - _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); - return ( mitkIpFuncERROR ); - } - - /* draw polygon to pic_help */ - - for ( i = 0; i < no_pts-1; i++ ) - { - if ( pol_x[i] == pol_x[i+1] ) - { - if ( pol_y[i] < pol_y[i+1] ) - { - beg = pol_y[i]; - end = pol_y[i+1]; - } - else - { - end = pol_y[i]; - beg = pol_y[i+1]; - } - for ( j = beg; j < end; j++ ) - (( mitkIpUInt1_t * )pic_help->data )[ j * pic_help->n[1] + pol_x[i]] = 100; - } - else - { - if ( pol_x[i] < pol_x[i+1] ) - { - beg = pol_x[i]; - end = pol_x[i+1]; - } - else - { - end = pol_x[i]; - beg = pol_x[i+1]; - } - if ( pol_y[i] == pol_y[i+1] ) end = beg -1; - - for ( j = beg; j <= end; j++ ) - { - y = a[i] * j + b[i]; - (( mitkIpUInt1_t * )pic_help->data )[ y * pic_help->n[1] + j ] = 100; - } - } - - if ( pol_y[i] == pol_y[i+1] ) - { - if ( pol_x[i] < pol_x[i+1] ) - { - beg = pol_x[i]; - end = pol_x[i+1]; - } - else - { - end = pol_x[i]; - beg = pol_x[i+1]; - } - - for ( j = beg; j < end; j++ ) - (( mitkIpUInt1_t * )pic_help->data )[ j + pic_help->n[1] * pol_y[i]] = 100; - } - else - { - if ( pol_y[i] < pol_y[i+1] ) - { - beg = pol_y[i]; - end = pol_y[i+1]; - } - else - { - end = pol_y[i+1]; - beg = pol_y[i]; - } - if ( pol_x[i] == pol_x[i+1] ) end = beg - 1; - - for ( j = beg; j <= end; j++ ) - { - y = ( j - b[i] ) / a[i]; - (( mitkIpUInt1_t * )pic_help->data )[ j * pic_help->n[1] + y ] = 100; - } - } - } - - if ( pol_x[no_pts-1] == pol_x[0] ) - { - if ( pol_y[no_pts-1] < pol_y[0] ) - { - beg = pol_y[no_pts-1]; - end = pol_y[0]; - } - else - { - end = pol_y[no_pts-1]; - beg = pol_y[0]; - } - - for ( j = beg; j < end; j++ ) - (( mitkIpUInt1_t * )pic_help->data )[ j * pic_help->n[1] + pol_x[no_pts-1]] = 100; - } - else - { - if ( pol_x[no_pts-1] < pol_x[0] ) - { - beg = pol_x[no_pts-1]; - end = pol_x[0]; - } - else - { - end = pol_x[no_pts-1]; - beg = pol_x[0]; - } - if ( pol_y[no_pts-1] == pol_y[0] ) end = beg -1; - - for ( j = beg; j <= end; j++ ) - { - y = a[no_pts-1] * j + b[no_pts-1]; - (( mitkIpUInt1_t * )pic_help->data )[ y * pic_help->n[1] + j ] = 100; - } - } - - if ( pol_y[no_pts-1] == pol_y[0] ) - { - if ( pol_x[no_pts-1] < pol_x[0] ) - { - beg = pol_x[no_pts-1]; - end = pol_x[0]; - } - else - { - end = pol_x[no_pts-1]; - beg = pol_x[0]; - } - - for ( j = beg; j < end; j++ ) - (( mitkIpUInt1_t * )pic_help->data )[ j + pic_help->n[1] * pol_y[no_pts-1]] = 100; - } - else - { - if ( pol_y[no_pts-1] < pol_y[0] ) - { - beg = pol_y[no_pts-1]; - end = pol_y[0]; - } - else - { - end = pol_y[no_pts-1]; - beg = pol_y[0]; - } - if ( pol_x[no_pts-1] == pol_x[0] ) end = beg - 1; - - for ( j = beg; j <= end; j++ ) - { - y = ( j - b[no_pts-1] ) / a[no_pts-1]; - (( mitkIpUInt1_t * )pic_help->data )[ j * pic_help->n[1] + y ] = 100; - } - } - - return ( pic_help ); -} diff --git a/Utilities/IpFunc/files.cmake b/Utilities/IpFunc/files.cmake deleted file mode 100644 index 150cad0e15..0000000000 --- a/Utilities/IpFunc/files.cmake +++ /dev/null @@ -1,32 +0,0 @@ -set(CPP_FILES - AddC.c - AddI.c - AddSl.c - And.c - Border.c - BorderX.c - Box.c - Box2d.c - Box3d.c - Canny.c - Close.c - CompressM.c - Conv.c - Convert.c - CopyTags.c - Curtosis.c - CurtosisR.c - Dila.c - DivC.c - DivI.c - DrawPoly.c - Equal.c - Ero.c - Error.c - Exp.c - ExtT.c - ExtrC.c - ExtrR.c - ExtrROI.c Extrema.c FillArea.c Frame.c GaussF.c Grad.c Grav.c Hist.c Histo.c HitMiss.c HitMissI.c Inertia.c Inv.c LN.c Label.c Laplace.c LevWind.c Log.c MakePicName.c Malloc.c Mean.c MeanC.c MeanF.c MeanR.c MeanROI.c Median.c Morph.c MultC.c MultI.c Norm.c NormXY.c Not.c OpCl.c Open.c Or.c Pot.c Range.c Rank.c Refl.c RegGrow.c Roberts.c Rotate.c SDev.c SDevC.c SDevR.c SDevROI.c ScBl.c ScFact.c ScNN.c Scale.c SelInv.c SelMM.c Select.c SetErrno.c SetTag.c Shp.c Skewness.c SkewnessR.c Sobel.c Sqrt.c SubC.c SubI.c Thresh.c Transpose.c Var.c VarC.c VarR.c VarROI.c Window.c WindowR.c Xchange.c ZeroCr.c _BorderX.c _DrawPoly.c ipGetANew.c - ) - diff --git a/Utilities/IpFunc/gradient.h b/Utilities/IpFunc/gradient.h deleted file mode 100644 index a4e348bfda..0000000000 --- a/Utilities/IpFunc/gradient.h +++ /dev/null @@ -1,97 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - mitkIpInt2_t mask2[] = - { 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1 }; - - mitkIpInt2_t mask3[] = - { 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, -1, -1, -1, -1, -1, -1, -1, -1 }; - -mitkIpInt2_t mask4[] = - { 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - 1, 1, 1, 0, 0, 0, -1, -1, -1, - - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - 1, 0, -1, 1, 0, -1, 1, 0, -1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, -1, -1, -1, -1, -1, -1, -1, -1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1 }; diff --git a/Utilities/IpFunc/ipAdministrative.h b/Utilities/IpFunc/ipAdministrative.h deleted file mode 100644 index e6b4eb3921..0000000000 --- a/Utilities/IpFunc/ipAdministrative.h +++ /dev/null @@ -1,80 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * Administrative Functions - * This header is for grouping purposes for the - * documentation only. Don't use it, use mitkIpFunc.h instead. - */ - -#ifndef DOXYGEN_IGNORE -#include <mitkIpFunc.h> -#endif - -#ifndef _mitkIpFunc_h -#define _mitkIpFunc_h - -/* function prototypes */ - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -char *mitkIpFuncMakePicName ( char *pic_name, char *extension ); - -void mitkIpFuncCopyTags(mitkIpPicDescriptor *pic_new, mitkIpPicDescriptor *pic_old); - -mitkIpPicDescriptor *mitkIpFuncConvert( mitkIpPicDescriptor *pic_old, - mitkIpPicType_t type, - mitkIpUInt4_t bpe ); - -void mitkIpFuncXchange ( mitkIpPicDescriptor **pic1, - mitkIpPicDescriptor **pic2 ); - -void mitkIpFuncPError ( char *string ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpFunc_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpFunc/ipArithmeticAndLogical.h b/Utilities/IpFunc/ipArithmeticAndLogical.h deleted file mode 100644 index d4a8cb41cd..0000000000 --- a/Utilities/IpFunc/ipArithmeticAndLogical.h +++ /dev/null @@ -1,128 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * Arithmetic and Logical Operators. - * This header is for grouping purposes for the - * documentation only. Don't use it, use mitkIpFunc.h instead. - */ - -#ifndef DOXYGEN_IGNORE -#include <mitkIpFunc.h> -#endif - -#ifndef _mitkIpFunc_h -#define _mitkIpFunc_h - -/* function prototypes */ - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -mitkIpPicDescriptor *mitkIpFuncInv ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncEqual ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncAddC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSubC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncMultC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncDivC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncMultI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncDivI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncAddI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncAddSl ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t keep ); - -mitkIpPicDescriptor *mitkIpFuncSubI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncAnd ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncOr ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncNot ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpFunc_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpFunc/ipFunc.c b/Utilities/IpFunc/ipFunc.c deleted file mode 100644 index df281b7aa0..0000000000 --- a/Utilities/IpFunc/ipFunc.c +++ /dev/null @@ -1,1366 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* include files */ - -#include "mitkIpFuncP.h" - -#ifdef _WIN32 -#define strcasecmp _stricmp -#define PATH_MAX 255 -#endif - -/* main function */ - -int -main (int argc, char **argv) -{ - /* variables */ - - mitkIpPicDescriptor *pic_new=NULL; /* image descriptors */ - mitkIpPicDescriptor *pic_ret=NULL; /* image descriptors */ - mitkIpPicDescriptor *pic_hlp=NULL; /* image descriptors */ - mitkIpPicDescriptor *pic_old=NULL; /* image descriptors */ - mitkIpPicDescriptor *pic_mask=NULL; /* convolution mask */ - mitkIpPicDescriptor *mask_1=NULL, *mask_2=NULL; /* convolution mask */ - char operation[PATH_MAX]; /* image processing operation */ - char pic_name[PATH_MAX]; /* file name of original image */ - char pic_name_t[PATH_MAX]; /* file name of transformed im. */ - char mask_name[PATH_MAX]; /* file name of transformed im. */ - char error_nr[PATH_MAX]; /* file name of transformed im. */ - mitkIpPicType_t type; - mitkIpUInt4_t range; /* result of range function */ - mitkIpUInt4_t no_label; - mitkIpUInt4_t border; /* handling of the borders */ - mitkIpUInt4_t rank; /* */ - mitkIpUInt4_t keep; /* */ - mitkIpUInt4_t radius; /* */ - mitkIpUInt4_t *begin; /* start of window */ - mitkIpUInt4_t *length; /* length of window */ - mitkIpUInt4_t len_mask; /* length of mask */ - mitkIpUInt4_t dim_mask; /* dimension of mask */ - mitkIpInt4_t axis; /* reflection axis */ - mitkIpUInt4_t i; - mitkIpFloat8_t min, max; /* extreme greyvalues */ - mitkIpFloat8_t min_gv, max_gv; /* extreme greyvalues */ - mitkIpFloat8_t gv_low, gv_up; /* */ - mitkIpFloat8_t threshold; - mitkIpFloat8_t value; /* value that is added to image */ - mitkIpFloat8_t mean; /* mean greyvalue */ - mitkIpFloat8_t var; /* variance of greyvalues */ - mitkIpFloat8_t gv; /* new greyvalue */ - mitkIpFloat8_t s_der; /* standard derivation */ - mitkIpFloat8_t *sc; /* standard derivation */ - int *perm; /* permutation vector for transpose */ - mitkIpFloat8_t *grav; /* center of gravity */ - mitkIpFloat8_t *inertia, *ev; - mitkIpUInt4_t *hist; /* greylevel histogram */ - mitkIpUInt4_t size_hist; /* no. of elements in histogram */ - mitkIpUInt4_t mask_size; /* size of transformation mask */ - mitkIpBool_t picput_flag=mitkIpTrue; /* */ - int *grad, *order; - - /* input of operation and image file name */ - - - if ( ((unsigned int) argc == 1) || ( ((unsigned int) argc == 2 ) && (strcasecmp (argv[1], "-h") == 0))) - { - printf("Usage: ipFunc operation infile outfile parameterlist\n"); - printf(" Arithmetic: AddC, AddI, DivC, DivI, MultC, MultI, SubC, SubI\n"); - printf(" Logic: And, Not, Or\n"); - printf(" Geometric: Refl, Rotate, Scale, Transpose, Window, WindowR\n"); - printf(" Point: Equal, Exp, Inv, LevWin, LN, Log, Norm, NormY\n"); - printf(" Pot, Select, SelInv, SelMM, Sqrt, Thresh, ZeroCr\n"); - printf(" Locale: Canny, Conv, GaussF, Grad, Laplace, Mean\n"); - printf(" Rank, Roberts, Shp, Sobel\n"); - printf(" Morpho: Close, Dila, Ero, Open\n"); - printf(" Statistic: Extr, ExtrC, ExtrR, ExtrROI, Mean, MeanC, MeanR\n"); - printf(" MeanROI, Median, SDev, SDevC, SDevR, SDevROI\n"); - printf(" Var, VarC, VarR, VarROI\n"); - printf(" Segmentation: Label, RegGrow\n"); - printf(" Misc: Border, BorderX, DrawPoly, Frame, Convert, MakeMorphSquareMask\n"); - exit(1); - } - - strcpy ( operation , argv[1]); - if( ((unsigned int) argc != 2) && (strcasecmp (argv[2], "-h") != 0)) - { - strcpy ( pic_name, argv[2]); - pic_old = mitkIpPicGet ( pic_name, NULL ); - pic_ret = pic_old; - if ( pic_old == NULL ) - { - printf("could not open file\n"); - exit(1); - } - } - if ( strcasecmp ( operation, "Inv" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " usage: ipFunc Inv infile outfile \n" ); - exit ( 1 ); - } - pic_new = mitkIpFuncInv ( pic_old, pic_ret ); - } - else if ( strcasecmp ( operation, "Label" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc Label infile outfile \n" ); - exit ( 1 ); - } - pic_new = mitkIpFuncLabel ( pic_old, &no_label ); - printf ("Number of Labels: %d \n", no_label ); - } - else if ( strcasecmp ( operation, "RegGrow" ) == 0 ) - { - mitkIpUInt4_t blabel, rlabel, kind; - - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != pic_old->dim * 2 + 8 ) ) - { - printf ( " usage: ipFunc RegGrow infile outfile beg_seed1...beg_seedn end_seed1...end_seedn border_label region_label std_dev_factor(double!!) kind(0=show border,1=show region)\n" ); - exit ( 1 ); - } - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+pic_old->dim+i], "%d", &length[i] ); - printf ( " %d %d %d %d %d %d \n", begin[0], begin[1], begin[2], length[0], length[1], length[2] ); - - sscanf ( argv[4+pic_old->dim*2], "%d", &blabel ); - sscanf ( argv[5+pic_old->dim*2], "%d", &rlabel ); - s_der=atof(argv[6+pic_old->dim*2]); - sscanf ( argv[7+pic_old->dim*2], "%d", &kind ); - - pic_new = mitkIpFuncRegGrow ( pic_old, pic_old->dim, begin, length, blabel, rlabel, s_der, kind ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "Convert" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0) ) || - ( (unsigned int) argc != 6 ) ) - { - printf("Usage: ipFunc convert infile outfile type bpe \n"); - printf("type must be given as number\n"); - printf("type: mitkIpPicInt = 3\n"); - printf(" mitkIpPicUInt = 4\n"); - printf(" mitkIpPicFloat = 5\n"); - exit(1); - } - sscanf ( argv[4],"%d", &rank ); - sscanf ( argv[5],"%d", &range ); - type = rank; - pic_new = mitkIpFuncConvert ( pic_old, rank, range ); - } - else if ( strcasecmp ( operation, "Refl" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Refl infile outfile axis \n"); - printf("axis must be given as number\n"); - printf(" x-axis = 0\n"); - printf(" y-axis = 1\n"); - printf(" z-axis = 2\n"); - exit(1); - } - sscanf ( argv[4], "%d", &axis ); - pic_new = mitkIpFuncRefl ( pic_old, axis ); - } - else if ( strcasecmp ( operation, "Sqrt" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc Sqrt infile outfile \n" ); - exit ( 1 ); - } - keep = mitkIpFuncKeep; - pic_new = mitkIpFuncSqrt ( pic_old, keep, pic_ret ); - } - else if ( strcasecmp ( operation, "Pot" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Pot infile outfile exponent \n"); - exit(1); - } - keep = mitkIpFuncKeep; - sscanf ( argv[4], "%lf", &value ); - pic_new = mitkIpFuncPot ( pic_old, value, keep, pic_ret ); - printf ( " Fehler : %d \n", mitkIpFuncErrno ); - } - else if ( strcasecmp ( operation, "DivC" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc DivC infile outfile value \n"); - exit(1); - } - keep = mitkIpFuncKeep; - sscanf ( argv[4], "%lf", &value ); - pic_new = mitkIpFuncDivC ( pic_old, value, keep, pic_ret ); - } - else if ( strcasecmp ( operation, "MultC" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc MultC infile outfile value \n"); - exit(1); - } - keep = mitkIpFuncKeep; - sscanf ( argv[4], "%lf", &value ); - pic_new = mitkIpFuncMultC ( pic_old, value, keep, pic_ret ); - } - else if ( strcasecmp ( operation, "SubC" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc SubC infile outfile value \n"); - exit(1); - } - keep = mitkIpFuncKeep; - sscanf ( argv[4], "%lf", &value ); - pic_new = mitkIpFuncSubC ( pic_old, value, keep, pic_ret ); - } - else if ( strcasecmp ( operation, "AddC" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc AddC infile outfile value \n"); - exit(1); - } - keep = mitkIpFuncKeep; - sscanf ( argv[4], "%lf", &value ); - pic_new = mitkIpFuncAddC ( pic_old, value, keep, pic_ret ); - } - else if ( strcasecmp ( operation, "AddSl" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 ) ) - { - printf("Usage: ipFunc AddSl infile outfile \n"); - exit(1); - } - keep = mitkIpFuncKeep; - pic_new = mitkIpFuncAddSl ( pic_old, keep ); - } - else if ( strcasecmp ( operation, "DivI" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc DivI infile outfile image \n"); - exit(1); - } - keep = mitkIpFuncKeep; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_hlp = mitkIpPicGet ( mask_name, NULL ); - if ( pic_hlp != NULL ) - pic_new = mitkIpFuncDivI ( pic_old, pic_hlp, keep, pic_ret ); - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "MultI" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc MultI infile outfile image \n"); - exit(1); - } - keep = mitkIpFuncKeep; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_hlp = mitkIpPicGet ( mask_name, NULL ); - if ( pic_hlp != NULL ) - pic_new = mitkIpFuncMultI ( pic_old, pic_hlp, keep, pic_ret ); - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "AddI" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc AddI infile outfile image \n"); - exit(1); - } - keep = mitkIpFuncKeep; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_hlp = mitkIpPicGet ( mask_name, NULL ); - if ( pic_hlp != NULL ) - pic_new = mitkIpFuncAddI ( pic_old, pic_hlp, keep, pic_ret ); - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "SubI" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc SubI infile outfile image \n"); - exit(1); - } - keep = mitkIpFuncKeep; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_hlp = mitkIpPicGet ( mask_name, NULL ); - if ( pic_hlp != NULL ) - pic_new = mitkIpFuncSubI ( pic_old, pic_hlp, keep, pic_ret ); - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "Or" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Or infile outfile image \n"); - exit(1); - } - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_hlp = mitkIpPicGet ( mask_name, NULL ); - if ( pic_hlp != NULL ) - pic_new = mitkIpFuncOr ( pic_old, pic_hlp, pic_ret ); - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "And" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc And infile outfile image \n"); - exit(1); - } - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_hlp = mitkIpPicGet ( mask_name, NULL ); - if ( pic_hlp != NULL ) - pic_new = mitkIpFuncAnd ( pic_old, pic_hlp, pic_ret ); - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "Not" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc Not infile outfile \n" ); - exit ( 1 ); - } - pic_new = mitkIpFuncNot ( pic_old, NULL ); - } - else if ( strcasecmp ( operation, "Close" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Close infile outfile mask \n"); - printf(" mask must be the name of a PIC-file containing the mask \n" ); - exit(1); - } - border = mitkIpFuncBorderZero; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_mask = mitkIpPicGet ( mask_name, NULL ); - mitkIpPicPut ( "Test.mask", pic_mask ); - if ( pic_mask != NULL ) - { - pic_new = mitkIpFuncClose( pic_old, pic_mask, border ); - mitkIpPicFree ( pic_mask ); - } - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "Open" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Open infile outfile mask \n"); - printf(" mask must be the name of a PIC-file containing the mask \n" ); - exit(1); - } - border = mitkIpFuncBorderZero; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_mask = mitkIpPicGet ( mask_name, NULL ); - if ( pic_mask != NULL ) - { - pic_new = mitkIpFuncOpen ( pic_old, pic_mask, border ); - mitkIpPicFree ( pic_mask ); - } - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "Dila" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Dila infile outfile mask \n"); - printf(" mask must be the name of a PIC-file containing the mask \n" ); - exit(1); - } - border = mitkIpFuncBorderZero; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_mask = mitkIpPicGet ( mask_name, NULL ); - if ( pic_mask != NULL ) - { - pic_new = mitkIpFuncDila ( pic_old, pic_mask, border ); - mitkIpPicFree ( pic_mask ); - } - else - printf ( " iamge doesn't exist \n" ); - } - else if ( strcasecmp ( operation, "Ero" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Ero infile outfile mask \n"); - printf(" mask must be the name of a PIC-file containing the mask \n" ); - exit(1); - } - border = mitkIpFuncBorderZero; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_mask = mitkIpPicGet ( mask_name, NULL ); - if ( pic_mask != NULL ) - { - pic_new = mitkIpFuncEro ( pic_old, pic_mask, border ); - mitkIpPicFree ( pic_mask ); - } - else - printf ( " iamge doesn't exist \n" ); - } - /* else if ( strcasecmp ( operation, "hitmiss" ) == 0 ) - { - strcpy ( mask_name, "" ); - printf ( " mask name 1 : " ); - scanf ( "%s", mask_name ); - mask_1 = mitkIpPicGet ( mask_name, NULL ); - if ( mask_1 != NULL ) - { - pic_new = mitkIpFuncHitMissI( pic_old, mask_1, mitkIpFuncBorderZero ); - mitkIpPicFree ( mask_1 ); - } - else - printf ( " iamge doesn't exist \n" ); - }*/ - else if ( strcasecmp ( operation, "Scale" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != pic_old->dim + 5 ) ) - { - printf("Usage: ipFunc Scale infile outfile sc_fact1 ... sc_factn kind \n"); - printf(" sc_factx must contain a positive float number \n" ); - printf(" kind describes the interpolation used to scale :\n" ); - printf(" next neighbour : 7 \n" ); - printf(" bilinear : 6 \n" ); - exit(1); - } - sc = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpFloat8_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - { - sscanf ( argv[4+i], "%lf", &sc[i] ); - } - sscanf ( argv[4+pic_old->dim], "%d", &keep ); - pic_new = mitkIpFuncScale ( pic_old, sc, keep ); - pic_ret = NULL; - free(sc); - } - else if ( strcasecmp ( operation, "Transpose" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != pic_old->dim + 4 ) ) - { - printf("Usage: ipFunc Transpose infile outfile perm_1 ... perm_n \n"); - printf(" perm_1 ... perm_n must be a permutation vector, e.g., 4 2 1 3 \n" ); - exit(1); - } - perm = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpFloat8_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - { - sscanf ( argv[4+i], "%d", &perm[i] ); - } - pic_new = mitkIpFuncTranspose ( pic_old, NULL, perm ); - pic_ret = NULL; - free(perm); - } - else if ( strcasecmp ( operation, "Roberts" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Roberts infile outfile dim_mask \n"); - exit(1); - } - sscanf ( argv[4], "%d", &dim_mask ); - border = 3; - pic_new = mitkIpFuncRoberts ( pic_old, dim_mask, border ); - } - else if ( strcasecmp ( operation, "GaussF" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 6 ) ) - { - printf("Usage: ipFunc GaussF infile outfile len_mask dim_mask \n"); - exit(1); - } - sscanf ( argv[4], "%d", &len_mask ); - sscanf ( argv[5], "%d", &dim_mask ); - border = 3; - pic_new = mitkIpFuncGausF ( pic_old, len_mask, dim_mask, border ); - } - else if ( strcasecmp ( operation, "Canny" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 7 ) ) - { - printf("Usage: ipFunc Canny infile outfile len_mask dim_mask threshold \n"); - exit(1); - } - sscanf ( argv[4], "%d", &len_mask ); - sscanf ( argv[5], "%d", &dim_mask ); - sscanf ( argv[6], "%lf", &threshold ); - border = 3; - if ( pic_new != NULL ) mitkIpPicFree ( pic_new ); - pic_new = mitkIpFuncCanny ( pic_old, dim_mask, len_mask, - threshold, border ); - } - else if ( strcasecmp ( operation, "Rank" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 7 ) ) - { - printf("Usage: ipFunc Rank infile outfile len_mask dim_mask rank \n"); - exit(1); - } - sscanf ( argv[4], "%d", &len_mask ); - sscanf ( argv[5], "%d", &dim_mask ); - sscanf ( argv[6], "%d", &rank ); - border = 3; - pic_new = mitkIpFuncRank ( pic_old, rank, dim_mask, len_mask, border ); - } - else if ( strcasecmp ( operation, "MeanF" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 6 ) ) - { - printf("Usage: ipFunc MeanF infile outfile len_mask dim_mask \n"); - exit(1); - } - sscanf ( argv[4], "%d", &len_mask ); - sscanf ( argv[5], "%d", &dim_mask ); - border = 3; - pic_new = mitkIpFuncMeanF ( pic_old, len_mask, dim_mask, border ); - } - else if ( strcasecmp ( operation, "Shp" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 6 ) ) - { - printf("Usage: ipFunc Shp infile outfile len_mask dim_mask \n"); - exit(1); - } - sscanf ( argv[4], "%d", &len_mask ); - sscanf ( argv[5], "%d", &dim_mask ); - border = 3; - pic_new = mitkIpFuncShp ( pic_old, dim_mask, border, len_mask ); - } - else if ( strcasecmp ( operation, "Laplace" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Laplace infile outfile dim_mask \n"); - exit(1); - } - sscanf ( argv[4], "%d", &dim_mask ); - border = 3; - pic_new = mitkIpFuncLaplace ( pic_old, dim_mask, border ); - } - else if ( strcasecmp ( operation, "Sobel" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Sobel infile outfile dim_mask \n"); - exit(1); - } - sscanf ( argv[4], "%d", &dim_mask ); - border = 3; - pic_new = mitkIpFuncSobel ( pic_old, dim_mask, border ); - } - else if ( strcasecmp ( operation, "Grad" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Grad infile outfile dim_mask \n"); - exit(1); - } - sscanf ( argv[4], "%d", &dim_mask ); - border = 3; - pic_new = mitkIpFuncGrad ( pic_old, dim_mask, border ); - } - else if ( strcasecmp ( operation, "Thresh" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Thresh infile outfile threshold \n"); - exit(1); - } - sscanf ( argv[4], "%lf", &threshold ); - pic_new = mitkIpFuncThresh ( pic_old, threshold, pic_ret ); - } - else if ( strcasecmp ( operation, "Conv" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 5 ) ) - { - printf("Usage: ipFunc Conv infile outfile mask \n"); - printf(" mask must be the name of a PIC-file containing the mask \n" ); - exit(1); - } - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - border = mitkIpFuncBorderZero; - - pic_mask = mitkIpPicGet ( mask_name, NULL ); - if ( pic_mask != NULL ) - { - pic_new = mitkIpFuncConv ( pic_old, pic_mask, border ); - mitkIpPicFree ( pic_mask ); - } - } - else if ( strcasecmp ( operation, "ZeroCr" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc ZeroCr infile outfile \n" ); - exit ( 1 ); - } - pic_new = mitkIpFuncZeroCr ( pic_old ); - } - else if ( strcasecmp ( operation, "Exp" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc Exp infile outfile \n" ); - exit ( 1 ); - } - pic_new = mitkIpFuncExp ( pic_old, mitkIpFuncMinMax, pic_ret ); - } - else if ( strcasecmp ( operation, "Log" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc Log infile outfile \n" ); - exit ( 1 ); - } - pic_new = mitkIpFuncLog ( pic_old ); - } - else if ( strcasecmp ( operation, "LN" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc LN infile outfile \n" ); - exit ( 1 ); - } - pic_new = mitkIpFuncLN ( pic_old ); - } - else if ( strcasecmp ( operation, "Norm" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc Norm infile outfile \n" ); - exit ( 1 ); - } - pic_new = mitkIpFuncNorm ( pic_old, pic_ret ); - } - else if ( strcasecmp ( operation, "NormXY" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 6 ) ) - { - printf("Usage: ipFunc NormXY infile outfile lower_value upper_value\n"); - exit(1); - } - sscanf ( argv[4],"%lf", &min_gv ); - sscanf ( argv[5],"%lf", &max_gv ); - pic_new = mitkIpFuncNormXY ( pic_old, min_gv, max_gv, pic_ret ); - } - else if ( strcasecmp ( operation, "Equal" ) == 0 ) - { - if ( (unsigned int) argc != 4 ) - { - printf ( " ipFunc Equal infile outfile \n" ); - exit ( 1 ); - } - keep = mitkIpFuncMinMax; - pic_new = mitkIpFuncEqual ( pic_old, keep, pic_ret ); - } - else if ( strcasecmp ( operation, "Extr" ) == 0 ) - { - if ( ( (unsigned int) argc != 3 ) || ( strcasecmp (argv[2], "-h") == 0 ) ) - { - printf ( " ipFunc Extr infile \n" ); - exit ( 1 ); - } - mitkIpFuncExtr ( pic_old, &min, &max ); - picput_flag = mitkIpFalse; - printf ( " min: %12.2lf max: %12.2lf \n", min, max ); - } -#ifdef MESCHACH - else if ( strcasecmp ( operation, "Inertia" ) == 0 ) - { - if ( ( (unsigned int) argc != 3 ) || ( strcasecmp (argv[2], "-h") == 0 ) ) - { - printf ( " ipFunc Inertia infile \n" ); - exit ( 1 ); - } - mitkIpFuncInertia ( pic_old, &inertia, &ev ); - picput_flag = mitkIpFalse; - for ( i = 0; i < pic_old->dim; i++ ) - printf ( " eigenvalue[%d] = %lf \n", i, ev[i] ); - for ( i = 0; i < pic_old->dim * pic_old->dim; i++ ) - printf ( " inertia[%d] = %lf \n", i, inertia[i] ); - } -#endif - else if ( strcasecmp ( operation, "Grav" ) == 0 ) - { - if ( ( (unsigned int) argc != 3 ) || ( strcasecmp (argv[2], "-h") == 0 ) ) - { - printf ( " ipFunc Grav infile \n" ); - exit ( 1 ); - } - grav = mitkIpFuncGrav ( pic_old ); - picput_flag = mitkIpFalse; - for ( i = 0; i < pic_old->dim; i++ ) - printf ( " center of gravity[%d] = %lf \n", i, grav[i] ); - } - else if ( strcasecmp ( operation, "Median" ) == 0 ) - { - if ( ( (unsigned int) argc != 3 ) || ( strcasecmp (argv[2], "-h") == 0 ) ) - { - printf ( " ipFunc Median infile \n" ); - exit ( 1 ); - } - mean = mitkIpFuncMedI ( pic_old ); - printf ( " median: %lf\n", mean ); - } - else if ( strcasecmp ( operation, "Mean" ) == 0 ) - { - if ( ( (unsigned int) argc != 3 ) || ( strcasecmp (argv[2], "-h") == 0 ) ) - { - printf ( " ipFunc Mean infile \n" ); - exit ( 1 ); - } - mean = mitkIpFuncMean ( pic_old ); - printf ( " mean: %lf\n", mean ); - } - else if ( strcasecmp ( operation, "Var" ) == 0 ) - { - if ( ( (unsigned int) argc != 3 ) || ( strcasecmp (argv[2], "-h") == 0 ) ) - { - printf ( " ipFunc Var infile \n" ); - exit ( 1 ); - } - var = mitkIpFuncVar ( pic_old ); - printf ( " variance : %lf\n", var ); - } - else if ( strcasecmp ( operation, "SDev" ) == 0 ) - { - if ( ( (unsigned int) argc != 3 ) || ( strcasecmp (argv[2], "-h") == 0 ) ) - { - printf ( " ipFunc SDev infile \n" ); - exit ( 1 ); - } - s_der = mitkIpFuncSDev ( pic_old ); - printf ( " standard derivation : %lf\n", s_der ); - } - else if ( strcasecmp ( operation, "SelMM" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 6 ) ) - { - printf("Usage: ipFunc SelMM infile outfile lower_value upper_value \n"); - exit(1); - } - sscanf ( argv[4], "%lf", &gv_low ); - sscanf ( argv[5], "%lf", &gv_up ); - pic_new = mitkIpFuncSelMM ( pic_old, gv_low, gv_up, pic_ret ); - } - /* - else if ( strcasecmp ( operation, "sel_mm_inv" ) == 0 ) - { - printf ( " lower greyvalue : " ); - scanf ( "%lf", &gv_low ); - printf ( " upper greyvalue : " ); - scanf ( "%lf", &gv_up ); - printf ( " lower greyvalue (new): " ); - scanf ( "%lf", &gv_new_low ); - printf ( " upper greyvalue (new): " ); - scanf ( "%lf", &gv_new_up ); - pic_new = mitkIpFuncSelMM_Inv ( pic_old, gv_low, gv_up, gv_new_low, gv_new_up, pic_ret ); - } - */ - else if ( strcasecmp ( operation, "Select" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 7 ) ) - { - printf("Usage: ipFunc Select infile outfile lower_value upper_value new_value\n"); - exit(1); - } - sscanf ( argv[4], "%lf", &gv_low ); - sscanf ( argv[5], "%lf", &gv_up ); - sscanf ( argv[6], "%lf", &gv ); - pic_new = mitkIpFuncSelect ( pic_old, gv_low, gv_up, gv, pic_ret ); - } - else if ( strcasecmp ( operation, "SelInv" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 7 ) ) - { - printf("Usage: ipFunc SelInv infile outfile lower_value upper_value new_value\n"); - exit(1); - } - sscanf ( argv[4], "%lf", &gv_low ); - sscanf ( argv[5], "%lf", &gv_up ); - sscanf ( argv[6], "%lf", &gv ); - pic_new = mitkIpFuncSelInv ( pic_old, gv_low, gv_up, gv, pic_ret ); - } - else if ( strcasecmp ( operation, "LevWin" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 6 ) ) - { - printf("Usage: ipFunc LevWin infile outfile level window \n" ); - exit(1); - } - sscanf ( argv[4], "%lf", &gv_low ); - sscanf ( argv[5], "%lf", &gv_up ); - pic_new = mitkIpFuncLevWin ( pic_old, gv_low, gv_up, pic_ret ); - } - else if ( strcasecmp ( operation, "Box" ) == 0 ) - { - if ( ( (unsigned int) argc != 3 ) || ( strcasecmp (argv[2], "-h") == 0 ) ) - { - printf ( " usage: ipFunc Box infile \n" ); - exit ( 1 ); - } - picput_flag = mitkIpFalse; length=NULL; - mitkIpFuncBox ( pic_old, &begin, &length ); - for ( i =0; i < pic_old->dim; i++ ) - printf ( " [%d]\t links oben %d \t\t rechts unten: %d \n", i, begin[i], length[i] ); - } - else if ( strcasecmp ( operation, "BorderX" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != pic_old->dim + 5 ) ) - { - printf ( " usage: ipFunc BorderX infile outfile edge1...edgen value\n" ); - exit ( 1 ); - } - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - { - sscanf ( argv[4+i], "%d", &begin[i] ); - } - sscanf ( argv[4+pic_old->dim], "%lf", &value ); - pic_mask = mitkIpPicNew (); - pic_mask->type = 3; - pic_mask->bpe = 16; - pic_mask->dim = pic_old->dim; - for ( i = 0; i < pic_old->dim; i++ ) - pic_mask->n[i] = begin[i] *2 + 1; - pic_new = mitkIpFuncBorderX ( pic_old, pic_mask, value, NULL ); - mitkIpPicFree ( pic_mask ); - free ( begin ); - } - else if ( strcasecmp ( operation, "Frame" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != pic_old->dim + 5 ) ) - { - printf ( " usage: ipFunc Edge infile outfile edge1...edgen value\n" ); - exit ( 1 ); - } - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - { - sscanf ( argv[4+i], "%d", &begin[i] ); - } - sscanf ( argv[4+pic_old->dim], "%lf", &value ); - pic_new = mitkIpFuncFrame ( pic_old, begin, value ); - free ( begin ); - } - else if ( strcasecmp ( operation, "WindowR" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != pic_old->dim + 5 ) ) - { - printf ( " usage: ipFunc WindowR infile outfile image beg1...begn \n" ); - exit ( 1 ); - } - keep = mitkIpFuncKeep; - strcpy ( mask_name, "" ); - sscanf ( argv[4], "%s", mask_name ); - pic_hlp = mitkIpPicGet ( mask_name, NULL ); - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - { - sscanf ( argv[5+i], "%d", &begin[i] ); - } - pic_new = mitkIpFuncWindowR ( pic_old, pic_hlp, begin, mitkIpFuncNoKeep ); - free ( begin ); - } - else if ( strcasecmp ( operation, "Rotate" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != pic_old->dim * 2 + 4 ) ) - { - printf ( " usage: ipFunc Rotate infile outfile grad1...gradn order1...ordern \n" ); - exit ( 1 ); - } - grad = malloc ( _mitkIpPicNDIM * sizeof ( int ) ); - order = malloc ( _mitkIpPicNDIM * sizeof ( int ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &grad[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+pic_old->dim+i], "%d", &order[i] ); - pic_new = mitkIpFuncRotate ( pic_old, NULL, grad, order ); - free ( grad ); - free ( order ); - } - else if ( strcasecmp ( operation, "Window" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != pic_old->dim * 2 + 4 ) ) - { - printf ( " usage: ipFunc Window infile outfile beg1...begn length1...lengthn \n" ); - exit ( 1 ); - } - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+pic_old->dim+i], "%d", &length[i] ); - printf ( " %d %d %d %d %d %d \n", begin[0], begin[1], begin[2], length[0], length[1], length[2] ); - pic_new = mitkIpFuncWindow ( pic_old, begin, length ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "DrawPoly" ) == 0 ) - { - /* - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 2 * pic_old->dim + 5 ) ) - */ - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) ) - { - printf ( " usage: ipFunc Window infile outfile nr_points x1...xn y1...yn \n" ); - exit ( 1 ); - } - sscanf ( argv[4], "%d", &radius ); - begin = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < radius; i++ ) - sscanf ( argv[5+i], "%d", &begin[i] ); - for ( i = 0; i < radius; i++ ) - sscanf ( argv[5+radius+i], "%d", &length[i] ); - pic_new = mitkIpFuncDrawPoly ( pic_old, begin, length, radius ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "MeanROI" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 + pic_old->dim * 2 ) ) - { - printf ( " usage: ipFunc MeanROI infile nr_points x1...xn y1...yn \n" ); - exit ( 1 ); - } - sscanf ( argv[3], "%d", &radius ); - begin = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+pic_old->dim+i], "%d", &length[i] ); - mean = mitkIpFuncMeanROI ( pic_old, begin, length, radius ); - printf ( " mean: %lf \n", mean ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "VarROI" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 + pic_old->dim * 2 ) ) - { - printf ( " usage: ipFunc VarROI infile nr_points x1...xn y1...yn \n" ); - exit ( 1 ); - } - sscanf ( argv[3], "%d", &radius ); - begin = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+pic_old->dim+i], "%d", &length[i] ); - var = mitkIpFuncVarROI ( pic_old, begin, length, radius ); - printf ( " var: %lf \n", var ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "SDevROI" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 + pic_old->dim * 2 ) ) - { - printf ( " usage: ipFunc SDevROI infile nr_points x1...xn y1...yn \n" ); - exit ( 1 ); - } - sscanf ( argv[3], "%d", &radius ); - begin = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+pic_old->dim+i], "%d", &length[i] ); - var = mitkIpFuncSDevROI ( pic_old, begin, length, radius ); - printf ( " var: %lf \n", var ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "ExtrROI" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 + pic_old->dim * 2 ) ) - { - printf ( " usage: ipFunc ExtrROI infile nr_points x1...xn y1...yn \n" ); - exit ( 1 ); - } - sscanf ( argv[3], "%d", &radius ); - begin = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( radius * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+pic_old->dim+i], "%d", &length[i] ); - mitkIpFuncExtrROI ( pic_old, &min, &max, begin, length, radius ); - printf ( " min: %lf max: %lf\n", min, max ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "VarR" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 3 + 2 * pic_old->dim ) ) - { - printf ( " usage: ipFunc VarR infile beg1...begn length1...lengthn \n" ); - exit ( 1 ); - } - begin = malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[3+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[3+pic_old->dim+i], "%d", &length[i] ); - var = mitkIpFuncVarR ( pic_old, begin, length ); - printf ( " var: %lf \n", var ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "SDevR" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 3 + 2 * pic_old->dim ) ) - { - printf ( " usage: ipFunc SDevR infile beg1...begn length1...lengthn \n" ); - exit ( 1 ); - } - begin = malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[3+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[3+pic_old->dim+i], "%d", &length[i] ); - var = mitkIpFuncVarR ( pic_old, begin, length ); - s_der = mitkIpFuncSDevR ( pic_old, begin, length ); - printf ( " s_der: %lf \n", s_der ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "MeanR" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 3 + 2 * pic_old->dim ) ) - { - printf ( " usage: ipFunc MeanR infile beg1...begn length1...lengthn \n" ); - exit ( 1 ); - } - begin = malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[3+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[3+pic_old->dim+i], "%d", &length[i] ); - var = mitkIpFuncVarR ( pic_old, begin, length ); - mean = mitkIpFuncMeanR ( pic_old, begin, length ); - printf ( " mean: %lf \n", mean ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "ExtrR" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 3 + 2 * pic_old->dim ) ) - { - printf ( " usage: ipFunc ExtrR infile beg1...begn length1...lengthn \n" ); - exit ( 1 ); - } - begin = malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - length = malloc ( pic_old->dim * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[3+i], "%d", &begin[i] ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[3+pic_old->dim+i], "%d", &length[i] ); - var = mitkIpFuncVarR ( pic_old, begin, length ); - mitkIpFuncExtrR ( pic_old, &min, &max, begin, length ); - printf ( " min: %lf max: %lf \n", min, max ); - free ( begin ); - free ( length ); - } - else if ( strcasecmp ( operation, "SDevC" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 + pic_old->dim ) ) - { - printf ( " usage: ipFunc SDevR infile radius begin1...beginn \n" ); - exit ( 1 ); - } - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - sscanf ( argv[3], "%d", &radius ); - s_der = mitkIpFuncSDevC ( pic_old, begin, radius ); - printf ( " s_dev: %lf \n", s_der ); - free ( begin ); - } - else if ( strcasecmp ( operation, "VarC" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 + pic_old->dim ) ) - { - printf ( " usage: ipFunc VarC infile radius begin1...beginn \n" ); - exit ( 1 ); - } - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - sscanf ( argv[3], "%d", &radius ); - var = mitkIpFuncVarC ( pic_old, begin, radius ); - printf ( " var: %lf \n", var ); - free ( begin ); - } - else if ( strcasecmp ( operation, "MeanC" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 + pic_old->dim ) ) - { - printf ( " usage: ipFunc MeanC infile radius begin1...beginn \n" ); - exit ( 1 ); - } - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - sscanf ( argv[4+i], "%d", &begin[i] ); - sscanf ( argv[3], "%d", &radius ); - mean = mitkIpFuncMeanC ( pic_old, begin, radius ); - printf ( " mean: %lf \n", mean ); - free ( begin ); - } - else if ( strcasecmp ( operation, "ExtrC" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 4 + pic_old->dim ) ) - { - printf ( " usage: ipFunc ExtrC infile radius begin1...beginn \n" ); - exit ( 1 ); - } - begin = malloc ( _mitkIpPicNDIM * sizeof ( mitkIpUInt4_t ) ); - for ( i = 0; i < pic_old->dim; i++ ) - scanf ( argv[4+i], "%d", &begin[i] ); - sscanf ( argv[3], "%d", &radius ); - mitkIpFuncExtrC ( pic_old, &min, &max, begin, radius ); - printf ( " min: %lf max: %lf \n", min, max ); - free ( begin ); - } - else if ( strcasecmp ( operation, "MakeMorphSquareMask" ) == 0 ) - { - if ( ( (unsigned int) argc == 2 ) || - ( ( (unsigned int) argc == 3 ) && ( strcasecmp (argv[2], "-h") == 0 ) ) || - ( (unsigned int) argc != 6 ) ) - { - printf ( " usage: ipFunc MakeMorphSquareMask infile outfile dim size\n" ); - exit ( 1 ); - } - sscanf ( argv[4], "%d", &dim_mask ); - sscanf ( argv[5], "%d", &mask_size ); - - pic_new=mitkIpPicCopyHeader(pic_old,NULL); - pic_new->dim=dim_mask; - for ( i = 0; i < pic_old->dim; i++ ) - pic_new->n[i]=mask_size; - pic_new->data = calloc ( _mitkIpPicSize(pic_new), 1 ); - mitkIpFuncAddC(pic_new, 1.0, mitkIpFuncKeep, pic_new); - } - else - printf ( " illegal operation \n" ); - - - if ( mitkIpFuncErrno > mitkIpOK ) - { - mitkIpFuncPError ( error_nr ); - exit ( 1 ); - } - if ( ( pic_new != 0 ) && ( picput_flag ) ) - { - strcpy ( pic_name_t, argv[3] ); - mitkIpPicPut ( pic_name_t, pic_new ); - picput_flag = mitkIpTrue; - } - - - if ( pic_ret ) - { - mitkIpPicFree ( pic_ret ); - pic_old = NULL; - pic_ret = NULL; - pic_new = NULL; - } - else - { - if ( pic_old != NULL ) mitkIpPicFree ( pic_old ); - pic_old = NULL; - if ( pic_new != NULL ) mitkIpPicFree ( pic_new ); - pic_new = NULL; - if ( pic_hlp != NULL ) mitkIpPicFree ( pic_hlp ); - pic_hlp = NULL; - } - - return 0; -} - diff --git a/Utilities/IpFunc/ipFunc.dox b/Utilities/IpFunc/ipFunc.dox deleted file mode 100644 index fb21dbba85..0000000000 --- a/Utilities/IpFunc/ipFunc.dox +++ /dev/null @@ -1,408 +0,0 @@ -# Doxyfile 0.49-990829 - -# This file describes the settings to be used by doxygen for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of word surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = ipFunc - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 0.6.0 - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = ../doc - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Dutch, French, Italian, Czech, Swedish, German and Japanese - -OUTPUT_LANGUAGE = English - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# If the EXTRACT_ALL tag is set to YES all classes and functions will be -# included in the documentation, even if no documentation was available. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members inside documented classes or files. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSESS tag is set to YES, Doxygen will hide all -# undocumented classes. - -HIDE_UNDOC_CLASSES = YES - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# If the FULL_PATH_NAMES tag is set to YES Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. - -STRIP_FROM_PATH = - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a class diagram (in Html and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. - -CLASS_DIAGRAMS = YES - -# If the SOURCE_BROWSER tag is set to YES than the body of a member or -# function will be appended as a block of code to the documentation of. -# that member or function. - -SOURCE_BROWSER = NO - -# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen -# will only generate file names in lower case letters. If set to -# YES upper case letters are also allowed. This is useful if you have -# classes or files whose names only differ in case and if your file system -# supports case sensitive file names. - -CASE_SENSE_NAMES = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = NO - -# If the JAVADOC_NO_AUTOBRIEF is set to YES (the default) then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the Javadoc-style will -# behave just like the Qt-style comments. - -JAVADOC_AUTOBRIEF = YES - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . mitkIpFunc.h ipArithmeticAndLogical.h ipGeometrical.h ipLocal.h ipStatistical.h ipMorphological.h ipPointOperators.h ipAdministrative.h - - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -FILE_PATTERNS = *.c - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. - -INPUT_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -GENERATE_RTF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. - -MACRO_EXPANSION = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. - -PREDEFINED = DOXYGEN_IGNORE - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED tag. - -EXPAND_ONLY_PREDEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tagfiles. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO - -# The CGI_NAME tag should be the name of the CGI script that -# starts the search engine (doxysearch) with the correct parameters. -# A script with this name will be generated by doxygen. - -CGI_NAME = search.cgi - -# The CGI_URL tag should be the absolute URL to the directory where the -# cgi binaries are located. See the documentation of your http daemon for -# details. - -CGI_URL = - -# The DOC_URL tag should be the absolute URL to the directory where the -# documentation is located. If left blank the absolute path to the -# documentation, with file:// prepended to it, will be used. - -DOC_URL = - -# The DOC_ABSPATH tag should be the absolute path to the directory where the -# documentation is located. If left blank the directory on the local machine -# will be used. - -DOC_ABSPATH = - -# The BIN_ABSPATH tag must point to the directory where the doxysearch binary -# is installed. - -BIN_ABSPATH = /usr/local/bin/ - -# The EXT_DOC_PATHS tag can be used to specify one or more paths to -# documentation generated for other projects. This allows doxysearch to search -# the documentation for these projects as well. - -EXT_DOC_PATHS = - diff --git a/Utilities/IpFunc/ipFunc.dsp b/Utilities/IpFunc/ipFunc.dsp deleted file mode 100644 index 8b9a845c3b..0000000000 --- a/Utilities/IpFunc/ipFunc.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ipFunc" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=ipFunc - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ipFunc.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ipFunc.mak" CFG="ipFunc - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ipFunc - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "ipFunc - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ipFunc - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ipFunc___Win32_Release" -# PROP BASE Intermediate_Dir "ipFunc___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../../DataStructures" /I "../../DataStructures/ipPic" /I ".." /I "../ipPic" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /D "lint" /YX /FD /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 ../../DataStructures/ipPic/lib/libipPic.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"msvcrt" /nodefaultlib:"LIBCMT" /out:"./bin/ipFunc.exe" - -!ELSEIF "$(CFG)" == "ipFunc - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ipFunc___Win32_Debug" -# PROP BASE Intermediate_Dir "ipFunc___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../DataStructures" /I "../../DataStructures/ipPic" /I ".." /I "../ipPic" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /D "lint" /YX /FD /GZ /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 ../../DataStructures/ipPic/lib/libipPic.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libcmtd" /nodefaultlib:"libcmt" /pdbtype:sept /libpath:"$(IPDIR)\piano\lib" - -!ENDIF - -# Begin Target - -# Name "ipFunc - Win32 Release" -# Name "ipFunc - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\ipFunc.c -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/Utilities/IpFunc/ipFunc.pro b/Utilities/IpFunc/ipFunc.pro deleted file mode 100644 index 1dc6e33bf1..0000000000 --- a/Utilities/IpFunc/ipFunc.pro +++ /dev/null @@ -1,132 +0,0 @@ -TEMPLATE = lib -TARGET = ipFunc -LANGUAGE = C -CONFIG += warn_on release - -OBJECTS_DIR = obj - -INCLUDEPATH = ../../DataStructures - -unix { - CONFIG += staticlib -} - -win32 { - INCLUDEPATH += ../../DataStructures/ipPic -} - -HEADERS = gradient.h \ - ipAdministrative.h \ - ipArithmeticAndLogical.h \ - mitkIpFunc.h \ - mitkIpFuncP.h \ - ipGeometrical.h \ - ipLocal.h \ - ipMorphological.h \ - ipPointOperators.h \ - ipStatistical.h - -SOURCES = AddC.c \ - AddI.c \ - AddSl.c \ - And.c \ - Border.c \ - BorderX.c \ - Box.c \ - Box2d.c \ - Box3d.c \ - Canny.c \ - Close.c \ - CompressM.c \ - Conv.c \ - Convert.c \ - CopyTags.c \ - Curtosis.c \ - CurtosisR.c \ - Dila.c \ - DivC.c \ - DivI.c \ - DrawPoly.c \ - Equal.c \ - Ero.c \ - Error.c \ - Exp.c \ - ExtT.c \ - ExtrC.c \ - ExtrR.c \ - ExtrROI.c \ - Extrema.c \ - FillArea.c \ - Frame.c \ - GaussF.c \ - Grad.c \ - Grav.c \ - Hist.c \ - Histo.c \ - HitMiss.c \ - HitMissI.c \ - Inertia.c \ - Inv.c \ - LN.c \ - Label.c \ - Laplace.c \ - LevWind.c \ - Log.c \ - MakePicName.c \ - Malloc.c \ - Mean.c \ - MeanC.c \ - MeanF.c \ - MeanR.c \ - MeanROI.c \ - Median.c \ - Morph.c \ - MultC.c \ - MultI.c \ - Norm.c \ - NormXY.c \ - Not.c \ - OpCl.c \ - Open.c \ - Or.c \ - Pot.c \ - Range.c \ - Rank.c \ - Refl.c \ - RegGrow.c \ - Roberts.c \ - Rotate.c \ - SDev.c \ - SDevC.c \ - SDevR.c \ - SDevROI.c \ - ScBl.c \ - ScFact.c \ - ScNN.c \ - Scale.c \ - SelInv.c \ - SelMM.c \ - Select.c \ - SetErrno.c \ - SetTag.c \ - Shp.c \ - Skewness.c \ - SkewnessR.c \ - Sobel.c \ - Sqrt.c \ - SubC.c \ - SubI.c \ - Thresh.c \ - Transpose.c \ - Var.c \ - VarC.c \ - VarR.c \ - VarROI.c \ - Window.c \ - WindowR.c \ - Xchange.c \ - ZeroCr.c \ - _BorderX.c \ - _DrawPoly.c \ - ipGetANew.c - diff --git a/Utilities/IpFunc/ipFuncLib.pro b/Utilities/IpFunc/ipFuncLib.pro deleted file mode 100644 index 4f5571d194..0000000000 --- a/Utilities/IpFunc/ipFuncLib.pro +++ /dev/null @@ -1,123 +0,0 @@ -TEMPLATE = lib -unix:CONFIG = qt staticlib warn_on release -win32:CONFIG = qt warn_on release - -HEADERS = gradient.h \ - ipAdministrative.h \ - ipArithmeticAndLogical.h \ - mitkIpFunc.h \ - mitkIpFuncP.h \ - ipGeometrical.h \ - ipLocal.h \ - ipMorphological.h \ - ipPointOperators.h \ - ipStatistical.h - -SOURCES = AddC.c \ - AddI.c \ - AddSl.c \ - And.c \ - Border.c \ - BorderX.c \ - Box.c \ - Box2d.c \ - Box3d.c \ - Canny.c \ - Close.c \ - CompressM.c \ - Conv.c \ - Convert.c \ - CopyTags.c \ - Curtosis.c \ - CurtosisR.c \ - Dila.c \ - DivC.c \ - DivI.c \ - DrawPoly.c \ - Equal.c \ - Ero.c \ - Error.c \ - Exp.c \ - ExtT.c \ - ExtrC.c \ - ExtrR.c \ - ExtrROI.c \ - Extrema.c \ - FillArea.c \ - Frame.c \ - GaussF.c \ - Grad.c \ - Grav.c \ - Hist.c \ - Histo.c \ - HitMiss.c \ - HitMissI.c \ - Inertia.c \ - Inv.c \ - LN.c \ - Label.c \ - Laplace.c \ - LevWind.c \ - Log.c \ - MakePicName.c \ - Malloc.c \ - Mean.c \ - MeanC.c \ - MeanF.c \ - MeanR.c \ - MeanROI.c \ - Median.c \ - Morph.c \ - MultC.c \ - MultI.c \ - Norm.c \ - NormXY.c \ - Not.c \ - OpCl.c \ - Open.c \ - Or.c \ - Pot.c \ - Range.c \ - Rank.c \ - Refl.c \ - RegGrow.c \ - Roberts.c \ - Rotate.c \ - SDev.c \ - SDevC.c \ - SDevR.c \ - SDevROI.c \ - ScBl.c \ - ScFact.c \ - ScNN.c \ - Scale.c \ - SelInv.c \ - SelMM.c \ - Select.c \ - SetErrno.c \ - SetTag.c \ - Shp.c \ - Skewness.c \ - SkewnessR.c \ - Sobel.c \ - Sqrt.c \ - SubC.c \ - SubI.c \ - Thresh.c \ - Transpose.c \ - Var.c \ - VarC.c \ - VarR.c \ - VarROI.c \ - Window.c \ - WindowR.c \ - Xchange.c \ - ZeroCr.c \ - _BorderX.c \ - _DrawPoly.c \ - ipGetANew.c - -INCLUDEPATH = ../../DataStructures - -unix:TARGET = ipFunc -win32:TARGET = libipFunc diff --git a/Utilities/IpFunc/ipFuncMain.pro b/Utilities/IpFunc/ipFuncMain.pro deleted file mode 100644 index 853bacdb92..0000000000 --- a/Utilities/IpFunc/ipFuncMain.pro +++ /dev/null @@ -1,27 +0,0 @@ -TEMPLATE = app -CONFIG = console warn_on release -HEADERS = mitkIpFunc.h - -SOURCES = ipFunc.c - -unix:LIBS = -L../../DataStructures/ipPic - -unix:LIBS += -lz -L. -lipFunc -L../../DatasStructures/ipPic -lipPic - -win32:LIBS += $(IPDIR)/piano/ipPic/lib/libipPic.lib $(IPDIR)/piano/ipFunc/lib/libipFunc.lib - -INCLUDEPATH = ../../DataStructures ../../DataStructures/ipPic - -TARGET = ipFunc - - -#DESTDIR = lib - -#INTERFACES = - -win32:QMAKE_CXXFLAGS+=-GX #exception handling -win32:QMAKE_CXXFLAGS_DEBUG+=-ZI #edit and continue -win32:QMAKE_LFLAGS_DEBUG+=/nodefaultlib:"libcd" /nodefaultlib:"MSVCRT" -win32:QMAKE_LFLAGS_DEBUG-=/incremental:no -win32:QMAKE_LFLAGS_DEBUG+=/incremental:yes - diff --git a/Utilities/IpFunc/ipGeometrical.h b/Utilities/IpFunc/ipGeometrical.h deleted file mode 100644 index 2ce7016844..0000000000 --- a/Utilities/IpFunc/ipGeometrical.h +++ /dev/null @@ -1,117 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * Geometrical Operators. - * This header is for grouping purposes for the - * documentation only. Don't use it, use mitkIpFunc.h instead. - */ - -#ifndef DOXYGEN_IGNORE -#include <mitkIpFunc.h> -#endif - -#ifndef _mitkIpFunc_h -#define _mitkIpFunc_h - -/* function prototypes */ - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -mitkIpUInt4_t mitkIpFuncBox ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ); - -mitkIpPicDescriptor *mitkIpFuncRefl ( mitkIpPicDescriptor *pic_old, - mitkIpInt4_t axis ); - -mitkIpPicDescriptor *mitkIpFuncFrame ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *edge, - mitkIpFloat8_t value ); - -mitkIpPicDescriptor *mitkIpFuncBorder ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncBorderX ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - mitkIpFloat8_t value, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncScale ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t sc_fact[_mitkIpPicNDIM], - mitkIpFuncFlagI_t sc_kind ); - -mitkIpPicDescriptor *mitkIpFuncScFact ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t factor, - mitkIpFuncFlagI_t sc_kind ); - -mitkIpPicDescriptor *mitkIpFuncWindow ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpPicDescriptor *mitkIpFuncWindowR( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpUInt4_t *begin, - mitkIpFuncFlagI_t keep ); - -mitkIpPicDescriptor *mitkIpFuncRotate ( mitkIpPicDescriptor *pic, - mitkIpPicDescriptor *pic_old, - int *grad, int *order ); - -mitkIpPicDescriptor *mitkIpFuncTranspose( mitkIpPicDescriptor *pic, - mitkIpPicDescriptor *pic_old, - int *permutations_vector); - -mitkIpPicDescriptor *mitkIpFuncDrawPoly( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpFunc_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpFunc/ipGetANew.c b/Utilities/IpFunc/ipGetANew.c deleted file mode 100644 index 4bb0c2b504..0000000000 --- a/Utilities/IpFunc/ipGetANew.c +++ /dev/null @@ -1,56 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -#include "mitkIpFuncP.h" - -mitkIpUInt4_t _ipGetANew( mitkIpUInt4_t aNew[], mitkIpUInt4_t Index) -{ -mitkIpUInt4_t NewIndex; - - /* return original Index */ - if (aNew[Index] == Index) return (Index); - - for (;;) - { - NewIndex = aNew[Index]; - if (NewIndex == aNew[NewIndex]) return(NewIndex); - Index = NewIndex; - } -} diff --git a/Utilities/IpFunc/ipLocal.h b/Utilities/IpFunc/ipLocal.h deleted file mode 100644 index 3c778e7398..0000000000 --- a/Utilities/IpFunc/ipLocal.h +++ /dev/null @@ -1,114 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * Local Operators. - * This header is for grouping purposes for the - * documentation only. Don't use it, use mitkIpFunc.h instead. - */ - -#ifndef DOXYGEN_IGNORE -#include <mitkIpFunc.h> -#endif - -#ifndef _mitkIpFunc_h -#define _mitkIpFunc_h - -/* function prototypes */ - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -mitkIpPicDescriptor *mitkIpFuncConv ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncGausF ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t len_mask, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncCanny ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpUInt4_t len_mask, - mitkIpFloat8_t threshold, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncRank ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t rank, - mitkIpUInt4_t dim_mask, - mitkIpUInt4_t len_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncMeanF ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t len_mask, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncShp ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border, - mitkIpUInt4_t mask_nr ); - -mitkIpPicDescriptor *mitkIpFuncLaplace( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncSobel ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncGrad ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncRoberts( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpFunc_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpFunc/ipMorphological.h b/Utilities/IpFunc/ipMorphological.h deleted file mode 100644 index 697d84cf8c..0000000000 --- a/Utilities/IpFunc/ipMorphological.h +++ /dev/null @@ -1,104 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * Morphological Operators. - * This header is for grouping purposes for the - * documentation only. Don't use it, use mitkIpFunc.h instead. - */ - -#ifndef DOXYGEN_IGNORE -#include <mitkIpFunc.h> -#endif - -#ifndef _mitkIpFunc_h -#define _mitkIpFunc_h - -/* function prototypes */ - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -mitkIpPicDescriptor *mitkIpFuncEro ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncDila ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncOpen ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncClose ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncHitMiss( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_masks, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncLabel ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *no_label ); - -mitkIpPicDescriptor *mitkIpFuncRegGrow ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_seed, - mitkIpUInt4_t *beg_seed, - mitkIpUInt4_t *end_seed, - mitkIpUInt4_t border_label, - mitkIpUInt4_t region_label, - mitkIpFloat8_t std_fact, - mitkIpUInt4_t kind ); - -mitkIpPicDescriptor *mitkIpFuncDrawPoly( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpFunc_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpFunc/ipPointOperators.h b/Utilities/IpFunc/ipPointOperators.h deleted file mode 100644 index 6971f809ad..0000000000 --- a/Utilities/IpFunc/ipPointOperators.h +++ /dev/null @@ -1,135 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * Point-Operators. - * This header is for grouping purposes for the - * documentation only. Don't use it, use mitkIpFunc.h instead. - */ - -#ifndef DOXYGEN_IGNORE -#include <mitkIpFunc.h> -#endif - -#ifndef _mitkIpFunc_h -#define _mitkIpFunc_h - -/* function prototypes */ - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -mitkIpPicDescriptor *mitkIpFuncInv ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncEqual ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ); - - -mitkIpPicDescriptor *mitkIpFuncPot ( mitkIpPicDescriptor *pic_1, - mitkIpFloat8_t exponent, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSqrt ( mitkIpPicDescriptor *pic_1, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncThresh ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t threshold, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncZeroCr ( mitkIpPicDescriptor *pic_old ); - -mitkIpPicDescriptor *mitkIpFuncExp ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncLN ( mitkIpPicDescriptor *pic_old ); - -mitkIpPicDescriptor *mitkIpFuncLog ( mitkIpPicDescriptor *pic_old ); - -mitkIpPicDescriptor *mitkIpFuncNorm ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncNormXY ( mitkIpPicDescriptor *pic, - mitkIpFloat8_t min_gv, - mitkIpFloat8_t max_gv, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSelInv ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpFloat8_t gv, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSelect ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpFloat8_t gv, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSelMM ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncLevWin ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t level, - mitkIpFloat8_t window, - mitkIpPicDescriptor *pic_return ); - -void mitkIpFuncXchange ( mitkIpPicDescriptor **pic1, - mitkIpPicDescriptor **pic2 ); - -mitkIpPicDescriptor *mitkIpFuncConvert( mitkIpPicDescriptor *pic_old, - mitkIpPicType_t type, - mitkIpUInt4_t bpe ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpFunc_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpFunc/ipStatistical.h b/Utilities/IpFunc/ipStatistical.h deleted file mode 100644 index 847d51a9a8..0000000000 --- a/Utilities/IpFunc/ipStatistical.h +++ /dev/null @@ -1,169 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * Operators to calculate statistical values. - * This header is for grouping purposes for the - * documentation only. Don't use it, use mitkIpFunc.h instead. - */ - -#ifndef DOXYGEN_IGNORE -#include <mitkIpFunc.h> -#endif - -#ifndef _mitkIpFunc_h -#define _mitkIpFunc_h - -/* function prototypes */ - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -mitkIpUInt4_t mitkIpFuncBox ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ); - -mitkIpFloat8_t mitkIpFuncMedI ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t mitkIpFuncMean ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t mitkIpFuncVar ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t mitkIpFuncSDev ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t *mitkIpFuncGrav ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t mitkIpFuncMeanC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t radius ); - -mitkIpFloat8_t mitkIpFuncVarC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t radius ); - -mitkIpFloat8_t mitkIpFuncSDevC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t radius ); - -mitkIpUInt4_t mitkIpFuncExtrC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ); - -mitkIpFloat8_t mitkIpFuncMeanROI( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpFloat8_t mitkIpFuncVarROI( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpFloat8_t mitkIpFuncSDevROI( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpFloat8_t mitkIpFuncSkewness ( mitkIpPicDescriptor *pic ); - -mitkIpFloat8_t mitkIpFuncCurtosis ( mitkIpPicDescriptor *pic ); - -mitkIpFloat8_t mitkIpFuncSkewnessR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -double mitkIpFuncCurtosisR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpUInt4_t mitkIpFuncExtrROI( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpFloat8_t mitkIpFuncMeanR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpFloat8_t mitkIpFuncVarR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpFloat8_t mitkIpFuncSDevR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpUInt4_t mitkIpFuncExtrR ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpUInt4_t mitkIpFuncRange ( mitkIpPicDescriptor *pic, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up ); - -mitkIpInt4_t mitkIpFuncExtr ( mitkIpPicDescriptor *pic, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max ); - -mitkIpInt4_t mitkIpFuncInertia ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t **eigen_vect, - mitkIpFloat8_t **eigen_val ); - -mitkIpInt4_t mitkIpFuncHist ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t min_gv, - mitkIpFloat8_t max_gv, - mitkIpUInt4_t **hist, - mitkIpUInt4_t *size_hist ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpFunc_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpFunc/libipFunc.dsp b/Utilities/IpFunc/libipFunc.dsp deleted file mode 100644 index 730ac503e0..0000000000 --- a/Utilities/IpFunc/libipFunc.dsp +++ /dev/null @@ -1,540 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libipFunc" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=libipFunc - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "libipFunc.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "libipFunc.mak" CFG="libipFunc - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libipFunc - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "libipFunc - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "libipFunc - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../DataStructures" /I "../../DataStructures/ipPic" /I ".." /I "../ipPic" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "lint" /YX /FD /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:".\lib\libipFunc.lib" - -!ELSEIF "$(CFG)" == "libipFunc - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "libipFunc___Win32_Debug" -# PROP BASE Intermediate_Dir "libipFunc___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "d:\users\ivo\c\ip++\ImageProject" /I "../../DataStructures" /I "../../DataStructures/ipPic" /I ".." /I "../ipPic" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "lint" /YX /FD /GZ /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:".\lib\libipFuncD.lib" - -!ENDIF - -# Begin Target - -# Name "libipFunc - Win32 Release" -# Name "libipFunc - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\_BorderX.c -# End Source File -# Begin Source File - -SOURCE=.\_DrawPoly.c -# End Source File -# Begin Source File - -SOURCE=.\AddC.c -# End Source File -# Begin Source File - -SOURCE=.\AddI.c -# End Source File -# Begin Source File - -SOURCE=.\AddSl.c -# End Source File -# Begin Source File - -SOURCE=.\And.c -# End Source File -# Begin Source File - -SOURCE=.\Border.c -# End Source File -# Begin Source File - -SOURCE=.\BorderX.c -# End Source File -# Begin Source File - -SOURCE=.\Box.c -# End Source File -# Begin Source File - -SOURCE=.\Box2d.c -# End Source File -# Begin Source File - -SOURCE=.\Box3d.c -# End Source File -# Begin Source File - -SOURCE=.\Canny.c -# End Source File -# Begin Source File - -SOURCE=.\Close.c -# End Source File -# Begin Source File - -SOURCE=.\CompressM.c -# End Source File -# Begin Source File - -SOURCE=.\Conv.c -# End Source File -# Begin Source File - -SOURCE=.\Convert.c -# End Source File -# Begin Source File - -SOURCE=.\CopyTags.c -# End Source File -# Begin Source File - -SOURCE=.\Curtosis.c -# End Source File -# Begin Source File - -SOURCE=.\CurtosisR.c -# End Source File -# Begin Source File - -SOURCE=.\Dila.c -# End Source File -# Begin Source File - -SOURCE=.\DivC.c -# End Source File -# Begin Source File - -SOURCE=.\DivI.c -# End Source File -# Begin Source File - -SOURCE=.\DrawPoly.c -# End Source File -# Begin Source File - -SOURCE=.\Equal.c -# End Source File -# Begin Source File - -SOURCE=.\Ero.c -# End Source File -# Begin Source File - -SOURCE=.\Error.c -# End Source File -# Begin Source File - -SOURCE=.\Exp.c -# End Source File -# Begin Source File - -SOURCE=.\ExtrC.c -# End Source File -# Begin Source File - -SOURCE=.\Extrema.c -# End Source File -# Begin Source File - -SOURCE=.\ExtrR.c -# End Source File -# Begin Source File - -SOURCE=.\ExtrROI.c -# End Source File -# Begin Source File - -SOURCE=.\ExtT.c -# End Source File -# Begin Source File - -SOURCE=.\FillArea.c -# End Source File -# Begin Source File - -SOURCE=.\Frame.c -# End Source File -# Begin Source File - -SOURCE=.\GaussF.c -# End Source File -# Begin Source File - -SOURCE=.\Grad.c -# End Source File -# Begin Source File - -SOURCE=.\Grav.c -# End Source File -# Begin Source File - -SOURCE=.\Hist.c -# End Source File -# Begin Source File - -SOURCE=.\Histo.c -# End Source File -# Begin Source File - -SOURCE=.\HitMiss.c -# End Source File -# Begin Source File - -SOURCE=.\HitMissI.c -# End Source File -# Begin Source File - -SOURCE=.\Inertia.c -# End Source File -# Begin Source File - -SOURCE=.\Inv.c -# End Source File -# Begin Source File - -SOURCE=.\ipGetANew.c -# End Source File -# Begin Source File - -SOURCE=.\Label.c -# End Source File -# Begin Source File - -SOURCE=.\Laplace.c -# End Source File -# Begin Source File - -SOURCE=.\LevWind.c -# End Source File -# Begin Source File - -SOURCE=.\LN.c -# End Source File -# Begin Source File - -SOURCE=.\Log.c -# End Source File -# Begin Source File - -SOURCE=.\MakePicName.c -# End Source File -# Begin Source File - -SOURCE=.\Malloc.c -# End Source File -# Begin Source File - -SOURCE=.\Mean.c -# End Source File -# Begin Source File - -SOURCE=.\MeanC.c -# End Source File -# Begin Source File - -SOURCE=.\MeanF.c -# End Source File -# Begin Source File - -SOURCE=.\MeanR.c -# End Source File -# Begin Source File - -SOURCE=.\MeanROI.c -# End Source File -# Begin Source File - -SOURCE=.\Median.c -# End Source File -# Begin Source File - -SOURCE=.\Morph.c -# End Source File -# Begin Source File - -SOURCE=.\MultC.c -# End Source File -# Begin Source File - -SOURCE=.\MultI.c -# End Source File -# Begin Source File - -SOURCE=.\Norm.c -# End Source File -# Begin Source File - -SOURCE=.\NormXY.c -# End Source File -# Begin Source File - -SOURCE=.\Not.c -# End Source File -# Begin Source File - -SOURCE=.\OpCl.c -# End Source File -# Begin Source File - -SOURCE=.\Open.c -# End Source File -# Begin Source File - -SOURCE=.\Or.c -# End Source File -# Begin Source File - -SOURCE=.\Pot.c -# End Source File -# Begin Source File - -SOURCE=.\Range.c -# End Source File -# Begin Source File - -SOURCE=.\Rank.c -# End Source File -# Begin Source File - -SOURCE=.\Refl.c -# End Source File -# Begin Source File - -SOURCE=.\RegGrow.c -# End Source File -# Begin Source File - -SOURCE=.\Roberts.c -# End Source File -# Begin Source File - -SOURCE=.\Rotate.c -# End Source File -# Begin Source File - -SOURCE=.\Scale.c -# End Source File -# Begin Source File - -SOURCE=.\ScBl.c -# End Source File -# Begin Source File - -SOURCE=.\ScFact.c -# End Source File -# Begin Source File - -SOURCE=.\ScNN.c -# End Source File -# Begin Source File - -SOURCE=.\SDev.c -# End Source File -# Begin Source File - -SOURCE=.\SDevC.c -# End Source File -# Begin Source File - -SOURCE=.\SDevR.c -# End Source File -# Begin Source File - -SOURCE=.\SDevROI.c -# End Source File -# Begin Source File - -SOURCE=.\Select.c -# End Source File -# Begin Source File - -SOURCE=.\SelInv.c -# End Source File -# Begin Source File - -SOURCE=.\SelMM.c -# End Source File -# Begin Source File - -SOURCE=.\SetErrno.c -# End Source File -# Begin Source File - -SOURCE=.\SetTag.c -# End Source File -# Begin Source File - -SOURCE=.\Shp.c -# End Source File -# Begin Source File - -SOURCE=.\Skewness.c -# End Source File -# Begin Source File - -SOURCE=.\SkewnessR.c -# End Source File -# Begin Source File - -SOURCE=.\Sobel.c -# End Source File -# Begin Source File - -SOURCE=.\Sqrt.c -# End Source File -# Begin Source File - -SOURCE=.\SubC.c -# End Source File -# Begin Source File - -SOURCE=.\SubI.c -# End Source File -# Begin Source File - -SOURCE=.\Thresh.c -# End Source File -# Begin Source File - -SOURCE=.\Transpose.c -# End Source File -# Begin Source File - -SOURCE=.\Var.c -# End Source File -# Begin Source File - -SOURCE=.\VarC.c -# End Source File -# Begin Source File - -SOURCE=.\VarR.c -# End Source File -# Begin Source File - -SOURCE=.\VarROI.c -# End Source File -# Begin Source File - -SOURCE=.\Window.c -# End Source File -# Begin Source File - -SOURCE=.\WindowR.c -# End Source File -# Begin Source File - -SOURCE=.\Xchange.c -# End Source File -# Begin Source File - -SOURCE=.\ZeroCr.c -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\gradient.h -# End Source File -# Begin Source File - -SOURCE=.\ipArithmeticAndLogical.h -# End Source File -# Begin Source File - -SOURCE=.\mitkIpFunc.h -# End Source File -# Begin Source File - -SOURCE=.\mitkIpFuncP.h -# End Source File -# Begin Source File - -SOURCE=.\ipGeometrical.h -# End Source File -# Begin Source File - -SOURCE=.\ipLocal.h -# End Source File -# Begin Source File - -SOURCE=.\ipMorphological.h -# End Source File -# Begin Source File - -SOURCE=.\ipPointOperators.h -# End Source File -# Begin Source File - -SOURCE=.\ipStatistical.h -# End Source File -# End Group -# End Target -# End Project diff --git a/Utilities/IpFunc/mitkIpFunc.h b/Utilities/IpFunc/mitkIpFunc.h deleted file mode 100644 index cec8e1266c..0000000000 --- a/Utilities/IpFunc/mitkIpFunc.h +++ /dev/null @@ -1,581 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * contains the function prototypes, type definitions and - * includes for the image processing functions - */ - -/** @mainpage - * @section QuickReference Quick Reference - * - * @link mitkIpFunc.h List of all functions @endlink - * - * @link ipArithmeticAndLogical.h Arithmetic and Logical Operators @endlink - * - * @link ipGeometrical.h Geometrical Operators @endlink - * - * @link ipLocal.h Local Operators @endlink - * - * @link ipStatistical.h Operators to calculate statistical values @endlink - * - * @link ipMorphological.h Morphological Operators @endlink - * - * @link ipPointOperators.h Point-Operators @endlink - * - * @link ipAdministrative.h Administrative Functions @endlink - - * @section Introduction Introduction - * - * This library contains a huge set of image processing functions. It includes - * operators of the following classes: - * @arg Arithmetical and logical operators. This class contains as well functions - * to add, subtract, divide or multiply two images or images and constants - * as functions to connect two images using the logical "and" or "or" operator. - * @arg Operators to transform the greyvalue of each pixel indepently of its surrounding - * pixels. In this class operators for brightness correction, contrast - * correction or to fade out single greyvalues are included - * @arg Local operators which use the surrounding pixel for the transformation. - * This could be a convolution or a filtering operation to detect edges or to - * perform a smoothing. - * @arg Geometrical functions which change the geometrie of the image like a - * rotation, a reflection, a transposition or a scaling. - * @arg Operators to calculate statistical values. The extreme greyvalues, the - * mean, the variance or the standard deviation of all greyvalues in an image - * or a region of interest (rectangle, circle or an area included by a polygon) - * are calculated. - * @arg Segmentation functions to find objects in an image. - * @arg Morphological operators which change the shape of the the objects - * shown in an image. This could be a dilation, an erosion, an opening or a - * closing. - * All images and convolution masks needed in theses functions have to be stored - * in the PIC image format. Because this image format allows to handle images of - * different datatypes and images of up to eight dimensions, the functions could - * be used to transform all these different kind of images. - * - * There's also an executable included to invoke the image processing functions from the - * command line. - * - * @section Installation Installation - * @subsection PlatformIndependent Platform Independent - * There is a platform independent tmake-makefile called ipFunc.pro. You need to get - * the free tmake-utility to use it from @htmlonly <a href="ftp://ftp.troll.no/freebies/tmake/ -"> ftp://ftp.troll.no/freebies/tmake/ </a> @endhtmlonly. - * - * @subsection Windows Windows - * The library as well as the executable are precomiled using the Microsoft Developer Studio 6.0: - * libipFuncD.lib and ipFunc.exe. The corresponding project file is ipFunc.dsw. - * - * @subsection Unix Unix - * There is a makefile, which should work on most unix platforms. There is also a special - * makefile for Sun Solaris. -*/ - -#ifndef _mitkIpFunc_h -#define _mitkIpFunc_h - -/* include files */ - -#include <limits.h> -#include <math.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#ifdef _WIN32 -#include <time.h> -#include <sys/timeb.h> -#else -#include <float.h> -#include <sys/time.h> -#include <sys/resource.h> -#endif -#include <mitkIpPic.h> -/* - Diese Datei wird in der mitkIpFuncP.h includet - #include <meschach/matrix2.h> -*/ -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -/* definition of constants */ - -#define mitkIpFuncERROR 0 -#define mitkIpFuncOK 1 -#define mitkIpFuncNOPIC_ERROR 2 -#define mitkIpFuncDIM_ERROR 3 -#define mitkIpFuncSIZE_ERROR 4 -#define mitkIpFuncFLAG_ERROR 5 -#define mitkIpFuncMALLOC_ERROR 6 -#define mitkIpFuncPICNEW_ERROR 7 -#define mitkIpFuncTYPE_ERROR 8 -#define mitkIpFuncUNFIT_ERROR 9 -#define mitkIpFuncDIMMASC_ERROR 10 -#define mitkIpFuncDATA_ERROR 11 -#define mitkIpFunc_ERROR 12 -#define mitkIpERO 0 -#define mitkIpDILA 1 -#define mitkIpOPEN 0 -#define mitkIpCLOSE 1 -#define mitkIpREFLECT 0 -#define mitkIpNOREFLECT 1 -#define mitkIpOVERWRITE 1 - -/* type definitions */ - -typedef enum /* mitkIpFuncFlagI_t */ - { - mitkIpFuncReflect = 0, - mitkIpFuncNoReflect = 1, - mitkIpFuncBorderZero = 2, - mitkIpFuncBorderOld = 3, - mitkIpFuncKeep = 4, - mitkIpFuncNoKeep = 5, - mitkIpFuncScaleBl = 6, - mitkIpFuncScaleNN = 7, - mitkIpFuncTotal = 8, - mitkIpFuncMinMax = 9, - mitkIpFuncAbove = 10, - mitkIpFuncBeneath = 11, - mitkIpFuncFlagI_MAX - } mitkIpFuncFlagI_t; - -typedef struct - { - mitkIpUInt4_t x0; - mitkIpUInt4_t x1; - mitkIpUInt4_t y0; - mitkIpUInt4_t y1; - mitkIpUInt4_t z0; - mitkIpUInt4_t z1; - } mitkIpFuncBox_t; - - -/* macros */ -#define IPFUNCMAX( x, y ) ( ( (x) > (y) ) ? (x) : (y) ) -#define IPFUNCMIN( x, y ) ( ( (x) < (y) ) ? (x) : (y) ) - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif -/* extern gloabal variables */ - -extern int mitkIpFuncErrno; - - -/* function prototypes */ - -mitkIpUInt4_t mitkIpFuncBox ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ); - -mitkIpPicDescriptor *mitkIpFuncConvert( mitkIpPicDescriptor *pic_old, - mitkIpPicType_t type, - mitkIpUInt4_t bpe ); - -void mitkIpFuncCopyTags(mitkIpPicDescriptor *pic_new, mitkIpPicDescriptor *pic_old); - -int mitkIpFuncSetTag( mitkIpPicDescriptor *pic, char *name, int type, int size, - int el_size, void *data ); - -mitkIpPicDescriptor *mitkIpFuncInv ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncEqual ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncRefl ( mitkIpPicDescriptor *pic_old, - mitkIpInt4_t axis ); - -mitkIpFloat8_t mitkIpFuncMedI ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t mitkIpFuncMean ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t mitkIpFuncVar ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t mitkIpFuncSDev ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t *mitkIpFuncGrav ( mitkIpPicDescriptor *pic_old ); - -mitkIpFloat8_t mitkIpFuncMeanC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t radius ); - -mitkIpFloat8_t mitkIpFuncVarC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t radius ); - -mitkIpFloat8_t mitkIpFuncSDevC ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t radius ); - -mitkIpUInt4_t mitkIpFuncExtrC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *center, - mitkIpUInt4_t radius ); - -mitkIpPicDescriptor *mitkIpFuncDrawPoly( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpFloat8_t mitkIpFuncMeanROI( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpFloat8_t mitkIpFuncVarROI( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpFloat8_t mitkIpFuncSDevROI( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpUInt4_t mitkIpFuncExtrROI( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts ); - -mitkIpFloat8_t mitkIpFuncMeanR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpFloat8_t mitkIpFuncVarR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpFloat8_t mitkIpFuncSDevR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpUInt4_t mitkIpFuncExtrR ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpPicDescriptor *mitkIpFuncFrame ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *edge, - mitkIpFloat8_t value ); - -mitkIpPicDescriptor *mitkIpFuncBorder ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncBorderX ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *mask, - mitkIpFloat8_t value, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncAddC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSubC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncMultC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncDivC ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncMultI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncDivI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncAddI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncAddSl ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t keep ); - -mitkIpPicDescriptor *mitkIpFuncSubI ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncPot ( mitkIpPicDescriptor *pic_1, - mitkIpFloat8_t exponent, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSqrt ( mitkIpPicDescriptor *pic_1, - mitkIpFuncFlagI_t keep, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncAnd ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncOr ( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncNot ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncLabel ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *no_label ); - -mitkIpPicDescriptor *mitkIpFuncThresh ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t threshold, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncConv ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncEro ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncDila ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncOpen ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncClose ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncHitMiss( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_masks, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncScale ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t sc_fact[_mitkIpPicNDIM], - mitkIpFuncFlagI_t sc_kind ); - -mitkIpPicDescriptor *mitkIpFuncScFact ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t factor, - mitkIpFuncFlagI_t sc_kind ); - -mitkIpPicDescriptor *mitkIpFuncGausF ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t len_mask, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncCanny ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpUInt4_t len_mask, - mitkIpFloat8_t threshold, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncRank ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t rank, - mitkIpUInt4_t dim_mask, - mitkIpUInt4_t len_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncMeanF ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t len_mask, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncShp ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border, - mitkIpUInt4_t mask_nr ); - -mitkIpPicDescriptor *mitkIpFuncLaplace( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncSobel ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncGrad ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncRoberts( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_mask, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *mitkIpFuncZeroCr ( mitkIpPicDescriptor *pic_old ); - -mitkIpPicDescriptor *mitkIpFuncExp ( mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncLN ( mitkIpPicDescriptor *pic_old ); - -mitkIpPicDescriptor *mitkIpFuncLog ( mitkIpPicDescriptor *pic_old ); - -mitkIpPicDescriptor *mitkIpFuncNorm ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncNormXY ( mitkIpPicDescriptor *pic, - mitkIpFloat8_t min_gv, - mitkIpFloat8_t max_gv, - mitkIpPicDescriptor *pic_return ); - -mitkIpUInt4_t mitkIpFuncRange ( mitkIpPicDescriptor *pic, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up ); - -mitkIpInt4_t mitkIpFuncExtr ( mitkIpPicDescriptor *pic, - mitkIpFloat8_t *min, - mitkIpFloat8_t *max ); - -mitkIpInt4_t mitkIpFuncInertia ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t **eigen_vect, - mitkIpFloat8_t **eigen_val ); - -mitkIpInt4_t mitkIpFuncHist ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t min_gv, - mitkIpFloat8_t max_gv, - mitkIpUInt4_t **hist, - mitkIpUInt4_t *size_hist ); - -mitkIpInt4_t mitkIpFuncHisto ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t *min_gv, - mitkIpFloat8_t *max_gv, - mitkIpUInt4_t **hist, - mitkIpUInt4_t *size_hist ); - -mitkIpPicDescriptor *mitkIpFuncSelInv ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpFloat8_t gv, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSelect ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpFloat8_t gv, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncSelMM ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t gv_low, - mitkIpFloat8_t gv_up, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncLevWin ( mitkIpPicDescriptor *pic_old, - mitkIpFloat8_t level, - mitkIpFloat8_t window, - mitkIpPicDescriptor *pic_return ); - -mitkIpPicDescriptor *mitkIpFuncWindow ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpPicDescriptor *mitkIpFuncWindowR( mitkIpPicDescriptor *pic_1, - mitkIpPicDescriptor *pic_2, - mitkIpUInt4_t *begin, - mitkIpFuncFlagI_t keep ); - - -mitkIpPicDescriptor *mitkIpFuncRegGrow ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t dim_seed, - mitkIpUInt4_t *beg_seed, - mitkIpUInt4_t *end_seed, - mitkIpUInt4_t border_label, - mitkIpUInt4_t region_label, - mitkIpFloat8_t std_fact, - mitkIpUInt4_t kind ); - -void mitkIpFuncPError ( char *string ); - -mitkIpPicDescriptor *mitkIpFuncRotate ( mitkIpPicDescriptor *pic, - mitkIpPicDescriptor *pic_old, - int *grad, int *order ); - -mitkIpPicDescriptor *mitkIpFuncTranspose( mitkIpPicDescriptor *pic, - mitkIpPicDescriptor *pic_old, - int *permutations_vector); - -void mitkIpFuncXchange ( mitkIpPicDescriptor **pic1, - mitkIpPicDescriptor **pic2 ); - -mitkIpFloat8_t mitkIpFuncSkewness ( mitkIpPicDescriptor *pic ); -mitkIpFloat8_t mitkIpFuncCurtosis ( mitkIpPicDescriptor *pic ); - -mitkIpFloat8_t mitkIpFuncSkewnessR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -double mitkIpFuncCurtosisR ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *begin, - mitkIpUInt4_t *length ); - -mitkIpPicDescriptor *mitkIpFuncFillArea ( mitkIpPicDescriptor *pic_old, - mitkIpFuncBox_t box, - mitkIpFloat8_t value, - mitkIpFuncFlagI_t over, - mitkIpPicDescriptor *pic_return ); - -char *mitkIpFuncMakePicName ( char *pic_name, char *extension ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpFunc_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpFunc/mitkIpFuncP.h b/Utilities/IpFunc/mitkIpFuncP.h deleted file mode 100644 index 63f5a57a7a..0000000000 --- a/Utilities/IpFunc/mitkIpFuncP.h +++ /dev/null @@ -1,191 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * mitkIpFuncP.h - *--------------------------------------------------------------- - * DESCRIPTION - * contains the function prototypes, type definitions and - * includes for the image processing functions - * - * AUTHOR - * Antje Schroeder - * - * UPDATES - * - *--------------------------------------------------------------- - * - */ - - -#ifndef _mitkIpFuncP_h -#define _mitkIpFuncP_h - -/* include files */ - -#include "mitkIpFunc.h" - -/* type definitions */ - -typedef enum - { - mitkIpFuncEroF = 0, - mitkIpFuncDilaF = 1, - mitkIpFuncOpenF = 2, - mitkIpFuncCloseF = 3, - mitkIpFuncFlagF_MAX - } _mitkIpFuncFlagF_t; - -typedef struct - { - mitkIpUInt4_t length; - mitkIpInt4_t *off_vekt; - mitkIpFloat8_t *mask_vekt; - } mitkIpFuncMasc_t; - -/* definition of macros */ - -#define mitkIpFuncCASE_FOR( pic, dim, mitkIpFuncSourceIndex )\ - case dim: for( mitkIpFuncSourceIndex[dim-1]=0; \ - mitkIpFuncSourceIndex[dim-1] < pic->n[dim-1]; \ - mitkIpFuncSourceIndex[dim-1]++ \ - ) - -#define mitkIpFuncFORALL( type, pic, pic_return, \ - mitkIpFuncSourceIndex, mitkIpFuncResultOffset, mitkIpFuncResultFunction )\ - {\ - mitkIpUInt4_t mitkIpFuncSourceOffset=0;\ - mitkIpUInt4_t i;\ - for( i=0; i<_mitkIpPicNDIM; i++) index[i] = 0;\ - for( i=pic->dim; i<_mitkIpPicNDIM; i++) pic->n[i] = 0;\ - for( i=pic_return->dim; i<_mitkIpPicNDIM; i++) pic_return->n[i] = 0;\ - switch( pic->dim )\ - {\ - default:\ - { \ - fprintf( stderr,\ - "sorry, only 1 to 8 dimensional data are supported.\n"); \ - pic_return = NULL;\ - break;\ - }\ - mitkIpFuncCASE_FOR( pic, 8, mitkIpFuncSourceIndex )\ - mitkIpFuncCASE_FOR( pic, 7, mitkIpFuncSourceIndex )\ - mitkIpFuncCASE_FOR( pic, 6, mitkIpFuncSourceIndex )\ - mitkIpFuncCASE_FOR( pic, 5, mitkIpFuncSourceIndex )\ - mitkIpFuncCASE_FOR( pic, 4, mitkIpFuncSourceIndex )\ - mitkIpFuncCASE_FOR( pic, 3, mitkIpFuncSourceIndex )\ - mitkIpFuncCASE_FOR( pic, 2, mitkIpFuncSourceIndex )\ - mitkIpFuncCASE_FOR( pic, 1, mitkIpFuncSourceIndex )\ - {\ - mitkIpFuncResultFunction;\ - ((type *)pic_return->data)[ mitkIpFuncResultOffset ] \ - = ((type *)pic->data)[ mitkIpFuncSourceOffset ] ; \ - mitkIpFuncSourceOffset++;\ - }\ - }\ - } - - -/* function prototypes */ - - -mitkIpUInt4_t _mitkIpFuncBox2d ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ); - -mitkIpUInt4_t _mitkIpFuncBox3d ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t **beg, - mitkIpUInt4_t **end ); - -mitkIpUInt4_t _mitkIpFuncError ( mitkIpPicDescriptor *pic ); - -mitkIpPicDescriptor *_mitkIpFuncDrawPoly( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *pol_x, - mitkIpUInt4_t *pol_y, - mitkIpUInt4_t no_pts, - mitkIpFloat8_t *a, - mitkIpFloat8_t *b ); - -mitkIpPicDescriptor *_mitkIpFuncOpCl ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - _mitkIpFuncFlagF_t kind, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *_mitkIpFuncMorph ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_mask, - _mitkIpFuncFlagF_t kind, - mitkIpFuncFlagI_t border ); - -mitkIpFuncMasc_t *_mitkIpFuncCompressM ( mitkIpPicDescriptor *mask, - mitkIpPicDescriptor *pic_old, - mitkIpFuncFlagI_t kind, - mitkIpInt4_t beg[_mitkIpPicNDIM], - mitkIpInt4_t end[_mitkIpPicNDIM] ); - -mitkIpInt4_t _mitkIpFuncExtT ( mitkIpPicType_t type, - mitkIpUInt4_t bpe, - mitkIpFloat8_t *min_gv, - mitkIpFloat8_t *max_gv ); - - -mitkIpPicDescriptor *_mitkIpFuncScNN ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new ); - -mitkIpPicDescriptor *_mitkIpFuncScBL ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new ); - -mitkIpPicDescriptor *_mitkIpFuncHitMissI( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_masks, - mitkIpFuncFlagI_t border ); - -mitkIpPicDescriptor *_mitkIpFuncBorderX ( mitkIpPicDescriptor *pic_old, - mitkIpUInt4_t *edge, - mitkIpFloat8_t value ); - -void _mitkIpFuncSetErrno( int error_no ); - -mitkIpUInt4_t _ipGetANew( mitkIpUInt4_t aNew[], mitkIpUInt4_t Index ); - -mitkIpPicDescriptor *_mitkIpFuncMalloc ( mitkIpPicDescriptor *pic_old, - mitkIpPicDescriptor *pic_new, - mitkIpBool_t over_write ); -#endif /* _mitkIpFuncP_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ diff --git a/Utilities/IpPic/CMakeLists.txt b/Utilities/IpPic/CMakeLists.txt deleted file mode 100644 index 718ec78ce8..0000000000 --- a/Utilities/IpPic/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(_options NO_INIT GCC_DEFAULT_VISIBILITY) - -if(MITK_WIN32_FORCE_STATIC) - list(APPEND _options FORCE_STATIC) -endif() - -mitk_create_module( - C_MODULE - WARNINGS_NO_ERRORS - ${_options} - PACKAGE_DEPENDS PRIVATE ITK|ZLIB -) - -target_compile_definitions(${MODULE_TARGET} PRIVATE -DMITK_IPPIC_COMPILE) diff --git a/Utilities/IpPic/ChangeLog b/Utilities/IpPic/ChangeLog deleted file mode 100755 index 6a887158eb..0000000000 --- a/Utilities/IpPic/ChangeLog +++ /dev/null @@ -1,23 +0,0 @@ -Tue Sep 16 09:03:36 1997 Andre Schroeter <andre@happy> - - * ipPic: - moved encryption to sepperate branch - -Fri Sep 12 09:02:34 1997 Andre Schroeter <andre@timor.dkfz-heidelberg.de> - - * mitkIpPicClone.c: - now can also clone if pic->data is NULL - -Sat Sep 6 21:28:48 1997 Andre Schroeter <andre@happy> - - * mitkIpPicPut.c (mitkIpPicPut): - now with return value - - * mitkIpPicGet.c (_mitkIpPicReadTags): - new parameter: encryption_type - - * mitkIpPicPut.c (_mitkIpPicWriteTags): - new parameter: encryption_type - - * mitkIpPic.h (mitkIpPicVersionEncryption): - new macro to check for encryption type diff --git a/Utilities/IpPic/Makefile b/Utilities/IpPic/Makefile deleted file mode 100755 index 0528c95549..0000000000 --- a/Utilities/IpPic/Makefile +++ /dev/null @@ -1,162 +0,0 @@ - -CC = cc -fullwarn -woff 1009,1174 -CC = cc -mips2 -CC = gcc -Wall -pedantic -ansi -Wno-comment - -DEBUG = -O2 -DEBUG = -g -COPTIONS = #-DDMALLOC_FUNC_CHECK -INCPATHS = -I. -I.. -I/usr/local/include -LIBPATHS = -L. -L/usr/local/lib - -CFLAGS = $(DEBUG) $(COPTIONS) $(INCPATHS) - -LDFLAGS = $(DEBUG) $(LIBPATHS) - -LIBS = -lipPic -ldmalloc -LIBS = -lipPic -lz - -.o:.c - -all = mitkIpPicInfo.o mitkIpPicType.o \ - mitkIpPicAddT.o mitkIpPicQueryT.o mitkIpPicDelT.o mitkIpPicGetT.o \ - mitkIpPicOldGet.o mitkIpPicOldGetH.o mitkIpPicOldGetS.o \ - mitkIpPicGet.o mitkIpPicGetH.o mitkIpPicGetS.o \ - mitkIpPicPut.o mitkIpPicPutS.o \ - mitkIpPicGetMem.o mitkIpPicPutMem.o \ - mitkIpPicCopyS.o mitkIpPicCopyH.o \ - mitkIpPicNew.o mitkIpPicClear.o mitkIpPicFree.o mitkIpPicClone.o \ - ipEndian.o ipFRead.o ipFWrite.o \ - ipError.o \ - mitkIpPicSize.o mitkIpPicElements.o \ - mitkIpPicTSVSize.o mitkIpPicTSVElements.o - -DISTFILES = Makefile \ - mitkIpPic.h mitkIpTypes.h mitkIpPicOldP.h mitkIpPicAnnotation.h \ - mitkIpPicOldGet.c mitkIpPicOldGetH.c mitkIpPicOldGetS.c \ - mitkIpPicGet.c mitkIpPicGetH.c mitkIpPicGetS.c \ - mitkIpPicPut.c mitkIpPicPutS.c \ - mitkIpPicGetMem.c mitkIpPicPutMem.c \ - mitkIpPicCopyS.c mitkIpPicCopyH.c \ - mitkIpPicNew.c mitkIpPicClear.c mitkIpPicFree.c mitkIpPicClone.c \ - mitkIpPicAddT.c mitkIpPicQueryT.c mitkIpPicDelT.c mitkIpPicGetT.c \ - ipEndian.c ipFRead.c ipFWrite.c \ - ipError.c \ - mitkIpPicInfo.c mitkIpPicType.c \ - mitkIpPicSize.c mitkIpPicElements.c mitkIpPicTSVSize.c mitkIpPicTSVElements.c\ - *.ps - -all: libipPic.a picinfo pic2seq - -picinfo :libipPic.a picinfo.o - $(CC) $(LDFLAGS) -o $@ $@.o $(LIBS) - -pic2seq :libipPic.a pic2seq.o - $(CC) $(LDFLAGS) -o $@ $@.o $(LIBS) - -test :libipPic.a test.o - $(CC) $(LDFLAGS) -o $@ $@.o $(LIBS) - -libipPic.a :$(all) - ar rv libipPic.a $(all) - -ranlib libipPic.a - -install :libipPic.a picinfo pic2seq - cp mitkIpPic.h /usr/local/include/ipPic - cp mitkIpTypes.h /usr/local/include/ipPic - cp libipPic.a /usr/local/lib - cp picinfo /usr/local/bin - cp pic2seq /usr/local/bin - ( cd /usr/local ; rdist ) - -clean: - -rm *.o *.a core picinfo pic2seq test - - -#distname: version.c -# @echo ipPic-`sed -e '/version_string/!d' \ -# -e 's/[^0-9.]*\([0-9.a-z]*\).*/\1/' -e q version.c` > $@-tmp -# @mv $@-tmp $@ -#distdir = `cat distname` -#dist:$(DISTFILES) distname - -distdir=ipPic -dist:$(DISTFILES) - @rm -rf $(distdir) - @mkdir $(distdir) - @for file in $(DISTFILES); \ - do \ - ln $$file $(distdir) \ - || { echo copying $$file instead; cp -p $$file $(distdir); }; \ - done -# @tar --gzip -chvf $(distdir).tar.gz $(distdir) - @tar -chvf $(distdir).tar $(distdir) - @gzip $(distdir).tar - @rm -rf $(distdir) - -picinfo.o :picinfo.c mitkIpPic.h - -pic2seq.o :pic2seq.c mitkIpPic.h - -test.o :test.c mitkIpPic.h - -mitkIpPic.h :mitkIpTypes.h - touch mitkIpPic.h - -mitkIpPicInfo.o :mitkIpPicInfo.c mitkIpPic.h - -mitkIpPicType.o :mitkIpPicType.c mitkIpPic.h - -ipEndian.o :ipEndian.c mitkIpPic.h - -mitkIpPicGetT.o :mitkIpPicGetT.c mitkIpPic.h - -mitkIpPicAddT.o :mitkIpPicAddT.c mitkIpPic.h - -mitkIpPicQueryT.o :mitkIpPicQueryT.c mitkIpPic.h - -mitkIpPicDelT.o :mitkIpPicDelT.c mitkIpPic.h - -mitkIpPicOldGet.o :mitkIpPicOldGet.c mitkIpPic.h mitkIpPicOldP.h - -mitkIpPicPut.o :mitkIpPicPut.c mitkIpPic.h - -mitkIpPicGet.o :mitkIpPicGet.c mitkIpPic.h - -mitkIpPicGetH.o :mitkIpPicGetH.c mitkIpPic.h - -mitkIpPicOldGetH.o :mitkIpPicOldGetH.c mitkIpPic.h mitkIpPicOldP.h - -mitkIpPicPutS.o :mitkIpPicPutS.c mitkIpPic.h - -mitkIpPicGetS.o :mitkIpPicGetS.c mitkIpPic.h - -mitkIpPicOldGetS.o :mitkIpPicOldGetS.c mitkIpPic.h mitkIpPicOldP.h - -ipFRead.o :ipFRead.c mitkIpPic.h - -ipFWrite.o :ipFWrite.c mitkIpPic.h - -mitkIpPicSize.o :mitkIpPicSize.c mitkIpPic.h - -mitkIpPicElements.o :mitkIpPicElements.c mitkIpPic.h - -mitkIpPicTSVSize.o :mitkIpPicTSVSize.c mitkIpPic.h - -mitkIpPicTSVElements.o :mitkIpPicTSVElements.c mitkIpPic.h - -mitkIpPicNew.o :mitkIpPicNew.c mitkIpPic.h - -mitkIpPicClear.o :mitkIpPicClear.c mitkIpPic.h - -mitkIpPicFree.o :mitkIpPicFree.c mitkIpPic.h - -mitkIpPicClone.o :mitkIpPicClone.c mitkIpPic.h - -mitkIpPicCopyS.o :mitkIpPicCopyS.c mitkIpPic.h - -mitkIpPicCopyH.o :mitkIpPicCopyH.c mitkIpPic.h - -depend: - for i in *.c;do $(CC) $(CFLAGS) -MM $$i;done > t - diff --git a/Utilities/IpPic/annotation/Annotation.c b/Utilities/IpPic/annotation/Annotation.c deleted file mode 100755 index be51797736..0000000000 --- a/Utilities/IpPic/annotation/Annotation.c +++ /dev/null @@ -1,418 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * Annotation.c - *--------------------------------------------------------------- - * DESCRIPTION - * the annotation widget methods - * - * Author - * a.schroeter - * - *--------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)XipAnnotationWidget\tGerman Cancer Research Center (DKFZ)\t1993/09/17" }; -#endif - - -#include <X11/StringDefs.h> -#include <X11/cursorfont.h> - -#include "AnnotationP.h" -#include "icon_text.xbm" - -#ifdef SHAPE -#include <X11/extensions/shape.h> -#endif - -static void Initialize(); -static void Realize(); -static void Redisplay(); -static void Resize(); -static XtGeometryResult QueryGeometry(); -static void Destroy(); -static Boolean SetValues(); - -static void activate(); - -static void getDrawGC(); - - -static XtResource resources[] = -{ - { XipNactivateCallback, XtCCallback, XtRCallback, - sizeof(XtPointer), - XtOffset (XipAnnotationWidget, annotation.activate_CB), - XtRCallback, NULL }, - - /* change parent class defaults */ - { XmNtopShadowColor, XmCTopShadowColor, XmRPixel, - sizeof(Pixel), - XtOffset(XipAnnotationWidget, primitive.top_shadow_color), - XtRString, "black" }, - - { XmNbottomShadowColor, XmCBottomShadowColor, XmRPixel, - sizeof(Pixel), - XtOffset(XipAnnotationWidget, primitive.bottom_shadow_color), - XtRString, "black" }, - - { XmNbackground, XmCBackground, XmRPixel, - sizeof(Pixel), - XtOffset(XipAnnotationWidget, core.background_pixel), - XtRString, "Yellow" }, - - { XmNtraversalOn, XmCTraversalOn, XmRBoolean, - sizeof(Boolean), - XtOffset (XipAnnotationWidget, primitive.traversal_on), - XmRImmediate, (XtPointer)False }, -}; - -static char defaultTranslations[] = -" <Btn1Down>: activate()\n\ -"; - -static XtActionsRec actions[] = -{ - { "activate", (XtActionProc)activate }, -}; - -XipAnnotationClassRec xipAnnotationClassRec = -{ - { /* core_class fields */ - (WidgetClass)&xmPrimitiveClassRec, /* superclass */ - "XipAnnotation", /* class_name */ - sizeof(XipAnnotationRec), /* widget_size */ - NULL, /* class_initialize */ - NULL, /* class_part_initialize */ - False, /* class_inited */ - Initialize, /* initialize */ - NULL, /* initialize_hook */ - Realize, /* realize */ - /*XtInheritRealize, /* realize */ - actions, /* actions */ - XtNumber(actions), /* num_actions */ - resources, /* resources */ - XtNumber(resources), /* num_resources */ - NULLQUARK, /* xrm_class */ - True, /* compress_motion */ - False, /* compress_exposure */ - True, /* compress_enterleave */ - False, /* visible_interest */ - Destroy, /* destroy */ - Resize, /* resize */ - Redisplay, /* expose */ - SetValues, /* set_values */ - NULL, /* set_values_hook */ - XtInheritSetValuesAlmost, /* set_values_almost */ - NULL, /* get_values_hook */ - NULL, /* accept_focus */ - XtVersion, /* version */ - NULL, /* callback private */ - defaultTranslations, /* tm_table */ - QueryGeometry, /* query_geometry */ - XtInheritDisplayAccelerator, /* display_accelerator */ - NULL, /* extension */ - }, - { /* primitive_class fields */ - (XtWidgetProc)_XtInherit, /* border highlight */ - (XtWidgetProc)_XtInherit, /* border unhiglight */ - XtInheritTranslations, /* translations */ - NULL, /* arm_and_activate */ - NULL, /* syn resources */ - 0, /* num_sysresources */ - NULL, /* extensions */ - }, - { /* annotation_class fields */ - 0, /* extension */ - }, -}; - -WidgetClass xipAnnotationWidgetClass = (WidgetClass) &xipAnnotationClassRec; - - -static void Initialize( request, new, args, num_args ) - XipAnnotationWidget request, new; - ArgList args; - Cardinal *num_args; -{ - /*printf( "init\n" );*/ - - getDrawGC( new ); - - new->annotation.cursor = XCreateFontCursor( XtDisplay(new), - XC_hand1 ); - - new->annotation.icon_text = 0; - - if( request->core.width == 0 ) - new->core.width = 25; - if( request->core.height == 0 ) - new->core.height = 30; -} - -static void getDrawGC( w ) - XipAnnotationWidget w; -{ - XGCValues values; - XtGCMask valueMask; - - values.foreground = w->primitive.foreground; - values.background = w->core.background_pixel; - valueMask = GCForeground | GCBackground; - - w->annotation.draw_GC = XtGetGC ( (Widget)w, valueMask, &values ); -} - -static void Realize( w, valueMask, attributes ) - XipAnnotationWidget w; - Mask *valueMask; - XSetWindowAttributes *attributes; -{ - /*(*xipAnnotationClassRec.core_class.superclass->core_class.realize) - (w, valueMask, attributes);*/ - - XtCreateWindow( (Widget)w, - InputOutput, - CopyFromParent, - *valueMask, - attributes); - -#ifdef SHAPE - { - GC shape_gc; - Pixmap shape_mask; - XGCValues xgcv; - - shape_mask = XCreatePixmap( XtDisplay(w), - XtWindow(w), - w->core.width, - w->core.height, - 1 ); - shape_gc = XCreateGC( XtDisplay(w), - shape_mask, - 0, - &xgcv); - - XSetForeground( XtDisplay(w), - shape_gc, - 0); - XFillRectangle( XtDisplay(w), - shape_mask, - shape_gc, - 0, 0, - w->core.width, w->core.height ); - XSetForeground( XtDisplay(w), - shape_gc, - 1); - XFillRectangle( XtDisplay(w), - shape_mask, - shape_gc, - 1, 1, - w->core.width-4, w->core.height-4 ); - XSetForeground( XtDisplay(w), - shape_gc, - 0); - { - int i; - - for( i = 0; i < w->core.width/6; i++ ) - XDrawLine( XtDisplay(w), - shape_mask, - shape_gc, - w->core.width-4-i, w->core.height-4, - w->core.width-4, w->core.height-4-i ); - - XDrawLine( XtDisplay(w), - shape_mask, - shape_gc, - w->core.width-4-i, w->core.height-4-i, - w->core.width-4-i, w->core.height-4 ); - XDrawLine( XtDisplay(w), - shape_mask, - shape_gc, - w->core.width-4-i, w->core.height-4-i, - w->core.width-4, w->core.height-4-i ); - } - XShapeCombineMask( XtDisplay(w), - XtWindow(w), - ShapeClip, - 0, 0, - shape_mask, - ShapeSet); - - XSetForeground( XtDisplay(w), - shape_gc, - 0); - XFillRectangle( XtDisplay(w), - shape_mask, - shape_gc, - 0, 0, - w->core.width, w->core.height ); - XSetForeground( XtDisplay(w), - shape_gc, - 1); - XFillRectangle( XtDisplay(w), - shape_mask, - shape_gc, - 0, 0, - w->core.width-2, w->core.height-2 ); - XFillRectangle( XtDisplay(w), - shape_mask, - shape_gc, - 2, 2, - w->core.width-2, w->core.height-2 ); - XSetForeground( XtDisplay(w), - shape_gc, - 0); - { - int i; - - for( i = 0; i < w->core.width/6; i++ ) - XDrawLine( XtDisplay(w), - shape_mask, - shape_gc, - w->core.width-1-i, w->core.height-1, - w->core.width-1, w->core.height-1-i ); - } - XShapeCombineMask( XtDisplay(w), - XtWindow(w), - ShapeBounding, - 0, 0, - shape_mask, - ShapeSet); - - XFreePixmap( XtDisplay(w), - shape_mask ); - } -#endif - - XDefineCursor( XtDisplay(w), - XtWindow(w), - w->annotation.cursor ); -} - -static XtGeometryResult QueryGeometry( w, proposed, answer ) - XipAnnotationWidget w; - XtWidgetGeometry *proposed; - XtWidgetGeometry *answer; -{ - - answer->width = (Dimension)256; - answer->height = (Dimension)120; - answer->request_mode = CWWidth || CWHeight; - - return( XtGeometryAlmost ); -} - -static void Destroy( w ) - XipAnnotationWidget w; -{ - XtReleaseGC( (Widget)w, w->annotation.draw_GC ); - - XtRemoveAllCallbacks ( (Widget)w, XipNactivateCallback ); -} - -static void Resize( w ) - XipAnnotationWidget w; -{ - /*if( w->core.width > w->annotation.image->width - || w->core.height > w->annotation.image->height ) - XtWarning( "XipAnnotationWidget resized" );*/ - -} - - -static void Redisplay( w, event, region) - XipAnnotationWidget w; - XExposeEvent *event; - Region region; -{ - if( w->core.visible ) - { - if( w->annotation.icon_text == 0 ) - w->annotation.icon_text = XCreateBitmapFromData( XtDisplay(w), - XtWindow(w), - icon_text_bits, - icon_text_width, - icon_text_height ); - - XCopyPlane( XtDisplay(w), - w->annotation.icon_text, - XtWindow(w), - w->annotation.draw_GC, - 0, 0, - icon_text_width, icon_text_height, - 0, 0, - 1 ); - /*XDrawLine( XtDisplay(w), - XtWindow(w), - w->annotation.draw_GC, - 0, 0, - 200, 200 );*/ - } -} - -static Boolean SetValues( current, request, new, args, num_args ) - XipAnnotationWidget current, request, new; - ArgList args; - Cardinal *num_args; -{ - Cardinal i; - - Boolean redraw = False; - - /*printf( "setv\n" );*/ - - return( redraw ); -} - -static void activate( w, event ) - XipAnnotationWidget w; - XEvent *event; -{ - if( event->xbutton.x < w->core.width - && event->xbutton.y < w->core.height ) - XtCallCallbacks( (Widget)w, - XipNactivateCallback, - (XtPointer) event ); -} diff --git a/Utilities/IpPic/annotation/Annotation.h b/Utilities/IpPic/annotation/Annotation.h deleted file mode 100755 index 4c3bdc8b49..0000000000 --- a/Utilities/IpPic/annotation/Annotation.h +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * Annotation.h - *--------------------------------------------------------------- - * DESCRIPTION - * public header for the annotation widget - * - * Author - * a.schroeter - * - *--------------------------------------------------------------- - * - */ - -#ifndef _XipAnnotationWidget_h -#define _XipAnnotationWidget_h - -extern WidgetClass xipAnnotationWidgetClass; - -typedef struct _XipAnnotationClassRec *XipAnnotationWidgetClass; -typedef struct _XipAnnotationRec *XipAnnotationWidget; - -#ifndef XipIsAnnotation -#define XipIsAnnotation(w) XtIsSubclass(w, xipAnnotationWidgetClass) -#endif - -/* -** resource strings -*/ -#define XipNactivateCallback XmNactivateCallback - -#define XipCActivateCallback XmCActivateCallback - -/* -** new data types -*/ - - -#endif /* _XipAnnotationWidget_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ diff --git a/Utilities/IpPic/annotation/AnnotationP.h b/Utilities/IpPic/annotation/AnnotationP.h deleted file mode 100755 index f155393245..0000000000 --- a/Utilities/IpPic/annotation/AnnotationP.h +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * AnnotationP.h - *--------------------------------------------------------------- - * DESCRIPTION - * private header file for the annotation widget - * - * Author - * a.schroeter - * - *--------------------------------------------------------------- - * - */ - -#ifndef _XipAnnotationP_h -#define _XipAnnotationP_h - -/* superclass */ -#include <Xm/XmP.h> - -#if( XmVersion >= 1002 ) -#include <Xm/PrimitiveP.h> -#endif - - -/* public header for this widget */ -#include "Annotation.h" - -/* other headers */ - - -#ifndef XlibSpecificationRelease -#define XrmPermStringToQuark XrmStringToQuark -#endif - -/*private macros */ -#ifndef Min -#define Min(x, y) (((x) < (y)) ? (x) : (y)) -#endif -#ifndef Max -#define Max(x, y) (((x) > (y)) ? (x) : (y)) -#endif - -/* new fields for this widget's class record */ -typedef struct _XipAnnotationClassPart - { - XtPointer extension; - } XipAnnotationClassPart; - -/* full class record declaration */ -typedef struct _XipAnnotationClassRec - { - CoreClassPart core_class; - XmPrimitiveClassPart primitive_class; - XipAnnotationClassPart annotation_class; - } XipAnnotationClassRec; - -extern XipAnnotationClassRec xipAnnotationClassRec; - -/* new fields for this widget's instance record */ -typedef struct _XipAnnotationPart - { /* resources */ - - Cursor cursor; - XtCallbackList activate_CB; - Pixmap icon_text; - - /* private variables */ - GC draw_GC; - } XipAnnotationPart; - -/* full instance record declaration */ -typedef struct _XipAnnotationRec - { CorePart core; - XmPrimitivePart primitive; - XipAnnotationPart annotation; - } XipAnnotationRec; - -#endif /* _XipAnnotationP_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ diff --git a/Utilities/IpPic/annotation/CMakeLists.txt b/Utilities/IpPic/annotation/CMakeLists.txt deleted file mode 100644 index 8b13789179..0000000000 --- a/Utilities/IpPic/annotation/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Utilities/IpPic/annotation/Makefile b/Utilities/IpPic/annotation/Makefile deleted file mode 100755 index 7b954dbb5b..0000000000 --- a/Utilities/IpPic/annotation/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -CC = gcc -DSHAPE - -DEBUG = -g - -CFLAGS = $(DEBUG) -I../.. -L../../ipPic -L../../Xip - -LIBS = ../../pic/Pic.o -lEditres -lXip -lXm -lXmu -lXt -lXext -lX11 -lipPic -lm - -.o:.c - -all = main.o Annotation.o - -main :$(all) - $(CC) $(CFLAGS) -o $@ $(all) $(LIBS) - -Annotation.o :Annotation.c Annotation.h Annotation.h icon_text.xbm - -main.o :main.c Annotation.h ad.h - -ad.h :main.ad - ad2c main.ad >$@ diff --git a/Utilities/IpPic/annotation/ad.h b/Utilities/IpPic/annotation/ad.h deleted file mode 100755 index 4db90a1a50..0000000000 --- a/Utilities/IpPic/annotation/ad.h +++ /dev/null @@ -1,2 +0,0 @@ -"*background: gray75", -"*annotation.background: yellow", diff --git a/Utilities/IpPic/annotation/icon_text.xbm b/Utilities/IpPic/annotation/icon_text.xbm deleted file mode 100755 index d38f1e15a5..0000000000 --- a/Utilities/IpPic/annotation/icon_text.xbm +++ /dev/null @@ -1,13 +0,0 @@ -#define icon_text_width 25 -#define icon_text_height 30 -static char icon_text_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfc, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Utilities/IpPic/annotation/main.ad b/Utilities/IpPic/annotation/main.ad deleted file mode 100755 index 25cb50de92..0000000000 --- a/Utilities/IpPic/annotation/main.ad +++ /dev/null @@ -1,3 +0,0 @@ - -*background: gray75 -*annotation.background: yellow diff --git a/Utilities/IpPic/annotation/main.c b/Utilities/IpPic/annotation/main.c deleted file mode 100755 index ad280d5dda..0000000000 --- a/Utilities/IpPic/annotation/main.c +++ /dev/null @@ -1,181 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -#include <Xm/Xm.h> -#include <Xm/BulletinB.h> -#include <Xm/DrawingA.h> -#include <Xm/PushB.h> -#include <Xm/Frame.h> - -#include <mitkIpPic.h> - -#include <pic/Pic.h> - -#include "Annotation.h" - -/*#include <X11/Editres.h>*/ - -static String fallback_resources[] = { -#include "ad.h" -NULL -}; - - -static int n; -static Arg args[20]; - -void activate( Widget w, XtPointer data, XtPointer call_data ); - -extern void _XEditResCheckMessages(); - -Widget button1; -Widget button2; - -Position x, y; -char* text; - -main( int argc, char *argv[] ) -{ - XtAppContext app_context; - Widget toplevel, bb, pic, annotation; - /*Widget button;*/ - - - toplevel = XtVaAppInitialize( &app_context, - "Test", - NULL, 0, - &argc, argv, - fallback_resources, - NULL ); - - XtAddEventHandler( toplevel, - (EventMask)0, - True,_XEditResCheckMessages, - NULL ); - - n = 0; - XtSetArg( args[n], XmNheight, 400 ); n++; - XtSetArg( args[n], XmNwidth, 400 ); n++; - - XtSetValues( toplevel, args, n ); - - bb = XmCreateDrawingArea( toplevel, "bb", args, n ); - XtManageChild( bb ); - - - n = 0; - XtSetArg( args[n], XmNx, 200 ); n++; - XtSetArg( args[n], XmNy, 100 ); n++; - annotation = XtCreateManagedWidget( "annotation", - xipAnnotationWidgetClass, - bb, - args, n ); - XtAddCallback( annotation, XipNactivateCallback, activate, NULL ); - - n = 0; - XtSetArg( args[n], XmNx, 0 ); n++; - XtSetArg( args[n], XmNy, 0 ); n++; - XtSetArg( args[n], XipNquantisation, True ); n++; - XtSetArg( args[n], XipNpic, mitkIpPicGet( "../b.pic", NULL ) ); n++; - pic = XtCreateManagedWidget( "pic", - xipPicWidgetClass, - bb, - args, n ); -/**************/ - XtRealizeWidget( toplevel ); -/**************/ - { - mitkIpPicDescriptor *pic; - _mitkIpPicTagsElement_t *head; - mitkIpPicTSV_t *tsv; - - pic = mitkIpPicGetTags( "../b.pic", - NULL ); - tsv = mitkIpPicQueryTag( pic, "ANNOTATION" ); - if( tsv != NULL ) - { - head = tsv->value; - - tsv = _mitkIpPicFindTag( head, "TEXT" )->tsv; - text = malloc( strlen(tsv->value) ); - strcpy( text, tsv->value ); - printf( "%s\n", text ); - - tsv = _mitkIpPicFindTag( head, "POSITION" )->tsv; - x = ((mitkIpUInt4_t *)(tsv->value))[0]; - y = ((mitkIpUInt4_t *)(tsv->value))[1]; - printf( "%i %i\n", x, y ); - } - - mitkIpPicFree( pic ); - } -/**************/ - XtVaSetValues( annotation, - XmNx, x, - XmNy, y, - NULL ); -/**************/ - XtAppMainLoop(app_context); -} - -void activate( Widget w, XtPointer data, XtPointer call_data ) -{ - static Widget box = 0; - - /*printf( "activated\n" );*/ - - if( box == 0 ) - box = XmCreateInformationDialog( w, "info", NULL, 0 ); - - XtVaSetValues( box, - XmNnoResize, True, - XtVaTypedArg, - XmNdialogTitle, XmRString, "HELP", sizeof( char *), - XtVaTypedArg, - XmNmessageString, XmRString, text, sizeof( char *), - XtVaTypedArg, - XmNokLabelString, XmRString, " Close ", sizeof( char *), - NULL ); - - XtUnmanageChild( XmMessageBoxGetChild( box, XmDIALOG_CANCEL_BUTTON ) ); - XtUnmanageChild( XmMessageBoxGetChild( box, XmDIALOG_HELP_BUTTON ) ); - - XtManageChild( box ); -} diff --git a/Utilities/IpPic/doc/CMakeLists.txt b/Utilities/IpPic/doc/CMakeLists.txt deleted file mode 100644 index 8b13789179..0000000000 --- a/Utilities/IpPic/doc/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Utilities/IpPic/doc/ipPic.pdf b/Utilities/IpPic/doc/ipPic.pdf deleted file mode 100644 index c43cce9032..0000000000 --- a/Utilities/IpPic/doc/ipPic.pdf +++ /dev/null @@ -1,2879 +0,0 @@ -%PDF-1.0 -16 0 obj -<< -/Length 17 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p!dUPTYSsU&s;PJF4NtMh_CC!Am&G0#<L.=Fbp:3?!g16\,6q -BJGJV6jFqb.*N#<NM;"*Lu;\U)i+s0M1FT+1S.C@'%+M)@iQ>Fk<j6V_DjNPe)u@. -BoEd/Vc3l<Gu3.61_:.1[!CT`1,Pe%B6=$!,.oWI9J6K/%FAC"SdYgcX$o4n1:(D. -=A%Cm'8r2Xl?-9ak+"->;J5#n%E^1ac-U7H0N;XC*=tP,3&-_HD_Tbh[9CfQ\lBJ' -!fD;+e8d^PN/dH!]tVYZ5M4:p>92#X9to,9FaRAOVhN.Tnp$\Lf(2\P*6UCJ8/2Wr -dMq(g?;"$':Krd<Din6d;Ir_GI=:c+rEEb&W[m:LVM9qk_R@7:P.Vci.*uoN.11G8 -^nqEa[f2$,9.^N9!<V^!TLt.%q5l>cYm;jo88<]@mi5C>!DOf1e1pAY>cFI&:d>en -8YU#97]rK0ii$`VW#N0r".LFEl0:%VUOd)g*i>\hJFJ9@BPe_6$.rFW8(+\^VR[k_ -)VE(rCGqU'Z34dsaNi7BccaL"_]UT@4)64<Z7'-E.5"hDm`k0UCI'PYj,C]F1Y[g6 -d&9KIlVYocM^d&\9cl\\Z(n-"b>_Ip,cWYjPtjF/NA2c8'fAK+dZlnb:<im'IjW8M -+qbbi$11GX<fW&=9WusRG?_K'9n?9;+f,aKd1S#K:t'QXQl+3@'[Jt:2Tq9<4-m4H -B$?7:[c:TD26-+MD-b;mh!uk/=P)/1+rH&LD/j7;=4;q3eJDn1F5F>_5@RX%[=_cC -QNal9i,UrjA`-Z7V+et7L*]OQPkF3m<Rd;uK\SLt4\=:nFVf@5q(;&J@sBn/IGn5? -)14DPPd29;iL4n*4A^KMcfH&<EYg443dIHSfDMsk7Mch8_8'q,Fe;NMW+[)_3kD"n -eZKhq(^<]<H*D$"Y0=(a;hagrB26.:Io&,e"-`/5<\[0"F_3#5]G>a/,cME>G<<6R -'h"QuR8uC/"qe<0K5r_1cc<UYI9F)C[I/_6a`*OWPdWOi15a9EC+I4.6D@"#%S7iM -(Pp.I"=bbnJkCZ>>ndLFXFZhe.O\saW3:H`\.fV_K.-"G%V$@&16,d6W&5ij17kb( -!hr-u$#-'N3K1k#jlh[+W8'1hA'i@W%YKl.2Yu:NBYsYG]+NkmLuVZ29Yi&,A8%XK -64+*OJJEFu/1Nk\'Wn"g&2=?MZm]t9%Nm:@JIj65!e?.>_E^j&+UfKHa;k3#0a<,C -jdct8/HHpZ)M'Pb%YZ<,$:uc[#&#]U'$+Da+cHY\E%VY)!1jmtCY&S^d&90r*_RZm -.j9^2P8RgK!M2#P$XfVU682RTK6V5A+J]d*:f&/586lRR.OBa\nEq'+It*5IZi`!o -9FGq?-V\J$Tn?he!_?.=`:c3Sa+W[_&VuKd%N.RQQQW#%FH0rC3j"Up*fKrTLe),J -!f0>hidiD;L%,A@Bb_t)ll1\?/0RPE.4!r<4"'DR9Lm1/![Qj-PJIMO"H]2i!^K0\ -EX\VYJtb^S)(I3<aLDrIDXh;b<e8QCnO2Na0r(ccOHVAWSLB++_C/:hEqh"O7<hj! -5ql@0VDWmsMX,nR%qZ&P!g<_hfh#XN;\#mtKlB9rJ5`Rmm_j`>0T9<EjA'J%iN+I` -VEg&mHR"Y^<P4Za)ab0NJ^_78"V;D2An##:Wb-W'[LYS&<;rNn#_EUs&424&%jE8n -#U,?^QW6U",Z$X/cU(C(6+UijU`%*@B!aokV*>0a9\DpHcI5ET8Te#g6\=64e1+/J -B8%P0eT*.ja\+g4"a[?%Kc*eL]hU,Oeu6W0SH]Cc7[#\R[hI98e6+N@Y"`f0"'0Np -ih8`"eV:F4$BniNi=1gd2SU+F[[G:6F`$h1W77,q=-82p,)!,A[A%\2)D-Xq$'?JI -)YOUjV5+<MM81%!:L+@YE2g9LbQC+<K0dYm:j-Tr=DMd^Xim@oZSA7/3kns;PF+27 -]"V9YhQJM:9t6'TH/.^b:ef"e\p#(U>8lsNXaPr'<A:-&"Z',6V+`g,R\*]<WHuaO -OX1g$pCQ*;:9Tpi\+^*_R>;GfmBsI58t;oDRr1_I4INnW/u.;t'n);m5;kEnGI5l4 -XdhFhTJ!e8:dPC+?0k=N,T9$DPRCoNPAud`A_4Sn[f]MF2['5Ikm$(o(rHVq"9D%K -LBl'B,?/KN^u9[h@uC#P=i(@,9U&D`>XN4f4!Nr*SH8j_C(pi[98*m-**&OmPT+Hs -3HkdpB(i%kc=XRhLshN'cW0R!QE0i!2:nA<Y;5fn>F(u2B0<u2Z`jc_lGkQe]57ps -o6/BC3qML1\YCOLHI*@PGe##(T?00n-,_Y_;Q;q^c&S8Q\n*O/[+S&ar>jEV"9~> -endstream -endobj -17 0 obj -2374 -endobj -4 0 obj -<< -/Type /Page -/Parent 5 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font 18 0 R -/ProcSet 2 0 R ->> -/Contents 16 0 R ->> -endobj -18 0 obj -<< -/F2 7 0 R -/F4 9 0 R -/F6 11 0 R -/F8 12 0 R -/F10 14 0 R -/F12 15 0 R ->> -endobj -6 0 obj -<< -/Type /Encoding -/Differences [ 39 /quotesingle 96 /grave 128 /Adieresis/Aring/Ccedilla/Eacute -/Ntilde/Odieresis/Udieresis/aacute/agrave/acircumflex -/adieresis/atilde/aring/ccedilla/eacute/egrave -/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis -/ntilde/oacute/ograve/ocircumflex/odieresis/otilde -/uacute/ugrave/ucircumflex/udieresis/dagger/.notdef - 164 /section/bullet/paragraph/germandbls/registered/copyright -/trademark/acute/dieresis/.notdef/AE/Oslash - 177 /.notdef/.notdef/.notdef/yen 182 /.notdef/.notdef -/.notdef/.notdef/.notdef/ordfeminine/ordmasculine/.notdef -/ae/oslash/questiondown/exclamdown/logicalnot/.notdef -/florin/.notdef/.notdef/guillemotleft/guillemotright/ellipsis -/.notdef/Agrave/Atilde/Otilde/OE/oe -/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright - 216 /ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright -/fi/fl/daggerdbl/periodcentered/quotesinglbase/quotedblbase -/perthousand/Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave -/Iacute/Icircumflex/Idieresis/Igrave/Oacute/Ocircumflex - 241 /Ograve/Uacute/Ucircumflex/Ugrave 246 /circumflex/tilde -/macron/breve/dotaccent/ring/cedilla/hungarumlaut -/ogonek/caron - ] ->> -endobj -20 0 obj -<< -/Length 21 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)1b1"U_H'n3Cf`onh`B1</h;od]iqT ->:LEu7\TpNi++GZN8s'QnPI7h4+`B"Jk<=7:,8A6VW0t,dVUb0KEP^Sb[;hSRgalS -BY[MO.MAMnfT=6>A-E;GK$gg`@PWQK.E5!%MP=_tPmpbU/Y7VD.LL%cHH<U<+>+!) -@mS4U;BQneL/9%,J8&U5%*#&7rJ(+V^JO3J>.K=VLrEjYfaO0F/XRE8#.`J&P0GA6 -6%uXbVM%c:2k:D4PAup!9d(-?"@?6.Zn8g,DMH?>b60[:)9(3%TINM[O7#CTZ$,c= -BG;0+L(e]G@ga97LEh`%mra'MhogWqX9`8TTh?X2LBrc.kW+T:B]]j4BXku@N680' -2i^^"coR0(39E@blG2193m/bP3fTh@5j5dsWpm5D89.gr-4,jF)[=,t?lLJ/pma%S -+\5cT2CZF<\dbq:J/P)"9@igXdL3:j6o$lf^kON?KJL@gE7-VcY/&IGNfn4?*%M,] -RMl>Be.XOVnd&b?%BnDr)%>pQ&f+1*Leo7Sj(R@3Nf&YT2iPYImd#SCQr#K2o&rq: -bi(hZ3moi"!]CLF>k'_,PY?fc^L<dR4M(]_dPB='6]"d$1r>RH^@Xs6RD13gJi?Nj -<'2p'"$Ks+L1.aP$k/9kK/\X%X5`JAUD&G;Ne9mZif2MHKG6a&[.H,5'Zf>k,3)D" -78\uIdm/qEFfdTY0U._]bglc3M+RA"jtb#eP`\B?nH`V]=I3,e3<noQI/['i.+"nr -\!5`)<;0Z]G(s%";*[I5rITl';W?W930cm6ce(+Ld%Q9u%1?LraH1=V@$(pX,iTP. -*/4V(VCNqHQM&%k.CVKF+f[McYURq`1BgP8oOUknKbmc0U(,#/m6SFcNbsd6CsEE_ -[qK%(Kjg>aCPc>`FNKIcphc'TA'?8eQIE]7SfEFd]Cr^n)3sBRAQagedSnW77p+iS -nB"K2<>CH0@JGh5aCcD[$XDq\>oUn_npWI;"VnZpS`T@:Tc[Y4'mn9u\@e6T"Tm3a -psE!W"Sg31N'54U;^1INWnll8,*#s"[Q-C_#:VU`_fc;Ac&/mb2t[%/OuDN0K@qYq -RDA/'^O\hOa3d7L(Z%qT%H&#Q%j!`6\(14k4`=#]AT#jSCG3=-"-DAG(pVX].P*Kd -<.<-A,*NLFL'!UIb#=Wo;Fgf(,_SZ5A\l5T$G`GVZ"Ake(EsrGb;#D,(1&"!@Vp^S --o3h2%X_N>2LfEeSNDVF)]i`gKl%DMOOSppQ$[aP$;Cr)Ap2)H";<pM-2'<BgoQnu -Irc-s7^W@mU^qc<%dKPq,m_*b(H<Ni_1`,KPh$aZJP-+V:oJsIU)oRZCk!RYi[`s* -Q@kY#":0RlVa0J_@r'"a-5#;q<sYOe<),Q:_-3/'\@YA>(ClC72b#+'X(.Tq5r!ck -Kd<l@,Q$A<XPjLG3%19D1&D.T_5sj'1@!r!C(.(-%Q]n_"=%#^31th,L:.A7@m[j3 -&r7Jj+QX1Nis_%sGhj$Y(s1S@Y$gC/S4Veme&Y\E;ePWKWhufHeskH`C3:nY(#q4R -7+RS9NDD]?\H[UU3.d!LYX!_8*M\QFIaQ;G`)aaBh/^JN1QW;:\`B%46K*V(Ao30( -!>ZC7A;b9XGI%]r.`#1"PMLId4=k\>t`:X,6*OO@F#XGVGr7%qaO86pj9QmllC -L<\83%4@Vf@C4QJ,ss$#"(MQ@'EWIlAG"uP<46jH?kc>@C^L7UH;NZKS5W%On*1OC -L^R1L/35nf*N4"U-ao/0p+Cqa/Ea%u0aO8[L8U;BDGB)c3BYaRaAEC(B.niM9P+ds -=3WjREpAN]ADW$:E_-]i']I!`R1n@LNNERl$6=lffdH$/?;U%SX:h\T(pe$g5hrE& -E8^b]jD\o8c56V<UM1?7Ci@\f$n)m%>A&U0Gj=?,X12)@PjqlbTrekX1r!35ot:]@ -jY/?B[qR5%i&_L!*Ph?o7pIp4/<N3T;W=rfC[CgH1[)<oa.XF2oV/"46nqN<3X?uM -a"DqSAX4Hr7mi(>9!D1f"$gQ):Z4,7ct&PrctX$2Yo!i+J2\(uO+)W[Be+^a,nP#\ -)MgC.^')f>UO\d=!n^d$`M"c_ZRf^N[Kn7;<euBiCeg,o$O.Fk.Zki_NY2A(.bN,u -K'[AjdA\oLpt$TtK-j>$Bfa4d:D[L@@L^YL8kR%GLueVW:9kk7,teBaAGi/p6'b=k -#/-@6SACSPl'KI6K.Q/D:QD]O?rOUS"CiEL9CXo`c6W<JJ>C5@JHbmP,VpnP,\qpM -?A$$=7fX2VfE-YrI`%h2&*PR<U<&@J";n5al)X_bFEWbo5iY+DD*5867]+WQJ.QDm -,G4V*JM#pi$):r5MUJe1#5Qed!sALgLe4e&.093ZU1-Q4<Z9&+"(Y"XC1Ko---+\' -3gh5R7<P$%-KkOi?`gC>$+;PAgMjX$dNWJi-IC%.QWe'>Q++4\mFZ;%\!)6UAoTpI -f@bd[CXNBY0S'AX)H=2AMu!k8EAO(3N/Ea<1((Ja#10Ao<:Ee*Tj`\LdQ<dokgL[O -Yr<.$gd?DPm#LuV7Kqm5-\q*W'8cL^$9WK5Q?#,YWHbk0#'q8WQ=PK"\JHMq=7d@" -m1Xt)VO>4\]:8+*okq>g7__4CUh/CGdl8DSWgYT8l)[pI2"t;?HAel^Y//^NO>5-d -(S5Buae\\ZB?Hb5YA16'.JVLhmQ=-NEIBcpS0nR/]jnQpU2SaIWrMOLA&!7_8^jrW --LQ2d(%k?#UGUS_k8coVpWQ_%3k(OEr]bunr>2A=LS+-,^V4us+mHZ.Ie?m:_>6?7 -A9C,$l@'hcqd!RfHj@=&rO8u+Ncjg&f7rWTU`0.^F6L=;V"n9]h(Sc^oD9WWo6b30 -plK7qHl(0*4p14uN[r]YTAo4O8'CC_^%m/%g&-*O$=a"tV89u(`H=urIJck?%ANad -3qo?q"q@.MYQWI;#Vp4Lp<Ol^:5\9_3(FMQ;kS0G_Aq%d&k<&\-LMH5A)_M2hZ49O -"D!$PV>f5Q[.4`Hk=mT/:Nk44Pj^9W"gB9Lc928*jS`Vjk`<5pW1G>RK'prOihW[G -&9dgYEsD%^e#mfT0&6\K#mS`TnLlHOn6ZMQoER%>V[YIlU3&ob%1$E&-_`pM_F=gK -DEKM`_SQ^5i`ceDCb3MT-LaJ3Jp8ETHmf'E5c"HIb0iJK5/uMs_#s63"<%]E*Xot8 -6H+7<@[9Cb8J"P_!C3@[9ChNQ*n)Lp+Y3sE!mKWI(;[72dnrBZ;*;`]>8.QM'QG]>iW9~> -endstream -endobj -21 0 obj -3304 -endobj -19 0 obj -<< -/Type /Page -/Parent 5 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F8 12 0 R ->> -/ProcSet 2 0 R ->> -/Contents 20 0 R ->> -endobj -25 0 obj -<< -/Length 26 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+k+HM\YiWE." ->W!'5_uhudfK`.B(<`pl+=LnYRLSB]EKK#p0Gq`>iW3`:D\e9KKg;@E;@4Nr*2Kk@ -GoAmK.Ro.HCES5K+<"1RJcWC"A1ej].gF_<:rd]?JqXqk#mcne&/3.%!Z=+j<$L;D -@ZmF`'Lf&gUm"*_g2SDV6KhIm/K@&u)@Qj2l6RB)+>s:Y@'$5-5RJEg@Tn(P^Gg6Q -NM1\jr,Q5Fe^\F(90JTeZ&(kb_bCubjA`\t#rp.P6FR)ict3Ag`nFf[QjZBp)MD_# -_Lk,Y=">r,c'aF-H^eo$d'b>P$=],P7J?_rY\Yg"`/9LU\ge"O;S&[*b/2)X\B=^, -M?FG,ClU]P;skKV+_o"8W54it-ji9hN$*pc/39M\$$]8`Ks9cKL.1&p%g8UmY[SK) -C18I5MM^[X(INaeE#^:BX84l9K1O-D$tChh)i##Q@MZslP\V5<nF0\=L<=mr%7TJk -4!Vij5bp/pK*^ZrN.Ctb2iM7FgFS>N%co!DsH6^$F<02*#nKeeC(4HUEeK?2t0 -N8p#:3"5s\`\<C2+Po$ee%jF,cTuAM5>)[nD$3M787O?S'K_LI9d3-a2qE*Gh*&N8 -K`<W#2+7aM<KeDW)V,U1cn^7UJ<D(0U+kFa%C:/S(;s5&B0M&M4;2)Foj&"^7lDo` -=\[q<h+Rqb=Q#*tF2Zm=>%)QS(u!q;ZU%+4m=SIbQOlt;Nu'Co9\ic]gcAaV'WF>i -o#OZrbDU\(c-VdL>AtgM-3,`ZUO_$."sMF!.>kqAMiZ0VS`>!L2lLS1<B&IC+gfnY -4--3U&<JZ."!m4m"9Wnm&.Be&5U>&.4Jd`[d]IXib<`jMVS44**A9qt4gPY'&I%50 -#f<O1+c:kE%)q1&CpY'g[5IKU-5I@=%`@fB:aQJmR&L&g)\0oom.ZJ8,=C.<\ZF#+ -VWk8O_FU1@#bo;u/I=Nlh]M8C4c-=Wd2)8cDh9[+,Dr`Yd2!sfmk%L"a9V~> -endstream -endobj -26 0 obj -1050 -endobj -22 0 obj -<< -/Type /Page -/Parent 5 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R ->> -/ProcSet 2 0 R ->> -/Contents 25 0 R ->> -endobj -28 0 obj -<< -/Length 29 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+k+HM\YiWE." ->W!'5_uhudfK`.B(<`pl+=\<=Qjq&&H2rJ)1lmPa@sG@g`$tp%MNC[9:us!b$cp`j -&Q1G?K32g6JZuY$'cW*$6K-#6WbnaN%!NAp-rEteOGSWf!Bc;`+d:$e67r\D.4Q6e -6s?*!8MhD]VZ<E`g5%\\d-.q>N'`FhU(!n'^emc?ON@b/6]59.NC]('/ee2+*nQbj -Bf+?iU_:KoK5\d';73uq3>W)U`Ck`SP"ET$Z'C+fiYSa:CGmmBJ@'&JK14fX#RC~> -endstream -endobj -29 0 obj -329 -endobj -27 0 obj -<< -/Type /Page -/Parent 5 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R ->> -/ProcSet 2 0 R ->> -/Contents 28 0 R ->> -endobj -33 0 obj -<< -/Length 34 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP5`,^h.2[Y(,)T!ITMZK*#*ML< -;_c5AD^?8fkVg!u(dW0\$jSe-*>]nB2?JbDXCaFW$6%Z>e:Ej)?ZI'ETm?TK]0W0j -iT(bi-(@gGLtP7cZ%19+EkI<"3%QBp[03*u-0&FR[jF)$Mak7GHtK3SX$HqpCF>.c -Obq&'SSg=''O/5-7AF;4cs/CA?LOVN^2.g(#U)`Nrrif2;D*iY;]q;I_2>nt,(Tj) -)^CDYjS0oo>*p9R6+d13L.p67'Fpl\dP?g"(s<#t+B#_F/?6:uZ9b^2+H!QM^g%^* -cYu]1%0K/`&.F29`]B*a5j/bM8V#kYNe=-(&.HI$j:De'OPVdR6O;ElN`$_22[kkF -X:RqnGhtKADIT^/+c<jU'Fk3nhDbss/=8@g8@[h39VY/6&.X=\oJd:)*1/XC,<YTN -#%<m94Nt^.(chiLEk&;B:g88OTl>g$)TP.V/GH=rA)nNFLu;)Y%&74J5Qh-6N?h(o -C_6h>mP;Np_2Bj]:nk!U@3*Cm\54O^j)e<=LB0h"?,atQ@^&eQ6lbgNM3FtI\Fi06 -):`kG4=ULX[>l+."3BFQbG0`B0oR>b5U"gb'/g_^"14:LfsT=6(T+V:9,^o5j3j>W -G"'7^%!,[F16,>\N>Q'E=D[g[!hsr7$MR)!'M?7g`A07P/>J(nF;3,Z7.RkPG>D,< -q)sB5..JqoZ"+Q$:()e@3_qLJjtoeBABHW&=e+e5N&b_.aP'8!K-BC*>amV[ZRi/7 -g6r'hTiD`Mi@bYI&C6m0@r1Wil>[iBJ`>m:%,M*rC`M*d45L_j[8H'.-sj8Sg;2LQ -`B1_%X"D(a-<q"D<!aeI$UkGS5j)9GRcq6qd$^^('4-idL-#f!Geu15SNtggmL]Rk -(2)*Fa#RtDPZ=Mn=_D7Z"b?fsY7@g.l$uTY8C(O:Or3".FulM`?<Z*p5>U67M^&_] -nAF^8_kB>ZcHi(PCL5`g"++J8@?Q+q4jSe4+[/2T`"Z($E9hiL^UVA?!uasLM6n%N -,;]`A.P$%QgbcJ#nrcr2Z[C+OObWALrEq_oJ#nSPK$]mPhHGn-D1natG!+k+k].*J -KbZgKAr+?tDhZQS6UN[#&jdHl"ou"T!gjgr>5FRa0GYJ"p9+pX?tg$@F?'SnD#GP% -,>^s'1,[^$$sfoC:,&45#&r#*T;XY4%@Jh,LOB1hZMY+cL,#_Okn%>3r(p2f3lP(o -*'ltD77#3#"";+i+d?YIOD6ToK`p#\lm-6si:naFO9cNr<bnep0S0:u%O'msA7;;s -_r[U#R^.5JMU"hLGrWL+@kS;7pc0iiba*lt=bO%sTu]e&$pd6A:Tll=7N$/6d`ZT$ -:e?&SM/b7]]Ej7sTomG2\tc+k."C4/7)5dc(+(l\R_[W^75cS=;/BEPLVd@3q19UK -)ol*_iWPZgar=6c:2auL+A=4a.g)9^AZ2F(!f(+^h5S[B+9~> -endstream -endobj -34 0 obj -1633 -endobj -30 0 obj -<< -/Type /Page -/Parent 5 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F18 32 0 R ->> -/ProcSet 2 0 R ->> -/Contents 33 0 R ->> -endobj -39 0 obj -<< -/Length 40 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U'+:A&P0hQ)&,tJ2$/TA-o@)O.[c;D -ZZ&afD*o8h-r`ia`Z[aCd)JuT?mqlZ`8\]8TuF&k7AImLpA+ERNG?Oj1V*@A:'k9l -6+7^0<hOIc(gBUuqlmG=J&("-n3OuG:,^PhH(k=Qe7f,F`bG<P1_R,aU=CdF*S0O/ -17Hmu6OI01l=MuFKEbAkK\CB')+4]s8*IrONPi!C3=]Om!<%oGg\MHiK*^]H%jQVI -3J7J?gbK!7&FqjjYDC:$\I+^-M'M#SGV+UNi(u2Gj%M$2NagpE&.RYV'`AK9#f[R5 -iBYaHNPd/Bb67oc;D*iY:_`B-:D?3R,-`g:'F?"';W@siQr*cQ;T,psNh_ai2\)"\ -ALrN;9CD_;Z"+n:5gm$P'L5J?j"jCCW:N,E6X\>'%Zej0(!KI4O!Mj2@]5k%!uq(k -NH,$E&.L=daT)aC$pq%rEcTU`W2eUtoS*X5DW*2;66mJliL"U`"TkJ8-j_(7=sH3c -bf_8':AW\I4EUaFb6Ec3C)VikS(P2BFcC$;Kq_7]1Q8`O;At:`7<8]3Pd&:_9-LZp -$pG2`a>Ajn1^>rB".8<IN&IJF3Df9E%2$ucPYaCN:pB(?d]b852Vd<u>S%1l]s@FI -DlhOg6I_gQ!KFu&fFUJL!'rN&YDDcf"d#kP7)Z>i;':mO]Ab]lb]Hc?NWNnV1WER6 -HOC7MBP\ALg!j%b6\C[S2J1Wi!M<TtQu)]_XtXQ2U>phX3R,omj!/9kh.7a2R3`W[ -N?`tH1lQ:5dP5+(ORm@C"0SU3?/Ync!5N*?.M,XG[AA,_6P.G*N3Qo3W^JeY8[$)E -rf_=1Yf<H;lEc-D3JB$>MimMP?G7*Z42kqGDg.;`M!rr2nNXpQ`.>G5LqI[\j$S@6 -3=^\/FV(:J$7ZmJ+i%>$#%7LF*%5u7h%YT0V-(MYY9Lmr#"qS2JTuVog>WD@.)QSP -SnE).GCAq0i3D,4N8b5::R8f*$O^t<X[0FpkVsWsROV`KjX5_^o17"C"!a%GYC(sd -(OY]n&2Z?7S@ZG$P_`[\."1PUq*:;_rII=G%hJRL"@O4H;$k5d@*Ft@KVG4[g7&Af -=R_U-RS!rbBa1B`pRDjC8)=5"I]G.:4dWU5*b)j;Ws/5/B9Ngb/&DL0l37<C(kfdD -Ebsr6)oA7YP@8HA+YNtN,p6%7&^"X#OJqY"!uc+ZaT@C#0cD9I\J:jT)CAk1a-)7l -#,(#u61L(EUudID'$PNYMj>j*`gdEfR;H:>Q"I2Zio=.V-k2m"2CA[RRmV5uBP>L[ -/Mm$VOD5:jBLO'i7RA&HW,6InaVq^BW8Z@T.$Ef"9fY]p$PP3P#"YgV,I_o[>&!2e -@GN$#[!EW:be$cYj;=`"qT.1IE?q@(aH5W:>sk!)9S%jZ8'$Eu#\440kb;+JBB:q4 -m)"\H]Sj+abqi9sHq7Z(bKagG$<lfDS*5jkW``ZB=YohPn*,KN0OXpR"9MF4$8Y3A -A4Pdp:3LG>\H_QUIR>';%FMUD:%s&5W.Tn,..A->TNW&]i,teDKkc<PGd^_YF_d3o -(!"s3DraUCF)jYu"Yd&++8XN@1d$ddR28Di_mMd'E^p^`.N'$c)IgcC&!Xl^K;=.$ -6$("[:H'oX>g+REkOkhi9"Y^%3YZ[XD7Q>51qSC*.Lq]J$q_)Ja@!%sV)5>ueO]F: --iApnLWD0s=tU\+b&NE>d4QLgn<#4h[Tb1!I$L\FVr)Nh=Jqg[!stp+(24Bcb-b<5 -^eg;"$UY$t82@Ru-KJ+=Q&M_gk:AJ[oF-[?4ij>!Yq&aPgjQAqFDAdka#pJk9%[?6 -a^$gJN-m%`D[t^6=&aHSUk&M5?+'+2eDrhKJONYDW<-`JWMKb!aYfT)_6Kc>CI,dY -aL5(%3<JAh+H*;0LbPtM,iXOfM0lf^[b^Tgb<VBT+s0;)_RVX/?KT/^%RbDp&7Jfq -KnHUJ%4GU!=($3>N@[*q+J9O&TKjJNdh=o>`&Isg2T>!j(WJ_=(Yr!!afrBc]r>!+ -!WZ2]%u)/cfS$Zl9MLBb=p%%rh9ZAmH\3j-qSnoW$7SH_f`ItF$glYFTe(ja@_P:L -WEb7A.Ht,jUnl4b`]:/oc'n5\kfs<)'Ooj)Re(B><M7IjJrHU80V#Dg+i#S]J8(>= -W+*rm[%lV3N.t:-'LG=4T[]KCV=:pC;%=NpiE!ji;^R:CP$]A'SAU0P[Nu%hU/ba" -C4d1!Zq`#J9Bi;?KAuTWe,e#q@8P_p_YuT4JN+hVOI?u.;?[S$lW;7i1LdceBa_Gs -)SF<T(PD-V]qH&e73LPN0`CmWE4Q=H>R+m"U<'f6&1aC$01TM,1BqKDM!Q+a)"o;r -S'dUWK5q]U,';#CEF-i0M%dZ*`qr?Sl"j\+G0W$u:,KcIV9p:2KXb(D,(*F^WDmPm -@r;&r.WJ5#l?'"VJ1r;13#k;[QL\'/!*P,N,6j7TedUDT"t5JcS87"r[Lcs'J^,[? -Ef<YZK^<5^-od?q:.,gO0-N$6L_96a(%kZ9l*0KORZgOsa`5hqV(`'qJD:3XO(\P^"9~> -endstream -endobj -40 0 obj -2709 -endobj -35 0 obj -<< -/Type /Page -/Parent 5 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font 41 0 R -/ProcSet 2 0 R ->> -/Contents 39 0 R ->> -endobj -41 0 obj -<< -/F2 7 0 R -/F10 14 0 R -/F14 24 0 R -/F16 31 0 R -/F18 32 0 R -/F20 37 0 R -/F22 38 0 R ->> -endobj -44 0 obj -<< -/Length 45 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP7&e+'_9g>F2],8@!g/`+(HImX -_U1qOeQ*I(L6[&BT]ffF)GTA\DENhWK1R<YWL2[\2j0,nF;nKuN$,Y?"p:EE%Z@=u -)Z`A]<gQQ("V#=[qEW1`0=_N]d(RI9O1F)roF_NhP0Lkc5cG\gL/-cR(t1:6XSll? -5+kQg_i?XZEA&)eG#\7]8uYjC<sCHar+_,NV$Jh+(puo'.N9u'j1MoX_oUakN.WP& -&2?PNg@:i[M^Z4KE5IpEZCq7`1l_WfdP6WSE7QrWj1*k[6dX2Z&B&Q>:*C),GhEog -b_/6o6r>4'0o.$@L*VU1iu\]MiC&;;$t;c_3_<3@2^_)#(oo)XOc5bWaC6jU2mX-u -R4HJn31S74,=p$;N^IX-&'Ya2:+?T[[(I1Ze*<JAY64!3n\7beqN@q91<fkDBV7U/ -L>fpQ(f0X/Jud3OT\)#ZXAJ-nNbWnD1lkI`5VU\4T[5HI'6r1bNoN[c1P>fH=t,Ja -OQnQ\K;pOE:kCLsZE!Bcpm8(D*",7s6%frQ_1SO(#XUfWk?QVKV"P[1MhGdSa0K.l -DU,L%c#\hR5f,NL9XrA"Mt.SM+Gf#bMC/R9Lq4U[!I.QT0JquY2o9]6do;8`TKj4q -p>*hU9+sk9.U$<[4qLmoIJIsEOVRd*%#i(YC#F4f<Y,bb&F3A*R!#r[gsICV.>F4s -6nr1RmWFSL6V-H<_=q?\:"-D>4-nYUrPt8a)"(rfB"5@l1l]$%F`ZU'F=]."q(=t5 -0ghEe2cMbC)l0c#?+h@n>(11T?l+OX0o<aiOs](1mJjFj](W%rlqH9q1lJq5Q_dou -?6cMh6a5E(N0mpL2J%3C4-.olB.&u7QTkp$D,[D14(<9V/O@Fa/VpW.&.6TL=_OaI -q,2=7n13%&]n.,!<\&J4#&6J%5RV!hj!Y7d#Z;Lp!Cc=$Kd,`Z,lq:O%bnV0*(,AQ -IIC9p#%<uJK44kKARP:45JW0SN2XTP%%cogYe`jHgE:b3*p^H:'K:CKScQ]T7H*Yq -P.LCDd`r'^7KK=CE;s:5)[?n2#(l#^"Ag>GK.8SX(3![^!P/X>:DCJDP*c^ecmUQ$ -pqR^k#[rZYShgh8ke/pTYb1OE;(fMe]+SYM?)l8)@%\XBpe2*[kU9sg?6b)1D@.,C -9a8D,pVe7O),'4D0Hm_P"TX^fJhtRS&OB.1B=J=Y6r+<Oae'C03>s)8;2u5^2Fc?B -*9+U"%5CmC7.f=UN+::^Mi#CWdkD/\!(g,JM,Y[?"<.HcTN(5Z^W3kL*hf'T@#SNX -X!;#M'82Jljr?.DP8:UT\X,*!D@8@SgkOZ6<+PN.(.GO$.4$gNCi+IAJdB%,!D#'P -TV4>9ANm+>SA,64KX"!3b7.u$Le@(@0WeaHS/=l";lrf0Y]W^><H>;RCB=Sd[sWp& -.[65!U011bcpRn"8.;2G#_sk&%GshYJ1DgdTb-?'j'u=(E?#q:2`!V>j1Kst!T:cB -'-WO--\;[F)E\0"!8]4/TT]k<a=(snPW?_g&5J/cKM3F**?,._&WonGE<Jg8@\8\m -'M&!+6'Y^LN<CdL!tm*;>?f'Ml+p:%^ebt;W,+7ArNN^d";_)2,ETa4<`Eb!2-A)K -H%;P'0F"u;B[n/cPP).<7`RdS5W8me>WN'JQLdCb:kI5n),A=q8#T)e;$p%fcEO5S -@16*DoFeRUaMo-%(hB:^ig6TiGb^nC`EdPpU/t1/@0&W'7nRW)6V?St"#V^,%f&[Y -&jKo>AUjuN$!XN^`unftBI7-6Ls7D_Y=Q/T:IPI;3D#iQ-d/TcYV)?<)N:6h[89do -EDJ'Le>MRL(KB@UWQMbg<Q]Q&1C-89K%l#q.Ko(+no7\f8[DX;6l*%d]gInC'Lr1S -0I>d>T+k1o0TDe,45cbV#*@.T%gXoq:6OZmA&`d]M5`@C^#5AI=A]O$n2NibMh%J' -^^i/#,_VPL&u#e-(3(uS-MX&DJoo'?.;:^@cM3jtBi!RI'Ij8Z&fQ@Y7<)Wc3M=<E -T+#1%n>T8G7EhipA+Hj]o=d;IY`r\(bA@NP+<e6I+[/6Xq$XgRSl="N_INr[,+U*, -Et+gp$<\#jn1@ei9Gj#R,Xj;Z=-rJ)WN+/=),]Y[+@Hk]S-PG^1!7d#'TAmKoBD?t -^.&-+3Fo*G#(g4u;^KD1\P!K3%Nnc'";gdMfXPaC6B4E\R1ucgglgtVEFlj#aG6(& ->Z7n='u*2\.i2lSIrG-o.@:MjL)E)f!D0RCd8G<*bT(2Z%:P"F#j%<9J4nOJ^!:o[ -BBPGYJohb!.429PT)p-*n?*Q:^aj4>rP!(@kt2,kI/7_''rZ6]!<~> -endstream -endobj -45 0 obj -2496 -endobj -42 0 obj -<< -/Type /Page -/Parent 43 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font 46 0 R -/ProcSet 2 0 R ->> -/Contents 44 0 R ->> -endobj -46 0 obj -<< -/F2 7 0 R -/F10 14 0 R -/F12 15 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R -/F22 38 0 R ->> -endobj -51 0 obj -<< -/Length 52 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U'+:A&P0hQ)&,tJ2$/TA-o@)O.[c;D -ZZ&afD*o8h-r`ia`Z[aCd)JuT?mqlZ`8\]8TuF&k7AImLpA+ERNG?Oj1V*@A:'k9l -6+7^0<hOIc(gBUuqlmGAJ&("-n3OuG:,^PhH(k=Qe7f,F`bG<P1_R,aU=CdF*S0O/ -17Hmu6OI01l:Eo?%Arp1JB2:_(el?n!RT1KKFdjpqi4JY_E#B7pcpVEj'^LuNoN[c -1P>jtkW'-J)!F#TiR<mfKqZ@#)54pAGSCLH:tRP?Dt$"NN6k5u0ob4,i>%B7"9ei0 -"&'7E+i.8G[Y7QSZ5GSs&pbBHBQ=Oq/u!<@,`/f\N:8?RdaY]WZ?gaIK`M1l4NA\6 -;U'mrE)J<GJl!-sL.RbQ)(hOs,`9_V6khP<UBoZ^6BQq3q[Fc(bVGpQE9Ii@JXC$g -%&74P"@ph;d0MoiPo3'r_`TpZ"sI_r0TM7k%6G_jUeWlX,<\<WbtJ*On&['G5s*U^ -<5B9a!h`F1L4Mcs&.$*F///OMN@-U.[@FD.b90];KVS,/l4?FL;tTk"e``k\";H[8 -5#G:Si]2smM!GfdK1Nj;6fDm[3P($05<QZA,X#:0l54OZhXNRX.nL6\Ck5d?h1&h_ -TkL>3__Bds(5gZ;CLI[=?(!W5p4S[fL<i1`4PbW\kWI7D7L<7n8XO*.g9o.%Dp$MH -PkBd1XfN3EJPE@-NPh963^FGp]*6$THm8sS+c=>X#'6p6R:OndkC'Q_WksXJ+j<=m -#'(WH(F`!tl7Ph_Y%s=KY9Lmr#"qS2JSYZ7b4f=1XtCiQpt_L1<m<B5Oiu]KFK,ca -XXcU=!XPYHM'>[!?\JSI_Dr#YeI`/*oE8M<kj_n]1iLipIYuYm%<N:l'3*m.L&jQ& -1Bfpd@ME%[X#J\_eiroc#/.c'1NiYT<]Tr6herHih?RP@GTF<7b&Z:X1c]hEKoo:, -ejm(!dBn9@15qf\:caUUohVR0'*KNr$q"S'29aN7?,Su1KK(q#pI@E!<2p]D:3fHe -5i-pA.!#f9$o%rfe@ejSH$:a[,IYH7%DfVNAkDMW-jFG,Q*PE8/SSIe#QEp`3f@aH -[?QGXhR_D,-UC$qRMM2ARZh2uKS15G2;h`l$'EVQk7P''7b%YT]G>A(iOG2HCd=++ -C5?HN.>:$_'g`a:$DlkqY[TFl''"WtXrS4U<Q)E^>1mR[=\:M>,)fJ6kRP`YGHVk! -%2tHCE3YsW4ID]I"1sD9@,8u;W;_5'<"+?"_2u9]rumrCA5n,76N\]T*^bU=4V$:4 -5$8`ii"H]$nl-;J#Ti8>/<2t.8Go75\:U*J^]a`A-3[5'VUTq7"j6?BLJYqscpO.N -d,eKPU?WBn-r(',:a?+ZW"q^M7@Ct!B[#P5PpUNM8ufuF6)"fI8WYkii5R0'!m84% -+>H7Gi38](86]8SA;XchB*.>b2H$7kS-=Xd'Q@`(>)>%G/XR4Vj?F-j"?gPfKn)*l -gCYAtCQ$HEgp[!HgrY\BMJ7ZEX;P_(S+@YpAB`-2VqU+%1hD"dh&egnEqa-UP^BHA -r1PLZq5#n'V=,k$YueOZ'N:j(JCK?HMG>2M(j&7tATP#>etSLNr*M'npSi,sU=8]^ -52i_&L=WBu'0J3qV5P@hp`Q.?4M6<'r<^73hL?USOA\\J":$e:*U71F;lY5>WZXR+ -!<T?&eb"Qho9:4d.H`#?5nP%KKi(.@1F;3p.tRcVElsdq,fH@@&7Sb*$$e6^,hSV# -U[1c^C!R"4r6q6h>eNl1P:<DG_A,D=G?alI8QI^%&rV"i)]17QT\7sU7.=F/H#cL< -ckK0(SRID<![*ef`YlB-@dR;d-s"4:SW]LB/ZHr=QM,7R2W5>.rJS1YcJt6fWAG"R -Z3DT`UX<</&'4_96rXZHQ:f=d-aL!22ZA/3B"C=QGT\a*0^p.A:_FH,"M,@Xl5Dbp -DaCea2!R9VVe]a?!*.o<KS'>1lcbM)@>_m&Y4fIMM)&*%Z8kuWckB&C:JPdE_aM6+ -iTn*lmfBjRQ^\&BL>WP4O>1Q1&LLi,#rOAmagraM$CV1[CiIY#a+]VAj6L94D5KY< -\!J<A15nRQ*\<tJ?>\dT.?09qN]6[4/N3`tQa$`=]K$KIA6I&k$=6CNLm6mnUcq-- -n0$*]aFoj`L6)dG28RbB).bn-S.-Bt/=FrRA]qWNo@@BlR%#js@U4;CA/V&/)-LXY -_kPO%A-SJ-8->D.E<2@=`gKe^U+JB[kPeb&\Gn6n)f_7dIHDsR-RIPR<J.\fJ^q]6 -7CE=e$kH+@f&bC?#"lI^bgSU!)harIU<A.VI]%#(J/C@H*"3Hf2KbJN7TND(lN+AI -hU5Nln"OI0%R0QXqoKt!mI&1;n]D2#)V\dJO)C5i)M7k%Q]U-FWc1h^.#5CpQT%qW -K1KX(l@^'8FrhWoY%ItMSIJZB9ed8hkQ\TRHP6*!K!9h/;&E'H)/SS\Z`T9LJCs3# -M^rB/TnOuWS:atk6"fS5U=08+SYWu8U9D9M6s4XlkFBDQmC?=kr'9e6c,=mS1N9io -!4KKBn'/"$<4PFo\gt"^m<=@7@^?^I-.5ZJ>CeuPT[FF73RD&RVJb"3@al@g@dm(= -01:RoY2/N[8.,B2S\2n0Vb?9KJVS0:OO8rd0*#+%!U))'X25hI90kG\Q-K*(lG8+" -j9d(V_nK1p@P_rc0=S_?UbBdb'%bnlF#<O-:VRHZ!"?\p$ctsN_YX0M%/&1NnV&JR -P5fNVh+,-1^A555U/C&U&gVA>LUVY\8+MTLVsjX?+mk8SomAn+6g5_[1D1,rL0u>q -;EPHqdr4fm.G"8)2XMcO?G`"?$HO`LhI0/3,%ZEoN^-`8ba=D)iI\)g_R/Z^8GqI, -idr3pm8>&r?n?p]CsG)PDEd,67QR\G6LIaDmT,Q>lK.,ro8[F7"&>ZSNd%]%P/W1Y -.d#\6Up1D=ih@XjiY4G*+=$2#ZG71]Jr'hDL`mrXbHRk^%ZUQb(?&^(~> -endstream -endobj -52 0 obj -3159 -endobj -47 0 obj -<< -/Type /Page -/Parent 43 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font 53 0 R -/ProcSet 2 0 R ->> -/Annots 54 0 R -/Contents 51 0 R ->> -endobj -53 0 obj -<< -/F2 7 0 R -/F10 14 0 R -/F12 15 0 R -/F14 24 0 R -/F20 37 0 R -/F22 38 0 R ->> -endobj -54 0 obj -[ 48 0 R 49 0 R 50 0 R ] -endobj -56 0 obj -<< -/Length 57 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP7&e+'_9g>F2],8@!g/`+(HImX -_U1qOeQ*I(L6[&BT]ffF)GTA\DENhWK1R<YWL2[\2j0,nF;nKuN$,Y?"p:EE%Z@=u -)Z`A]<gQQ("V#=[qEW1`0=_N]d(RI9O1F)roF_NhP0Lkc5cG\gL/-cR(lLkocrPV' -"J8L:j'ftI=?)ZB[T*%H8uYjC="Mo!%?_.u[7H`9)_L#f@&H*F5c?LJT`C`BNrpm: -1,B"?aSdl4i"Vo?Tpf_K$B1oK1lc:#j>;mTnD+\qCe3PHYtW=D&.RZ]aM4Sa5gVHM -US'k+NPir\(;l7)QAI4#i3j=hj'^:n`=)J''X^4l>SN*jTTfUE:\q5uUPOMfiuueU -'d\[P87EPB"&'sq"X.Pif`iTbR)KKoT[>`siK.ji#`u-m/L79V@,XZ?@jntsK?2t+ -]S\+R(oFT-().(M/:]R:_`TOr.17]@"Yq[)i.3>A<6Z_G+s;aj$Bp9\)C(q@Af4>e -Lh%>,!C25cLgio=3/1jnO;&!U\D5;dJXehWZOG>a.?9NR4$h%uMMhRkFA.lSK`a/H -&5Q,9THo>%"O\3CTgWWRZPLG%93#CgJ2.6/YYq-J&s]7($\:S$0T;.,i@N/c1F#mk -5sXlZ"9T4g+:VhJ\.jT1K\%_Qd]BX*?=@k)HJ,!RATQZdebO\NBp9$Y"ke]0VM,m9 -B6c6jfPbZQ<*Yblj'i:T3/5UfHX#)Zh0WM]2B%un#*q]CAm)sXTZlN+V6*O((=Wea -gY)8;ESRS,eM_)C"pKTdf9R.t1:V`)LuMof.uVR:F\/c@P9.Xh<T6!:,YfMUF(YXW -VNY<i"/t!8N?^F<1>qdLLM^$1K(2Sh_`Ief+^rMUZJg_WS2uY)'Q?!ifSK+57'u!r -\+Hc/(_@2$'OcN,Z[G&D<(dB%PX"T_Ar.^i44k>n._=`6M^!\0U':Y&BU<]rb@VT% ->]1_*npIRGmKPU[ie^BN?H(3"86sur%Tef0%pb_Rdk]mdUG$Xbcu3$s*Op8bL95e, -`*a(EEf#81>_*".+reFECj'bG*'U1B$4-P>Bo<<)YdbI^<pU;&.kUJ-^ejqO9HJeh -iG]Yo*#2fWP&c))&XVS.6IYi\A.I#uR8RAoJhV!Mlc$P)aB#.ZX:>Q\[MT46`#ODG -*ISM@$^Bip'`sj#Dam1i/$^YAh%2RslnfkK-A]t(ipC_T7I@e?*989,iZt^io0Gnu -_d?q5HP#F.5;SU&_/qgn!=9Ga<?<-2!(@?JPW#9NLA=D_?7BF0mBSVg'7q>u$*)(( -",F-"b7gV0d)GLX,/k[7X=B7rJiq-[hWNPpIX\Os<J$!$l<RVr#`1[_(s%UUTjT9h -#&Pg.\QpJU!OI_ri_7J&oL"N[%Xb(rL4TIFkXtYk"U8t[(>"@F8/!<SdKXIhM*1B) -qFd%bZlHdCi@.sp/rVReotj8m/)Q;j"jbU^80C_C_ao*'dct.%p00Han^B=Jd$l!Y -FDApDIOM(t\PVmh%A'i.2aI_K)sS>5B/-Ta7_Xc.'6-J_\ZDQJG(poeImiLY7APG` -QdL+88rB/j1t6mj".@/E.2fWJ<;)rU\o(1*=hUZ0!8/;YECf;e4Z6odPYnH%;Q8?J -WO1BDS:aa.!<lK$'QU8oqP7s;?oD'K5)Q!Odou&X3ipkJeh5*QCb#8,Y/``%dH\,= -l_lO$<T8p=)[B_b?"Z1UdL+RJnnTdbHDqWc^JrAV9@3?FX4A'1+A2H@/5:5m!7%fL -g;(%q"c03;>0R^,NFT'OY-LPaZ<:BH:aqZ,[P^CnejJk,))K)R;aJhDeIFsi3NagO -/abTBS6c7QOTi^g(5$":<Sb5!Obh"dR.n+_JZ2CQB&X35nA9gE5V9Q&/Fjiii^V2/ -&@Q*pplPVA7DM`$"9H"9?MhH0n$0(1Kd[_oA*JHGi)'MW."Hg~> -endstream -endobj -57 0 obj -2097 -endobj -55 0 obj -<< -/Type /Page -/Parent 43 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F10 14 0 R -/F12 15 0 R -/F14 24 0 R -/F22 38 0 R ->> -/ProcSet 2 0 R ->> -/Contents 56 0 R ->> -endobj -59 0 obj -<< -/Length 60 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U'+:A&P0hQ)&,tJ2$/TA-o@)O.[c;D -ZZ&afD*o8h-r`ia`Z[aCd)JuT?mqlZ`8\]8TuF&k7AImLpA+ERNG?Oj1V*@A:'k9l -6+7^0<hOIc(gBUuqlmGEJ&("-n3OuG:,^PhH(k=Qe7f,F`bG<P2VnUG(r3Gp87^;r -&r>:n7D#pG>VQr@7^Fh:TSdtJRna1*/JN<,$=^5),/8bDau9f]8@g8W5Z4n_.&s#S -Yd[?U/f?dfZH*k3DB%.@$A1Ul3PI&sBG:lY_t<prY-:__N<=Fo&d>No:b]kn38c`U -A!k\!7?OZV.KqB-:`tSaaA=sX,G<F1%F<,=,n#9kA/Y__Ga]t8U2[(]ZXIAZ"tF%r -,`dh>jDGM8P3@oU#lt0t16&8dRPY-[F8@qWdI>F?%&5*0":V%bauKS,Yei:.YNYHm -L7s488N@G8cDi7Q@(6mZK.+baLB0YF&-bZ:H4UQr=OK0.L_.KeNe8bC4H8;&WYpQ/ -FTjo2'EIV`:Ep.j/d3Bu_d-%_6i&;:+hUPmM1Vc+"i7,ob_B%(XQMXg!K`BeM1T-- -0ICnDXGJ.-9'Z;g0AH=^N7Kfd!=g?Q_D2TgXkXppY^3bb!DWN3gk6LWC)I4a_Dm)N -W2&6,/am5+*3E3HJeWra&5a_,N"VpGUp.F:)afVM)PdR'JctFtp$7pCUkpj'Pp"1V -@$`2HP%^=4$.(r/1<o]*)M[U1?AD4t;I8^hb(Bu".aIB#,6fTs\;_nFU+3D5.&^Sp -U.M:ukTXmWhLdF2Rd)'EY#5CS1caPf*9b3CM7VpZ:3!-mH?on#i1("chhHu:a+Y]J -:f&P,Wg;MgB5D-ORC)k'V!;l%>+<77^fLQ>"kqL1Kn^bBmBU^cn5(J%\UNS\"peOj -U:7-@?_m.<hOVs`kskc=ZUh81ZLM41!KVBYMaeR`W[B@MmlF@6"_k.!6/J9js-U3n -INMJI0A\nJOELP)B_$=na"cgsS:_Qe@1+I3bP*".WQo6b^d6l:.k\d*)_lJ+O,:n@ -8!He8OhYq>d+GsCf'ZnW]72GeXh3dFW<&JI#7N?f31uf->^PQ[T[_URBGf.THhM0X -M$u1ak6"l)om1I3_m?8tjG6IS3[UB+_3T!#@G./#"[3\(6A>rD!G#_qXId@>b7G1/ -nKOiH[3;FVF?u@W</`YjZoG<+MijWb:h59BkcY2IX?C_S![&(!+DKcW'nh6gL;d'F -&!)*ENkg6#^>hUW<Q$pTd4qhpkcZ,ROe.W[_Ea?b%L]#T9M4\#l,QpM(6Z=#M?GY= -76$hN,.pNk1%Ib".172-GW%.N<Jj(-DF:5,W[OP%S#'f%)i?X/C\$%!7YsZKa>&L$ -n7DhjB'Ns$Mj]<<iTn=(5j4rdDN9g$eL9p&#Ttr_H!oRT9OiB[ThNXlAhbep=._+: -N"C<;q9Mau/MnTl^i7b!iWk/d!?Oqg1_(5Vc>nfZS\3*nY?AWckHb?.Qo&5>2:K'k -!X^<Z0UiNg@EPL=$0V6FTQ@C:3!F8(!N[97c74Xt13uQ$[!r9mc9W=85qD-b6'3;t -,"t#lZ^\4W/@(9WdrO0[@Z6j)<%*UF=M@Gm=g2^B*ad2K7`%]X2^)/_>/lal#0>n) -@AHMK`rL)'_4aK#AZ5qLVA'KU[#[Ncp+a>7oh2%&P`b*ug!o%J>H8a1M3W1gd^jI& -Ul@`b;S`aj.MH4Sbb?EVZ=1=Cb?rSCX#('7QNNRK-*&J%+dDu-<SERIP.ahX"P,c` -7]'?cM-XLINIiinA7XEm3B-Z*eL&Y5S&.MjC5lAH;:mKtLm'<1n0j&QTNuR)eYm6@ -.'d"h_fJIe]6#W^/d"%+LQ?!Z9[n_7/q?e7;(:*Rf6eGX)PiY>jklNnFn(PbK1]@3 -5rZ!=&sQ8t%&hpO62'm">N\E+ad=b+[=jsV#8M,h`$'ZtVABmBkr8(E!d@\6s$\VM -JOobC/S/qk;J93E%?:rW2JRcVbU5n/1]+ZC)Yr3*2WB=#*l2c2e)Dg!KQ/g\_O.1e -&@NJ_0\-H:[$hoMa1$k6F?GDc+nNt4B2*$eV0:K$OOL`c%!%q)CJo,X.ark&-r*qo -Fp7"DX::A/eP1jtOQ^*:pqY-ak:EN*o9N$3W@J9d+X@FP+UKMA.\;&?[PK>@XD<u0 -,d#0+3kF;Cd@VV*JMih!L`rk=RW=X_b>9[^BpK?m19=-n:`Zal%0I9*KWH@mQN:fB -+`rV@DU-\m=gNNdQAA`I['R#e>*:aYM[ch#-CN=B;orin^aN?GPk$BuU9rAqm4*/b -.,sV)I8::j`:rQQlfm-eVL2=(-+>#U_Wp/&5/"LN6%X!tV00'G#]qGmp-M.+6:t*- -"V$GGT\ZFnQubVS1OQ$rB2*hYQ2B=g<`tP9Ib'<ZU7.m)).a@er1#\J`,pRSE.,1u -pB9s%bUP1)!Ykn6SJ&apAj<rNjP@>q]&9`WEFZ^M6/<3uN4TminL<cec:eD9R7-AR -mUB%<k6C(YURU8GE^WIW2<#UNTCS`Z\uk31E'7o5_5Uk^b:;a9JP[nO#JskmA^@]( -s"E_;0&8I_h`0Q$ZnUEJGJVT'Go/%[_j;n$g8rEVf]uj\gR#f$DKFmo8$Nk5ljc"Y -/M]-V^iM^F3o/p\\*h^cF5Ip)3X:#nO2FD+QdIFs:Gh#D2l=4XfR*GWN23&#J':"Y -dChb8n6I]kqUuNnT79f&hE0*WMu2(r!=iZ$]<B/V4qP=]Q0filFr@W9L%5Ie6``Zi -*IH%Y]=hYA?IjNNC)?-3q).DCXFbDp&*BaB#pn9rc[.J,b5*,.c<^J*p_j5)l'S-I -I$tB:bHHTjl:V'`lrOT6jq%=e:K6BC=G!\p,,K7<_ArXFB'R]1s!Hg.:FQ>43qnY# -!fifQb$a5t(@$s;"-8CV&!2C[*2+q'j"HpT^k`:EN9q,+m7TeD`ZG"%aR0M#I,j3; -`%[>b\d%WCkYN&Un+ci7G5[=o^Q;k(E%D5AjSk3Nib>Rs844XOUAYKio$Br0DROXR -+spsK"`K.f&30TDr[@'X%$+6mE$YK\9Q1?Uf$:)jY#=g;jF$2$!R:uSE2_`Sl6:$L -&.Y_N-3!]!*;M.9n0jC\!epmeME$]=#A]_4YGgi'_Q"u:NG`EP:[Tn]Wi30T.4I7j -7C#(6'`7=bhdbTXJu$JeL4kE[b6hKnYSs;h(mM"S1LepSVX/T17#/%+/VaaMm(!2B -nhECGZLN=H.Zu*nCDlKYN"Ll<6QBA=ISpPU/b-^qk3VRgmVnoAX5Xd5,)/DrJ935K -(Wt>KmTKiLlQ-C<AL,S@Jr%gU('c(6)fbr,9.#NG_L&PjMaXWtL8u3Z36STK4mLK6 --Gl!a#j%p`*g-6J-K]E&XC77X\g_<POj_fj>pSDm*A)<=M%hkMJ0bYY+%M-?LMS:( -OpYTq$:Z_X?r.3'L'iI20//gq5b\9K5_nK^l3<!C?s8QQVIcFV.7,pLkh^U1:3Q3( -AVOJ>16Nb&~> -endstream -endobj -60 0 obj -3642 -endobj -58 0 obj -<< -/Type /Page -/Parent 43 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F12 15 0 R -/F14 24 0 R -/F16 31 0 R ->> -/ProcSet 2 0 R ->> -/Contents 59 0 R ->> -endobj -62 0 obj -<< -/Length 63 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP7&e+'_9g>F2],8@!g/`+(HImX -_U1qOeQ*I(L6[&BT]ffF)GTA\DENhWK1R<YWL2[\2j0,nF;nKuN$,Y?"p:EE%Z@=u -)Z`A]<gQQ("V#=[qEW1`0=_N]d(RI9O1F)roF_NhP0Lkc5cG\gL/-cR(lLlZcrPV' -"J8L:j'ftI=?)Y*7_:-tAu/J-5qTBu2sb#(,&!ok*4m]3j=RP`iYWB/JZ<<"KaZhU -2N@lIaq+bCcp/ibTh&XHL*8hO1(LO]5W=Y<!5^Yt!_D$!Ke8s6'FaJ@BH2^;kdi5M -5Z5*/VQ0JLgV8:@.fZ2UTKjGfLuZ/NK`VP$1(HTl(`N\<UM^bOCteeG%YL-61^p.p -_D2Opd*iejOCH-G8-n:N.>VG(OqbrVl3tb>MniO]ckHom6-tiJ%7AM2,keFITnOLW -KE8-bMQHoB&/th1G\Yb5CH->Q73S>I9-urlAIF6$Ki/HmJH2>gLg^:b,)S^SOsc+. -OBk@R8mN:H;;m1Z$mWhN/Q,^E22bpH(1!,9+N*;f4pmNk+&ab.P/g*n<,rL?/6;Fq -K@8?,]iL/EFk(WjQYiX-Kbar-LJd7Ma*QM6of#RGj!#^=L-_KOBN9TegNAB?.%299 -6=&J4hDBX8Jm%lNSVu12c(g'J[KR]l=]j6(AVO\8`GSqic(YaSQoqIj1)GXr*2]Ea -6$"T$%TNpJfu,Sn;k]B3Q0#i$=`oXR5fPD[39@8N5O"8=)5=^8B:st[Z9B5kCH-$Z -/FHWXAg,n*Q\'r8aE(+86c_M:$">Tq&8<=64.&liL$FDp@>(rq<+mt"Ij<pHhMTb5 -S<i8%6)MpH%!pJ33*du;KI#fDfZH%q"(9*GA(DF1`Mdf\L,%>NFoa1-GJ1OX<NGo? -('F[mUa,*:"s[O\g%Sd9p`9*9F5Yb)?/8h\^2)^&?4U9&@(nR\]N<k<*OMU?s-rEO -r[4Opq%Rs'H?pXa]C&\5rS?aBRWrCor;Vi&o6ii'fC5Q]Vs!XNSp0JuR<aj3/9Td; -Vj?qHg^&3:rVJg2M"Y3Agjq$i!'h</on`)sI#off5pp(1?j$1(-;Fl^-d&GsU`k/F -a[[gi`jVFS.#'EuS\W:r#_AI&$rA,b06__Ee<@TkYbhWA\1e?@ga69&r.BWe`6P!N -+Gd6.lG,ikHQl<sL/%J`16>l]?h@6NnJWoEdNKB5PYbp%H4%ECHOjRoZ\FCp+HUia -&L/8pIAPp1^Ndh2?MWYPk"R!3;TO>`l2XC@b_dpVS9Me7<(r..18701*5b$[%dAd+ -U;6"=_W+]%_8nWl5X61(G\fdRH:auUW#7sk@RU9K:UbT@7#QUY5n\nlb"5:]9CO'f -ZI2=eJE1/AJX[(2F>K%n1l%&e-j@Rr@\r*".>(6%QCraa8s%^QN+.'E,Vb*K^iXi- -WFSQ^b"!*m*BRe^>[S](nf:V)=ciD8+biZ.cM%0eJ5QZ989>W9TP+ZYjJ.s<0\$8( -/02WV$jO'u2G)S17&W1=<7FNq9F5+U.)SYM_1k_4_^q2h_E:?-FT.PG_@@3!p.qV1 -=+iV.&lV,)%5]=bL)Im$N/]Ma,RDK:8-ig$fH?EPb%=0eN)C$8/gmH6KbB,$JfCG] -##s,U!g8.qAKdL2K[!"Z&q1)gKWY`WOI-6?4pV6%Cdhd63J*ZnQ)>>\,nm?s:=*U. -kCIZI'@*L*8II\W6"N6$mAUZ-s!.YR71$dM.KkX"<$X$k-0,uFJr6lE6RZcQJ_mj? -M26lI6=?8Q:cp=rSC1>$@me&kBi:1A$Z+8*W7'nBU^!3OW%+0t1nrpTE5io14P-9n -$=noQh,pgc#7McC^BZ9`$4+4UWOEY,c'tn'D$X[`pNl6pRdj"7?+V`j,o"V9,@p/@ --Uf>gRa%'rPj;S]%J(.T4%Zki"/p#l+h8N.]@70$,%iRkjM_=Lhe<1$K+(:V&"I@5 -I=l3E7<<-!)2h:'kYQA,pSe9#!7Do?%1I!%TK<u5lUC"dZ3:l*0S^pk6SX^j`CT"N -h"*Ib!J,MpGliXs+R;e,-9K4Z?Q3'O@utOQT=34/>c\<_3YF#lSYZ0&=;(-dPg+oY -V1M&[=n,tYL0VpM6nF#lMe1rq;E_rFX'<e6G[%!g[7PoY-;.OO=n"QW(<5%P,%Ls9 -'V-nnSA2GH=d87"#0TsD3##R=@'^".Ad*4m<@\V`:[VmOH<2tW/DZgGNat,g[[C:R -o:NDm^sO&/1><p]D'k^hcp<Pu-6V9!nMVd)RQF&OP05p7qe;oG?SC&+2bQ#"@?C>; -`D<DjZEmY.#_=6JlA5jfPl)f(G'TnL"cK$rVRG(^@p+QO,H^SpZ^H&K2dGB$*;1\( -fYo&Km$>2NoZgq"3L&iE*N^JDrlbNbDf2lg@(ck:%kOO[QRU9jnpti6OoWO@C$hf^ -)#u9:ge@-,oV&>7.f!Dn6U>B[iABINq5%7`,A_f);j%AETGA%lm/9#62#_.Gjd"]b -^)2,TO_!HV>_Sj:'N',*Jd,J(TQ0T"HUsbgkdrTUi/U^L(EY6[\eg_RY%3T8iEiNh -5eST*?J/%m:.^3X)&#r_Jc[W?%/0emQ]oBKkUEha^nD5>PuHVg)C5k-0\M&2;<&+^ -Zpf78^@tH=;lV:VJ<\P!pQR4S%kquJB&JI]V);7=Bb2NM>Qk:M5T>5TU@Q"1T,R86 -dn3uI5/+Y]"V;F;L^3~> -endstream -endobj -63 0 obj -2858 -endobj -61 0 obj -<< -/Type /Page -/Parent 43 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R -/F22 38 0 R ->> -/ProcSet 2 0 R ->> -/Contents 62 0 R ->> -endobj -65 0 obj -<< -/Length 66 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U'+:A&P0hQ)&,tJ2$/TA-o@)O.[c;D -ZZ&afD*o8h-r`ia`Z[aCd)JuT?mqlZ`8\]8TuF&k7AImLpA+ERNG?Oj1V*@A:'k9l -6+7^0<hOIc(gBUuqlmGIJ&("-n3OuG:,^PhH(k=Qe7f,F`bG<P1_R,aU=CJc>7=J? -3?/E]K/!Oue1d`gm\Ra]ctg]+<^p;s'UHVl+Mj5hZCk!7JG?8+fMF%'+\O@##iS=c -.LAnlN:8?RdaY$SMP>>0"9RLn)$WaTRNRJS>XTGmK&BK<KEDeV3XhdR65bMdYh1iB -UEDf_NX:6a3Xl[WfJ&<&=QV4>+_1$PT[,F@of\7[B)!t(S*KmT&@;*"X0;,8YlkUN -e/LZH]WVGjU0rj+#i_M=r&a4\1<-045cG:6n]8j28&KSqWX<4>5WOjWOQnQ\K;pO8 -7+"8d&;:5%Ahf#J"Z#uZTqq5pU.G4U"[PH<5V`bC*#oq%!H::BTM^qf)\/W^kVS9M -!8K>j"/Q;k%HEO81^p=mFW]2b`;1D_<'W].%3rgk#ssN?5__YLW9c3tK;cs?8^csu -&5#_kf(Oi,KF]VfMQ.o56Cgak%qblV/e<3Z0a@`Y4W9=(_9%5guL7hA'eo`,P" -<W*Frd<'4I8B!EYn;gKr4YhWp[,YPI\s3`1'NG5Taq.Oi+Mp/J+TU^gNWU[p+GsVF -OsJfqI)g9MQ$@?,hejar/hes/jKCf>-1<['g'$%B#Zpu`$pUuK@Y#ZS4dSC[1`32Y -iUg+f7qPl"-Pom;_@@Pq38MHeKt=PnCXbr:'p@*iC*/[01)t.ufN*^%2J4_6.rja= -3,7Y_GNO[*9Coj\P[;]XRDlj#$L/uEJk2B1cHkcf(l%<^Zb'MJ^hp4X4,@Je"V_bW -(3UVkXkEC+71le66SEBrKc;sjfPMAdL(jh!pgN4C@>(2h!D5mgdOBO>Zb+aLc!5g! -_f4N#@?_VM1l\7Ygc:?=J'Z!c]L%N*nOck%ThBcfO"jtF%kN89^R$ba*:'4iVkf(` -(^QO,_/!'=]GDdrp^CF1"+LeX!/!)U%EPUK-uN`&27=:<?*dsK/WiR,<)1D"\7c=$ -W#L>AMAY5L/.F8'C*?X;JI$>J<+m^)46GO!5sd[C_4;c33.U@hqnRul(`<C1D@PEP -5m`*A^I.db_Hg>qLsH+]LPV<)!KrgqEEV?W\@)_]lst#?4;UHUBFPSb2$$L_o<)TU -%7,PUJ*oIMY8APGciRd.C;)gF2+\I48P0-u8h*=X"J*Z%2)[(W]"SqbYo%PoKPXBs -.4("3_3-DZBef@7PLthYjH2>Sl-oi$Q4\_sPR)i)3!VlW'1*?l"X&=@##NaJ"(5S? -TpugbYYY].!(I;]*>O2djW,Folir266S@!UQXg1jOE4*L^[Ro'<h+SY/QDiaq'^ic -]S_i&'Ih,a0'H4@Sj'KKOg+>l*0p+G"9F02#!sp^dBG>0V5UCcLX7*1P7<@_F;C00 -RTj?6LP6nb*\=lP)JBC4/LT'cUGQ_^**jRcEptj1`JT;4bf<tAeQF,!j?]`%$4;<Z -)M:j_(dgF-V#[/F[D:r[Bsbr;AC\(e0L8Q8U8A,OB_Y1;G=tf>jJNF.Pqp:G)d\*<+<U~> -endstream -endobj -66 0 obj -1786 -endobj -64 0 obj -<< -/Type /Page -/Parent 43 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 65 0 R ->> -endobj -69 0 obj -<< -/Length 70 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP%#Dl#E=Ad;-^0EsP+efg7B42" -Onhu#EAa6-7SpZ*Y),UZ>_[k3c=2PtabUCVU6mGOO:VJJ[bShEAK7&lL8/EgLL%.3 -Be"@q"e*PFe\n1?;5SGC1ooE8,12Da%>_,P-e&HIfQ"+;N[<]4Y&9jLWDtFp6'ie; -jg*t,EF-+aO`:O?mimm-fQ&eb%0[Q[mJd7(MkZl/"Y5Hsb,_To+q1d^02a204/'Gp -(b*d`j=1T@8ELHl@7Y8M%0Hmo3XhdF5WBtJR*%>tOP%E/"9Sq^3(+u&auTtV*+[Ga -6_H\'N7!I62?X+9l8K,k^tq";@n>Ah^b?Z8jroVnGkhi%5fsWI,ClI-a+Fra0TJNA -;[.uM5[>d'9KK2(J,~> -endstream -endobj -70 0 obj -547 -endobj -67 0 obj -<< -/Type /Page -/Parent 68 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R ->> -/ProcSet 2 0 R ->> -/Contents 69 0 R ->> -endobj -72 0 obj -<< -/Length 73 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1ejilC*/fOed\X\E/K%r8GZq`kE=:9U[/9iIJ6FfK6)*n<IbkOELKJU3>fb'' -d]s>WS7>.+TP6-Cbbn38QJ:E-jp$pn37ISWXimZ?4H77'i&QcAS*I)0.B9n;-t0Df -YbJ>Mp^dYGPP4Z7+[ALRNPcUc3fJ\>5TW(lGfCO/!V>T/"fgR,'La[*Lbb!#)!(CN -K6ZGg"];>[q29eh5V\6#%"8p"_arE8MrScn2N4>??L('RW'N#YP3fk8bQ.j#)oj\c -i?$*NKA[:KJOjtgX%Fk?Y<M2;N:K2O0L-PY!H\>$Y-TBr*Xs?=h)J1!H:kENNT80M -L7tUm(b'P,[M0'9.)I_L@0".U$3EbQ(5Te!^D]]&!6dG4j)$q;#%<m9-]V]XjuNpG -BNu70U7d_S.k9?:q_r@knI*c:SGp"GidaoE3$H@?,t`*CauNGB=D/C7<UG9D\!@tT -nPRcXC)R=+SLG&,Q&TE)8lDJsr7G[bCpPDhUh2(c&N/S^%HB--3a]:KAQ6^MAN*o! -<W][JX.WCoZJQ7OeuD2\:rdk,=H2]q+P5',,iDKIkR\';W0eo>GV.[&`5B6X2?X*r -9T.A@&D`#tO@VZs7cA0eM^/$40/CS1oYl@k"*iu3$rVLJBifKO*FWD5]CBCW8j!$T -=d6hd3fZRH5V!!d9%RdqEQ*31@FS#j7P%a)cJc94Y/2<8/jn,&BG&2g1WS88Kl,rE -S=VKTg\tc9EOO^01@_'::biG(TYnj)'jY%hEd[$`WG:#h3fO>:;uH.F$a3'F>.EZ. -rOQ(SB>WW@2&3k0b=WeLFeM9'Q1e5se/X4lY!`t4N#dQ"fUCSI4U,fBrNIoK..JaH -)OGIh6,&!s$)J38*gm4OgX`s[Hkag^8/Tk6L;jkPQkt%JS7CL;5lc4uO)aYQ6.$m. -!(<t)\1V8VM(:eYYjbR"&S2BMQ6t5GElsLF~> -endstream -endobj -73 0 obj -1225 -endobj -71 0 obj -<< -/Type /Page -/Parent 68 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 72 0 R ->> -endobj -75 0 obj -<< -/Length 76 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W8[@3Y]i*djV#jC'>2a -Y\>A3<APUhB(Af`/q[r6;1o`/TYPW;U![nT"(3OS$HQb2!26O(2+STT-2/R]g)$O: -Cp]XGSh<<@Z<=T?.#jI*T,8"epE;fER>/XhX&)C\!a[c)Ci\QmGdM7WVoEIO9!f.> -%cG6Z3EVeQYVqM^XuD9ho)4*T@6,$-<sOu_TkL)a)[:kd>iNJ+5c-Z'_g(*"N?aqd -Xp->T^5XPCZ;?/tYQNV\L/9RAq)O!CdPhSE@-TKUT`B?6YG#p^+$XEm>-Fi^b4`Q* -K.,k:N_@a_2i^0(<>[pd$O/>EU>SiZ$tDQ?,)&B<dP_N.ptRQ_UF97`WH#fE&589= -bqmTX9[P+UZ2B25891B]^<>k(XW+;1bgel&P=kHsM'I!')@PSu5WQr+BXeb3E14AD -Wp:&hPUQtjf`="5N"G,GZ35h;NT5.%9#BgBaFc%joe<!A_1J3QMd\lH15mG#jq%qE -!+[9MoLM5'%RYKq>UEJ/THo>%BT*Y,9?aYJfJXaj/d>aOD(H0,aQ>MlUM*o5N=75H -.LB%b,e-?&V5u[]FmB;E8l`CV3fTmGb9EZ[EkP#YOP>af5U`[o9e5Op@OMC'P<Kt? -&tHJI?M7nt'LGkAb,tqK7JPe=Psm?W.!9B5k$;$#ZRsA.)uk@1@BaR*TYdLF.U4,$ -;&5/O0L.[2\LjEsWV*2qI:GnM'^l4YE[r)_aKB'd:1G>F88-[o?Bf0_5a.a)ZnS"" -M1T>`T%^_1@4R=g"mqtAJHScAB97p8W5kTJ_5:K<<F[sY;C:4j%Kgt=#RjVMQlH8J -*\7J))CdV?Bi>M24KfGdofGL.?E9meq2BBd7CSiRH\<9^`tn6oAp--#RNF7Se?l:T -J4&:a+TpZ7eRZH*UQF7B$Gf=JVW"dZHkc*ucD[tslRk>NVGJU-jf\^qk8m.Co\mPt -d`1!&NB-/s&.F0sl!2jV(WY%0]m_d!JP#fD*7B/Zfr=[+BQE`cP(1n!:Y76^L3Scg -L\g38"$V.1+i_7uAdo6n=C!MD/1%/7rYOPu3tKj]Udg1<(H=/pmWcB%p;7(Q0sLs3 -&d]A0>lu+")cCFDs0;-*;B<[)"T]<"-,AHtSU)$"#\99f6otjF;BeMad2ds!3h+TU -7VXD14!S:Si^%Z>>gN)AJcL,OU1o*K7M.!L!(=:3fIgn]M)q#[XT)5aI"]<k2T<,2 -*)kMl;/oFrPu7Y~> -endstream -endobj -76 0 obj -1402 -endobj -74 0 obj -<< -/Type /Page -/Parent 68 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 75 0 R ->> -endobj -78 0 obj -<< -/Length 79 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1ejilC*/fOed\X\E/K/#9GZq`kE=:9U[/9iIJ6FfK6)*n<IbkOELKJU3>fb'' -d]s>WS7>.+TP6-F%]<'$QJ:E-jp$pn37ISWXimZ?4H77'i&QcAS*I)0.B9n;-t0Df -YbJ>Mp^dYGPP4Z7+[ALRNPcUc3fJ\>5TW(lGfCO/!V>T/"fgR,'Fr$*dP:q;9AoUU -K&BH:$tDQ>3<T@ZbVY<3.)%VK,A>487IINn\qC]tXXhR,d)I7<UR9%]4en\-+pC>d -i"-9I89Y6<8h-dC53YCmniq%H5T6a*F9(='ZK/\Q%KiBP2iZ9sk6If`$[CMjWMjPM -U-XBt4p;##^cG,^!5]9S!_A%]cdMa/0n^2T2)GMGQu++/A'!h,%A@mrXj-=@G1B?L -]c``hCO!9%$3<\.i.iIDLF.te^uQ2a-s1-s5sje6,lpWZADU@he&=dOWMjJMVKA%` -/lac6PpT)P1\4eD@C"+A$Amkn.LctId1ZuL2+r8G'i^ApNTl-L1>.sFASG>6[BQfb -::eVm`[b5l)9fu=eMgp'D;KnO/$8%L@^QXG0h@Q``=iaR]eDBG9GOTdd1`#>>gC0^ -<BVjtn5(Q:,H0Z^"9Pf*KWTDS7kTKT7UJO;1fD;]>L7/>8`rE_$%ar67Ls4poqiUp -:/B+QR0MWiE=Rf"`0rYW1c-4V_D%EU$LD2gCU6BmUpZ=aF!`CpjjAaZXTdBn#Jjkb -XL0*>_#Qnt<T/*N&P=#OV8UFF`35'C'3"2Y+<U~> -endstream -endobj -79 0 obj -1030 -endobj -77 0 obj -<< -/Type /Page -/Parent 68 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 78 0 R ->> -endobj -81 0 obj -<< -/Length 82 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W9<b3Y]i*djV#jC'>2a -Y\>A3<APUhB(Af`/q[r6;1o`/TYPW;U![nT"(3OS$HQb2!26O(2+STT-2/R]g)$O: -Cp]XGSh<<@Z<=T?.#jI*T,8"epE;fC=uF3,0ib.tqLL:=%Q6=e`4qq8VoEIO9!f.> -%cG6Z3EVeQZ8R_`XuD9ho)4*T@6-/M<sOu_TkL)a)[:kd>iNJ+5c-Z'_g(*"N?aqd -Xp->T^5XPCZ;?/tYQNV\L/9RAq)O!CdPhSE@-TKUT`B?6YG#p^+$XEm>-FiT5jUFh -,9T8h53rX]0oVjb:_4%F5f,Ma!DpusNIrXn2[gpEaqdIH>]@=Y'(!:bbS(,0+q166 -`]5\>T\h("6\>1d`p13X0[>lVoI>\BE9J2Jj.JXtaDkn''SgXr]!A@%$i6):$S0m2 -2Q_oLk"Lsqco;Mf8DZ:%e8-b#XGAXV%oN`'>Snp9R'm\9o0DOqKct,?m"GNN@p+Qs -BSfsEJq0"-Ks[r-1sL1)E\P@1Q"aH*<QtOB=f]d=2qNW*CL.5(5\FBV2>)JE"ZE`\ -_V-j&NGFHHTTlKHk[`be$\=[W)bM?Bni>7\BO%Tt'G][J%TgUK5_KbHjq&!>W7is7 -Z=5+I/(@5f%Cjo0!fFM[P.nJ,@Xq>o1\S2B.ZCc[j:nR!i)'ed2d3^/<*5?87T<?9 -0VR"h9::%]Ef?oZ;m60GKndFL.YA(jaJjXI)'D1'N55MYVIu6k>;[`BF^@!1fS3k> -!D[lFU8#,3/#9?^E6"X!)[;.o,o]*HV8^&HKhKZgB!I)+,=q($l`<:f\*U/<hc8A# --"D4T@@$)R@5qR4Vs6=5>K#geIf!4.(!aFWJQ[HV7:MMTCmbM]KdHt'@[9VIN^IbN -.g7=l?'.QULHu8\>6\_;B"5E_)nm%SQdu<AFZ.+LiC?+TF>Q-F7_dT_5C!JF4uU%Z -UVs/l8i5ldM*i_<aU[t%S'Lg(lcSq8me.pZ[8=LMD(YS"G65^3pOCtHMu#aoM&6d* --!n:dF(thL@J_@Kr1-c]C4VH:#<+%RQq.jBI]#`:O:V~> -endstream -endobj -82 0 obj -1233 -endobj -80 0 obj -<< -/Type /Page -/Parent 68 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 81 0 R ->> -endobj -84 0 obj -<< -/Length 85 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1ejilC*/fOed\X\E/K8):GZq`kE=:9U[/9iIJ6FfK6)*n<IbkOELKJU3>fb'' -d]s>WS7>.+TP6-CbbmcnPeprdS@MO%Di38m#)Hd7)F,^.gq&AQaP8_7".7Ls^M:i! -R]D7mL)VH)$7c*A5lb^=5VH(H'Eho:gbFe@X7-Z*O)*T,Ku60'rLguA\=Nj9F5S5N -UR9%]4en\,3<T@^FSNRgX7#nDJNuITN<9TF'b%uNfJ8BFE5FMlTk%j&7dI!=1!Gh4 -bqmTX4HCORdK&5L8n3M3&.=%[G6k6A.]BO8WBuR75VFfV)Qa$^%-"FrA:G_],C&$, -:[kAVYd]VPb*n'YW[&E1F?m8K$;[nI3J7L-cn^7h4I76$j"N_PKE?[e+bcXE;Qn+r -\3Mh[6[7?ec@M?p)bT.Xni;__.,#I@,3YsO!D:MD4hm!2<BrpYdUtqLo_>'nL/&"p -'M;9Xk5<fo=D/C8(3Q<b2jU4\nP[jDC)R=+SN.:?Q5,6-92ajos4W92CpPDhUi7e_ -i<BB`<OFFuIb8emKFePl68&/gN"r(h?7P.Ql`@TaCpg:*`8iZ2F4Nd4@0eb*\qr:d -(-2R"E2k5kR$CO+?g36F2IdTS6kDc=]hJ`b)-hD%bP=1`RFCbDK-BIoE8W[8E,`cH -f(U2QG@U?<76eQ<`<;sOWo^ih5%CPP2Zs2d;M;/r,Z>c;[XLG3hGg5g[9i8?Khf.p -%\"KZZs;LiBEMeJ12'ZGI8n]lc$*LGoeq;LC`)j(QQneZAqYn`9QA/3(H,Jh5TuM6 -nDu1'3l0NU-*+DjPSJqY>DoG;4A01>6ehsoT61OZ.7?*fVG)S$orbW.)`LM)/lt-p -dB(2!"lBfbn)[sXH_`gNKB2lM,F"W."BJ6Y(M."h^$a)bXIV3JP:gt'';BY7B/"jd~> -endstream -endobj -85 0 obj -1189 -endobj -83 0 obj -<< -/Type /Page -/Parent 68 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 84 0 R ->> -endobj -88 0 obj -<< -/Length 89 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W8[@3Y`&MF-rc%C'>2a -Y\>A3<APUhB(Af`/q[r6;1o`/TYPW;U![nT"(3OS$HQb2!26O(2+STT-2/R]g)$O: -Cp]XGSh<<@Z<=T?.#jI*T,8"epE;fC=uX?.0ib.tqLL:=%Q6=e`4T82cI:f2.]$;S -0o'^V_]5aQ/(kk33EHbhDY&4hhs_hP^3jf4$mA6](C#FX#S`2kTTkVM:(*<[+_[N6 -)[:kh#d:djR.<0Fj+-8KYcKeuXp->T^5XPCZ;?/tY_1a<L/>*lq72%ndPhSE@-TKU -T`B>N07t*H1^D<`X;7l$j6n+HK.,k:N_@a_2i^0(<?OLW!sHIKJNuITN<9Th'b1W8 -bVY<3.)%VK,A>488B<WLX3!X1m5rW-bk4-F'#;O7amt8H.Eli]`XiN/89Z:/MXmpS -_5Tb_ZG!K(C:6Is>4FjM&s1O#NRV?q8]9jCaFc%kFY)*t_1J3R5/NE(0T:XO5WT>d -kc"Rf!C25]f#)aV&./J0L),Tl&7E/q+TT_H%HD+e0[TogAfFGhR.<7tK.,Fi5nI!b -Y,o!X)&9[2U`t](WLJfJ"Tj3P))L6q!'*cT!6R;e;34Vk_(].6<*[]P,udd@X,`Uu -eBh#E>1UXB2GM^:8TQ%`Y\]2i_PEDG=!7bs*nXK,6\nq>Co4,]QNTa.goCDhmtKEB -.jP;>Xus?nfX)`ZB"6PlS\Ds3bS5c)PUI55K;Od-5b`4t-4-,cC`.pA^rrcDUSA%1 -krMr81_#o3:bca4$jqpDRl#%4m+'$?ZV](`>B%E"OsIObO0o'=8q?uk@?(G7k7<MM -9m@@W(_+MUAlP9@F[bQe/U+?tMZ>eu6Z>:@"Xm,e!(Tq1nT!RdND?e<(L#,Fe[9ak -+G:]8SPIOZ%`_gbdHu!Y?Zqgl13^.?^Lp^cQF1Jh3o42Gi0fo'L/*ZH;2J"kc@)(T -:p=OO4[-%e;0!A)d8FC%PJKr,JO#)T9r!IY&NXS2~> -endstream -endobj -89 0 obj -1164 -endobj -86 0 obj -<< -/Type /Page -/Parent 87 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 88 0 R ->> -endobj -91 0 obj -<< -/Length 92 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1ejilC*/fOed\X\E/KA/;GZq`kE=:9U[/9iIJ6FfK6)*n<IbkOELKJU3>fb'' -d]s>WQL`\$dVpTQ9P%X'dt0On),<M\Lt#6]N?`]'-B'0GhYiA,TTlF0W/tQqUZ/"m -p:]pQk5)g\bP(qMn-fLXNR0X`"Mnh/G1A^+U)<L<iGp-O/u"a)&<7;%k2cV9aC:U= -Lsh"s-0kmfbXG;]5T:rhj4:epE<+!:%\k/h&-n;tj;/7+oPfFKWhOb4%K`Sl2\(Cp -^,cB0Zf_3O&/5EQ%RT)N1qjK^Lbb!#)!(FOO>oK?%M+Xd/d3ER[d,H,qqj,%P;LZE -$I`NJ-H$HXjZ5`W]^n:H'BnOBcm'P96H9GU[]1k$CW*[&O]Xm83&,c;]$jU-q%$H) -ds4n<Wsa1/4K58o))rdkQW_1hX=hW4:Z,Xkc-S"1&k=-&9cg[`E+Bi_&<c=U%YL_@ -2\'6rkVPnAD5C$ge<C(I%E#-u0g@r(hD8Eg6u_3k<ob0R9>FK[3KBkbi&2#h.*)s! -26Al7=k7h#&]%MHAR2@El6[EL=:LH%5*f^OB3GlE6Ngl'eQH2`$#jeOi%pfTE85Xh -cZIU=gB7[G[>Z1q?l&@gG)fL7h0<7-Uc'&miH?XReB0@g'30$H>f\=9PLpQV!DSBX -K`_VA0TDhUl&i`cF8r/tfYY=//6]E?N[T'-?kcQtc*(Fs@C"-qbMoAGL/-4:D,/F+ -l3FXi,B1jcKEDLu2iaZ1SXo%(`i,,*p'<qMegfgj.;[TONqsn\!5g3\)eDaQ=0Xi0 -<li+G.,e;)h&mEm>$ai\g3HDpQ/alALMe6cp1;\7\'<BEKGl1sUgA<g0jSNrc2$D` -#d/k8A0'_/Zs!5_.?jG]+0plNfma$RH$Q7.k6(m)F6MH64lbhlH>h62fZTaCMQtJ0 -0P4LWd<,_giNb.Vb)Qs?!<~> -endstream -endobj -92 0 obj -1212 -endobj -90 0 obj -<< -/Type /Page -/Parent 87 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 91 0 R ->> -endobj -94 0 obj -<< -/Length 95 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W8I''U9+mU+KCT,`g*F -@u7;D8hu+ID0/B(K&ea*%W\p;/jM[<"VedT]P)g027DU\""<6Ej>@lCo@glqIm[/P -81`=b2PMK0ZAgY-!Ms,`-lEC_3#itT[03*u-0&FRZQqMsMak77HtK3SX$HqDmGp6: -OGUr&K4sE`j*87E0A$[IQ]&N9q;H<Z!8(s'"jR5,'FJ?kgc(5qR*n"*J5WloVQ0JL -U:)L;%#Veq9DTMk!P@.IKO[R.0o^gaa>/DLj5Re,_a&VSTYYBWShD==W[*SATP-!= -JHT$LMh+9E)b1"'AKCsVT^k&NTk%Q-`bW@U.E[gTXX^MO]Q5=<UD0(,$\:im#-3XP -Y->Y)6BJLd&)_325UuYk+q166`]5\>T[GcYdiaW-_FZ5uK.PBngscMDJt2pu@sH]^ -6rU$L0Zc(T:b[mH+@.YL"+\6K$mTH.3XhdJI2n7=RUhK-&a7:iNg-7j3$R<tT,Af0 -\p,f\".77Oee?j8(5>,ZEYJplHqkBg@6e'3fT)V$.LcqpTjl[J9p]OK(.BrnfYKhs -2i^rC\h]<]#iITL[fqdH?+,`Q3nM7qbe2SO/\3Xle`cEXNe80H)heAZ;D*iY;QX1V -(#=4=e<L_h,h4+S5nW%"-p\NgPg+\!c]UiH'I)QCfFSMp8FSCqomL=Bad-MMBAj\, -b-K7[Zn1.[O4l'%,*RqD"]p;+;Ah8k4[2cmFY0!kf=4!X#:m/.Eo"u>,hnsDe4g_= -a]XPf#JW:A()pAt5cKN:OoAc'>?>[2RVHmrXKV_#cs="&[DFH%Y8$'r5]#33dXuKR -jf&qoURk=\KGe1@M+=>L9KMTESu%o,\]4.s^DZApLp`<Wj^&9o)!X*j_#UPNTcnTE -'$e/HWPW`K)U#6qacbPbBREiM&6Ui<,>AAbAc[nB'p-UB::U7TOR>,oS_IcK%m`'; -3ne-3kYN+SFH*b8gTf)oNcPORlQe4R#%=#`&&&G*q`7L$^u.7YJH/Zl6Q0GuW5U0d -i*<VH)GjL(i&S"7!ZD[Y6U!s<#f$FD&"<o#AHhc8WPlZ@!D9hOWD#Il-l.o-TOSB[ -q?Wkk.$0Sf=q6(eLVa%5PlZ+Z8mpUYJcP(lOm"7un<q'YKW>.36%a]LSL^sQar!KN -!f9`',,JCA$R(/r8.fD.,Zn`5+ga4a84"B9"K)g*+uDp^+uH,AXV7F^;IOO(.R]Ze -'-jSqLqnU(7(B7^&NFA2+k/CT5]n-2\7Sd(!&HnPjrG$nEXkpnQR`4jQiTGu%3WAZ -61bYJ6^W!+!Pre+75VNlO<R9C,oK4+Y:JP<(fJ`/=K0A-*2E.@NU2rZaFHMt:he2t+9~> -endstream -endobj -95 0 obj -1521 -endobj -93 0 obj -<< -/Type /Page -/Parent 87 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 94 0 R ->> -endobj -97 0 obj -<< -/Length 98 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1d+Zu(MU@2'iJ"Y<Dn?Bmp`(=jY65h3ocn<;Z6(_8NCK"C]OmeFK5P,K*5r^L -17IkeK75\j[O<u&$3l\336EZeoS!Ni8T^mW,cb_%[^-"/)"`QE1*X1[U6tL1%HE!$ -1lcH]'Wd$<Wjn$:@Bs4D\1]ql)*lMY(_d*_8DGqZK;cjHKE:,mq2Aa$clYTq1R+me -O+ZNi#_OPf0of%chDk]><+btj_mm2j"9Ymb1lQtc\.j^;ZEgU4MY%%9.*j^YoE52n -E#8c*>E6;91)u02%YI=/2bQIo_[WEB$[CMr;^cK>"q"VdpP:&%fJeb!#jEK8!sm^4 -`C!>Y0TC]UogT?5!8K?,,D:Uk8<8Sk,JO80?k`djli.?n8h@RS[r#*`"3dI%eMTM+ -5bJgG:)J!c$mUkN2N5"FjSU00TMZ'2cic')<UJ8W5"o[hC6(?='lkZsDn@`'<E=6H -4A7FLB/24R;Rp%i<[d5n%D`%G'VR$_JJQ=.%9YdH1Xa6`VQ``'5f&[22,48V.,-]l -+U't_c*[u=;ChE';eFRCik&;tcn/quXHgZf,**KVi&3dc(&&/;nE`?'6oM&U`ZpOZ -lQtO*"Q*(u!EL9nj\aI:*ei<!EY(`MUjIlM!U)h>8[<`G/4.X&!W~> -endstream -endobj -98 0 obj -912 -endobj -96 0 obj -<< -/Type /Page -/Parent 87 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R ->> -/ProcSet 2 0 R ->> -/Contents 97 0 R ->> -endobj -100 0 obj -<< -/Length 101 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W8C?2k,c#P+efg7B42" -Onhu#EAa6-7SpZ*Y),UZ>_[k3c=2PtabUCVU6mGOO:VJJ[bShEAK7&lL8/EgLL%.3 -Be"@q"e*PFe\n1?;5SGC1ooDc"!MNj$&6B!TTeXD]PKRZj[TsRB\,1=N7=kmBHY;8 -^P<5<EB(.,D&hVAD\oJ9qZ2<3aa"j)8#d>^"9G`?)?nD*j:hr2aP8_7".7Ls^FJ/N -R]GZ#MV9?^1+N;eO9fD!#4IJ7&WJ#S`\n=%+Nb6#O.uIe%0?(kK/osCGeC4qk_M!S -@i4:?%YK#e&-YpPm(eRSi(stUdG0'jNY2bT'b1W85V<3`g`io&Wk-(GV$]Q3otUU. -f`J5B<1P+%"%r_JbYY<3Z67=I3AS!NE+#S-6J,*a%1mbL1CgZDkr0'f"FMt`,G]Pq -$oCMt4:EGOks[mja?V\Ce:9h7N,r6t.0V45?k`d\!.m*<JOm@%#thOmL.9A%a[V4E -@-/"/K;d]d0=5E81'Q+[]e;THbD@sgkbr553)`?_57.E^ABorR5f,Mi,A>7j%TP&F -'LEO_@]fo6XcVF61T\ZTL4R2f4h3)^5r_*;65CLEaJoXu-^43(("<s4JKY./%=);_ -"!*(nLD<6`=92Jk]!,<jjd?UoBq,UB:VrC23f[01X;%?OFg<^?&`tH^Lsq@83\7a_ -R^8p`eG52%j$ZsTfCfXn1/m_mGrA8M'hT<Bp+=OHbEJ10NDA]9B'mhZW)+\dK5H(R -YcKmcJ:I~> -endstream -endobj -101 0 obj -934 -endobj -99 0 obj -<< -/Type /Page -/Parent 87 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 100 0 R ->> -endobj -103 0 obj -<< -/Length 104 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1d+Zu(MU@2'iJ"Y<Dn?Bo3#itTY65h3ocn<;Z6(_8NCK"C]OmeFK5P,K*5r^L -17IkeK75\j[O<u&$3l\3%,Pq;N+$3.60++_N$BIf3<^VjW$N^iCWNrj!MUG'L6-F" -[k=DBni&bmR*n"*J5WZiVQ/W4Tn^[8_Vi)q87`#hOJ#D^N?`D^2@cr&5TW*BR)TpO -!VAF*3D-#jpc_KHLbb!#)!(IPK6ZGg"]<J,q[O//!<EZsi(stW6QD.4a^^!n-\Xp? -kS?OZOC4M*_$#?>-]`Ye0?I+&S.rRYb/jQUYFrTg%&:K)K[4'l\.j^;/.W7A8h-dC -5tOK!#/T6uC:"/kRuY)*P6gA/NT5+B&&FKV9!GdajAS\UW/tD`dr0K"0TC*<5VRin -)t#hA"*i$$%YI$h&6Ma;#@?$T`6Br,'<K/7X5SS*(K"!qZE;X*C_lV.cUBB%VKC;B -'FFk3ADr:e5f,Mi,A>4\5]=d\)?g]5%;RIgjg.o;<okeL#:Z3N(KkktNChX@=DY;i -'8#L!=@!+W:<q:9JhW49!9Q*Ij/CTc=HM?q/(jOEbVG-CUBO+]<-#PR4"Dp#jXkKc -lXeE7%Ln)&pf85a@DP3m?c*`%S19AIAUlUJ=IkpW8]cM22@Y3;`F4bdZj&V6A"[$J -c,c&4T\]co<5I;aFWfMJ=7s5$_Fiq0.:(u4j>R2CYYp.VG>r9%>-qmdY@!:>.CZgi --",d>30]E#ijtD-V:]rBYRh1nQt@:PR6X"n%RYKqK4V;#HSpO@:)bA7\Qqe7,b]E= -)>.dD>S%5%E7nQ",:kkkL.IOQ[cX&!iY6Fa5"1YE3Cds7%J\7qW]qZB:`tSSSU69( -1GJ;RlD#[[0\Vl-=kHqXPSmJUDUgPR/tscaG)cZ;I?h@a#Q~> -endstream -endobj -104 0 obj -1171 -endobj -102 0 obj -<< -/Type /Page -/Parent 87 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 103 0 R ->> -endobj -107 0 obj -<< -/Length 108 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W8C?171g'P+efg7B42" -Onhu#EAa6-7SpZ*Y),UZ>_[k3c=2PtabUCVU6mGOO:VJJ[bShEAK7&lL8/EgLL%.3 -Be"@q"e*PFe\n1?;5SGC1ooDc"!M?rB8"03.o8h1!a[c)C\"6WGdM7UVoEIO9!f.> -%c>0Y3B3O1YVqM^/iS^=o)4*TF<nMYs!-*KU4E;\)?tb6LA?N)R.<0Fj+-8KNc3@U -(oF>01nqF864Aadmq`+E5bYgNjTK'agbFe@W5p`I!TWIZKu60'r?0C#Y+>e!Yhh3q -JHT<VYTo7>'M$@#qB??CR)V->6_N9r"9D?W^4ZRG;B<VHlH60/0B,g(/?`Rc)M\?H -%'R3>7$T)/"/+($NRH%e$RDbs%'r=-(i;&5$?P>]K`W[W2N9I_5VRj(R)_'UEbq<] -X?hA5(BadFfJWj7TY`LFF?&(tNe9`&.?=Q_0JX%ne9qU\U7daO3N-J+"],:<;B(<# -_CdSI_+e-8X,?PZrPMAU_Z1m_>g3AR;uiR*L.pfO'JMl[g+n\@.gDdoJON^C!EKWt -@CO\_mkH#h/GVLj<)hrY=D1fQ)^;47W1HfeV+!ennkC&]an3[%<.k@@co6u[A9ot! -Q*kU;%(52FE*+mL_.#X;4?OMdXaQU@"Tjsn3fZRH5V!!d86oqg0hddffE*nmE_ae0 -cX\TcRpS@i3<5U0%((P)8`gft[5ptubjpXG@E]+?cm-N23%tllUk!s~> -endstream -endobj -108 0 obj -914 -endobj -105 0 obj -<< -/Type /Page -/Parent 106 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 107 0 R ->> -endobj -110 0 obj -<< -/Length 111 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1d+Zu(MU@2'iJ"Y<Dn?BjfGkqJY65h3ocn<;Z6(_8NCK"C]OmeFK5P,K*5r^L -17IkeK75a%dVpTQ9OqhIQ^K/.q(9..UbgF;5H'Ip\r("=gc(5qR*n"/lH!G'X,,2Y -)^XeXK(HZ!PPXu<@6d:=NPcUc3fJ\>5TW)WLrL5?!V>`33D-#j'Fr$*dP:q;9B>pX -UF<Vd7k]MU+q166`]63BT\_[3!Dq_M"9RLZ*Pnc(MQ/2Qb#"iqcg/ph#-1!p!BBDH -M'GRoJEShLj)h=S67FD$hD^P7^`&q5JsS6N@6fbcX5QG23J7J?fJWj7BZ`6TA&pno -N+3^j-]G=G`CC=["J.?lniW*^ciJZ)'Eu<D\ge"O;R3FJ&&WS@9<\!'(oD?uh`cnu -87^\7+[En)$oCfE16,<8()d>fAPZ:UD<4sW4HlkZRYHC9B0AVhgtr"[W*!lB,m'lS -.LctI2bqUQ<1#]U!sn*%%V%c\3fTB29J\l-,tc!R;RGI:5?3ZV)@!W2\QaahONKTo -UQF7B$Gf=I[F`eGMc3Ulm,;U&CDI(g#&%;I4p;"0gA<Z@-8B+>epOj]5BF&@*2n"c -l6;9)#iIU)fAiBOJ,~> -endstream -endobj -111 0 obj -877 -endobj -109 0 obj -<< -/Type /Page -/Parent 106 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 110 0 R ->> -endobj -113 0 obj -<< -/Length 114 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W8731)13EECj!W<YiW. -Q$MKRpO0fE$>39Q$OMOk&SeOa,^r`L*)1&9;3W\cCSF[Z(EoHeF/kq]FJ8kF.&I?u -BS6AZXg_;$)+Q"I+fO*2Zf#f2RqeO46"[E*\%&@O,@3(Cgi!9G8Cn6)buUL$l3+b9 -38j&A'(KYe>>L4-Wg.6?`Z<H^%!8a6YFKEh4"HE$a"NA?a:u&@\59tp+i%J%#%9d7 -"9lW_:r3U7TTmA=6'OLA-]f8>!jD*h'Zi+^U`0PnOH_1%6P.[<`O[U)oS'#j!,W5M -aGR.2"Tk(^2\"etjtr*9p_9k8.B:+A.'>=%K-IS4q&L^,"Fdud@n>B0NJ"1N15#\h -7_XSo5^aq$bY&ec%`<P>1'A7Q%)B)Vi))P?iu!S-Naipe]af[>j:DJ^K)-6YO=7%V -MSf/Q6k4j:ljsPU89Zs@CASr0c?*hE^bT`-o0(CKI3V>2,76%^%[:O'85`E`/PK)@ -;Rin[lO7Hk.17[#*50UEI-h(Nr<#?G"/+($NRcC8@*.X_aFc%l[>5\]l>s?6Z6P`% -0SBOIb*^.DYYZHui<9W$%WP$<F^9Ou5sj@8"Vj6u'GUpA?=A@l'Eu;QP=`k4.,Hug -0[)I6_m=^p0nh;XcnaUB:t@DIK1O77h''bhG)kTRkVQW@^#1T(ZQS(i9S3W'Mi8l' -ndl5)`0!ZG/M7?a``:a9?H.#Sb8XPsW+[.&b5;AV$5r/:$WYl1kVA0"QtVK`&l'Gn -X1$$(kZAV?P-^i*E+*ZU(Ytp&BS]c,)^;47W=XabVCiR:W[&=-fiRj9J8_-kC_RBS -\hCd9_+%0TnU\=fEt8,,'p.L([^n:)j/CW5n?>a.aD:R&))oE+"umE&6'fHn!DdB7 -\Y?0!/(>%DE6D@#n[@K2mYOF$"[IFaakYG=SQ(tr;^WZ-h!2T9O^=fT3R:Hk*eB*q -]g%;%b[W#&bZB4=2;*/El7;>OUUPTDp)B?N].q#TY=N![IE''MCd*N[<XL]d8DoAX -2U\kaGZ"sDcoQq)g^!tc.;^Y60W55bfGfIICl;`.5XJuif'6I)@6&!]"k;iVqu:JI -rG4<H4:K&We4X2B,):nT*!9]4I#C]H1dn'2b9Br&j>;\qF95b^Z[l8:'gnp_qPMKS -&9S?)<NgNs'F[*%Hf2If.E($='t?CaCreL=nA_&dJ8#N[PW+>-obA1(R9'u/%Q].& -*<VC5%KY]K51!IDK;!opJ;>TV&?$4.-r(,"J0tI2RLqh"F,S1c]LV2d*^bNiN(MYE -KeS5o6;2KZ7Q*mD.5D/R&3,nHFjruja;RE^W%>6W0?Q^8+2bE?%^Ken7tAZ$6\K+U -5u8bZ3>WiL4GaE.781lr.-%/64q5>E(^8T(*Q++%%E[m.9:.4c@e(Xu$1u<,B[FKC -A*oFK@.96h~> -endstream -endobj -114 0 obj -1596 -endobj -112 0 obj -<< -/Type /Page -/Parent 106 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 113 0 R ->> -endobj -116 0 obj -<< -/Length 117 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1d+Zu(MU@2'iJ"Y<Dn?BH,A[i#$Whoi+aT9ZT32\kMajI41gVt6gVL?QlOIB^ -R2J_F[R%YHhHL[4:'C_kN/2%''a5h2(uS4EKduk&)?g4&;D*iY;PrP!JWq.S-]`o@ -qEE6@VE0Z3e+g>cn-EG'^p#p6P-(o;g<9bWA(:fLC?(C)O!AW#3"BFhk2q4ebEem& -Lsh"s-0kqjoK>b93;5&!(t(>O@pnRW%&!ZH$,3*PclYa`1R/4uZCo2e$=^6R3WoI_ -]HE/c+K-uQio!WE9@(-10of%kkVnN#.,arUJH3\H$o>t(2[gpIU+QTmgp.Ja@\S,B -^2L*h0hdcg+u.=E,VKSNPB>bVdW6E$5`DIWks!Gc%*Lt6_$(E>0N$!#*\4K?G1A_F -9@=A5DAj_.0!gf,3t3EZh&Jp^4F30l/`V+#=+QQi(b'>^'_i#&.,$V?_^OXY$nA%S -rs0f.5Vim;Gh[0?'AP)ucD-'\3CCW5:_s69E8D.&f%B%Gc5-B*15qtN>nK@pb-tr\ -e\2t:76poe*26I3XS<,'9r/=r1apL-%(Dm=Ktrh`&VR2Zjr%d4<R)d,/Ij),jB^>% -NJH2#=DY;i'QpPm$A1aAG?@q+k*TgQ\3N)g5m:DCgeIiHEeFO^co6u[@*+'fBTbTP -"ToI5Mq`FC%@[Q)<GLnP\`=TbliVr5;eF_%CRo*o2LP:5,:HG*_842i\K^pK!GQ3\ -%fR=MGHgP3n(^,2VK+e1mAK8tQ@X&@@Qt[IC>-\8`UUPMrKHQGA@N=iQKAR-ei6^[ -NGY*;/%>1tId:Q_qe@Xp695=?Vh>.sc)'[3SsOlu[d4+4@/WP0=t@uM;2<j4<\"u! -p;lGYN^IbN.g7=r3@A%bjcet4R!#$,-D?fAM-?2LVfn'j?9p^!r^Oo9ST&*hM1sre -OIR%P?qb_J%I'.uWl'r\f`i_HM]@8)*Y^#A%?:29ZZ9g`J5SU&,bZBr!'moJRI,IF -`G[:bjIR%4oi;8+/JZ5GQ^%ng%Y;hc6T2O@_/qt?C,JN!Yj;VrlCUCuh#+/$hRf!8 -+pjrRW\.+9X-?:FC[g+8.Hla,+riKnTR[RY\AIOk,\.?=FZ76H=q?7i@=8`==Mn7g -)Ijuo%'b+"7el!`e3mK#n`5VK\D%N<`'04+JhdS\E-')+~> -endstream -endobj -117 0 obj -1433 -endobj -115 0 obj -<< -/Type /Page -/Parent 106 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 116 0 R ->> -endobj -119 0 obj -<< -/Length 120 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W9Bd17XCO6OB8\<&I[0 -Yp#rMH$R*\Dtk!f9^6*(@Bfg,/QN<+O34>0M6,Q+154(lF@n6=j>7\`FgO1^TKm;s -'Z!s9."E!h[d.W0.-/,'2&emUgcd@JF&UCU/CmHQ!uV09Ck`e]NSnB+)r^<Ig=-a` -5aRIc*)08h?7d)^.Iijl;QU'=_n(rgNhRkX]g8q`mOgi\+MKMQ!9=iJXcRQ;0O[Li -f`qOC_A'i&6OYT)Jl<A?##P`cSj:KK&BVb-BO(kKXLP596SQ//%E#.q)X9&\l5#6[ -!OP00+tC1b'FJ?kgc(5qR*n"-5Z5*/VQ0JLU:D^>%#W)$r-FDhEY@jRN?`D^2@cK) -aq+f?1AVdr!VDh50l1eD'!``!W%!V@puqteTtCLHK`P0'"L=!-\.h_r$5irLU*.T= -N+8%C3XtUQqW1NuK)-6[1\ad$N<9VA70Z]sgb=__/NT4%!oQrsKeVRN3%OMF)*:V- -eIrKj1`T@.ZOADr?.!a6ml\p7J8G^K6\Ro`NPhSPpaq_95uCaL-rj3r20E>18]p>@ -X/n%e:o#YGoQ^/>;@C&M;:L:F3"CR3hD\$3Huj<RX!.tY9/fs`m4$?I$n2U[V'IgV -e9F54Wo6VA'F5mB;Po-KF^l>jMY6de7i+jBMM?]*Y:i/XJ5_$<E3SG'@4Vm6)C'f$ -R;cZFr]bl`\,Fj?>+pZY+k&e!nfqEQPC=;Pelkm"1#ekR1[)<-,>$=W"Xjoj;`Ne@ -%3m:CNAGk)`ioJ>L7+qoEEqQ==ie:OUZj_s(T*q*2P@]t>,@j)Wq46;2sZq+_6Ig8 -:<fVP>Jc]8D>*'kZKW1^dC\YteSW$R*0<EEN7uj\LuNZ_6njXP!9Q*Ij/CTcE1mKM -_!F-(2\0E14j,?,Z-Ifd+]8BV!ehIVkW4_kE'PoW-r*r"b`mTqE:1>*VfV%S)J)?N -;YDLM%Kh*q3\WZ<75KnYB\h<Cr:o=a$,WX.-?1sS4mQA)s*a8=CJETG_C0Y/!PgTR -2\a[QMYp)"]Wri=ILO&L70_re]I5\>][W_F=f(dn)7=/4ehXdY+j`6)BKBU1qg2fq -\ba1,*si%R+:"Qj?Qc*JY^o1";db+f"TX,h!_>`d_,9t1&=O1s&0P3!]VV>^.N+I4 ->(j.835V=S'u9ks"OTb%!ml<8"3>FTi:\%e0S1"U(eG#g-ksWhC0i*oE)K=u-ps(a -#shC/$\<7U![(V^,4KIX@)+D8oa\Cfd]S<:GWS%j!?31BS1:<;~> -endstream -endobj -120 0 obj -1438 -endobj -118 0 obj -<< -/Type /Page -/Parent 106 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 119 0 R ->> -endobj -122 0 obj -<< -/Length 123 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1d+Zu(MU@2'iJ"Y<Dn?Bu(`XS4Y65h3ocn<;Z6(_8NCK"C]OmeFK5P,K*5r^L -17IkeK75\j[O<et:'C_kN08'7$:[Ag@%c?jMkZl/P-(o3g<9bWA'u8].#QfkMIX`_ -2i\!-dQ+jg;R..:Wo>k/L<4bYi4SMLAH]].GYf!3,B1X\%\k/h&-n8[kV7e/5^a'6 -c;LU4"Tu!c1lQtfiq^<l\BHmiJNuIF#pNc7&-YFgk_kBEBNZAZ&b)bB";;3_1!Ggi -D#/s?.-<7E:QXd!N`)P.qTE[fV_:^W/G1_]6EBN8#(lX6&.HHa_D@3\!4W_uE6>Jg -Wf$EUPUOj7'(c;-X*b^Lc8t8Jc#[RV3Xm<Yh+%b#X?;ZI/`V*hdk+[0V:3b8Tf.nJ -V%XWdA!#Cue<M^Q0T8ADlTpIQ"QhGg'4foY=CZH13Xl[lJ3")`(fD<,(9#=T5Z>6> -O3?H[hC8[[^ec/0nA@:$"i3`6'8G+E_#_sNjW_aTJ\/rEY+jidV,6hR<ILT-bG^Y1 -YB]Cf`WIgS'8E^^o)RYTeb$#O8=4'.iJHUP,KB:SdMP3cE1SKbU'R06_c9A@ICN^d -)3EXi5jgIgK4ZIO"Ts;92iNBfa,+,2VCF:_pScbD%/GO?iJ*>]P_NQVGhEJSK6F#c -LD[ILYi6Po^_BuGc*qSL[f2J.>o-MoG@Il7c_bORINu,a=N4hKW452?)5HCR)Yd"p -Zgj6o_O-INh&GuFRH&k8b6DSsep3l_f:'dW-G$n4O[$a&fK?U2i'D*I@s#$pNT2s! -C=m$mZ#*^2pK'`MQ\Jp=n2TM["&dKB5fduqleE0]&(?7Qm/r\]3XhdKdY3F,6nuen -?4+AHXBmJ5#'/7a<@^]ED@O`586B]7F!@MroF/%J@;;P8S7c/'(&`_'JH0a#$Q(cI -:rL;9Z9;H0AY?)ZW3jnIl35.'1a-g'(rHa^JF<C(Wj9?A?\=)($!8r6@-IIDnNA4P -<Y6-JiglF[.;EBJo/1P<\QT=4KaOsV65BP.+-JE_CGes9o\u@k<"=WE%N)4PZNpi< -2M^W*JgcFu^>\E0L[(;[+.-IA=5+jOXGt0(?t'OI9.OST^$[Rt3,l^&%Y^lB3%B[a -#DmL]N/8^s+.1@6>^0.e.tu*^QRksh'Q]+JrY3"&."Tp!1BtnijYN!o)+1'>%T!-U -!g41"gHuR"EY4^1f>)9c6cP-6nae8-:_TS_l"hlhmO8BoUs7t^;WQ=FOl\Q(%R<Gn -$"Q""a:NDbOT>~> -endstream -endobj -123 0 obj -1533 -endobj -121 0 obj -<< -/Type /Page -/Parent 106 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 122 0 R ->> -endobj -126 0 obj -<< -/Length 127 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W9TV1R!bEdjV#jC'>2a -Y\>A3<APUhB(Af`/q[r6;1o`/TYPW;U![nT"(3OS$HQb2!26O(2+STT-2/R]g)$O: -Cp]XGSh<<@Z<=T?.#jI*T,8"epE;fC=tq#UYo'Lj&q*$3NJAGm\DggH)Wti)R[$dQ -";o%d0]A$m-Pc"XUR\B@.(=K8hb&K_^3jr8$mA:A'JM'W$8.3f;G-%1/lUJXU4E;\ -)?tb6MY`#.R.<0Fj+-8KNc'pmXp->T^5XPCZ;?/tY^>76##M79qDj*DdPhSE@-TKU -T`B>N07t*H1^DD@%-OYTi(u.f!sms!"]>Hp4H9Lo"MtOt5X<!iU.F'##(lX6&.Xl! -H7f@EgdJ:qb.>Ip,mlu]pHg%%E#:paqj8Q9UR9%]012D\2iZ9gNB'Dk.`d5nd<+Xm -:B?';qS(rKdQ:72+OM6icnI^DN55MP^<Dcp;Y5YDE)Qm*;e!p/6#g+g3Pl'#C)Jo` -]&`aG!D$c&aj;a*16,?sA/%EhA4E`LQ%OWId?CDCNs4$sQFonsXUR[!#Ztm^,,d2o -Sj)/12c@f)+PmY<F<rV$9OjpM3aCYMVBLd?83p"TPrNb_eSn6L2QRXP)d5\hUaJ:Y -n$o/KNe=:k2Zs2d;M9bMpqn+J\.)Y0_:E`EZJ%19cO*j_STY\Q+\5eZL*8h?2obP3 -MjLiF7HKkJ$d?@p;kmrMS?RWZhDl*-*b0L),Gp\>%0Lk-1.4.BQVH`)R-?jF_`iem -B2WW<X"QN:H[7sP'TS#&(FE:3h`'@S:fC6YZGP-,<L$W_1R8PA,,(BF$J.qdMEES& -JCq`Cp0:6li3>m\Z:23bAJr4*]C@#iPP"o8?;c#J;2fQt)n!d<^g5L3b$)P+%N=9h -1J8kk7<:it"G.DG,AR<$pH,8?&-Ssl`&u\$+Qb9aK5a3oFg=HU]EB:ZXm5P0BRDO? -+aP6oFT$D^/UIE/Uq\Sr\B?H#+nk@]";=:!l)LZf~> -endstream -endobj -127 0 obj -1164 -endobj -124 0 obj -<< -/Type /Page -/Parent 125 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 126 0 R ->> -endobj -129 0 obj -<< -/Length 130 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1d+Zu(MU@2'iJ"Y<Dn?BH6OXG8$Whoi+aT9ZT32\kMajI41gVt6gVL?QlOIB^ -R2J_F[R%YIOD-Zg%43hb4JY7i'+<u`CmNfGXfT<OL-7hu#)KD)W2;\:_g(*"N?aqh -XG/1(\;_nFZ<jcF0145,5]:HO'Eho:gbFe@W5p`I!TW,6$t4,%+$Z\X>-96(6sf]' -YIjB(Mh+,Y0?)pAL+e?lBS[EpE\*5!8CCmO.>.c\;B<VhdYb%Tch^J54Ra<<&-eiD -?l)*=3pImtUR9%]4p.J+2iZ80_$d'>$[CMqdi`K`L'h28/VO6Sn2Lh$E6/DH6)\6, -%YI$h'Y?Y]AeYY`Hrior[!9eT%HD,"/rG6W'Weicg:KJL@ChbW$B`PgpqCc:Prh5d -i"WIV[<edC:kP.m:/TMkcnLKG,p"nr1i49gd5E+X'F^bPat\pOV'fmZ';\2sJPj"5 -O"IWJ).0PA#hV$<"+]5g_?1A&((?Ko_@R30aPf%1"*i'AeMG!MM$@Ci2fqSjS=q=O -e\tLI+`S6**/3#L*re09<5Sc2MYti(/bC0Y'S]@"EYJp,OMWo7[a=(LL+$/;'LGeG -9iO':drb0,P7hUK#;cSejC(qDCa*<:^i5W<a[KYB:kGMiHs]`YkVn//aP8icUQF_f -CD;_0+GsVFOsG\_G#q8A!CeT/<9i%U<JA"dCSon.Y+?>@\6t)ff3>\QM6=FS=?&Kk -!'tARp<=r#DE&..QNn\*SQSP<564ccMD]gqhkP?FaAj(i_#Rtd(haeaF&#%9$<_'- -3=We)X;%?Y?;VE][f1.h:ANE3Z#r)%@[YRs9aE+ARp^6FGMJ6R0/nt$qP@e,!p`3b -@tj)-6IjRAK:pTZI$nB`j4q5d@iX/\:'66R3<T@a&2D?JKP_\]ZCaTohqJDFJ\4%I -,Zl!_1\lP$JK)BQ#m#SWD%%TI"VihX_>tQ*%*4hP"EOnd_IuLId"!6mKS%_jg.Zt[ -0dm3UMLM6):5+6G(IJI#PsJ#B9$cc,5K&3\"5"`P;%=d<=H*pP6qN3nEZMs*)X&@_ -n-Yj72[;T](Y\c\636<d"4c+Q_.Z"A_/'qlfBX6j*+=e6`%H\PP7nP04^ep7I':$E -iYJb7$h)467HB(A;.(kGce^@Z;!8a+F@q@O_B),;EtK!??O\b;77gW6'&m^CLXKL( -8_B:Q,'9<1E4-S"#XeqBoV@5X@T5j:diN#OF:LR;(!0#^-m[;`LgcZ0LF>nhip\[^ -`1.l<Lpe15*41J6H:>rC!u)q)6(*p3:X&%a1a4K$Mt,q1^M.!lA(5mlP1i])M4Z$T -V!4&kRVU3)N#G&?-]\pl(4lim.=uZbSP\T2aPuLuVn=aLZck=&8_#mMoKS/\J2s@G -iB4"6lj)"n)G3hq%FVW4Tb<5.:`+*eW$MY=1i?Se5l3b07/W1SE"E9-qFB;pm74)4 -r<"HD#D/cHKRmSI+#KAe"*Hh[E8h4pncA~> -endstream -endobj -130 0 obj -1751 -endobj -128 0 obj -<< -/Type /Page -/Parent 125 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R -/F16 31 0 R -/F20 37 0 R ->> -/ProcSet 2 0 R ->> -/Contents 129 0 R ->> -endobj -132 0 obj -<< -/Length 133 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP)GUG<8W8U(.1f((_YN+f<&F`5 -[9,8K5:W(]-F7tGaqm@Od3uj>OO.Aqc-Y[b@0*SH;[$]P@K96UgRFuIUQYM9e85TA -Cj(,14\lq<ZWSj5k`eQZ1scX8Q$\UcA1\Z-E;5r/C'd(s9?+l/Q=+\c(6*CbpruF1 -<e=BW1Ks]kMmnp:U8&^8:+P(lEpbl;):[Fs%&5LA,I(_QRO!a:0S1i:C9sS6Vh3Pt -3"A;Hgc>k\i(t-#/<F*VK`Ma`1^t\"3#]]^!7Eca,<3j[6_UkN'Fb-Q@2)1.!8o\p -"";hA`@K$c'>*4BC_RA35g(?A+[G*BNR;j9)2uIphDWMr!(o">1-j_Lb@9D>2ZuES -;D*iY<#i*>JNuL[c4bHk$OhZ4mOsR([*6H_E.[U>c81si4&5qan.5tY89Y9LW!E~> -endstream -endobj -133 0 obj -593 -endobj -131 0 obj -<< -/Type /Page -/Parent 125 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F16 31 0 R ->> -/ProcSet 2 0 R ->> -/Contents 132 0 R ->> -endobj -135 0 obj -<< -/Length 136 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<!jc`+JJq2b"EinOe_Ci -UhF6BYYeg2@;spM2].L-_i^clgJ]R=mK[]-U-;$rPDEd:8N`MA'U9+mU+JtH,`g*F -@u7;B'Jpb*`q0TQ'&G@!;(+7UPe>WU.>"gLd/YS7C<k4?n]?3nIAruFZ=47AL8.\! -=61!1d+Zu(MU@2'iJ"Y<Dn?BH6S&]X$Whoi+aT9ZT32\kMajI41gVt6gVL?QlOIB^ -R2J_F[R%YIOEit[5uj&+f!u]mNMZ=iVm#70AF\r<E"kVA/cE'Q7?!iV8@%Y::e -3WoN^(aoh<(oB-N6R]GY$tFP;3KB/`$l5n#i(stRO_e;>`Y".F3(!cbLbb!#)!(r3 -K6ZGg"[dqu&.=%[G7t)k6HU6&.\p&G_!k$1#=8ud.18V,aGMkaUM.gV%WM>Y)TM<k -FuW!sr.?06Z9&2ga\lZ<.S9+d&HtI`Ua$2_Ye2_@$=^A$%a7l@a$:!\i)D`IA$h(; -8J+@]!`%1.o*<T^]a[A&EpUP1:pS=V5g`PB*B(W,H3+~> -endstream -endobj -136 0 obj -639 -endobj -134 0 obj -<< -/Type /Page -/Parent 125 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F16 31 0 R ->> -/ProcSet 2 0 R ->> -/Contents 135 0 R ->> -endobj -138 0 obj -<< -/Length 139 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP%)`:c8PH'*-]s&b@];>A<$[[L -`A'q\e-[DM@+%UDWb+5Zc/bWJ>mAnKUBiJ>6%J,c6_``H#/F)0'pm.#!CL(/L6+0N -9C>/EZnGFgh!4R?4HtHBA@$+s;&^q49J@AbmQuLZZt#*9jD.R`o`AGX*,[RMM0QCC -Uo24I<D'V0A^Rf1m((3-=2En[gd+B@aJ;uY#9faF)?gN.r4k![,7MLF9OPF]#s_Cu -Ub&OW_N257oB;&7%leBc5:_rm09%3,TJVU:8DH!1n*jfe#-@#b)$Q^)@#bBkLi='E -n;7Y?.70bR'L]2c`ZU4m+K-uQm_Z(K7H(PC+[9um9b^/$+Jq2Y;I#[V#%>;bdg#?4 -CE(KkLhe%u&pbgib)bVA'F82VatSiQFJSt-&Ys7`"sKMi+";8WY+ABd\ApXij)E1) -2ke1e1XHWEHT+JP7'.[>@sHooM%dD?1=%`YGn8-*o[+Y5<#m\Q89:0<+q15W]dH>6 -PbT\V<L%5U960Be(EtHm-U5j![9[%d19GpQ7DZcO)`If!c"$tYc'LcMZqQE'$0%%u --4,;!nR=No7B]^G6%ucj<Yffl,9lc,XL99Q4]\@aoJGT&`<&$A3a*\do4q?)mJCeZ -"!.S+<$MiB;Q0],ECjRQUs!=Ip1<9&?oT"#2FSFhe/X6"IFfH8=REY[iOF9J3Q9'3 -L6lIm-uXh%'p+q@Nq%.F5i5NEh3VF^4lmmq"0Mpq#8f34N8"B1H)5$R*h#-#GqNls -AQVXL2<bqM@mp_LX[kS*lub$glPONg[Fd@KXG4rF/CU0V\7K5)$,[&'P6RD^eZhV& -f)'^NU:!NPNAP=;0TAGIo=%klL&Y:q_j;Og%3p'K(C"btB<"sOh\We`,Kp%/]]q(I -NCJ&-0'sc(~> -endstream -endobj -139 0 obj -1068 -endobj -137 0 obj -<< -/Type /Page -/Parent 125 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R ->> -/ProcSet 2 0 R ->> -/Contents 138 0 R ->> -endobj -141 0 obj -<< -/Length 142 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<<Wq*,P%h$ibLIV%0k<: -]`NmU2T]DB8du2?0/`lh@&g>65RJJ>W0D(_F?s?-=m35;jeC63+VcI16^9tD0-a!F -77beF%?I7"X)Q,p(ih5G%0Qi-$lGpQ_4AD2YsB41.2[pH6B^S0PR8VmTMRqm0(_'3 -hdQ*GB[g`#MoKK#&-~> -endstream -endobj -142 0 obj -283 -endobj -140 0 obj -<< -/Type /Page -/Parent 125 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R ->> -/ProcSet 2 0 R ->> -/Contents 141 0 R ->> -endobj -145 0 obj -<< -/Length 146 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'.<>WE^&c*_#SNp(Zj$8*TeE=e"0'U9+mU+KCT,`g*F -@u7;D8hu+ID0/B(K'"m,%W\p;/jM[<"VedT]P)g02&O9<e;JKBju")EolK?X^HnTo -<M5Xn-(@aELtP7cTnUFaEtf6UUDsaS$X/-XW"SX)j'+/V9?!Z2`BH(UgqfY9.ufb7 -A]R:!]j5Opk$,M+7AFXK\7s(!ho-niTdi[?+NlOoKqa,#?lC?4qi8=F:1t?E.17W. -N?H&PgomW,5_LNkY]M"k6>UsF!2JM9I^c2Wias+F:O#\QKs-SG(C";5DAFe.Lg(b: -Tu6U'_<UA4YWqXrb7['rX&+MhMj!WT6c(Z(YJQ0%/uul6+He(^N"glPaD2,HhScZY -EgjLW7%4@o&VO^67a]01*R58gq#<YgN2\#1Z:!-JL>g&a-Nt.0RMe^R"SXTDJHNuI -bk)&B29"%7GoK9F`.^Xq&j+JdXPp6n8hVAW'0S`;XKF$?,!a:)N.WP?7)T]a(mI]. -Hr./(9[u]ma&K_a43R:cD,.lB9F?TpEGG&$%&:VZ3fTngBe[J)D08D&PT8?mfJA%r -9ZT)k_dlQi-t_i#c9RdrgD*Oj$nif4MC/\hV+iU1p;Lq_;:@:8)2?U?SR>1^XD]*; -+[k]?/!i*g>[8bVB7aEiaIRQOGEqA+0='E;7Efnmb*g[$Qt%INpBDRjdaP>?Lu6fQ -5<kjA/P$Q_)!+[H??3pR-j_(75U=o*E9K-;_aqd$l!ntn&.W3Cj>;k65"?1AmmS37 -;@0:4)[=s?&NX?'S>B_#nhlV-1)1h#Sdcp[au0A)-D3'YFgaqn>C.)RZXqlV;.8Gu -hRT+@H,NF9K`[io,%K=C+uTij:s(P3ZPM@0lkS/`(a;u[$VS$r,kIJlfW*,<B6pN; -3fIRAlAL<6DXK7iI-n8(C\nWLQ:]go/fO+ZPBi$__7F4qL2]$Ya9nH-Ws`Su@e(uS -,!ULYbR/,c""bK>@iC)cP[dSLgJk)iotG@:kf&t@jsgca3'\\t4l:S#&sLIVm<S45 -`!g2t1Zr`GW"ct]B`"9/'0mf[U-CICC0m\2"edV*[?0Sj!GGDHcI(AYE*=!/#](!E -Q1)LGE^GT@%QJC[ij.b"%"VjX#/iA#!eqQh!Ls^DM=pZt2kg`^_khhOC(<Pn5mec3 -AHWHE1ku(a$QoM.CQQ&eK.q=>aS\Sc:t7Kik_,iUN"q/fSCkM?Qk[EE/T^!o[Qn57 -)dl:s7^1koP2K1K>uPNpD_a15!mYcATNOXEa[X'J_]g>K07f1hLT.29c(lm\##U?` -Jr&G&@#L:s;Ks=;^oE0!bQ<fF34"5AjV];jHBN:E8uu/#"QCte?#1BF"_gUYgm"dF -d;YLBp^Jk51[C?bOQV]:~> -endstream -endobj -146 0 obj -1540 -endobj -143 0 obj -<< -/Type /Page -/Parent 144 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F12 15 0 R -/F14 24 0 R ->> -/ProcSet 2 0 R ->> -/Contents 145 0 R ->> -endobj -148 0 obj -<< -/Length 149 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<<Wq*,P%h$ibLIV%0k<: -]`NmU2T]DB8du2?0/`lh@&g>65RJJ>W0D(_F?s?-=m35;jeC63+VcI16^9tD0-a!F -77beF%?I7"L@[-k-tkUW$jM:bV1oCX1#U@8U=c,B.2[pH6B^S0PR8VmTMRqm0(_'3 -hdQ*GB[g`#MoKK#&-~> -endstream -endobj -149 0 obj -283 -endobj -147 0 obj -<< -/Type /Page -/Parent 144 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R ->> -/ProcSet 2 0 R ->> -/Contents 148 0 R ->> -endobj -151 0 obj -<< -/Length 152 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu:s`c0)p?7]+hTR:0o4#+!n!Cl/Jp2LJOC]X'L5VX8Rqnn -1k#R,N=94G0a3@u1oA:r"*'8jEuukNC;iO\bjGfP9?DjMR8?.E,7"RnOuZL;74F*d -L7hBZWs4_Wj\mnPeo)iP6Kg>=,oApg)@Qj2l5^Zr+>s:Y@'$5-5RJFaF4>c*EaNi* -NM1ZHVV=tJWT3%TCF,H[&r>41RPB?@YAt<g7ACi'1EBYN:T+orYiBMg*)"8G>n&tR -;Q<`iK._;1fk&CGik=4K3oUJuhF/X9YiKI6#(],7^9?l2#/[V28@g8W5Z5+f/?6:u -O1;4]iedjL+Dd'%bEMKA%3mi;ZFXJnp9?PBE+Tdn,ClFDN+*pP3K.I4=um,QPYN&E -!Q#Zf"sIYX(aFSsA/)k!C(0@+6DA`9`%`6`)+;c;@2-\#CgJiRJs`VmNfc;3d3:l@ -JK[R8\54'b&7Vag-1Z-H'LWNI8/]RT65LAnUBo:,"9O+j3=^\/5W=Y<!9c6JZj;g< -YX:t61;@7r?lGn`1kQsmZXf7YU/R#C3_D+LBfsQ0fMF#WK95@QNe=>b6d[_r)C,`d -#fndA:Z@3Q;c?)A)GRM8QVa^T*:#%9F[WK7e[9g8=j[p`(orT?4X)Y@K-9=TL4R-M -9[*.ieRDJJ?'.->'=<?1=k-?JCYOIig+nZ;/SG\(1iS0b`"\cXs#.:pbl(g*4I]n] -Z3YAn`Bcq34:Hk@g,NGL%0.eRp]Vs95Cn>t%H,]+:`J&gC8uf7~> -endstream -endobj -152 0 obj -844 -endobj -150 0 obj -<< -/Type /Page -/Parent 144 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R -/F14 24 0 R ->> -/ProcSet 2 0 R ->> -/Contents 151 0 R ->> -endobj -180 0 obj -<< -/Length 181 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_3l5WBYj7Dj\tJE18F)5*__\A2YXNQ5PiE)[+l#7qNE#,jMk -C*5To#&uB%J=7T4QXIfu<&PUI)iTOCnGpLA*u9gTnS#ap<<Wq*,P%h$ibLIV%0k<: -]`NmU2T]DB8du2?0/`lh@&g>65RJJ>W0D(_F?s?-=m35;jeC63+VcI16^9tD0-a!F -77beF%?I7"L;RGA$B-t]$jM:bV1oCX1#U@8U=c,j/JO.4"!L6XW(I4*E)7r*iYQn[ ->]6kBGdM3BK14fWp]p~> -endstream -endobj -181 0 obj -284 -endobj -153 0 obj -<< -/Type /Page -/Parent 144 0 R -/CropBox [ 43 78 553 764 ] -/Resources << -/Font << -/F2 7 0 R ->> -/ProcSet 2 0 R ->> -/Contents 180 0 R ->> -endobj -7 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F2 -/BaseFont /Helvetica-Bold -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -8 0 obj -<< -/Type /FontDescriptor -/FontName /AvantGarde-Book -/Flags 32 -/FontBBox [ -113 -222 1148 955 ] -/MissingWidth 250 -/StemV 70.00 -/StemH 70.00 -/ItalicAngle 0.00 -/CapHeight 740 -/XHeight 547 -/Ascent 740 -/Descent -192 -/Leading 0 -/MaxWidth 0 -/AvgWidth 0 ->> -endobj -9 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F4 -/BaseFont /AvantGarde-Book -/FirstChar 32 -/LastChar 255 -/Widths [ 277 295 309 554 554 775 757 198 369 369 425 606 277 332 277 437 -554 554 554 554 554 554 554 554 554 554 277 277 606 606 606 591 -867 740 574 813 744 536 485 872 683 226 482 591 462 919 740 869 -592 871 607 498 426 655 702 960 609 592 480 351 605 351 606 500 -378 683 682 647 685 650 314 673 610 200 203 502 200 938 610 655 -682 682 301 388 339 608 554 831 480 536 425 351 672 351 606 0 -740 740 813 536 740 869 655 683 683 683 683 683 683 647 650 650 -650 650 200 200 200 200 610 655 655 655 655 655 608 608 608 608 -553 0 554 554 615 606 564 554 747 747 1000 375 369 0 992 868 -0 0 0 0 554 0 0 0 0 0 0 369 369 0 1157 653 -591 295 606 0 554 0 0 425 425 1000 0 740 740 869 1194 1137 -500 1000 502 484 351 351 0 0 536 592 166 554 251 251 487 485 -553 277 354 502 1174 740 536 740 536 536 226 226 226 226 869 869 -0 869 655 655 655 200 502 439 485 453 222 332 324 552 302 502 -] -/Encoding 6 0 R -/FontDescriptor 8 0 R ->> -endobj -10 0 obj -<< -/Type /FontDescriptor -/FontName /AvantGarde-Demi -/Flags 262176 -/FontBBox [ -123 -251 1222 1021 ] -/MissingWidth 250 -/StemV 133.00 -/StemH 133.00 -/ItalicAngle 0.00 -/CapHeight 740 -/XHeight 555 -/Ascent 740 -/Descent -185 -/Leading 0 -/MaxWidth 0 -/AvgWidth 0 ->> -endobj -11 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F6 -/BaseFont /AvantGarde-Demi -/FirstChar 32 -/LastChar 255 -/Widths [ 280 280 360 560 560 860 680 220 380 380 440 600 280 420 280 460 -560 560 560 560 560 560 560 560 560 560 280 280 600 600 600 560 -740 740 580 780 700 520 480 840 680 280 480 620 440 900 740 840 -560 840 580 520 420 640 700 900 680 620 500 320 640 320 600 500 -420 660 660 640 660 640 280 660 600 240 260 580 240 940 600 640 -660 660 320 440 300 600 560 800 560 580 460 340 600 340 600 0 -740 740 780 520 740 840 640 660 660 660 660 660 660 640 640 640 -640 640 240 240 240 240 600 640 640 640 640 640 600 600 600 600 -560 0 560 560 560 600 600 600 740 740 1000 420 500 0 900 840 -0 0 0 0 560 0 0 0 0 0 0 360 360 0 1080 660 -560 280 600 0 560 0 0 460 460 1000 0 740 740 840 1060 1080 -500 1000 480 480 280 280 0 0 580 620 160 560 240 240 520 520 -560 280 280 480 1280 740 520 740 520 520 280 280 280 280 840 840 -0 840 640 640 640 240 540 480 420 480 280 360 340 700 340 540 -] -/Encoding 6 0 R -/FontDescriptor 10 0 R ->> -endobj -12 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F8 -/BaseFont /Helvetica -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -13 0 obj -<< -/Type /FontDescriptor -/FontName /NewCenturySchlbk-Bold -/Flags 262178 -/FontBBox [ -165 -250 1000 988 ] -/MissingWidth 250 -/StemV 154.00 -/StemH 54.00 -/ItalicAngle 0.00 -/CapHeight 722 -/XHeight 475 -/Ascent 737 -/Descent -205 -/Leading 0 -/MaxWidth 0 -/AvgWidth 0 ->> -endobj -14 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F10 -/BaseFont /NewCenturySchlbk-Bold -/FirstChar 32 -/LastChar 255 -/Widths [ 287 296 333 574 574 833 852 241 389 389 500 606 278 333 278 278 -574 574 574 574 574 574 574 574 574 574 278 278 606 606 606 500 -747 759 778 778 833 759 722 833 870 444 648 815 722 981 833 833 -759 833 815 667 722 833 759 981 722 722 667 389 606 389 606 500 -333 611 648 556 667 574 389 611 685 370 352 667 352 963 685 611 -667 648 519 500 426 685 611 889 611 611 537 389 606 389 606 0 -759 759 778 759 833 833 833 611 611 611 611 611 611 556 574 574 -574 574 370 370 370 370 685 611 611 611 611 611 685 685 685 685 -500 0 574 574 500 606 747 611 747 747 1000 333 333 0 981 833 -0 0 0 0 574 0 0 0 0 0 0 367 367 0 870 611 -500 296 606 0 574 0 0 500 500 1000 0 759 759 833 1000 907 -500 1000 481 481 241 241 0 0 611 722 167 574 333 333 685 685 -500 278 241 481 1000 759 759 759 759 759 444 444 444 444 833 833 -0 833 833 833 833 370 333 333 333 333 333 333 333 333 333 333 -] -/Encoding 6 0 R -/FontDescriptor 13 0 R ->> -endobj -15 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F12 -/BaseFont /Times-Roman -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -23 0 obj -<< -/Type /FontDescriptor -/FontName /NewCenturySchlbk-Roman -/Flags 34 -/FontBBox [ -195 -250 1000 965 ] -/MissingWidth 250 -/StemV 92.00 -/StemH 45.00 -/ItalicAngle 0.00 -/CapHeight 722 -/XHeight 464 -/Ascent 737 -/Descent -205 -/Leading 0 -/MaxWidth 0 -/AvgWidth 0 ->> -endobj -24 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F14 -/BaseFont /NewCenturySchlbk-Roman -/FirstChar 32 -/LastChar 255 -/Widths [ 278 296 389 556 556 833 815 204 333 333 500 606 278 333 278 278 -556 556 556 556 556 556 556 556 556 556 278 278 606 606 606 444 -737 722 722 722 778 722 667 778 833 407 556 778 667 944 815 778 -667 778 722 630 667 815 722 981 704 704 611 333 606 333 606 500 -333 556 556 444 574 500 333 537 611 315 296 593 315 889 611 500 -574 556 444 463 389 611 537 778 537 537 481 333 606 333 606 0 -722 722 722 722 815 778 815 556 556 556 556 556 556 444 500 500 -500 500 315 315 315 315 611 500 500 500 500 500 611 611 611 611 -500 0 556 556 500 606 606 574 737 737 1000 333 333 0 1000 778 -0 0 0 0 556 0 0 0 0 0 0 334 300 0 796 500 -444 296 606 0 556 0 0 426 426 1000 0 722 722 778 1000 833 -556 1000 389 389 204 204 0 0 537 704 167 556 259 259 611 611 -500 278 204 389 1000 722 722 722 722 722 407 407 407 407 778 778 -0 778 815 815 815 315 333 333 333 333 333 333 333 333 333 333 -] -/Encoding 6 0 R -/FontDescriptor 23 0 R ->> -endobj -31 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F16 -/BaseFont /Courier -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -32 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F18 -/BaseFont /Courier -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -36 0 obj -<< -/Type /FontDescriptor -/FontName /NewCenturySchlbk-Italic -/Flags 98 -/FontBBox [ -166 -250 994 958 ] -/MissingWidth 250 -/StemV 80.00 -/StemH 45.00 -/ItalicAngle -16.00 -/CapHeight 722 -/XHeight 466 -/Ascent 737 -/Descent -205 -/Leading 0 -/MaxWidth 0 -/AvgWidth 0 ->> -endobj -37 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F20 -/BaseFont /NewCenturySchlbk-Italic -/FirstChar 32 -/LastChar 255 -/Widths [ 278 333 400 556 556 833 852 278 333 333 500 606 278 333 278 606 -556 556 556 556 556 556 556 556 556 556 278 278 606 606 606 444 -747 704 722 722 778 722 667 778 833 407 611 741 667 944 815 778 -667 778 741 667 685 815 704 926 704 685 667 333 606 333 606 500 -333 574 556 444 611 444 333 537 611 333 315 556 333 889 611 500 -574 556 444 444 352 611 519 778 500 500 463 333 606 333 606 0 -704 704 722 722 815 778 815 574 574 574 574 574 574 444 444 444 -444 444 333 333 333 333 611 500 500 500 500 500 611 611 611 611 -500 0 556 556 500 606 650 556 747 747 950 333 333 0 870 778 -0 0 0 0 556 0 0 0 0 0 0 422 372 0 722 500 -444 333 606 0 556 0 0 426 426 1000 0 704 704 778 981 778 -500 1000 389 389 204 204 0 0 500 685 167 556 333 333 611 611 -500 278 204 389 1000 704 722 704 722 722 407 407 407 407 778 778 -0 778 815 815 815 333 333 333 333 333 333 333 333 333 333 333 -] -/Encoding 6 0 R -/FontDescriptor 36 0 R ->> -endobj -38 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F22 -/BaseFont /Helvetica -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -2 0 obj -[ /PDF /Text ] -endobj -5 0 obj -<< -/Kids [4 0 R 19 0 R 22 0 R 27 0 R 30 0 R 35 0 R ] -/Count 6 -/Type /Pages -/Parent 182 0 R ->> -endobj -43 0 obj -<< -/Kids [42 0 R 47 0 R 55 0 R 58 0 R 61 0 R 64 0 R ] -/Count 6 -/Type /Pages -/Parent 182 0 R ->> -endobj -68 0 obj -<< -/Kids [67 0 R 71 0 R 74 0 R 77 0 R 80 0 R 83 0 R ] -/Count 6 -/Type /Pages -/Parent 182 0 R ->> -endobj -87 0 obj -<< -/Kids [86 0 R 90 0 R 93 0 R 96 0 R 99 0 R 102 0 R ] -/Count 6 -/Type /Pages -/Parent 182 0 R ->> -endobj -106 0 obj -<< -/Kids [105 0 R 109 0 R 112 0 R 115 0 R 118 0 R 121 0 R ] -/Count 6 -/Type /Pages -/Parent 182 0 R ->> -endobj -125 0 obj -<< -/Kids [124 0 R 128 0 R 131 0 R 134 0 R 137 0 R 140 0 R ] -/Count 6 -/Type /Pages -/Parent 182 0 R ->> -endobj -144 0 obj -<< -/Kids [143 0 R 147 0 R 150 0 R 153 0 R ] -/Count 4 -/Type /Pages -/Parent 183 0 R ->> -endobj -182 0 obj -<< -/Kids [5 0 R 43 0 R 68 0 R 87 0 R 106 0 R 125 0 R ] -/Count 36 -/Type /Pages -/Parent 184 0 R ->> -endobj -183 0 obj -<< -/Kids [144 0 R ] -/Count 4 -/Type /Pages -/Parent 184 0 R ->> -endobj -184 0 obj -<< -/Kids [182 0 R 183 0 R ] -/Count 40 -/Type /Pages -/MediaBox [ 0 0 595 841 ] ->> -endobj -48 0 obj -<< -/Type /Annot -/Subtype /Link -/Rect [ 409 588 468 599 ] -/Border [ 0 0 0 ] -/Dest [ 55 0 R /XYZ null 800 null ] ->> -endobj -49 0 obj -<< -/Type /Annot -/Subtype /Link -/Rect [ 184 576 222 588 ] -/Border [ 0 0 0 ] -/Dest [ 55 0 R /XYZ null 800 null ] ->> -endobj -50 0 obj -<< -/Type /Annot -/Subtype /Link -/Rect [ 366 293 463 304 ] -/Border [ 0 0 0 ] -/Dest [ 55 0 R /XYZ null 800 null ] ->> -endobj -155 0 obj -<< -/Type /Outlines -/Count 25 -/First 154 0 R -/Last 179 0 R ->> -endobj -154 0 obj -<< -/Parent 155 0 R -/Next 156 0 R -/Dest [ 30 0 R /XYZ null 843 null ] -/Title (1 PREFACE) ->> -endobj -156 0 obj -<< -/Prev 154 0 R -/Parent 155 0 R -/Next 177 0 R -/First 157 0 R -/Last 176 0 R -/Dest [ 67 0 R /XYZ null 843 null ] -/Title (2 FUNCTIONS) -/Count 20 ->> -endobj -157 0 obj -<< -/Parent 156 0 R -/Next 158 0 R -/Dest [ 71 0 R /XYZ null 843 null ] -/Title (ipPicGet) ->> -endobj -158 0 obj -<< -/Prev 157 0 R -/Parent 156 0 R -/Next 159 0 R -/Dest [ 74 0 R /XYZ null 843 null ] -/Title (ipPicGetSlice) ->> -endobj -159 0 obj -<< -/Prev 158 0 R -/Parent 156 0 R -/Next 160 0 R -/Dest [ 77 0 R /XYZ null 843 null ] -/Title (ipPicPut) ->> -endobj -160 0 obj -<< -/Prev 159 0 R -/Parent 156 0 R -/Next 161 0 R -/Dest [ 80 0 R /XYZ null 843 null ] -/Title (ipPicPutSlice) ->> -endobj -161 0 obj -<< -/Prev 160 0 R -/Parent 156 0 R -/Next 162 0 R -/Dest [ 83 0 R /XYZ null 843 null ] -/Title (ipPicGetHeader) ->> -endobj -162 0 obj -<< -/Prev 161 0 R -/Parent 156 0 R -/Next 163 0 R -/Dest [ 86 0 R /XYZ null 843 null ] -/Title (ipPicGetTags) ->> -endobj -163 0 obj -<< -/Prev 162 0 R -/Parent 156 0 R -/Next 164 0 R -/Dest [ 90 0 R /XYZ null 843 null ] -/Title (mitkIpPicVersionMajor mitkIpPicVersionMinor) ->> -endobj -164 0 obj -<< -/Prev 163 0 R -/Parent 156 0 R -/Next 165 0 R -/Dest [ 93 0 R /XYZ null 843 null ] -/Title (mitkIpPicDR) ->> -endobj -165 0 obj -<< -/Prev 164 0 R -/Parent 156 0 R -/Next 166 0 R -/Dest [ 96 0 R /XYZ null 843 null ] -/Title (ipPicNew) ->> -endobj -166 0 obj -<< -/Prev 165 0 R -/Parent 156 0 R -/Next 167 0 R -/Dest [ 99 0 R /XYZ null 843 null ] -/Title (ipPicClone) ->> -endobj -167 0 obj -<< -/Prev 166 0 R -/Parent 156 0 R -/Next 168 0 R -/Dest [ 102 0 R /XYZ null 843 null ] -/Title (ipPicCopyHeader) ->> -endobj -168 0 obj -<< -/Prev 167 0 R -/Parent 156 0 R -/Next 169 0 R -/Dest [ 105 0 R /XYZ null 843 null ] -/Title (ipPicClear) ->> -endobj -169 0 obj -<< -/Prev 168 0 R -/Parent 156 0 R -/Next 170 0 R -/Dest [ 109 0 R /XYZ null 843 null ] -/Title (ipPicFree) ->> -endobj -170 0 obj -<< -/Prev 169 0 R -/Parent 156 0 R -/Next 171 0 R -/Dest [ 112 0 R /XYZ null 843 null ] -/Title (ipPicAddTag\021\021\021\021\021\021\021\021\021\021\021 ipPicAddSubTag) ->> -endobj -171 0 obj -<< -/Prev 170 0 R -/Parent 156 0 R -/Next 172 0 R -/Dest [ 115 0 R /XYZ null 843 null ] -/Title (ipPicDelTag\021\021\021\021\021\021\021\021\021\021\021 ipPicDelSubTag) ->> -endobj -172 0 obj -<< -/Prev 171 0 R -/Parent 156 0 R -/Next 173 0 R -/Dest [ 118 0 R /XYZ null 843 null ] -/Title (ipPicQueryTag\021\021\021\021\021\021\021\021\021\021\021 ipPicQuerySubT\ -ag) ->> -endobj -173 0 obj -<< -/Prev 172 0 R -/Parent 156 0 R -/Next 174 0 R -/Dest [ 121 0 R /XYZ null 843 null ] -/Title (_ipPicInfo) ->> -endobj -174 0 obj -<< -/Prev 173 0 R -/Parent 156 0 R -/Next 175 0 R -/Dest [ 124 0 R /XYZ null 843 null ] -/Title (ipPicTagName) ->> -endobj -175 0 obj -<< -/Prev 174 0 R -/Parent 156 0 R -/Next 176 0 R -/Dest [ 128 0 R /XYZ null 843 null ] -/Title (ipPicFORALL_x) ->> -endobj -176 0 obj -<< -/Prev 175 0 R -/Parent 156 0 R -/Next null -/Dest [ 134 0 R /XYZ null 843 null ] -/Title (yy) ->> -endobj -177 0 obj -<< -/Prev 156 0 R -/Parent 155 0 R -/Next 178 0 R -/Dest [ 137 0 R /XYZ null 843 null ] -/Title (3 LIST OF FUNCTIONS) ->> -endobj -178 0 obj -<< -/Prev 177 0 R -/Parent 155 0 R -/Next 179 0 R -/Dest [ 143 0 R /XYZ null 843 null ] -/Title (4 INDEX) ->> -endobj -179 0 obj -<< -/Prev 178 0 R -/Parent 155 0 R -/Next null -/Dest [ 150 0 R /XYZ null 843 null ] -/Title (5 LIST OF FIGURES) ->> -endobj -1 0 obj -<< -/CreationDate (Tuesday, May 23, 2000 2:05 PM MET DST) -/Producer (Acrobat Distiller Command 1.0 for Solaris 1.1/2.3 (SPARC)) ->> -endobj -3 0 obj -<< -/Pages 184 0 R -/Outlines 155 0 R -/Type /Catalog ->> -endobj -xref -0 185 -0000000000 65535 f -0000082734 00000 n -0000077816 00000 n -0000082881 00000 n -0000002499 00000 n -0000077847 00000 n -0000002723 00000 n -0000070482 00000 n -0000070611 00000 n -0000070875 00000 n -0000071914 00000 n -0000072186 00000 n -0000073227 00000 n -0000073352 00000 n -0000073628 00000 n -0000074674 00000 n -0000000010 00000 n -0000002478 00000 n -0000002635 00000 n -0000007334 00000 n -0000003915 00000 n -0000007313 00000 n -0000008658 00000 n -0000074802 00000 n -0000075074 00000 n -0000007493 00000 n -0000008637 00000 n -0000009261 00000 n -0000008818 00000 n -0000009241 00000 n -0000011156 00000 n -0000076122 00000 n -0000076246 00000 n -0000009408 00000 n -0000011135 00000 n -0000014166 00000 n -0000076370 00000 n -0000076644 00000 n -0000077690 00000 n -0000011342 00000 n -0000014145 00000 n -0000014303 00000 n -0000017018 00000 n -0000077956 00000 n -0000014407 00000 n -0000016997 00000 n -0000017156 00000 n -0000020534 00000 n -0000078917 00000 n -0000079048 00000 n -0000079179 00000 n -0000017260 00000 n -0000020513 00000 n -0000020687 00000 n -0000020779 00000 n -0000023033 00000 n -0000020821 00000 n -0000023012 00000 n -0000026990 00000 n -0000023233 00000 n -0000026969 00000 n -0000030150 00000 n -0000027177 00000 n -0000030129 00000 n -0000032251 00000 n -0000030350 00000 n -0000032230 00000 n -0000033086 00000 n -0000078067 00000 n -0000032425 00000 n -0000033066 00000 n -0000034587 00000 n -0000033247 00000 n -0000034566 00000 n -0000036291 00000 n -0000034774 00000 n -0000036270 00000 n -0000037623 00000 n -0000036478 00000 n -0000037602 00000 n -0000039158 00000 n -0000037810 00000 n -0000039137 00000 n -0000040649 00000 n -0000039345 00000 n -0000040628 00000 n -0000042115 00000 n -0000078178 00000 n -0000040836 00000 n -0000042094 00000 n -0000043629 00000 n -0000042302 00000 n -0000043608 00000 n -0000045452 00000 n -0000043816 00000 n -0000045431 00000 n -0000046665 00000 n -0000045639 00000 n -0000046645 00000 n -0000047890 00000 n -0000046839 00000 n -0000047869 00000 n -0000049367 00000 n -0000048078 00000 n -0000049345 00000 n -0000050587 00000 n -0000078290 00000 n -0000049556 00000 n -0000050566 00000 n -0000051771 00000 n -0000050777 00000 n -0000051750 00000 n -0000053675 00000 n -0000051961 00000 n -0000053653 00000 n -0000055416 00000 n -0000053865 00000 n -0000055394 00000 n -0000057162 00000 n -0000055606 00000 n -0000057140 00000 n -0000059003 00000 n -0000057352 00000 n -0000058981 00000 n -0000060475 00000 n -0000078408 00000 n -0000059193 00000 n -0000060453 00000 n -0000062534 00000 n -0000060665 00000 n -0000062512 00000 n -0000063434 00000 n -0000062724 00000 n -0000063413 00000 n -0000064354 00000 n -0000063598 00000 n -0000064333 00000 n -0000065704 00000 n -0000064518 00000 n -0000065682 00000 n -0000066268 00000 n -0000065868 00000 n -0000066247 00000 n -0000068077 00000 n -0000078526 00000 n -0000066419 00000 n -0000068055 00000 n -0000068654 00000 n -0000068254 00000 n -0000068633 00000 n -0000069766 00000 n -0000068805 00000 n -0000069745 00000 n -0000070331 00000 n -0000079388 00000 n -0000079310 00000 n -0000079497 00000 n -0000079661 00000 n -0000079769 00000 n -0000079896 00000 n -0000080018 00000 n -0000080145 00000 n -0000080273 00000 n -0000080399 00000 n -0000080548 00000 n -0000080669 00000 n -0000080791 00000 n -0000080915 00000 n -0000081045 00000 n -0000081170 00000 n -0000081294 00000 n -0000081479 00000 n -0000081664 00000 n -0000081855 00000 n -0000081980 00000 n -0000082107 00000 n -0000082235 00000 n -0000082349 00000 n -0000082483 00000 n -0000082605 00000 n -0000069930 00000 n -0000070310 00000 n -0000078628 00000 n -0000078742 00000 n -0000078820 00000 n -trailer -<< -/Size 185 -/Root 3 0 R -/Info 1 0 R ->> -startxref -82950 -%%EOF diff --git a/Utilities/IpPic/doc/usingPic.pdf b/Utilities/IpPic/doc/usingPic.pdf deleted file mode 100644 index c3d96bdb32..0000000000 --- a/Utilities/IpPic/doc/usingPic.pdf +++ /dev/null @@ -1,3380 +0,0 @@ -%PDF-1.0 -11 0 obj -<< -/Length 12 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG5stip<!^np)$gOFE<3()/fKNUiW5Q? -C`k'\$Y@sFO;'PiN.o.u9I=j?Paas+@A(2^+J2N--GWIa<C<)"`rgWeY\H!+$V#(` -ZsoUn.Ro;N.+Af77ZbECOcbS@g`X%]#1Co+Ui?ta%Klr-'H!cYYoUYLYsArDFZLMd -AqMPV5YI"PNb2]jb[;hXS?YP9WOU5p4UOY';*gH%F?'[s\hQM#g*nY>#uRg,\mA@* -@0n:.!BUgh`YqRK;ilNhQ-5RiL.MC'?n;j$"f#MI`+9,u),2GQ;2^6CkRmTYWSjH' -@5hl,LRj1@'Lf7L7hYWVhK)]*d:\%<("RPm^G#@IV@$ud:mE>`EaTFZ:3*?RL+8j( -JLEgoC_oD]b-;4=8.][0#(a9M#UQ1#EhgP2F@-Xp!Q5J`757n^(d:6<pBs=h]JR/( -+imq1Ttu>\l:98)!$!.raC(@UOnpJ_L!c]!)S^<GV&@7o9TL8fiJ^DCY0otGQc"uD -"U@I-N6Dhe&1ci<6%R6c'Lf5=KfMHXKS9<>J5kD0JQ'K`)'uK?KSRD9,R$BXn#Z_W -_?na%5gFJ*'g;XsF;4S,$.U0a78)/A+YI2t6V,]]*.7'?CM\G;6e,I;(a>)rAJRU0 -e:QEZFYm3SL8bVD"3,Kc6R/P'Rd.RgWC;JoLDF9+>fl\nV-:^D[9FdZ21ciZfl_*r -]i]CTa#6jEl3BOPE+KV<W[UPH(8?]Mbbs:hKU4bdW[uT2.<eIJ!CQJ7jK-;@W\8_8 -[u@2aTrQZXY@4p`@gg%c86[5`2mT&Fh:M<a(I)U>>,(&e>+]]jPL]Jp7eFCs9g3Y! -@N%d9V@<GKTp6pPB67_>T'(*bG+h/]eJE>g#j>]Z7@H@g4QMp$fp]XZ$uQpI\`FoQ -._6D#"tcc[[t&+BNBs]4]+j1`bLpd0ZJsV.h4$1HIcF#2g&@bCk*pg<SDRGcJr]"- -c@`!-Eq4^shjb\X_a&T]`f@e)V^\E]4(eSpn6)#\6LaEP8QP5k[fs:d3pr-.mp/]k -Rrt/),MMd;rgU<(d3g/Qmp/-GXRitE,4"7EQU.*d&\_PbH*mU*eScETF6I;LhQ>Vb -($/XA00LtNA^gY^OLR^"PXPjHc>[P2D,Kl%e0f)RdFmhM88U+Z<US;Sd8D,TDtL+m -_Bf3'MA$4?2?ONbkf)GkbA/_e#X/L3l-T=VIgqPJ3[Tsb=c=8N9=_DS2UJ@h63h#F -9r09qd-[(9)dfTke#7G_KH-c)K90OR4sD2>@'c+`V1>k%U<`j5fk`/B]pk`PoNm*R -5Xe(o^&Xo8)+/p_%RJJ#RW).>"&q_q`4WJiQ'=iG1hT,X0S'p-:g/_f-jcRQ,fTPq -HjK!B-#W,0UW34c=E2i/an?n\.$dFM0H^RW+o0(iMF*6S6=X_t#T'fJ*2B<Q!C4#G -[THFVc,!kPiDNB)^hO>bBmqDW9aSp>rtU/8M[dLu0np7l#Qg5m1Ek1@'D/qDNNAd" -^n<.\,Xr3YGm]a(S@qBi3aSOkbp!AEStC9O'he(I0S*'?&2<Bm_^HW;J\2Nu:s9^V -R`Z%IUsfQ65TN4^iB7E"3#\.3%Lg-c%RGb+L="@]O(kpC`mqITU@rIj5^*Y\cnke( -TFsR.+?2Z?'VnQ%)9l'^"t#Qpcks])@S9IU"i,aHE["e"<2V*Tl7//dJoV<;$o9'N -*Dr,M%B%!-"i3mOLEPFk:>r/VVHi<g:f>R>5V<0?#V_$;Ki%jS7]@+N,+7JUH,FXd -2Db]@PG<%_![)CiB"E/Tdp.*V81c4q6=L*JeM8IO>;hamK:"G&=K<UC"9DU=SE!4R -K1KoD25n->E)?[Mo`M@[KYdjW_Ar_1)$XdtbClNdFj4T9,NtT+T'I)-X/UaYiP=uL -cr"<9ph'^19K\(l+<+!ro<2b_6<E[>?pf&nVTJ$9"aUq&"*o]h"uOh,P=[>.V7<;. -as35[6U9B`TpUD(1mm4C?6\b(%,n),RR$4cW8Jd]'M-^%i5cp+*QbNNJ28(2`A^/p -U,(kA23P"i6`>\O4Q2gMhC78J-OJcB<F?@@1XHub*HIfaios+(itdS["eDP(ncAp" -3!3`*1fN?%&[R<p0*1FB;;ctT~> -endstream -endobj -12 0 obj -2139 -endobj -4 0 obj -<< -/Type /Page -/Parent 5 0 R -/Resources << -/Font << -/F2 7 0 R -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R ->> -/ProcSet 2 0 R ->> -/Contents 11 0 R ->> -endobj -6 0 obj -<< -/Type /Encoding -/Differences [ 39 /quotesingle 96 /grave 128 /Adieresis/Aring/Ccedilla/Eacute -/Ntilde/Odieresis/Udieresis/aacute/agrave/acircumflex -/adieresis/atilde/aring/ccedilla/eacute/egrave -/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis -/ntilde/oacute/ograve/ocircumflex/odieresis/otilde -/uacute/ugrave/ucircumflex/udieresis/dagger/.notdef - 164 /section/bullet/paragraph/germandbls/registered/copyright -/trademark/acute/dieresis/.notdef/AE/Oslash - 177 /.notdef/.notdef/.notdef/yen 182 /.notdef/.notdef -/.notdef/.notdef/.notdef/ordfeminine/ordmasculine/.notdef -/ae/oslash/questiondown/exclamdown/logicalnot/.notdef -/florin/.notdef/.notdef/guillemotleft/guillemotright/ellipsis -/.notdef/Agrave/Atilde/Otilde/OE/oe -/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright - 216 /ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright -/fi/fl/daggerdbl/periodcentered/quotesinglbase/quotedblbase -/perthousand/Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave -/Iacute/Icircumflex/Idieresis/Igrave/Oacute/Ocircumflex - 241 /Ograve/Uacute/Ucircumflex/Ugrave 246 /circumflex/tilde -/macron/breve/dotaccent/ring/cedilla/hungarumlaut -/ogonek/caron - ] ->> -endobj -14 0 obj -<< -/Length 15 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f&"_E854=)Fn<-#l(c=15a&p_Osa3 -W<EhJ%T<WU]SnZY5`1\dN#I+)K+(6p!H>n>2]N3[6]$Z.?rSl0cJYB^E+ChW&IbQ> -$-;=I17O;U!bhq'/.`E;V^#o/g`RcpN-;H,8BQ!/QqV+MKnS]4TgFGZ6Vo1K/rbjD -!n`Iqa9jMV#U[H"<75D9*=d+Z_8tsl(l^rg;]qmI<$_UNP``c-'K-n-AFgdh&7@D\ -'e3[ETqKON1n0HDqdG0ABfFfA+p4O3e!i*3b\(,`Mh.?XSP2MJ.?;Di2i',1j$*D/ -C$(o1[PMp<O)l+UGNMNRG/&L3=bI"N2`#igX_VV*_6Bjo(`+pJ.Z,,fXjX/XNQ[^M -\utA?jLqat''SG6"";Uo%>,;F!Wc"'A>UKdUM?0rCl$BD/P[i$(9(_-o$]Gr;F2<G -kW<J^"qY<IW\";Yk3T/XgY0p_%S5_=N'g.goFE)ILC(*1+CZ4B_5M;la3dea.]m3E -Ls<K50L3(hUBod;6I?uO/d>a9.0IC@96TF-Y'<4q\o+J1(IX?=AHX5tqM6#E/^&;] -#bi6b8-i^mki4Z*FXK_?A'HP[NN5=E-;-m6>a.Z.H[$tG,/?IQ%"SD[.TP]<;\C=7 -Jd#,RK0,[>U=G(`3=IR8g,TUYg\;<cN4[FjZD&c,3fPA<"Z\'t-tJ(Y'NBf$#]:oW -@Q<dM#f7o#U)>&Y+uP1\$)7dWcisq!-U/"lAVjnIUKdHkh89T8R"Z]slL'WBB\58& -nu]bh>]ds0*&TQ1f.f$)Gbu\h+iW`R@mVkU(uuOd?7*A'9D_gBR8-gf=EZ8^Ib@N_ -RbrtnK&.rkK:q[Z"UaRFN\hnHe2If'OPN5[po>2u_5qu-.>jj@Y?0<O/U^FI2qDPM -hpu,5WsPOla"pZ$pt@a1!_ai97l[rOa9;XDgbb'1^%.(<%2QE\1n++5A7+:"X&alT -SNOZHT`CH6N(tUViXIEPgUH0m:l:U4+9~> -endstream -endobj -15 0 obj -1024 -endobj -13 0 obj -<< -/Type /Page -/Parent 5 0 R -/Resources << -/Font << -/F4 8 0 R ->> -/ProcSet 2 0 R ->> -/Contents 14 0 R ->> -endobj -17 0 obj -<< -/Length 18 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7:BP%&/B"=L`8`2M-\D$-_ga57eb775.QZ5n4c#ij!aPDEB_Fd6n(F -JDP]>ThB#u]'Xs19*GlaOtr`R7g'WjLB7_n;J7e96(lh\"PS\Y&.JjXR+YAi"tCJW -LN$(_dO?XaJQE]EenI'u_6X50V0Hcs)iWeZM1-9U>8.b]6BR9:AgfF&N$^>/Uq0MO -AF<Mb"kjSJbhY5\).f1N58RrkZlMFp`+h&pcA%OfPia)IR=kf46'OWO0UoJ76'.c) -@5_u3)kj/#HnhO*Y*A?"[ZE?brO<b\+M__25AX_(.LcJQXtu*58BC6XXGUa/"pndi -`$@W6n2Ll0#gtXmj$;JB1.f8jTrr@0)N-\;n=V%_@0"M1N_]Z=&4"&3l8afu+@+St -#YN%]V(jZ#/i5ku`\`XLE9K1j+ToV&%&7Lo1^kV!%-oumm!9G%8g?A6/n&Ku(l$B> -HBCFcP/\t:6Q"\j%YKl.km]FqYjG05P@ciZOkcuaNe;^r*(e%iF>HFn+C#nc&eqAa -N@t:Wmg]G]hV&H[YhV%R_l2BP:%#YQ/A\EP`#DQg7)Tm8P;&sm2m=#H2iQdY_D[CX -h)PnmD`oEY#[qh$\?9YSIc/.[UPbj$8Ag\@2$+%])8)"aaWsgPX)?^q05Z[C=V%?p -M?\neI/U;=J7hqK:aBd2;WF_1,gm14mPt_$T]m`@d==Mcf!W3R3F:)%5q5C1l;80; -om7IoNm[4+*$UM$qfT\*CV;ud".8:+N_u24*iBOl5DI%[JCe'N\&co-7:I7FSRH\9 -='!(YK\4;m,7T,=`ZkcR@6rHhgq1F:I?OH._5$qh]r`tb,$m3uQ&a-GR-6T.2AhEl -2ljRNV-Hg%-lIdNe!AIuE%A,:%!S!#&5CDY:@dBfLhbRMPpQ8b%?UR&f8fZ<!]UW6 -)!2i%:!CTs9E>;u1=aJ[:bF*RW)=Cd(8<Pu#]cTsI?$snF:\a6<@fn@;ldlSUjS]U -SF)icbK]XY+E>bM>p)BMFSUpnTT5O\@[?SUV_?9g*;=[(N'/$$dY<07;X3;[8C*uP -e$q\ZN5ITP\_n41EL&a.+PlI4*\n2XEkSZEc?[5kJiF5Q9s-S]!Y9mZQj@OX-lD3J -YibJE1>cdlm,>*+ILV-KcR9p/.0`a,^<tDKDFl;[ZrXoga@g"rD3V@/+D+]+]'+!e -&FVo^X;qe\D%5iX!J[r#:Q9s"4),&hL;;^Q"3>BjU^T#^VHCm,";j_K`PstE*op[\ -b"-HqgpupQF@/<2E@7Cj5u?Ku"/E\$NhK#bi/ARA@GV?-I7#aia:!P!<<^2R9u1>T -)hW0Z#U$W+L+psoSA6ob:6G92-]m]D47[R`dG5p)Ynhs3>`7!]0d>+N'*Cd7<l)j> -`sDAE,OBoA1(EKh=JI'LS$t]24VGi"qI`?o4-@qe84arI(YK+C#/IkkK1AZM64c^j -$NN,fFZ1]n?t>85c;-q:6QdO/U^fui3=pH;%E!-:@T"(E8;8*n&.i`2do&.q74&ru -\`,ok'Xa#6~> -endstream -endobj -18 0 obj -1596 -endobj -16 0 obj -<< -/Type /Page -/Parent 5 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R ->> -/ProcSet 2 0 R ->> -/Contents 17 0 R ->> -endobj -22 0 obj -<< -/Length 23 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@>l*-</ccD:h_`l -D\3hG6j%GMaBUKX'b.FrToOAA"W#&\"-B<j2AZf+##d70`aojN8q`j7(-)RDJtPT# -3.R9"2*o41,Ii8:&fV)_U&s"k$tKMN7TOMnaDVS*%H^To\AE0-]O$6q^emia*0H6a -&p[0R].06+L=7<=ibrP%!egiB8>N2!XUXU%D%O]1'#b="A"+NKG=!IBc.$T<jA:"T -RuW5oOj9_#"\A#?b18UXM]*&t!WfOb(,a]?72ln`j)r#fMag&GcEM%3-CIOSj%6c, -^T'iER(2d#$n[9p7Y=j+;W0suRnUHQB[Cc=\PDpu1^p&XaJK+i.W,q/,H06U"9TLf -0TJbEkVA/a!9cP*&1Hg(N2%L\nq7)NfJZ"4GfDeZ:"+Kh4XhLap*C"1i3C"7Wo+R" -@sI9!%5>[^cok7#1?C@=R_&AW6F]p^/7Cg#3=LP18iK.*@*1Msj-6YY8$VuE%)[&J -5Vk;pKLi$g+`hH^$mTHE/P<pJd2rg[&B(M:&[Gda"tW`@r'QST9.u<6E]c/f1:5Ea -6uoY!6VS-5i&M8,4=W7KY:.[-9of/13DP-Hd,9`-Rtqj%!Mku"^/(Id*Pd;;E8?I_ -%#7eFDC&L5+Oh6).??(-_E:*0fZ,*E%GQ1?$\:Qr-OA0`VDaHDi):8_ek"t8NAK?X -4,kJXck'6QZkA(IC0bgb:To0G5h9c$b6#OWUb*!Ier(\`gJp$o<&ef0'ikLd8nD*p -2lKP-%J.`2Vo(kMn2aWk/U`<&ad%JTK`\!-)?ms`2Z68"r#pl*5tb<"6("H$FeV/k -01^a1S4#CIi<8L+Ke')uZI3^8auBm8JB9N.d2R3:"gpMTK[:DK5moKBQ:Tb9;es,L -N.Xeu9TH=49g5@e/<,;6pfld5ac+m:'+H0*I=^E\2VTP=)%^GDAA_/>&aj.@lO?\% -G/IS%o!QuYi@nem0T8oV6-$P*@+hiG@:2A]WP^:U4Pu\#`\M9p"E-Q^Q4V8$NPcd, -2d;A://\Tn4BUC!P-Eb%m+"93KlpUJARR0a86Qrm/@3&9p6;N00^2V<RG%2*!6#;( -@pBY]?*`8#/8i1spC0H.JFE-1)V!Qs_)WjWUIFSTpXSQ<WeB/d@pn/L(E2C4NmVnj -=12&!o.OCl+:nbMRW]9!B/gD2NkA>1n_!nh&$IB#-l:qO*eMrQ:JL,VpTAZ\bQfT] -eK:cG@#0FA'b$eS3eieKLld^:DQ"7.L1O-Yf:,es:c[l-d*)b;>BO35aTB%u)B4<: -H&:`!2PKhFJPcJPG"@=<)@.alhD.,Q61PKfQ!BP?$^Z;gjJ@VXhMMCJ'PG7H3%q0J -W"RN1GHi&3.)[DGg%'>QaltuRAiU\HUTI%+A2;-.aVS/lLMbCE0bbb?%*;Hg8L[+? -WY?5Ie!^)TbFpA>OS"u=1jEuU^cA@F'_u7Mk'E)^!i^G`LfF"2P#,<46mgt4<l>G\ -aBi8TQY;uLOr\qu4:hX_Nr`fgBpFjm=%d"oJ^`+H=%j(&bLRYo<8_2+dm/gbUb7IU -/9uGrej1[M[2(!_G#6#4D'9JJ3+R\LP%r!/Jq1<#RaJ2@i1M^EGqu!rgE0hbp_XWA -E_mn]jDg6P=Wn*F3bAK,M%Bt+6DqK3dqCQB^qbh(W"t%^*:K:CMK>Y;0H3PD]06?M -O]"bqr_d4AU($RNP!VjYLkm_h5iEU/@qOR!1;0UqnU!5CK##3:X9Kg&)&ah>"qH`A -TE*IY!eC/6JW.0bPUI<oaY9BdK@"UVR4D-;Bc\\FOBd^4NkNKZ0r\.6V2A0;T#u=V -)c=PC[,AGmUGYos,tVrc3Ok]MT,3Mb'9NsuLIhjY,)k'<VY4C38HP#bM30\EjW4:$ -LsjmX,m-LH^1bbMa'.S^"G*Rp3Qff^*u?KD;:Y@WUXTe=?cAC^ENM0t)+-*U[,FXh -M@r3!WBQkM2QDM3dY"37%q+KcKBNaGL>^qDh44O1dB`'?fj@/5C[%tcTbFd<h!Pt' -9qr<b.jqh(dqRnLQZiX@9`ttQauSO+F64T:91fc5TQ1Kl]KA<O.Y<]YBg`N[r^DA' -+2\Fd_&+[,?@(9#-(&sJ^k+%k1a)#0&7iJpHoo,3$!<k&r3WYPP*EDNRuZTh/esTe -!s0AU."kJ-N`'tqUd^$c6qMFOLcW*;/T"D!ha!!0O.$&X;CW@(WKnJB9u<&g1"?ZP -\Gm],Lgh>IdFW*@rIL2`EXXEE>9hW_4%$SjHg2nXLc1JP1`EsR=l=2.`Dhj5E,\uR -=^!ZE#e@6-l\RGq&MQK&m[')I@0-ui!EpF1!WWoCJWYE/jik&u,'TtC&U"?sUqr1q -25^g_Sh=3Q7[O&sXS'#dTNY](BsQ-f99,^oa"p?QD'Q:Xf#,rT^L-2qEMV$;`\cC? -R0.<$Y;FP=d/*oXg(7nr9A[_:Rt#!bdK0~> -endstream -endobj -23 0 obj -2477 -endobj -19 0 obj -<< -/Type /Page -/Parent 5 0 R -/Resources << -/Font 24 0 R -/ProcSet 2 0 R ->> -/Contents 22 0 R ->> -endobj -24 0 obj -<< -/F2 7 0 R -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -endobj -26 0 obj -<< -/Length 27 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p!dUPTYSsTn;7%JF4NtMh_CC!Am&G0#<L.=Fbp:3?!g1@KF9k -@i?>C%Rs8lQkVCq%0aWtW7YK3(CfB$cqrSA4:k;e'HmL]'N:/^kRgq0AiC_A9u^&! -5i,^2U![NggANdt:`,4.O]iHrQnoVrKqfN-b%PB%!f09:+].8GJd]ZIa:V<e3Kh4` -"$rHi@1=07a"m_s;MbT-)"4AA:nWP]2]W=<':>SoC'A"#!XpX4@fh9K[IRa^g35%c -%L'a@DHf/9i+]S9/1+G(%G9u%'(Md9C,M?:[<poiGgKkYBT>EAD!*-#'F]>X=[Zq" -8^R1N,C_G\aE95.%6>![n74HspdHLWTdiV$L!?Q4)mZF^WZetAaNEn^Y%i+o##?(P -nqR62THo>%!7Eca,<3gW%)GP\'Fj)e3''7(Lg]\*!Lrf^[3@;<ei:HC1)u%1(dPWc -_6eUl$BR(f!5!fl@,2#q5`X7.@gL`!6\CKOd_HJd>q=)2bdB%GP3fk8bS(E(/OE&4 -.i1F2o&Q.Q;?VXj-ZUbuPm%5VkW(g/T^%qu"*i$$%YI/6$c=[R3tI:t/5G`\P8tZ6 -dLt?Xo1]gK?K\I'gt<dbTMqmN:(In>T`tN_O>;b>,Sop)XgG3$eeO0U=jh8fBc##n -e,rH:2"ZQ"8>3.X+H1pqdeP^4F>PpR0egLU%G"ec5m.l:;cTu<PoEl\P3luu<qAua -9ug9$5+SNN%8&#X,J_JMN0\_+,,Os\]6iEMNPBGP'4#g&c1aYF;:n0"Ub[r:R-)eV -Q@%e.cdnWl$q!kP4V1IkIAA%!G1Gu-bST)S"\4fo<ut)CmEZSJF.ACA%RYKd3=I-G -g,+f,4fb(_P+pB`j7rn5U"eP/7n\TDc;@nU.*Y1Y"TgCC2a03GkDTmQXUYmK+aBRi -$mT`4&4;(hdPq`3AfUY"@E*g3BQSEUOlX)K:NB1[o\kABdQgVON+3^I3KAC)F[3k: -2D9=6Y8D=^DB"W_86b&]7t5)/1l%i;]Cr$\E>m,BB#OIkl5<>8%k#oU2Y_?U\<3Nq -P"+uc#lo$%'G0Um:TPQ*AWJ$6$G?I2Bi9u-87PQeDii;QiY29L1CVf<f(3=$"r$)b -\X$s!E8(BGhQD_A:cDh>;Lp+h5$1[u]7Ilfn2:/tA_AEdXE>RSfEHZOPEVSQD,ek5 -Yj?th64G\fWRa>d>$T2>jp!5&EAWE7hAK3C5Ud:s.StrZ_\dE1lTm_4pCR%dM_et< -J1^nT/@!)XD[rJf&-l8Dc<DE"KH\%0KtpTe%qH)U:dHlY(b!.!e%'ttD$[u);$Y"/ -+bXYq'!Wi]pRthDL9TL)+inj<@JS^`/\VH9KteJZU_[k6rOe\!\H#R';JM;TR>,,% -),H+^Dpak75kAb'6&S3aUf"`lQC/B9$L2@LUcAZ>B`[:2<!AqG<A;eK*SVQVNpmT= -*\tJAUZu3Fnd6X!\,@846qqCs:-9F!a!;WU"d3[C4%G)tPDoZ*%'i,\[K,e8=n.PW -E&oe-LG'gI4;r>t-n5FX)(X'=Z!&nV3X:c)i`d'%1hru9QYC4_%iiHN%S^ko,K.*^ -`.sTemR77lAEX+\+I3X3Z87.l)FMk_%"PR5UrI'e-cGkNdVWY=1?1(?biOZDq:M.e -84lFR\=H,mhCXAmK@h-[4M`a^Ut#$_NR?YmVplWWL_bXi,.XFH-/G5i)+DjO5s/Q% -aI[!OnrI097$+?*JcJ),,]e]4NhGO&1\,tOZ882mA/g_q)ZM4Q6%b0ho/4>>4Q%_% -Cb9?3;`E:gAIP9&T\ZBa81to)bu.8oW/:Y,RM]2G=/V.a'HtJ8(YQTI"i63@.`W]7 -<paCansVJGpmG>8dHD!IYWAe[5panU/[$iN(C#co(nFB/YRM3h*b2$Si5;"c9;W3M -f]=J'23\Mlco],NAITfhiJYpu3SA@\gSdPMZ`$pNcA@ZlD&[k)<gj'+9.&j(phd3W -db)HqB+HQ+k$GK2c)+-WMc?\TDRH&^*Eo9hPF<5PPS,HGV4utK)EaO6<M;#6B"nlG -75';s~> -endstream -endobj -27 0 obj -2053 -endobj -25 0 obj -<< -/Type /Page -/Parent 5 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R ->> -/ProcSet 2 0 R ->> -/Contents 26 0 R ->> -endobj -29 0 obj -<< -/Length 30 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@>l*-</ccD:h_`l -D\3hG6j%GQ6u4W>)e5^3*:3)#'G/OOj.VcpEtjlK5b]fM$qCIdNA,>Q.]@*7Ml'!a -!6uiJ&/.G8ZKrFL$6"l(_^U](*\JDUVaGHS]%JmKgdD@^;,/tgOcBPWGtbB?.[f*^ -dikCH[3qLP%4>mb/k.\6a/(SKAe&c7)3"g;%)CY31:p:I7Bo,_ln0-47CO57e5/jn -RSCX$J]Q\\3>bJb!oTa+\Mk>a`a`Dd``s5EV,7hlTO$19G'dN/kBFVsn8+dq+\%,_ ->q-J^U=k(LCc@DXopY85b@S&_$4/'>)6iB]%&![F1l[S)MWMXK)!DbF%YJ:1L<*l+ -n3W5</IT2Z&f)HLTrZK2]l.]CppFsS?5^K9X(i=S_lNPn%4W8G1:`#g'\!P/+Aakm -_^g<s%3s6B1'@[bfJANIOO?0!")JtN#)fO_$qcQP2"Ciio?d.QcXUAW4p%M@'/]fd -;\d9VHt(pJ&[:IPNNpEE*Y$NhN?H;N?pHWZ6VR;!8;"9s3R)ShAB.;_X0F1mNBBDt -9>RQA)54A*@k^<3RMbpV!Q3"6%<80L1;$6P'1Gn99iY1jJO!p*957oqJ:I~> -endstream -endobj -30 0 obj -654 -endobj -28 0 obj -<< -/Type /Page -/Parent 5 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R ->> -/ProcSet 2 0 R ->> -/Contents 29 0 R ->> -endobj -33 0 obj -<< -/Length 34 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7:BP%&/B"=L`8`2M-\D$-_ga57eb775.QZ5n4c#ij!aPDEB_Fd6n(F -JDP]>ThB#u]'Xs19*GlaOtr`R7g'WjLB7_n;J7e96(lh\!7YLb)N=k%6,_nD<1q'b -L-&i!'IXfU8qs!8c8U'-`l<&@n:5C4N".0/J5E\10W/CMq&GbOiu>SS-Lgdgb[rdR -`5_W?"Lpan`FB&SPB"t1D_`>,B1#8'h3,ocE*F/R4"rCe%!.YaXR^eOi!Y8AOgfr_ --n6,E-SYX`hIAU99Y=4'Q_4[)7Ri#*[f/Z/%g.@70T@;ufJF'+\o8N?%GMTsU;NYN -15#^ZOs,J\0]"f!UBp&p4^e?U3K0^Xl8(Wi_PILBXE_8%#/_;+q2U)8o)#0n@`K6@ -mj$&sKu!bQ%ud8si%tieS(9?TDn&uA-c*$+P_H)M@N.G5nd=mk6%\5K4ReR`0tG2k -N9*'[E'Q@@_$%k)$nbXaqT0u'5WTAE'M&cD,BQWo25,p8)@"C]*\'DF9Kk;NUHBqa -39)!H,n7aS1-1E?>FP^_%XVD0cu^d^.YZ<`ZU@6U7)TX7"*i*O$mTH?!n,F9.QWMF -E'PS#cajQ`9,0KUdl^SB;_Trp9cc?U6\+&Wc',chp*M\:j[HkH^d'V@K*XaLNIum? -%DK)?$EhNn3^gqLj0a7N0SlN-@KmT(Ie/MnORb+d'<pp.>OkJV4Nt\PY):1J,)6)& -<D5;.erju_gkJTS.8j-k"btK\'g']&NA-Wo&CHce.1JY+oR\HMdobE58JCcn$;oK) -?oA-$0]b,oOJS^9`"[#:IuPZid1B"%n3N"+(t?$@d+1HZ1IH.64-@4E6p#3JZ=([4 -%6!9A5/boM<]A5iQ33Nb@sd<U^n[[XU1i"phE$XK-C(H1;/!BP>EdFV1N+/N;-#[L -I:HF.Zf5GFN?Lo9'OAP2C(rjSkdi5M8KEAZb?Oan1Cfbs!YgB+aDo@'S:FKU,iP(< -'_?_<o"SVBUJlPO[d`G_@.6fmS-G[n6&+3G<r^>5pW2_>p71-3GU0K[;;GRFH7`g\ -H.I8]qiI<u$f$#%(RF:&#iX3l;K-*(#,.L+^1lG!rhugH=PIK9E\oZp'C$ZYMIeWD -`t$<\+Dc2&!KsLV\E3g2B1OWpR"c0nXV7(C$m;>b]#?/k>jB'rc@Jq5EfeeD@mWn, -W%`tAfR)!:XZfPJI6LX*b@#!p$\5(o+[bU3;Wo_qN&:SX,RDT@1V\G'frMiRf"P7K -7#5d//K/`,Z-PF-,6YCt1=RS*@WUm(%<<5meoH?S8YHA>V%s,_mMh@[BSZs_)OEG; -KO5>qCJ_u-1\Pjk"(I<#+lY>@2EHJRe!ObQXX=3+LgSU%98%0Tq_^5"9NrGkN<qno -a+Qbs&G"[ONStO1']Pp@RNr<%C$@r,>d.S7ifV?1o=?p#(XHSK?SJl_a1)K#eESK- -JDhNf=0hD599sW*Qo'PB5kN:)3I8lO=\0H-0@l'u:^0ad"%.&bb]m`,.+,s_j^>0_ -=DWD9[>>OCBe8>.V1ac0@tK6e$s]!_?-^rQ`$6oM;WGf48MR"ud,rs7$W]Nl\KjT: -e4'oEiXCqHarR<N%TG2GHS3OnPXXU&-k'34iKb:8"6=kOi-.BJjRLGo:^RlYX`6Y6 -p-A:OMp/DG9[+`;'bG9$b&gU9Wg(8\7\kjoZJ%RB..Iq\_")0tPbZ%QGu+V_;4#0* -<GK7*!2LA>fOYt9603;ffS!-7j[=dbSed)b#g_JJ.Vt:L&gg(Y[Y]u'#2tg._fgXR -P&mX0eI$URLAqWVEgA`/F?CVSG<o$2Q7"C%!MEJp*(-bM6Bk4F#+5QCk'0<HA-;~> -endstream -endobj -34 0 obj -1913 -endobj -31 0 obj -<< -/Type /Page -/Parent 32 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R ->> -/ProcSet 2 0 R ->> -/Contents 33 0 R ->> -endobj -36 0 obj -<< -/Length 37 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5fT'_Ojg,RktJ7R/f9P%!o_C/D`+$0B4\>6,i!L;N?Me/6+k9]0qAb#o5LM:<$_U% -Z,eX@RNOH:#uq(,**k?^L^%iBY^i/b/XKkb5Z#sARi+o>nF:JSB0.'doeQJX\3Oj6 -']W'4*F;NQW(UN&&THH:<h&8b<"YCF'c_aS~> -endstream -endobj -37 0 obj -301 -endobj -35 0 obj -<< -/Type /Page -/Parent 32 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R ->> -/ProcSet 2 0 R ->> -/Contents 36 0 R ->> -endobj -39 0 obj -<< -/Length 40 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7:BP%&/B"=L`8`2M-\D$-_ga57eb775.QZ5n4c#ij!aPDEB_Fd6n(F -JDP]>ThB#u]'Xs19*GlaOtr`R7g'WjLB7_n;J7e96(lh\!7YLb)N=k%6,_nD<1q'b -L-&i!'IXiV8qs!8c8U'-`l:B'oE]=jN".0/J5E\10W/CMj"-Koiu>SS-Lgdgb\(&u -NPl_5%Z_5FeHuWdOr/_tD(qC%U'!-_jiBJu6!#$A`Y2+k$u*TsAXI6qT5M$)EId%H -<6#=QL4`(A5[uVf:'X-8b$\d8Qq`=]ER<(o\8EgWjLK/DShQ1U!9Q*u_k>XE\j;-m -T*B$t'Tk+G86c]3d"kpD#(at%i'S(Qb4E;!E'Q=lc</.CNe7Vcr]rn%QB/pm#gE,T -:68Ws.#Hkuh$'ck@N.jX,>-F>0.VSFNam=fjgda"lMWp75iaf;YP](q%R[273Y&-F -5W=Y<"8r3ZN\cdY36u\Q3K.I0dP20*+@%W?e't-AKEHbc2heDt%3gMS4H_0]&pP*B -K`a<q0TDi@dPh:>@,*e+_[OaFN?Lo9'FqrM@N'q&.,5UB,3YsO3bsoBi%FEGZJA*N -^iI7EarkB61mETd(kj,Kba\k\5`\o;j(,Jl99j@$=Lto8Y1bLggUa17J[<5O0f2F/ -cr&+g]g3,"Ppo?8_`EuF%-+Dp&3-kOh)n\5Hl+m$0Jq<539,PA1<O^o&2]C=`6j'n -ZnOd6;,7lu(^@gO;Y7aWA";aM@\]`_L;B>XLXD'*hY5/[KP'>lPL.uUNH71W_M3WA -.1<E@]eD5PUNFP0%F9"]p-'29>Ck&G,Mc?.@shT<8'^0ZNC]3hObk3bphm@M%"0`> -@k]^4"\MNq/hr?<XBlGGN<!gHe$J>'4482Sb4e(RN$hoDfd.T?e<DXl_Ii@;:T^@] -"-tuYo>?Q\^9=@)p$CB*dhg'Q#6rO$3/4U_-)#qgnNAsL/\!"9+ON?rd^8U.oo</, -2nq#uo.S(hf"X(q"!H$Zb\hMFajr)pB"K=9obYBV+aE94N^8/-g4fDg08B7^ViJBf -Mk4q+gmeNA\IN,J`I8:AX]5N%UDJ@:ELX2qNm#gXk60]sD#!5hOtXDag9\sWXa/)J -UR(/6HZsW]GSl'dS>$Wa!X/UDRtFY8>[B/98C0Bc,bRsP6\%uB+cI3ALb9:*X2lXo -NKSmK*eL"?mlq?%iL8\a#$/%d#,Y];63p!d+Zq2#KOPuX<1&lA&aMT_4g[IaR*+)L -##a`.rNO(&Q%L!/J#u8b5Qqe`i\DS[b`0RH0]o:(]D"uJNAA;B\>hi6B8#d5j;:^4 -iF4S(LX:u(2g"?k+,iL4?mqATpr+*]9,^">nH#Nne<lFC0aiN.n[/Y2=/3E7@P/O= -]>K`$6[M.B:;d\J;"28_P#cd!@/(fhGZ>Z>M1^q:#doI9"_3tT>0q+61Pe47!hafK -%Gh`=,HOJ\'S]k0p$jp6gC0YZEe^b5>s*hR`F\D+E"VFkb[mkJAl(:OLhP]f_qapZ -E+Xt:2CUI"XGc7@=u(pKPG/=)!*[65;.l[`#*A&q'09iOO$2,"6kFqs'Z:+T">R:1 -jR8FMC1Qc%-A3M)]bdG=;X:hAUD3R&K-54[loF0'PWl;^8o%dop4ItDksA0d$Ou(E -2CGCC5nh_+":dFbUA9P9?WkTL@C@[.)BKpKo8>j*P'g!!d^g5kD,[F%0S\ih6s*'_ -MfQseK'@%UTVFB21(IVVfNSU_1HgDQRI%eI##6[)'5";2(X2W'%,M_/3n%Arc3g)n -K7r*,"c9uOPX+5@,YFTr't)>aOZO/6;i8bl`_uVe*866H8IL]EfC2VRe+s6M;uMBA -g*WWL$Y!ft.J^N;;&J#h?Ao:ec7W0HgqseJ%596)_DbOo@_+I3nr^-##\dVAg(R!\ -NUO#OSFdkdZp.>X44k`j@:JT^Ho<;Iaqsk9_3'6P`K&6aRC4&%KDJMiinZl"P63,$ -&@Q17Yeb)/*=KPcXsQ;uL+0V?K+6B4;&#-ZlP4ak6rC6G\XkVC8NWp!nP?827_km- -)U;J?$mC]J,N:Y-E%#p*a3c]8Ass\[^(n&`D?eYF^C+t^aKTmR_Ld^C=t<VR^f+SY -^IX]@>H>6=&u@57/0*"g12=2tcIHC([1/%a)HOd>OfORKY03QSE,,HHX<M\i<]Z'@ -'Qu@U':-Mkiu,_>.-N6/@.p8A,;3hGQB[$/OA?Wt"T\d#B".3r@<qqXXbd03:hC2. -^c)E1YW8<)':K"h0f`[Y:FXNC6?/jmJ4`0GXC,Z75sbOgB@fe0;V")u~> -endstream -endobj -40 0 obj -2367 -endobj -38 0 obj -<< -/Type /Page -/Parent 32 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 39 0 R ->> -endobj -42 0 obj -<< -/Length 43 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5g#?cOjg,RktJ7R/f9P%!o_C/D`+$0B4\>65a"JG)GR(@9fQB4'H-A7!C;r8AiH6` -B0f+2W(I4*@ut._2Y0`k<"2ZDFNj.q)8q9H!bd+m?%X!q6W'/&AMY:C`PZtklu-[k -bP#.+!O*8:NCP7:Gs.Ie/V.cX_eGZFDkik"7[<IBN_@?gN4AFreAuGY(i0D?BUrrS -F=muVK2G1HE&3<0`<Hu!OOA5-S'AqdA`VXb0gc?<r@tC"3YnG5ZkOISbu<!^4ca[B -fnBNYdQ@rAkfEiYN,p-#XD("iP,[Dt8fYJ%X;Dl].p-QM/o'Zh^V-Xfd]/!&5g&pP -&1g#.6n(d:'"b)o,ceaIas=MG,,!<#6Gp^>d"VSB@g4'mUK"XU%;He2-k%Xa%Klk@ -/.`5B.-<7E6V,-NN0!Hn3_A95T,oF2>+3gWP.I>=-m<UnU(2_SgDu9kSEE3l1apBB -%YG&97).(Mp(k6$6b_3-BP\6p_/O,rS'%n`^nAJQFNQ<Ij/i\M0[SW"(64$gi56#a -2&@Z-m\EP0LG'YHeP&>t=^AM3.,6W(JH^*MKG'3B,tc:]L7lF?OQJSY,7)RMf_'qR -oep6<3Y56KNC,s(JUhSA<8g*t3fUIjj_%Xj[1>[?1n_]E:,RPe3K596EEu(E(st/n -<`TM):dPUu3mI)f?ZOur]X';NoU+H+N:kuO1lcbu(78Sj:"IhuZJnl/9K2h>1l]hs -\P@ms*!LfLA#.jjKEJa21uU_(+.CVWV'eoKDq.oiibUC:]P3T^s+&5ZU(*At2e"nB -/q^J+)R-!&*]F8MoFD)dEbq@(bfhcY<`Qs9au#(;7136,25P.I:f;?C2N@FeN&Qa/ -,unU/")Q,<#?o[)Pp)CY^QrH^($!,.X@jA$EKd?`1?e=iY@LC\8EDgk6[a?^#%=HF -X339T^@R$ero:U#,H0$)L7t>Z'PpV8(#a=aSZe?l&N*:MNL!E*A'Ohrld>AErPk=/ -1\SA(95F<AWV5:?8Mgjd\7QZhdtGn5Al_pqUhR5:CKp9bAIj:<;ksQPK*t+sjr$ah -\'>p1,)'Qf8aiZ+2XV+hO^V%rDCl%S]i"+3,!_j/]OX9N&M`$n.%nkY^h+'B\Xc2" -i2i,aC((]a1^*m_1)MeG$4jGA5DiFSUnDN2*:rhu9F3eXP*6-6"<^6HSKa1-E)j`A -2`p2ekcWO%k0p>mA1sl#+csd>RQ?R]VpZQgfQP^&$E4.7]J^k/3m]"M!\[2k1;B1% -)$<Ku:JGYm[b$n5?R##q8+nb^(t>=uW,,3W!P9lBiXF)T[4!3V0S[s4oOD*G2kdlC -L9Oi%6\;[_EabXu7MZu]6EQAJA.UnK.-m)F#a+93#-PiBCWa6Y5/GN;L(Np]&?oXS -J^fT4&DS5TK(f\RpmV@>BQ#/X.$B`s9Lj+-7?4)!#*WpN[H1.h"3]'q/6j(*7b!#U -_L@Y:XL,rg_R;hCP73ViVA^.J\`Sa@PcY^#8u1IcAW#OQ!7@%Of"178MkaEPY$\&f -b]Osl1-P(XG+6J1(h?6mBN-R79GrT+e5TZ]o+<r:&D2J2Rbe4QE\BW[cD0VcUaYKI -0p1TLGL8-$SSsgZ.?J.Ff6ZVGWt6U/V3i/%BN&Q[emVHA=r!'n.0eq^g-FY8$tu1J -%>!$H"i*qL!anq6_/L*kJ3`R!TQ68&AO-H5*(5@Bcr<jCH`!1KoP($!N@aV1[08;o -@IPtL<#P0=pMd2T`F,c:%)N)"cl"?3[ge3EKc4?KA]!dS5gXna+uhuId7OhM0-V-t -86QG\Hnd7RoY4.$ZJQTuejq0#&Ob-/#Ru'QMM6&q/L9tR*L0W$&cJ'1>@*^<g=n>8 -\^A%@U`*[snP5'015=n<6Hs&'Y&lN0Q_WtH++mDn%>d57R%HF4FiFnhrFI>m6Sdj6 -g,*p];4\R\Qt#+'IkUd!WCQo3Y#,s0/b(Y>VJ^2"n_Zcn$>?oQb,s:tc@4/P^TWKE -Y>`k.7I+5g\/$W&d6^sK/&ll8TN[#p>NEMTE#[\TK)e7WC4E57!ZuIRU7Z<X%UmU< -9DC#b$=^bC[E1[.-@Gl4'E_L_f(Z`.%-SGSig)S3\<B$UmE;:oK.W6J.&l5uj^Mpu -BsfnOQdK*fP6r_7*IHOmX(ILi`3Z\%'&!U`8W.sG4P#o<SMUoe$+)Gp=?ML&2N\o` -CJul4m(o&&g6.MZL8";@[T>g3S:VcdM)ij-P1sgeaYU7pB::>7:m6R\K<5R@b"@E> -5]9a&,E@;)]JCtu\'pY#C:N*lAi/<?K+u'//G?IU3:p,oih2t<(qNT9%*ki31_'OP -U'*m6Rfc5O0d*81(e'KLfN[O2Z]26qF]AHE&W!7N\Vl(fF0"4dm:<IE[+d?@M+A68 -49WrQkG+doc@TJ"D>o<,8sj*BaYtDS#u?1'ioTM\-kC(iK`ct8_g$L%H(3?/LLAsW -;huRW>`Y!KVYCYeI1i9D.$CbT8]ZI-.U"r_RZrKf)t[IC^mpK$!qW?]bo,/"#)%e6 -&3tK^\2WX#H*@@+#('gDc67_2]s+=\!>l"O]rt([X*.-m_9@usTV4lQSMYKUm`B]+ -a\`jC-;iM>@pA%?(9[8GKf76+%!nG`+G3ltq]2V[h5L"12#pnaWr*:o[_2>9A_`F3 -/YZ0]%JQ0E'mnpt>u&SJSNd>>bjU8QTV;#\E8H,VJ2SU":WiqrN>m:6Z3HkVZ6%&F -A:RKr<+b3HT+Ya&Ej6-:6s'TrE'PAUcatNR#b1_^'PCK;_BPd_j*ZG::C.%+,[,$s -DfX,gJWMcH.p/iJBNCEjoFER*)8&jB6k$:^0^8YcC*?Xc_#kC=DibKTTPnd)K.IHV -0Jc'U1W)I76V'&O:e_"[K0skfTO<HuE[P=,GYfIN"*cc?KEXUT[mNVATG09EPW(9= -;e'SG+qj^E5Xe#<2_[)kO?EUlNi2AH"J]T4mq+KhIPrl["n4SS&3pGqDZl.H"[[D= -6F-o3UaC&/"u(Z8E0UXh%0<[b$8=4[:gjV05W*MS"_:U?:alFkIgbbL")r\o&3gPA -OTqZ<$kTBF:i-WF3!pcC%Y=`~> -endstream -endobj -43 0 obj -3194 -endobj -41 0 obj -<< -/Type /Page -/Parent 32 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 42 0 R ->> -endobj -45 0 obj -<< -/Length 46 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>#)ar^rEQhg&3"QfQ&7V>nS9G,P`<?@*UhM1pM@JR6W1_IZ(l]_KK*ep=Bf?pJ -#)kjpjs_pJ#sbM]U9?Bn8d<0P5dY>dN/WNLGn?W`.4Q7APsLLa/d`AQ`Y*j4fOuBH -7Ku3h*Mu4Vfo..e97W\LBfHe9-8J0&b\o/*"9PYp4E_k6G!lE%:k7JB`gKRg"/3@n -b3!cKHC]T/-8umd7C(=&bN$=GJqX9"I\Tkp5%/NtqhgC1K&O5Be.i/'ODD;mNanaC -3fIRAlBoE7>PS4!:N1(D5#7s?PeaKOORrm4aP\hc6_m[:]'rY.&.F0skV0Z3GX+3H -dA1V!4&F\b!(9X.9&p>^B]p?q0$qQP`\E[g0b#[T]^Z+,.+g;7UF=p^5uJBq&3qoh -8L'6.9YVoJ%`$.BNO"JM)3)P4g+c54jCpSH_jJk2NPh6j0dLfk7f3E&7$TYl6ZBKo -\Lq!S+pfH,]+-A8U:qSjOt=oW6S?Sq57^V%of(($%/r0g'QDJQd",stppZLS"[g5% -5l)$[mT>9#Naipej?0KDfVu=HG[f7)NH8:=V4kcQc*0L&?F;[$#\4gkN[Uh_7?ZlO -2_b_?oK$4X"T63]@0";+NNW'401shX)*pSCS1=udK=j2?UEP50[PX`g">X'p&CW`M -Q/u+&N<9IE3]p6s>CZqq&h*g8+gXB12IW+>ME$[Gh"NBZ9PYTZ!t6o;=>h3<LL&Pm --S/fm5[BVnO`XV>";5t&TN)!r`\KoE+C1#fnLK,+"q&m@P(aTm+S8QRW4R7[(R=5N -:BP/.`B:=Mdr5^T7?#b$+j,*M"q*m+rFc;F)2M@]4qj=m\8)\Fi`N)/fPS6Lj'-5d -S.2DE3i6q`kF+6a3`TYqfnVTJOP:^SH`lcnB[FV*3$ol@l+Z@+cHR,1pPf3"6].G# -f.AGH6l-&dqC/tWN[q.&[8oe2X?F1>Eh['2pCt-@;=2aH=/-dcR+R%;l5;d:7Y/4q -/;#4$[VIA,LW$>'Gh2/4^u.*Z/4WRPiZ&GJ!IgG-dm8,foY9g!nUG"`*Z6duDhK"B -2j2W]'>6V)>ihL)Sodff=s<!Lf)npf$j`Ob,j,H?PQm`Gg7piMTp6\&PUIOj9"%F9 -+RB?C;PB7/TN!E28;8gs(dg>Y"9I0F-fk=<iHh)LLLp`XBQ+s..U,mrd3aI@DAg?Z -?Yoh,+=&pGXplp<4!u-o#4UIg+jbF8Ceudr5i0HkXAqr5_,#Z8Ycct:%QXX=2&`lc -m79jn+n!Tg&X(KM!L]TacualHZI%,;qlFS9]e@.qq&TnL3$bcnns5Jt'B4sL1$]f( -7sBbYh;j<Rb(4c5pY)9?BOtbkZ.1u0e6uldY$Pgj5qlqP`KjXEP&;H)1'pETU72l% -V;rFUj!J>F#mjOg1`34/WaM>WB-Rt-C_n>O%)GId#7GLeQU'D7bUJ<%-7m0(o-._h -$kkM<g`2Uo5"3;_DOQ7\CGVVn2G1']#(W?k#>j30<Eat_`UUD>EqFV*J71*iKYL6M -$47AQ8Hn'9UB]j!k1:_p%^3.[-jbkRVG"7`M`d:qi[tXub_'+-Bu[::^kN_I/.NiR -.\ak#fT),@%+G''-j9b,=H+)%X,UFGYg++hfMl5ES[QX-8pQ$p@gm,ST<8Dm#V"R/ -UT+KU0F+fl9l(&[E$uDmi7PoaP:guXSLR!'>`KY\5<R'G&-l91)($n85V.3a86,l& -,oA$;CV`q3lE#mnbrq=$f]B[O@k)5\Et3>knfD<cbDqbb4cBB@ed';q_iSY=UfAnU -$!\/G840Eg=;KH9h.LL0/TE=mW%DZ/EEq2FZ0];\1H,6D+1m&8mL0qpK!aLkQmepa -g^mM.,.`ClDkh,+5YB%K9s0-"3^LtPL>^o.'C^'U@2]E?$Gg*jjaha%=;d:K@0(5' -9:)[>2SEX'_@a:l%>er:*iCjX'E[P.W3@k+r!XBWb\JN4o!,S&B]7[<6,.POSlN0% -@iNC1B<8)GYd[J=C>"N=<c$Hj\XR6Xa=%PC-/;'C:iLB$LH)C/b9LufAo0'![<M#r -!2eOR/k!EgJ_b@sf%``d7C'X>Q%T?#fii.I#rQ`di^##\5_4k0C'7E#9f%P0Yq<FL -5`EWli9J/[!'GQM^$((+cjugqmOmVY+Znn&o[m(U]k=V12^@hto+Cj0#;)SMXTfWZ -r*Kl$(INoLjrNK]<Lm;b[[EQ@1JQ?^-ifqYSb'^CgFTM$2'$f_-r.N&frD`_d\gQ> -$'h:B=NaNKf,:m5+UaM(/uEk4)mE-VYL$k.d_IGfi.;V/-sm:S"=s`/JN;TlP:FB2 -92+8WAjO/">:hKnVb(9Vlnd"eeg"RrbuZ$1D.M2YDcjhX/k%BATUpLJigIskU6AhC -6&LeuV3mM!j/>BqU]^~> -endstream -endobj -46 0 obj -2528 -endobj -44 0 obj -<< -/Type /Page -/Parent 32 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 45 0 R ->> -endobj -48 0 obj -<< -/Length 49 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5g#?cOjg,RktJ7R/f9P%!o_C/D`+$0B4\>65a"JG)GR(@9fQB4'H-A7!C;r8AiH6` -B0f+2W(I4*@ut._2Y0`k<"2ZDFNj.q)8q9H!bd+m?%X!q6W'/&AMY:C`PZtklu-[k -bP#.+!O*8:NCP7:Gs.Ie/V.cX_eGZFDkik"7b.!-O%70dN4AFrd)I4A[ga\33o'qs -BebDK\!)A1cpoj^"9lV3b[rXM)[rS7EJ3%$Kn0?O0oP(:fJ5X!9;muKY/1S_U*6lh -)l(YUeeeTWN$p/(!C3S?%3q>P3fV#okVS:ZE[ii',:#Z2`CnRp1U+bNj>W'l!6Ge3 -CWP9l%H.<N1bd"TkW4_kE6A@n05JoY%&9303D$LXP,3_$_k*<s!i&^/"i12%1ItCg -W#!QBODQU:$iD@ZVr1J:3".$qr:m6&'@?lslc_aE$DLpq&.CoV&;pYn-rM%="2amQ -YbN'$'90mlb7MU3/5Hu(X>Bi6Yp7=T42_4<d6B@eH94$>1OQj.a\lB156M&ofJX3! -(rE&a"+5j!%e0o81qlr+/38f3=Bu)dcFV+t_DQGM-G@;6Th2t:W4;`>0AH@'^b?`A -AjNkQ+)$DUgap3q0=j:V_t:ah&k(,8<&q.F^heiVb.8$`hsfjrl7HbVB7J`GNS9-) -M@?7``[fhY64C9@.Q#SZ'SBc+QE6c/8r>D<4ZtdDCAU4+eBT#9+f__H>#U5SDq9*g -;f>G)>d3NFBgn]Vjrm13p"GHlS2-,nV8o.&RHcSLkSHqO$`\G^3[m6J5i!6l6[g_a -N`agm]])U=juNu>XA'rod=do"=V[HX>1WAkG/Hjm`+=elqae^Bi.2)@WF,aG@=I%t -%$$6>+qVq'DD^_m9F]DZ5>\T[*]Wc=d_mu!2jd&S2Fgd"_n&naeTh/`0c&%kf&6[e -&T2\Acd.@Uk6H-)/"juuN3`pW@?&bu(OH8eI*%C>O_jX3%(2<3\^oS3mn:T(\E#c+ -/n/`Q<@ilM#B3a7H(e#S;a7!J_\e+eNW[@b((?DPPl]3`-,]B>)Hsr*?Qs>R:(_W$ -")_,kC*#bKM0Z(uO;Ql*BjpHbqBqVo`#.c88h!IaZ8_9(SspZiNlh^;(R3i`gJ`)@ -c2Id.?MD@Lh$/UV0EM6+#SL(p2.k&L1??%J>-!J`#(=4oV\ZMaHZaI'bVZ1enIAgo -T`tWc$9BL8S>$q/:^RMd.!#fkOFo(h$8k>Q'dgp7Z`T!R5cOp*B^U_80gb!%"<lD9 -]i=!"$0qFK//=?#_h'fUl.I&XFcu,8)N&UT:`4mb2%Rh8GXO#Y90<?o&lpPT%VZ(m -"uN'g*nqTVnhN]Y85d5I'@h!>*"Y907%r?SHSE9udkdp$Z^LD]J8^r<L62%9O'#b& -To:GDisbn46iK-N!HUG*U@/Z*/o&?/Geh;^VU8;Q%>m\72gGtfVDH>>E/n'^;!@0% -]&I8:LcgoD76:MOaGgOM'LruGba?;f=)T8j_+1$J>B266D/?k?8Sp6E_bZ]Km5Pq] -oRG9b,+(.p,1,i&6rqJVR7K'11\qsI@[^PQ1K@,hM6a7\jPF]]\2oAp$ONPHBlg+* -c\!?NGbg$'6qj#/:/JkG<_C%o;T7X_QN3<r#reaEC/^g>K^mRQrIf)HqR..^JeBkC -VfWeg:msMnAf*m"8_/j'+Lm#l@c`q5/iaa;CJH;u$`(+:&-b28*0GP%IB7l-1*j%t -(Yq!I%Z20X(Lntd7&s@/_Oe2;Dd[<bc;h4-.tWUl3Th+q?:7q-:Ka:=gb:U)Liao: -UfrfEUN9N,r]AA]^7l:AD%2YE&4s5..mjYB%JAfc5mFeYkeVQT#O8(K`h?r*KhnH. -nPQ;d:BUd"I8I8hA?Rp_W@5?cPJPONZ'k`#_fAJ_1[U.Re7U>oX^.^-l(H6Jg(T&\ -8I;G\Nf^JZIEp>CE5:0t^m/TtmIOs[#K]jbMk5f=3uFI\i^jrq8P:LS(/0PPLeH5q -*7I(E^D9F%6ms\Pcl>P[/==$cM=e&`b)$QNS2;<6G1b=K&.XtsK>'@8!369M$<PU@ -)B8HNjFM(N+O9t[g]).CdUgDe6C0E_-O@V_Gn(:j2^!XiPh*ob=GR8GYu&W&X$)kP -l(9%WMOHh(r&p(:#'/C@:MQR?7!-4qX@O&#Ep)/HIIG\di)NKh"'O,2Ub_p<=rP<L -g+8SijggULWlh>2K0Ku51W=T@g;pW07d/qSL1jgY_2p&R`?OEP9@#W)ISrcg/B9ps -N,]V\O"'W^VaERsL5E=44JgDo"$f`l6,E;MJHR^`]=Sto,A#C:lAcm:dWY>0hBF*# -iZ.""FE.t--?(4Q]pk>$Q(!Dbd`5p2j_CM/3JlNI[RCnK10$WPTqSag.NjG.*(-md -<lk+5ge\]R#`N\^$+e8=Ckjk$'c2=ts"Qi&h3;rMQ^hf#EsFDG)t&_e;oliG:"u&W -ObSH2A\G'3BN>HT'JTcgL,"Dt7@)e_IuSE^P"KHTmf@6G?-jooVc?.?_crBeRY*Ir -P<Q1f94?g!f'R9fk-*1Vn=E^I\TG<6;%Jfh7M6kMiKA-,FK:/;Li!Xi/_+u)Ih'bM -V^\[DcE/A\4aUg=c^+K]akdRX3QaW1`W]O6P\n;H/=VR8V=k<'D>Nc?'VP)?K(%R8 -"g5LH"/^JN%Ou*M:)rGLF2#e*RuQ!89&MY'gg8#06ZqgM`]%7l<<?2/).p\:1UbJr -JZZ,09*J-3)TE<Md(]gA6/Mk.guc_TGH3`Q\%BGE%V1)e!<~> -endstream -endobj -49 0 obj -2887 -endobj -47 0 obj -<< -/Type /Page -/Parent 32 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R -/F10 20 0 R ->> -/ProcSet 2 0 R ->> -/Contents 48 0 R ->> -endobj -52 0 obj -<< -/Length 53 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:8(*7&)HEQhg&3"QfQ&7V>nS9G,P`<6hlN663%RSCeA!RT2)&/n9?&PZ500bbMp -UB*gaaC.,<$`-0d.]6s\ej^>-":/0h)ob?7R_4GQ2\_Md=^j)36(*CbU%N8a`+Uot -^kUl8UnV42"UYNi;h:1gAA)=Zk3MF45]#Hun%o0PQp>'k*"=9T:97qB(lX2iRq.=Z -RhuPlp7$dnfH;dR":$_8"12PRO,R=@!;&N2%3qP.m#7^$5VfnQCQ(;<!DAls$tFPC -R"_^,'Ge=I42dB$$oi(M/L_=b\1U.9i8qKWfK_A*UM.UJ\rO#54H>?3!s,T&W8oob -0rW1Z^i!BCmBE:bg_U,FRjs$oTp'F8#,/n3.RZrl>Uhn2URX@U0At;!%C%nRaGnPS -bm?]&%*J^3_[G=ga,@SG0T@\i@l1IWLg1Js6R]r.Nj#6#$V?1g@h4=a$47RR6%F"/ -9+DBb"\:8Or5T6k1b@".!P?@,b)QbP!l8:Jo'B#0/-[jhN\l5I;XU<;3AM(;jueZD -W7s/U0J"aje!0Jb6W"Orc5-Zkbp!j%K&aii%Ds`H;q3V/Wf@?O9AoUUj$;$IN=NO0 -;[g*RB4tII<78Gg@pnV'4r/L<^lAJM^))bRJ>in\6,6`h"uJuq\%"3YmM?<6i)="? -\+j`hKFmM]&6(A4co6u[A:GDK($Nb&Lsd\J2iWGth@t]=k[kM=osIQ/i6W=YEQ%1Y -dP3cq9.5ItiPm#N_t]ro\I4frC(uB-P;XBa(W_dqL*HEWU]r!@C=%]$5]dQ$@n=pZ -a776n1WC#;>lo_@R-=o_/(:J2^[[u?SOn'`>G0A'W)9:DRQclPl$@%%ViH=oV5e:a -`jMs&3r[kkm#X-M(QM]oF1,m;@-B\3qi#8MmYN!9@ddO`rM:`$(C1punAc23EI.'o -bf7;S<u1@s[api;+U$(O^sSc=d*SJ0nO7,[2NcL'QcQ5EC-%scS9?-Uh8\dp=)5,9 -)b/B%>uDJ%\]J+mn'Ylrhj(tG5'I=NH;^*/XlI.0^$P)k[jUWbrT2Pkh!;g0mh*/o -B@'mj;giq/!S"jEb3L.*1Oa1\lTL"Ep=tkfEj'ok2WoPY>Eb_-Y8-*/=4Zs_&4U3M -63oDuCj96<oF0*K#!]UUs'0ob@h=4M_Dho0?V@8IDmVJjT\a2[_l\XTiN0pFB^OP: -2g96%1:?&eK-1jPB5C/3.$mEMNXGY@8h:m52B]f]6NJBh/^CM1TW>u1$s"pmC8R1! -(rMObN+G]PRe"m-8AI2`Uf'$#K5V[SCAD2PN$8EO[WY^Iq-'nrqk')GguB:iAOV"" -0dmNfc3jtG`D"l&"#`X$)0,ic7?"LX!+\H!.4cUs`eNRJ&l;tL$n)RmTCW''TD?c+ -m$3cuE_spoY]lC$9G@[Bo&sTB[?'AoXcW+\CVcr--,>($RBUQuc2u%IX"69:d-.tb -I#;/!2FkkcI3dm)pch:=KcnnP!E*s0;,VoY#IH$T=6MW-ZiCt>V*d5,JaH7u#l(Sp -(HX$]l3qPB[$HR74[ITt;1RYW:PoLDbqLdS9lMeQ;XRjg;bh':8Q-K/YQt8+0:qBN -I*r3)$3Lkp$mD\mX82ie-lS&>lPRml3Ya9k"VG(IY")Hj(I\dY)kuOWN5do.7qnee -<$7ot;G'X-WCqk;YJQTn(:d+QSHPV,M"Vf,EZ&TI4d.a0T[R)#L9"u9TlhXV;(<_r -C0_KHXeZi(.]*J$WN28GpoG$i\M]8M;$G"BTWEt#>3j<<%B)m3`\a'Hi0&t?<K4oL -js+Oa=f-bddHK%@5aC_97>?pNWQ$WL;aZBJ2W]ac!su>090'L+M)<s#!b<%n=U?3] -,T@L3Eu@[Y7#]Q:Ib\CE$@krM.:k?E'`neCNGXV)1K:O%^hG]XRBBu\Kb'K=0O%X& -EX9p8i"ud1Z]o,YBa3q.K9hs6gEgDm%D'eea$X^Z<Ok$-i1^=#I%ptD_'4&oifaog -EW^;++Ts94!Wj?-LlK7qUg/k@Z8tLt#R[1^n/DI$Ajn>RR_$>Z"\9V,#Vf7Y`L+6n -0\_A:8X;3Q`,cnOds=c/DD.K;q]D9n/Wd4i7)lIHU1Bd@P8gr*a=Qh<&T!1lEN(M+ -!.ud99Oj.a<]%`tHRS"[cZ=o>A]>Tt).`Y\RrQ8O\iIePAo-_#14^@d:%omqba"6p -c83cB$SWNHJ"a0^M9ae(,3,c):@f@3_K'DukreKnM<7@X"Qn_._C;CiApMOea&.sn -9;]*\>LJpoJ83(%W==$Jd9=jTjtf<*ol7[e\p%:kr:Pt*Bs6,L_d2O**NunHYLm&< -<.M(WZo/-2dsElM@sh9BG"10=>8&jW]tDK[*k'NZ059h/V*Rf3U>/tZEbHK=%X-.4 -h0X'`ls6Z#B%E=*Hh2ROCo%8k`p2.nB7fHfV7:_V%+[M,=d%%YR5U)Sf3>jVK2(CC -[LX#)RsO\0mKLORhYu=,><%6eCUUNe,Mi3OQLb!Nbd2Jnbac;0BFYK@ZPH*pS1cqo -Xq,SrpI!Rpo:0HTF.W3b2Vjo_CBH.1e9UIcigVnGk[(Ns3bKGR]7VU*Xd,]n2IP>X -Za4_%`JUmD8a9TVXmK%W^3ac:kM#O.G0Zr:HVSk,>mn48?L,(Y3>h+s(VT1p[GSIN -1%",pO7iK>iO?7J#2G]:oq&.?arr(IR^ik&0*A=4+/65uBjp\9BM3C6,hep>JQpH" -;$mNZ\`uB8'S;UhIBT?n*oh$Yhc'$cVnS+WO'21hWs#Q`5l',!UQh@"OaE*ZqB$Aq -C[CrhI^dSZ)Z/ocr)NO_8)H?,LLYPcSk8o/!69@8j_N0IS:;q0-laK#Io"_SmN2>q -U;jD=qN&Gdmi:?FD#Z//na*:S:[6WY4T(8ur6HekYBp6:8FpY#!KF2`O<4GK&FRc\ -peNmL9N;4i./*-?qWr8)TKm8]:AR^g"tt5tYX[F:ZNY90"V83=Das\EEoq8Q##GNF -cVk&;>5V+$#g^$Z&6B07Ka#Ysp<\-cDKQ,EVXKPJC@%2bDYj*G'a\`9rpXD)lt[$V -[/qrZkmO*m%=8?l1C.gQ!3jcRE!ZqlD$ViJnID/ud.#]V6OHZdcu:!1ORV8UD%Mdc -cu?l7&-ghWjTc?&!q>(Z0IIKPaS'R=&eBfZYnmq5)UYa@'@8<FYkJWH>[T"o"`.B8 -DY2hgashq4]??MF@pgd]Ai8SL/-Qkf-EK-+CpN&j/]md88-D9'&A(71~> -endstream -endobj -53 0 obj -3357 -endobj -50 0 obj -<< -/Type /Page -/Parent 51 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 52 0 R ->> -endobj -55 0 obj -<< -/Length 56 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5g#?cOjg,RktJ7R/f9P%!o_C/D`+$0B4\>65a"JG)GR(@9fQB4'H-A7!C;r8AiH6` -B0f+2W(I4*@ut._2Y0`k<"2ZDFNj.q)8q9H!bd+m?%X!q6W'/&AMY:C`PZtklu-[k -bP#.+!O*8:NCP7:Gs.Ie/V.cX_eGZFDkik"7htMnKOnYX!f%uYKU8+^(lb>f9i/:M -Boc'o!qB*;5[cC7bbm7bUtfUqS-^P&T[:D6"9Td`3XdZ\<#<-%0Ns9e6',u=]SZK: -0d=L@efD>`>&G;b%_OY'_<CL5o=EqVe1ln,Rg^nQ&'1D#N+*p*&4M_'?n/p$TNHt= -JP:A$#>V'4%R\TR*=+Mu>MAhc0:V8(^G3Y$(r,PK#6M^183md-nJ!5_6A$g@$n5R` -59`a@1d_P]bPY!H`A(V$1l`/q@i<:mV!TU$8M`gg8(7Zm+[^58d[SFaN0O'#&!Q5S -580jf)+q+I#m3I,//:$6')]X%__N5A/kp=*h"7O"6rb.#F0&df<KXN+5"B%NY<bu_ -%*ML=ZpdT[]p*&s8'2O1ErSB=ZjI@;1t<*J;lDNI$,Wp[6UKD5KY9:W(77s!:0!Qf -4Oq=dN&D.7*G\m+1%fXc=-e7J,hOk`*@K8[L!OkU[&gHC;^u?;?Wo<T_.q2OAC"-% -QJ>&a>SW4j=3hUtm=!eV"2uA61a$?d<0ZbdHV)_>o8F01`ViH_\/"+4g.t^5CJ;6D -Z['dIICq<DUG0PGNK=>#VV;u;6oYZPYimlD+V_$[%YMj\_[M0Eju3[5Y\O4IUVP;< -^]NH(2Zt%A!JJ\=Y\G-;GmqBRW$CW,Oef-0Rd6sA6IHgZTt!@g#0ib;k_0'DbbL1a -!f6+u+e$X]X^QigX4tP#9qH>,C[<g8JH4mjC6H<+WItA&REr+\d)%U21q:IdKEJ@H -cZB0fgcCFi&s:V$d*EV]6Vdu)_6mO*AV1CY8E`'e)P7WtNIrY51;Alph9P[7CgkY) -9K0<*N3uLHP:3#1kVn/8e,hRg_^Jb$#gT)S^kSP<L8],-6Kl@@""7&N_3cV]!JE@d -#GRt%Bod*adJGlcJdn?`Cj=;po`kV-*<W8VGE6al0f@1d&0'2AXDR$k#Ftg#Mpm!N -Z3pnmj?uV-2(Io`,eX?af?;;6.06q4L;;I.#d[&cDc!3`6o#1EJ2i9U*T9+MEd&1C -'6XD1Z6r+<b)c_7G9nBs*O'Dj,$ZrQ0>&F2G:pYJ(iO'tFnIUngC@M_L+s872l%f& -%*2C(D=?[&#Bic]_+?UBTV*uoOA^=ZO=5P9,lfgt&nD#Yo.T/k#87pt'8rN)%2%)- -"%a+Gii?UIO7^0.i,8Ug,R,s=gb^5Ucj1ji(-Z`VJWXF<6Jr,p%akIua?\AuAXfQ= -Z+\[Ka#s2BTPnrV,T=g>'dM#&7W1_WVNt_R8Vhr(3M`URShbJu,)@X%%OF5h!.$rI -fp;qoJ1nasM[Eo<bXSg=0no,R)]\0V0-I>2UXhQK(i"ptX-,!0;qdnBTO3,@g_PP( -P`N]6Ba_88=O9T(b"qlcA*bq%-/_WddIdg;iKArBo`0+CO9uILh7ahiB(3pQ1Bq7F -d$$I7'$.9a$LZQi&47jWK1I+Gk%')^ZIWZJ!MVE*R+*5i'bUsq1LohUhBE*N8SQ7T -"[FK_K7cX-C3gAe2$b.b@sCbr"_4QRB\o6T\PfI2SK]plZI[1G2JT@#XbQW/<SG.m -.X3foFjdT8>6A9uQ$PBSo!d07QW)1,\O"d\&6=]6@VVSmZ'G1+Z2$OnX0$$6k/teJ -X#4+_j`)l[WmKC-E)eJARB<mj\6&tVALsBqX+dFZ<kB/_/Zi9@<YF4=CLqFd4g_KE -J/Nu+f5WAWc+3OW^"a!^D6+JRZ@qQ^h4%nsDH21eJCs8C$b(BL/_%9(L<%b(UKK65 -m]BNYg">&u*ZO4fYh.mkhb,nI8;2,b<jp/$X93rhQ2eGj(t[Nt#Yr45%Bh`<lWu!% -J;H.0Z;O;a!uX3plHNP@2?=$7JkSiieg7GK`sl:Cm:TqK/&`9[f#?W]M]<&6_,slQ -ehCTmm<1WO39%4']/gD'L,[0j(&?p\1QHHu,IDVm+5r+(LN-WP^:?e)>:ch46-`f[ -=W6E=j*@!ZNb6<,Nsab!)j'Vrgs,Yu-tU#B%.T?sb11Pqk=gf'DI>?8q4diO/:F!@ -A^%"hT/b[ho:N;=J@<8R$tr<B9_>KD`V2'?@k@?q0fDGJ3[VWS"*'L1hPSZqf.q)D -4--ad&[V=$(D((4QSA)B#%5=4jNVa=S<eZSPs7,E!+DJY7^K$YjT\n5O\9DSa1Al1 -?#.W`*6AXc"<-.T`/T,Hp-ufs>;JM1rMtY^p=._5o\Tjf\%9#)=gd"B@q0<?Xf>,( -M&,,c)k,/m.^$V;H>aDu$e%q^(A#\<P=WWN9NnojD;TO2IbK4T;"r6Ni74l]lg>Rq -G`ac@S4@\j$Dk^WDXQ/Ho8)l4E*p*rprZYV[VcJ2E;#:[e[Gh2S'?/(o9I?K)F[kK -DL\;SV`rg8s,69Y1RkrD3NRW5hXim*d<VZEk>r#DF)-9J\kc5]h/f%O>8bYnmEXa^ -K"L;s&]lkp:SmuMWRUptOSEG5#+*)\DI2eRq#S4o]5rCE4p/uT[r)C5kD=Ds3SYnK -DCo/tN,JXpg\\1:X^&a[&[HXP%^FY4,s8.>D%.*e"-+k-Cn;=&i!L'*/;hf+/1ea@ -4Xhj^:]YAL"k^D,gM%6(Q]dDV&5hfG:UL@4h&(L'$1>Wj^1O9\)%obMCoA/Spugl? -.7=4-_,%S7hWP[Nc_OJZ%$XTg=5s1Sk`1,d[er?KnbiF1oP$T2f,H/CFWGl0N]+Rg -#j#gNea-tYM^8B4>Tc?=d`ahq`]bQF,&`E*,48D;,D,OSZ>P^kR\Plg_?@p>6LSAW -X@U(uKr"C_p^"[`%-TH#b(OOSe-9;Y"f*3Wk6b=(AsfK"5cKDFJC8YBZ3L]S.0t__ -,5.DH*de9eoHroU7e.\>?8O3pW)"0Ui_D"bN;`4VT[/u6Dk%4hFp:af1*S]SB(jhK -@&;"Z1ShI"@O`SeFq);L184oM/hj6!32m<U1uhL7M^6:r%cT$>!)0p78u+>G;\9KN -hTjF2bdb<H*qM*3Z;.d>&-dT$*tmpS'!,t'$\#Q>/H<uD'@/A\/[-A7#icLA'6!fN -&PV_1.,?B='Q'`^cMGsA<.8]q#&I3S&-C!)K+0;9%;KFNOP[I..KN8K!s/N~> -endstream -endobj -56 0 obj -3361 -endobj -54 0 obj -<< -/Type /Page -/Parent 51 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 55 0 R ->> -endobj -58 0 obj -<< -/Length 59 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>#),FfgEQhg&3"QfQ&7V>nS9G,D#ffl+d*Q>a#Rr-@0tcRa0V&Y"o5LM(C'@T( -'mZJ3HNFtBL@LCfk-#sC%WL'XR*\-XKT)VtD%O]i)70kFj,&2_'J1.0L'&E\VVijS -PRSrqV9mA+&/`[T;dkbQ@PW`K]M&p!dVUb/Nd*@"K\.mg&5CsO$(mB)1u3fhi<MH< -dctc\49M#"r+4np`!.26*_%`Im5Ce4(<3N3NPTDSkdkRTXSIlDOMX,d?rJ$^#/Po< -[PJE/N<[-@Ua1`1Mi.ED%'[NP)_44e36Vm8#hh6IN_%"u%V$pH3k?OTOuJ?9!pl;b -0H8CA%=nN;h7'AAe2b@K_dXSi+du=,"jb[m%^mO2C8)&p]A!"n0-jl<Y)b**!]lE& -_Z[ep_D'LuYbL.D$B)Q)1lkMHEk==UjI@/!:Mdu@^onu:"LmED#Vns^Zgfo-NNAg& -/L_?@f`k(GCq.1+eDrOuUMGt(`sI:R#-r3,2`CmB\E4Q*:/#-U%F-ge4?R`Q4qL[< -@eS^0Q(mV%N`D1u<n=YKnKcVXKJuDUceJ<L#4L;b:rS%op>A-"PiXSOUI965es,9U -:e*8[Gi(Y^oO/V,K61ri:.t)t]J!']&;+,OEo+<dj$S$/<g"<i#,Lb8Em[V2RqGBJ -"";i=-8C/.R*2X/au6H@bC[K"e2:^n<d4.dH!'O>@N:*GZACLlMh&5M:'"!iPQ_g> -_D0'JRt6+o+du.DiM0dY/rG6Z?CRblPoT_TZC<P(^/`P8jIpLWBJmW:68ktL)ULaR -,7S$HAum/^>+c$,Zn[4WiJU)A#&.a_NJ>lm>dWl!D6!D225Z'(CYIp`b(e#).C)?g -4YS^0D&Y[d#%<8'd;H%W`7JSZC@o;'efsrK%@%ur)V$@jcPR0;E9K!:%L_L\\Ke1b -12(ta&umdh9!YSdW"<DVn?TLB(pVp%nCPG"'XG7(_.\3O0JRg\L]d`^oG)YFnD#UM -!q3-#%=Z3=kBh[H`%h1AfOO@RE,G*1X9#n2%YXogmJHo*YhAXH5<#nAhcp#*6#7E% -i4=P7l(</hKuZ+35&/8+2(+Dh[BROH!Zf2d.g.0T("5A9%?V?L"J+QkjX1/%==AML -6.M+UeG"RIBncYk(^A%kI@s0)J^&3?)Ick[+G_jemO=I*_X>?Lpfe32GkJ.*VO^`( -G>:a>Ni7.qT@4s:"jgYr^p%:)U#ICKT[;@X'Wc,,gR&-JKGoH(=q20b'.u`$4;X1S -?VC3G3f_ac6^YO@%3uI>je*M;_GLmXLc?T?Ua_&iTY4jOJ1sG(q1^,K*=nS!4-"D; -](;#d!u%_:B,E?XV?.`iG\9<.[36L!mMiuPmK<pZV_>Jb^K:5W4cZVTT*91Z'qfIT -"l_[:5is+`CDR*ZZkTltA-rFC.<k.^j.ODK+(33`N.e<+,mBaOTiA0JM[VBGPZi3? -GZt?FQ5B\T)%H^&Sqf^2<'t^<IMkQ/1fJ[sW=fPSU([qBjkVQo6_#*d4M_L?9_(rd -LgU>$cVq,[is*s+7&=Fo6mpY[V%UpC=^qjN1IV*Z&9>qVnl;>:V!B6p+EBi"E\CkJ -p`u/eD'O_?BoD7#Jq1a)Ns]H?#Vc-F6A1Pb433(0I>/bmK2<s_`0aLZ=fpWF,E>?> -%=uAga`WF+Np:eQToN3tU';N4CIeX4mZ:>30$EC9dlK4$CUA7]=Xmt[?VJ*eLG7*= -W\UPT"m(\;-qQ5t8]`q^&lLe-B"-5#F'>YY-j5Wdk3E:o?3l557j^)@:F)PqWLfPN -8Z_<:S3;FEC`6$r>;tZB.'Ki.EmAc,7d%=e-T12AZ%24N5m=YW2Vnj<-l*2#+XOP; -NddflA4_\I.CO4Re[:%r7M+"6<<l"7=62qpamEoD2@)>KHIE.66hFJoq*:Tu2K.fQ -b.HdZ[h=@`>@45A3AKJe,KR*McDuGdi5h4::hrrTV(";rS`Lf;hdGfgSOP$P)Op?& -(#)lsX`Mp?!e\A!Xdngr()6WYF'/XL*Vue6c-S2Lg0bYR;PjblgXAReP%+;;E_/Hc -b?B4[c:Y[9+d+FL@#@lR#Q~> -endstream -endobj -59 0 obj -2202 -endobj -57 0 obj -<< -/Type /Page -/Parent 51 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 58 0 R ->> -endobj -61 0 obj -<< -/Length 62 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5g#?cOjg,RktJ7R/f9P%!o_C/D`+$0B4\>65a"JG)GR(@9fQB4'H-A7!C;r8AiH6` -B0f+2W(I4*@ut._2Y0`k<"2ZDFNj.q)8q9H!bd+m?%X!q6W'/&AMY:C`PZtklu-[k -bP#.+!O*8:NCP7:Gs.Ie/V.cX_eGZFDkik"C"<-?EWQ~> -endstream -endobj -62 0 obj -309 -endobj -60 0 obj -<< -/Type /Page -/Parent 51 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R ->> -/ProcSet 2 0 R ->> -/Contents 61 0 R ->> -endobj -64 0 obj -<< -/Length 65 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7:BP%&/B"=L`8`2M-\D$-_ga57eb775.QZ5n4c#ij!aPDEB_Fd6n(F -JDP]>ThB#u]'Xs19*GlaOtr`R7g'WjLB7_n;J7e96(lh\!7pWl)H2BCM9Ke86%]m\ -G/Lg<;0We?%7$VWDY4g*N.s4K\BmK")9)mor&?*/6l8k-=Q,iA-ZP.%As7Ie)eh?s -NM'Ga(6]:PeVXY[j0=j2F>TE04G.ph5]8Fa%#0s#R*.3C*AuPc+Ok?cQ]#ZW6DTE6 -E&el]k9C;?g1`J``!-l`e#mTMRWt_oh8_Y2+Y%Oc(ob?/=L/42id;]T$p\(#YV$"r -iAneHg+\KG-p[D6iu<q;^(6F)1HT$d>hprI9?c]`"/%n6NIqN!3Om@]U,S)B]9YC9 -6_!5*\k]$/(o%Bf2M\rHFBC<1,>4=XN.HdaWDhW)4VBOm&+6%gHP"i6"2)aTW[ -'+'V-Hedc&nVh*!N%'^@0S][\k:fSN,Ckma@6h>lL7q.A*!U.#E"iWKbLejGOnBP& -%Zb#Q3K2ADg4?+GaR&a5UF:76_bXCX9iI/&TF_O,#f\\g@n?)ENI_)Y+&ueYj!Y'T -kbodN1Sj@K9G8-51I:>oW<p9@+Nkaael/mo=p(S!&.W3KjReJ@CdV7Rj(*Ni"Tp/X -1Wia_2#'&8kgMFhpGF[&Ks',=@*E[A75M3uf\'#[@c1-#9.=Oa3mQu+o6W4@ph<"! -<UL*!`CMO$)[@ro-72*`URstFEU>q>%2BULIE&a5VeXrGIBr+O2W\?h:,(&\)@Vj\ -h\X"nNZ39%=02,80uFjo(r"LRVib=cmA"BU'm3oAN<;mV=]U/DD%,R9"iYKb"#/1" -](bUlJCiF):S137o`7)3l^f;p0+A=8`sC^5hD&M;`-"OZ_#T'F<]Y*0+(Wtc0+>ns -Q>)h$"(m7]6W\6^162*oJY(M<^?-,D'eYg^BNDd6(N<B/!J]5d-SMgt3)8([i*BC@ -0[@d7NlP!Yh&E;-<FTG!%U#pi%*_-k,!>JiQOaO@<uPI%N5K&G0tE<e:KqkkVd"NP -&@=,Hhq^@A/L:kU)*DaLj=-j)EIOuK5/W\G%9ZXA@d\pPYYl<m[gqaE")FZ8/lc1- -`!d$)b6r12r6tfQ.d#Eq*'IrB+$S8i^<Sct8dS(N4MsJpOm4PZX.>V3&odtJo;bte -+OgK>#j1'-lr*+2p`6Y8%1KTPF)U<6QiM(o*LWm\mbMi;,[BifP78lN3ZpegLo-N' -#Up>i(HZ.SWE^Uo<mN5`_8`5R=bG:8O&b$o2qf4'H.mBEr"qZ><;KAL%noQ[$*9tj -b7BbP?,=?-L7$'@<h^a`95u,-BFnO4@hF453NF@^jr,+6ChBAtco#BPPX,:@7FG&F -*u"Ggj=quPmqNUm3$/_HHL;0&ILrC+AJSD&\jrYhis%3u)J#U#$mCEcUb]Rl6)tQR -aA*co15K>bN'Up3=N<$?5d_Z$c"=2up:U3%%)KR)%ZuHqQp>$faJ>V_K]F$cLkteq -61d1BjiO,KnG>Sb;/0gATuf,Jkg$b9"9FA?0'6bgcIk6Ei8+^[W4`"3dYhC>\Lc)O -]*%4/Ao;>V:/82:c.?tiQ0UbiZ.+1a?0fgdDtGi;Qhm4Y'1WJ7(#urpd(#@`]-M<g -mAs83&IocO";>)Q*,n1u8ZE:+0hn:Y<'\&*N4`=bD"POtgER\oGt0^%jddW^(g<`B -IODhNL.&==i,M;^/ns(<eSQpk1\#L]Ss-f$Hl/*2X.N:dBr74b*96&4AZ;M;7H9]6 -&KiYNl5]+Q7"#!+\J'e&,#4a[p_de']P!(U3&^ts'o[7!$t4m?e#D=Gj;f8"NEV7d -[m1n`;`.IVa],Z-pl+=QK++#M3`RW"#@>T@Kp57F*73@/&Jur$AE(I%OPGVVOj74Q -d21Mi1lX&D!?u+aPd(lsKA^jqF-$Ok`X6j*;9bT.eukQ',_ec1jMIWkQ2ailkSR3Z -7^t_3hS1A4XR:sL2^%7=>H,W/WO``i.*4@h!g8c)PsCGHe/>'-'\I)&5!nhn/%D(3 -UhrA>6dH(.P7ZZ2DF3b$@GX4<AL=3le(%)N0*].;rHchZO/ImmkD*0"[-aFQ;ARsU -;`5()0"<UI/oI2^iaXk.bLE5.0_Id\k)^I<e9IlSF$Cn0ZI/9-6cdM3]SeX[/n47B -/F$_7pU951b&!*[0JYU\Pg^@f,q$d1TB$uI&K6)$O45]r;kVnd6Yr!98t>/%b)W:6 -!,Z=gD%/ms-4Ea*1n,(9(]^B/8S`1B^F+WU(-9IRO>=S,Q(FNN);`RgCh6V7)=SOa -PA&@-N08rg&YCqn)rgD-\`_U)1CY@cXJTXDM^UT?3H76e2BnSLco<Bi7!*@Z<=COt -J4p#@$5`mL!C7F-O:V~> -endstream -endobj -65 0 obj -2462 -endobj -63 0 obj -<< -/Type /Page -/Parent 51 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R ->> -/ProcSet 2 0 R ->> -/Contents 64 0 R ->> -endobj -67 0 obj -<< -/Length 68 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5gGWgOjg,RktJ7R/f9P%!o_C/D`+$0B4\>6,hsge>/k$(Z'=Bm1muQI"*qCAD_hY- -L6F<e@Q,)470[KlUh>c-$4NflTRbum)@Zkf@6qXJ0GGDh1Ff>r_JM3"9u_/RK\8jU -)mEqDl-*%2.M@;#=QC<[9b84X"KI$Q&!7DD_uhu\fK`.B(<`pl+=Lt[l3sP"G^-`: -1S'NmIOTc5c6,"HMK,TUNish9e0V=P<fUdm-LS0]TWK^?RN'"51_?QA8t''(LFeAe -\Z;EC@MFNi^h2je687[`$u@-sfe9+^khim"C.bCY.4B3U1,))FKnch!'Y6>^N%h.] -/SKsT$tGCIUCAb)%`FB[5g%D1E/8D[[7tm2/d2`@dj0q5X#`;%D3JWkN%tZ:[6i+d -k:)*>6\LStYJQ_G5q>Q$La#I$D"=<8g'SW#!ONgr-ilT4,r"m$cIk,"nC%r/W3_[D -U;I8X&.CqI5qYgH"Ht-jd/66TY3K+'Yg*o(a;K`:g7ToWW&4RJaC9i=,E/lj75c]2 -5SVTqolXJ&:Wg@X.^i=,#VuqM@+`q-9bQ=Wf?*l@43Pu)>+@0qX;i"Q+g>ed<KXdf -41+3]>Wg82(l^OMa`LX9-;f;$R>/PX,9"loC=bIJ@tb[0#HgVV=U]GJ4"=)p(r"f8 -UF94U$,WX.-;>%/EH]V>AP5&h'<l))_@tI*5`YD8*IeK>I#gu4,Cmsq?$.X<VQ&jB -5k%)t:i28eMj7_%d;esE+NS&chPA`e-$#71.m2`-gDSRfOMGn8_DbA&9[5>u_g>qL -;aYtm-&j\\cR#dTOR#A5c'>B]#0ToJDF2qI_!ZmnB\T<<'beJHTsfj0WMXh[+-^2N -I`XCp@0RSqYo=[\%>Mc4aMVPq=OG6,UCPV80D[ZN1'Q#[`>0T4U>""gTsGi4j@JqG -LuNh@R[2uIN]I_IcDIPC@Cj2jU,0Bp@<Q723mN?^8Q-j["s*Db'NR7'JKZGq5%-AF -4h=@cL)7Uul"!`N@[d!_#XG,(Rh3Ob[anR#_=V/T5Tl$?!f>B4qhf!m9B)@;.S[pg -J6K@3P.Y`6J[tq!lpm?90F&u=@>@8ifaR1M3@]]Z)B`c(<eM#f7I^HqZE4)b'8(mS -'gS"8Nn-l[NDld,&MTC7l&/Y&<=8F6^6hHiTe`QHE(1S[kNieO1):(-C*AfWNoqPC -$9ElE&?Zd<:d_T9.\Pc87:c3+<Z+G$W>ZX*Q'Qu`J22[-2/o]U12VY'Dh.,0CRG0; -<JYH#Jalnc,UANl=]/LH@-Q^X-$6bW3q,V<n<q,cjGfMS(/>5GM[(s$D8Q+K%&)`D -)dqrofEu!s!.Yf9"(G\iB`fR-E_eIaP4p4`hHc(ZX/_<uSkpD./uE_GR+4Sm6*[,C -O@>55"Ti6I$c=Z98khN:raE\]@o97<9fcd_a'rP1LXL2p6rsM`-7h?GXJdh.1qFRB -F/*P(8i*Im+q@;Z?#Kc!^H>Q$#QqAjQ,PInUB<hVj3lh?Wt$]!#e)p[fkCYk$5SC> -jqqI1Fp&B$:RG8ldb1@7H&-:XP#K*_RIn(%"knQo#*d+@MJrbbfa,W;5tB"]+d,eW -*ue9%5/:#R,uc'o/k2#p,Wdk5-VUMYqHic-ML'T.!&:i-M"Y"@-C,)rPasa7"KFU- -I'bAX5,F>\U4NS+7u:5?WX0H74AB0qMQWAC9feg1T5.7HGnDml5[1o.47KJI^C]9" -iHQJ'ZeX4[E7/TU8:#`\GVh^b1`6]O92_cq/t4dG71g4nUHj>J04hI__1@]7"R[e, -8#dEC(iKlgS.l3iO;V#[PrK!T3AIOo<_/t=ZqjEEa$t<"QJ1/f98'l)1H-b8.shau ->-HKk+@MnH19K+3\@Ak[ZE*lpFGltn;2Gj5aY\o^G&SD:koj6ho8&qb8V#NA;B.92 -YRH4/.A^'A_qh(%$]1`'5f+`aU!t7i(T9*EE*<d)+bOQnL;,L0&/X^n;m@c'KO@0D -Ib:a*]@+gVVcu-K/K/tB@+%WF(\$&i9ZqFLd?_<GOJ+;+MSVucA0LUmQ;$\0;\iNU -V?DLW.5a@:2$gHWK&_X0?6PY9S0A+a[ta1J/U'Wg]V>m%>oL?Y=Rhd-*[oiUK:::" -JW7p@pZTLgjkOH,GdC][j!,&$30)U^8OMj]Q1H<p?q_4\kGSe"Z"#D*l7Kq*ONE'k -'.uurA>ToMl$s%UHrshF,_I9f5dYbk^ak.1YJgS@_k%QEPqtV.Mb[Q1UCSjL@gkn" -ISJJ^GJEui8@O+U$D?*!0G[flYUrZ[6Mq^;aY(C2TO/"DnMf$`%7#Xo+r\;PDq4pK -=_t2uGBE7!-ouuXB=<C+Zdu$1N'7J[]j%=UNlf]d$X;qa>oV0.E7Fs3@%<dC@"AO% -fc"L=_EFH+2MTZ.gJ`62]fCBS*o,O3PAk8ORAq*N:u&j^&8L3mJ+l_9etiUpU.sOK -2iag@S(AMD?&sJ[f$#O(r%RUWl,G\1.H($RK[*l8P;mHT@"DC8&FLpbG=OC=Hh8"l -d+tk6K*(4jF'rf34g?rt.-Q%r?#n4r5<4JKh0dOED8'l(oB/-g_2kGXP"^#+B,'@E -2ehrf%B[%Y*^ng1+nf4+e"$F5jSCfen(t+Op5^lo^%[NRR!li]G@BhF0=(*^iS&S^ -YMai@U3(:8a?!BHjI>&?Dn`-lJO`c14_)>"/[</Ls'P:XJ&R-rN3^YLNp$AEXS>NC -gj21,2Oa:^qXE?Lq&akH*UJg_D>iB(0uO)\"9~> -endstream -endobj -68 0 obj -2877 -endobj -66 0 obj -<< -/Type /Page -/Parent 51 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 67 0 R ->> -endobj -71 0 obj -<< -/Length 72 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>%N"0?-EQhg&3"QfQ&7V>nS9G,P`<9\M\AiVIS'AeP8[qYS*/fRrK<^[%F;1'6 -KV2=?d8ubGKu5'qc8I6n%HAZVc!Edd(lZE[6WQ+D1([ss6ID=3W]8K;UB;ZoG1.WN -N!7*>5uQVh0pk^J;#tW5HoMfL-8H`;MoR[FH":Dn]Y\b+#R81A.&XX!*GG)Nd?*Br -+;XbW6[;7%4tdXX%G4oKoZeR5hYKB1Z-[GCNf2iL0T>EB<#<2=)q)jADe_\K2rbN[ -0TBMr'*Z%P4>@&Km9=\h/M6b=15s*Vl8Cm\$V5rVD_k6"]o_GS3"AUFkVG6X!(7A, -Nk;GVNXd2Q2iON!gb&eF]E0jL"%_STMh9s_*K,JB/JWu5OsV-f0n^OUJO)Qu"KHA" -<=g[?92HJ%Ls"'`#,.br[&mbU@%/@"oYMlWA"_3.%)[>BlG59>C`0'"@m2ug_#W-% -aIrb7iXB=E7M&B@PpJZ/:eJ+2/G)Ut#YZJM'&<bC_C7nrZaB66bUbI1]Y?h$5WOf+ -HkMWt$R8ML"Tu@19YV+f#6KP\HuM,;""_OB[4=kU1oe^*g@IBlUN@J%lVtY63]#^X -)*eo,[YLnX88?7Ama,L1h/fASh7'Nb_Db_=!'ri/K7pDUT[Lnd)GW*3hY=T*@)iql -mNj1k5]UPl3fUR#+MNgpSglOn,KT4*NJ"9gAQ*Ih6'K+W44*Xi06G)+5Yre%PNJ:9 -D4B]+c?5[h0jXr6@$i3NHf$Le+qP!abDbLe=!RkBb+Sgnjb9E#H9)HeppM"I\,6u, -9D8GFVVaaUqkRq$L<"[U_$6S$C1A<cX6Vg,\$"gp(5%652C=`Dkokk+^'"Jp5VK]$ -:rX]=K.,G/h\ESd\@]BjdM7IRmdmY^Fb!:Oe'VrJ012kdl-E^hL62V6'hTR7"WC_I -[HP5D^UW]Op9ZZ7YeOAKFIe/IV!3:u5TaG;#k7;<pXmZ<]H0W6Y@'KUKsUQ75E3Qs -bMK#VpqbN62f$dZ\:JlYIm#OLcUNJ;oW\;[QbG!9ke%AN^)r@D\Fr2/Q*WQ&:^s## -#Md,PK<T:76*p_!/E'hqM)fH.a#O.`jGl<d9!2=@3M]]$+$1u=N3ppC-Ig]eHac"D -HoD7+md=8r]*kdD'r@R<%F3`Q16@VP[!+;":IAi1NNmmipMeZRdroqpGquK7YX2@d -kY5htZi`(tSC[8,/jTUO.8\f`_iT!nlHr*+OOab2W@.oX35l`OVMGmHk:<U4FqI-* -8_8jVFNB"r!f)Mj?8KZ9msX@^#K4Pi?q*i58gk8AXVAllfEQ'FPV(DMDZS&Q>RK+E -S1r$]"+$DE/1`\"FW/0KF<;g%fGF\ld'*VfF=&V&&1V3k7LbG6#4B.M^\!BkJHC3t -BfTD*JE[5=_8T7OfJt5N8dGM1Dbr`ar1S(=:*[Cq"sDRB\_-d/=9AX]O[YTUTO84c -b^C!-d3>VHoNr??i$P6nYUV*EkG>QE#)*Xi:2/(H:&Fs!Tordd5g#0UE+DhP]n_d_ -k)%;K.uier7N)me4eG]%@OjW2`;(W2'l<'(-N0.P6\MPY4=uc`5(&S-:^s5F+B3la -0V_I](n>?eNY4&tQk\44:gDbEY//W8aIGs;coEE;Z-u=lBdSirB/h7KB@,odZ;t/! -;PCHW;cK;Ljs76C9h%t'qH@_Bko,n0p!6Y'Dbau/co"fMDH=,U7dH$S.jS_g*.">c -lC@E<+Q@\qM7$Vcl#NJs(9=`1+'.[l2%Fb[>6\cf$n7ic3,)>.(m>_LN-uF&M5<*3 -!lUD@!L4t;STu"q0R3[jklq@^JV&af*5`[P%L(j9f]>)P,=-kbi1N$6^r"&o>b+`j -%buZ"BlP,S.C7F579"OOBdA:J[5"Jm0.Hirc1jS*`sp*3.(U<!%D+=4>htm[Su#Dt -"bQ<q:DkR^WmQr`%k9QP+)pY?liMYF@BE#D5fO]\ODbVDcC@uc[RqGQ6*V*Z4VoI/ -ZP!\^#hM(]>X^K"n0@bBl<-_=g1k&I8[9Q`T^:ILjarQ00g8LW91C&I5mp;7WgLC8 -@XG!(c/'*Z7E@6>&F(0OE@1s&'-F'MFY9YVG!)\2J@O9q*<U]8%Vd[Y@!RXI>^XZ; -2Y*,>AfiI6FpG]:*'#.*.j\bLI@(%B!(G8l<s)!0"fP[qOZEGMl5C0lBuWk>H[gtA -1DO?iYo3i9a#e&fnkFYG]&/9O3mYlX<lt2IA''6901&=;d]*oD@m1c_.<j6UE&l^# -"eSiS'Z+#W0Gc7tE=NS.X"68CcN$5:VS$Z7C-45*OQ[W:h?VRcSA=3uDeEQt5b"4i -%td\uPnOY#0ZOf8#4/Z_[2GgT`kK1PJmr#oidFa]%C>9S'!8;/@1N%]N.X^5YVOHT --)La]/-TRd'sM.iK_9Q@B4)`V$YN@_o"lHRF0+K['J9R11Da06455X?0DF3JD&(]7 -\2Jr<dV</;`1Jn4rOt7ZDe!A>T9pb+pgj0jP0(g/Vo(up$o[9"UuX2Ll2e'/97;K' -d)f%]V&ifpUoP0h-;2L`p6*OP#mN)B'>fhs$%Xk,-?u:1m7M4OSMR6Nj*&6H7"&1C -Ie7?fk).WM-E6\4/D2%LRff9B3/Jd$9[j,M[c4`24OF3Zj#"3BjPHOUp"p^`\$`RJ -&`clMcX6:1Jg0eg0=n?PL@FIJ[!m0rlP%9(om,PAP,2.E%96sN@HAj3ou(#bjbHVq -)10f@eKsKVpLbS;&4f5=U]^~> -endstream -endobj -72 0 obj -2863 -endobj -69 0 obj -<< -/Type /Page -/Parent 70 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 71 0 R ->> -endobj -74 0 obj -<< -/Length 75 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5gGWgOjg,RktJ7R/f9P%!o_C/D`+$0B4\>6,hsge>/k$(Z'=Bm1muQI"*qCAD_hY- -L6F<e@Q,)470[KlUh>c-$4NflTRbum)@Zkf@6qXJ0GGDh1Ff>r_JM3"9u_/RK\8jU -)mEqDl-*%2.M@;#=QC<[9b84X"KI$Q&!7DD_uhu\fK`.B(<`pl+=Lt[l3sP"G^-`: -1S'NmIOTc5c6,"HMK,TUNish9e0V=P<fUdm-LS0]TS=Va^',cr/+BEj:XVrA^o3'. -[g%\p-EWrF#]PNUM?$I0NaVqO1^pNXi$]$Z(l5p8A!#-6%HEW^`5HXDdPd%/4A%\p -&P17[%V%c\3fSb75VYaO\s<L(9bPkmWou.8m`JAqm/sJ*Z=bUYOOQ9$.1/&U(F.<M -5o`=q1mYA_$R2%;W_"rgM(QQ,W=-L^We2,,!uQtEMF%T9-:%&m`frcNEmbLN9S=aZ -cH)10"YPe5fS^._+S$'PTh&]5-K.5[&.Xg._Db$5!u*MKJXC$g%Dsbq_a^e"gbFe@ -W6#\&[<UA"\.05+6_uSjU(@N[RMH`+TtM[5/!K$l(YV4n>Vo9V-&G$hoN5iF\s?nN -447P+D$,KcRb!qF@/sJuL;C*3O#s%&(5iT2UgcI@1gCg$>H)EcS#,U+,n'qXGj7;L -6$V$@N,>u%>LtagZNX(Q?+U<='a:(Z=pbO@F=f,IgkafGQ0A_1QY\^ULdNd>KuC&X -6%uaAUdnEZ"-DCP9Z*BT3=KmU`])LhSq.N5_l[gn8P9&CIq(Al`FPZ`YWs-4/J^]: -"TsEU]1V[#[=?$&h2n!NlFsg4;JTTC0;p99b>P(9*(ZmI@;'2q-?j]>(u@3AVOu:f -7"Z>:P9?#L<Nd&)*26\75W)tdm:2lNA!k+n;g6SSUQ,f\K*EKMUYd\8JV%O$KcLTH -&lU8LQ!01<.m4T,K;pKVeI`RGgL9l7O/:ooY\2L*2hk>MliUqD2W&O7atlLA/o]M. -F#_&ojEiea6m^FL"IW40G.6!W0G8OEX`RoYYmb+?@d+-&2#8ATj+-\5""UcK6#gs1 -5ecYR+=mWr3%Cj\5SjGl4%g!PS%&#L]jNYj"ebWG(bif4+3HPPNtqu'@(s$8Qt[(' -ncGPPlkrQ_&:s=?$+Joo%7-bm?E7'jW#-NU!<>[t_-."-BFt[2P@e;8OgLEr+Ipr- -:fImO(BXij<S`<p$HFGk#0)=5?Lhek..f6hoi/*ElEF;b=mS6CC=?@2BeZU\2SMY^ -6'/']#7Jg+0QckUORb@h9O2M?W1:.&#ni;Li[M>RWtj[t,##*.n$Cq;;%<,F4@IsC -'3H[A*dV+7cFj`-BYGJh\d'Rtjjtdo<bY8!T/H#kU^&`t'b`E<%Rp@L4j`C66\@6c -M4+3%f7&bmoY"=<i7P(FB"B9nXcr/fQ*pj2cVmb?HtsHc'$tZA%!Wm!WBrg$'MaNo -l@Mip.RM)%>/pnAK9)4Z.P/W3LS_RF6m9EM4X4p%V?/YD,Zm#1a1iP1'=($+?oCgf -K,Dhdk]24/)kgE4-rA*?PKq$\a]<kjPj1ni0!892M>4(cPkd_@c']DJNB[N0Z_-N^ ->-1b)*78LS?V&<t]S?;ShJ7b4O$Y=upC)h>\iE9#OWV*?Llmiek=K5EWl(!moH]9@ -9*J97-+U'RB+(q;1o2t%;f!?!LhT7c[U-"94S4W5+]idE(F4]I:PrWM?">h/8d>cK -?\DE)k^$N-_`f$a;6L*436nP"DB'X*V_b91_6g\#We5@W$re*K]kL:\9\\Bm!.`m, -"\opYX3Rp:+;?>&`CrW9CI%&[XtlnWgm8+b1KHA:->:c,UJa>eL(3C8ZTDmT"dO`6 -N_DP_XQ\A+CGnX&=J#\+).*hu[XdJ)=5&Co.a'PYFKsSb6TY9X/_7MB216TgL]WU4 -N&omJ-=+K+J)f5E4VtqR?_rm6:O2I95cFN2aUZ?r)-8<2OUN$n2ei_&2dF2U[3PH1 -#_Lu>"AFe_TSB?b:WqlG^t&(LoIB`7`IWJ/GSbt.<Z-m^C5tb$Ri<RJ*/s7:[Uj&P -<JOrhJU6MaGk#tkBQI1D4t8k$^_*W[@<H&/5aV'H,,1H;Nlto&+h$7/iLGTOo$e?X -:g-qU]WlY]^0?luH+r?%Z^PqNAB?LF-)'6^M1V^M%Y2nZRF@?48nMtc)64i]80OID -#&nNaO#Uc2#G#)$%Rdkb8nW6:)ZthF^)A@c?3ao.$=O.dH-(Bt!#3"dk&JeW"$0GP -n!*I53"HRP''ih2#VgEVIZSFWgc/m]_15h?=pm%Gbs.oieu@/FY>a`<@B8T%GF?%j -+D!."Y!G^m%!qITC]/miohNNRetrf@^eq)=7W5J`7n,dmS"oXq+K)IEjZei9%aITf -#CqC>c>^c8<Vt3#Lk[$:8<@jX==_PY04JQ'`)(YEl61gZAa\RBR@E\+/`rf]@GTRh -cu0Y1Gq,o[E8e2@2V+T!@r6)-I11_[C"Q=_aqWcDO*(*UP?cTSF+%'#\Ke?0>bXlG ->qcNboA8&;a<1%\NXiX$RO8RUT(@kC\iQHA.f>2p@^:Wnhon@HgZ^NM5+0m15>[c] -9:g4m+1_)7VrBtfMJg[0i^;oYj#h7i3b*m!ql]&:h=j<TY(+OdG';_5a'.q0&&&NS -qqnCIJ6ZCcX`uZ6nf0$2kT.PuEpn!R-0rA7elTifd5^TbFjomMEQEL8bigquF09@u -b95"_jj8LEF!s?!3i?lf)]iZB"2@jIk,ctgfTPkL_lWW6dfltBPp0RSMLF?rk$:X? -,hfr*G_`$_*Z`.b:@m?(B77\%fG`.3fANKTH(Bqg77?bnIH9:-6O0^*`Ip@?!g'M( -IZ5\s.=r?6UnFaLl9qB_0r1*^`L&,o'IY1S,/ZAC!7j%na@%@kUSQ=uM$f:'VJV%& -6/i[[8H*c<GYe^rOH8UB7?TD;8kJFts(OIp7pr/b<,JibFbaEaVg`)'7TN>N?gpHM -,j6Mj<<f8i-KEte:&LP.#(]TOLVT8bi*q7&>mkVN$8>RY@(nnPk$ojq6042,k6=4K -QN[G6INi='.TEd*l4'PN7S>4#X5"qO!W~> -endstream -endobj -75 0 obj -3202 -endobj -73 0 obj -<< -/Type /Page -/Parent 70 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 74 0 R ->> -endobj -77 0 obj -<< -/Length 78 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>%)%3*)EQhg&3"QfQ&7V>nS9G,P`<9\M\AiVIS'BC_8Bc!#'H'Pr47SX).5$kl -5cUBLY;@1j#9tD%J6FkGNWqk>]SKB=)N%.AXC2rZ+NM>g;#7W%@k<Sm#5\G>^=3K* -N!7*"PiSf_^mg:7"*p8!F>Ok'#3-$!P]S[M%>R,3,X?K4R8-'N6,,ja(t`J2M+t9E -Cu@aAVA"0$'k&$j7^e@9j)r#lE"=,pJV<+HN37]ll8]>QehN1PGX*kb"1Z]7N+5+< -1r,-X"rW0B)!L\tXT2V0X:2C<(l$8OddsRn"8`&.ckD5q5d,4*n?iWrZE>A9W'K47 -$*nZq--Jo2'Fc:;Ta1q@GbcI=Jn/E@7]O@*ehmn=AD3bp=Do<?Z4c.2";![./d3Bu -`]&pQ@tlfK+\6/"#,+<K'XS8S5VS.L+O[nU6OT\PKd![6M1ktO&B-R=$;_QnOUte2 -`586:\HpZYE"icLfZQXeCC>C/U%FQ8h1ec7IK]lW_jWOoN_n1A3n2nRR^OpYlL\'Y -_!%/r_$&q(UB.*4o#12?GuH[9nEMd?O7SSjcbgaN0Y.`2`%m;$bF\#]%TA8M^r$Qm -"^DVu[)iM'X?*USXK=or/lNGu43ii4AP>fV[5Pt.ELU5Q+Y)8fJM[dk@#?`S(i#&= -mE3AteFFlE,Y:mAQnPjd?pGuo_Q[/A63?r>2.Q)WnWJk^grLMXm5n5b7hMM&QA5i8 -j$AE:ZI]f6ihNS10MEU*2`X6ml"UX0E83JW(<a/I6B_kt"G@&Z;B2Gj`7,?%pB00! -1qAnPX\,'0$JjYAP$<X`fQ:h`KR*XCPdsoSXc3gCaP\i6j+JS=N&a#<Pegd$g_m1: -^i)M<0h*?>9U1uL`$7BK:Na.?\l2H0"5aX-o%\(Za?uJq'uk;'V`'ZSfRnaTaJ,Vs -V1sU$R0hu@#=6@1q;>,u<bOEjbuh[Z,1:LY?PJb"I9f@P\/KH*0Hjli(`gJ%!-f%_ -ngoeULp_,b3]`YZr%[]T^sWsOHnQ#lGb+:Fj0o&[ll<?rG;JD7>jtp/_6`nf:Dln= -OBe'pe,"2[("U"X(u?4ZaotNTO9RDQd0$m1#JlO;"rJa(_an&9!;-"'ZZ]>?Hh'-, -!TYL/[L>erc%1W6kUM<\#Tm_sE.G@\_$9T=+IZhmY\FY)G7+ZXla\j6\[<MJMQS'H -P((aur"(8eW/Hac"Y]cn^_X-_?mB'"A7YIt7Fl_q_o6AqBj$]Z>hI;*0f?ttZn*EF -cA3p]N=Pd;SQ;Jl%a&uVBIXNG-CUf11=99:i&:j_^^([;i!0DXKpbm)W`@eF3D04t -,LCBu,eD-$LN"r?6kn6?\8kAX5W:*(,]?7?/6tf+G/X*!>_3QB$nHKkWN]o&!Q:@, -P&:?C0QL!cZnjXK_.5$P7'fIAb7()0TH#lr*5d*9%HnMnL19FRbK+Q^M<tV?5iNe_ -fudO*GW$_eNA;2g,Z66S\/-:OJs0Y]2aGVJ.:hcb_l=;Dm7D;Li'7i>"P=07eNOeV -*/"ldh*S556T#Uj22g+'%3^QPQU:$HK*m?L"uRfoR?CR/WDuc&_E+oBG/FXfE[(S, -/]NJN8#HB6-4=6_R!M5d)16Eo1!Q.&K$I"lb$I9u0]3+UP$Z7f(C'"?7S)RlK[3b5 ->A#?D#4UcHk6`l)mJ&dbi*t7F+srK97WH^-gK-b+7qlg\>t`;M,ZIKOMmCTN:H7p] -c^VXOdL$W&EmCp+HbNgI"J22&5ni!AJRTdU4J5=`'%D5/Ym,IW<_Ec.+:UYYQ*?.= -q?:9m_3$i1V9pcW,'tfdA>%(F=f=,'W$K$3Y77SW=SFeTX*Um7B,V9c9.m=Ib6NmL -E<R_ePulH$m?RCE/]ML=?]Va.Fip@6eWu):=3YibF\8Z.8H`@qEWlRHj;,6@UO&$5 -)/..IiCNIk.9^;S<bVOP"$:mCNf"K'E-dL#6of`Mo^S6U,u^-Zo3'eiF&&Vs;k0[B -?^)[X[IQ4j:gf;$=s<oAi2!%[cqqdP'TcQj9*3YZdof8L#;@=+m%2+MB:At!JG1M? -0]6=I$6p.u-nr?P_A<^`N'a-db`e8A=UL>k&l(Da!l_r[B*ojKSkHUcJqgk6c$h"W -8[An2-8o2aJ^fbd.)"L/X]NEghGsk2pn=?HF-^@qUe2fh'%J.l'h,JdM81$-a$b@B -F2!bN$o\7CnMmERI]EL(XYj:V@4Ig.^gXP@*45,T)N.InU!Bir-!C\VFs)qD>f)4L ->)+p]L<E[Mo@!H'$7K`P5DUR@U;NL?_n(3-%5@-(R2il$Wm;.A!.gdVW@&4&_$:i@ -iglk=V^-,$=r#]Ni-hG;24]3:`kLhlK_u_;cGC$rP#G[;\uR+*9>&SA1?,t8#>RAn -]_c>fg3l4+kVGD;2]aE;bmfmr1&F:tPl%?Q@s.DJj4<;156dY<7O3G*^3`1<RLTk9 -:`WtKpS^&e`*&Y^@L/`QRDN.si/=S&@\D-Boc9T/4,XY-em(P_;Tg>)$dllG"bjm7 -qa\_Ae`treUuZF%UK4W1(#o/9VC$Z,f4_gP4*n5,l]h?o0KCQ?fIH5\Es'+ZF6-(# -AS7mc??V.;#Cu4YRHB.(JY=bVP8#;+#7:])B,aK0+d.B4C%&BSLhtW/K0IoC!.EbE -jl4g/?&&<(F*cCeTN[CSgaJ)#GLIJtM4:tq%cg5\,mFW,0im1cb4'a*&`KN_M"hKP -CcQ-O>)cZfPuSl=/T$_5^@$#aB"->$ahuu)gQI<i9[[oT&"lJ4aa;r_n2Cl=m(pBK -TD`f[=p'+2>8Z@DCgC1_Si"r>JA#U'q@S[-@l3Pje&B`_8q+H,9@V.q!uSHrV%a,c -jp`Ho;TK(&A$l<X^q'r3jT^_S-!E9G\>kD&J>h8!Uo'/>:l^VqT4m]t%KtJN$3l+) -ZXo*NUU:,[`8lqPo*1rd_id)uY`Zo-gM$`R5hOm!<9^O;3:&+gc'FfY_ZYZ3q_!27 -:M>&)FPb>-h^Eq8,Z\*!fME*)-)@]OXo^Z0QNppFh.6GQ%.7-UgoV+LGbE:b/l;I6 -o\2!^$VgW9i`\:%@[TZFgoeBG0;Lp-eH0SF#HnW\lHE(;ig.S.XK*0BM*At_)V3pW -To;#8!/<.!^1[gPgE>!-#+/U;l8ri)!JLAU_JoA^Geo7%8;k,ANE0^E>1YEd?VXE- -DH'g"L6SYI3^^P,irBSIk('+^.A?k~> -endstream -endobj -78 0 obj -3331 -endobj -76 0 obj -<< -/Type /Page -/Parent 70 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 77 0 R ->> -endobj -80 0 obj -<< -/Length 81 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5gGWgOjg,RktJ7R/f9P%!o_C/D`+$0B4\>6,hsge>/k$(Z'=Bm1muQI"*qCAD_hY- -L6F<e@Q,)470[KlUh>c-$4NflTRbum)@Zkf@6qXJ0GGDh1Ff>r_JM3"9u_/RK\8jU -)mEqDl-*%2.M@;#=QC<[9b84X"KI$Q&!7DD_uhu\fK`.B(<`pl+=Lt[l3sP"G^-`: -1S'NmIOTc5c6,"HMK,TUNish9e0V=P<fUdm-LS0]TS=Vq^',cr/+BEj:XVrAL+%X! -X+nl.-EVhbC=X4a#\^00"Tu9]U^X?o5V<3@!7VcE0jrTK%?WVJjGmXKkn18>8FZeY -6#oru+Msnbbsj=,AGA&[/!Rt._dLA,NG_Au)oSM%dP6c7W\!p!lqF>h%V$pH3jW<5 -b6*I'm!bAI1%8uu#3bZj%0aRu?l?l0!5^Z'JH4IWNM>W&)b1!Ll8FSn7(Np<UL;5& -ZX]eH,Ko*ahDldtR,GidD4;4rU=-j*_M,f+P0T%AW8'/P_jKR?N^M##K2&R$iAi:D -;Wp.No)S&1%YKk\/26a!5Vim;GhYGZ'GV68N$GFA.0K\kC;X'f&G%RcQ%^LINA8)A -1/-qo:cnj_dZ?DAc23*Qc*Mh:+X!bqE<a>G#cSdOPJCup0Auou"11@mC)TCD%#1Pf -FW1c:7eKD;A@5-V5t_]_AGX0&QJE/b>!jk;1K*p+h^qe!JDGsaXgHK-i:(T!2pO@X -2AdcbaA=^QUBo/[<4CXUT@J*!@_[pjXKa?K;67fW`40Sm-Os"]HS=V%<3n19&]6dk -ihL?;];^"+A"$I,=CS>o6Q1cU;,3hh;MZPRE"FFZ3--/H280ctNm3c$M[VE.^Rf)c -/A@$LXM%`Q0\DK._T>J*bW:a6'+6X8@?14Ek'*<,%D]NU5q<@QONYYL'f;dE@U-Z( -a>UQ<hDe#]Nr#\daRhc8Yn/t6#V:jJSuFbZK-7XV%f-tL^gT`009,bYKT[m#6l?4] -/sp@dq4;UP\R(tb9A_-PTL#1)QG!)c%CEgWgC8d`TVKiGD>q<+].DB@!L_psmY.+@ -2!PMdRNQ93<Rn!tDWBAjl>gYX,Ha;iB%J8q7'1UN#FI.@PThC^+lS8'E5ItE]&@ML -E5@9*>-,OC"Dofb\h^$AMA$=CD8d7%[j6>;!D>^K%Pe8T!t+mhZK+fTKc76^f_n*- -i^>>SG8qubp.re+/HF9>-WC"i%#P*6C!l@TVF]676-060oRhe+e.3/4@sX)I(5(W_ -)e3i$"^nGM6Nl*OJWMfXaULP72#\Cm'Pr)6<&-sH%MqFdIO;kXK<pet)::Jo3Dq:V -a#P(ZRH/Vr&\p&SOPgfc\5!<\,UUR!pE*ThZm%7,5q@Ue+_5t9,go.a_\jgJA[!fk -5_(tKfLEfT/BO;Y/nRf1SKU9q09Sb)?nXum@Ui$J%1>iN`l&f-,P8=(1(@K?JG,$1 -\J$)_rc+upaM&5g-B/;-(rj@")j-(u:Z0Mh*sl:6-1'uaZWIc6H36.**/%-sk^c4A -@kcC,1/Lq8/V=rgZN5`@S1E<H^6JpM,>(h)dCC[OTXR=g,l\$)DH]e,DaA)Jm@]Xg -4WrD0P\?m/";FambJKYuW9#Y"<.[h;WUCeWAJUQYnpj[6@mVXZae70FJQ3SP*f+WK -3E5R/:jRaGVI`.a<>me9l:k&O<@Xk&G*g`)%RS:!1HO&e>9\mP.>tEP"sJB>bW(.F -eQ@$UTod+-G^pRI:b/6*-lH-dq&7U?2?oi2>1Z?J?)5hdY;Pa^UF@!",IN5k"Yh'[ -ODIL)Z_MpKTIm)<1(-HIBsBqC``VN;;\MfNJ2UH,:?L(h..kXm[B?PY4,6n:D.'m* -'!PVfE@g9Q:TO+#k9,;6Fc]`<1@,n@R/h3[f>Xas-.%PSAK9iu`$@:WZl+LLlpQhP -C^fT7E/&nt'lL;aGdRTFa^oS)_+6.)Ur)m3#r7C#?ti'N_&5nI%2r)L8IM2u1o?cY -QR;gL3*5ZC?fL:NYS;X4+Q;QmHm=5o!\_Fsc:(<o?%hU$0u5hT(u^b;LG%TY/qN<g -K:@(9EAfVl3&2Uam"1-rAJ,0?Y7"gOnW#<m-k;X;n"!-DK@*FA`gA\#i=(EtVqr'r -M5M:4,DZDRMY0,c4G]U"&t9/Q%3iS9/#Va]RYdVU-KNK3SH)la?tON+`,)"X!XqVk -`Ruf_ljt3^D.N_J2?n$d/g5n":Qc#L/qFkT[)E4XfBI#S3!:26o%AD/Qu]pA/keZ' -*I9BYB/mpSjUbph6&or#->,t%*Fl<sNo<\:`%:U/o>5f3(;r=Ce?tn>iXgZ;$J21\ -&-/[3UWJsCgCLK'"+@V'jd@pXqaY@kK=q#@2VHM]mquscgTpNjiZhZhlKq<k<d0;_ -gP?Qk*qR^j:PSJp>M!q4c1"BBT)^6co6j.^!P%nA37lndK5SP6FUrs0[/;`tnVuY; -30+a0qlh"uh=\dsmb-[U4+V9U.#0f+Drgd'Pj'6#b;fe[jEhR[D8&l][at<7!CR*5637~> -endstream -endobj -81 0 obj -2644 -endobj -79 0 obj -<< -/Type /Page -/Parent 70 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 80 0 R ->> -endobj -83 0 obj -<< -/Length 84 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>%)%3*)EQhg&3"QfQ&7V>nS9G,P`<9\M\AiVIS'BC_8Bc!#'H'Pr47SX).5$kl -5cUBLY;@1j#9tD%J6FkGNWqk>]SKB=)i@7BXCY4=+NK(fUH8b*E]95BV5'0g`m@\I -$Utm`3E"c`&.?HD"2M:\GVkr/*56&ES^6MAH<eio^I=rN$Z%%RYB&*`&/n6Z!p9PK -@542\Al/R#H`6KBHL`e,Zt5JdmK$Pphp:X/1Q8[,r&aB"5Vil0PK;YkO(oLPKFhgA -&.QM/AhLq&?re#V0:T9K[Latb%mWF%mh!600L.cD:OF)>_P*(&&4Q`R@i<:[KJ=*' -Yqub$\WB2nnq7*M*#M!T1aa-X&hGsOZu;a*r4EMDq^BAPoMI*KK@<TiaO.)-)FB&2 -F</DbS4)O2:g:g^_?aD5)bHeuSh<3)`(LcdO>E@V]+`tL/if]T;YQl)b]c3?ZfK^# -O$TQ^,!rUQ>;t!o'_*qFZTQ\g:U*if2TU]4h]sBH"QqS8'>3p%dBjnkk>2Jb`#=AD -h.&%OD_-]$NWMc,3X-f'kqZ$:JC601j)E.&Kq\"W0TLbni[p-U>ZknJ<n&bq^2"!h -)oOVi6XMeg"bgDfej*/F=bCtO10QT,X!ffUMS^>ZBVis2gAqF;(1:!D:P"7b>=e-? -D3/O_9i;(b51B.I,j&R#Ag8p<224$lA$&]0!8m>O6L;=%l7!i8;-V?,3DQ/WRHBN6 -Wubh)oRQI+cU64U4ik>,.9$sdCQY8m/&>+LPCt/\9X)/c=(8S%7u_2l^'PTSK%sq? -b]Hh3XCBW?R3LnD<6H.N3i:$"3L-\PZIWnu]a%4e0#KHngO4?E7<CZJ-8O=E1AL2J -`qb=%S#6:nTliKXW)Bt)h2c>.+@3P7>Pk*b_:26sZ1ArVTsN7qI8a.f[`g`oC:s/1 ->,:,:EF!)57F:PV2B@]c\9:T5B%cp\WG>9F`O$K:QIZ^g8h^'!cJ8BKe)&oP"64V6 -pQauWGkrHQN/&7"WIQ0P)?k\g3(Fh^LFGUtV/Ef`@o0_h5L58f?_`.m67GVO+9~> -endstream -endobj -84 0 obj -1186 -endobj -82 0 obj -<< -/Type /Page -/Parent 70 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 83 0 R ->> -endobj -86 0 obj -<< -/Length 87 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5gGWgOjg,RktJ7R/f9P%!o_C/D`+$0B4\>6,hsge>/k$(Z'=Bm1muQI"*qCAD_hY- -L6F<e@Q,)470[KlUh>c-$4NflTRbum)@Zkf@6qXJ0GGDh1Ff>r_JM3"9u_/RK\8jU -)mEqDl-*%2.M@;#=QC<[9b84X"KI$Q&!7DD_uhu\fK`.B(<`pl+=Lt[l3sP"G^-`: -1S'NmIOTc5c6,"HMK,TUNish9e0V=P<fUdm-LS0]TS=W,^'-&2P/`^e9Rq""#&^dj -Rt^sd:@<h:>1/H[!C/n6_!!IURg+GF8rl'-5[G0."/&gONrqr8&4Ve`D&^M-b]OrG -_,+JMKFo-''..1a;T8h@j?,,T@mK03KE::_&1"".;]l7BLh%A-k\Q3MW$C(./L"jB -ZCB%#oJ$e@6DQXR%)[>O,f@N1U4\5>J3Y.Y")t[dMmLLW'np[%Y,.o"4LZr^$4&pP -;%XMM1srQ"BK[J9SF%(f_2u5>;hEY3:XgPA""[>lAA:b?"4S&7a]%R+:PH.*C4T"- -"_CJ2;tWXeMfg^t<)"*,;]<q;SROJ%iIpf7:R(5J&.N_-%:W1U<?2uU$=tMmgJqf; -L<=[N6XS?N4X2*"2[jV8cAkVg4LnLP7;7`>[&n.BQ!A6Fd5Pnm*03ZBVWD)A*S3_e -[QJPS<\AKlB*8]em9sJ5eIQS(QNd[7?jKqI#iiA<.j\4@8Dq)iJV_%c`KII`1lPo= -gbOoKBRDQh@grhuNBpi)Ta#fSBhsMnjc+-&R8-f.A_DbHRHC8hfJ7)Bi9?k@F@0.K -#1+tqL8[-55sj,V4^*U-)Enk46u-,G)Q%akQZ5L""rDhtdC/_.DV&uE^Yh*ErPDE1 -0#tTAn2a%%^C"ckVo)r#+GhT,QuIbRC>?V9%c]m<-rU-HlD"g]C.^1Sh)(]Y7D27S -0XAq7E5"'NPb9ak"/oD=%C1N&15o]KlR0Zb(Q^_%X`2oRYKSujd1/OVALJsX87^+' -?=IHi2sq1`(l#l2Dapj;K?gOBap@7]pgFDb2@O)ofYNN[K4GN%Z=)#b$i"9C"rtRp -1nYciG]+&l\;rZn5k>o`3?a*iaf/?tqpUsf$t^6VRj;VIPN[,uY73LZKFX;UOd@Dr -Fn._/d"_r91CjeO!/!$F6'D'_F%LWeL/?N]hqS*$VC49`@)cUWF:89Ug%bggOS$a7 -aUOqs1VFU+oZr);KB3Z^-P5R5bZhmm_9=a';gb;R;@k"NSef%^^4npm0Er*!p4@hW -)?Y?[Fq;NL"itKhi4JdgO!WV:nCeij.@Ug'bf!%C*gk0%2?j`FW'cq[Ath>,:T$T; -1IqH6i'F\m0-iKhK,5,NCaUt"N_.6r@ejMRh0g[X%`F$4p/F?-1%;=c9.;Ls(@bCG -E`Q=5)/)iEKC8pR`7Y?Y!,[?ZH@I]17)Yas;%2Z"0s,]c*h[3N<EYQBnSTbl#S@-# -S"Z%p/ftp/B`$mgO?t)L<s%U?$f>Z?H?,9!8pE!,@i;[sTp=DbLh?D<+E]+#^qtiA -nmTFT@go$@n=1f=q.$,S/qF>g4D:>hT\*dI#g,ZL@l,1(I%d,#3LbVb*C5YN!J#9T -AIpXU;C7(FOiH$0V^\,S")H#91HLE-3FJUTTQ:UL3>o"&Cn6]?14bWqP#KMNo]ch8 -%>id5cpLoA_n^5?k/qDQ\3WbmZ0%noaJ'AY.btE@.&)Isi?)SG8kCOt,bX3;)<l -i/ff]7EhouEc)4^a=o1mZmiXT$LA/bX!)'B1)NuB#Qg*!O2bLUfjek\TAbee7V9`o -La3GG71ZCFqRRf$8R:,6qBX-2b7P;)<RTQ"F/TMY7)u2s&nscn#:.UC8jjZ:(ig'= -$o1@5nFhEh-ot1VX'D[/S0ZT,O0S]0_5QqTk@HO\d\bTtq<o9[8`5Af+?<Aeo2OXj -eYi'EWl+R05oT8O#/K<obL1t`$92q!:;URCGXVo],XdSl<e/JoLK-^;WkVX*]#sk) -QiTHhPbrUl#<9dAK47YK6'T0>Mi(qpJ4U#S[:I61k`r*AHSfjc<J<h-A3lV^R"-YG -=JUh0>te71pTuhQ)3]G8ANdWT!ocEp^E1gUa.#lY;9j<OnOTlrIag@2ged6_&qi#* -jP\G'H1;DDZmLbLk'KZDY8]3m)?gplc!ADO=^mn$ajKDC^GkHVkZP<mX]bijU)"0? -Q)o@(-J/so-pWWSI0Ki!b8CZjkG*VJNic0J1PW3]:<CdXTqiDNj\4B\?DUaIG?$0_ -<e91j0L8G;8qtSiWO6WF>"p-c1JL'acH1kNaZMTff,\Y^MApT%dEC9b9FO[m]-hRV -%_<HHZ.u<h.A]/+&n#Tf/Z-l=7ED.g/W$afL>(<LSHT*I`OL)Oj?qFZ,uPlDB$=MS -ZJ![Na9[hl%B;,mGejKP5SQIK~> -endstream -endobj -87 0 obj -2535 -endobj -85 0 obj -<< -/Type /Page -/Parent 70 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 86 0 R ->> -endobj -90 0 obj -<< -/Length 91 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>%)%3*)EQhg&3"QfQ&7V>nS9G,P`<9\M\AiVIS'BC_8Bc!#'H'Pr47SX).5$kl -5cUBLY;@1j#9tD%J6FkGNWqk>]SKB=*/[@CXC2rZ+NM>g;#7W%@k<Sm#28lqVUd@: -%#5IYV8,o!]q#T:PF-ma@5/]0U&u:Gl>/3]$s^-,PfnF6)@RugcS"j+4GXIOo9lKG -HA\."ZQA=\_JD#tc<b!HZp8.YRC$-kfXel8+l]4a[Pu)[f&F3#fG#+9YPM-4V4i]] -bUkLfE6pIZkS+^j:0[3A^*@^U&.G^<g?XcME'PR#_[,Pm]s#mSKSG=K@1"TFnA;fO -:+4mLL'$R('a+PZN?Nrept$Yt04<Qo]7V6K3'-NDgbXTke.i6YTq$#C_@%&)b.pYr -isn4<!8'5ij+'BONRF!d(bc'0]#6<q$H*he$Uf%>c@LLRU-h46_WJDsMl,W"iu=TW -N3lF(1HnQ<K^q-E>hV3W:'95?N8p#:q[=VJm0*\b^hO\jZh,b(0I%E=/^(tLC`5X( -$mc6SYiFh7%?=9,"Y*r=>dUAa^iO(pF8/Sn9(!8)4#"RKLsn3s5SV;7F8FuW\?UH+ -&5n.EZJo,?890ZC&_Q=hL"!pU@bBt_'!7kmdngsg2./ZfL:'o;[875F1>c7;4f)mG -ncXUe[/o%sK1mGP.,Hc3-pTBg'6lg!"sMhc*WuQ>dPqR98B*"_Jk2An%3\hTNJ0&a ->2:un[Vq)Sp3Wus%2PM7/WD`;eXtfH(t/a];C$adi_c/Ae$V(i=O]4QJ8hkqCku\i -i04SohD`<HeFm/YGigrueMJ"Y12*K`!^h.5IPJP0'sFYq0rT.tft$=`4?/cC&#ibB -8l)XrE""97Chl[k(-OZSd,luV4Q,4[:L;^64k:$5'1E"n[MZ4@AQt^!<TFD,DRc26 -c1!M@!Z8CpJ5A?:EgsT4`1nkY2`m%5jHtsG*90"O(OOoQm5&"Nb)C_\3g_Tp+E)"u -/(iu@3R3;e3\27fFYVGDU?+h&MpTW^CtD10iJrpHc8,C&B\YY.Y+<cU__L-[+lF&e -&8GT?@L+q@Bde_!@U7jUnM)Q<W\78U^'a0&?_gL:&lWbbaoF"gNEJTQVDuVa!'4Y, -Q'8M><m+WlDe;\jRf__k5a\T7=0FkL\7"OJ)DXTn-BX1<L3!hj],3nSnfJ%BFrCsC -/N!tT+2mrL'[3lq>4#1(2.F)H%7=;N"L+31@r/tIJQFeH"R[8&_Apk\*Gl#rpGV)E -%Mc75DGR+b2eC2Rc5Y;=$N[q#LA83P`#X%P3B/<-nIMAJfj;jE=2H48m[U)'EmbD: -*>UJe;VJ*/!9)JBG?gPoP)+@D0t.g=g3h13b(3'j9a:h_*=NfE"Y9Yh5blOA:O$Sp -Va]c/d,Z/(P'LMi[0aurj:tH@dmL(M;k$$kXB0Xe33QSSQno*Q%ml(5#>#F1;!&V@ -RF=2O]lF>MJfDNt2_Y9gdm5c^7bXp\2$=4q+VJl*aZB?YjiSVGPTUF6!BgSt!&GWq -XZ`,COsZADM8@UgR7iWeTZ63Nd&&d`dKhE683ed/OB4`*e@^=iJsK<g>t[OU.\m@X -PG&8F?g1iLVa,bidj?)2JVlbs'\*KlErHN8m5q43Yp%RWJ/;qh1(1/(Oer\*7@EKF -7V.tBR8j24UIg\o6q4"OW_SMp3&Do.m5!5p#f+^X*t*2o(::;U8SR`]V3RS!7t>/O -)k4'9op1omg745h%==oU@\_GB#b%c15Htqh+4Vj?9oZqF#%VVP<J>`?OB#Pe<INWQ -,n!j,I>Y-3qR*it;.H[R0rB('PZ)TL$7hB>"ei)^!h/^l/"K#*O-NpR$Hl@"rD0FN -:4!&pn6$1KXK(UfSulb9NNF1c[&K/E>)Q<d$*C;?Q3@_"4!/:+FgS$bqV0_n%:lUN -/Z=sjin#;b(I;_N\$e^JgoDrH'?ETkTu;Q#@OOjk)&+?l;Wef#YQBEf8HDp*3YRZW -=@pdG,%b$ei;=c<MHNY*Kg:8*-PI;/deZriKV8GS&KW>6@4`e9obT=1)8iH?,4agM -cshBn-FrS/-d:NkA>GJ3>LP_G?@pQ)NBS-)/MH1Rkb,g<#@Qi#TT0W5:jN``_*B]p -^sXGC,<qRLgbo<9b;<;Y:^lWc&N)CCl-XN?7VLF6UUbr97*2IdVS`mEF5#"g!aD49 -cmY$MQ3*gd_'A*E!RN8"P1%-G<AUJCcKt@?ZlK*_g)YL8o@k_4@K].$J2u.@-UkgK -:Js$(NRS@p`9D+nFL9J/@4X'5CH-fQFW,PT[mrgOQ+s@oVN4o,p&hZ_V6-Z(RC\Vm -:,EEH!O_E$g%tokln_p9G+P0tl,Q80QZojbY0CCahe5]cEO^/?8CQ;9F[Q,\[h)], -L;;OnlA\cq1u&4"RHkVCh3"JA5*=SWkonSO$bQ#=n^G+FL!rYnWEINch?D(djj#7a -F:E?Cp32M[Xi[bhLD8US#>4LAUVnua]A@mEQ0\u5$\?K*21,4#m7kTj[l1MRRKmKr -mG5lDM/q`_?V,)%/ZCbN3].k/V!r7td!8ZCh45D%m4PHfo`$Gup0W4M/bj(sD`lqa -T$VF6>=,n"jl%3fVQenpV=Z(dd+qWfmk1rFH@E`r4D2BLm?+IE:A!U)$bUS12:qa" -$Kf&-DY5$,iH3rtE4UO\FR9=n]Y\=>oIILiR\e2TDdDKE;m:)`M<,E&3P%AS7/%^5 -ZF^WNnXPZ\pYI:c=s%7b]pH'nDeZTp[qRc`,MR@%-)CLsGtZ\GUjML2n2n+`itM%2 -m!c.t3YpuMHahOR?WlH<F$o*G6eQ>T&`L=9F6T9ckkYhIVYtF#l.4>WFYA'pO#2Wq -3;634r3-+KDasI3'_if^oac<EXfC!*B^AN&^d&S@0J:4Y$Gs\g.#\qZN#X/q+Mpf# -^qs&%&59u8(rNRG_sB]=bX`jd8rJDi?V%oM5[krH=t<=qKE@[`MZh&DE5t4Ua,Js! -9%<#-g-,W"5(i33A_IR.kWNe&%Z-2SJEdPW=F0?u#&1;3W_0:Q/0Me@+[R4n_@.V6 -kTYU0,6B\HJik:\mU"ml,(q;\!e1]A9Et!L.,pNr5SXaF2C"q/#,Z;K_e(:#npo*t --Uh)>_N5%#!>&)c-F"!_d-h+SJ7&s.%u&UGd3T>J1D!q['%&cOYnl":.21)C9i1j( -:u;hH3=fWr."[!TO]htZC*Jcb&ogDSZ">@-KZ0'OdEtusd9@El@2+hu'*:lCZ#:@N ->oE/u(XZ_,Z%EP'G8^YR(sH8)EN9ssJJ-s_6>R8;&Yg;mbo&6C&s3J*-.XFdB*A?X -(?W@7b;UF2Po\7F*Y;$N.fBs!miG:e(QmGgn_PY@>6cAP(;^_.6AVsenJ0G=++P'l -_D*0qc6s;[*rp.%EVCUg9-^0P+d';\Jgha]5p5^$&2D9Q1(,*8>nO@g&e\=bM?+<p -9d.r+*td`[dOQS.'XLZs-5&6cEX*mG5:4g2-*i@Lle*H0T-0:u.C#6e_Z(mUcP&W[ -m';lu;K!Bb]HZkZ+jpB+Z1B!!XV.O.,k<0,1$lIAN@e#0)3R'5nrGB.I4Q#_&<`qD -EZHG-0.&GA-*jd/EO`>QjY1`N0!a.S![oj8kq(8G";<(6Oi8)6a"m51+[U6+P(>@9 -'.qZX*qLg/ZRn#_6SgI%1NQPC;Y;j;?SJaQ01(J=',M_=;)].C,1@&JXOAu0l896- -20(9,+t4m["ZLIs37<L7;jB6S+>jh%,*PG0ZMutK)\4^m3A[]oP/Sq-]fU7G4#<WL -:b`%R!W~> -endstream -endobj -91 0 obj -3903 -endobj -88 0 obj -<< -/Type /Page -/Parent 89 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 90 0 R ->> -endobj -93 0 obj -<< -/Length 94 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5gGWgOjg,RktJ7R/f9P%!o_C/D`+$0B4\>6,hsge>/k$(Z'=Bm1muQI"*qCAD_hY- -L6F<e@Q,)470[KlUh>c-$4NflTRbum)@Zkf@6qXJ0GGDh1Ff>r_JM3"9u_/RK\8jU -)mEqDl-*%2.M@;#=QC<[9b84X"KI$Q&!7DD_uhu\fK`.B(<`pl+=Lt[l3sP"G^-`: -1S'NmIOTc5c6,"HMK,TUNish9e0V=P<fUdm-LS0]TWLi]'To2p_O;?,8Mh8$U'Qq; -)CEOo[Xs4LJn1p>M?$HqNaVqAc*2h>ata)%&BZd<kcd<5%0J+q2@T+hdhiOf"B[ZQ -nV\+$5f&>V)53u_W:$s+6qH$m"&)$=%]fMV`i3?E+;kCKKT;_2K9S^U8$S6n0T=t, -$l6KM(dJk6+g>f7bA13f)6rDt4MnPC!6R2.Yo>Y_Kuilp)`2MEN?etl!63b%A#S%r -`_hD"`)(5WA/n.=oT1j=@k0UY9J#\]4@$tiC`"L@3eKT6,Il)WN+5+<U/\A>+Y;/A -1d!ibb?D#Idnn!G3lA@1?UVk3e-tUHJXnMI413Lg4B<[7B+rM]\6P;%o4>Bi:(HRQ -43$rY,t/<=Ot=m4nMNZL>r5C72NA1s8J'I(Wur@bN,p:9fb'=_1(9:.![P#q%%927 -p#IOm1IE#C/WCt?P7W_kGj+%p..+Yag_L7\4XgJX=\t'N9>65d"2d;_Nak]iN]9Z? -*jR5pHDD*7%2=VbL'q6<!JRkABURMH5e,ESG\G5WicqQUjGhe?nY^+=TXl`Z+TPL: -1LiOUXD/sG%0S4r6l-'0+TQ9`1,%dAM(VBrK8[tFUb_D9GlC&iVXG3Z%q'W1acka^ -LuiYU]/YeY_+PE4Yri;JCk2f,`<i69CKP?Z:<ErUX)*C?f8FG9j(GX#]$F0m5rls> -aha(5Cs[hTcSrGKHl#*`@dU<)K2>IG()[>0rD_4m;2E4LgFAk5Atcj/hdG/(79r]/ ->^%@EB1e%TnqI]dh[8e_A=_0.]nXt"d*"Nhj<;9%kmQ^tT783k)'J"7=#b7Ykf>KG -;Z7YgWtK#6)5Y."\duU[%Klds#dg7&f+"`'@%ke!LEP$&K-FqWaCH9spT1l/Z#iYI -<21.[VRG(0a&,G`7k"X=@uV$ZAYIJ/+tu9c'1mO/_:64^'V`F3UE4I#rFi=;A:#4c -64BkH,H;=5W77b'#04"1Wl#<U=#h$(M%CWF16.4o88V%Z#o>tJX;oXA,E2mFF/%4m -Ntl]>%1/Rl7AJNBhSZ$>MFi:/^ec(HW\,sg[1fr;:E<,B1,MYo:+>BW&m;R0B.^?? -.<955cEpf20;QNX;!8_:Y\"?*\]DMu>(ZjE!0duU8O%;%"dPH`8a/XgLIM?q+R4AC -OWc3O`3'Li]&$0->qMC.W/lqD21s!/0UQMJd_hGc1rkI?(h@f,B!c:]l:s#<OPn8V -"#Y)bh6f6ec9[b:KEb1Z(eQV;$3Nh<0#>mOL%[Ei>=>T1Nn.<rH0IJg]3K^3Yl)$e -"AG%(W,9?.KuKi?d:.13PcAn*b)k6]!U0goC@sHH(nM2XC0NH,[L0E487,J\>6aFt -OFmOW97n`rV@64fJcL$$"*H@,[#HQ(^hDiP]&'7TV'J)_Emq"I1Bh0h#_JF36L$Tu -9lAe5["OO$WFJT!'^@IXY\d)`'k=6P::&F7JQ\uk6)t_EP.2E,Y\1jRWV#Vg<B@0\ -b,ob["]heXJ3d9Lj^P4>P*gl*d7pZAI'M55T\/Oc;^sYVUrd)C2gZ?E_VL6Ue1+q: -"!3aXh1TJ8)K49.oj\i+1pQ]0ce$?OAHL\nZK4!TK*!K"XQ=]8[?fKL3j!+5mD#]f -Y*E+9>4=-b0a;gHaOXRnDD%KlZSqZke@Q03=ImpNd"p(QFL,B/4j9u$53gT.AT]X+ ->J8tcT\fRR>jBkTY4SahhYY?-D_3@uf:p.1X4_kdNUX@LK*9qf'6^SgZbKOak[;!t -JoCHY9nnMqhj]s6S%]-EeW^nYWaCT"[6LTLQMZc\"bbqE8\R0MWS1$&a:C(TZZkd( -d>$B'Cd!OaFH[PHgk/)Gn6\Z)d[Jpr%?YE)6,<,E[%+.G'uM(b%=sTVKB!^dD5J2- -<SIjk&4)E+WA\*`h^CF.^F?Hf*]APOOLh=-)D)%h"\9Ri"*^YeD@J(HY5s>@](jd+ -m5:o:J03iGGD.].;?pAe109@PTibo^$_Xt"Z"CMt/_DWuABP9mq[JWSmZb?:)T1c! -o02@%SHV`//-YZ>*V/`Q$nZEMjGH!U_dtYq,hs@AKGg7c#%l4p-@HcV@b7tn[12qM -/r!)CT+>(+="aMZL2>h3l\rfSAjsr1I8#ssndNSW+)b#u;6VOA:='jL2ZaFdPtiG/+<U~> -endstream -endobj -94 0 obj -2512 -endobj -92 0 obj -<< -/Type /Page -/Parent 89 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 93 0 R ->> -endobj -96 0 obj -<< -/Length 97 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>%)%3*)EQhg&3"QfQ&7V>nS9G,P`<9\M\AiVIS'BC_8Bc!#'H'Pr47SX).5$kl -5cUBLY;@1j#9tD%J6FkGNWqk>]SKB>(lCq?XC2rZ+NM>g;#7W%@k<Sm#5\G>^=<B' -$jOTW5uQVh.N/_i$dl3L+?1@#js+<!g)r6/cA$sCc]Q@+S;]T0W.UsU3d8)#!su3W -D`J_^I.KXZXE6CW$sYS[[,K7fR8(^h.?d0J+Mher(l$8OdZF^,K5qg,/asGg%*q1( -15mFpd,YYrR-$69NYok,$nh&?3"2L$dcrm=9:#K:%^>(SNJ"S:KSL^iA/YZQ6J0UK -YEOu-_ddZ2&.PkEPj:KK!9Q*InX?JB-#Hn1\&%+9p?9M)CGlt5a\2iB5cgo_OY0Cu -L,TO787J(m"2i"a$mUE"3<^S-fG?7N;bG(^.a(Si2%;NcaG-dpC`FapW]&V78A`4] -KeO'H"pMi<JEfm\N+s;c"!Bij%(+)j'LQZb/J1C2JD;mgYpEHL4=Q0m_QN4Gh)qrW -RnhJLNFPf:2N's2"ZEDRf%c!R,1>A*/sK2uNUFuunMk$Gme&op;!@C/eUf:9>9geN -*)`J^F")eU9S"8!!<m'S<GirEnBBEML,Y(BUp:imJYgSJ9CO290t.b+.0g"eW5:@. -d0%L8h4l4THIbb4DSn+B1V/sfn>ppj3;9Aknr82'+urhi,`O.XBc[@1_!T$]*$mR0 -dPqR98B)k\ifJa=$%i%L45:CZ]"MGEbGPcYE[\sQ]MASZ:q1RA>8t%3L!VqlY)I\j -KG0%#:s1o;FTZ4M*"`>Y!JV*AUBt\P&.'ut]+F5P<PP(kiu$W6NKj%s&7'DO:QmE= -Wq>U\m[d.fjTC%Mm6<Cok7]g9ZiJ97H%lX66*:+B3=]s<--?Y&Ru*t(H+n?jkILSD -e*erM(FM\G[J_+X2bq3$KEH;)UqE*rSi?6Q7JGU3I,r,O!DlLP(sG_SCTt!CgS4GT -D_'-*]mP9+MD//@0jAo]Wsl[?h*6\F41D0ISHZ9g"4$`^B&<iRK;rD1:C9a5mKE>* -2Cbg>i+.6YJ2SJ/_Lu:daDu44:o&mGRLe^k=jS&WX%2Hu?b=WX7#88jp+ft1W\Z,> -oj/B=*`e7eMDleW)M:@1U6[U_5t^g>1PU"t)=p+,9=PZ;!2L2n0MDY*+e8f/?l:.j -@1NTB0<,*B'$b5Y3cS/Y!ls[!JWZ1/VK`YA=Nq`D6E4%:i\!ZDK"HS)4,$.ke0i^E -YG#FA"9?pg,?9V<i@5@Z0,We@3*@8QTbE0[8`%C1P8r-.Ft>*@R$T3<)oHo98I&B( -L;;H*>/3*$!Sf]9K1dB1_$Ph7Fr6V_g^!qR3C-L"gV#"[Do!?n%*a)C7"CX@+t.P$ -@?r4S0ZOl:Que/jkVJbhQ?6V=/.KF7'Vd?o=@'_]G=4U?XL'#b-DN-rZWrI6UJ@09 -#WI]U4?^r'YrS]?St$+!E_Vt23[5:mQH$%[7TOCA<bQRZJUHt,<U^lYS#M7bUbg%< -><QVN;ii,rH-Rl_4kl4s@$C"s6rT`u-is4<F;<?QMA/`O0PmH&P)IFR]##krS"C@n -hU<:994J,DD.STR)u9s\WA&E%oV%G#dMYZm<B-^PG+25ehaS3c3ep]*NlG-20I'D* -%fpJcL!W+_JUfh_2/]RK!-n!Ji*EE_6EO:M<XRl?m[UV$V:,ag9W62m@$FR$ds@WH -lce[iPP-e4G`,cUfJ]e\K!hWU'3D4oD@:V;`l>V;(MeG=U%SD0V+UP"l(%(GoNKOD -)>+L(l48k4)R5"#CLZQlXgRhjZs*>W>A\eVR[)$B;Wp\N/*nFM2N"B\MbQ\.79,=# -MBZ6NBl#:/cE\1ZkM+-'b\3Qd['g1feOp3hmfh[0(*G3aqfOc4h/g'VHL5%=F'bj$ -\$]:pem:USF=k11^@p!s?[@i4Y/S1`Ajlo($\rqEP6nM1DYr:4SUgg,FMKcfH<n+W -Hn(]o]N,aR<K"p,YJmW^([s$9$iaiiX.lf*3qlm+j(`9$)obuu&(uj!DXU<5ZaXQ^ -ghXH@0(hEJG;Bb;Y[`K--:c"B*u!Mt;`F77(;T_J%:hT'GVW#PZW+7F@6@PDEGe"[ -pF@b$>S[`'7VB;U9/L27Fd)21UrA_e(L`hBQ1Mu<]U>N"A"0Ypo)5B.3*sF+S%k'J -DLTH+""7ail'SfcABONcK[_6n)H%T7]%SdoiCUu=(/>(6<Xta/>/+lE?"]P?Zl]K> -lWWoEUsoCj:0u/>T^n[ad.pm6jij9^Zu1KCq@a!EI.J5_V$bZ8$l.9*ZSOs6>7EH7 -'kt;3NuKNV;+><pkZiafi[%]a7osD,]"o?e!'`qmKScXQ)5B!Gd8N<?*6TO5SR.Fk -es0;,D(n3bY&<80H^#<7d(;.^V+BHieir-,"gFnZps@\%49s]E_mJs0#c0A.J,~> -endstream -endobj -97 0 obj -2572 -endobj -95 0 obj -<< -/Type /Page -/Parent 89 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 96 0 R ->> -endobj -101 0 obj -<< -/Length 102 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5gGWgOjg,RktJ7R/f9P%!o_C/D`+$0B4\>6,hsge>/k$(Z'=Bm1muQI"*qCAD_hY- -L6F<e@Q,)470[KlUh>c-$4NflTRbum)@Zkf@6qXJ0GGDh1Ff>r_JM3"9u_/RK\8jU -)mEqDl-*%2.M@;#=QC<[9b84X"KI$Q&!7DD_uhu\fK`.B(<`pl+=Lt[l3sP"G^-`: -1S'NmIOTc5c6,"HMK,TUNish9e0V=P<fUdm-LS0]TS>aq^'-&2P/`_8TsMr_#&^Y] -n:gtd:@<h:=CR#BM?$Ha$\:]4&.X?6i%frd<'V.X"%^EbNPd14(5KdP"u(sd9<uJE -_jJS-$g=h=2@H5F%e)'$TPfLW_P=^i_ntJTV1CpGA;IP\W'D,m0J&NN6P.U\)^MZQ -K+Pt@/5Hu!EG3B27`2$A*=HlJI39!ZP6*@lE]gT!,*Hc6O%M0rQkkEjY]:[Uo&=O) -9Cd2*%7*oL4qLX,br&5E1UMWSN3X:$(!j1^'"1Z#AAFh]oJET<-Lcmc7n_4i_A=d\ -,(^@:Z8rcj9T"NM-rmK7&Of\Tgq-*Xapi\I,\\duVSPlQEYtMVP-,`.W*1OMTV6=4 -(t"Vq:`t_A`(2^<d6QD>N+7t+3OYlj5Vg.6bKLnl()+7n%g.@!2[k<ea`YQ)(uKqU -2l79L,/]f+_QdsIU,7m_7Fo;ZnVa+u7DhQRI0TH*)b4/"/VdUaK=am52:n]43SkuO -`Ig0%0ZKh8b!W%qkRIEA":3>baJPcAZ:dWl+h0cV6EH+K\Z<:ABGAXV)JmWR_g(IB -b0\L4N._T)<eZ8O5iso-ZIhFpNPeCu4_kk\Em5#D@L&t`fn22Y2T&;R(>hh5E/P*T -Rk?ITCa/<*3*(tRPhN0#'l5';_QFgK8<W(RL&n1eEse7A6%ra"4F_Ye,H`a8%V%ot -cAqX/$p*d#[PN,6(R=2<k"GD`S)E\#:S(if$5aREkVc9ml.-lnd*f/fKuONa`)5@I -_[YrmNT4m34N.DM:,t7L/a;;56P!/B?:,Y0gpWcV6H'A<4pd8F[T.;='j5;V!8-uo -B6IpSRi$!s(rS+\4;pT(q-6@aRA_<])+.m*Hjji:]<i&7di^JfW^mg/O?eb-_\in6 -cn^t"ct?44IqJed2ni\^hO).,5jMhYYMt/cK4>-ulPLKS6nGlTHR_VQM#rku/DOTq -,Rr[^U*+NUKo]a[=G?;-Pu)H(?jo_ZW-K'](>eLhS+^K*<W%Tji*Vj<5!BP-3!V-B -#Re!L$te-M.=fX6?uk^B0hfH=_"+ai&2OP=^*LB,#+:CF#<'Dh4L'F`)aOUV%T#0P -2pc)NN8lmFc2ksS7tDA*"#jj@pc0%-aR^C&*Dsq=,nq.fMB#5#%Rp?VYW(GHj4&I? -1'.R!-00X(99Ug$4K0>TB+]r52(^G+DutR<*!1^E#f/VP";$q6!rH&&"Hm=HQ)oRn -Jdr#A7VT!s"puTf[mU]S)b[Lu^n4!R>u7[J.&,3kjD(_!&aVC[`XO[)1=p4$M/*aN -D^&g[D46[&D1s+"'>eujTaOJH\PcU_P.D-#+FkA-.GR\V'&6a3ec!\tbqYtd+H:1c -c3=qm]c]Eh%.LtEQg%cqiO&,sdC?rmA/ndD*<CIO^_rCpbruS_5A/Kn3E(/C.,RFh -ND+&T4!<i#AP?YF!PgStQr=^W47./fga&<A#Rb#,8s/38\ct40@,lnF0`\%P(USLL -bW1N1kdCc7_^,L(qtG7g![/bAn7s<EG\;'mS-O<k*h)m?1Q6E2b6E_W<gbRD`!DbR -i*_&sP>YWkAR%ArK/Mf4A"p;UE"Z,?7;0@PDb7GlLA6C=d;gp15dC[u";IsRAHHKq -'KcQiqVtf.Skf[V1YbRA9W'=O-I+"Z>!`?#RXpSci5j:J<i6JG21N2L":t[`%]NDf -lNSb?s!q<=-BS?O3EN^-6\%E4+F5]M_3$]9+Ehd*)Cp`TJLt,\,/:qoHV!3gbM76, -KC;7o\$o0F!k[8SNLLfrc7mOtYgO=b9KTmgf&X\9d"fLEG_LC%`grVqHZ.mo"9AH* -[/qe0Q>QJ+JX5HRr(E$ceigjZ?Qc'_@uTt6Cc5?N)@&r0(K&=8^'tXobbYkah$MZR -(Fa!_$-?jonKr;?!36/&ECcVt>Fng2KM\H^GsSMULVTY>;2R4jkiR(5;#%UUfC:IZ -Z8#bXSj1S#9WSYfQ8WRdaO$8,6H_+\,hJH('/^nC+<@L\MjP*\:s<a<7X_$[L']9@ -p6pUc^d[J*42[#3*\NH::AAY@h-ub7!IujsnS*%j-&ehQ>)gX]Y1>+g/>kCXR^te4 -1C$b3)":G#=W7hNlr@;qeOI\Ypg=eE/[`)g<\E.bb_W45EJ:k?c.TP:CBjj>?%\e, -$g)S*#+W07%2n5[Fj4Bl71m.V(+d?Bc#ZU-mUnK0r3/.o.4Pn^^\C:eLXC$ME,G]g -[tXNR>VSlGIIY6Tcu'5"Ib5k&S.Pfn9i$mUN:8],Lm<&,fmBc0o3N0E[2P@G#`el? -o94[n%D@QW'K4lgdt1HC1uLK3@OZ1UU$?>#a8G=/m,U=PZ+]S7QjjsW%VD\udXg/d ->BTQ(a2n)a*p@h5p@Oj[f]!6Ul('o3ElkT0\U[E=b)KmWdO%5kIfr/)VCQMsd_GXi -<S7a-`2Ph&9%;1!m\%UMq!L)MX,gND]jnNt/kCc+T+snFe/31cVp2a2XuLq[J:I~> -endstream -endobj -102 0 obj -2837 -endobj -98 0 obj -<< -/Type /Page -/Parent 89 0 R -/Resources << -/Font 103 0 R -/ProcSet 2 0 R ->> -/Contents 101 0 R ->> -endobj -103 0 obj -<< -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R -/F15 99 0 R -/F17 100 0 R ->> -endobj -105 0 obj -<< -/Length 106 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>%)%3*)EQhg&3"QfQ&7V>nS9G,P`<9\M\AiVIS'BC_8Bc!#'H'Pr47SX).5$kl -5cUBLY;@1j#9tD%J6FkGNWqk>]SKB>)2_%@XCY4=+NK(fUH*0m1a!`,#"&g\VF3!Q -=L@0_J=t,)3=$"EJH;S%A29_a@rgd`HOLqbGl4.?1jC-%F[_iR7k9rW(%?o</LIbM -3#g"WOt1/:\6ST>L3oHIe6=LBAL/Ws^>rbZ\#oOZiOb,CD!&:eK;.BfU>-4i":i&M -"2SlEPlnZ0'B8hAc`4G./`9H%pV%ed2AZQ)Wa>S?YLGhm2bQgGi&FIW)!V=06_O4T -6#^Lm^QB4Jj[V"`+RI,lgYs3J1&KPP2^,4OhF(0kLb?RuKAsY#iO`eH4ctst&i=H( -.%Z/ZMU<2(02,^P5S4\6)ToqLBcTK<XR@Aq1UqWPcI0L0/PNK1D`"R/HeU9h'.chu -L5[<82FZ%&@/nGFoP"A'!M&Ze_6ik0/^r-J$V4/o"@EdKXX!6P,:i=`8kmgBiCqP( -oWn#2ToEG"<`N-9<^`pu`#8iYV.fhBZ&GYV5]O.^/V[7&lY=pmX\@/Feb,,7;_o_) -(o%,1B_t".Xd`!ep:UV==19d-&'-XL`A8_>^hOfYp0?Kf7WsaU(u!ID#uTWHfG)[W -2r'r8?I`gjs2247dotRKNMQj;Q/$VgL.L,8E8j_M_gSreokf4S<8KOu"rJqiR+-DA -'`=\6ZX8jJpUfkKLFO"iMqO8J=dQ[%N]g_4)AU)[jLN9,e)a.6j?82O0Oc$b;!j(W -Z"fY8MDZm3*jDl"_?I7M<WHAD+BR:r(aEfq6oU(B0]k-NK)!R$N-JCAe*O=8\e#(> -MZ+P@qijshW"p["1rHmE>E!7IA).a,K:qcp%&!Z#nH8rEdP6[?E6:7rU%$,WNe7f" -DEeh1+d,7!AonpMgqJ\>j$MVm]l/MtUb[nHA.^-Tp'*t?l4GYW(C),-^T-lbe8#,, -h$6BsFMf2)fCh@r'./%2rcn0J^"8dtBTWAXiGUg7qVVf-34gJ#qe@eoRe_hMA@.N' -a5HEYO=5?lfIt!ic?LGirs&P^(dJ`MRin2"IOPE1#M-2L>2VAUaH<\]1NIlr9H,e7 -GqtXAIb@FU>W!!&Q4];,=:$rC-10>!"`Vg+8VutVAtZMrQt03SZ<]TNJfGXPdc=e? -`Gakl+TuIc&P,SM+mNGQ.2\Bb@FS'qY!$"o1A'p.0QR?tdN=&@_A`S=pl0j522:Tc -(uojN%\^/[3Z-N5>J`KX/Hhdno6gLf"*ffF[F5A5i^qp63IPRs15<_>H'\(-"sDRB -+okF[_aC=2!.Zm1(t9QNY[V\tN`(Vic5Atm'b)n'7EVk"*/TJh%[&-g!or9+O^suG -X47n:Ai(&dE,Ug#"?6VTjrD90@LXKd=biC09EQha%3b"$7b:TZ_kaL>$-Y:3nD5-0 -:hc0afK-LOg^""LGF!9TGWQe[)ac0fQcYP$)VI*7cXC99`)10#5g&:#3Q;KunlhT7 -l5O;3_3%$F1s^^.1^hg2Ob(S4L2c2jA"[;+jk:g%\f2N`^h!\Tr_62_TNhkdF.'B^ -<rr]O3TG,"+qqCjL/:dc!Pg+Gb5&4X@-]dce"NZ1U01,S_HtX'5;FA(Ti5@B1ZbT_ -O7YJh6jXJDN'm`>V2CU57d*TJI2&F*@Z,itdjS^&D%%SJNZ:mX)iPXn8!"9!(e%C2 --/@"?'8eRMd,5i^jHZ1S)F_rE5T'ZOHD87([fi^V6Y1L[V.r"3K3J,QkOcZb-iRPD -fRY")W,`BEhHS&$c!t6_nXac]E(AY1/;%>H";7_Z#(YQX9plZ@Z"Y?&nD.<#'ZuY_ -b.::-CDBgdAVfKAK*+ItLIlcELG8)&WK>OJ$__aMC:G.^!+8GB3^:-J(ak"[JeJ2r -<JomI/<KG(i?D57,48>__od!;&`qIkTRb^fJclMNjkN7*YUK^jSeJtn+26+J!Wte6 -QZ(P/^SLq@*skITC&B=^!SA*p1BU!3SKN#%)K:H]^lnet.'@!E?U@kLiGb8uCh?'P -&OY\_>GP_Q$=ja=JBW#<?/TZ=1A?IFT"Iql&%Jfb17bnl"%-I,"drZH#BR>8_."]_ -/"'s8VXFCh/.Oa]7D?_p`h=1d@=i9ClmshrS`sY:aD3um#>+-1*t.,'YF;_ner$]c -_S'ujU'*6\1l.pFmKWaV*][>$UJ16";i=<h/Ssl>f,g61>%:)qB0m("U4je!h?,op -TUcbtbW3^/&8CfqWqC7A"WBhVK5FM38B<^7Rd3[)KH6ts_N%tb$Sq!@mBTG5Kj@Jc -9^BP5YK<bQ#-RM!k\32b;l_`@-V%B:c+C@T7[7i%?Z0W?1^i+VFJN?i!EUK7?E3h? -Y#;s\!qYC`8ne;~> -endstream -endobj -106 0 obj -2524 -endobj -104 0 obj -<< -/Type /Page -/Parent 89 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R -/F15 99 0 R ->> -/ProcSet 2 0 R ->> -/Contents 105 0 R ->> -endobj -108 0 obj -<< -/Length 109 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5gGWgOjg,RktJ7R/f9P%!o_C/D`+$0B4\>6,hsge>/k$(Z'=Bm1muQI"*qCAD_hY- -L6F<e@Q,)470[KlUh>c-$4NflTRbum)@Zkf@6qXJ0GGDh1Ff>r_JM3"9u_/RK\8jU -)mEqDl-*%2.M@;#=QC<[9b84X"KI$Q&!7DD_uhu\fK`.B(<`pl+=Lt[l3sP"G^-`: -1S'NmIOTc5c6,"HMK,TUNish9e0V=P<fUdm-LS0]TS>b,^'-&2P/`_8XV0,&,b_Q] -(^DKO\eG[Z3*OB-iLD;-"fR5p)hpYi4UZtk9Fd2\YJQb4.I0T"La#K2@*o0oP+!0k -!LRh\MM_C1+G9j(%\!ZY;P5L+l9OJgYcKo!3Xl0^jq%us#f\k6mS'e:"9RLn)2?%: -b2eQa0^:S*@;sTSYfp9%0ogm2j?1Cj1h@IS;2SQr#7@tW*3W5f%3VSmGj7;L6$V$@ -N,>e*faM@ul7rdTR,J.WJ5QF~> -endstream -endobj -109 0 obj -620 -endobj -107 0 obj -<< -/Type /Page -/Parent 89 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 108 0 R ->> -endobj -112 0 obj -<< -/Length 113 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7:BP%&/B"=L`8`2M-\D$-_ga57eb775.QZ5n4c#ij!aPDEB_Fd6n(F -JDP]>ThB#u]'Xs19*GlaOtr`R7g'WjLB7_n;J7e96(lh\!7pWl)H2BCM9Ke86%]m\ -G/Lg<;*#DV%7$VWDY4g*j^dCkTR^o9N".0/E)=!!0W/Bb_b?(ciu>SS-Lgdgb\/\h -%B8%Z%Z_/DeHuV;PG+6%@6,E@3m^mI40aIfZJujB``ZmlcR6VZ"U%Y+,+FPR;dm&M -DDti+,E\[A6/hA0I/];-YWu,ARLVd&ON_7pN^3Ys(HID0@_K8Z]*R3s$_%ck"Tj4; -+bTqjbjg>g0[_ifT`F494Q@R$3=LutN9A#":i[?V_4i@`Z,(L31;>&QdMBBEBOn;4 -W1[=[L*<d;mL#&+`\<C'!2MB1"*ilf3!,1,_4uSnOr&q+=H"gp:LjaQ1pR+$#)!Td -=Wp=m'2H)qN,-0*5>U><!)'M2mejh<li,p4coUD*_!D&61.D:4"qX*tUaY2\:,q;s -We#gt'J@1"#TJNGH[uGl6DS9O7aaD_--<H?X"2@Kgi=79JUh5P8/"EM`\G;feso`K -F]gIndM.I>c1Am84hrq]f_8,Sbi[qN;Ys]D:X4Rk)C:F*$7<p3"V`nSK1j/[_uk*M -&e9)+RhO-?XTBD>0Qhpa`hQ6s,tX8ATINQ"W,3N/8g&!h=7\8$?c]<kYuF@ojc*M= -!\2cOJ,~> -endstream -endobj -113 0 obj -801 -endobj -110 0 obj -<< -/Type /Page -/Parent 111 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R -/F10 20 0 R ->> -/ProcSet 2 0 R ->> -/Contents 112 0 R ->> -endobj -115 0 obj -<< -/Length 116 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5gkokOjg,RktJ7R/f9P%!o_C/D`+$0B4\>60[iOfb_667U"5A_)i>&uP3Gf-$6mM5 -`-Q*Idnh>i%8_%dbjHSk`.l,1BRmNsK,F\W;3ka(1E46N_g.d=DemhFoif04YS:#q -7jN5&4dMcnJSW6BBq8FGS"3AF6YcTE3<9~> -endstream -endobj -116 0 obj -299 -endobj -114 0 obj -<< -/Type /Page -/Parent 111 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R ->> -/ProcSet 2 0 R ->> -/Contents 115 0 R ->> -endobj -118 0 obj -<< -/Length 119 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7:BP%&/B"=L`8`2M-\D$-_ga57eb775.QZ5n4c#ij!aPDEB_Fd6n(F -JDP]>ThB#u]'Xs19*GlaOtr`R7g'WjLB7_n;J7e96(lh\!7pWl)H2BCM9Ke86%]m\ -G/Lg<:biuI8qs!8c8U'-`l:B&D0/$%)9)mor&?*/6l8k-=Q0f`.<1@'As7Ie)e_%/ -NbR2V(6]:PeVX\=,C,g?@5`oE"N*gTk\2snc?eDK`+a>O?0U$nNAtr=SB=<r>Thg? -^r-V8",]BC)CQl#KEjk71dGP-(et<'.EFb.NIta'1^p&Xi8Q`A5irUdK.,k:N^H@U -15pbdT`Ms536LLj8S^X4,qMYV'Fr#OhE&Jk_t<p<:ftT%W@hu]1'Pr+#jOLT;TBA( -_or%H\q+W`PQoA<5Sg2iLhn"mihAii]h>E_k7-[7.gs(Q.*+6B,8fYpa2*."3D;f0 -qDj8i#i%HM6RZ7s5H]7V(WN2F#S7Hj6jbl3d(hn!1a0*V!kuPXaTfoVOMp1<@p>oU -L-a%C*\f<mauVh+KS)fn8PG3^8Q'&KOYmE>grE&D`:OU:POqiQbjhVs+MhQtb5d1t -1oii>9UZTt#:Wld;6c(!m-6!X)C\9A<Ac?D`6XO_"kQQC;OGf3Qu4\&er2=#:n[mC -0\<D%OMV3QZZRM710g:r[/lKBi'$QkMW;6'<%Bgm_f3UR%^9dL5gWqK.f-mj]M:@O -Ya@]j6C#f>!'jRJHl4C^cslUeJOIgt_0'G60]=st&iRb5N!AFc35V_Uh3A0"@T&jq -[M2AEPeAbToH[["%V'kcE==[C@\O)%os6qLUV79r@7.17&7O4E.kfjKB](_oDuF[> -?NZ[#'T8]YPj5DH_X1^=X/""9aXe!>W.p>E9:L_p!)aTN!ME7#4sRL"2ni:/pb^c9 -4?'S4iJXl,3oS5#^+_K8m%Ee^#5'5G&]eu,$+D/@",/[s:_[7(7/dm*DLfJr#)XO9 -&d9Gj^`*FXE5jL64!r4Z41eDYbV*Wc^@7lj%7%M'15CK\K`N-dJ)E"/7-JSWOQ[Ji -!>U_AW\%1>3t:4D/(VF$k5OQSOnd3Vi6bL$'h..Bm#TKkm<jObl`E^k$ugQ?i3i'U -8"==TGV94cJ3+tEdMP=aK0!cBQ4e^UA_EjZ"TYJ;U_kQii4Inp0GpNHoA1BQJ5?[u -N$9D*+USkZo4r9[&-AeB(W13'%cHaUUmO]O'T<rZ7k,]N=G[L9aDD?ZCaT>sRLqm] -9aDnM/q^Zm#U!$UCPW`OVmQ;c6V(iN#QY#oYim**";F5MKh=Y03<u<^)h5*k',]qg -(#h&@:JSP]5BrY2if$fnZ!mlkBXXq8;QNZt@2d$CcPfKQ+,u@nkXP5m$Y5KBLWMO) -6<5fFT4E2(iP7C-33=U*7!OVFO?&&ZT&CLP>#91s<OCf_L>u5KK+`0m_72QQjNB9- -dWQa!WDbP67*1O@J.VkHAdFiuAW/pd$-=%D6fmBHQg:)J^dpsC+?UR#,fN,-3?9"a -`7C8R@K4GP[V;W*"e63O:aalEqh#_.#GC_U432`H(*e;3&.+8WOCiXqS=B`g*VN9@ -rWoD_0T31I*DFM!%j0TDTI;r\-eDEU!@W!l9H$&^W\0B)Be2C=-?c!Mqaq8!0VssG -3jIgtJP``aI^A0bJc_K-W6I,k<"R2:aYnt7.F)Ql_&lI!8f:_eomYi;0#*i0;/"Je -3E3_ccQl!hkL(-"0WZLuHCYE)Ue5%23%BTsR8p0__Z^(<LIPG;#\W78Xj?)K;]8_7 -egMrFKI4H6Q/OH(KNWX.`8rJ;,,#O/Ae(m<=1U@li)G$d#3ub8cJti893D8~> -endstream -endobj -119 0 obj -1909 -endobj -117 0 obj -<< -/Type /Page -/Parent 111 0 R -/Resources << -/Font << -/F4 8 0 R -/F6 9 0 R -/F8 10 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 118 0 R ->> -endobj -121 0 obj -<< -/Length 122 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fgMHkg(uETsk,PaGu?g@E71$YN.; -]!TMV!eZ'"`a:YBF<f0<[)PZr*J=U48(ZPpKd#3PK*A9t4OsZ:GZ54a@mJntNT6,K -1U0:Qf`)@iT^%Fr_4%;@L8qfn.Q*>-eeJAVYZhVl0aL&HVXQPZo7bL]W:c,pJ=uWD -"/tG^^TY!%_2P'u0`XI2=umFr0p#3gN7%\k1I<<jpau^n!.+Jad_i/BU&ho6-H(cI -aug*-*%q3n!>&QuNan/W2@\[d//O7=:gQ&>j06reKMjKm5#9Z2N?JbZ,`F)XU0sB7 -78j1r0h)[)&HtI^F$bcn_dq2jN0(t8%S9N.5nQR`14p90<A[uR`_iOJoo9-!k:JuP -T]F$$;O%h_9qcXp&O6qU0d2OO/<ZkqP9^`H%Ds%@4P.o%O>;a\;!gX(e4l,of$oA< -B#_-!GrnOfAUe7F0?jV9>?2En@S7JAQY.^$b]Y_][nMElaHpbQA%jN(lN,4R/B]E` -1M!FE9#3p#/PD0.^8fV+8l#R`o1[a7c-q@-3_mS'nNB^4r<"t>1c>YjgJhGt8)Wr; -?lTAbS=,(!Y>Ts9dQ#2pHra#nehW5;R*,9B6ZD:Ej8paj3C5:4gkq&c#fssni;gcr -N?`,R1[/B,\2OOnXdP/K3Ufn=8PUbTPUWR]T"fpZb5g1J!N9DA#-O-IY/[HN;^M\V -9PP8+!uOoR"p%!A3fKOY`Z%k)!u)H(@EWC"%a%9O)"YSR:c\ct7(gRG0#m%<]8DX? -cN\57BH-DY.X.WS_&T+,EjC].U^i"Od=c.Wg4Bq3/68+rNa=B"EQ.E*(JHP^="0u) -_bE85a[h"#*20VYHQ1LT:2TNBW,5rupRa]Jhc`.7.M)iD7^b8K+nq)4+.Lr4bq8jo -VRZY5q`K.C$15KXf[rP^F:N75l9(<$r>sG^#E.g?!r+_li1k(>bUs;h2t2i8n8JZL -eS)f6QM$KR$OkCe%#0l#e\d#=%Y;8R#E[j]?NEiKO-$:e<E';?A*Y<l[HaM'i-H:s -q+!rb,")FNKShQc"\75C+/IQpii$pUkiNndfXA2?G\g>2WY`V7&.$0(^e+TX9K`WV -#U2qdJ-o[."Rqof_Or"W+V5hg+Ij36TL]A43$ZKeN"lCB;BsU<.=qia*.ousLi8Qe -^F8Yq_D0%]NR[$P@S5L:fH:AeeA/R:'O3s4Ka)FS`04S<$6`U#0ehFa3QFbU*>2&4 -m[u;1!:L%eE]sU4_6*hD`>.0R\cua(3P)O?-kAo'/5=oP".*\86'3oLmcbV.#2H'V -D!@KhY'*Rnh)jeQnX`X,E]g:\JtPcZIOL`jV)W0AiPFr?TR\%?B0u5j\9&/h/A?j8 -nf<grFbg$J2l.E,da,4oCo=Qq7\m^$?iV[KTRr>)>"qTQ.pl7$=]'q='11n=`!iZ# -N1mg@U(<M2O&.;NcUQS$dB$22-n]dE>)cDE5V8n[^%7i*9(p(6g3AXR&Pn[%3M2OD -MU>lga,%6S;O(FE<H9Z:.+9*N9id(p\37*=_b\Nfqhe&70ZH)Y)6(Dq#BZ*p+.?b8 -%s8dXY':q=F%Z7bqrq+h'#RcWb>;D`3=;\B3WhX]O6JoD8AV=>dYdgOe"CVBY5pH3 -0O8+'4Inn/W2:Fd'L4n~> -endstream -endobj -122 0 obj -1935 -endobj -120 0 obj -<< -/Type /Page -/Parent 111 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 121 0 R ->> -endobj -124 0 obj -<< -/Length 125 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -ZjKnn(CWeIU!-nW@k(:t`BtY*mKtP'#q"V%b]5<S$4b'SOJ]$1)[['ePBjZ'D_hY- -3+GOe_C<*V70\,.^eeSVQV)q(<DLS9RLU^?6-KU<2B0Y*>#>;u6n$TC8qsG7:h1]q -6>M\ZY2Ee,)TkP00p&nV\$Ua@UC.SVhC'1tKEaGnK]m!d#S"dUZ,"dt3ZVfVcC)?' -Gn:u**KO?VaaEXr9npQ2O0.%mR8'RMOlp9/0$)+ONNHn-f&q`QHiE+l+iFQr"g0A; -OZ@;p>3EN8(r#C3_<=-@NWOjI+hY_6O>=Mmi'8mu!<b/2NT4Efnd313QmP7189Y61 -_.m/S[IJW((5KdPX>#;=o,RS?Z!:Hc`"<R#.?,S$YnfdRr&3t51!FgoUi;6Nf!Xq( -dQEO"_[uIREm)8g%&56'r=#H?kW,n8E6.:'$s:e3NPdgf`5oik+#$!bHj[=`5su@i -KsXH20g]bVQl*B`B]_C9,G<%58^RB%mtcR\6Pm`e,`"KU""VJm7T(AJ1s;WO;['"s -@`KQA1F3kP%s>bY(l%O5-!s!G`%OU(bF>Xj`DL(I+V-3=D$>Z2877`,m<*nKbS6&E -DGlch02.'1Yib:E2'A_H?)&F1ngnpf5TNruAW(T`_*gS%"sWj+&3XN2i@hX%m>l_? -b]*%f"9Yat&.PuN+>]l>aR&^4XMka7L;AscDSXh/*<f[kSjAK@diH,4h&$"VJDb[F -_E:CFFl55e(_Ass<n2n(,09?=[MTC^7)L+ufCjKXkLcU3SAgoQH\(A]:5'lgZ:4/U -kqV=)8qd@'q,!c(n7!EUi;e*68ei2_,0k,Nm6!h+'lCAg+]qech^]BaVH_D1)dpl) -c&'9g\UDef@&&IT'Pc?VYoN(U,n6UY3t/qHn;Vl:&9<"@jiIb\[W-X!rAG+3oibE_ -`q3H,9??MSP7?)cglQ[7BiX9f`^gj>qab^,hA6N=ihN,%:^bq;J`?hb23&*?S["I@ -FC,K@dMYsaQ=$4o/a$!C0]fZS+bogJmP:*m3c=M3oc6EspAr4bFl,Nhgd/;e9C;bc -##*QECGHBYd@[t&[#j(l?3MU"cD6[?EC%JlG`=T.\+V:[JSR;t/Ns?Ek-F,Ql^W%9 -ck_7$N(ou"Kk/LME4hQICVpb7%;uFO[Pc;)hKdOP_3J[tZrh1rU=NB1+`WdTI.u4q -/6a7-D45+'V4n$N>t_H5.TU_WQ^P?.CY=)"a+jChC^LA?q8g/rI)?GX%Uoi<4i-hE -``Ul0A$9b>^"ApuU5BA+OhL?;VpNnYFDGKkN=S:.73Z.s%RWjbXu'1ndN`eFGd8JS -8>f#agmaQ=P'Re<W@7sR1mi)VTsD+Li6GP2D/Ja[n%UdIS_pfO7SW:J\+QpBS.qEQ -nf@dmQ%oA\Uf``!4krT[.1"Y?%;7N]Tu*,0k@Dd9"V-OH\o9q">oUG#%fM/WR?KPb -[*Eluk"nf%]f?c04IGWoj#i+o+XU+NH3(S@4\5)9*n)3lXH@G,Lnu6S6jAbAWV.Lu -h(5%InWq;J>W8(M0,s8lM/WfKbU@$W&6M@MU]^~> -endstream -endobj -125 0 obj -1690 -endobj -123 0 obj -<< -/Type /Page -/Parent 111 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 124 0 R ->> -endobj -127 0 obj -<< -/Length 128 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ1_S-A]gGniZI7d5@P)[JK!L:!g -/_sT?e,_jVg*k/b#q"]*aM)a-$A8T!8\ib/MrSd!4,'Bta=rX,$hb:B"%^!7#HkXS -*!U,E>*u)0?r/b?,JZPZKEH!(&-]8lhY=g'X7#o%DtF#gNIrJa"2QZr)D6e_\6AG\ -d3LCq22Erbp(+FV,)@`<\6P686P:q(NH*+,"\D78D\=QSbc(0HcX:)X73a5+UdW<Q -KKQ4%j/s8Snld078.#-E'a=-Wff($>CpQ+7&mW#@N+3.U1;4rbrZV\FFUJ/f+_*pK -5CifVlcA%DY<=6'cqlR5:S;D:N<:T]3(ceP%88n2e@uR4Tl<7XNPd#.`Dt+Fauk^% -#hV1sZW\+`L.NqM+MDidlR@OlX(u+d'[6A*=L?mF3`GLd=UtbB2&/kT2QU$[7Det2 -)*lP:'hF6kKQ-8,nbb7^;pel_2aS;/iHSOg>P2r"pCq*TgsNOYFinhhpC.PKGi]Sp -(T:d`iM#0p0@Q.>`ZgCp.,$GjK:GYTgi)<t1kfoPeLAqP:#.f5"5PB*da@]R/PiQL -L7m$R*U<B'G+H<p^UNUNJ4@"9*E&Z<<1'>rOS3kmB-Vpl+'S3=ILp6NQ*6uh\X_[h -`-Qm;;/03t7=%im^9SbcH:4g$ku-#b,"UC?PCq&"oqPNl6aDgO<n503?88aVQ!d]u -Q(pB8ebtn8AsS0h'O`t,[sEcH(dX!fK8(t:@p%[RO$2/!A!&Pb//OYp)4$W"W&]#u -Qr<`dCHoN.mCRd8\*O8">e2I'/]#ee,`+k$FZ$&6pRFg%72LmPTQJd2Blj&q4EV\s -RuHC["VNDLPhEH:K-q)5L>>JMqo3@iV_[l9.ZM?5dPJ[=O?kSEI'?F4P<*C].BPLp -o$$j`>/r(M-3C(=+LBhOP>E_<7><Z2cWIDO;5?2k.5tk(T.6:.OD+Im'gUFjj<8=( -Xer,[@'#hY[3Em&?)uQcj.&dKEc*UB3-QG@S<</kBVlFpB:-,1iqEooO?,d0^<f`' -s*-2)e1R[tpQp8#Ll9B][.\h[,'27I;+^)X.'1$(;[?f*0[-Yb*lM0M'gM,;NNq&! -(rISsA;lrX_=1pVRe"C;DTJ\=a-?cFZ0Z6\+VVdR9(*SW;0pFiUG,,2+je]^Ce\K@ -4N>h%g!abOZ!EX'"mIAg,F`u,IC6N7lNe]P/::8Gnj)eKmG$=jDlrqg__lKE>U`@% -d,mV8aE[jL*,0=H,bV\Mf]F1&S;p9KN5o!i*TWH2F\JAn[qRP>,U#m*PC?as30JZ! -"H\KH"Tbu$W::FF&P?_2jNA5qLL+e&7'iIT7+p)_B6+-$9-N^tpVAE/UpY+@U%COD -Y%5=F!<~> -endstream -endobj -128 0 obj -1659 -endobj -126 0 obj -<< -/Type /Page -/Parent 111 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 127 0 R ->> -endobj -131 0 obj -<< -/Length 132 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -ZjKnn(CWeIU!-nW@k(:t`BtY*mKtP'#q"V%b]5<S$4b'SOJ]$1)[['ePBjZ'D_hY- -3+GOe_C<*V70\,.^eeSVQV)q(<DLS9RLU^?6-KU<2B0Y*>#>;u6mrq373t<%G,R/- -BH]7SI91J@N7c/10p&nV\?pjAUC.@eYAY*_`BjX*]*;n,),,V_"jH1A1Z&<=_+*@9 -H1.('4$BOg;D=D(p"&%tTN!T<EkT?YL7=(],YhO[j>mA[_E!RK!7Eh6"%^EU$;Vo^ -#!p,,]G<FSgXHc>:Wck,#2oPcs0\tV(CL\iTO]^9JH4%PNIub)r1MFVN=rt.O?ghs -!H::bNR$211l]oPcBsY;Yei:.XM\]T#&-&5)$Z.b7('T:]CH`[/-Mpa7$!i@(r236 -:@CVkCj%Ln!<@H9Kb0Kp'[7d'VY(E1E5"8jK-4>>%"eiL0YCgd4;\I2S=^^rWk;"b -71iL$mRV.NhXXE@K[EB:iCrescZAIQ5gXU)%n+F$"E+$h"#/Rl:(UC[gkU$6GRt8P ->T,>QUL;5&N3Pq:3)fJUaRrT/86-JPYk%:g6r[uB/3]ibSIesT$un#GTgW6)eo\]) -$.:W34(?O"o`7?TOP$uueJ);q7m=3<\P(_$ptu\gdp1W:L[fIpI>:ns'\^s#eQGN$ -oo8ST<qp8-JQs$D.tbB/pgXkh[Zflh"U",#N@](V!9H5),?j;$;Bkfp7C"nr,ft(? -k5<E.S>s!>q-3/:8b1r=0BC^@;f:.9K]Q?k(/?#X=&=$d?e?U"L@SU`m?%QTG&3e6 -??Vof'O'5hT8mF.%ZdmM=!]d@h"0"#44JIc9m;N%F7S=G&rsk`c%-%dL'=o;1NLs/ -0!f\"QYd2E@f^7Vj!NO[H7Crn(5&i)[:$q?N$D[SNFS.^eE4=3bGOR9m`W',`@h>3 -nk-)Ide1`Ng\WKbO0eALpJ6i3e)aiPlN9EaSTb?<2;KJc30c<^ZWeIjbtUVMV'g\$ -&[+pZ?d\Ls+\7bQOX3S^F5*DOHP_\!96ng>n(X<OjuN]'Sc*NQ2]qJ]RtHSo9;T5" -<SX;il]uk^7K=l*M#SGThLVfJ:d@J$!M"NC<A.KUWqBgfds*T]b2$<r7<l#%!lA'$ -%BT\sP1NK-f3/T*KfO4IfhJNCJPXhjYk@Mh?H\1$&@'56A_ap@9Jg(+TmK#D.)+<u -p0qi$M^HN.g/k?dM9J,=_"aeBd,I,XNfCB\VEj:'X>D5^Q23DJhTJ9-04ll.RYFj\ -mU'J:A.8Ss^EfiPU#F@40R]fb2PCGGS1/4"XpW%u?F(f5e:qsOO@+U5).HN65]*e* -[ci>D@N(nWE#$D*jl#!YH[Kb[A\]YE#6Wa3D1D'^:IIcFh;Ub*Eb*t\9#tgs@m_,: -nZc)_pHBI#$tO[h[S=d5V@eGgDbs$Ag7Ei<,Yr.C4tQ6\a2@R.O7^D&'/]iaF;!)" -H4bYRRV5D<kk#>$)gZ,G,*^LW~> -endstream -endobj -132 0 obj -1611 -endobj -129 0 obj -<< -/Type /Page -/Parent 130 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 131 0 R ->> -endobj -134 0 obj -<< -/Length 135 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ1b.\4egGniZI7d0j)[hB>+eHR( -dh_AR1$Sb3dVpEM%H\=sd(XT5)@WL\JFBXn"ff^-ecc)!<"KM6#k/W5"/t!15n$^0 -^5Si.lnFEOW64F\BNT-i,cEDqejN;I<#<.)Cc^:g!<`In^gL*h(Hl6&g@r<7S*Km( -&4@3D#GD.-'M*Ξ#QtZge-UJOn]UN+2S=2@P.MHnmm<%"o>&!J%c].;7pKR)Ue$ -Nu^ehkh=!H&ep-98C>YF*_DN:Td`Ts['2Sa;J`ru^[ZCL&Z?p.hDn<S`7c&`FAR2n -$h&>6-jZSUau53RE9K=,dX7f=N08#r1kf@C[d0Y9K!-oKOc2o*O**dh(l%R&a[/I: -X4mM:PAH!u`tCda--LE&nLD]PbdQ"11^(\r<q%@I4@c[cMd?ko!.>qmPOO&!^NR\@ -DG1CKTiTNk7+O;#Zq[b9;>4@_Dr(..f5el29kdg;&L5r$O0MFP<R>SoEq?uK1GC`t -b!Y\+6I<Y-`lp/B57lAspe_^D34)m+]_F;5KM]$='$SE?Kh$Ac'U:+?;\[bB+kY<K -7*JW<4Mua-M*:eV<Y^c@>1K&5AWc"Qr8D&.';^UKNPd154]t_Q[q<\k\ni?R\a7LR -KG?B*(<tD5cT0X@DJMAf1Zat(fud]+^c!]TMi?j#7KY?pPuRu)>pBt50TC:rqgIN; -NXq+X;j6_pWoFZ]UWKauD]0f,KaCi@ECT^@o'?,U`7GnsnhH(JR*-^P@i1"NCu'"L -('FZD90WYb(D27t06jP<#8-(&HpA_5$No+%A/tq]E1/A7__Bpt%n3`=IhQnXQ9:?& -R1s@u9\ontDHG;7j'd0o9^PXCPMH$f$ZbuuY?a2!l1E5!AZbQQ_l*!p>?]*rc+Wp$ -(V7^f6GQH7X[f?%i9O@BQW#AN:8`8O$<8$*EieY2WjSQsg'es7Dpe#(U4U#7gLbh/ -WW9Frgsq^+o5<ljYWc(&Y?'Cc>L;2G/k?EVf2?F>bIr.taEG6nLi.1Tl(UK<38WDR -4FliO]We.F_aBUuH0APtYsOiOgsak'/90"L8%A"3U$Y\'-)IKi<25jt%qY6%R6ap, -W*mM&<7#HY74=\GQ&Ho,&:QI#(6nXBe,O.H7B!UPgABH/?#(mCXgQen[#t5p9oY<' -^Y'=TTX4$#YJM-NQKW+X,Tq#!$4aQ=6;UnuAT3b`=gU`Hl&TLg%&'%BLJZWP*R'+l -X7W'?!9@UATOq%DL_'\XPT9kIE-5TN2hk/k)hAUr%&)Us\F@#?-=W]<10-3@#fS:J -jF3J[TV`S\'L4n~> -endstream -endobj -135 0 obj -1600 -endobj -133 0 obj -<< -/Type /Page -/Parent 130 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 134 0 R ->> -endobj -137 0 obj -<< -/Length 138 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -ZjKnn(CWeIU!-nW@k(:t`BtY*mKtP'#q"V%b]5<S$4b'SOJ]$1)[['ePBjZ'D_hY- -3+GOe_C<*V70\,.^eeSVQV)q(<DLS9RLU^?6-KU<2B0Y*>#>;u6mrq3`?dlN,\[di -D9!keFQ@<nQAoBtRt./a@Cuq9[8Db&_C-WL9u\ud',bo(:N'=[:r_o^'HISDd;b+1 ->SJ2tB&bk'*+Q^AL)ff1bd]+Gk4>uHOFofOX,))%&-f:QHC'B&_jhT/XrpOU"mqdo -(8[*R;WXu3C.&iODJNFbK`QEt&.L7ZfK+tD-s@i),@JYS_E_'MeYOd"7('rEKOY?8 -Z(O>t_/Ra9%P0;M5S:r0*)@9%!>J/>N^KIE1^$[7B!TJAC9JSoi)Cd([ZVW6$d2E^ -M%9rU"@Nei,;`"L\u[Cl`6%?'kSCklOP_QYZG^Rg9@;8+K0p:-"#*&_*4$']dMt=n -9>MV&&r`LaOs^U_5X7@@,CmoP"9X2&o02d*>oLd]`4R]do*fnCd;Wl-4k.<dr?2=Z -A9SC3dj'2q;=`pI&4D/$Wk".@TY<HhK1L2if(<fZ>h-2R>@,l="H-\jPiY&;>S\I/ -16$p?T.nl_N4CdqG,e%@<`a-^CWdNJ[5:8em5mqR_[,`C#Hp:G9j?,K7f1[m(g8!i -K*^Zp]\uIF(^mf7CNS)BQ%`LDfYt0dbk-UE:#C+:gCiE](0,s>(d96C%!Z(tLZ1:b -.qiEO>X=B.Zm:!'B9O(p?X>`%\.B(dGib26GR.b!`.7o5&.@Mhi$_Q6/6k)lUN#EW -j]R<_W!snP=,?#FIPl:PQ.tF>#3an17YMSRdC8O*;dZ2OY/juhXF$Hr@-s:$bEUIX --;0\63K=u4@MhA=2!4B>rP3>N#2<4"r!n4<E015CJ+49r$oe@jp%s6t!Vet0KE9\+ -MZI)O1MQ<K[fo9+HY-$jFM3+Ee7sF2CY*_MQ[d_4e,OE36CZ!VcaDg"Xm'mhhKt=P -IYL#AkhB[*V!3!PRYGXIQDpp#"!4g)l^IO`9l*V>ag5h#7YfaYIeU)7gT/pZ%HTgf -Uk\</UV'q@X^%qc=Q:9L?Oai940p:Wc!6WA?jOa6WgERB_3q8,`3J_qVF8Omn/uQ9 -(`'>''Y!"Q$?>F[aZ2kZ#b`KgKC!a\^lVCcS%JhJE#$)MpjE\j]DIDFH2XF'-GA(F -CB^t<.RdIA(#m/7Mc"@D/4B^8e1;YXLkutTjVZq3l8_7L+R'n6XQ)s@G'59q2^J[B -VUl[f-6_G3"r'gje!tY\XM?k%;I[G7Li3`RO]&,8(86h;CKrVi8hL2])$th)OJ0`S -2?;t_;lW\'Z=6-kAL`!KN"Z]l2D?IYerE]rn!2:p"el]$(F@#1QW!*%9,._o>GLOa -@1a<J#-8g`;_;Sn`MPM<LG;/\a-e'M7*)k/.q:Z0DUF&D91Vg_?YmXjEu6l1L6jb4 -*"mj_5S,9Q66.?kNK[s_r?5hKgEQM]T$`8=7[1Ql<\ha!9/9*DPs?7c@c:$iYW%=0 -6lV7ZGZ;c\*D_N$X3pS;S';tS/9\Z7<a:n!JVC7]E6CR\C*Q0fZ;8OW+Xp!?jF.P[ -3`.cak,6H@?DX)=1j%;r""OjZX?oo_.86ZB*=`T8$/l(&;B1r)I\D=QTcWCTdY#e& -B/JV+W2+sIkNoTYP,8RAR=lEo*D-VQ#,emIdisDgTHMS71<B-.=Q`AXK$;VmR,HXs -fi(n=_2KgtOS('R*FpA<,.^>1^:[SeCJQ+e:"`+q;^mEVI"j,cVT:C+:U0\dZr/VO -"C_s8B`S~> -endstream -endobj -138 0 obj -1924 -endobj -136 0 obj -<< -/Type /Page -/Parent 130 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 137 0 R ->> -endobj -140 0 obj -<< -/Length 141 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ1d_6'mgGniZI7QU`*5aV.EM`_I -D!?k%<g`O[:a!t%$3l\3(nOVJP6lgBkIcs*$Gg+83'MrhhDPe'i)1T,kV-2AUWm<* -MN"='l8]=#*""V5UV%G?US2F4#cHqnqWkYl)Gm;cmRg1hWQ:!,&38"^C?[>Xl>@;i -Tu3lE$:?5c2@Q?"&i[]QGg$^-0Z_[#N$C=)a"e!:8uJl\qokI__2)pC`rK#s+K"+: -@ie)gY[S:QUC.e;W?III)6XG6#6"c=K+ou5_Vf#DL>d*k/d4#*,4*9?9=h(6mg*OR -Tem/&Xas8Ibk+'7GZ;lr_\h#eN.WND1CZ)a)\=2!?uh!p_P:77]tmNOl\2`;B2sTr -H>aEocX<^G"Dh($:fK^n/Kr31TNj;V:i17Z<QYU62iTLboaJUBi9;Qu6TE*e$u-pG -&-YE1\iVc'<Lj^qd3W1nO*=m&elT5qK(r81!:=h:,7)7e3q]n#<n6YRK3;6B&fY+> -(SfT/6=W[Lq?V^%jtVluOQ\XY@8mPOgmIlO%R\iQ7qfb`%F"TYR;Q/i%Eo[3/W%=M -RNd[LBS%cCU"DYYe<1q?R#SKfPRq>W8C#0_,@iYV6Lp[DLt;61h1GkJ6pY#AQ,VC> -iRGTGpgmMJ?*iZ2PkcI3RAOhkB3F/:TN&<7M5*Xc5+RbOaL22RlILsPXO_^S'jThs -%=In6(m'n>%Y::fD=$h)_E!RcpFFDD44TKNaT6(l4>?[2<P[P#rXZlFRcdJb?+,aY -Z+`>M,K]OeJDN<X>i.P9pHt=s,K\<XJhlD4P<^rR)NpN+i/oZ!K^^":_+N\bVg[t0 -T&&rL"k`T<&.CoYQ8_eBJ#hf&HIlB=iK`T4eO"ZIatUXV%\LJb9NOp<8qV_2&%P<I -"m5Lt'D-:D/SqS$]EeQ%4Y1=Zl]Df&Md$!ZIZ)/V6""/%i6/ETB=KoUQQZGAGTo`D -7Ct[TF9is,KL=iU#<7lu`R8Ko:Ct;SLG2,HRnH2)9UXP,-q[s$UaUs-Gp>?Q1?cqA -+GK=("iNp6$6d3&LJ).i!`6uL_#Pej/mV=B2R`pb"?(44ShlX.@g4*_Z[kAl15<h( -!n5't$ueN>(<@p0@ru[GY=]9=aO'UPPR0Lm+?9W[i#Z=^5n'\!#;1O9(Jn'e6nm7- -7!MK;eh_,`kohB75j&iTKUI_=Ot6esEdT(l?AoJR1.nM!6mGBXNG?lP811S\S7H`% -b)"8.M"Mi!''bPi?:7%,2[*]5\X2fG)i%!(,NO_$Al;KIKt/igTqoq"6-_$9BH&lr -OBk+KFt]L;BGr,.Ap(C#&A"(])^h/,=mGDe8>Yb'i.:D^@>lG)<O3s4&5ES1l>T>* -#/jtL*s;Ru#uIW>+659TT!AuB98WA[?pfi#0A0k]?pG_RA,C!jED_Kk3q4,75tGWn -)3mI%%8+8!J8VVado-?D./\pt8%k95g&f=ZP>7e6dRm/8jG72'-sn.A1^<P<dU,(1 -V+pas;sJ9r@+)<XL.ha^&-~> -endstream -endobj -141 0 obj -1806 -endobj -139 0 obj -<< -/Type /Page -/Parent 130 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 140 0 R ->> -endobj -143 0 obj -<< -/Length 144 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -ZjKqQ(sBqZR)$pb+=^21`BtY*mKtP'$:[qOb[rdhR*LGMH+6+X1C+CJj%6Vp.3-Z& -#'!@::h:?-8q`j;:=!"1@R^GCKY1JH)ob?7R_4GQ1E)-CL9.LRA0B)_CQSCq^h'45 -:54m^QG1cS(5rF7*VI'ABfHe9-8L/%kTDJb":#E>I,&-gR73Z1?U.LNeS?;Efl!#h -a2%=8#%Mr"f?l2X6j(j'5NC^UMku&G#EsnL1rCa2]T%r(U_*djW9-)Dj'^^uN$D_: -0b#@H?8df'YgP:[:=quD6VugOl3qR:YjDPpE2k5kNq:':\-ZsEre<^[I+&8X:d@%# -"*uMcN5K,q3Xhc.\@iBOMt"&;6)r5<Ue=pN'a='A>:'Q;FD2[Z%KhCD/IjJm2i_gH -Fug+#SC%F0nM@K^"jnG\mm"-oY3a-r'Dh:CTg[Bj%Ds%@4O'!6gbOfY!8.sqZb0-i -bccurOh]4!rA6hNHdtJ\e4@b*c3p.p34X+$,lBcEXD[X?%TAbX:pb%7:K/"3b)96h -K?$._NA/fQ\kchkpc_KKlkI2HOCJ2eZg7hs9oqaX#!pUh,mlud"?-gD&H">$d?-"B -76>Kg=Vj]XW,U6^DuG!k4QGe1AQb;X7,YRm/'\\/"";e^N38Q0$BCDU\g!/%PM-R7 -WIW,FN0(!`_(^g%c[ao>i4(BKeMFs>?*?)]GeXZn@'hF-U)p@H6-*aZ,(Z\+d"\LR -I^k1gZtpGhJV/d;K`XsM'XN?UfK+tY$L/L`dM*+Wl"e0.(C^ne,g%TX"(KumD5_Kn -l%&hMA]E!cJUC,mUPof:j*$U$erg[<09$hQRs0Pe*o@=_4,es+DUh_`*9!+lO/0I! -9S>F@$"RkX+npFT'M=Ot*7:T+DZt@P(Y80bN-mej*_famhl6q9[I!MPS2QMWchNi( -eQpEY>L<'%!-gCUUIaT/p3"qR55+pkF]Q%]IulD[1Y2$LF<3,\jEX+CN&o<LD(3`M -&_?Y7@R1"6^<K=nJ&\=ta!3"V00^s("h_SnbtFSf^X$gtrqI$1Jk2=D63pZr!7ATs -=1W_7_0Rbgpc't#kSqF4Gn'k?`Zk`L8lC91Ef!fk6$0Q8h!=>ek9T/B815>-(iY&b -a:JEK8>qV!d9.`bQ+jY/#m2.o%WJ*%6F^3mK6V2@J?^UE+Ckoio;aoB+e]-+BG\s@ -)2^_549h&pa5;D%,ik2@5=JUpJJ_s8b5;f15e_q>Y[n;1dCMZs3:ikCKF!,k-N\7c -#Qb9"#a+$m"d#Yq!_?&ln_bVq5`-867">VPJhY1ubk`<,(e_#+pR9)qf%Eu-AZWP7 -`-,J390kgU%-SS8_Q(quLa[T7"ML/Q*7Rk)2%4.8`WFU%%SV+bNCZGoLT*sdJXMQi -a@%hUf6eJ=CK<3&[B23:ABN/J#&E:mNIr?`-Q=gI?SI>R4Vr,VS5^2c&#p&[8D\;. -oNk1pKs`t`]]&r)MF_S\&N=1Ai6fn'T2Y0,:YG\2kQM![<!@_B<@I.fRQ5PHRW]u6 -FTNk"$V9d&&-JpK,iKIB=)QT+2Ns*Y-ljJ,<0!*f=jF$T1cJF]l5i9h(CQ7/'Ko5E -Q9pse9G&gALhnb)7+e)P_['`]$io`<J;R8r#Q~> -endstream -endobj -144 0 obj -1755 -endobj -142 0 obj -<< -/Type /Page -/Parent 130 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 143 0 R ->> -endobj -146 0 obj -<< -/Length 147 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ1g:dougGniZI7QU`*5aV.EM`_I -D!?ffI<^E!Et&o/A(naaW*e-lN;Oo_^6dgq,jeuCh(:&GJ.rG;J=n`X@N`fRN+8(b -3Xt,25SXb?@(nQ.UUYIY6kKhr&V]1B0K0Ka6B3f(&BMjP%]H_:r<:O-8qRJ1A8q^c -cbsN:":tD3"[I#/d0%3/W00(LJY9_<6u`;C1(9qn^D+ZHfY7R*@i1^[#pO&p&&bUF -hD`=sFJq;*ZG\/eWF/\Sri-RQI\=`fMt6hlOq["&5a"0\,ft(CT.%2/.i(/T'"H+9 -bA^Du0?c3kY(KO!Zk,2g;Il=H8g=W2_pQte\Ok!Y&9gdg09nBtd'W`_&.R(<:G5^) -[,Xh[c_UqD;"BFj('F_>='a@\"TM3FZo(,]NT2_:3K0`+^C#rF4cZC@Q;q9e<]1D\ -Bj-h./2Ia$g,^"M2I+DD%4k&e2DF/!&iYfd"elQ&d&S*Fc>gMs*R>8/omk+BD!`F^ -U8/8T6D4Ch'JfaiH@s-%aE\Q=6[76="ekG,1l]#d<YaU[9<O)F$GA4k<hi3tMdqA[ -YE.a)NHD$^q/-h7fm&0%M;l%X?(9mm(.jI<(u6DhdXl@2PREmYj-Bm0FaB_D=eK8I -B=cB;oKJ]Z-&OK<\7)7Ke\7fXjZ-MFZ"<O=e[Zk)]osVuPS=]e9!p)2/`p35f2cd_ -77C*Kga6[AC`:=d]&8-)qYY+HFqk$S0Js%jCuGB20oZsG/W69*Y49)=Hring@c<Xu -\a*;fkVA-g0[nB^SKCHZo\fl)eS>&[pLX*TJkaq]geS\Gn3Z#ri!$)=+'NtrJ#Va) -5$noHW$>jf1XVeM@I*7W7pE<5RnoB.j*EmPUuZeO0pD#h0:UPj<*^F&>UpV?YEAj` -pBDO3M_dcFl/jop^^:`)&Ib_ni!'p0LKUW2,0LNPVL\4C'P"of&5=VZ-&B4O?uHHm -:_3iXar=0UGt)N<JL>([Slt(Z?&\l=\^h`s=umW[/6pCJ+N=uNn484d+jdtN5-Y0. -<=+42PcgjoOMO=N6`bqr05)oU_e^`T:5,U=^nr#;e%fXZB[F.hWqYK2oLtt*4GO/l -^>TJ<7Nn&P6M2$5".Q#Z5_7>f',G&03r3q1F?0UCArT``3(H_gqQOXS%3$48DmE2" -LNVV@*=B7]JP%f)eo2.pUiok&3M_BXm)i\W9QMj.)bEEJZ6@t5:^J%4-<1Bj6Te%O -A-a=`P)f&>?o'9_e/FTt,i,026j@&T!"fMn%qXfd"V@fl6to-f@PWX>KjH\?VcMm7 -C=-4#<%kCnf\rR3Ztug4p:(7,j$C</"q7U)9]_S)g^NsiCi*A%QGA%PJc9f!!dh^j -[m"0;a@M#\g4NQCm>;;<D%kUdK5't5d5l'<ZjlA!jj[Ya!&m(O[ZJiS*Cm&d<bIXn -gJN4#7]C569-DfHe!Hh*)Je!'PaoMk)HAnW%6ed=nsHt>C^s8lM5M%Bk^uKS<?,jV -W%-B!<'hF&S5!+ZeQSiJWbF7=5U`XSEQ3VlY?NDtDQ@2`[o.8573##oXs%todlNCa -lBLq9FG\"i.c4Y_Fb[&B)0HfN'L4n~> -endstream -endobj -147 0 obj -1879 -endobj -145 0 obj -<< -/Type /Page -/Parent 130 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 146 0 R ->> -endobj -150 0 obj -<< -/Length 151 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -ZjKqQ(sBqZR)$pb+=^21`BtY*mKtP'$:[qOb[rdhR*LGMH+6+X1C+CJj%6Vp.3-Z& -#'!@::h:?-8q`j;:=!"1@R^GCKY1JH)ob?7R_4GRG8-;O=^%K>6(!>W+n\sIfPiG^ -70_dC^rp"t"Udd$iK!oo-kI:k`^;35^37/[$Y(CEXB$Gr$?\D7D\dXVNV@[`NA6gW -EpRg,>g@O[oNN0!6j)(LmutrWoD1Z^ORPLo5CqRtKSGL3Fq?c1-ku>=%r:n6]$A4# -eMo2PI.3u::f-aH!ot3l5>QN3q*'@^m.J+HF/9J%&+fl7^eg\6!eql0;Zsap>ON+l -6JP':].b28)*@?*`[W6,>E1k^Bkg`h_%=h2iAciS(;L?rR*%Gtml8`O^2L(WK1?PB -(CiS\9Z%N<:[m:!N,n.71'OB@aMPmd"=D[@_2?PoaX]cG-ABlqUEcR4UPhE1j#"(o -bG1<:0Zt*Y\M$VW>mWkp&^]/cNPda>1disXdeO&F*=iTHd.7B&%3qE9/_'6Z9*k_% -rDcUH&O[W5etLW<.87QH>VO_DP^?SfZ.r7UeF(Md(qYqRE#FCq>]V2WA*en5ch8Xt -iR),0O&iq]J<Di$JV_$$"9DMB2pNXeaudnD+Mp/J0U/%F5kX'E9%"$%bVhkTr.tg9 -<\;\Zh,e1DG[=.d6$c:)V!WTfZ4(;u]GPJfF$Y$k*D99cpq(9-\-93F@$9X\2EKN$ -`D0Z=mCnmhbk?&k$qZ8l2<NBSTGGV.rPpD8JO!Rf?"9PM1Q8R%:tGt?cD?RZCUdUd --&?rnD?U&;?Qj4>!X5A'g/EWE9#3d40[!RKTf<=0Q!?/+)n<qeKoLC;Mc`iA$QA)* -D',/S\3/B/9UYh+]tq+DD\=4[rn=]\D)Hab5HjjkbN@D!@3\-Er-QW5=B(3s_f%Zd -eN[KO0fE1bqk`%9]bbOO7W:2&TD(48D:ZRe+(&>pE;cC&L:t5qb/_5WHN8@U"p*]1 -&_Ca\3j-3-$HS2O?06<8Uj2imSsP?VrP#eNpA7EK8(`1VQeUR_OK`Ig+%'(WkNj)# -kOKDH/+S4o!0`RI@0"W$"b2K=iB%:6":gRDEU[B#\eG-e+0%2FLh[D?81*npA-$jl -;$XmM=F8APniea]J@nD_KHChRI#fl$5*qf-On:8SBSm<g(hj9'bWf-ArZ&N5;U/Jj -9Q857m\m#BbZRPG7'8ia6fcc5dq]ap$tXgaK9HGi",VmbD8[mUXOCXqQr8m684Os` -']WuI;sK'6X#4Xl:ns/"Wu=;Soj])+,.D%(l9N+??E'!LKf*lW<ZHgU+kBfe=g/o[ -JsE3pQEo/&9f6iOR+!"DK2#eAnYh'dhRlp[@p[@;NN^>!N1"akABl_ZZSiIGR00CE -19H@f8R04\MK'*ic$Ze<DP&6aUL\nL?*]/<b1?L$AeEG10Qq3?gcJ#=ns03\^h1og -)aOn7%@.,pRQs+~> -endstream -endobj -151 0 obj -1600 -endobj -148 0 obj -<< -/Type /Page -/Parent 149 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 150 0 R ->> -endobj -153 0 obj -<< -/Length 154 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ1ik>c(gGniZI7d3FM,hRU4b^5> -/_sT?e,_hI<$3HUW9/CkJ@I"jOH25=i2<^qL>d1PZO2\$$n=Dk:gWIAYQP)b"9E8C -O#;td"S4d/(rA:lXMEaB%3l^G.6d7n5V]ttTNKSnO6AhL3p;GD)o=%_.%lR[0[1(; -K).#S%=nM*K84?U$l6k0.Y9Gcj-/gD1BVU;162M3lnXN0TXGetZ4[ZbYR=@&,m=]V -V^fj[bdT3[JH4L`aJr>W$Rs=OOT@rC/>Xggd_rOG"^tX%s%ZHYCth_593;m"P&s>Q -:QnJZ)b[IR?lan5N6a]4<1lN8c1IgkVD%EP`u<8;,rJ6>_VHY+cu<IBg4lt/;ao*> -I9/7*Trfgh=*3N2?W6Q8[pN*LCB,4$o=@^dfJJkR0%LR#A=EfW<Ll8(1jo%(9gPV* -9A27?`F@*d'pDOMC=TdK;ATJDEE]^nR6t#3S_m[D[FO;G$XoUH9OILZ"a",rmFJln -QeI(4bub_H=]oob'd_bGof$Rh=<8V;A%4uiFlK?;*@P='DEE^%[@In/=norVP[!n_ -@uk1W<c<Y'q'A^tjS8MZS)p!N?!?A+jtiH9F_G3RB"""tKPC8TR?M+VAQ^m)qCLg) -f%Gulp()/#X(H'$<9Xf]&_)%YaeMDQ02h@!dsbnF`p&(WUP)"E%>,d,*t3cmgOa4g -OCG9LgDY^Mc<O=_LM^s9gDu6Xmc1k!ER-Aa%U5#[($s>>mtZmT.i(/T(]`#;Kj1u\ -qo#68nAFqKXXuhl!WQ`4k;(Xr(\dU6KA-%ZT5t;%?$lGIfeAR7)<_pP*#&pkQI!Q[ -r2^LjKbSdj'S_57kR]oIG5O(Qj)E.&n7*TX3Xdm,,Du?30Mj@mgO+Gh'WTbcNJ0L, -7Srm+PN@2\U_JCcf&.M]KRRjiCH3+>dN!%gIrG#([g,5;fM`Jsm[UpJkW8an$diuk -OmKC%,'b#@=U[]#0S[):g"`#0D+CCh6)33@!iTuHD9;MV6f<?E.J.4_#lPjaliN8h -"&*AH%3VGa'MsG14NLLo[_P^oOQ%TT.#ma@E2ndm=]\&5_8sNM8I#jns)2fjR&J#j -d$!F29Ea.OTQM%>;d0N#O$rVm#RJ']MQK\^$4=.R0-T)erfJ[QO#/.FW"jCtId3?& -5H-3A,\0\X%)%k,f!N)URsSgA&kjj4p=8+IX-=.K7fqeX>9thEO:.UP0M*V(dpg=& -;=/PE(\KEBS;h=R?%"Su9[K.h]p]T<2m=VE?tM6<RVd<q10@+(j9$Qo;hf#j[RVk# -[%<eOENi15FYDGf:hd#rEjOHGrasZ1BTe)N8kGR8kF,RhF,kK&3AAur7%Kr,(1bQ: -gBM!Z-uoJFaag)e~> -endstream -endobj -154 0 obj -1667 -endobj -152 0 obj -<< -/Type /Page -/Parent 149 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 153 0 R ->> -endobj -156 0 obj -<< -/Length 157 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -ZjKqQ(sBqZR)$pb+=^21`BtY*mKtP'$:[qOb[rdhR*LGMH+6+X1C+CJj%6Vp.3-Z& -#'!@::h:?-8q`j;:=!"1@R^GCKY1JH)ob?7R_4GQ1E;9EL9.LRA0B)_CQSCkJ7LWu -%A6(.UgRc;["=",!H?)1D\QRfa"o0k^2H"M9]?*>0R'PJ6%uW#-n%o(kQhQJJHRX+ -0HKsW"2P#RdUVI0%"cmsP7-V3MT(#f:LXqQ-&XjniiNM"f&R?[nlh=`i<0AQ\8EgW -ml=-QSEN"/UAcr/DJPj-\m\hY!!Y,n*s0'j!8'&d_`6j:$feP`3X]Fg\e#$@o<dpS -!COlsYX?4S3Q<eDCE&&4489?ln^JR#$B6af2[k<enKP/73'\KUd6+/l8-99S,">JS -D$N2/Uoc1;Og)>0c0i2Ei<DioAf=81,ejGn_s@7%^ba1Wi],+KOWV5g8DktS,B2i` -MrUUQ-,%WTgbOoYTZAgIK+%JY#*(3Z5t@[).h<sO0\I^ImP9),UN5s#6p.h^)b8=5 -SDNtQmu-?)e!0L^"\u&i@jjUl1VH^SOL.49$aZ%!mF3jAnQA2ED,<"<:Xu9"6#eJJ -081)3k3]"GZTVh\_\-E4NHY7$E<W\LJ<</AMC9r7!I.QnNPh6^98nE%6!K;C36F6D -5sns%%jRh4rm#E3m1`n]Qr#Mr/nJcG4lRT\+Al8Aa$rqB@pk;JEocD&`7JL_D)p-; -faU(WmUYfqR3^<5bd!gZ,U&EQ>hbtH,c<-U&iPL;KEH2&U#&`k@:RV]Q@Cf-@dE\_ -h">fLEO=E])`6fJi,,2O(cI^<kT\m8W+oOB^)5Rt\l3EB3o8o)lh2C;@b)JC]sDA+ -:?!2ZO2h,CELWW1`bt\!pR,k;LEWicHkiP\1lZt[`,E:fN#H]KcC6BX*1'OFV%"LT -'Q*eRC".)]Va&$BSK#Jbo2<YBeFpK:LWOdf\k\F^I92ERC`NI,g%:kZiYd!2I'`0[ -?H6Ieo(pR/iqiY04`GA/_n,=2r@`dA#!U@-/H.buj6tKEkH,tX4j@1,?DHn;Bk/&F --f,Ws/!>FdiUFRk#)s`UrbuVcocf(a$4oi`7#]+T0pS!Id-;E8%,l-"\&A.]lA:1L -W:hZ?I&;t8jaot,E1eN1"lRT]K5MS<0?(7'<dE.TWh'eGPXPe<A'IGU[266hcAl#- -ZW;p>+iNH'P*O`qMCnAh,\53DNm(B`O\ml&jDG?5H:L]o`BU8!E4+Z;+'d*>&jp=n -Tbu4b;,!WD"!qspPbPihl=F?Pf:kT9b]&7$1*AAa=TmIuI#gnQ7n;Ye+;NZa%Hki- -//\rMS1<0CnhFc#JBkN%Cl*=T&21A$]W5JqI#_unFIIts]7VU&?;\6pT]Rknf>ocn -E;1,#i'>'p&8,C0*ChfL(;j(g&7SG*ZQK6_=j(!jR"2+OVt06`JUoA=boMa5Ld&ir -o-IouNC8O+9ck6L1H"O,&]C"2.iG]>B2G/a`RM3BcT=U1'4gQ-k(J`?@o@&sp`bsN!W~> -endstream -endobj -157 0 obj -1653 -endobj -155 0 obj -<< -/Type /Page -/Parent 149 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 156 0 R ->> -endobj -159 0 obj -<< -/Length 160 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ9_S-A]gGniZI7QX`)sq*eEM`_I -D!?k%<g`O[;2R+H:Bg?pPf@esNQ\'$=Fdmq]&@DPg4l^\";`?N?r/Wgj-0BT1BV^X -q7a&B[MoUJ!.'9Q@0@e]^5oVj$j6Uh5W;$hk]Z9qn3ClG_!jsK&&(mL/IXk)oDk_= -:_IU!5fnmH"[S5h\HkA2X=F,PYfo!B6aBB7&IWVq9,#IQ<*6p?0mGu$aDm`H)bH+F -qZ">b(io=D!i1YW_==>!$O2c93B9cbh!6K0'<G7V7A60X2Si<3QT\$ieC,LoWLX<f -aKpj8.L't$Tfc0DXS=BqZhg&W0IWb>,XPC/.7DDmj97//eK#kZdh8<b91h&mk588% -h.KM4[:E\h:"'ho4P"Ms;Plt2,_H4n0O3R=;K/jM>#mPG1D<1mSTu!oW@^VT^D<B" -*SCuDJM5XhI#V#l'KBN9=tdkP:#5O!I<8VX%G=ZHf6t\.fiQ+&K*mZYpD,6amKG;X -:d`V(%HB.d3K0`+^BTZB4>dU0kVZXYaV`hdbf%DLdP9bA@)s+=_][AcauB8"KW=Zn -$%lXlJ8^.o3,@3!W&TebMW3Z^1QCU#VCda:6!eVd>N9,6`K#R=nhe6-<]cm=;E\DA -Nsn4U-V<jT5Tf<7*TA[:!<@8Lh'roLY`=&M^Mn%Ali-q9JSK!@#'T_#S#@Rue!b'7 -ldpp[5t.G+$DL)H3X132kR[o%2GKDF_^Ou>%"eiL0[Wi'=i"H!:q*7aLp5)]8_=3m -;<uY#+j"bp[kZ-<q+b"WoN`c'VU:]9#54uY?6uF]\BM?\>E:-E]Qnp=bLaLul6DjG -HoI^SL1-WA\:k"t/23'4ee=VCahAY3q#N`fb_X/EhpFaS."j^]rYT6l9DN1%/eA]u -TO*.Uq?S8OI&t'U*;i/@@:Ft!3!BL]&H\/WK#*HC^MrBE%2!D@mCB./a2mQ`Z`Xar -M-_q"aK*qH[m)?F/X(4X_%\B:;!7(;T;MI2_1Ta1XfVIW--GaaS1njeOXHjTQF5/X -(gb:o?b2MU]2G@_9^@f^Y%.nQ=T`n@d5E^J"Ak:kRU(fLar%%@Rh;CZ2GIbfO05q\ -T&V&2:MXB,75Y5Cij%s-8PqOh"d3_eF>&S)X\D<R#)/;kHrHuJ]1<4[hA!&GH82O6 -`2;+gA9:p?b2tl<\8*"SRs8&?D:qAQlD15%iEd/8/Zglg[\Z(6>OAP49#mV<-$mq( -Mp>/&`T7thg@^dfEIBd"r@am,!G9ZsK<mMHUY56tHArB1Zt;0/>D.Qkd'1_?G;eo\ -"#"7B5c2&JVU,?3ePkq=`6FY/$6F$@";Bak!X>2QRY0Z[m7]=D<p\D"j=ZNHe.=MB -`1bq!4`%?^Zm3I8!f.*~> -endstream -endobj -160 0 obj -1671 -endobj -158 0 obj -<< -/Type /Page -/Parent 149 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 159 0 R ->> -endobj -162 0 obj -<< -/Length 163 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -ZjKqQ(sBqZR)$pb+=^21`BtY*mKtP'$:[qOb[rdhR*LGMH+6+X1C+CJj%6Vp.3-Z& -#'!@::h:?-8q`j;:=!"1@R^GCKY1JH)ob?7R_4GR//4?Y=^%K>6(!>W+n\sIaD<IG -b!tD^^rp"t"Udd=NW$LdBf?n<Vh4`unoQIP9;2I<VcO'<bB0DN6#]\Q4;ptBhLA%m -/J)q_>g@KXbZkk[#CUIqatbak#Wk,+7#KRU&$Mc%Q7VLZ[c'3(6]CIqcUct=%>/oB -3X132kR[n`"5j_#"%^EbNPd14(5KdQ-8<>'9B[4INPfr<4&>1P/[,=2jt_sKqI25i -NgP.o"u!90NPNr*]-G/=KI$sld)8im6c/WT2@P]n9KGTQKNB<$Z6Wm/5L<AB)TM<g -hDl#i34epn:(18A5;Fe*mS&b]F>Cmf=B@C<E#<%'`Xh.m'L4HiZBhZ;oY/c_8Vk5@ -c]`<QQ;@Ttm,+U87"[2t!IQ[L6?(:JZ\Uuikdj2]C@2lB$"=u:^[C#Z(Vj$V>(KSf -FYMa`FP*PP$tB]a#7;%3LabWb8E"$:FTCV@"9Gk#%D&l\>=q^EfMO]M1"b+i#H22X -lqqZYbqmjF99SDLO)T"Z+d$#5)(b)X9_D\PCS>s*!T64%$[7"D9a27'"af'DA'9)B -;+uNn@+NlR3F+S`'__g`J7'CN(K8q/\er]hIuAQr,<*s59]XZ4f?;?riNguC+K)O4 -ZQiq(XqQm)@BMJJ@bKmlOl.,N:DW%P]a'k_mY6.WeMHW,dP]]`c#d)Kh=N:RRJrVG -CUtk'2;Unl8#9W2rjT&q(k-4WC;EA\XR/e3B<Pu0hX@^eq)V96m1/9n]aMGiB;>b- -<Qhpg%fZ%iL0M[*a?"P=!QaKpG85c">^P;JnCj0O_"!ehl'FQLO!VC14K_9+F#3aS -`UIe!<RB"H*ojg$gmd(9FaZWNi+u^)A&S#1YCFECG]m`U>d]Aa4iMN5s1m)Y/EelZ -e$RFXg_UXgEc[d(/+DS;:.Gf3nsl`nYdt'ZCPFMrUJ?-$\#i9X^<JXH&s?o:mtLg* -p]_)^Wn;23J2RU.g_n#&BP3)l$pHU@K+@Zb4=?,j_*E=V82;+hn6*93j.QVlWRlak -AduR4cLRYg>s8M8!?Y]gIN/aD:p!=T5A)tUQ203f#pfkN0Q<4Par>bbJIs2=:@jHL --q3OB)El$]S^HF\D938&XHXe=;9B]3+JgJMe>X+E`)%U16-_VAWqTFK!c3l;3''S1 -\!,8CIZO$i_mJ3n!LemnW\cK0q"4R3d[*F#!95&lbSW^GCdRWeKZJo-*"tST%Yb,k -Jg@LP_oQd*TR\d%nB)`gEHNVl>ihP&/f+TID?NM,J\u/?eY1DVLTb,m]qA1q6_JQ3 -7J\=)&FUe#;tl(t&GcN-RQs+~> -endstream -endobj -163 0 obj -1544 -endobj -161 0 obj -<< -/Type /Page -/Parent 149 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 162 0 R ->> -endobj -165 0 obj -<< -/Length 166 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ9b.gZ6e*l8sc3%Q0LgYO1$LHWL -.2LC7,2n?NN-.&rnL!jL<6AG`N5k!eOaPlP$t0.G^-)M<>TAG".,:U,,@Jq_4UQ3I -"H7n>5W5l79JHeVYV9u&"9Yrk]eBJk:cXLgTXY]@b^^D3Xc>H2VlEMQ$lQFOJg)'a -NgO#+/L^1?'F!Go0_gW[W5p`I!\i%\%'430NeOLU4OsZ:)\b$K10?dR,/Z71q$"Z$ -7-hK/Qu[qS_P:6laC.nOl\2Z=edtHQ]WME.mppbgaIra&1IEgbl8O[J[)DqRJS<ak -N+8%B.F-CQpGaQWPj(fd'"$IY2aNO5PK7/Q#/s/c0]"erK6Z645[aZV4H9Lp/3"(` -*H,2@n6#,e0iD-D$W.![jt_sKrDkb6p)qUi=T\BBpcpQ=d"mH5]\>Bd8dMsBb&a\i -42!H#4qnNN]FSjT@7@q*gh:QJ*jq3uJgs<""#)\AU.F'##(lX7I5:o[eSN[`r@rM$ -$>%2!hGN)&HV`o9oJGHlp&T_PQ7\/.bTg^/8mX!%'lMusL*8Zg<;n>2@cN2#JDbYp -gb"HZ^nG"i_B>!gMn'annDP6B\U7W6CoN`D(Oa2q>af4i5@sorbuMPF6SK&VW&T"' -LOfVJ1"ep%a;0QK,W2cb+]qeH7@>K(D5[5*<MJ>pS:QR`=g5=kMn8&i?4Hcid@9VD -&/D-P3]r1q.>TnRF7L"-)4"OZY4ns]j-I$Rlan4]ZgBh\^^t-'L3><7\c19kDAYOi -PN`r[T9Abmeu@B]JHle&l_0@SbO1a)/'2O3[N3Qc3h>_eKGaBWORPPkLQ_GC7k9A` -)O=aeC>-X:@#Ukr[N"u[oT*F.r!pW6r>T/#p3ds8Xgr,ZcYMS4(T-Qdfiu^Jmm2@^ -f09!P0K+>4=nTL*[fV*_mt'j1#/H>3rL8^4HO='G1oHGt?i/#j%scF6#C?KD)tSWr -ecif9faAp\^'enc(IGVagY]X^DK'Uo_<:[,?JE\WNpZs1f>?^E9C)kE[L._uQOI$0 -989X=-,G@Ij'/S,BlJYU4iX6&+<))Pd%0\aW"9`\S4nn3VC4oi.2q0WZ%!8.a$LWO -s.\jHN"D:!`]+>D@V@NV:oX%W.,,l=Qs5YL=ujQWN=VUsH%^2*,"=!Z&YVU)OF_3b -a>_d"@r.]u13Q,SVt1E=I#rV.#"cSn_V\n:A!8W((eNp3/RrV)OYYKc\@=Ha,tiH? -o"%"VBk$O49T<`5Al_/6L@aOaa*4^YA?@ZIp#4]ANmW-.a[r0W-Bl,.C;j>V:dC/* ->D$aLq6U>k_Ar^dE*knKC'F;tn05NgOn/otbXj<E-O`J7D/+*eaj:B-<:-7J`cTNq -T#]DYE`nA+I(uY5!$:L`Dj1GN:KBg:VSoC%;G(S!VQ32hm1km"DEULI;_ji=,]<ke -RBl(7OV0?"Vc<)U;qcXql30JP<<[e"Uo+I>4E[P,?DKNZrX+fE<a(A!FTio1R"55u -;+Z^-#;AG+>8VGlUfje1-OL_=8e!t8S`l`X^)d\G9QLpp9[t%A5_21/XoZff`Ob7? -.YW)*Fm-`nU'(umn/r5A[_a=<,@&i;JZr'D[TJ&F*c,D7Y"P(qfdeF$88XY'<bAkk -HQ]lcoq.;`QHL]2)eR3O/$K?*dojha2q/:([oVqR>KVk@$=T,!6j*~> -endstream -endobj -166 0 obj -1969 -endobj -164 0 obj -<< -/Type /Page -/Parent 149 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 165 0 R ->> -endobj -169 0 obj -<< -/Length 170 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -ZjKqQ(sBqZR)$pb+=^21`BtY*mKtP'$:[qOb[rdhR*LGMH+6+X1C+CJj%6Vp.3-Z& -#'!@::h:?-8q`j;:=!"1@R^GCKY1JH)ob?7R_4GQ1`;0CL9.LRA0B)_CQSCkJ9-Pb -`l@$nOLSl*["=",!H?)1D\O*b"Tq>TLh/T6c<R-<]]:1M*'(Ja0sEoJ'F6^(c?DXP -eE_9>7PaePfOPbBNQ4^)i6l]8MKN+D0Xb05Xh[b04hk\J>2Haq'8GMVn.7kT3GrW( -kdk8VWp@8LBYHD6UUYLQ`"<DH&-_#kj?!dFOQ\HYJHOIa%]PBoQ8cu2*\&F.>EBR' -n0hKZ1hfV\iiNbjLuU&s6ltFsU.aVe$h'l\1l]Bqaug(%6M)jfmi.]C#_GU90#R3- -5W0)3HaP?GiG>n0`bB7A)oj^-"Wg1^"Do<t&6t;H8Pk)0-d".`c8(Bs39W1l/'-s- -9>_ac0hdZZqZ"X@FTj-&P(]YD$nnjJ7a#i=,=tQb(jAUU'BM"=_A))p6NdL6+]Hg3 -<G<#g_f4m!N)<4H^q2tLau2HsTKk8k,8eff`i2S^3m\PQHI]N(e:gRd%MXs.eeR#[ -ESQZjbVClZ5j#cieqE4#^`c,9Ce+)]pMNOKAF3JjQ'D_+^*?TAEn>@hd5=*cYjlp, -f7\9^:H,\j,$VDH_'P*U*BSbh9E<9sN2*0%l&>:@Yl;HRHlk.:K1bhkNK:Td]s"j] -5rZBmSf)6@3.9n([?n"j<ol<C^O<rY1XbbT5lc4c6g.Wt(ILu;a;0Q_5hi5k@9`=) -\"UTLMH/6k;-OJRm[^@@R^TK.;R`O@Z072@<"Nb=^6jW=mp"N?lPe?K&8H>Da^"/# -n@8F-okj4n62QDf)!'$)>-dSnbJ*K7RYI<KdQBn9Y3Yeu>*]BjFt%/d&1:-f-&Xt1 -I*_4KWJ+<9Iab]Z*39UiKbY!agl$U;TAIWE3+LW]q=+:Bp&U4Q"7Fl#okNBC%[l9? -!UcP1EI.aC\or$/\[@/tpSkE6Scg-Fj:<'6nGN:T5hGol`om'gIl0XThc'Dp8-)gU -a,'Q-Bs;GK4^11-'WXr\^1@gSdie/4U(gLa:#Tn*2Q-VV+"FL9:$r!Ap=S9V]3-hj --.87'"UJMIM,A1'j""2gg6"3HK.t[P2\q#Rg+3sA$(0s.`)^92WZ>r4^mL`*`gVP$ -+AlR3&-diUQ%P4hAdP+bZT+m&6RZe4_<%5c7H1u6$JKBr-#Yqh!oK*u(2<&%+iOGD -("O$lDp;DZOCo@4TGr*8#^*qh0Z)Pf0PlZ-C_/R9RM<Y1HA[jL%7_*&IUiQ1NJm=* -KOCAcJd>$VJUA@Y;\BPUYnULETr%s&X:l7<E'?#CpWGQHLJNi;9((d8Z0"<mNj*4+ -i3<?HctX$+Uk*@1q2hmBK^U20^k?TGBL6EI$="7>EDA4=4K#(J=50mIY=<HFeh"Pt -AAD`8Y&qnGc3P?\3eh@]O#sRFnj/tg2fgGl0M21u%g1Qc:?Hl<[uViOr#gF:re;U' -FI";M2Zs-GKg4,*6YH?!G]ZC1^mZ>S)cMZUo+^&Fi\pU=E]uFZgjqd.o$Cr1WJtY) -F1m5J9O_FZOD&rtTF+T*!\$hd+9~> -endstream -endobj -170 0 obj -1745 -endobj -167 0 obj -<< -/Type /Page -/Parent 168 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 169 0 R ->> -endobj -172 0 obj -<< -/Length 173 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ9d_AKqnmpRFF@Tgo)3/Z!.tr-` -.2IpJ@mNC;_J:opN@)Oq4!4m7gGniZI7QUC]Kr#ZQj2fdf]e(j)m4esWJWgh"g-5$ -O!kQ15V\8YB]/]c!<BVD5(fO#UQ.kajuNm$9GS1*TlNoZ+Msp)"Y"-O>8MieN*QP* -@/u$&"9PNh.L@;\Yn)d\GiUdlUNflP$pt<Q1rV4pJi4)G,X+5KUM.M*%RUY''uo`h -Jg#qY!.,*JF!@qH6IGZ;`=AZ]5,&NSP7K-r!gnun_rDTVq@#_>k9nHjOR0q^Jsbg^ -$0%I=4Xd'jhD.cEX;M6MNFISuc!qU22^\-H7c01M'Z3(1dj7"M<:JP\<)l9kj?1u? -FPnPR+rJ$@#pKpH2+<[qi$]$l*AnU,o]h'-YsTA\3fJ\>5l!Tp!9#Sj(!LV2#pO>C -.G/hqeeX)cGj7;L6$V$@N,k"eB\IX38H[NE"JdqVQ*kEbe[A`+B*B%SKlYge=@j%T -Q1bY$fV<<P1Ia*i]e`/TS7Q?Rd*+EE7&#!d1l^O:)hD#RrL]#$fZ\T5Lk7%..Z!d@ -=u59)n=D%!NBPQ7k;,)V-3teYaYe_g=AbXP\;$8fgiU],:"NJiLS<qC4bokG3LGl* -6i)K_'jt'Z4=1?&`f4GA>%!L?l;=ugK'bTGf7cTgmV02IRl35Lj3O:sM[dK+WtL-: -SZtONJS9EB"iGbl%V5F+=d7pV?;[`>&=-W:"i?Y,,7).WYTesF#:%;m>dakS6Ac9e -aG3O%,)A<DHumVW+\%_RC^Ls.Z,Muq800h^DfKAg\0^h[8.8>]U^i@!h<BqeTYA8e -__^L2qS)F43\?s8bOBk./*$0s@@YEdTsuJHl:;QZ'JK;g?g$eH4gM'r?-@;5i=4_R -LPE_JCQ\gO!"_A&h#8A,qKhU-e[21pfa;63J.FA^'GpK:K5:,g0AZQ:-pI@^l8<bS -D;@;754ASG8OMtb]0&UsdU6SqJcXR34buB-@@G#M0PT=Oi)'6A"<r<`M:KOpkmC$n -.tB6kTYNMoh-/#.JPbJ@_"a;XU3&Y.YmLmaR&($$KMD_K.PEuqReko'jGF*us2?k1 -'qpR%M[^RV6\lZt6Mt17Z,,oCBGD(F'LRi;[Ne3'di0P@DN#2@&4gI3o&4D0L/$(u -_\d:nj8;Q5;@W(b(Xj4o]?-1U2G-0d+X!S"D)>hd'h;=Y'd7UiMXkm*7Cbc)?M&0# -YG,/lLrh-C[#B:1H6#=Q&G0A"r*-,Laag)e~> -endstream -endobj -173 0 obj -1555 -endobj -171 0 obj -<< -/Type /Page -/Parent 168 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 172 0 R ->> -endobj -175 0 obj -<< -/Length 176 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>87g2/;+p]nQ(a(\'"iF1<gd!Y3%L0cOBRmNsK,Gf9nYkM`/fBHM"$qlV -EZd@[5t56Ye7C"sL^*FTE8E!["V'S"l.#9[C]tNh6mAFcW,e$:"ls*N)?a$.$t)nH -Zj:>(N"./oEQhg&3"QfQ&7V>nS9G,P`<=WrXAV'MM@?>tR*9A_15\`$6;T/0BWKB& -"&XTiDBK^SL@LCfk-#sC%0iPiTrSW%)$hrNRcHZ4+<95ke"NRFAYHL5Ka*`\fZJ4q -$]Xu+nDYcK)FMZ1+_\Yr1"]_7"/,qJD7CB#2h7T>q\d3cbB!=TQTK),0:R/k5.:WJ -`8bki4K`=DU!h6Z4M?<-]3unlEfHq:TmgH,%?DIfq7Q-jdc@i3A,a7PD9Lk`3j&:` -m4C!/f%E?!//nUKY`oLS\F;kOQjg2%2$Z0]Mlt,fNZ5JB6SN<@h8""#f^qQc]LNgX -%uaKZ4"`WG(WVRFB(AF>*'j0(O(:fq6Z@D6%nJ>-o*e$kA&(!t&YqK'`pbg+-G_Hb -[-5)1.[km<~> -endstream -endobj -176 0 obj -540 -endobj -174 0 obj -<< -/Type /Page -/Parent 168 0 R -/Resources << -/Font << -/F8 10 0 R -/F10 20 0 R -/F12 21 0 R ->> -/ProcSet 2 0 R ->> -/Contents 175 0 R ->> -endobj -178 0 obj -<< -/Length 179 0 R -/Filter [ /ASCII85Decode /LZWDecode ] ->> -stream -J.+gME)=>9"r`LkU>_JiE&8DiLBEY>aN=iG!f099."J7:Nkkn[@A&2T</ccD:hV\a -5W=LX7^DR*aBUKX'b.FrToOAA"UYNIK*f?WAN:)iL7hA_=U1-`7K\3\cuCn3:*\5m -5mETJOjg,RktJ7R/f9PIK.=grF#tt2$5AVu/8?RlMJ9q[4X=Jn(L>63d/brLF#k46 -`cINC\l9sWLp>#U*h"3.e-T+W<$)/a4,=)\+g?Kc+>&pf`^!AMAYU,:`piM;hIenh -N$eERVV".M"VfuoaW4\`AZ/70>ENmYB3(MdB2fJ9g:rf25X5~> -endstream -endobj -179 0 obj -314 -endobj -177 0 obj -<< -/Type /Page -/Parent 168 0 R -/Resources << -/Font << -/F4 8 0 R -/F8 10 0 R -/F10 20 0 R ->> -/ProcSet 2 0 R ->> -/Contents 178 0 R ->> -endobj -7 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F2 -/BaseFont /Helvetica -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -8 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F4 -/BaseFont /Times-Roman -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -9 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F6 -/BaseFont /Times-Bold -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -10 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F8 -/BaseFont /Helvetica-Bold -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -20 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F10 -/BaseFont /Times-Italic -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -21 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F12 -/BaseFont /Courier -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -99 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F15 -/BaseFont /Courier-Bold -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -100 0 obj -<< -/Type /Font -/Subtype /Type1 -/Name /F17 -/BaseFont /Courier -/FirstChar 32 -/LastChar 255 -/Encoding 6 0 R ->> -endobj -2 0 obj -[ /PDF /Text ] -endobj -5 0 obj -<< -/Kids [4 0 R 13 0 R 16 0 R 19 0 R 25 0 R 28 0 R ] -/Count 6 -/Type /Pages -/Parent 180 0 R ->> -endobj -32 0 obj -<< -/Kids [31 0 R 35 0 R 38 0 R 41 0 R 44 0 R 47 0 R ] -/Count 6 -/Type /Pages -/Parent 180 0 R ->> -endobj -51 0 obj -<< -/Kids [50 0 R 54 0 R 57 0 R 60 0 R 63 0 R 66 0 R ] -/Count 6 -/Type /Pages -/Parent 180 0 R ->> -endobj -70 0 obj -<< -/Kids [69 0 R 73 0 R 76 0 R 79 0 R 82 0 R 85 0 R ] -/Count 6 -/Type /Pages -/Parent 180 0 R ->> -endobj -89 0 obj -<< -/Kids [88 0 R 92 0 R 95 0 R 98 0 R 104 0 R 107 0 R ] -/Count 6 -/Type /Pages -/Parent 180 0 R ->> -endobj -111 0 obj -<< -/Kids [110 0 R 114 0 R 117 0 R 120 0 R 123 0 R 126 0 R ] -/Count 6 -/Type /Pages -/Parent 180 0 R ->> -endobj -130 0 obj -<< -/Kids [129 0 R 133 0 R 136 0 R 139 0 R 142 0 R 145 0 R ] -/Count 6 -/Type /Pages -/Parent 181 0 R ->> -endobj -149 0 obj -<< -/Kids [148 0 R 152 0 R 155 0 R 158 0 R 161 0 R 164 0 R ] -/Count 6 -/Type /Pages -/Parent 181 0 R ->> -endobj -168 0 obj -<< -/Kids [167 0 R 171 0 R 174 0 R 177 0 R ] -/Count 4 -/Type /Pages -/Parent 181 0 R ->> -endobj -180 0 obj -<< -/Kids [5 0 R 32 0 R 51 0 R 70 0 R 89 0 R 111 0 R ] -/Count 36 -/Type /Pages -/Parent 182 0 R ->> -endobj -181 0 obj -<< -/Kids [130 0 R 149 0 R 168 0 R ] -/Count 16 -/Type /Pages -/Parent 182 0 R ->> -endobj -182 0 obj -<< -/Kids [180 0 R 181 0 R ] -/Count 52 -/Type /Pages -/MediaBox [ 0 0 595 841 ] ->> -endobj -1 0 obj -<< -/CreationDate (Thursday, May 25, 2000 9:31 AM MET DST) -/Producer (Acrobat Distiller Command 1.0 for Solaris 1.1/2.3 (SPARC)) ->> -endobj -3 0 obj -<< -/Pages 182 0 R -/Type /Catalog ->> -endobj -xref -0 183 -0000000000 65535 f -0000119342 00000 n -0000117995 00000 n -0000119490 00000 n -0000002264 00000 n -0000118026 00000 n -0000002417 00000 n -0000116983 00000 n -0000117107 00000 n -0000117233 00000 n -0000117358 00000 n -0000000010 00000 n -0000002243 00000 n -0000004748 00000 n -0000003609 00000 n -0000004727 00000 n -0000006579 00000 n -0000004868 00000 n -0000006558 00000 n -0000009314 00000 n -0000117488 00000 n -0000117617 00000 n -0000006722 00000 n -0000009293 00000 n -0000009424 00000 n -0000011679 00000 n -0000009511 00000 n -0000011658 00000 n -0000012590 00000 n -0000011822 00000 n -0000012570 00000 n -0000014763 00000 n -0000118135 00000 n -0000012735 00000 n -0000014742 00000 n -0000015322 00000 n -0000014907 00000 n -0000015302 00000 n -0000017950 00000 n -0000015468 00000 n -0000017929 00000 n -0000021416 00000 n -0000018107 00000 n -0000021395 00000 n -0000024229 00000 n -0000021586 00000 n -0000024208 00000 n -0000027390 00000 n -0000024388 00000 n -0000027369 00000 n -0000031019 00000 n -0000118246 00000 n -0000027547 00000 n -0000030998 00000 n -0000034654 00000 n -0000031178 00000 n -0000034633 00000 n -0000037130 00000 n -0000034813 00000 n -0000037109 00000 n -0000037712 00000 n -0000037289 00000 n -0000037692 00000 n -0000040435 00000 n -0000037858 00000 n -0000040414 00000 n -0000043571 00000 n -0000040579 00000 n -0000043550 00000 n -0000046708 00000 n -0000118357 00000 n -0000043730 00000 n -0000046687 00000 n -0000050184 00000 n -0000046867 00000 n -0000050163 00000 n -0000053789 00000 n -0000050343 00000 n -0000053768 00000 n -0000056707 00000 n -0000053948 00000 n -0000056686 00000 n -0000058178 00000 n -0000056877 00000 n -0000058157 00000 n -0000060976 00000 n -0000058326 00000 n -0000060955 00000 n -0000065153 00000 n -0000118468 00000 n -0000061135 00000 n -0000065132 00000 n -0000067950 00000 n -0000065323 00000 n -0000067929 00000 n -0000070796 00000 n -0000068109 00000 n -0000070775 00000 n -0000073910 00000 n -0000117741 00000 n -0000117870 00000 n -0000070955 00000 n -0000073888 00000 n -0000074023 00000 n -0000076758 00000 n -0000074116 00000 n -0000076736 00000 n -0000077669 00000 n -0000076932 00000 n -0000077648 00000 n -0000078748 00000 n -0000118581 00000 n -0000077830 00000 n -0000078727 00000 n -0000079324 00000 n -0000078908 00000 n -0000079303 00000 n -0000081500 00000 n -0000079473 00000 n -0000081478 00000 n -0000083713 00000 n -0000081660 00000 n -0000083691 00000 n -0000085683 00000 n -0000083875 00000 n -0000085661 00000 n -0000087611 00000 n -0000085834 00000 n -0000087589 00000 n -0000089502 00000 n -0000118699 00000 n -0000087773 00000 n -0000089480 00000 n -0000091371 00000 n -0000089653 00000 n -0000091349 00000 n -0000093575 00000 n -0000091533 00000 n -0000093553 00000 n -0000095650 00000 n -0000093726 00000 n -0000095628 00000 n -0000097685 00000 n -0000095812 00000 n -0000097663 00000 n -0000099833 00000 n -0000097836 00000 n -0000099811 00000 n -0000101713 00000 n -0000118817 00000 n -0000099995 00000 n -0000101691 00000 n -0000103649 00000 n -0000101864 00000 n -0000103627 00000 n -0000105582 00000 n -0000103811 00000 n -0000105560 00000 n -0000107522 00000 n -0000105733 00000 n -0000107500 00000 n -0000109346 00000 n -0000107684 00000 n -0000109324 00000 n -0000111584 00000 n -0000109497 00000 n -0000111562 00000 n -0000113609 00000 n -0000118935 00000 n -0000111746 00000 n -0000113587 00000 n -0000115433 00000 n -0000113760 00000 n -0000115411 00000 n -0000116252 00000 n -0000115595 00000 n -0000116231 00000 n -0000116834 00000 n -0000116403 00000 n -0000116813 00000 n -0000119037 00000 n -0000119150 00000 n -0000119245 00000 n -trailer -<< -/Size 183 -/Root 3 0 R -/Info 1 0 R ->> -startxref -119541 -%%EOF diff --git a/Utilities/IpPic/endian.c b/Utilities/IpPic/endian.c deleted file mode 100755 index 31ddd1f570..0000000000 --- a/Utilities/IpPic/endian.c +++ /dev/null @@ -1,57 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -union { - unsigned short s; - unsigned char b; -} t = { 0x1234 }; - -void main( void ) -{ - - /*t.s = 0x1234;*/ - - if( t.b == 0x12 ) - printf( "big\n" ); - else - printf( "little\n" ); - -} diff --git a/Utilities/IpPic/files.cmake b/Utilities/IpPic/files.cmake deleted file mode 100644 index ef022fffa9..0000000000 --- a/Utilities/IpPic/files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -set(CPP_FILES - ipPicInfo.c ipPicType.c - ipPicAddT.c ipPicQueryT.c ipPicDelT.c ipPicGetT.c - ipPicOldGet.c ipPicOldGetH.c ipPicOldGetS.c - ipPicGet.c ipPicGetH.c ipPicGetS.c - ipPicPut.c ipPicPutS.c - ipPicGetMem.c ipPicPutMem.c - ipPicCopyS.c ipPicCopyH.c - ipPicNew.c ipPicClear.c ipPicFree.c ipPicClone.c - ipEndian.c ipFRead.c ipFWrite.c - ipError.c - ipPicSize.c ipPicElements.c - ipPicTSVSize.c ipPicTSVElements.c - ) - diff --git a/Utilities/IpPic/ipEndian.c b/Utilities/IpPic/ipEndian.c deleted file mode 100755 index c1c2ed6193..0000000000 --- a/Utilities/IpPic/ipEndian.c +++ /dev/null @@ -1,149 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * $RCSfile$ - *--------------------------------------------------------------- - * DESCRIPTION - * Routines for the conversion of Data - * between different machine representations - * - * $Log$ - * Revision 1.10 2004/01/17 22:58:18 andre - * big endian fixes - * - * Revision 1.6 2004/01/17 22:56:18 uid9277 - * big endian fixes - * - * Revision 1.5 1999/11/27 23:59:45 andre - * *** empty log message *** - * - * Revision 1.4 1999/11/27 19:15:08 andre - * *** empty log message *** - * - * Revision 1.3 1998/11/11 11:11:26 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:07 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:58 andre - * initial import - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *--------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)ipEndian\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include <stdio.h> - -#include "mitkIpPic.h" - -_mitkIpEndian_t _mitkIpEndian( void ) -{ - static union - { mitkIpUInt2_t s; - mitkIpUInt1_t b; - } t = { 0x1234 }; - - if( t.b == 0x12 ) - return( _mitkIpEndianBig ); - if( t.b == 0x34 ) - return( _mitkIpEndianLittle ); - else - { - fprintf( stderr, "%s:_mitkIpEndian: WARNING: unknown endian !!!\n", __FILE__ ); - return( _mitkIpEndianUnknown ); - } -} - -void _mitkIpCp( void *source, void *destination, unsigned long int len ) -{ - if( !source ) - return; - if( !destination ) - return; - - memmove( destination, source, len ); -} - -void _mitkIpCvtEndian( void *data, unsigned long int len, unsigned char bytes ) -{ - unsigned long int i; - unsigned char i2; - char buff; - - if( !data ) - return; - - for( i=0; i<len; i+=bytes ) - for( i2=0; i2<bytes/2; i2++ ) - { - buff = ((char *)data)[i+i2]; - ((char *)data)[i+i2] = ((char *)data)[i+bytes-i2-1]; - ((char *)data)[i+bytes-i2-1] = buff; - } -} - -void _mitkIpCpCvtEndian( void *source, void *destination, unsigned long int len, unsigned char bytes ) -{ - unsigned long int i; - unsigned char i2; - - if( !source ) - return; - if( !destination ) - return; - - if( bytes == 1 ) - memmove( destination, source, len ); - else - for( i=0; i<len; i+=bytes ) - for( i2=0; i2<bytes; i2++ ) - { - ((char *)destination)[i+i2] = ((char *)source)[i+bytes-i2-1]; - } -} diff --git a/Utilities/IpPic/ipError.c b/Utilities/IpPic/ipError.c deleted file mode 100755 index 815215a529..0000000000 --- a/Utilities/IpPic/ipError.c +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * maps @c mitkIpError_t type values to printable strings -*/ - -#ifndef lint - static char *what = { "@(#)mitkIpError\t\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include <stdio.h> - -#include "mitkIpTypes.h" - -/** maps mitkIpError_t type values to printable strings - * @param error the error number - * @return the printable string - * - * AUTHOR & DATE - */ - -char *mitkIpErrorStr( mitkIpError_t error ) -{ - char *str; - - switch( error ) - { - case mitkIpError : - str = "generic error"; - break; - case mitkIpOK : - str = "No Error"; - break; - default: - str = "mitkIpError: Unknown Error"; - fprintf( stderr, "mitkIpErrorStr: sorry, unknown error (#%i)\n", error ); - break; - } - - return( str ); -} diff --git a/Utilities/IpPic/ipFRead.c b/Utilities/IpPic/ipFRead.c deleted file mode 100755 index 19a42042c0..0000000000 --- a/Utilities/IpPic/ipFRead.c +++ /dev/null @@ -1,174 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads big- and litle- endian from disk - * and swaps to the other endianess - * - * $Log$ - * Revision 1.14 2005/09/09 09:14:45 ivo - * FIX: warnings on windows - * - * Revision 1.13 2003/03/06 10:53:08 andre - * *** empty log message *** - * - * Revision 1.12 2002/11/13 17:52:59 ivo - * new ipPic added. - * - * Revision 1.10 2002/02/27 08:54:43 andre - * zlib changes - * - * Revision 1.9 2000/05/04 12:52:35 ivo - * inserted BSD style license - * - * Revision 1.8 2000/01/17 18:31:59 andre - * *** empty log message *** - * - * Revision 1.7 1999/12/09 19:12:09 andre - * *** empty log message *** - * - * Revision 1.5 1999/11/29 09:34:34 andre - * *** empty log message *** - * - * Revision 1.4 1999/11/28 16:27:20 andre - * *** empty log message *** - * - * Revision 1.3 1999/11/27 19:15:08 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:08 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:58 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)_ipFRead\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include <stdio.h> -#include <stdlib.h> -#ifdef WIN32 -#include <io.h> -#else -#include <unistd.h> -#endif - -#include "mitkIpPic.h" - -size_t -mitkIpFReadCvt( void *ptr, size_t size, size_t nitems, FILE *stream ) -{ - size_t bytes_return; - - bytes_return = fread( ptr, size, nitems, stream ); - _mitkIpCvtEndian( ptr, size*nitems, size ); - - return( bytes_return ); -} - -#ifdef USE_ZLIB -mitkIpBool_t _mitkIpPicCanReadCompressed = mitkIpTrue; -#else -mitkIpBool_t _mitkIpPicCanReadCompressed = mitkIpFalse; -#endif - -size_t -mitkIpPicFReadCvt( void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream ) -{ - size_t bytes_return; - - bytes_return = mitkIpPicFRead( ptr, size, nitems, stream ); - - _mitkIpCvtEndian( ptr, size*nitems, size ); - - return( bytes_return ); -} - -int -mitkIpPicAccess( const char *path, int mode ) -{ - int status; - - status = access( path, mode ); - - if( status == -1 ) - { - char buff[1024]; - - sprintf( buff, "%s.gz", path ); - - status = access( buff, mode ); - } - - return( status ); -} -int -mitkIpPicRemoveFile( const char *path ) -{ - int status; - - status = remove( path ); - - if( status != 0 ) - { - char buff[1024]; - - sprintf( buff, "%s.gz", path ); - - status = remove( buff ); - } - - return( status ); -} diff --git a/Utilities/IpPic/ipFWrite.c b/Utilities/IpPic/ipFWrite.c deleted file mode 100755 index cc17208106..0000000000 --- a/Utilities/IpPic/ipFWrite.c +++ /dev/null @@ -1,156 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * writes big- and litle- endian to disk - * and swaps to the other endianess - * - * $Log$ - * Revision 1.8 2003/02/18 12:28:23 andre - * write compressed pic files - * - * Revision 1.7 2002/11/13 17:52:59 ivo - * new ipPic added. - * - * Revision 1.5 2000/05/04 12:52:35 ivo - * inserted BSD style license - * - * Revision 1.4 2000/05/04 12:35:57 ivo - * some doxygen comments. - * - * Revision 1.3 1997/09/15 13:22:32 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:09 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:58 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)_mitkIpFWrite\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include <stdio.h> -#include <stdlib.h> - -#include "mitkIpPic.h" - -#ifdef USE_ZLIB -mitkIpBool_t _mitkIpPicCanWriteCompressed = mitkIpTrue; -#else -mitkIpBool_t _mitkIpPicCanWriteCompressed = mitkIpFalse; -#endif - - -static mitkIpBool_t mitk_write_compressed = mitkIpFalse; - -mitkIpBool_t -mitkIpPicGetWriteCompression( void ) -{ - return( mitk_write_compressed ); -} - -mitkIpBool_t -mitkIpPicSetWriteCompression( mitkIpBool_t compression ) -{ - mitkIpBool_t compression_old = mitk_write_compressed; - - mitk_write_compressed = compression; - - return( compression_old ); -} - -size_t -mitkIpFWriteCvt( void *ptr, size_t size, size_t nitems, FILE *stream ) -{ - size_t bytes_return; - - void *buff; - buff = malloc( size * nitems ); - _mitkIpCpCvtEndian( ptr, buff, size*nitems, size ); - bytes_return = fwrite( buff, size, nitems, stream); - free( buff ); - - return( bytes_return ); -} - -size_t -_mitkIpPicFWrite( const void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream) -{ - size_t bytes_return; - -#ifdef USE_ZLIB - if( mitk_write_compressed ) - bytes_return = gzwrite( stream, (void *)ptr, size*nitems); - else -#endif - bytes_return = fwrite( ptr, size, nitems, (FILE *)stream ); - - return( bytes_return ); -} - -size_t -mitkIpPicFWriteCvt( void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream ) -{ - size_t bytes_return; - - void *buff; - buff = malloc( size * nitems ); - _mitkIpCpCvtEndian( ptr, buff, size*nitems, size ); - bytes_return = mitkIpPicFWrite( buff, size, nitems, stream); - free( buff ); - - return( bytes_return ); -} diff --git a/Utilities/IpPic/ipPic.dox b/Utilities/IpPic/ipPic.dox deleted file mode 100755 index 03d8f45c64..0000000000 --- a/Utilities/IpPic/ipPic.dox +++ /dev/null @@ -1,401 +0,0 @@ -# Doxyfile 0.49-990829 - -# This file describes the settings to be used by doxygen for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of word surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = ipPic - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 1 - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Dutch, French, Italian, Czech, Swedish, German and Japanese - -OUTPUT_LANGUAGE = English - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# If the EXTRACT_ALL tag is set to YES all classes and functions will be -# included in the documentation, even if no documentation was available. - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members inside documented classes or files. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSESS tag is set to YES, Doxygen will hide all -# undocumented classes. - -HIDE_UNDOC_CLASSES = YES - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# If the FULL_PATH_NAMES tag is set to YES Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. - -STRIP_FROM_PATH = - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a class diagram (in Html and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. - -CLASS_DIAGRAMS = YES - -# If the SOURCE_BROWSER tag is set to YES than the body of a member or -# function will be appended as a block of code to the documentation of. -# that member or function. - -SOURCE_BROWSER = NO - -# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen -# will only generate file names in lower case letters. If set to -# YES upper case letters are also allowed. This is useful if you have -# classes or files whose names only differ in case and if your file system -# supports case sensitive file names. - -CASE_SENSE_NAMES = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = NO - -# If the JAVADOC_NO_AUTOBRIEF is set to YES (the default) then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the Javadoc-style will -# behave just like the Qt-style comments. - -JAVADOC_AUTOBRIEF = YES - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . mitkIpPic.h - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -FILE_PATTERNS = *.c - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. - -INPUT_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. - -MACRO_EXPANSION = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. - -PREDEFINED = DOXYGEN_IGNORE - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED tag. - -EXPAND_ONLY_PREDEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tagfiles. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO - -# The CGI_NAME tag should be the name of the CGI script that -# starts the search engine (doxysearch) with the correct parameters. -# A script with this name will be generated by doxygen. - -CGI_NAME = search.cgi - -# The CGI_URL tag should be the absolute URL to the directory where the -# cgi binaries are located. See the documentation of your http daemon for -# details. - -CGI_URL = - -# The DOC_URL tag should be the absolute URL to the directory where the -# documentation is located. If left blank the absolute path to the -# documentation, with file:// prepended to it, will be used. - -DOC_URL = - -# The DOC_ABSPATH tag should be the absolute path to the directory where the -# documentation is located. If left blank the directory on the local machine -# will be used. - -DOC_ABSPATH = - -# The BIN_ABSPATH tag must point to the directory where the doxysearch binary -# is installed. - -BIN_ABSPATH = /usr/local/bin/ - -# The EXT_DOC_PATHS tag can be used to specify one or more paths to -# documentation generated for other projects. This allows doxysearch to search -# the documentation for these projects as well. - -EXT_DOC_PATHS = - diff --git a/Utilities/IpPic/ipPic.pro b/Utilities/IpPic/ipPic.pro deleted file mode 100755 index 8324a0b827..0000000000 --- a/Utilities/IpPic/ipPic.pro +++ /dev/null @@ -1,30 +0,0 @@ -TEMPLATE = lib -TARGET = libipPic - -CONFIG += warn_on release -unix:CONFIG += staticlib - -OBJECTS_DIR = obj -DESTDIR = . - -SOURCES = \ - mitkIpPicInfo.c mitkIpPicType.c \ - mitkIpPicAddT.c mitkIpPicQueryT.c mitkIpPicDelT.c mitkIpPicGetT.c \ - mitkIpPicOldGet.c mitkIpPicOldGetH.c mitkIpPicOldGetS.c \ - mitkIpPicGet.c mitkIpPicGetH.c mitkIpPicGetS.c \ - mitkIpPicPut.c mitkIpPicPutS.c \ - mitkIpPicGetMem.c mitkIpPicPutMem.c \ - mitkIpPicCopyS.c mitkIpPicCopyH.c \ - mitkIpPicNew.c mitkIpPicClear.c mitkIpPicFree.c mitkIpPicClone.c \ - ipEndian.c ipFRead.c ipFWrite.c \ - ipError.c \ - mitkIpPicSize.c mitkIpPicElements.c \ - mitkIpPicTSVSize.c mitkIpPicTSVElements.c - -win32:SOURCES+= win32/zlib.lib - -HEADERS = mitkIpPic.h mitkIpTypes.h mitkIpPicOldP.h mitkIpPicAnnotation.h - -INCLUDEPATH = .. . -win32:INCLUDEPATH+=win32 - diff --git a/Utilities/IpPic/ipPicAddT.c b/Utilities/IpPic/ipPicAddT.c deleted file mode 100755 index 35bec09865..0000000000 --- a/Utilities/IpPic/ipPicAddT.c +++ /dev/null @@ -1,103 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/** @file - * inserts a tsv into the pic - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicAddTag\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - - -void -mitkIpPicAddTag( mitkIpPicDescriptor *pic, mitkIpPicTSV_t *tsv ) -{ - pic->info->tags_head = _mitkIpPicInsertTag( pic->info->tags_head, tsv ); -} - -void -mitkIpPicAddSubTag( mitkIpPicTSV_t *parent, mitkIpPicTSV_t *tsv ) -{ - if( parent->type != mitkIpPicTSV ) - return; - - parent->n[0]++; - parent->value = _mitkIpPicInsertTag( parent->value, tsv ); -} - -_mitkIpPicTagsElement_t * -_mitkIpPicInsertTag( _mitkIpPicTagsElement_t *head, mitkIpPicTSV_t *tsv ) -{ - int i; - _mitkIpPicTagsElement_t *new; - _mitkIpPicTagsElement_t *current; - - tsv->tag[_mitkIpPicTAGLEN] = '\0'; - for( i=strlen(tsv->tag); i<_mitkIpPicTAGLEN; i++ ) - tsv->tag[i] = ' '; - - new = malloc( sizeof(_mitkIpPicTagsElement_t) ); - - new->tsv = tsv; - new->prev = NULL; - new->next = NULL; - - if( head == NULL ) - { - head = new; - } - else - { - current = head; - - while( current->next != NULL ) - { - current = current->next; - } - - new->prev = current; - current->next = new; - } - - return( head ); -} diff --git a/Utilities/IpPic/ipPicAnnotation.h b/Utilities/IpPic/ipPicAnnotation.h deleted file mode 100755 index 64aa9d944d..0000000000 --- a/Utilities/IpPic/ipPicAnnotation.h +++ /dev/null @@ -1,81 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * mitkIpPicAnnotation.h - *--------------------------------------------------------------------- - * DESCRIPTION - * declarations for the annotations in the pic format - * - * AUTHOR & DATE - * Andre Schroeter 09.01.95 - * - * UPDATES - * a short history of the file - * - *--------------------------------------------------------------------- - */ - -#ifndef _mitkIpPicAnnotation_h -#define _mitkIpPicAnnotation_h - -typedef enum - { - mitkIpPicAUnknown = 0, - mitkIpPicAText = 1 - } mitkIpPicAnnotationType_t; - -typedef struct - { - mitkIpUInt4_t _magic; - - mitkIpPicAnnotationType_t type; - - mitkIpUInt4_t location_x; - mitkIpUInt4_t location_y; - - mitkIpUInt4_t position_x; - mitkIpUInt4_t position_y; - char *text; - } mitkIpPicAnnotation_t; - -#endif /* _mitkIpPicAnnotation_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ - diff --git a/Utilities/IpPic/ipPicAnnotations.h b/Utilities/IpPic/ipPicAnnotations.h deleted file mode 100755 index edcd5b2795..0000000000 --- a/Utilities/IpPic/ipPicAnnotations.h +++ /dev/null @@ -1,73 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - * mitkIpPicAnnotations.h - *--------------------------------------------------------------------- - * DESCRIPTION - * declarations for the annotations in the pic format - * - * AUTHOR & DATE - * Andre Schroeter 09.01.95 - * - * UPDATES - * a short history of the file - * - *--------------------------------------------------------------------- - */ - -#ifndef _mitkIpPicAnnotations_h -#define _mitkIpPicAnnotations_h - -typedef enum - { - mitkIpPicAUnknown = 0, - mitkIpPicAText = 1 - } mitkIpPicAnnotations_t; - -typedef struct - { - mitkIpUInt4_t xpos; - mitkIpUInt4_t ypos; - char *text; - } mitkIpPicAnnotation; - -#endif /* _mitkIpPicAnnotations_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ diff --git a/Utilities/IpPic/ipPicClear.c b/Utilities/IpPic/ipPicClear.c deleted file mode 100755 index 6825cb047f..0000000000 --- a/Utilities/IpPic/ipPicClear.c +++ /dev/null @@ -1,127 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * Clears the entries in a picDescriptor - * and frees the data and info - * - * $Log$ - * Revision 1.6 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.4 2000/05/04 12:52:36 ivo - * inserted BSD style license - * - * Revision 1.3 2000/05/04 12:35:58 ivo - * some doxygen comments. - * - * Revision 1.2 1997/09/15 13:21:10 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:58 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicClear\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -void mitkIpPicClear( mitkIpPicDescriptor *pic ) -{ - if( pic != NULL ) - { - if( pic->data != NULL ) - { - free( pic->data ); - pic->data = NULL; - } - - if( pic->info != NULL ) - { - _mitkIpPicFreeTags( pic->info->tags_head ); - pic->info->tags_head = NULL; - - /*free( pic->info ); - pic->info = NULL;*/ - } - pic->type = mitkIpPicUnknown; - } -} - -void _mitkIpPicFreeTags( _mitkIpPicTagsElement_t *head ) -{ - _mitkIpPicTagsElement_t *current; - - current = head; - while( current != NULL ) - { - _mitkIpPicTagsElement_t *this = current; - current = current->next; - - if( this->tsv != NULL ) - { - if( this->tsv->value != NULL ) - { - if( this->tsv->type == mitkIpPicTSV ) - _mitkIpPicFreeTags( this->tsv->value ); - else - free( this->tsv->value ); - } - free( this->tsv ); - } - - free( this ); - } -} diff --git a/Utilities/IpPic/ipPicClone.c b/Utilities/IpPic/ipPicClone.c deleted file mode 100755 index 895bf7f51e..0000000000 --- a/Utilities/IpPic/ipPicClone.c +++ /dev/null @@ -1,141 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * creates the clone of a pic - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicClone\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -/** - * creates the clone of a pic - * @param pic the original pic - * - * @return the exact copy - * - * - * AUTHOR & DATE - * - */ - -mitkIpPicDescriptor *mitkIpPicClone( mitkIpPicDescriptor *pic ) -{ - mitkIpPicDescriptor *clone; - - clone = mitkIpPicCopyHeader( pic, - NULL ); - - strncpy( clone->info->version, pic->info->version, _mitkIpPicTAGLEN ); - - clone->info->tags_head = _mitkIpPicCloneTags( pic->info->tags_head ); - - clone->info->write_protect = pic->info->write_protect; - - if( !pic->data ) - { - clone->data = NULL; - } - else - { - mitkIpUInt4_t size; - - size = _mitkIpPicSize( pic ); - - clone->data = malloc( size ); - if ( ! ( clone->data ) ) - return NULL; - memmove( clone->data, pic->data, size ); - } - - return( clone ); -} - -_mitkIpPicTagsElement_t *_mitkIpPicCloneTags( _mitkIpPicTagsElement_t *head ) -{ - _mitkIpPicTagsElement_t *new; - _mitkIpPicTagsElement_t *current; - - new = NULL; - current = head; - while( current != NULL ) - { - new = _mitkIpPicInsertTag( new, _mitkIpPicCloneTag(current->tsv) ); - - current = current->next; - } - return( new ); -} - -mitkIpPicTSV_t *_mitkIpPicCloneTag( mitkIpPicTSV_t *source ) -{ - mitkIpPicTSV_t *new; - - mitkIpUInt4_t i; - - new = malloc( sizeof(mitkIpPicTSV_t) ); - - strncpy( new->tag, source->tag, _mitkIpPicTAGLEN ); - - new->type = source->type; - new->bpe = source->bpe; - new->dim = source->dim; - - for( i = 0; i < source->dim; i++ ) - new->n[i] = source->n[i]; - - if( source->type == mitkIpPicTSV ) - { - new->value = _mitkIpPicCloneTags( source->value ); - } - else - { - mitkIpUInt4_t size; - - size = _mitkIpPicTSVSize( new ); - - new->value = malloc( size ); - memmove( new->value, source->value, size ); - } - - return( new ); -} diff --git a/Utilities/IpPic/ipPicCopyH.c b/Utilities/IpPic/ipPicCopyH.c deleted file mode 100755 index 91093a56dc..0000000000 --- a/Utilities/IpPic/ipPicCopyH.c +++ /dev/null @@ -1,73 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/** @file - * copys the header from a pic into a new pic - */ - -#ifndef lint - static char *what = { "@(#)mitkIpPicCopyHeader\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -/** copys the header from a pic into a new pic - * - */ - -mitkIpPicDescriptor *mitkIpPicCopyHeader( mitkIpPicDescriptor *pic, mitkIpPicDescriptor *pic_new ) -{ - mitkIpUInt4_t i; - - if( pic_new == NULL ) - pic_new = mitkIpPicNew(); - - mitkIpPicClear( pic_new ); - - - pic_new->type = pic->type; - pic_new->bpe = pic->bpe; - pic_new->dim = pic->dim; - for( i=0; i<pic_new->dim; i++ ) - pic_new->n[i] = pic->n[i]; - - return( pic_new ); -} diff --git a/Utilities/IpPic/ipPicCopyS.c b/Utilities/IpPic/ipPicCopyS.c deleted file mode 100755 index e59d448877..0000000000 --- a/Utilities/IpPic/ipPicCopyS.c +++ /dev/null @@ -1,111 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/** @file - * copys a slice from a pic into a new pic - */ - -/*$Log$ - *Revision 1.7 2002/11/13 17:53:00 ivo - *new ipPic added. - * - *Revision 1.5 2002/04/23 11:06:25 ivo - *mitkIpPicCopySlice behaves now in the same way as mitkIpPicGetSlice: - *2D-slices are copied, no longer hyper-planes of dimension dim-1. - * - *Revision 1.4 2000/05/04 12:52:36 ivo - *inserted BSD style license - * - *Revision 1.3 2000/05/04 12:35:58 ivo - *some doxygen comments. - * - * Revision 1.2 1997/09/15 13:21:11 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:58 andre - * initial import - * - * Revision 0.0 1993/06/07 19:19:19 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicCopySlice\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpPicDescriptor *_mitkIpPicCopySlice( mitkIpPicDescriptor *pic, mitkIpPicDescriptor *pic_in, mitkIpUInt4_t slice ) -{ - mitkIpUInt4_t picsize; - - if( pic == NULL ) - pic = mitkIpPicNew(); - - mitkIpPicClear( pic ); - - pic->type = pic_in->type; - pic->bpe = pic_in->bpe; - pic->dim = 2; - pic->n[0] = pic_in->n[0]; - pic->n[1] = pic_in->n[1]; - pic->data = NULL; - - picsize = _mitkIpPicSize(pic); - - if( slice < 1 - || slice > _mitkIpPicSize(pic_in) / picsize ) - { - mitkIpPicClear(pic); - return( pic ); - } - - pic->data = malloc( picsize ); - - memmove( pic->data, - &((char *)pic_in->data)[(slice-1) * picsize], - picsize ); - - return( pic ); -} diff --git a/Utilities/IpPic/ipPicDelT.c b/Utilities/IpPic/ipPicDelT.c deleted file mode 100755 index 7e860e6816..0000000000 --- a/Utilities/IpPic/ipPicDelT.c +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/** @file - * deletes a tsv from the pic - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicDelTag\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" -/** deletes a tsv from the pic - */ - - - -static mitkIpPicTSV_t *_mitkIpPicRemoveTag( _mitkIpPicTagsElement_t **head, - _mitkIpPicTagsElement_t *which, - const char *tag ); - -mitkIpPicTSV_t * -mitkIpPicDelTag( mitkIpPicDescriptor *pic, const char *tag ) -{ - _mitkIpPicTagsElement_t *which; - - which = _mitkIpPicFindTag( pic->info->tags_head, tag ); - - return( _mitkIpPicRemoveTag( &(pic->info->tags_head), which, tag ) ); -} - -mitkIpPicTSV_t * -mitkIpPicDelSubTag( mitkIpPicTSV_t *parent, const char *tag ) -{ - _mitkIpPicTagsElement_t *which; - - if( parent->type != mitkIpPicTSV ) - return( NULL ); - - which = _mitkIpPicFindTag( parent->value, tag ); - - if( !which ) - return( NULL ); - - if( which->tsv->type == mitkIpPicTSV ) - return( NULL ); - - parent->n[0]--; - return( _mitkIpPicRemoveTag( (_mitkIpPicTagsElement_t **)&(parent->value), which, tag ) ); -} - -mitkIpPicTSV_t * -_mitkIpPicRemoveTag( _mitkIpPicTagsElement_t **head, _mitkIpPicTagsElement_t *which, const char *tag ) -{ - mitkIpPicTSV_t *tsv = NULL; - - if( which != NULL ) - { - tsv = which->tsv; - - if( which->prev == NULL ) /* which is the current head */ - { - *head = which->next; - - if( *head ) - (*head)->prev = NULL; - } - else if( which->next == NULL ) /* which is the current tail */ - { - which->prev->next = NULL; - } - else /* which is somewhere if the list */ - { - which->prev->next = which->next; - which->next->prev = which->prev; - } - - free( which ); - } - - return( tsv ); -} diff --git a/Utilities/IpPic/ipPicElements.c b/Utilities/IpPic/ipPicElements.c deleted file mode 100755 index c4e28f6381..0000000000 --- a/Utilities/IpPic/ipPicElements.c +++ /dev/null @@ -1,65 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/** @file - * calculates number of Elements in the data - */ - -#ifndef lint - static char *what = { "@(#)_mitkIpPicElements\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpUInt4_t _mitkIpPicElements( mitkIpPicDescriptor *pic ) -{ - unsigned int i; - mitkIpUInt4_t elements; - - if( pic->dim == 0 ) - return( 0 ); - - elements = pic->n[0]; - for( i = 1; i < pic->dim; i++ ) - elements *= pic->n[i]; - - return( elements ); -} diff --git a/Utilities/IpPic/ipPicFree.c b/Utilities/IpPic/ipPicFree.c deleted file mode 100755 index 7aa2abea49..0000000000 --- a/Utilities/IpPic/ipPicFree.c +++ /dev/null @@ -1,113 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * frees all space used by a picDescriptor - * - * $Log$ - * Revision 1.8 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.6 2000/05/04 12:52:37 ivo - * inserted BSD style license - * - * Revision 1.5 2000/05/04 12:35:59 ivo - * some doxygen comments. - * - * Revision 1.4 1998/09/16 18:37:34 andre - * added mitkIpPicFreeTag - * - * Revision 1.3 1998/09/16 18:32:45 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:12 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:58 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicFree\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -void mitkIpPicFree( mitkIpPicDescriptor *pic ) -{ - if( pic != NULL ) - { - mitkIpPicClear( pic ); - - if( pic->info != NULL ) - { - free( pic->info ); - } - - free( pic ); - - pic = NULL; - } -} - -void -mitkIpPicFreeTag( mitkIpPicTSV_t *tsv ) -{ - if( tsv ) - { - if( tsv->value ); - free( tsv->value ); - - free( tsv ); - } -} diff --git a/Utilities/IpPic/ipPicGet.c b/Utilities/IpPic/ipPicGet.c deleted file mode 100755 index 5d80efef8a..0000000000 --- a/Utilities/IpPic/ipPicGet.c +++ /dev/null @@ -1,318 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads a PicFile from disk - * - * $Log$ - * Revision 1.16 2004/01/16 22:11:59 andre - * big endian bug fix - * - * Revision 1.15 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.13 2002/02/27 09:02:56 andre - * zlib changes - * - * Revision 1.12 2002/02/27 08:54:43 andre - * zlib changes - * - * Revision 1.11 2000/05/04 12:52:37 ivo - * inserted BSD style license - * - * Revision 1.10 2000/02/16 14:29:20 andre - * *** empty log message *** - * - * Revision 1.9 1999/11/28 18:22:42 andre - * *** empty log message *** - * - * Revision 1.8 1999/11/28 16:29:43 andre - * *** empty log message *** - * - * Revision 1.7 1999/11/27 20:03:48 andre - * *** empty log message *** - * - * Revision 1.6 1999/11/27 19:29:43 andre - * *** empty log message *** - * - * Revision 1.5 1998/09/04 17:45:54 andre - * *** empty log message *** - * - * Revision 1.4 1998/05/06 14:13:15 andre - * added info->pixel_start_in_file - * - * Revision 1.3 1997/10/20 13:35:39 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:13 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicGet\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpPicFile_t -_mitkIpPicOpenPicFileIn( const char *path ) -{ - mitkIpPicFile_t infile; - - if( path == NULL ) - infile = stdin; - else if( strcmp(path, "stdin") == 0 ) - infile = stdin; - else - infile = mitkIpPicFOpen( path, "rb" ); - - if( !infile ) - { - char buff[1024]; - - sprintf( buff, "%s.gz", path ); - - infile = mitkIpPicFOpen( buff, "rb" ); - } - - return( infile ); -} - -mitkIpPicDescriptor * -mitkIpPicGet( const char *infile_name, mitkIpPicDescriptor *pic ) -{ - mitkIpPicFile_t infile; - - mitkIpPicTag_t tag_name; - mitkIpUInt4_t len; - - mitkIpUInt4_t to_read; - - infile = _mitkIpPicOpenPicFileIn( infile_name ); - - if( !infile ) - { - /*ipPrintErr( "mitkIpPicGet: sorry, error opening infile\n" );*/ - return( NULL ); - } - - /* read infile */ - mitkIpPicFRead( tag_name, 1, 4, infile ); - - if( strncmp( "\037\213", tag_name, 2 ) == 0 ) - { - fprintf( stderr, "mitkIpPicGetHeader: sorry, can't read compressed file\n" ); - return( NULL ); - } - else if( strncmp( mitkIpPicVERSION, tag_name, 4 ) != 0 ) - { - if( pic == NULL ) - pic = _mitkIpPicOldGet( infile, - NULL ); - else - _mitkIpPicOldGet( infile, - pic ); - if( infile != stdin ) - mitkIpPicFClose( infile ); - return( pic ); - } - - if( pic == NULL ) - pic = mitkIpPicNew(); - - mitkIpPicClear( pic ); - - mitkIpPicFRead( &(tag_name[4]), 1, sizeof(mitkIpPicTag_t)-4, infile ); - strncpy( pic->info->version, tag_name, _mitkIpPicTAGLEN ); - - mitkIpPicFReadLE( &len, sizeof(mitkIpUInt4_t), 1, infile ); - - mitkIpPicFReadLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, infile ); - mitkIpPicFReadLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, infile ); - mitkIpPicFReadLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, infile ); - - mitkIpPicFReadLE( &(pic->n), sizeof(mitkIpUInt4_t), pic->dim, infile ); - - - to_read = len - 3 * sizeof(mitkIpUInt4_t) - - pic->dim * sizeof(mitkIpUInt4_t); -#if 0 - mitkIpPicFSeek( infile, to_read, SEEK_CUR ); -#else - pic->info->tags_head = _mitkIpPicReadTags( pic->info->tags_head, to_read, infile, mitkIpPicEncryptionType(pic) ); -#endif - - pic->info->write_protect = mitkIpFalse; - -#ifdef WIN - if ((pic->hdata = GlobalAlloc( GMEM_MOVEABLE, _mitkIpPicSize(pic) )) != 0) - pic->data = GlobalLock( pic->hdata ); -#else - pic->data = malloc( _mitkIpPicSize(pic) ); -#endif - - pic->info->pixel_start_in_file = mitkIpPicFTell( infile ); - if( pic->type == mitkIpPicNonUniform ) - mitkIpPicFRead( pic->data, pic->bpe / 8, _mitkIpPicElements(pic), infile ); - else - mitkIpPicFReadLE( pic->data, pic->bpe / 8, _mitkIpPicElements(pic), infile ); - - if( infile != stdin ) - mitkIpPicFClose( infile ); - -#ifdef WIN - GlobalUnlock( pic->hdata ); -#endif - - return( pic ); -} - -_mitkIpPicTagsElement_t * -_mitkIpPicReadTags( _mitkIpPicTagsElement_t *head, mitkIpUInt4_t bytes_to_read, FILE *stream, char encryption_type ) -{ - while( bytes_to_read > 0 ) - { - mitkIpPicTSV_t *tsv; - - mitkIpPicTag_t tag_name; - mitkIpUInt4_t len; - - /*printf( "bytes_to_read: %i\n", bytes_to_read ); */ - - tsv = malloc( sizeof(mitkIpPicTSV_t) ); - - mitkIpPicFRead( &tag_name, 1, sizeof(mitkIpPicTag_t), stream ); - strncpy( tsv->tag, tag_name, _mitkIpPicTAGLEN ); - tsv->tag[_mitkIpPicTAGLEN] = '\0'; - - mitkIpPicFReadLE( &len, sizeof(mitkIpUInt4_t), 1, stream ); - - mitkIpPicFReadLE( &(tsv->type), sizeof(mitkIpUInt4_t), 1, stream ); - mitkIpPicFReadLE( &(tsv->bpe), sizeof(mitkIpUInt4_t), 1, stream ); - mitkIpPicFReadLE( &(tsv->dim), sizeof(mitkIpUInt4_t), 1, stream ); - - - mitkIpPicFReadLE( &(tsv->n), sizeof(mitkIpUInt4_t), tsv->dim, stream ); - - /*printf( "%.*s\n", _mitkIpPicTAGLEN, tsv->tag ); - printf( " %i\n", len ); - printf( " %i %i %i %i %i\n", - tsv->type, - tsv->bpe, - tsv->dim, - tsv->n[0], - tsv->n[1] ); */ - - if( tsv->type == mitkIpPicTSV ) - { - tsv->value = NULL; - tsv->value = _mitkIpPicReadTags( tsv->value, - len - 3 * sizeof(mitkIpUInt4_t) - - tsv->dim * sizeof(mitkIpUInt4_t), - stream, - encryption_type ); - } - else - { - mitkIpUInt4_t elements; - - elements = _mitkIpPicTSVElements( tsv ); - - if( tsv->type == mitkIpPicASCII - || tsv->type == mitkIpPicNonUniform ) - tsv->bpe = 8; - -assert( elements * tsv->bpe / 8 == len - - 3 * sizeof(mitkIpUInt4_t) - - tsv->dim * sizeof(mitkIpUInt4_t) ); - - if( tsv->type == mitkIpPicASCII ) - tsv->value = malloc( elements+1 * tsv->bpe / 8 ); - else - tsv->value = malloc( elements * tsv->bpe / 8 ); - - mitkIpPicFReadLE( tsv->value, tsv->bpe / 8, elements, stream ); - - if( tsv->type == mitkIpPicASCII ) - ((char *)(tsv->value))[elements] = '\0'; - - if( encryption_type == 'e' - && ( tsv->type == mitkIpPicASCII - || tsv->type == mitkIpPicNonUniform ) ) - { - if( tsv->type == mitkIpPicNonUniform ) - { - sprintf( tsv->tag, "*** ENCRYPTED ***" ); - tsv->tag[_mitkIpPicTAGLEN] = '\0'; - } - - free( tsv->value ); - - tsv->value = strdup( "*** ENCRYPTED ***" ); - tsv->n[0] = strlen(tsv->value); - tsv->type = mitkIpPicASCII; - tsv->dim = 1; - } - } - - head = _mitkIpPicInsertTag( head, tsv ); - - bytes_to_read -= 32 /* name */ - + sizeof(mitkIpUInt4_t) /* len */ - + len; /* type + bpe + dim + n[] + data */ - } - return( head ); -} diff --git a/Utilities/IpPic/ipPicGetH.c b/Utilities/IpPic/ipPicGetH.c deleted file mode 100755 index ef0b36f5d1..0000000000 --- a/Utilities/IpPic/ipPicGetH.c +++ /dev/null @@ -1,155 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads the Header of a PicFile from disk - * - * $Log$ - * Revision 1.10 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.8 2000/05/04 12:52:37 ivo - * inserted BSD style license - * - * Revision 1.7 2000/05/04 12:35:59 ivo - * some doxygen comments. - * - * Revision 1.6 1999/11/28 16:27:21 andre - * *** empty log message *** - * - * Revision 1.5 1999/11/28 00:36:09 andre - * *** empty log message *** - * - * Revision 1.4 1999/11/27 20:02:41 andre - * *** empty log message *** - * - * Revision 1.3 1999/11/27 19:15:26 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:13 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicGetHeader\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpPicDescriptor * -mitkIpPicGetHeader( const char *infile_name, mitkIpPicDescriptor *pic ) -{ - mitkIpPicFile_t infile; - - mitkIpPicTag_t tag_name; - mitkIpUInt4_t len; - - infile = _mitkIpPicOpenPicFileIn( infile_name ); - - if( infile == NULL ) - { - /*ipPrintErr( "mitkIpPicGetHeader: sorry, error opening infile\n" );*/ - return( NULL ); - } - - /* read infile */ - mitkIpPicFRead( &(tag_name[0]), 1, 4, infile ); - - if( strncmp( "\037\213", tag_name, 2 ) == 0 ) - { - fprintf( stderr, "mitkIpPicGetHeader: sorry, can't read compressed file\n" ); - return( NULL ); - } - else if( strncmp( mitkIpPicVERSION, tag_name, 4 ) != 0 ) - { - /* - if( pic == NULL ) - pic = _mitkIpPicOldGetHeader( infile, - NULL ); - else - _mitkIpPicOldGetHeader( infile, - pic ); - if( infile != stdin ) - mitkIpPicFClose( infile ); - return( pic ); - */ - return ( NULL ); - } - - if( pic == NULL ) - pic = mitkIpPicNew(); - - mitkIpPicClear( pic ); - - pic->info->write_protect = mitkIpTrue; - - mitkIpPicFRead( &(tag_name[4]), 1, sizeof(mitkIpPicTag_t)-4, infile ); - strncpy( pic->info->version, tag_name, _mitkIpPicTAGLEN ); - - mitkIpPicFReadLE( &len, sizeof(mitkIpUInt4_t), 1, infile ); - - mitkIpPicFReadLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, infile ); - mitkIpPicFReadLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, infile ); - mitkIpPicFReadLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, infile ); - - mitkIpPicFReadLE( &(pic->n), sizeof(mitkIpUInt4_t), pic->dim, infile ); - - - if( infile != stdin ) - mitkIpPicFClose( infile ); - - return( pic ); -} diff --git a/Utilities/IpPic/ipPicGetMem.c b/Utilities/IpPic/ipPicGetMem.c deleted file mode 100755 index 880857318b..0000000000 --- a/Utilities/IpPic/ipPicGetMem.c +++ /dev/null @@ -1,219 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/* - *-------------------------------------------------------------------- - * DESCRIPTION - * creates a PicStructure from memory block - * - * FUNCTION DECLARATION - * - * - * PARAMETERS - * - * - * AUTHOR & DATE - * Harald Evers 15.7.98 - * - * UPDATES - * - *-------------------------------------------------------------------- - * - */ - -#ifndef lint - static char *what = { "@(#)mitkIpPicGetMem\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpPicDescriptor *mitkIpPicGetMem( mitkIpUInt1_t *mem_pic ) -{ - mitkIpPicDescriptor *pic; - mitkIpUInt4_t len; - mitkIpUInt4_t to_read; - mitkIpUInt1_t *mem_ptr = mem_pic; - - if( !mem_pic ) - return( NULL ); - - pic = mitkIpPicNew(); - mitkIpPicClear( pic ); - memmove( &(pic->info->version), mem_ptr, sizeof(mitkIpPicTag_t) ); - mem_ptr += sizeof(mitkIpPicTag_t); - if( strncmp( mitkIpPicVERSION, pic->info->version, 4 ) != 0 ) - { - mitkIpPicFree( pic ); - return( NULL ); - } - - /*memmove( &len, mem_ptr, sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( mem_ptr, &len, sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - mem_ptr += sizeof(mitkIpUInt4_t); - - /*memmove( &(pic->type), mem_ptr, sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( mem_ptr, &(pic->type), sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - mem_ptr += sizeof(mitkIpUInt4_t); - - /*memmove( &(pic->bpe), mem_ptr, sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( mem_ptr, &(pic->bpe), sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - mem_ptr += sizeof(mitkIpUInt4_t); - - /*memmove( &(pic->dim), mem_ptr, sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( mem_ptr, &(pic->dim), sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - mem_ptr += sizeof(mitkIpUInt4_t); - - /*memmove( &(pic->n), mem_ptr, pic->dim * sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( mem_ptr, &(pic->n), pic->dim*sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - mem_ptr += pic->dim*sizeof(mitkIpUInt4_t); - - to_read = len - 3 * sizeof(mitkIpUInt4_t) - - pic->dim * sizeof(mitkIpUInt4_t); - pic->info->tags_head = _mitkIpPicReadTagsMem( pic->info->tags_head, - to_read, &mem_ptr, - mitkIpPicEncryptionType(pic) ); - - pic->info->write_protect = mitkIpFalse; - pic->data = malloc( _mitkIpPicSize(pic) ); - - /* - pic->info->pixel_start_in_file = ftell( infile ); - */ - - /*memmove( pic->data, mem_ptr, pic->bpe/8*_mitkIpPicElements(pic) );*/ - mitkIpCpFromLE( mem_ptr, pic->data, _mitkIpPicSize(pic), pic->bpe/8 ); - - return( pic ); -} - -_mitkIpPicTagsElement_t * -_mitkIpPicReadTagsMem( _mitkIpPicTagsElement_t *head, mitkIpUInt4_t bytes_to_read, - mitkIpUInt1_t **mem_ptr, char encryption_type ) -{ - while( bytes_to_read > 0 ) - { - mitkIpPicTSV_t *tsv; - mitkIpUInt4_t len; - - tsv = malloc( sizeof(mitkIpPicTSV_t) ); - - memmove( tsv->tag, *mem_ptr, _mitkIpPicTAGLEN ); - tsv->tag[_mitkIpPicTAGLEN] = '\0'; - *mem_ptr += _mitkIpPicTAGLEN; - - /*memmove( &len, *mem_ptr, sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( *mem_ptr, &len, sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - *mem_ptr += sizeof(mitkIpUInt4_t); - - /*memmove( &(tsv->type), *mem_ptr, sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( *mem_ptr, &(tsv->type), sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - *mem_ptr += sizeof(mitkIpUInt4_t); - - /*memmove( &(tsv->bpe), *mem_ptr, sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( *mem_ptr, &(tsv->bpe), sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - *mem_ptr += sizeof(mitkIpUInt4_t); - - /*memmove( &(tsv->dim), *mem_ptr, sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( *mem_ptr, &(tsv->dim), sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - *mem_ptr += sizeof(mitkIpUInt4_t); - - /*memmove( &(tsv->n), *mem_ptr, tsv->dim*sizeof(mitkIpUInt4_t) );*/ - mitkIpCpFromLE( *mem_ptr, &(tsv->n), tsv->dim*sizeof(mitkIpUInt4_t), sizeof(mitkIpUInt4_t) ); - *mem_ptr += tsv->dim*sizeof(mitkIpUInt4_t); - - if( tsv->type == mitkIpPicTSV ) - { - tsv->value = NULL; - tsv->value = _mitkIpPicReadTagsMem( tsv->value, - len - 3 * sizeof(mitkIpUInt4_t) - - tsv->dim * sizeof(mitkIpUInt4_t), - mem_ptr, - encryption_type ); - } - else - { - mitkIpUInt4_t elements; - - elements = _mitkIpPicTSVElements( tsv ); - - if( tsv->type == mitkIpPicASCII - || tsv->type == mitkIpPicNonUniform ) - tsv->bpe = 8; - - if( tsv->type == mitkIpPicASCII ) - tsv->value = malloc( (elements+1) * (tsv->bpe / 8) ); - else - tsv->value = malloc( elements * tsv->bpe / 8 ); - - /*memmove( tsv->value, *mem_ptr, tsv->bpe/8*_mitkIpPicTSVElements(tsv) );*/ - mitkIpCpFromLE( *mem_ptr, tsv->value, _mitkIpPicTSVSize(tsv), tsv->bpe/8 ); - *mem_ptr += tsv->bpe/8*_mitkIpPicTSVElements(tsv); - - if( tsv->type == mitkIpPicASCII ) - ((char *)(tsv->value))[elements] = '\0'; - - if( encryption_type == 'e' - && ( tsv->type == mitkIpPicASCII - || tsv->type == mitkIpPicNonUniform ) ) - { - if( tsv->type == mitkIpPicNonUniform ) - { - sprintf( tsv->tag, "*** ENCRYPTED ***" ); - tsv->tag[_mitkIpPicTAGLEN] = '\0'; - } - - if( tsv->value ) - free( tsv->value ); - - tsv->value = strdup( "*** ENCRYPTED ***" ); - tsv->n[0] = (mitkIpUInt4_t)strlen(tsv->value); - tsv->type = mitkIpPicASCII; - tsv->dim = 1; - } - } - - head = _mitkIpPicInsertTag( head, tsv ); - - bytes_to_read -= 32 /* name */ - + sizeof(mitkIpUInt4_t) /* len */ - + len; /* type + bpe + dim + n[] + data */ - } - return( head ); -} diff --git a/Utilities/IpPic/ipPicGetS.c b/Utilities/IpPic/ipPicGetS.c deleted file mode 100755 index d0fc1495d7..0000000000 --- a/Utilities/IpPic/ipPicGetS.c +++ /dev/null @@ -1,208 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads a slice from a PicFile - * - * $Log$ - * Revision 1.12 2006/03/03 14:07:58 maleike - * try to fix warning "cast from pointer to integer of different size" - * - * Revision 1.11 2005/10/09 08:56:31 ivo - * FIX: warning: comparison between pointer and integer - * - * Revision 1.10 2003/02/25 16:16:53 andre - * *** empty log message *** - * - * Revision 1.9 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.7 2002/02/27 09:05:15 andre - * zlib changes - * - * Revision 1.6 2002/02/27 09:02:56 andre - * zlib changes - * - * Revision 1.5 2002/02/27 08:54:43 andre - * zlib changes - * - * Revision 1.4 2000/05/04 12:52:38 ivo - * inserted BSD style license - * - * Revision 1.3 2000/05/04 12:35:59 ivo - * some doxygen comments. - * - * Revision 1.2 1997/09/15 13:21:14 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/31 11:26:16 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicGetSlice\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpPicDescriptor *mitkIpPicGetSlice( const char *infile_name, mitkIpPicDescriptor *pic, mitkIpUInt4_t slice ) -{ - mitkIpPicFile_t infile; - - mitkIpPicTag_t tag_name; - mitkIpUInt4_t len; - mitkIpUInt4_t skip; - - int number = 1; - - unsigned long int picsize; - - if( infile_name == NULL ) - infile = stdin; - else if( strcmp(infile_name, "stdin") == 0 ) - infile = stdin; - else - infile = _mitkIpPicOpenPicFileIn( infile_name ); - - if( infile == NULL ) - { - /*ipPrintErr( "mitkIpPicGetSlice: sorry, error opening infile\n" );*/ - return( NULL ); - } - - /* read infile */ - mitkIpPicFRead( &(tag_name[0]), 1, 4, infile ); - - if( strncmp( mitkIpPicVERSION, tag_name, 4 ) != 0 ) - { - if( pic == NULL ) - pic = _mitkIpPicOldGetSlice( infile, - NULL, - slice ); - else - _mitkIpPicOldGetSlice( infile, - pic, - slice ); - if( infile != stdin ) - mitkIpPicFClose( infile ); - return( pic ); - } - - - if( (void*)pic == (void*)3 ) - { - pic = NULL; - number = 3; - } - - if( pic == NULL ) - pic = mitkIpPicNew(); - - mitkIpPicClear( pic ); - - mitkIpPicFRead( &(tag_name[4]), 1, sizeof(mitkIpPicTag_t)-4, infile ); - strncpy( pic->info->version, tag_name, _mitkIpPicTAGLEN ); - - mitkIpPicFReadLE( &len, sizeof(mitkIpUInt4_t), 1, infile ); - - mitkIpPicFReadLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, infile ); - mitkIpPicFReadLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, infile ); - mitkIpPicFReadLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, infile ); - - mitkIpPicFReadLE( &(pic->n), sizeof(mitkIpUInt4_t), pic->dim, infile ); - - skip = len - 3 * sizeof(mitkIpUInt4_t) - - pic->dim * sizeof(mitkIpUInt4_t); - mitkIpPicFSeek( infile, skip, SEEK_CUR ); - - picsize = _mitkIpPicSize(pic); - - pic->dim = 2; - - if( slice < 1 - || slice > picsize / _mitkIpPicSize(pic) ) - { - mitkIpPicClear( pic ); - return( pic ); - } - - if( number < 1 ) - number = 1; - - if( slice + number - 1 > pic->n[2] ) - number = pic->n[2] - slice + 1; - - - pic->info->write_protect = mitkIpTrue; - - picsize = _mitkIpPicSize(pic); - - mitkIpPicFSeek( infile, picsize * (slice - 1), SEEK_CUR ); - - if( number > 1 ) - { - pic->dim = 3; - pic->n[2] = number; - } - - picsize = _mitkIpPicSize(pic); - - pic->data = malloc( picsize ); - - mitkIpPicFReadLE( pic->data, pic->bpe / 8, _mitkIpPicElements(pic), infile ); - - if( infile != stdin ) - mitkIpPicFClose( infile ); - - return( pic ); -} diff --git a/Utilities/IpPic/ipPicGetT.c b/Utilities/IpPic/ipPicGetT.c deleted file mode 100755 index ff7da68e6a..0000000000 --- a/Utilities/IpPic/ipPicGetT.c +++ /dev/null @@ -1,152 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads a tag from a PicFile - * - * $Log$ - * Revision 1.12 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.10 2000/05/04 12:52:38 ivo - * inserted BSD style license - * - * Revision 1.9 2000/05/04 12:35:59 ivo - * some doxygen comments. - * - * Revision 1.8 1999/11/28 18:21:37 andre - * *** empty log message *** - * - * Revision 1.7 1999/11/28 16:27:21 andre - * *** empty log message *** - * - * Revision 1.6 1999/11/28 00:36:09 andre - * *** empty log message *** - * - * Revision 1.5 1999/11/27 19:32:13 andre - * *** empty log message *** - * - * Revision 1.2.2.2 1998/03/25 15:03:36 andre - * added info->pixel_start_in_file - * - * Revision 1.2.2.1 1997/09/15 13:47:06 andre - * added encryption - * - * Revision 1.2 1997/09/15 13:21:14 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicGetTag\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpPicDescriptor * -mitkIpPicGetTags( const char *infile_name, mitkIpPicDescriptor *pic ) -{ - mitkIpPicFile_t infile; - - mitkIpPicTag_t tag_name; - mitkIpUInt4_t dummy; - mitkIpUInt4_t len; - mitkIpUInt4_t dim; - mitkIpUInt4_t n[_mitkIpPicNDIM]; - - mitkIpUInt4_t to_read; - - infile = _mitkIpPicOpenPicFileIn( infile_name ); - - if( infile == NULL ) - { - /*ipPrintErr( "mitkIpPicGetTags: sorry, error opening infile\n" );*/ - return( NULL ); - } - - if( pic != NULL ) - pic->info->write_protect = mitkIpFalse; - - /* read infile */ - mitkIpPicFRead( &(tag_name[0]), 1, 4, infile ); - - if( strncmp( mitkIpPicVERSION, tag_name, 4 ) != 0 ) - { - if( infile != stdin ) - mitkIpPicFClose( infile ); - return( pic ); - } - - if( pic == NULL ) - pic = mitkIpPicNew(); - - mitkIpPicFRead( &(tag_name[4]), 1, sizeof(mitkIpPicTag_t)-4, infile ); - /*strncpy( pic->info->version, tag_name, _mitkIpPicTAGLEN );*/ - - mitkIpPicFReadLE( &len, sizeof(mitkIpUInt4_t), 1, infile ); - - mitkIpPicFReadLE( &dummy, sizeof(mitkIpUInt4_t), 1, infile ); - mitkIpPicFReadLE( &dummy, sizeof(mitkIpUInt4_t), 1, infile ); - mitkIpPicFReadLE( &dim, sizeof(mitkIpUInt4_t), 1, infile ); - - mitkIpPicFReadLE( n, sizeof(mitkIpUInt4_t), dim, infile ); - - - to_read = len - 3 * sizeof(mitkIpUInt4_t) - - dim * sizeof(mitkIpUInt4_t); - - pic->info->tags_head = _mitkIpPicReadTags( pic->info->tags_head, to_read, infile, mitkIpPicEncryptionType(pic) ); - - pic->info->pixel_start_in_file = mitkIpPicFTell( infile ); - - if( infile != stdin ) - mitkIpPicFClose( infile ); - - return( pic ); -} diff --git a/Utilities/IpPic/ipPicInfo.c b/Utilities/IpPic/ipPicInfo.c deleted file mode 100755 index ef2580f9ec..0000000000 --- a/Utilities/IpPic/ipPicInfo.c +++ /dev/null @@ -1,249 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * prints information about an mitkIpPicDescriptor - */ - -#ifndef lint - static char *what = { "@(#)_mitkIpPicInfo\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -/** prints information about an mitkIpPicDescriptor - * - * @param stream the output FILE* - * @param pic the pic - * @param flags which information to show - * - * @return none - * - * AUTHOR & DATE - * Andre Schroeter 03.10.94 - * - */ - - -#define INT_MAXIMUM 5 -#define ASCII_MAX 60 - -/* -** private macros -*/ -#define Min(x, y) (((x) < (y)) ? (x) : (y)) -#define Max(x, y) (((x) > (y)) ? (x) : (y)) - -void _mitkIpPicInfo( FILE *stream, mitkIpPicDescriptor *pic, mitkIpUInt4_t flags ) -{ - mitkIpUInt4_t i; - - fprintf( stream, "%.*s\n", _mitkIpPicTAGLEN, pic->info->version ); - fprintf( stream, "--------------------\n" ); - - fprintf( stream, "type: %s [%i]\n", mitkIpPicTypeName(pic->type), pic->type ); - - fprintf( stream, "bpe : %i\n", pic->bpe ); - - fprintf( stream, "dim : %i ", pic->dim ); - for( i=0; i<pic->dim; i++ ) - fprintf( stream, "[%i] ", pic->n[i] ); - fprintf( stream, "\n" ); - - if( pic != NULL - && pic->info->tags_head != NULL ) - fprintf( stream, "--------------------\n" ); - - _mitkIpPicInfoPrintTags( stream, - pic->info->tags_head, - 1, - flags ); - - fprintf( stream, "--------------------\n" ); - fprintf( stream, "size of the image data: %u\n", _mitkIpPicSize( pic ) ); -} - -void _mitkIpPicInfoPrintTags( FILE *stream, _mitkIpPicTagsElement_t* head, mitkIpUInt4_t level, mitkIpUInt4_t flags ) -{ - mitkIpUInt4_t i; - _mitkIpPicTagsElement_t *current; - - char *indent; - - indent = malloc( level*4 + 1 ); - for( i = 0; i < level*4-2; i++ ) - indent[i] = ' '; - indent[i] = '\0'; - - current = head; - while( current != NULL ) - { - fprintf( stream, "%s%.*s\n", indent, _mitkIpPicTAGLEN, current->tsv->tag ); - if( !(flags & _mitkIpPicInfoSHORT) ) - { - fprintf( stream, "%s type: %s [%i]\n", indent, - mitkIpPicTypeName(current->tsv->type), current->tsv->type ); - fprintf( stream, "%s bpe : %i\n", indent, current->tsv->bpe ); - fprintf( stream, "%s dim : %i ", indent, current->tsv->dim ); - - for( i=0; i<current->tsv->dim; i++ ) - fprintf( stream, "[%i] ", current->tsv->n[i] ); - fprintf( stream, "\n" ); - } - - if( current->tsv->type == mitkIpPicTSV ) - { - _mitkIpPicInfoPrintTags( stream, - current->tsv->value, - level+1, - flags ); - } - else - { - fprintf( stream, "%s value : ", indent ); - - switch( current->tsv->type ) - { - case mitkIpPicASCII: - if( current->tsv->n[0] > ASCII_MAX ) - fprintf( stream, "\"%.*s\"...\n", - ASCII_MAX, - (char *)current->tsv->value ); - else - fprintf( stream, "\"%.*s\"\n", - (int)current->tsv->n[0], - (char *)current->tsv->value ); - break; - case mitkIpPicUInt: - for( i = 0; i < Min( INT_MAXIMUM, current->tsv->n[0] ); i++ ) - switch( current->tsv->bpe ) - { - case 8: - fprintf( stream, "%3u ", - ((mitkIpUInt1_t *)current->tsv->value)[i] ); - break; - case 16: - fprintf( stream, "%5u ", - ((mitkIpUInt2_t *)current->tsv->value)[i] ); - break; - case 32: - fprintf( stream, "%11u ", - ((mitkIpUInt4_t *)current->tsv->value)[i] ); - break; - default: - fprintf( stream, "???" ); - break; - } - if( current->tsv->n[0] > INT_MAXIMUM ) - fprintf( stream, "..." ); - fprintf( stream, "\n" ); - if( current->tsv->dim > 1 ) - { - fprintf( stream, "%s .\n", indent ); - fprintf( stream, "%s .\n", indent ); - fprintf( stream, "%s .\n", indent ); - } - break; - case mitkIpPicInt: - for( i = 0; i < Min( INT_MAXIMUM, current->tsv->n[0] ); i++ ) - switch( current->tsv->bpe ) - { - case 8: - fprintf( stream, "%3i ", - ((mitkIpInt1_t *)current->tsv->value)[i] ); - break; - case 16: - fprintf( stream, "%5i ", - ((mitkIpInt2_t *)current->tsv->value)[i] ); - break; - case 32: - fprintf( stream, "%11i ", - ((mitkIpInt4_t *)current->tsv->value)[i] ); - break; - default: - fprintf( stream, "???" ); - break; - } - if( current->tsv->n[0] > INT_MAXIMUM ) - fprintf( stream, "..." ); - fprintf( stream, "\n" ); - if( current->tsv->dim > 1 ) - { - fprintf( stream, "%s .\n", indent ); - fprintf( stream, "%s .\n", indent ); - fprintf( stream, "%s .\n", indent ); - } - break; - case mitkIpPicFloat: - for( i = 0; i < Min( INT_MAXIMUM, current->tsv->n[0] ); i++ ) - switch( current->tsv->bpe ) - { - case 32: - fprintf( stream, "%5.5f ", - ((mitkIpFloat4_t *)current->tsv->value)[i] ); - break; - case 64: - fprintf( stream, "%5.5f ", - ((mitkIpFloat8_t *)current->tsv->value)[i] ); - break; - default: - fprintf( stream, "???" ); - break; - } - if( current->tsv->n[0] > INT_MAXIMUM ) - fprintf( stream, "..." ); - fprintf( stream, "\n" ); - if( current->tsv->dim > 1 ) - { - fprintf( stream, "%s .\n", indent ); - fprintf( stream, "%s .\n", indent ); - fprintf( stream, "%s .\n", indent ); - } - break; - default: - fprintf( stream, "???\n" ); - break; - } - } - - current = current->next; - } - free( indent ); -} diff --git a/Utilities/IpPic/ipPicNew.c b/Utilities/IpPic/ipPicNew.c deleted file mode 100755 index 7e1045c51c..0000000000 --- a/Utilities/IpPic/ipPicNew.c +++ /dev/null @@ -1,105 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * Allocates memory for a new PicDescriptor - * - * $Log$ - * Revision 1.7 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.5 2000/05/04 12:52:39 ivo - * inserted BSD style license - * - * Revision 1.4 2000/05/04 12:36:00 ivo - * some doxygen comments. - * - * Revision 1.3 1999/11/27 19:15:08 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:16 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.0 1993/04/06 09:54:58 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicNew\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpPicDescriptor *mitkIpPicNew( void ) -{ - mitkIpPicDescriptor *pic; - - pic = malloc( sizeof(mitkIpPicDescriptor) ); - - if( pic != NULL ) - { - pic->data = NULL; - pic->type = mitkIpPicUnknown; - - pic->info = malloc( sizeof(_mitkIpPicInfo_t) ); - - strncpy( pic->info->version, mitkIpPicVERSION, _mitkIpPicTAGLEN ); - - pic->info->tags_head = NULL; - - pic->info->write_protect = mitkIpFalse; - pic->info->pixel_start_in_file = 0; - pic->info->lender = 0; - pic->info->borrower = 0; - pic->info->ref = 1; - } - - return( pic ); -} diff --git a/Utilities/IpPic/ipPicNewT.c b/Utilities/IpPic/ipPicNewT.c deleted file mode 100755 index 502317ed36..0000000000 --- a/Utilities/IpPic/ipPicNewT.c +++ /dev/null @@ -1,77 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads a tag from a PicFile - * - * $Log$ - * Revision 1.6 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.4 2000/05/04 12:52:39 ivo - * inserted BSD style license - * - * Revision 1.3 2000/05/04 12:36:00 ivo - * some doxygen comments. - * - * Revision 1.2 1997/09/15 13:21:16 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicNewTag\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -mitkIpPicTSV *mitkIpPicNewTag( ) -{ - -} diff --git a/Utilities/IpPic/ipPicOldGet.c b/Utilities/IpPic/ipPicOldGet.c deleted file mode 100755 index a3ea61fcd2..0000000000 --- a/Utilities/IpPic/ipPicOldGet.c +++ /dev/null @@ -1,167 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads a oldstyle PicFile from disk - * - * $Log$ - * Revision 1.7 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.5 2000/05/04 12:52:39 ivo - * inserted BSD style license - * - * Revision 1.4 2000/05/04 12:36:00 ivo - * some doxygen comments. - * - * Revision 1.3 2000/01/13 14:03:07 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:17 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.2 1993/04/26 17:40:09 andre - * 8 bit images from old pic format are now unsigned - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)_mitkIpPicOldGet\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -#ifdef DOS -#include "mitkIpPicOP.h" -#else -#include "mitkIpPicOldP.h" -#endif - -mitkIpPicDescriptor * _mitkIpPicOldGet( FILE *infile, mitkIpPicDescriptor *pic ) -{ - _mitkIpPicOldHeader old_pic; -#ifdef WIN - HANDLE hbuff; -#endif - - /*unsigned char *text;*/ - void *buff; - - unsigned long int elements; - - /* read infile */ - size_t ignored = mitkIpFReadLE( &(old_pic.dummy1), sizeof(mitkIpUInt4_t), 4, infile ); - if( old_pic.conv <= 0 || old_pic.conv > 6 ) - { - old_pic.conv = 3; - old_pic.rank = 2; - } - - ignored = mitkIpFReadLE( &(old_pic.n1), sizeof(mitkIpUInt4_t), old_pic.rank, infile ); - if( old_pic.rank == 3 && old_pic.n3 == 1 ) - old_pic.rank = 2; - - ignored = mitkIpFReadLE( &(old_pic.type), sizeof(mitkIpUInt4_t), 3, infile ); - if( old_pic.ntxt ) - { - /*text = (unsigned char *)malloc( old_pic.ltxt ); - ignored = mitkIpFReadLE( text, 1, old_pic.ltxt, infile );*/ - fseek( infile, old_pic.ltxt, SEEK_CUR ); - } - - - elements = old_pic.n1 * old_pic.n2; - if( old_pic.rank == 3 ) - elements *= old_pic.n3; - -#ifdef WIN - if ((hbuff = GlobalAlloc( GMEM_MOVEABLE, elements * old_pic.type )) != 0) - buff = GlobalLock( hbuff ); -#else - buff = malloc( elements * old_pic.type ); -#endif - - ignored = mitkIpFReadLE( buff, old_pic.type, elements, infile ); - - /* convert to the new pic3 format */ - - if( pic == NULL ) - pic = mitkIpPicNew(); - - mitkIpPicClear( pic ); - - pic->data = (void *)buff; - if( old_pic.type == 1 ) - pic->type = mitkIpPicUInt; - else - pic->type = (mitkIpPicType_t)old_pic.conv; - pic->bpe = old_pic.type*8; - pic->dim = old_pic.rank; - pic->n[0] = old_pic.n1; - pic->n[1] = old_pic.n2; - pic->n[2] = old_pic.n3; - pic->n[3] = old_pic.n4; - pic->n[4] = old_pic.n5; - pic->n[5] = old_pic.n6; - pic->n[6] = old_pic.n7; - pic->n[7] = old_pic.n8; - -#ifdef WIN - GlobalUnlock( hbuff ); - pic->hdata = hbuff; -#endif - - return( pic ); -} diff --git a/Utilities/IpPic/ipPicOldGetH.c b/Utilities/IpPic/ipPicOldGetH.c deleted file mode 100755 index 07bd7b9cbf..0000000000 --- a/Utilities/IpPic/ipPicOldGetH.c +++ /dev/null @@ -1,142 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads the header of a oldstyle PicFile from disk - * - * $Log$ - * Revision 1.7 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.5 2000/05/04 12:52:39 ivo - * inserted BSD style license - * - * Revision 1.4 2000/05/04 12:36:00 ivo - * some doxygen comments. - * - * Revision 1.3 2000/01/13 14:03:07 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:17 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.2 1993/04/26 17:40:09 andre - * 8 bit images from old pic format are now unsigned - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)_mitkIpPicOldGetHeader\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -#ifdef DOS -#include "mitkIpPicOP.h" -#else -#include "mitkIpPicOldP.h" -#endif - -mitkIpPicDescriptor * _mitkIpPicOldGetHeader( FILE *infile, mitkIpPicDescriptor *pic ) -{ - _mitkIpPicOldHeader old_pic; - - /*unsigned char *text;*/ - - /* read infile */ - size_t ignored = mitkIpFReadLE( &(old_pic.dummy1), sizeof(mitkIpUInt4_t), 4, infile ); - if( old_pic.conv <= 0 || old_pic.conv > 6 ) - { - old_pic.conv = 3; - old_pic.rank = 2; - } - - ignored = mitkIpFReadLE( &(old_pic.n1), sizeof(mitkIpUInt4_t),old_pic.rank, infile ); - if( old_pic.rank == 3 && old_pic.n3 == 1 ) - old_pic.rank = 2; - - ignored = mitkIpFReadLE( &(old_pic.type), sizeof(mitkIpUInt4_t), 3, infile ); - if( old_pic.ntxt ) - { - /*text = (unsigned char *)malloc( old_pic.ltxt ); - ignored = mitkIpFReadLE( text, 1, old_pic.ltxt, infile );*/ - fseek( infile, old_pic.ltxt, SEEK_CUR ); - } - - /* convert to the new pic3 format */ - - if( pic == NULL ) - pic = mitkIpPicNew(); - - mitkIpPicClear( pic ); - - pic->data = NULL; - if( old_pic.type == 1 ) - pic->type = mitkIpPicUInt; - else - pic->type = (mitkIpPicType_t)old_pic.conv; - pic->bpe = old_pic.type*8; - pic->dim = old_pic.rank; - pic->n[0] = old_pic.n1; - pic->n[1] = old_pic.n2; - pic->n[2] = old_pic.n3; - pic->n[3] = old_pic.n4; - pic->n[4] = old_pic.n5; - pic->n[5] = old_pic.n6; - pic->n[6] = old_pic.n7; - pic->n[7] = old_pic.n8; - - return( pic ); -} diff --git a/Utilities/IpPic/ipPicOldGetS.c b/Utilities/IpPic/ipPicOldGetS.c deleted file mode 100755 index ec43f428b4..0000000000 --- a/Utilities/IpPic/ipPicOldGetS.c +++ /dev/null @@ -1,157 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads a slice from an oldstyle PicFile - * - * $Log$ - * Revision 1.7 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.5 2000/05/04 12:52:39 ivo - * inserted BSD style license - * - * Revision 1.4 2000/05/04 12:36:00 ivo - * some doxygen comments. - * - * Revision 1.3 2000/01/13 14:03:07 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:18 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.2 1993/04/26 17:40:09 andre - * 8 bit images from old pic format are now unsigned - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/31 11:42:13 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)_mitkIpPicOldGetSlice\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -#ifdef DOS -#include "mitkIpPicOP.h" -#else -#include "mitkIpPicOldP.h" -#endif - -mitkIpPicDescriptor * _mitkIpPicOldGetSlice( FILE *infile, mitkIpPicDescriptor *pic, mitkIpUInt4_t slice ) -{ - _mitkIpPicOldHeader old_pic; - - /*unsigned char *text;*/ - void *buff; - - unsigned long int elements; - - /* read infile */ - size_t ignored = mitkIpFReadLE( &(old_pic.dummy1), sizeof(mitkIpUInt4_t), 4, infile ); - if( old_pic.conv <= 0 || old_pic.conv > 6 ) - { - old_pic.conv = 3; - old_pic.rank = 2; - } - - ignored = mitkIpFReadLE( &(old_pic.n1), sizeof(mitkIpUInt4_t), old_pic.rank, infile ); - if( old_pic.rank == 3 && old_pic.n3 == 1 ) - old_pic.rank = 2; - - ignored = mitkIpFReadLE( &(old_pic.type), sizeof(mitkIpUInt4_t), 3, infile ); - if( old_pic.ntxt ) - { - /*text = (unsigned char *)malloc( old_pic.ltxt ); - ignored = mitkIpFReadLE( text, 1, old_pic.ltxt, infile );*/ - fseek( infile, old_pic.ltxt, SEEK_CUR ); - } - - old_pic.rank = 2; - - elements = old_pic.n1 * old_pic.n2; - if( old_pic.rank == 3 ) - elements *= old_pic.n3; - - fseek( infile, elements * (slice - 1) * old_pic.type, SEEK_CUR ); - - buff = malloc( elements * old_pic.type ); - - ignored = mitkIpFReadLE( buff, old_pic.type, elements, infile ); - - /* convert to the new pic3 format */ - - if( pic == NULL ) - pic = mitkIpPicNew(); - - mitkIpPicClear( pic ); - - pic->data = (void *)buff; - if( old_pic.type == 1 ) - pic->type = mitkIpPicUInt; - else - pic->type = (mitkIpPicType_t)old_pic.conv; - pic->bpe = old_pic.type*8; - pic->dim = old_pic.rank; - pic->n[0] = old_pic.n1; - pic->n[1] = old_pic.n2; - pic->n[2] = old_pic.n3; - pic->n[3] = old_pic.n4; - pic->n[4] = old_pic.n5; - pic->n[5] = old_pic.n6; - pic->n[6] = old_pic.n7; - pic->n[7] = old_pic.n8; - - return( pic ); -} diff --git a/Utilities/IpPic/ipPicPut.c b/Utilities/IpPic/ipPicPut.c deleted file mode 100755 index 8708c8aecf..0000000000 --- a/Utilities/IpPic/ipPicPut.c +++ /dev/null @@ -1,321 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * writes a PicFile to disk - * - * $Log$ - * Revision 1.17 2005/09/09 09:14:45 ivo - * FIX: warnings on windows - * - * Revision 1.16 2005/06/21 11:22:48 ivo - * CHG: encrypted only a warning instead of an error on write - * - * Revision 1.15 2003/02/18 12:28:23 andre - * write compressed pic files - * - * Revision 1.14 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.12 2002/02/27 09:06:28 andre - * zlib changes - * - * Revision 1.11 2000/05/04 12:52:40 ivo - * inserted BSD style license - * - * Revision 1.10 2000/05/04 12:36:01 ivo - * some doxygen comments. - * - * Revision 1.9 1999/11/27 19:40:44 andre - * *** empty log message *** - * - * Revision 1.8 1999/11/27 19:24:19 andre - * *** empty log message *** - * - * Revision 1.3.2.3 1998/03/25 15:03:36 andre - * added info->pixel_start_in_file - * - * Revision 1.3.2.2 1997/10/09 11:03:53 andre - * *** empty log message *** - * - * Revision 1.3.2.1 1997/09/15 13:46:15 andre - * added encryption - * - * Revision 1.3 1997/09/15 13:21:18 andre - * switched to new what string format - * - * Revision 1.2 1997/09/15 10:24:13 andre - * mitkIpPicPut now returns status - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicPut\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -extern size_t -_mitkIpPicFWrite( const void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream); - -int -mitkIpPicPut( const char *outfile_name, mitkIpPicDescriptor *pic ) -{ - FILE *outfile; - - mitkIpUInt4_t len; - mitkIpUInt4_t tags_len; - - if( pic->info->write_protect ) - { - fprintf( stderr, "mitkIpPicPut: sorry, can't write (missing tags !!!)\n" ); - return( -1 ); - } - - if( mitkIpPicEncryptionType(pic) != ' ' ) - { - fprintf( stderr, "mitkIpPicPut: warning: was encrypted !!!\n" ); - } - - if( outfile_name == NULL ) - outfile = stdout; - else if( strcmp(outfile_name, "stdout") == 0 ) - outfile = stdout; - else - { - mitkIpPicRemoveFile( outfile_name ); - - if( mitkIpPicGetWriteCompression() ) - { - char buff[1024]; - - sprintf( buff, "%s.gz", outfile_name ); - outfile = mitkIpPicFOpen( buff, "wb" ); - } - else - outfile = fopen( outfile_name, "wb" ); - } - - - if( outfile == NULL ) - { - fprintf( stderr, "mitkIpPicPut: sorry, error opening outfile\n" ); - return( -1 ); - } - - tags_len = _mitkIpPicTagsSize( pic->info->tags_head ); - - len = tags_len + 3 * sizeof(mitkIpUInt4_t) - + pic->dim * sizeof(mitkIpUInt4_t); - - /* write oufile */ - if( mitkIpPicEncryptionType(pic) == ' ' ) - mitkIpPicFWrite( mitkIpPicVERSION, 1, sizeof(mitkIpPicTag_t), outfile ); - else - mitkIpPicFWrite( pic->info->version, 1, sizeof(mitkIpPicTag_t), outfile ); - - mitkIpPicFWriteLE( &len, sizeof(mitkIpUInt4_t), 1, outfile ); - - mitkIpPicFWriteLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, outfile ); - mitkIpPicFWriteLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, outfile ); - mitkIpPicFWriteLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, outfile ); - - mitkIpPicFWriteLE( pic->n, sizeof(mitkIpUInt4_t), pic->dim, outfile ); - - _mitkIpPicWriteTags( pic->info->tags_head, outfile, mitkIpPicEncryptionType(pic) ); - - if( mitkIpPicGetWriteCompression() ) - pic->info->pixel_start_in_file = mitkIpPicFTell( outfile ); - else - pic->info->pixel_start_in_file = ftell( outfile ); - - if( pic->data ) - { - if( pic->type == mitkIpPicNonUniform ) - mitkIpPicFWrite( pic->data, pic->bpe / 8, _mitkIpPicElements(pic), outfile ); - else - mitkIpPicFWriteLE( pic->data, pic->bpe / 8, _mitkIpPicElements(pic), outfile ); - } - - if( outfile != stdout ) - { - if( mitkIpPicGetWriteCompression() ) - mitkIpPicFClose( outfile ); - else - fclose( outfile ); - } - - return( 0 ); -} - -mitkIpUInt4_t _mitkIpPicTagsSize( _mitkIpPicTagsElement_t *head ) -{ - _mitkIpPicTagsElement_t *current = head; - mitkIpUInt4_t tags_len; - - tags_len = 0; - while( current != NULL ) - { - mitkIpUInt4_t len; - - if( current->tsv->type == mitkIpPicTSV ) - { - if( current->tsv->dim == 0 ) - { - current->tsv->n[0] = _mitkIpPicTagsNumber(current->tsv->value); - - if( current->tsv->n[0] > 0 ) - current->tsv->dim = 1; - } - - len = _mitkIpPicTagsSize( (_mitkIpPicTagsElement_t *)current->tsv->value ); - } - else - { - mitkIpUInt4_t elements; - - elements = _mitkIpPicTSVElements( current->tsv ); - - if( current->tsv->type == mitkIpPicASCII - || current->tsv->type == mitkIpPicNonUniform ) - current->tsv->bpe = 8; - - len = elements * current->tsv->bpe / 8; - } - - tags_len += 32 /* name */ - + sizeof( mitkIpUInt4_t) /* len */ - + 3 * sizeof( mitkIpUInt4_t) /* type, bpe, dim */ - + current->tsv->dim * sizeof( mitkIpUInt4_t) /* n[] */ - + len; /* data */ - - current = current->next; - } - return( tags_len ); -} - -mitkIpUInt4_t _mitkIpPicTagsNumber( _mitkIpPicTagsElement_t *head ) -{ - _mitkIpPicTagsElement_t *current = head; - mitkIpUInt4_t tags_number; - - tags_number = 0; - while( current != NULL ) - { - tags_number++; - - current = current->next; - } - return( tags_number ); -} - -void _mitkIpPicWriteTags( _mitkIpPicTagsElement_t *head, FILE *stream, char encryption_type ) -{ - _mitkIpPicTagsElement_t *current = head; - - while( current != NULL ) - { - mitkIpUInt4_t elements; - mitkIpUInt4_t len; - - elements = _mitkIpPicTSVElements( current->tsv ); - - if( current->tsv->type == mitkIpPicTSV ) - { - if( current->tsv->dim == 0 ) - { - current->tsv->n[0] = _mitkIpPicTagsNumber(current->tsv->value); - - if( current->tsv->n[0] > 0 ) - current->tsv->dim = 1; - } - - assert( elements == _mitkIpPicTagsNumber(current->tsv->value) ); - - len = _mitkIpPicTagsSize( current->tsv->value ); - } - else - { - if( current->tsv->type == mitkIpPicASCII - || current->tsv->type == mitkIpPicNonUniform ) - current->tsv->bpe = 8; - - len = elements * current->tsv->bpe / 8; - - } - - len += 3 * sizeof(mitkIpUInt4_t) /* type, bpe, dim */ - + current->tsv->dim * sizeof(mitkIpUInt4_t); /* n[] */ - - mitkIpPicFWrite( current->tsv->tag, 1, sizeof(mitkIpPicTag_t), stream ); - - mitkIpPicFWriteLE( &len, sizeof(mitkIpUInt4_t), 1, stream ); - - mitkIpPicFWriteLE( &(current->tsv->type), sizeof(mitkIpUInt4_t), 1, stream ); - mitkIpPicFWriteLE( &(current->tsv->bpe), sizeof(mitkIpUInt4_t), 1, stream ); - mitkIpPicFWriteLE( &(current->tsv->dim), sizeof(mitkIpUInt4_t), 1, stream ); - mitkIpPicFWriteLE( &(current->tsv->n), sizeof(mitkIpUInt4_t), current->tsv->dim, stream ); - - if( current->tsv->type == mitkIpPicTSV ) - { - _mitkIpPicWriteTags( current->tsv->value, - stream, - encryption_type ); - } - else - { - mitkIpPicFWriteLE( current->tsv->value, current->tsv->bpe / 8, elements, stream ); - } - - current = current->next; - } -} diff --git a/Utilities/IpPic/ipPicPutH.c b/Utilities/IpPic/ipPicPutH.c deleted file mode 100755 index c21b306a07..0000000000 --- a/Utilities/IpPic/ipPicPutH.c +++ /dev/null @@ -1,89 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/** @file - * writes a PicFile Header to disk - */ - -#ifndef lint - static char *what = { "@(#)mitkIpPicPutHeader\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -void mitkIpPicPutHeader( char *outfile_name, mitkIpPicDescriptor *pic ) -{ - FILE *outfile; - - mitkIpUInt4_t len; - - if( outfile_name == NULL ) - outfile = stdout; - else if( strcmp(outfile_name, "stdout") == 0 ) - outfile = stdout; - else - outfile = fopen( outfile_name, "wb" ); - - if( outfile == NULL ) - { - /*ipPrintErr( "mitkIpPicPut: sorry, error opening outfile\n" );*/ - return; - } - - len = 3 * sizeof(mitkIpUInt4_t) - + pic->dim * sizeof(mitkIpUInt4_t); - - /* write oufile */ - fwrite( mitkIpPicVERSION, 1, sizeof(mitkIpPicTag_t), outfile ); - - mitkIpFWriteLE( &len, sizeof(mitkIpUInt4_t), 1, outfile ); - - mitkIpFWriteLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, outfile ); - mitkIpFWriteLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, outfile ); - mitkIpFWriteLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, outfile ); - - mitkIpFWriteLE( pic->n, sizeof(mitkIpUInt4_t), pic->dim, outfile ); - - if( outfile != stdout ) - fclose( outfile ); - - /*return();*/ -} diff --git a/Utilities/IpPic/ipPicPutMem.c b/Utilities/IpPic/ipPicPutMem.c deleted file mode 100755 index 564c5523fe..0000000000 --- a/Utilities/IpPic/ipPicPutMem.c +++ /dev/null @@ -1,179 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/** @file - * writes a PicStructure to memory block - */ - -#ifndef lint - static char *what = { "@(#)mitkIpPicPutMem\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - - /** FUNCTION DECLARATION - * - * - * PARAMETERS - * - * - * AUTHOR & DATE - * Harald Evers 15.7.98 - * - * UPDATES - * - *-------------------------------------------------------------------- - * - */ - - - -void _mitkIpPicWriteTagsMem( _mitkIpPicTagsElement_t *head, mitkIpUInt1_t **mem_ptr ) -{ - _mitkIpPicTagsElement_t *current = head; - - while( current != NULL ) - { - mitkIpUInt4_t elements; - mitkIpUInt4_t len; - - elements = _mitkIpPicTSVElements( current->tsv ); - - if( current->tsv->type == mitkIpPicTSV ) - { - if( current->tsv->dim == 0 ) - { - current->tsv->n[0] = _mitkIpPicTagsNumber(current->tsv->value); - - if( current->tsv->n[0] > 0 ) - current->tsv->dim = 1; - } - - assert( elements == _mitkIpPicTagsNumber(current->tsv->value) ); - - len = _mitkIpPicTagsSize( current->tsv->value ); - } - else - { - if( current->tsv->type == mitkIpPicASCII - || current->tsv->type == mitkIpPicNonUniform ) - current->tsv->bpe = 8; - - len = elements * current->tsv->bpe / 8; - - } - - len += 3 * sizeof(mitkIpUInt4_t) /* type, bpe, dim */ - + current->tsv->dim * sizeof(mitkIpUInt4_t); /* n[] */ - - memmove( *mem_ptr, current->tsv->tag, sizeof(mitkIpPicTag_t) ); - *mem_ptr += sizeof(mitkIpPicTag_t); - memmove( *mem_ptr, &len, sizeof(mitkIpUInt4_t) ); - *mem_ptr += sizeof(mitkIpUInt4_t); - memmove( *mem_ptr, &(current->tsv->type), sizeof(mitkIpUInt4_t) ); - *mem_ptr += sizeof(mitkIpUInt4_t); - memmove( *mem_ptr, &(current->tsv->bpe), sizeof(mitkIpUInt4_t) ); - *mem_ptr += sizeof(mitkIpUInt4_t); - memmove( *mem_ptr, &(current->tsv->dim), sizeof(mitkIpUInt4_t) ); - *mem_ptr += sizeof(mitkIpUInt4_t); - memmove( *mem_ptr, &(current->tsv->n), - current->tsv->dim*sizeof(mitkIpUInt4_t) ); - *mem_ptr += current->tsv->dim*sizeof(mitkIpUInt4_t); - - if( current->tsv->type == mitkIpPicTSV ) - { - _mitkIpPicWriteTagsMem( current->tsv->value, mem_ptr ); - } - else - { - /* if( encryption_type == 'e' ... */ - - memmove( *mem_ptr,current->tsv->value, current->tsv->bpe/8*elements ); - *mem_ptr += current->tsv->bpe/8*elements; - } - current = current->next; - } - -} - -mitkIpUInt1_t * -mitkIpPicPutMem( mitkIpPicDescriptor *pic, int *mem_size ) -{ - mitkIpUInt4_t len; - mitkIpUInt4_t tags_len; - mitkIpUInt1_t *mem_pic = NULL; - mitkIpUInt1_t *mem_ptr; - - tags_len = _mitkIpPicTagsSize( pic->info->tags_head ); - - len = tags_len + 3 * sizeof(mitkIpUInt4_t) - + pic->dim * sizeof(mitkIpUInt4_t); - - *mem_size = - sizeof(mitkIpPicTag_t) + /* pic version */ - sizeof(mitkIpUInt4_t) + /* pic data offset */ - len + /* header + tags */ - _mitkIpPicSize( pic ); /* size of data */ - - mem_pic = malloc( *mem_size ); - if( !mem_pic ) - return( NULL ); - - mem_ptr = mem_pic; - memmove( mem_ptr, mitkIpPicVERSION, sizeof(mitkIpPicTag_t) ); - mem_ptr += sizeof(mitkIpPicTag_t); - memmove( mem_ptr, &len, sizeof(mitkIpUInt4_t) ); - mem_ptr += sizeof(mitkIpUInt4_t); - memmove( mem_ptr, &(pic->type), sizeof(mitkIpUInt4_t) ); - mem_ptr += sizeof(mitkIpUInt4_t); - memmove( mem_ptr, &(pic->bpe), sizeof(mitkIpUInt4_t) ); - mem_ptr += sizeof(mitkIpUInt4_t); - memmove( mem_ptr, &(pic->dim), sizeof(mitkIpUInt4_t) ); - mem_ptr += sizeof(mitkIpUInt4_t); - memmove( mem_ptr, &(pic->n), pic->dim*sizeof(mitkIpUInt4_t) ); - mem_ptr += pic->dim*sizeof(mitkIpUInt4_t); - - _mitkIpPicWriteTagsMem( pic->info->tags_head, &mem_ptr ); - - memmove( mem_ptr, pic->data, pic->bpe/8*_mitkIpPicElements(pic) ); - - return( mem_pic ); -} diff --git a/Utilities/IpPic/ipPicPutS.c b/Utilities/IpPic/ipPicPutS.c deleted file mode 100755 index cf492679db..0000000000 --- a/Utilities/IpPic/ipPicPutS.c +++ /dev/null @@ -1,185 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * writes a PicFile to disk - * - * $Log$ - * Revision 1.12 2005/09/09 09:14:45 ivo - * FIX: warnings on windows - * - * Revision 1.11 2003/02/18 12:28:23 andre - * write compressed pic files - * - * Revision 1.10 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.8 2000/05/04 12:52:40 ivo - * inserted BSD style license - * - * Revision 1.7 2000/05/04 12:36:01 ivo - * some doxygen comments. - * - * Revision 1.6 2000/01/17 18:32:00 andre - * *** empty log message *** - * - * Revision 1.5 1999/11/27 19:15:08 andre - * *** empty log message *** - * - * Revision 1.4 1998/09/01 15:26:43 andre - * *** empty log message *** - * - * Revision 1.3 1998/05/18 12:13:54 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:19 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.0 1993/04/02 16:18:39 andre - * Initial revision - * - * - *-------------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)mitkIpPicPutSlice\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" -#include <stdio.h> -#include <stddef.h> - - -void mitkIpPicPutSlice( const char *outfile_name, mitkIpPicDescriptor *pic, mitkIpUInt4_t slice ) -{ - mitkIpPicDescriptor *pic_in; - - FILE *outfile; - - size_t ignored; - - pic_in = mitkIpPicGetHeader( outfile_name, - NULL ); - - if( pic_in == NULL ) - { - if( slice == 1 ) - { - mitkIpBool_t compression; - - pic->n[pic->dim] = 1; - pic->dim += 1; - - compression = mitkIpPicSetWriteCompression( mitkIpFalse ); - mitkIpPicPut( outfile_name, pic ); - mitkIpPicSetWriteCompression( compression ); - - pic->dim -= 1; - pic->n[pic->dim] = 0; - - return; - } - else - return; - } - - pic_in = mitkIpPicGetTags( outfile_name, - pic_in ); - - outfile = fopen( outfile_name, "r+b" ); - - if( outfile == NULL ) - { - /*ipPrintErr( "mitkIpPicPut: sorry, error opening outfile\n" );*/ - /*return();*/ - } - - if( pic->dim != pic_in->dim - 1 ) - { - fclose( outfile ); - return; - } - else if( pic->n[0] != pic_in->n[0] ) - { - fclose( outfile ); - return; - } - else if( pic->n[1] != pic_in->n[1] ) - { - fclose( outfile ); - return; - } - - if( slice > pic_in->n[pic_in->dim-1] ) - pic_in->n[pic_in->dim-1] += 1; - - /* write outfile */ - /*fseek( outfile, 0, SEEK_SET );*/ - rewind( outfile ); - ignored = fwrite( mitkIpPicVERSION, 1, sizeof(mitkIpPicTag_t), outfile ); - - fseek( outfile, sizeof(mitkIpUInt4_t), SEEK_CUR ); /* skip tags_len */ - - ignored = mitkIpFWriteLE( &(pic_in->type), sizeof(mitkIpUInt4_t), 1, outfile ); - ignored = mitkIpFWriteLE( &(pic_in->bpe), sizeof(mitkIpUInt4_t), 1, outfile ); - ignored = mitkIpFWriteLE( &(pic_in->dim), sizeof(mitkIpUInt4_t), 1, outfile ); - - ignored = mitkIpFWriteLE( pic_in->n, sizeof(mitkIpUInt4_t), pic_in->dim, outfile ); - - fseek( outfile, pic_in->info->pixel_start_in_file + _mitkIpPicSize(pic) * (slice - 1), SEEK_SET ); - - ignored = mitkIpFWriteLE( pic->data, pic->bpe / 8, _mitkIpPicElements(pic), outfile ); - - /*fseek( outfile, 0, SEEK_END );*/ - - fclose( outfile ); - - mitkIpPicFree(pic_in); - - /*return();*/ -} diff --git a/Utilities/IpPic/ipPicQueryT.c b/Utilities/IpPic/ipPicQueryT.c deleted file mode 100755 index 802edd941e..0000000000 --- a/Utilities/IpPic/ipPicQueryT.c +++ /dev/null @@ -1,113 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * searches for a tag - */ - -#ifndef lint - static char *what = { "@(#)mitkIpPicQueryTag\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -/** searches for a tag - * - * @param pic the pic - * @param tag the tag to search for - * @param head the head of the tags list - * - * AUTHOR & DATE - * Andre Schroeter 27.08.94 - * - * UPDATES - * none - */ - -mitkIpPicTSV_t * -mitkIpPicQueryTag( mitkIpPicDescriptor *pic, const char *tag ) -{ - _mitkIpPicTagsElement_t *found; - - found = _mitkIpPicFindTag( pic->info->tags_head, tag ); - - if( found == NULL ) - return( NULL ); - else - return( found->tsv ); -} -mitkIpPicTSV_t * -mitkIpPicQuerySubTag( mitkIpPicTSV_t *parent, const char *tag ) -{ - _mitkIpPicTagsElement_t *found; - - found = _mitkIpPicFindTag( parent->value, tag ); - - if( found == NULL ) - return( NULL ); - else - return( found->tsv ); -} - -_mitkIpPicTagsElement_t * -_mitkIpPicFindTag( _mitkIpPicTagsElement_t *head, const char *tag ) -{ - int i; - char name[_mitkIpPicTAGLEN+1]; - _mitkIpPicTagsElement_t *current; - - if( !tag ) - return( NULL ); - - sprintf( name, "%.*s", _mitkIpPicTAGLEN, tag ); - for( i=strlen(name); i<_mitkIpPicTAGLEN; i++ ) - name[i] = ' '; - - current = head; - while( current != NULL ) - { - if( strncmp( current->tsv->tag, name, _mitkIpPicTAGLEN) == 0 ) - return( current ); - - current = current->next; - } - - return( NULL ); -} diff --git a/Utilities/IpPic/ipPicSize.c b/Utilities/IpPic/ipPicSize.c deleted file mode 100755 index 1e7644effa..0000000000 --- a/Utilities/IpPic/ipPicSize.c +++ /dev/null @@ -1,97 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * calculates the size of the image data - */ - -#ifndef lint - static char *what = { "@(#)_mitkIpPicSize\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -/** calculates the size of the image data - * @param pic pointer to image - * @return size of image data - * - * $Log$ - * Revision 1.7 2004/07/02 11:40:49 max - * Fixed bug resulting in mitkIpUInt4_t range overflow using float volumes of a size larger than 512x512x512. - * - * Revision 1.6 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.4 2000/05/04 12:52:41 ivo - * inserted BSD style license - * - * Revision 1.3 2000/05/04 12:36:01 ivo - * some doxygen comments. - * - * Revision 1.2 1997/09/15 13:21:20 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.0 1993/04/26 15:28:03 andre - * Initial revision, NO error checking - */ - -mitkIpUInt4_t _mitkIpPicSize( -#if defined(__cplusplus) || defined(c_plusplus) - const -#endif - mitkIpPicDescriptor *pic ) -{ - mitkIpUInt4_t i; - mitkIpUInt4_t elements; - mitkIpUInt4_t bytesPerElement; - if( pic->dim == 0 ) - return( 0 ); - - elements = pic->n[0]; - for( i = 1; i < pic->dim; i++ ) - elements *= pic->n[i]; - - bytesPerElement = pic->bpe / 8; - - return( elements * bytesPerElement ); -} diff --git a/Utilities/IpPic/ipPicTSVElements.c b/Utilities/IpPic/ipPicTSVElements.c deleted file mode 100755 index c29b670ce9..0000000000 --- a/Utilities/IpPic/ipPicTSVElements.c +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * calculates the number of elements in the TSV's value - */ - -#ifndef lint - static char *what = { "@(#)_mitkIpPicTSVElements\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - - /** calculates the number of elements in the TSV's value - * @param tsv the tsv - * - * @return the number of elements in the tsv - * - * - * AUTHOR & DATE - * Andre Schroeter 23.01.95 - * - * UPDATES - * none - */ - - - -mitkIpUInt4_t _mitkIpPicTSVElements( mitkIpPicTSV_t *tsv ) -{ - mitkIpUInt4_t i; - mitkIpUInt4_t elements; - - if( tsv->dim == 0 ) - return( 0 ); - - elements = tsv->n[0]; - for( i = 1; i < tsv->dim; i++ ) - elements *= tsv->n[i]; - - return( elements ); -} diff --git a/Utilities/IpPic/ipPicTSVSize.c b/Utilities/IpPic/ipPicTSVSize.c deleted file mode 100755 index 30328fa5f4..0000000000 --- a/Utilities/IpPic/ipPicTSVSize.c +++ /dev/null @@ -1,78 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * calculates the size of the TSV's value in bytes - */ - -#ifndef lint - static char *what = { "@(#)_mitkIpPicTSVSize\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - - /** calculates the size of the TSV's value in bytes - * @param tsv the tsv - * - * @return the size of the tsv in bytes - * - * - * AUTHOR & DATE - * Andre Schroeter 23.01.95 - * - * UPDATES - * none - */ - - -mitkIpUInt4_t _mitkIpPicTSVSize( mitkIpPicTSV_t *tsv ) -{ - mitkIpUInt4_t i; - mitkIpUInt4_t elements; - - if( tsv->dim == 0 ) - return( 0 ); - - elements = tsv->n[0]; - for( i = 1; i < tsv->dim; i++ ) - elements *= tsv->n[i]; - - return( elements * tsv->bpe / 8 ); -} diff --git a/Utilities/IpPic/ipPicType.c b/Utilities/IpPic/ipPicType.c deleted file mode 100755 index 3964719ca5..0000000000 --- a/Utilities/IpPic/ipPicType.c +++ /dev/null @@ -1,86 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - * initialisation of an array that maps the - * mitkIpPicType_t types to printable strings - */ - -#ifndef lint - static char *what = { "@(#)mitkIpPicType\t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -#include "mitkIpPic.h" - -/** initialisation of an array that maps the - * mitkIpPicType_t types to printable strings - * - * @param type the type - * - * @return the printable string - * - * AUTHOR & DATE - * Andre Schroeter 08.05.94 - * - * UPDATES - * none - * - */ - -static const char *_mitkIpPicTypeName[_mitkIpPicTypeMax] = -{ - "mitkIpPicUnknown", - "mitkIpPicBool", - "mitkIpPicASCII", - "mitkIpPicInt", - "mitkIpPicUInt", - "mitkIpPicFloat", - "mitkIpPicUnknown", - "mitkIpPicNonUniform", - "mitkIpPicTSV" -}; - -const char *mitkIpPicTypeName( mitkIpUInt4_t type ) -{ - if( type > _mitkIpPicTypeMax ) - return( _mitkIpPicTypeName[0] ); - else - return( _mitkIpPicTypeName[type] ); -} diff --git a/Utilities/IpPic/ipWin.c b/Utilities/IpPic/ipWin.c deleted file mode 100755 index 5add62deb6..0000000000 --- a/Utilities/IpPic/ipWin.c +++ /dev/null @@ -1,64 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -#ifdef WIN -#include <windows.h> -#include <stdio.h> - -DWORD hfread(LPSTR ptr, DWORD size, DWORD n, FILE *stream) -{ - if( (size < 0xffff) && (n < 0xffff) ) - return fread( ptr, (WORD)size, (WORD)n, stream ); - else - { - DWORD Bytes; - BYTE huge *lpwork; - - Bytes = size*n; - - for( lpwork = ptr; Bytes > 0xffff; Bytes-=0xffff, lpwork+=0xffff ) - fread( (char far*)lpwork, 0xffff, 1, stream ); - - return fread( (char far*)lpwork, (WORD)Bytes, 1, stream ); - } -} -#endif - diff --git a/Utilities/IpPic/libipPic.dsp b/Utilities/IpPic/libipPic.dsp deleted file mode 100755 index ec372c9188..0000000000 --- a/Utilities/IpPic/libipPic.dsp +++ /dev/null @@ -1,232 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libipPic" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=libipPic - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "libipPic.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "libipPic.mak" CFG="libipPic - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libipPic - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "libipPic - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "libipPic - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "libipPic___Win32_Release" -# PROP BASE Intermediate_Dir "libipPic___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /I "win32" /I "$(QTDIR)\src\3rdparty\zlib" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "lint" /YX /FD /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:".\lib\libipPic.lib" - -!ELSEIF "$(CFG)" == "libipPic - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "libipPic___Win32_Debug" -# PROP BASE Intermediate_Dir "libipPic___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "." /I "$(QTDIR)\src\3rdparty\zlib" /I ".." /I "win32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "lint" /YX /FD /GZ /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:".\lib\libipPicD.lib" - -!ENDIF - -# Begin Target - -# Name "libipPic - Win32 Release" -# Name "libipPic - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\ipEndian.c -# End Source File -# Begin Source File - -SOURCE=.\ipError.c -# End Source File -# Begin Source File - -SOURCE=.\ipFRead.c -# End Source File -# Begin Source File - -SOURCE=.\ipFWrite.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicAddT.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicClear.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicClone.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicCopyH.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicCopyS.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicDelT.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicElements.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicFree.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicGet.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicGetH.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicGetMem.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicGetS.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicGetT.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicInfo.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicNew.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicOldGet.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicOldGetH.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicOldGetS.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicPut.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicPutMem.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicPutS.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicQueryT.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicSize.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicTSVElements.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicTSVSize.c -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicType.c -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\mitkIpPic.h -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicAnnotation.h -# End Source File -# Begin Source File - -SOURCE=.\mitkIpPicOldP.h -# End Source File -# Begin Source File - -SOURCE=.\mitkIpTypes.h -# End Source File -# End Group -# Begin Source File - -SOURCE=.\win32\zlib.lib -# End Source File -# End Target -# End Project diff --git a/Utilities/IpPic/libipPic.dsw b/Utilities/IpPic/libipPic.dsw deleted file mode 100755 index ed5ec5bf4e..0000000000 --- a/Utilities/IpPic/libipPic.dsw +++ /dev/null @@ -1,59 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "libipPic"=".\libipPic.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "pic2seq"=".\pic2seq.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libipPic - End Project Dependency -}}} - -############################################################################### - -Project: "picinfo"=".\picinfo.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libipPic - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/Utilities/IpPic/mitkIpPic.h b/Utilities/IpPic/mitkIpPic.h deleted file mode 100644 index c89f8ddf03..0000000000 --- a/Utilities/IpPic/mitkIpPic.h +++ /dev/null @@ -1,896 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file - */ - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * public defines for the pic-format - * - * $Log$ - * Revision 1.3 2007/03/22 13:41:29 nolden - * FIX: resolve problems with chili plugin - * - * Revision 1.2 2007/03/07 17:23:18 nolden - * fixes for chili plugin build - * - * Revision 1.1 2006/12/13 11:54:43 nolden - * *** empty log message *** - * - * Revision 1.47 2006/11/20 16:09:18 nolden - * FIX/CHG: different mangling of zlib names for ITK 3.x - * - * Revision 1.46 2006/09/20 11:38:17 nolden - * CHG: use itk zlib header from itkzlib subdir of ipPic if USE_ITKZLIB is defined - * - * Revision 1.45 2006/04/20 12:56:00 nolden - * FIX/CHG/ENH: added PPC-Mac definitions - * - * Revision 1.44 2005/10/11 19:06:41 ivo - * FIX: typo - * - * Revision 1.43 2005/10/11 18:35:34 ivo - * FIX: typo - * - * Revision 1.42 2005/10/11 18:19:46 ivo - * ENH: trying to fix zlib problems: use renamed itk zlib methods (itk_gzread etc) - * - * Revision 1.41 2005/04/29 15:41:46 ivo - * FIX: qchili compatibility for version of 21/4/05 - * - * Revision 1.40 2004/04/06 14:59:39 nolden - * moved win32 compatibility settings from mitkIpPic.h to ipPic.pro - * - * Revision 1.39 2004/03/25 18:35:05 andre - * bug fix - * - * Revision 1.38 2003/12/02 11:54:31 tobiask - * Added setters and getters for rgb pixels. - * - * Revision 1.37 2003/11/28 14:24:45 tobiask - * Fixed bugs in macros mitkIpPicGET_PIXEL and mitkIpPicPUT_PIXEL. - * - * Revision 1.36 2003/09/30 20:12:50 tobiask - * Added macros for getting and setting pixel values. - * - * Revision 1.35 2003/02/18 12:28:23 andre - * write compressed pic files - * - * Revision 1.34 2002/11/13 17:52:59 ivo - * new ipPic added. - * - * Revision 1.32 2002/10/31 10:00:30 ivo - * zlib.lib including headers now in win32. gz-extension should work now on every windows. - * WIN32 define changed to standard _WIN32. - * - * Revision 1.31 2002/05/16 13:14:30 peter - * changed include path to ipPic/mitkIpPic.h - * - * Revision 1.30 2002/04/18 19:09:13 ivo - * compression (zlib) activated. - * - * Revision 1.1.1.1 2002/04/18 18:38:43 ivo - * no message - * - * Revision 1.29 2002/02/27 08:54:43 andre - * zlib changes - * - * Revision 1.28 2000/06/26 16:02:05 andre - * pPicFORALL_x bug fix - * - * Revision 1.27 2000/05/24 14:10:51 tobiask - * Removed ipPic/ from the include directives. - * - * Revision 1.26 2000/05/04 12:52:35 ivo - * inserted BSD style license - * - * Revision 1.25 2000/05/04 12:35:58 ivo - * some doxygen comments. - * - * Revision 1.24 1999/12/09 19:17:46 andre - * *** empty log message *** - * - * Revision 1.23 1999/12/09 19:11:51 andre - * *** empty log message *** - * - * Revision 1.22 1999/11/29 09:41:39 andre - * *** empty log message *** - * - * Revision 1.21 1999/11/29 09:34:34 andre - * *** empty log message *** - * - * Revision 1.20 1999/11/28 16:29:43 andre - * *** empty log message *** - * - * Revision 1.19 1999/11/28 16:27:21 andre - * *** empty log message *** - * - * Revision 1.18 1999/11/27 23:59:45 andre - * *** empty log message *** - * - * Revision 1.17 1999/11/27 19:15:08 andre - * *** empty log message *** - * - * Revision 1.16 1999/11/27 12:47:52 andre - * *** empty log message *** - * - * Revision 1.15 1999/08/20 08:25:42 andre - * *** empty log message *** - * - * Revision 1.14 1998/09/16 18:35:16 andre - * *** empty log message *** - * - * Revision 1.13 1998/09/16 18:32:53 andre - * *** empty log message *** - * - * Revision 1.12 1998/07/16 12:33:18 andre - * *** empty log message *** - * - * Revision 1.11 1998/07/14 11:16:16 andre - * *** empty log message *** - * - * Revision 1.10 1998/06/23 15:56:40 andre - * *** empty log message *** - * - * Revision 1.9 1998/06/18 09:12:14 andre - * *** empty log message *** - * - * Revision 1.8 1998/06/09 12:38:30 andre - * added mitkIpPicDelSubTag - * - * Revision 1.7 1998/06/09 11:34:32 andre - * *** empty log message *** - * - * Revision 1.6 1998/06/09 10:58:25 andre - * added mitkIpPicAddSubTag - * - * Revision 1.5 1998/05/09 18:30:23 andre - * *** empty log message *** - * - * Revision 1.4 1998/05/06 14:13:15 andre - * added info->pixel_start_in_file - * - * Revision 1.3 1997/10/20 13:35:40 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 10:24:12 andre - * mitkIpPicPut now returns status - * - * Revision 0.2 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.1 1993/03/31 11:44:35 andre - * added 'GetSlice' - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision - * - * - *-------------------------------------------------------------------- - * - */ - -#define USE_ITKZLIB - -#ifndef _mitkIpPic_h -#define _mitkIpPic_h - - -#ifndef NO_DEBUG -# define mitkIpPicDEBUG -#endif - - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef sun -# include <unistd.h> -#endif - - - -#ifdef WIN -# include <windows.h> -extern DWORD ipWinFread(LPSTR ptr, DWORD size, DWORD n, FILE *stream); -#endif - - - -#include <assert.h> /**/ - -#include <mitkIpTypes.h> - - -#ifdef mitkIpPicDEBUG -#endif - - -/* -** defines -*/ -#define mitkIpPicVERSION "PIC VERSION 3.00 " -#define mitkIpPicVERSIONe "PIC VERSION 3.00e " -#define _mitkIpPicNDIM 8 -#define _mitkIpPicTAGLEN 32 - - -#if (THIS_IS_BIG_ENDIAN) || defined (_IBMR2) || (mc68000) || (sun) || (__convex__) || (__hppa) || (_MIPSEB) || defined ( __PPC__) -# define _mitkIpENDIAN_IS_BIG -#else -# define _mitkIpENDIAN_IS_LITTLE -#endif - - -#define mitkIpPicVersionMajor(pic) (mitkIpUInt1_t)(pic->info->version[12] - '0') -#define mitkIpPicVersionMinor(pic) (mitkIpUInt1_t)(10 * (pic->info->version[14]-'0' ) \ - + pic->info->version[15]-'0') -#define mitkIpPicEncryptionType(pic) (pic->info->version[16]) - -/*#define mitkIpPicIsPic(pic) (( (pic)->magic == mitkIpPicPicDescriptor_m) \ - ? mitkIpTrue : mitkIpFalse )*/ - - -#define mitkIpPicDR(type,len) (mitkIpUInt4_t)( ((type)<<16) + (len) ) - -#define mitkIpPicFOR_TYPE( _ipPIC_TYPE, _ipPIC_CMD, _ipPIC_PIC) \ - _ipPIC_CMD(_ipPIC_TYPE,_ipPIC_PIC) - -#define mitkIpPicFORALL( _ipPIC_CMD, _ipPIC_PIC ) \ - switch( mitkIpPicDR((_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe) ) \ - { \ - case mitkIpPicDR( mitkIpPicInt, 8 ): \ - _ipPIC_CMD(mitkIpInt1_t, _ipPIC_PIC); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 8 ): \ - _ipPIC_CMD(mitkIpUInt1_t, _ipPIC_PIC); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 16 ): \ - _ipPIC_CMD(mitkIpInt2_t, _ipPIC_PIC); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 16 ): \ - _ipPIC_CMD(mitkIpUInt2_t, _ipPIC_PIC); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 32 ): \ - _ipPIC_CMD(mitkIpInt4_t, _ipPIC_PIC); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 32 ): \ - _ipPIC_CMD(mitkIpUInt4_t, _ipPIC_PIC); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 32 ): \ - _ipPIC_CMD(mitkIpFloat4_t, _ipPIC_PIC); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 64 ): \ - _ipPIC_CMD(mitkIpFloat8_t, _ipPIC_PIC); \ - break; \ - default: \ - fprintf( stderr, \ - "sorry, %s: datatype (%i/%i) not supported for %s.\n", \ - __FILE__, (_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe, #_ipPIC_CMD ); \ - break; \ - } - -#define mitkIpPicFORALL_1( _ipPIC_CMD, _ipPIC_PIC, A1 ) \ - switch( mitkIpPicDR((_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe) ) \ - { \ - case mitkIpPicDR( mitkIpPicInt, 8 ): \ - _ipPIC_CMD(mitkIpInt1_t, _ipPIC_PIC, A1); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 8 ): \ - _ipPIC_CMD(mitkIpUInt1_t, _ipPIC_PIC, A1); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 16 ): \ - _ipPIC_CMD(mitkIpInt2_t, _ipPIC_PIC, A1); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 16 ): \ - _ipPIC_CMD(mitkIpUInt2_t, _ipPIC_PIC, A1); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 32 ): \ - _ipPIC_CMD(mitkIpInt4_t, _ipPIC_PIC, A1); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 32 ): \ - _ipPIC_CMD(mitkIpUInt4_t, _ipPIC_PIC, A1); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 32 ): \ - _ipPIC_CMD(mitkIpFloat4_t, _ipPIC_PIC, A1); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 64 ): \ - _ipPIC_CMD(mitkIpFloat8_t, _ipPIC_PIC, A1); \ - break; \ - default: \ - fprintf( stderr, \ - "sorry, %s: datatype (%i/%i) not supported for %s.\n", \ - __FILE__, (_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe, #_ipPIC_CMD ); \ - break; \ - } - -#define mitkIpPicFORALL_2( _ipPIC_CMD, _ipPIC_PIC, A1, A2 ) \ - switch( mitkIpPicDR((_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe) ) \ - { \ - case mitkIpPicDR( mitkIpPicInt, 8 ): \ - _ipPIC_CMD(mitkIpInt1_t, _ipPIC_PIC, A1, A2); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 8 ): \ - _ipPIC_CMD(mitkIpUInt1_t, _ipPIC_PIC, A1, A2); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 16 ): \ - _ipPIC_CMD(mitkIpInt2_t, _ipPIC_PIC, A1, A2); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 16 ): \ - _ipPIC_CMD(mitkIpUInt2_t, _ipPIC_PIC, A1, A2); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 32 ): \ - _ipPIC_CMD(mitkIpInt4_t, _ipPIC_PIC, A1, A2); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 32 ): \ - _ipPIC_CMD(mitkIpUInt4_t, _ipPIC_PIC, A1, A2); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 32 ): \ - _ipPIC_CMD(mitkIpFloat4_t, _ipPIC_PIC, A1, A2); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 64 ): \ - _ipPIC_CMD(mitkIpFloat8_t, _ipPIC_PIC, A1, A2); \ - break; \ - default: \ - fprintf( stderr, \ - "sorry, %s: datatype (%i/%i) not supported for %s.\n", \ - __FILE__, (_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe, #_ipPIC_CMD ); \ - break; \ - } - -#define mitkIpPicFORALL_3( _ipPIC_CMD, _ipPIC_PIC, A1, A2, A3 ) \ - switch( mitkIpPicDR((_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe) ) \ - { \ - case mitkIpPicDR( mitkIpPicInt, 8 ): \ - _ipPIC_CMD(mitkIpInt1_t, _ipPIC_PIC, A1, A2, A3); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 8 ): \ - _ipPIC_CMD(mitkIpUInt1_t, _ipPIC_PIC, A1, A2, A3); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 16 ): \ - _ipPIC_CMD(mitkIpInt2_t, _ipPIC_PIC, A1, A2, A3); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 16 ): \ - _ipPIC_CMD(mitkIpUInt2_t, _ipPIC_PIC, A1, A2, A3); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 32 ): \ - _ipPIC_CMD(mitkIpInt4_t, _ipPIC_PIC, A1, A2, A3); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 32 ): \ - _ipPIC_CMD(mitkIpUInt4_t, _ipPIC_PIC, A1, A2, A3); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 32 ): \ - _ipPIC_CMD(mitkIpFloat4_t, _ipPIC_PIC, A1, A2, A3); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 64 ): \ - _ipPIC_CMD(mitkIpFloat8_t, _ipPIC_PIC, A1, A2, A3); \ - break; \ - default: \ - fprintf( stderr, \ - "sorry, %s: datatype (%i/%i) not supported for %s.\n", \ - __FILE__, (_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe, #_ipPIC_CMD ); \ - break; \ - } - -#define mitkIpPicFORALL_4( _ipPIC_CMD, _ipPIC_PIC, A1, A2, A3, A4 ) \ - switch( mitkIpPicDR((_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe) ) \ - { \ - case mitkIpPicDR( mitkIpPicInt, 8 ): \ - _ipPIC_CMD(mitkIpInt1_t, _ipPIC_PIC, A1, A2, A3, A4); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 8 ): \ - _ipPIC_CMD(mitkIpUInt1_t, _ipPIC_PIC, A1, A2, A3, A4); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 16 ): \ - _ipPIC_CMD(mitkIpInt2_t, _ipPIC_PIC, A1, A2, A3, A4); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 16 ): \ - _ipPIC_CMD(mitkIpUInt2_t, _ipPIC_PIC, A1, A2, A3, A4); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 32 ): \ - _ipPIC_CMD(mitkIpInt4_t, _ipPIC_PIC, A1, A2, A3, A4); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 32 ): \ - _ipPIC_CMD(mitkIpUInt4_t, _ipPIC_PIC, A1, A2, A3, A4); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 32 ): \ - _ipPIC_CMD(mitkIpFloat4_t, _ipPIC_PIC, A1, A2, A3, A4); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 64 ): \ - _ipPIC_CMD(mitkIpFloat8_t, _ipPIC_PIC, A1, A2, A3, A4); \ - break; \ - default: \ - fprintf( stderr, \ - "sorry, %s: datatype (%i/%i) not supported for %s.\n", \ - __FILE__, (_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe, #_ipPIC_CMD ); \ - break; \ - } - -#define mitkIpPicFORALL_5( _ipPIC_CMD, _ipPIC_PIC, A1, A2, A3, A4, A5 ) \ - switch( mitkIpPicDR((_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe) ) \ - { \ - case mitkIpPicDR( mitkIpPicInt, 8 ): \ - _ipPIC_CMD(mitkIpInt1_t, _ipPIC_PIC, A1, A2, A3, A4, A5); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 8 ): \ - _ipPIC_CMD(mitkIpUInt1_t, _ipPIC_PIC, A1, A2, A3, A4, A5); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 16 ): \ - _ipPIC_CMD(mitkIpInt2_t, _ipPIC_PIC, A1, A2, A3, A4, A5); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 16 ): \ - _ipPIC_CMD(mitkIpUInt2_t, _ipPIC_PIC, A1, A2, A3, A4, A5); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 32 ): \ - _ipPIC_CMD(mitkIpInt4_t, _ipPIC_PIC, A1, A2, A3, A4, A5); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 32 ): \ - _ipPIC_CMD(mitkIpUInt4_t, _ipPIC_PIC, A1, A2, A3, A4, A5); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 32 ): \ - _ipPIC_CMD(mitkIpFloat4_t, _ipPIC_PIC, A1, A2, A3, A4, A5); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 64 ): \ - _ipPIC_CMD(mitkIpFloat8_t, _ipPIC_PIC, A1, A2, A3, A4, A5); \ - break; \ - default: \ - fprintf( stderr, \ - "sorry, %s: datatype (%i/%i) not supported for %s.\n", \ - __FILE__, (_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe, #_ipPIC_CMD ); \ - break; \ - } - -#define mitkIpPicFORALL_6( _ipPIC_CMD, _ipPIC_PIC, A1, A2, A3, A4, A5, A6 ) \ - switch( mitkIpPicDR((_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe) ) \ - { \ - case mitkIpPicDR( mitkIpPicInt, 8 ): \ - _ipPIC_CMD(mitkIpInt1_t, _ipPIC_PIC, A1, A2, A3, A4, A5, A6); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 8 ): \ - _ipPIC_CMD(mitkIpUInt1_t, _ipPIC_PIC, A1, A2, A3, A4, A5, A6); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 16 ): \ - _ipPIC_CMD(mitkIpInt2_t, _ipPIC_PIC, A1, A2, A3, A4, A5, A6); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 16 ): \ - _ipPIC_CMD(mitkIpUInt2_t, _ipPIC_PIC, A1, A2, A3, A4, A5, A6); \ - break; \ - case mitkIpPicDR( mitkIpPicInt, 32 ): \ - _ipPIC_CMD(mitkIpInt4_t, _ipPIC_PIC, A1, A2, A3, A4, A5, A6); \ - break; \ - case mitkIpPicDR( mitkIpPicUInt, 32 ): \ - _ipPIC_CMD(mitkIpUInt4_t, _ipPIC_PIC, A1, A2, A3, A4, A5, A6); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 32 ): \ - _ipPIC_CMD(mitkIpFloat4_t, _ipPIC_PIC, A1, A2, A3, A4, A5, A6); \ - break; \ - case mitkIpPicDR( mitkIpPicFloat, 64 ): \ - _ipPIC_CMD(mitkIpFloat8_t, _ipPIC_PIC, A1, A2, A3, A4, A5, A6); \ - break; \ - default: \ - fprintf( stderr, \ - "sorry, %s: datatype (%i/%i) not supported for %s.\n", \ - __FILE__, (_ipPIC_PIC)->type, (_ipPIC_PIC)->bpe, #_ipPIC_CMD ); \ - break; \ - } - -#define _mitkIpPicGET_PIXEL(TYPE,PIC,X,Y,RESULT) \ -{ \ - TYPE* data = (TYPE *) (PIC)->data \ - + (X) + (Y) * (PIC)->n[0]; \ - RESULT = *data; \ -} - -#define _mitkIpPicPUT_PIXEL(TYPE,PIC,X,Y,VALUE) \ -{ \ - TYPE* data = (TYPE *) (PIC)->data \ - + (X) + (Y) * (PIC)->n[0]; \ - *data = VALUE; \ -} - -#define mitkIpPicGET_PIXEL(PIC,X,Y,RESULT) \ -{ \ - mitkIpPicFORALL_3(_mitkIpPicGET_PIXEL,PIC,X,Y,RESULT); \ -} - -#define mitkIpPicPUT_PIXEL(PIC,X,Y,RESULT) \ -{ \ - mitkIpPicFORALL_3(_mitkIpPicPUT_PIXEL,PIC,X,Y,RESULT); \ -} - -#define _mitkIpPicGET_PIXEL_RGB(TYPE,PIC,X,Y,R,G,B) \ -{ \ - mitkIpUInt4_t skip = (PIC)->n[0] * (PIC)->n[1]; \ - TYPE* data = (TYPE *) (PIC)->data + (X) + (Y) * (PIC)->n[0]; \ - R = *(data); \ - G = *(data + skip); \ - B = *(data + skip + skip); \ -} - -#define _mitkIpPicPUT_PIXEL_RGB(TYPE,PIC,X,Y,R,G,B) \ -{ \ - mitkIpUInt4_t skip = (PIC)->n[0] * (PIC)->n[1]; \ - TYPE* data = (TYPE *) (PIC)->data + (X) + (Y) * (PIC)->n[0]; \ - *data = (R); \ - *(data + skip) = (G); \ - *(data + skip + skip) = (B); \ -} - -#define mitkIpPicGET_PIXEL_RGB(PIC,X,Y,R,G,B) \ -{ \ - mitkIpPicFORALL_5(_mitkIpPicGET_PIXEL_RGB,PIC,X,Y,R,G,B); \ -} - -#define mitkIpPicPUT_PIXEL_RGB(PIC,X,Y,R,G,B) \ -{ \ - mitkIpPicFORALL_5(_mitkIpPicPUT_PIXEL_RGB,PIC,X,Y,R,G,B); \ -} - -#define USE_ZLIB /**/ -#ifdef USE_ZLIB -#ifdef USE_ITKZLIB -# define mitkIpPicFile_t gzFile -# define mitkIpPicFOpen gzopen -# define mitkIpPicFTell gztell -# define mitkIpPicFSeek gzseek -# define mitkIpPicFRead(buf, bsize, count, file) gzread((file),(buf),((count)*(bsize))) -# define mitkIpPicFWrite _mitkIpPicFWrite -# define mitkIpPicFEOF gzeof -# define mitkIpPicFClose gzclose -# include "itk_zlib.h" -#else -# define mitkIpPicFile_t gzFile -# define mitkIpPicFOpen gzopen -# define mitkIpPicFTell gztell -# define mitkIpPicFSeek gzseek -# define mitkIpPicFRead(buf, bsize, count, file) gzread((file),(buf),((count)*(bsize))) -# define mitkIpPicFWrite _mitkIpPicFWrite -# define mitkIpPicFEOF gzeof -# define mitkIpPicFClose gzclose -# include <zlib.h> -#endif -#else -# define mitkIpPicFile_t FILE * -# define mitkIpPicFOpen fopen -# define mitkIpPicFTell ftell -# define mitkIpPicFSeek fseek -# define mitkIpPicFRead fread -# define mitkIpPicFWrite fwrite -# define mitkIpPicFEOF feof -# define mitkIpPicFClose fclose -#endif - - -#ifdef _mitkIpENDIAN_IS_LITTLE -# define mitkIpPicFReadLE mitkIpPicFRead -# define mitkIpPicFReadBE mitkIpPicFReadCvt -#else -# define mitkIpPicFReadLE mitkIpPicFReadCvt -# define mitkIpPicFReadBE mitkIpPicFRead -#endif - -#ifdef _mitkIpENDIAN_IS_LITTLE -# define mitkIpPicFWriteLE mitkIpPicFWrite -# define mitkIpPicFWriteBE mitkIpPicFWriteCvt -#else -# define mitkIpPicFWriteLE mitkIpPicFWriteCvt -# define mitkIpPicFWriteBE mitkIpPicFWrite -#endif - - -#ifdef _mitkIpENDIAN_IS_LITTLE -# define mitkIpFReadLE fread -# define mitkIpFReadBE mitkIpFReadCvt -#else -# define mitkIpFReadLE mitkIpFReadCvt -# define mitkIpFReadBE fread -#endif - -#ifdef _mitkIpENDIAN_IS_LITTLE -# define mitkIpFWriteLE fwrite -# define mitkIpFWriteBE mitkIpFWriteCvt -#else -# define mitkIpFWriteLE mitkIpFWriteCvt -# define mitkIpFWriteBE fwrite -#endif - - -#ifdef WIN -# undef mitkIpFReadLE -# define mitkIpFReadLE fread -#endif - - - -#ifdef _mitkIpENDIAN_IS_LITTLE -# define mitkIpCvtFromLE(data, len, bytes) -# define mitkIpCvtFromBE(data, len, bytes) _mitkIpCvtEndian( (data), (len), (bytes) ) -#else -# define mitkIpCvtFromLE(data, len, bytes) _mitkIpCvtEndian( (data), (len), (bytes) ) -# define mitkIpCvtFromBE(data, len, bytes) -#endif - -#ifdef _mitkIpENDIAN_IS_LITTLE -# define mitkIpCpFromLE(source, destination, len, bytes) _mitkIpCp( (source), (destination), (len) ) -# define mitkIpCpFromBE(source, destination, len, bytes) _mitkIpCpCvtEndian( (source), (destination), (len), (bytes) ) -#else -# define mitkIpCpFromLE(source, destination, len, bytes) _mitkIpCpCvtEndian( (source), (destination), (len), (bytes) ) -# define mitkIpCpFromBE(source, destination, len, bytes) _mitkIpCp( (source), (destination), (len) ) -#endif - -#ifdef _mitkIpENDIAN_IS_LITTLE -# define mitkIpCpToLE(source, destination, len, bytes) _mitkIpCp( (source), (destination), (len) ) -# define mitkIpCpToBE(source, destination, len, bytes) _mitkIpCpCvtEndian( (source), (destination), (len), (bytes) ) -#else -# define mitkIpCpToLE(source, destination, len, bytes) _mitkIpCpCvtEndian( (source), (destination), (len), (bytes) ) -# define mitkIpCpToBE(source, destination, len, bytes) _mitkIpCp( (source), (destination), (len) ) -#endif - - -#define mitkIpEndianSwap2(x) ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00)) - -#define mitkIpEndianSwap4(x) ((((x) >> 24) & 0x000000FF) | (((x) << 24) & 0xFF000000)) \ - | ((((x) >> 8) & 0x0000FF00) | (((x) << 8) & 0x00FF0000)) - -/* -** NOTE: these macros *DO NOT* work for in-place transformations. -*/ -/* -** maybe ipEndianSwap should be used -*/ -#ifdef _mitkIpENDIAN_IS_LITTLE -# define mitkIpInt2FromLE(from, to) *((mitkIpInt2_t *)(to)) = *((mitkIpInt2_t *)(from)) -# define mitkIpInt4FromLE(from, to) *((mitkIpInt4_t *)(to)) = *((mitkIpInt4_t *)(from)) -# define mitkIpUInt2FromLE(from, to) mitkIpInt2FromLE(from, to) -# define mitkIpUInt4FromLE(from, to) mitkIpInt4FromLE(from, to) -# define mitkIpFloat4FromLE(from, to) mitkIpInt4FromLE(from, to) -# define mitkIpFloat8FromLE(from, to) *((mitkIpFloat8_t *)(to)) = *((mitkIpFloat8_t *)(from)) -#else -# define mitkIpInt2FromLE(from, to) ((char *)(to))[0] = ((char *)(from))[1]; \ - ((char *)(to))[1] = ((char *)(from))[0]; - -# define mitkIpInt4FromLE(from, to) ((char *)(to))[0] = ((char *)(from))[3]; \ - ((char *)(to))[1] = ((char *)(from))[2]; \ - ((char *)(to))[2] = ((char *)(from))[1]; \ - ((char *)(to))[3] = ((char *)(from))[0]; -# define mitkIpUInt2FromLE(from, to) mitkIpInt2FromLE(from, to) -# define mitkIpUInt4FromLE(from, to) mitkIpInt4FromLE(from, to) -# define mitkIpFloat4FromLE(from, to) mitkIpInt4FromLE(from, to) -# define mitkIpFloat8FromLE(from, to) ((char *)(to))[0] = ((char *)(from))[7]; \ - ((char *)(to))[1] = ((char *)(from))[6]; \ - ((char *)(to))[2] = ((char *)(from))[5]; \ - ((char *)(to))[3] = ((char *)(from))[4]; \ - ((char *)(to))[4] = ((char *)(from))[3]; \ - ((char *)(to))[5] = ((char *)(from))[2]; \ - ((char *)(to))[6] = ((char *)(from))[1]; \ - ((char *)(to))[7] = ((char *)(from))[0]; -#endif /* _mitkIpENDIAN_IS_LITTLE */ - -/* -** NOTE: Most architectures are symmetrical with respect to conversions. -*/ -#define mitkIpInt2ToLE(from, to) mitkIpInt2FromLE(from, to) -#define mitkIpInt4ToLE(from, to) mitkIpInt4FromLE(from, to) -#define mitkIpUInt2ToLE(from, to) mitkIpUInt2FromLE(from, to) -#define mitkIpUInt4ToLE(from, to) mitkIpUInt4FromLE(from, to) -#define mitkIpFloat4ToLE(from, to) mitkIpFloat4FromLE(from, to) -#define mitkIpFloat8ToLE(from, to) mitkIpFloat8FromLE(from, to) - - -/* -** types for the pic format -*/ - -typedef char mitkIpPicTag_t[_mitkIpPicTAGLEN]; - -typedef enum - { - mitkIpPicUnknown = 0, - mitkIpPicBool = 1, - mitkIpPicASCII = 2, - mitkIpPicInt = 3, - mitkIpPicUInt = 4, - mitkIpPicFloat = 5, - mitkIpPicNonUniform = 7, - mitkIpPicTSV = 8, - /* ---- add new types before this line !!! ----*/ - /* ---- don't forget to add a new type also to mitkIpPicType.c !!! ----*/ - _mitkIpPicTypeMax - } mitkIpPicType_t; - -/* -typedef enum - { - mitkIpPicUnknown_m = 0, - mitkIpPicDescriptor_m = 0xDDDD - } _mitkIpPicMagic_t; -*/ - - -typedef struct - { - char tag[_mitkIpPicTAGLEN+1]; /* name of this tag */ - mitkIpPicType_t type; /* datatype of the value */ - mitkIpUInt4_t bpe; /* bits per element */ - mitkIpUInt4_t dim; /* number of dimensions */ - mitkIpUInt4_t n[_mitkIpPicNDIM]; /* size of dimension n[i] */ - void *value; /* the value */ - } mitkIpPicTSV_t; /* Tag Structure Value */ - -typedef struct _mitkIpPicTagsElement_s - { - mitkIpPicTSV_t *tsv; - struct _mitkIpPicTagsElement_s *prev; - struct _mitkIpPicTagsElement_s *next; - } _mitkIpPicTagsElement_t; - -typedef struct - { - mitkIpPicTag_t version; - _mitkIpPicTagsElement_t *tags_head; - mitkIpBool_t write_protect; - long pixel_start_in_file; - struct mitkIpPicDescriptor *lender; /* lender of image data */ - mitkIpUInt4_t borrower; /* borrower of image data */ - mitkIpUInt4_t ref; /* reference counter */ - } _mitkIpPicInfo_t; - -typedef struct mitkIpPicDescriptor - { - void *data; /* pointer to 'image' data */ - _mitkIpPicInfo_t *info; /* pointer to the PicInfo structure */ - mitkIpPicType_t type; /* datatype of the data */ - mitkIpUInt4_t bpe; /* bits per element */ - mitkIpUInt4_t dim; /* number of dimensions */ - mitkIpUInt4_t n[_mitkIpPicNDIM]; /* size of dimension n[i] */ -#ifdef WIN - HANDLE hdata; -#endif - } mitkIpPicDescriptor; - - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -extern _mitkIpEndian_t _mitkIpEndian( void ); - -extern void _mitkIpCp( void *source, void *destination, unsigned long int len ); -extern void _mitkIpCvtEndian( void *data, unsigned long int len, unsigned char bytes ); -extern void _mitkIpCpCvtEndian( void *source, void *destination, unsigned long int len, unsigned char bytes ); - -extern mitkIpPicFile_t _mitkIpPicOpenPicFileIn( const char *path ); -extern int mitkIpPicAccess( const char *path, int mode ); -extern int mitkIpPicRemoveFile( const char *path ); - -extern mitkIpBool_t mitkIpPicGetWriteCompression( void ); -extern mitkIpBool_t mitkIpPicSetWriteCompression( mitkIpBool_t compression ); - -extern size_t mitkIpFReadCvt( void *ptr, size_t size, size_t nitems, FILE *stream ); -extern size_t _mitkIpFWrite( void *ptr, size_t size, size_t nitems, FILE *stream ); - -#define _mitkIpPicHAS_CAN_READ_COMPRESSED -extern mitkIpBool_t _mitkIpPicCanReadCompressed; -extern size_t mitkIpPicFReadCvt( void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream ); - -#define _mitkIpPicHAS_CAN_WRITE_COMPRESSED -extern mitkIpBool_t _mitkIpPicCanWriteCompressed; -extern size_t mitkIpPicFWriteCvt( void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream ); - -extern mitkIpPicDescriptor *mitkIpPicNew( void ); -extern void mitkIpPicClear( mitkIpPicDescriptor *pic ); -extern void mitkIpPicFree( mitkIpPicDescriptor *pic ); - -extern mitkIpUInt4_t _mitkIpPicSize( -#if defined(__cplusplus) || defined(c_plusplus) - const -#endif - mitkIpPicDescriptor *pic ); - -extern mitkIpUInt4_t _mitkIpPicElements( mitkIpPicDescriptor *pic ); - -extern mitkIpUInt4_t _mitkIpPicTSVSize( mitkIpPicTSV_t *tsv ); -extern mitkIpUInt4_t _mitkIpPicTSVElements( mitkIpPicTSV_t *tsv ); - -extern mitkIpPicDescriptor *mitkIpPicClone( mitkIpPicDescriptor *pic ); - -extern mitkIpPicDescriptor *_mitkIpPicCopySlice( mitkIpPicDescriptor *pic, mitkIpPicDescriptor *pic_in, mitkIpUInt4_t slice ); - -extern mitkIpPicDescriptor *_mitkIpPicOldGet( FILE *infile, mitkIpPicDescriptor *pic ); -extern mitkIpPicDescriptor *_mitkIpPicOldGetHeader( FILE *infile, mitkIpPicDescriptor *pic ); -extern mitkIpPicDescriptor *_mitkIpPicOldGetSlice( FILE *infile, mitkIpPicDescriptor *pic, mitkIpUInt4_t slice ); - - -extern mitkIpPicDescriptor *mitkIpPicCopyHeader( mitkIpPicDescriptor *pic, mitkIpPicDescriptor *pic_new ); - -extern mitkIpPicDescriptor *mitkIpPicGet( const char *picfile_name, mitkIpPicDescriptor *pic ); -extern mitkIpPicDescriptor *mitkIpPicGetHeader( const char *picfile_name, mitkIpPicDescriptor *pic ); -extern mitkIpPicDescriptor *mitkIpPicGetSlice( const char *picfile_name, mitkIpPicDescriptor *pic, mitkIpUInt4_t slice ); - -extern _mitkIpPicTagsElement_t *_mitkIpPicReadTags( _mitkIpPicTagsElement_t *head, mitkIpUInt4_t bytes_to_read, FILE *stream, char encryption_type ); -extern _mitkIpPicTagsElement_t *_mitkIpPicInsertTag( _mitkIpPicTagsElement_t *head, mitkIpPicTSV_t *tsv ); -extern _mitkIpPicTagsElement_t *_mitkIpPicFindTag( _mitkIpPicTagsElement_t *head, const char *tag ); -extern mitkIpUInt4_t _mitkIpPicTagsSize( _mitkIpPicTagsElement_t *head ); -extern mitkIpUInt4_t _mitkIpPicTagsNumber( _mitkIpPicTagsElement_t *head ); -extern void _mitkIpPicWriteTags( _mitkIpPicTagsElement_t *head, FILE *stream, char encryption_type ); -extern void _mitkIpPicFreeTags( _mitkIpPicTagsElement_t *head ); -extern mitkIpPicTSV_t *_mitkIpPicCloneTag( mitkIpPicTSV_t *source ); -extern _mitkIpPicTagsElement_t *_mitkIpPicCloneTags( _mitkIpPicTagsElement_t *head ); - -extern void mitkIpPicAddTag( mitkIpPicDescriptor *pic, mitkIpPicTSV_t *tsv ); -extern void mitkIpPicAddSubTag( mitkIpPicTSV_t *parent, mitkIpPicTSV_t *tsv ); -extern mitkIpPicTSV_t * mitkIpPicDelTag( mitkIpPicDescriptor *pic, const char *tag ); -extern mitkIpPicTSV_t * mitkIpPicDelSubTag( mitkIpPicTSV_t *parent, const char *tag ); -extern mitkIpPicDescriptor *mitkIpPicGetTags( const char *picfile_name, mitkIpPicDescriptor *pic ); -extern mitkIpPicTSV_t *mitkIpPicQueryTag( mitkIpPicDescriptor *pic, const char *t ); -extern mitkIpPicTSV_t *mitkIpPicQuerySubTag( mitkIpPicTSV_t *parent, const char *t ); -extern void mitkIpPicFreeTag( mitkIpPicTSV_t *tsv ); - - -extern _mitkIpPicTagsElement_t * _mitkIpPicReadTagsMem( _mitkIpPicTagsElement_t *head, mitkIpUInt4_t bytes_to_read, mitkIpUInt1_t **mem_ptr, char encryption_type ); -extern mitkIpPicDescriptor *mitkIpPicGetMem( mitkIpUInt1_t *mem_pic ); -extern void _mitkIpPicWriteTagsMem( _mitkIpPicTagsElement_t *head, mitkIpUInt1_t **mem_ptr ); -extern mitkIpUInt1_t *mitkIpPicPutMem( mitkIpPicDescriptor *pic, int *mem_size ); - - -extern int mitkIpPicPut( const char *picfile_name, mitkIpPicDescriptor *pic ); -extern void mitkIpPicPutSlice( const char *picfile_name, mitkIpPicDescriptor *pic, mitkIpUInt4_t slice ); - -#define _mitkIpPicInfoNORMAL 0 -#define _mitkIpPicInfoSHORT (1 << 0) -void _mitkIpPicInfo( FILE *stream, mitkIpPicDescriptor *pic, mitkIpUInt4_t flags ); -void _mitkIpPicInfoPrintTags( FILE *stream, _mitkIpPicTagsElement_t* head, mitkIpUInt4_t level, mitkIpUInt4_t flags ); - -extern const char *mitkIpPicTypeName( mitkIpUInt4_t type ); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - - -#endif /* _mitkIpPic_h */ - -#ifdef MITK_UNMANGLE_IPPIC -#include "mitkIpPicUnmangle.h" -#endif diff --git a/Utilities/IpPic/mitkIpPicOldP.h b/Utilities/IpPic/mitkIpPicOldP.h deleted file mode 100755 index 5a3e07f31c..0000000000 --- a/Utilities/IpPic/mitkIpPicOldP.h +++ /dev/null @@ -1,92 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * the old pic header - * - * $Log$ - * Revision 1.5 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.3 2000/05/04 12:52:40 ivo - * inserted BSD style license - * - * Revision 1.2 2000/05/04 12:36:01 ivo - * some doxygen comments. - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision - * - * - *-------------------------------------------------------------------- - * - */ - -#ifndef _mitkIpPicOldP_h -#define _mitkIpPicOldP_h - -typedef struct - { - mitkIpUInt4_t id, - dummy1, - dummy2, - conv, - rank, - n1, - n2, - n3, - n4, - n5, - n6, - n7, - n8, - type, - ntxt, - ltxt; - } _mitkIpPicOldHeader; -#endif /* ifdef _mitkIpPicOldP_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ diff --git a/Utilities/IpPic/mitkIpPicTypeMultiplex.h b/Utilities/IpPic/mitkIpPicTypeMultiplex.h deleted file mode 100644 index 7c515e335a..0000000000 --- a/Utilities/IpPic/mitkIpPicTypeMultiplex.h +++ /dev/null @@ -1,730 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/** @file -* -*Module Name:mitkIpPicTypeMultiplex -* -*Module Klasse: ADT -* -*Beschreibung:Multiplexing a method with the image datatyp. -*The image is the first parameter. -*The method must be about a template method. -*The number of parameter is constricted by 16 -* -*Method with two parameter and without a return value: -*mitkIpPicTypeMultiplex2( funktionsname, parameter1, Parameter2 ); -* -*Method with one parameter and a return value: -*mitkIpPicTypeMultiplexR1( funktionsname, r�ckgabewert, parameter ); -* -*If R is set the method return a value -*The number set the count of parameter -* -*exported classes and methods: -*no one -* -*imported classes and methods: -*std::complex -* -*@warning These module is not finished -* -* -*@version 1.0 -* -* @date 07.09.2000 -* -* @author Marcus Vetter -* -*/ - -#ifndef IP_PIC_TYPE_MULTIPLEX_H -#define IP_PIC_TYPE_MULTIPLEX_H - -#include "mitkIpPic.h" -//#include <complex> - -#define mitkIpPicTypeMultiplex0( function, pic ) \ -{ \ -if ( ( pic->type == mitkIpPicInt || pic->type == mitkIpPicUInt ) && pic->bpe == 1 ){ \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ -function<char>( pic ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic ); \ -} \ -} - -#define mitkIpPicTypeMultiplex1( function, pic, param1 ) \ -{ \ -if ( ( pic->type == mitkIpPicInt || pic->type == mitkIpPicUInt ) && pic->bpe == 1 ){ \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ -function<char>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1 ); \ -} \ -} -/* -else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1 ); -} -*/ - -#define mitkIpPicTypeMultiplex2( function, pic, param1, param2 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2 ); \ -} \ -} -/* -else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2 ); -} -*/ -#define mitkIpPicTypeMultiplex3( function, pic, param1, param2, param3 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3 ); \ -} \ -} -/*else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3 ); -}*/ - -#define mitkIpPicTypeMultiplex4( function, pic, param1, param2, param3, param4 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4 ); \ -} \ -} -/* -else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4 ); -}*/ - -#define mitkIpPicTypeMultiplex5( function, pic, param1, param2, param3, param4, param5 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4, param5 ); \ -} \ -} -/* else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4, param5 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4, param5 ); -} -*/ -#define mitkIpPicTypeMultiplex6( function, pic, param1, param2, param3, param4, param5, param6 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4, param5, param6 ); \ -} \ -} -/*else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4, param5, param6 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4, param5, param6 ); -}*/ - -#define mitkIpPicTypeMultiplex7( function, pic, param1, param2, param3, param4, param5, param6, param7 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} \ -} -/*else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4, param5, param6 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4, param5, param6 ); -}*/ - -#define mitkIpPicTypeMultiplex7( function, pic, param1, param2, param3, param4, param5, param6, param7 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} \ -} -/*else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4, param5, param6 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4, param5, param6 ); -}*/ - -#define mitkIpPicTypeMultiplex8( function, pic, param1, param2, param3, param4, param5, param6, param7, param8) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4, param5, param6, param7, param8); \ -} \ -} -/*else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4, param5, param6 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4, param5, param6 ); -}*/ - -#define mitkIpPicTypeMultiplex9( function, pic, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9); \ -} \ -} -/*else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4, param5, param6 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4, param5, param6 ); -}*/ - -#define mitkIpPicTypeMultiplex10( function, pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ -} \ -} -/*else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4, param5, param6 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4, param5, param6 ); -}*/ - -#define mitkIpPicTypeMultiplex16( function, pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - function<char>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -function<short>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -function<int>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -function<long>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -function<float>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -function<double>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16 ); \ -} \ -} -/*else if ( pic->type == mitkIpPicComplex && pic->bpe == 64 ){ -function<std::complex<float> >( pic, param1, param2, param3, param4, param5, param6 ); -} else if ( pic->type == mitkIpPicComplex && pic->bpe == 128 ){ -function<std::complex<double> >( pic, param1, param2, param3, param4, param5, param6 ); -}*/ -/** -* with return value -*/ - -#define mitkIpPicTypeMultiplexR0( function, pic, returnValue ) \ -{ \ -if ( ( pic->type == mitkIpPicInt || pic->type == mitkIpPicUInt ) && pic->bpe == 1 ){ \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ -returnValue = function<char>( pic ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR1( function, pic, returnValue, param1 ) \ -{ \ -if ( ( pic->type == mitkIpPicInt || pic->type == mitkIpPicUInt ) && pic->bpe == 1 ){ \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ -returnValue = function<char>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1 ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR2( function, pic, returnValue, param1, param2 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - returnValue = function<char>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1, param2 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1, param2 ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR3( function, pic, returnValue, param1, param2, param3 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - returnValue = function<char>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1, param2, param3 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1, param2, param3 ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR4( function, pic, returnValue, param1, param2, param3, param4 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - returnValue = function<char>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1, param2, param3, param4 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1, param2, param3, param4 ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR5( function, pic, returnValue, param1, param2, param3, param4, param5 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - returnValue = function<char>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1, param2, param3, param4, param5 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1, param2, param3, param4, param5 ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR6( function, pic, returnValue, param1, param2, param3, param4, param5, param6 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - returnValue = function<char>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1, param2, param3, param4, param5, param6 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1, param2, param3, param4, param5, param6 ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR7( function, pic, returnValue, param1, param2, param3, param4, param5, param6, param7 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - returnValue = function<char>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1, param2, param3, param4, param5, param6, param7 ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR8( function, pic, returnValue, param1, param2, param3, param4, param5, param6, param7, param8 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - returnValue = function<char>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1, param2, param3, param4, param5, param6, param7, param8 ); \ -} \ -} - -#define mitkIpPicTypeMultiplexR9( function, pic, returnValue, param1, param2, param3, param4, param5, param6, param7, param8, param9 ) \ -{ \ -if ( pic->type == mitkIpPicInt && pic->bpe == 8 ){ \ - returnValue = function<char>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 8 ){ \ -returnValue = function<unsigned char>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 16 ){ \ -returnValue = function<short>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 16 ){ \ -returnValue = function<unsigned short>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 32 ){ \ -returnValue = function<int>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 32 ){ \ -returnValue = function<unsigned int>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicInt && pic->bpe == 64 ){ \ -returnValue = function<long>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicUInt && pic->bpe == 64 ){ \ -returnValue = function<unsigned long>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 32 ){ \ -returnValue = function<float>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} else if ( pic->type == mitkIpPicFloat && pic->bpe == 64 ){ \ -returnValue = function<double>( pic, param1, param2, param3, param4, param5, param6, param7, param8, param9 ); \ -} \ -} - -#endif // IP_PIC_TYPE_MULTIPLEX_H diff --git a/Utilities/IpPic/mitkIpTypes.h b/Utilities/IpPic/mitkIpTypes.h deleted file mode 100755 index 5927d88ba0..0000000000 --- a/Utilities/IpPic/mitkIpTypes.h +++ /dev/null @@ -1,122 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * defines the ipTypes - * - *-------------------------------------------------------------------- - */ - -#ifndef _mitkIpTypes_h -#define _mitkIpTypes_h - -#if defined (__mips) || (_IBMR2) || (sun) || (__i386__) || (__convex__) || (__alpha) || (__hppa) || (WIN32) || (_WIN32) || defined (__PPC__) || defined (__x86_64__) || defined (__APPLE__) - typedef signed char mitkIpInt1_t; - typedef signed short mitkIpInt2_t; - typedef signed int mitkIpInt4_t; - typedef unsigned char mitkIpUInt1_t; - typedef unsigned short mitkIpUInt2_t; - typedef unsigned int mitkIpUInt4_t; - typedef float mitkIpFloat4_t; - typedef double mitkIpFloat8_t; -#endif - -#ifdef DOS - typedef signed char mitkIpInt1_t; - typedef signed int mitkIpInt2_t; - typedef signed long int mitkIpInt4_t; - typedef unsigned char mitkIpUInt1_t; - typedef unsigned int mitkIpUInt2_t; - typedef unsigned long int mitkIpUInt4_t; - typedef float mitkIpFloat4_t; - typedef double mitkIpFloat8_t; -#endif - -/* -** this boolean is NOT a 1 bit value !!! -** it is NOT intended for 1 bit images !!! -*/ -typedef enum - { mitkIpFalse = 0, - mitkIpTrue = 1 - } mitkIpBool_t; - -typedef enum - { - mitkIpError = -1, /* general error */ - mitkIpOK = 0, /* no error */ - mitkIpEDIM = 1000 /* wrong number of dimensions */ - } mitkIpError_t; - - -typedef enum - { - _mitkIpEndianUnknown = 0, - _mitkIpEndianLittle = 1, - _mitkIpEndianBig = 2 - } _mitkIpEndian_t; - -typedef enum - { - mitkIpTypeUnknown = 0, - mitkIpTypeStringPtr, - mitkIpTypeString, - mitkIpTypeInt1, - mitkIpTypeInt2, - mitkIpTypeInt4, - mitkIpTypeUInt1, - mitkIpTypeUInt2, - mitkIpTypeUInt4, - mitkIpTypeFloat4, - mitkIpTypeFloat8, - mitkIpTypeNBytes, - mitkIpTypeArray, - mitkIpTypeList, - mitkIpTypePic, - mitkIpTypePicTag, - _mitkIpTypeMAX - } mitkIpType_t; - -#endif /* _mitkIpTypes_h */ -/* DON'T ADD ANYTHING AFTER THIS #endif */ diff --git a/Utilities/IpPic/pic2seq.c b/Utilities/IpPic/pic2seq.c deleted file mode 100755 index ecaaa6fef2..0000000000 --- a/Utilities/IpPic/pic2seq.c +++ /dev/null @@ -1,274 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - -/********************************************************************* / -/ pic2seq / -/ -------------------------------------------------------------------- / -/ DESCRIPTION / -/ / -/ converts a pic-seq to single pic-files / -/ / -/ / -/ FUNCTION DECLARATION / -/ / -/ / -/ PROTOTYPE CALL / -/ / -/ / -/ PARAMETER / -/ / -/ / -/ RETURN VALUES / -/ / -/ 0 - no error occured / -/ -1 - error oocured / -/ / -/ AUTHOR & DATE / -/ / -/ Andre Schroeter 08.06.1992 / -/ / -/ UPDATES / -/ / -/ / -/ / -/**********************************************************************/ -static char *what[] = { - "@(#)seqtopic \t06/92\tGerman Cancer Research Center (DKFZ)\t08.06.1992", -}; -/* standard include files */ -#include <stdio.h> -#include <string.h> -#include <fcntl.h> - -#include <mitkIpPic.h> - - -#ifndef FILENAME_MAX -# define FILENAME_MAX 1024 -#endif - -#ifndef Bool -typedef char Bool; -# define True 1 -# define False 0 -#endif - -void main( int argc, char *argv[] ) -{ - int i; - - int n_infiles; - char **infile_names; - - unsigned int n; - Bool is_number; - Bool scan_error; - Bool use_stdin; - Bool use_stdout; - Bool use_textfile; - - Bool append; - int soffset; - int aoffset; - - char outfile_name[FILENAME_MAX], - outfile_string[FILENAME_MAX]; - - mitkIpPicDescriptor *pic = NULL,*header; - - - /*--------------- commandline scaning starts here -----------*/ - append = False; - use_stdin = True; - use_stdout = True; - scan_error = False; - use_textfile = False; - - aoffset = 0; - soffset = 0; - - n = 1; - while( n < argc ) - { - if( *argv[n] == '-' ) - switch( *(argv[n]+1) ) - { - case 'a': append = True; - ++aoffset; - break; - /*case 'o': use_stdout = False; - strcpy( outfile_string, argv[n]+2 ); - if( outfile_string[0] == '\0' ) - scan_error = True; - break;*/ - case 'h': - case 'H': scan_error = True; - break; - case 'f': use_textfile = True; - ++aoffset; - break; - default: fprintf( stderr, - "%s: sorry, unknown option -%c\n", - argv[0], *(argv[n]+1) ); - scan_error = True; - break; - } - else - { - use_stdin = False; - strcpy( outfile_string, argv[n] ); - } - n++; - } - - if( scan_error ) - { - fprintf( stderr, "Usage: %s -a -f outfile infiles \n", argv[0] ); - fprintf( stderr, " -a appends the infiles to outfile\n" ); - fprintf( stderr, " -f \"infiles\" is a text file containing the list of inputfiles\n" ); - fprintf( stderr, " outfile the outputfile to create\n" ); - fprintf( stderr, " infiles a list of inputfiles\n" ); - exit( -1 ); - } - - /*--------------- commandline scaning ends here -------------*/ - - /* read text file, if specified*/ - if(use_textfile) - { - char tmp[FILENAME_MAX]; - FILE *f; - - n_infiles=0; - - f=fopen(argv[aoffset+2], "rt"); - if(f==NULL) - { - fprintf( stderr, "Couldn't open text file containing the list of inputfiles.\n", argv[0] ); - exit( -2 ); - } - - while(!feof(f)) - { - fgets(tmp, 255, f); - ++n_infiles; - } - - infile_names=malloc(n_infiles*sizeof(char*)); - - rewind(f); - - i=0; - while(!feof(f)) - { - char *nl; - infile_names[i]=malloc(FILENAME_MAX*sizeof(char)); - fgets(infile_names[i], FILENAME_MAX, f); - nl=infile_names[i]+strlen(infile_names[i])-1; - if(*nl=='\n') *nl=0; - if(mitkIpPicAccess(infile_names[i], 4)==0) - ++i; - else - { - free(infile_names[i]); - --n_infiles; - } - } - } - else - { - n_infiles=argc-2-aoffset; - if(n_infiles<=0) - exit( -3 ); - - infile_names=malloc(n_infiles*sizeof(char*)); - for(i=0;i<n_infiles;++i) - infile_names[i]=argv[aoffset+i+2]; - } - - /* make filenames */ - if( !use_stdout) - if( !strchr(outfile_name, '.') ) - strcat( outfile_name, ".seq" ); - if( append ) - { - pic = mitkIpPicGetHeader( argv[aoffset+1], - pic ); - if( pic != NULL ) - soffset = pic->n[pic->dim-1]; - else - soffset = 0; - } - - header=mitkIpPicGetHeader( infile_names[0], NULL); - header = mitkIpPicGetTags( infile_names[0], header ); - - for( i=0; i<n_infiles; i++ ) - { - printf( "%.3i %s\n", i, infile_names[i] ); - - -/* pic = mitkIpPicGetSlice( infile_names[i], - pic, - 1 );*/ - pic = mitkIpPicGet( infile_names[i], - pic); - - if( pic == NULL ) - { - fprintf( stderr, "sorry, can't open %s\n", infile_names[i] ); - exit( -1 ); - } - pic->info->write_protect = mitkIpFalse; - pic->info->tags_head = _mitkIpPicCloneTags(header->info->tags_head ); - if((i==0) && (!append)) - { - pic->dim++; pic->n[pic->dim-1]=1; - mitkIpPicPut(argv[aoffset+1], pic); - } - else - mitkIpPicPutSlice( argv[aoffset+1], - pic, - soffset + i + 1 ); - - } - - exit( 0 ); -} diff --git a/Utilities/IpPic/pic2seq.dsp b/Utilities/IpPic/pic2seq.dsp deleted file mode 100755 index 918d048bcb..0000000000 --- a/Utilities/IpPic/pic2seq.dsp +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="pic2seq" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=pic2seq - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "pic2seq.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "pic2seq.mak" CFG="pic2seq - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "pic2seq - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "pic2seq - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "pic2seq - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\bin" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /I "$(QTDIR)\src\3rdparty\zlib" /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"LIBCMT.lib" - -!ELSEIF "$(CFG)" == "pic2seq - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\bin" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /I "$(QTDIR)\src\3rdparty\zlib" /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libc.lib" /out:".\bin/pic2seqD.exe" /pdbtype:sept -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "pic2seq - Win32 Release" -# Name "pic2seq - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\pic2seq.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/Utilities/IpPic/picinfo.c b/Utilities/IpPic/picinfo.c deleted file mode 100755 index eeb361ad7d..0000000000 --- a/Utilities/IpPic/picinfo.c +++ /dev/null @@ -1,309 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -/* - * $RCSfile$ - *--------------------------------------------------------------- - * DESCRIPTION - * prints information about a picfile - * - * $Log$ - * Revision 1.7 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.6 2002/10/31 10:00:30 ivo - * zlib.lib including headers now in win32. gz-extension should work now on every windows. - * WIN32 define changed to standard _WIN32. - * - * Revision 1.5 2002/04/18 19:09:13 ivo - * compression (zlib) activated. - * - * Revision 1.4 2000/05/04 12:52:42 ivo - * inserted BSD style license - * - * Revision 1.3 2000/05/04 12:36:02 ivo - * some doxygen comments. - * - * Revision 1.2 1997/09/15 13:21:22 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:10:00 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *--------------------------------------------------------------- - * - */ -#ifndef lint - static char *what = { "@(#)picinfo \t\tGerman Cancer Research Center (DKFZ)\t"__DATE__"\t$Revision$" }; -#endif - -/* -** defines -*/ - -/* -** standard includes -*/ -#include <stdio.h> -#include <stdlib.h> - -#ifndef _WIN32 -#include <strings.h> -#else -#include <string.h> -#endif - -#include <limits.h> - -/* -** ip includefiles -*/ -#include "mitkIpPic.h" - -/* -** typedefs -*/ -typedef int Bool; -#define TRUE 1 -#define FALSE 0 - -/* -** private macros -*/ -#define Min(x, y) (((x) < (y)) ? (x) : (y)) -#define Max(x, y) (((x) > (y)) ? (x) : (y)) - - -#define MIN_MAX(min, max, type) \ - for( i=0; i<_mitkIpPicElements(pic); i++ ) \ - { \ - type pixel = ((type *)pic->data)[i]; \ - \ - if( pixel < min ) \ - min = pixel; \ - else if( pixel > max ) \ - max = pixel; \ - } - -/* -** the action starts here -*/ -int main( int argc, char *argv[] ) -{ - int i; - - long min_i = LONG_MAX, - max_i = LONG_MIN; - double min_f = LONG_MAX, - max_f = LONG_MIN; - - int n; - Bool scan_error; - Bool use_stdin; - - Bool show_extrema; - mitkIpUInt4_t flags; - -#ifndef FILENAME_MAX -#define FILENAME_MAX 256 -#endif - - char picfile_name[FILENAME_MAX]; - - mitkIpPicDescriptor *pic; - - - /*--------------- commandline scaning starts here -----------*/ - use_stdin = TRUE; - scan_error = FALSE; - - show_extrema = FALSE; - flags = _mitkIpPicInfoNORMAL; - - n = 1; - while( n < argc ) - { - if( *argv[n] == '-' ) - switch( *(argv[n]+1) ) - { - case 'e': - show_extrema = TRUE; - break; - case 's': - flags |= _mitkIpPicInfoSHORT; - break; - case 'h': - case 'H': - scan_error = TRUE; - break; - default: fprintf( stderr, "%s: sorry, unknown option -%c\n", argv[0], *(argv[n]+1) ); - scan_error = TRUE; - break; - } - else - { - if( use_stdin ) - { - use_stdin = FALSE; - strcpy( picfile_name, argv[n] ); - } - else - scan_error = TRUE; - } - n++; - } - - if( scan_error ) - { - fprintf( stderr, "Usage: %s -e -s [picfile]\n", argv[0] ); - fprintf( stderr, " -e calculate the extrema\n" ); - fprintf( stderr, " -s short output\n" ); - fprintf( stderr, " picfile the picfile to examine, if not given stdin is used\n" ); - exit( mitkIpError ); - } - - /*--------------- commandline scaning ends here -------------*/ - - /* make filenames */ - if( !use_stdin) - if( (strrchr(picfile_name, '/') >= strrchr(picfile_name, '.')) ) - strcat( picfile_name, ".pic" ); - - /* read picfile */ - if( use_stdin ) - pic = mitkIpPicGetHeader( "stdin", - NULL ); - else - { - pic = mitkIpPicGetHeader( picfile_name, - NULL ); - pic = mitkIpPicGetTags( picfile_name, - pic ); - } - - if( pic == NULL ) - { - fprintf( stderr, "sorry, can't read %s\n", picfile_name ); - exit( mitkIpError ); - } - - printf( "\n" ); - printf( "%s\n",picfile_name ); - - printf( "%.*s\n", _mitkIpPicTAGLEN, pic->info->version ); - printf( "--------------------\n" ); - - printf( "type: %s [%i]\n", mitkIpPicTypeName(pic->type), pic->type ); - - printf( "bpe : %i\n", pic->bpe ); - - printf( "dim : %i ", pic->dim ); - for( i=0; i<pic->dim; i++ ) - printf( "[%i] ", pic->n[i] ); - printf( "\n" ); - - if( pic != NULL - && pic->info->tags_head != NULL ) - printf( "--------------------\n" ); - - _mitkIpPicInfoPrintTags( stdout, - pic->info->tags_head, - 1, - flags ); - - printf( "--------------------\n" ); - printf( "size of the image data: %u\n", _mitkIpPicSize( pic ) ); - - - if( show_extrema ) - { - pic = mitkIpPicGet( picfile_name, - pic ); - - switch( mitkIpPicDR( pic->type, pic->bpe ) ) - { - case mitkIpPicDR( mitkIpPicUInt, 8 ): - { - MIN_MAX( min_i, max_i, mitkIpUInt1_t ); - printf( "min: %li, max: %li\n", min_i, max_i ); - } - break; - case mitkIpPicDR( mitkIpPicInt, 16 ): - { - MIN_MAX( min_i, max_i, mitkIpInt2_t ); - printf( "min: %li, max: %li\n", min_i, max_i ); - } - break; - case mitkIpPicDR( mitkIpPicInt, 32 ): - { - MIN_MAX( min_i, max_i, mitkIpInt4_t ); - printf( "min: %li, max: %li\n", min_i, max_i ); - } - break; - case mitkIpPicDR( mitkIpPicFloat, 32 ): - { - MIN_MAX( min_f, max_f, mitkIpFloat4_t ); - printf( "min: %f, max: %f\n", min_f, max_f ); - } - break; - case mitkIpPicDR( mitkIpPicFloat, 64 ): - { - MIN_MAX( min_f, max_f, mitkIpFloat8_t ); - printf( "min: %f, max: %f\n", min_f, max_f ); - } - break; - default : - printf( "sorry, datatype not supported. (min,max)\n" ); - break; - } - } - - mitkIpPicFree( pic ); - - return( 0 ); -} diff --git a/Utilities/IpPic/picinfo.dsp b/Utilities/IpPic/picinfo.dsp deleted file mode 100755 index b1b81810e2..0000000000 --- a/Utilities/IpPic/picinfo.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="picinfo" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=picinfo - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "picinfo.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "picinfo.mak" CFG="picinfo - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "picinfo - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "picinfo - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "picinfo - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\bin" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "$(QTDIR)\src\3rdparty\zlib" /I "." /I ".." /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /D "lint" /YX /FD /c -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt.lib" - -!ELSEIF "$(CFG)" == "picinfo - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "picinfo___Win32_Debug" -# PROP BASE Intermediate_Dir "picinfo___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\bin" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "$(QTDIR)\src\3rdparty\zlib" /I "." /I ".." /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /D "lint" /YX /FD /GZ /c -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt.lib" /nodefaultlib:"libc.lib" /out:".\bin/picinfoD.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "picinfo - Win32 Release" -# Name "picinfo - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\picinfo.c -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/Utilities/IpPic/test.c b/Utilities/IpPic/test.c deleted file mode 100755 index a96d506f4b..0000000000 --- a/Utilities/IpPic/test.c +++ /dev/null @@ -1,73 +0,0 @@ -/*============================================================================ - - Copyright (c) German Cancer Research Center (DKFZ) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the German Cancer Research - Center (DKFZ)." - - - Neither the name of the German Cancer Research Center (DKFZ) nor the names - of its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE GERMAN CANCER RESEARCH CENTER (DKFZ) AND - CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GERMAN - CANCER RESEARCH CENTER (DKFZ) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -============================================================================*/ - - -#include <stdio.h> -#include <strings.h> - -#include "mitkIpPic.h" -#include "mitkIpPicAnnotation.h" - -int main( int argc, char *argv[] ) -{ - mitkIpPicDescriptor *pic; - mitkIpPicDescriptor *pic2; - mitkIpPicTSV_t *tsv; - mitkIpPicTSV_t *tsv2; - mitkIpPicTSV_t *tsv3; - mitkIpPicAnnotation_t a; - char buff[] = "test test"; - - printf( "%s\n", _mitkIpEndian()==_mitkIpEndianBig?"BigEndian":"LittleEndian" ); - - if( argc != 3 ) - exit(-1); - - pic = mitkIpPicGet( argv[1], - NULL ); - - mitkIpPicSetWriteCompression( mitkIpTrue ); - mitkIpPicPut( argv[2], - pic ); - - mitkIpPicFree( pic ); - - return(0); -} diff --git a/Utilities/IpSegmentation/CMakeLists.txt b/Utilities/IpSegmentation/CMakeLists.txt deleted file mode 100644 index fb533b5b9a..0000000000 --- a/Utilities/IpSegmentation/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -set(module_options NO_INIT GCC_DEFAULT_VISIBILITY WARNINGS_NO_ERRORS) -if(MITK_WIN32_FORCE_STATIC) - list(APPEND module_options FORCE_STATIC) -endif() - -MITK_CREATE_MODULE( - DEPENDS MitkIpPic MitkIpFunc - PACKAGE_DEPENDS ANN - ${module_options} -) diff --git a/Utilities/IpSegmentation/GraphicsGems.h b/Utilities/IpSegmentation/GraphicsGems.h deleted file mode 100644 index 3bd91ad5e4..0000000000 --- a/Utilities/IpSegmentation/GraphicsGems.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This code is taken from the Graphics Gems book series by Academic Press. - * - * For information on the books and more of the source code - * you can visit http://tog.acm.org/GraphicsGems/ - * - * The following note on license is taken from the mentions website: - * - * EULA: The Graphics Gems code is copyright-protected. - * In other words, you cannot claim the text of the code - * as your own and resell it. Using the code is permitted - * in any program, product, or library, non-commercial or - * commercial. Giving credit is not required, though is - * a nice gesture. The code comes as-is, and if there are - * any flaws or problems with any Gems code, nobody involved - * with Gems - authors, editors, publishers, or webmasters - * - are to be held responsible. Basically, don't be a jerk, - * and remember that anything free comes with no guarantee. - * -*/ - -/* - * GraphicsGems.h - * Version 1.0 - Andrew Glassner - * from "Graphics Gems", Academic Press, 1990 - */ - -#ifndef GG_H - -#define GG_H 1 - -/*********************/ -/* 2d geometry types */ -/*********************/ - -typedef struct Point2Struct { /* 2d point */ - double x, y; -} Point2; -typedef Point2 Vector2; - -typedef struct IntPoint2Struct { /* 2d integer point */ - int x, y; -} IntPoint2; - -typedef struct Matrix3Struct { /* 3-by-3 matrix */ - double element[3][3]; -} Matrix3; - -typedef struct Box2dStruct { /* 2d box */ - Point2 min, max; -} Box2; - - -/*********************/ -/* 3d geometry types */ -/*********************/ - -typedef struct Point3Struct { /* 3d point */ - double x, y, z; -} Point3; -typedef Point3 Vector3; - -typedef struct IntPoint3Struct { /* 3d integer point */ - int x, y, z; -} IntPoint3; - - -typedef struct Matrix4Struct { /* 4-by-4 matrix */ - double element[4][4]; -} Matrix4; - -typedef struct Box3dStruct { /* 3d box */ - Point3 min, max; -} Box3; - - - -/***********************/ -/* one-argument macros */ -/***********************/ - -/* absolute value of a */ -#define ABS(a) (((a)<0) ? -(a) : (a)) - -/* round a to nearest int */ -#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a))) - -/* take sign of a, either -1, 0, or 1 */ -#define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0) - -/* take binary sign of a, either -1, or 1 if >= 0 */ -#define SGN(a) (((a)<0) ? -1 : 1) - -/* shout if something that should be true isn't */ -#define ASSERT(x) \ -if (!(x)) fprintf(stderr," Assert failed: x\n"); - -/* square a */ -#define SQR(a) ((a)*(a)) - - -/***********************/ -/* two-argument macros */ -/***********************/ - -/* find minimum of a and b */ -#define MIN(a,b) (((a)<(b))?(a):(b)) - -/* find maximum of a and b */ -#define MAX(a,b) (((a)>(b))?(a):(b)) - -/* swap a and b (see Gem by Wyvill) */ -#define SWAP(a,b) { a^=b; b^=a; a^=b; } - -/* linear interpolation from l (when a=0) to h (when a=1)*/ -/* (equal to (a*h)+((1-a)*l) */ -#define LERP(a,l,h) ((l)+(((h)-(l))*(a))) - -/* clamp the input to the specified range */ -#define CLAMP(v,l,h) ((v)<(l) ? (l) : (v) > (h) ? (h) : v) - - -/****************************/ -/* memory allocation macros */ -/****************************/ - -/* create a new instance of a structure (see Gem by Hultquist) */ -#define NEWSTRUCT(x) (struct x *)(malloc((unsigned)sizeof(struct x))) - -/* create a new instance of a type */ -#define NEWTYPE(x) (x *)(malloc((unsigned)sizeof(x))) - - -/********************/ -/* useful constants */ -/********************/ - -#define PI 3.141592 /* the venerable pi */ -#define PITIMES2 6.283185 /* 2 * pi */ -#define PIOVER2 1.570796 /* pi / 2 */ -#define E 2.718282 /* the venerable e */ -#define SQRT2 1.414214 /* sqrt(2) */ -#define SQRT3 1.732051 /* sqrt(3) */ -#define GOLDEN 1.618034 /* the golden ratio */ -#define DTOR 0.017453 /* convert degrees to radians */ -#define RTOD 57.29578 /* convert radians to degrees */ - - -/************/ -/* booleans */ -/************/ - -#define TRUE 1 -#define FALSE 0 -#define ON 1 -#define OFF 0 -typedef int boolean; /* boolean data type */ -typedef boolean flag; /* flag data type */ - -extern double V2SquaredLength(), V2Length(); -extern double V2Dot(), V2DistanceBetween2Points(); -extern Vector2 *V2Negate(), *V2Normalize(), *V2Scale(), *V2Add(), *V2Sub(); -extern Vector2 *V2Lerp(), *V2Combine(), *V2Mul(), *V2MakePerpendicular(); -extern Vector2 *V2New(), *V2Duplicate(); -extern Point2 *V2MulPointByMatrix(); -extern Matrix3 *V2MatMul(); - -extern double V3SquaredLength(), V3Length(); -extern double V3Dot(), V3DistanceBetween2Points(); -extern Vector3 *V3Normalize(), *V3Scale(), *V3Add(), *V3Sub(); -extern Vector3 *V3Lerp(), *V3Combine(), *V3Mul(), *V3Cross(); -extern Vector3 *V3New(), *V3Duplicate(); -extern Point3 *V3MulPointByMatrix(); -extern Matrix4 *V3MatMul(); - -extern double RegulaFalsi(), NewtonRaphson(), findroot(); - -#endif diff --git a/Utilities/IpSegmentation/empty.xpm b/Utilities/IpSegmentation/empty.xpm deleted file mode 100644 index ba49885034..0000000000 --- a/Utilities/IpSegmentation/empty.xpm +++ /dev/null @@ -1,89 +0,0 @@ -/* XPM */ -static const char *empty_xpm [] = { -/* width height num_colors chars_per_pixel */ -" 80 80 2 1", -/* colors */ -". c #000000", -"# c #c4c4c4", -/* pixels */ -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"..............................................#.................................", -".....................##...##..#.##.##..####..######..##.##......................", -"...................##....#..#..#..#..#..#..#..#...#..#....##....................", -".................##......####..#..#..#..#..#..#...#.##......##..................", -"...................##....#.....#..#..#..#..#..#...#.#.....##....................", -".....................##..##..#.#..#..#..#..#..#....##...##......................", -"..........................###.###.##.##.###....##..#............................", -"........................................#..........#............................", -"........................................#.........#.............................", -".......................................###.......##.............................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................", -"................................................................................" -}; diff --git a/Utilities/IpSegmentation/files.cmake b/Utilities/IpSegmentation/files.cmake deleted file mode 100644 index 6452f6aec4..0000000000 --- a/Utilities/IpSegmentation/files.cmake +++ /dev/null @@ -1,19 +0,0 @@ -set(H_FILES - -) - -set(CPP_FILES - ipSegmentationError.c - ipSegmentationNew.c - ipSegmentationFree.c - ipSegmentationClear.c - ipSegmentationCombineRegion.c - ipSegmentationRegionGrower.cpp - ipSegmentationContourExtraction.cpp - ipSegmentationReplaceRegion.cpp - ipSegmentationRegionCutter.cpp - ipSegmentationGrowerHistory.cpp - ipSegmentationContourUtils.cpp - ipSegmentationInterpolate.c - ipSegmentationUndo.c -) diff --git a/Utilities/IpSegmentation/ipSegmentation.h b/Utilities/IpSegmentation/ipSegmentation.h deleted file mode 100644 index 092ba39252..0000000000 --- a/Utilities/IpSegmentation/ipSegmentation.h +++ /dev/null @@ -1,209 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -/*! \mainpage - - \author Tobias Kunert, Thomas Boettger, Tobias Heimann - \date October 2002 - - The ipMITKSegmentation library manages the results of the - segmentation process. It provides basic capabilities - to modify segmentation images. It includes also an - undo mechanism which allows to trace back the changes. - -*/ - -#ifndef IPSEGMENTATION_H -#define IPSEGMENTATION_H - -#include <mitkIpPic.h> - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" -{ -#endif - - /*! - \brief Defines the data type of the segmentation images. - */ -#define ipMITKSegmentationTYPE mitkIpUInt1_t -#define ipMITKSegmentationTYPE_ID mitkIpPicUInt -#define ipMITKSegmentationBPE 8 -#define tagSEGMENTATION_EMPTY "SEGMENTATION_EMPTY" - - /*! - \brief Initializes the segmentation. - @param image the original image which will be segmented - @return the segmentation. - */ - extern mitkIpPicDescriptor* ipMITKSegmentationNew (mitkIpPicDescriptor* image); - - /*! - \brief Destroys the segmentation. - @param segmentation the segmentation. - */ - extern void ipMITKSegmentationFree (mitkIpPicDescriptor* segmentation); - - /*! - \brief Clears the segmentation data, i.e. the pixels will - be set to zero. - @param segmentation the segmentation - */ - extern void ipMITKSegmentationClear (mitkIpPicDescriptor* segmentation); - - /*! - \brief Interpolates the shape of segmentations. - @param pic1,pic2 the images of the segmentation - @param ratio the ratio of the images, the ratios 0.0 and 1.0 will - produce pic1 and pic2, accordingly. - */ - extern mitkIpPicDescriptor* ipMITKSegmentationInterpolate (mitkIpPicDescriptor* pic1, mitkIpPicDescriptor* pic2, const mitkIpFloat4_t ratio); - - /*! - \brief The type of logical operation. - */ - enum LogicalOp { - IPSEGMENTATION_OP /*! copy of input image */, - IPSEGMENTATION_AND /*! logical and operator */, - IPSEGMENTATION_OR /*! the or operator */, - IPSEGMENTATION_XOR /*! the exclusive-or operator */ - }; - - /*! - \brief Combines the region with the segmentation image. - @param points the array of points, each point is represented - by a 2-D vector (x, y) - @param segmentation the segmentation. - @param num the number of points - @param mask the image which restricts the operation to a particular region - @param operation the operation which will be performed (see above) - @param value the operand value of the operation - \note The last point is automatically connected with the first one. - */ - extern void ipMITKSegmentationCombineRegion (mitkIpPicDescriptor* segmentation, const mitkIpInt4_t* const points, const int num, mitkIpPicDescriptor* mask, const int operation, int value); - - /*! - \brief Enables the undo operation for the specified segmentation. - @param segmentation the segmentation - @param level the number of undo levels - */ - extern void ipMITKSegmentationUndoEnable (mitkIpPicDescriptor* segmentation, const mitkIpUInt1_t level); - - /*! - \brief Disables the undo operation for the specified segmentation. - The available data will be discarded. - @param segmentation the segmentation - */ - extern void ipMITKSegmentationUndoDisable (mitkIpPicDescriptor* segmentation); - - /*! - \brief Checks if the undo operation is enabled. - @param segmentation the segmentation - */ - extern mitkIpBool_t ipMITKSegmentationUndoIsEnabled (mitkIpPicDescriptor* segmentation); - - /*! - \brief Checks if any data for undo is available. - pending? - */ - extern mitkIpBool_t ipMITKSegmentationUndoAvailable (mitkIpPicDescriptor* segmentation); - - /*! - \brief Save the segmentation image before it is changed. - @param segmentation the segmentation - */ - extern void ipMITKSegmentationUndoSave (mitkIpPicDescriptor* segmentation); - - /*! - \brief Steps to the previous undo level. The data which has been saved - before the last modifications will be restored. - */ - extern void ipMITKSegmentationUndo (mitkIpPicDescriptor* segmentation); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -/*! - Starts a 4 neighbourhood region growing at startOfs (y*picWidth+x) of the 2D image src. - If relativeBounds is true, the region grows in [base-lowerBound, base+upperBound], in which base is the average - color of the 9 pixels around startOfs. If relativeBounds is false, the region grows in [lowerBound, upperBound]. - If maxIterations is > 0, the growing process is stopped after maxIterations. - If segBuffer is 0, new memory for the segmented image is allocated and returned, else the segBuffer is used - to store the result (has to be an 8-bit datatype, e.g. mitkIpUInt1_t). - histBuffer must be 0 or a pointer to a 16-bit mitkIpPicUInt image of the same size as src. In case of the latter, - history data is written to that buffer: the seed pixel gets a 1, all direct neighbours 2 etc. The buffer is - not cleared in this function and can thus hold history data of several growing processes in different areas. - */ -extern mitkIpPicDescriptor* ipMITKSegmentationGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBound, float upperBound, int maxIterations, mitkIpPicDescriptor *segBuffer, mitkIpPicDescriptor *histBuffer=nullptr ); - -/*! - Same as the other ipMITKSegmentationGrowRegion4N with two additional return values: - contourOfs holds the lowest point of the resulting region and is thus guaranteed to be part of the contour - Take care: if the region could not grow at all (e.g. with fixed borders) contourOfs will be -1 !!! - startCol holds the color that was used as base if relativeBounds is true - */ -extern mitkIpPicDescriptor* ipMITKSegmentationGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBound, float upperBound, int maxIterations, mitkIpPicDescriptor *segBuffer, int &contourOfs, float &startCol, mitkIpPicDescriptor *histBuffer=nullptr ); - -/*! - Replaces the 4 neighbourhood region around startOfs (y*picWidth+x) of the 2D segmented image seg with newValue. - Seg has to be an 8-bit datatype, e.g. mitkIpUInt1_t. - Returns the number of replaced pixels. If newValue is the same as the old value, the function returns 0. - */ -extern int ipMITKSegmentationReplaceRegion4N( mitkIpPicDescriptor *seg, int startOfs, mitkIpInt1_t newValue ); - -/*! - Same as above, but for the 8 neighbourhood contour. - */ -extern float* ipMITKSegmentationGetContour8N( const mitkIpPicDescriptor *seg, int startOfs, int &numPoints, int &sizeBuffer, float *pointBuffer=nullptr ); - - -typedef struct { - float *traceline; // x/y points describing the calculated path - memory has to be freed! - bool *onGradient; // flags for each point if path was calculated based on gradient (true) or on max distance (false) - memory has to be freed! - int numPoints; // number of points in the path - int absMin; // indexes the point at the narrowest part of the path - bool cutIt; // true if a leak has been found - float cutCoords[4]; // x1,y1,x2,y2 of the two contour points where the leak can be cut - float *deleteCurve; // x/y points of the closed contour describing the leak region - int deleteSize; // number of points in this contour -} tCutResult; - -/*! - Calculates a path from ofs to the origin of the growing process, when possible on the skeleton of the - segmented area. The narrowest part of this path is used to create two cut points that are part of the contour - and can later be used to split the segmentation. This funtion is useful for detecting and removing leaks in - region growing. - */ -extern tCutResult ipMITKSegmentationGetCutPoints( mitkIpPicDescriptor *seg, mitkIpPicDescriptor *history, int ofs ); - -/*! - Creates a grower history (i.e. the order in which a region grower would have segmented the area) of the given - segmentation, origin of the grower is startOfs. histBuffer must be a 16bit unsigned int or 0, in the latter - case the pic is created. - */ -extern mitkIpPicDescriptor* ipMITKSegmentationCreateGrowerHistory( mitkIpPicDescriptor *seg, int startOfs, mitkIpPicDescriptor *histBuffer ); - -/*! - Splits a contour in two parts. contour is the original contour, cutCoords a pointer to an x1-y1-x2-y2 array that - specifies the two points where the contour should be cut (these cutpoints must be points of the original contour!). - part1 and part2 have to be float arrays of a sufficient size to store the two parts. The sizes of the two parts - are returned in size1 and size2. - */ -extern void ipMITKSegmentationSplitContour( float *contour, int sizeContour, float *cutCoords, float *part1, int &size1, float *part2, int &size2 ); - -/*! - Returns true if the specified point lies insede the contour, else returns false. - */ -extern bool ipMITKSegmentationIsInsideContour( float *contour, int sizeContour, float x, float y ); - -#endif diff --git a/Utilities/IpSegmentation/ipSegmentationClear.c b/Utilities/IpSegmentation/ipSegmentationClear.c deleted file mode 100644 index 663164c73b..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationClear.c +++ /dev/null @@ -1,76 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include <assert.h> -#include "empty.xpm" -#include "ipSegmentationP.h" - -void -ipMITKSegmentationClear (mitkIpPicDescriptor* segmentation) -{ - ipMITKSegmentationTYPE *cur, *last; - mitkIpPicTSV_t* tag; - const char *src; - mitkIpUInt1_t *dst; - mitkIpUInt4_t i, j; - - assert (segmentation); - if (ipMITKSegmentationUndoIsEnabled (segmentation)) { - ipMITKSegmentationUndoSave (segmentation); - } - - /* clear the image data */ - - cur = (ipMITKSegmentationTYPE *) segmentation->data; - last = cur + _mitkIpPicElements (segmentation); - while (cur < last) { - *cur++ = 0; - } - - /* create an 'empty' tag */ - - tag = mitkIpPicQueryTag (segmentation, tagSEGMENTATION_EMPTY); - if (!tag) { - tag = (mitkIpPicTSV_t *) malloc (sizeof (mitkIpPicTSV_t)); - strcpy (tag->tag, tagSEGMENTATION_EMPTY); - tag->type = mitkIpPicBool; - tag->bpe = sizeof (mitkIpBool_t) / 8; - tag->dim = 1; - tag->n[0] = 1; - tag->value = malloc (sizeof (mitkIpBool_t)); - *((mitkIpBool_t *) tag->value) = mitkIpTrue; - mitkIpPicAddTag (segmentation, tag); - } - - /* create an `empty` icon */ - - tag = mitkIpPicQueryTag (segmentation, "ICON80x80"); - if (!tag) { - tag = (mitkIpPicTSV_t *) malloc (sizeof (mitkIpPicTSV_t)); - tag->type = mitkIpPicUInt; - tag->bpe = 8; - tag->dim = 2; - tag->n[0] = 80; - tag->n[1] = 80; - tag->value = malloc (tag->n[0] * tag->n[1] * sizeof (mitkIpUInt1_t)); - strcpy (tag->tag, "ICON80x80"); - mitkIpPicAddTag (segmentation, tag); - } - dst = (mitkIpUInt1_t *) tag->value; - for (i = 0; i < 80; i++) { - src = empty_xpm [3+i]; - for (j = 0; j < 80; j++) { - *dst = (*src == '.' ? 0 : 196); - src++; - dst++; - } - } -} diff --git a/Utilities/IpSegmentation/ipSegmentationCombineRegion.c b/Utilities/IpSegmentation/ipSegmentationCombineRegion.c deleted file mode 100644 index 439358f285..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationCombineRegion.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * This code is in part (the CONCAVE macro) a minimal variation - * of the code from the Graphics Gems book series. - * - * The method ipMITKSegmentationCombineRegion is by Tobias Kunert, DKFZ - * - * For information on the Graphics Gems books and more of - * the source code you can visit http://tog.acm.org/GraphicsGems/ - * - * The following note on license is taken from the mentions website: - * - * EULA: The Graphics Gems code is copyright-protected. - * In other words, you cannot claim the text of the code - * as your own and resell it. Using the code is permitted - * in any program, product, or library, non-commercial or - * commercial. Giving credit is not required, though is - * a nice gesture. The code comes as-is, and if there are - * any flaws or problems with any Gems code, nobody involved - * with Gems - authors, editors, publishers, or webmasters - * - are to be held responsible. Basically, don't be a jerk, - * and remember that anything free comes with no guarantee. - * -*/ - -#include <assert.h> -#include <math.h> -#include <mitkIpFunc.h> -#include "GraphicsGems.h" -#include "ipSegmentationP.h" - -// changed "for (x=XL; x < XR ; x++)" to "for (x=XL; x <= XR ; x++)" -> correct segmentation results -#define DRAWPROC(TYPE, PIC, MSK, XL, XR, Y, VALUE, CMD) \ -{ \ - int x; \ - for (x=XL; x <= XR ; x++) \ - MASK (TYPE, PIC, MSK, VALUE, x, Y, CMD) \ -} - -/* - * Concave Polygon Scan Conversion - * by Paul Heckbert - * from "Graphics Gems", Academic Press, 1990 - */ - -/* - * concave: scan convert nvert-sided concave non-simple polygon with vertices at - * (point[i].x, point[i].y) for i in [0..nvert-1] within the window win by - * calling spanproc for each visible span of pixels. - * Polygon can be clockwise or counterclockwise. - * Algorithm does uniform point sampling at pixel centers. - * Inside-outside test done by Jordan's rule: a point is considered inside if - * an emanating ray intersects the polygon an odd number of times. - * drawproc should fill in pixels from xl to xr inclusive on scanline y, - * e.g: - * drawproc(y, xl, xr) - * int y, xl, xr; - * { - * int x; - * for (x=xl; x<=xr; x++) - * pixel_write(x, y, pixelvalue); - * } - * - * Paul Heckbert 30 June 81, 18 Dec 89 - */ - - -#define ALLOC(ptr, type, n) ASSERT(ptr = (type *)malloc((n)*sizeof(type))) - -typedef struct { /* window: a discrete 2-D rectangle */ - int x0, y0; /* xmin and ymin */ - int x1, y1; /* xmax and ymax (inclusive) */ -} Window; - -typedef struct { /* a polygon edge */ - double x; /* x coordinate of edge's intersection with current scanline */ - double dx; /* change in x with respect to y */ - int i; /* edge number: edge i goes from pt[i] to pt[i+1] */ -} Edge; - -static int n; /* number of vertices */ -static Point2 *pt; /* vertices */ - -static int nact; /* number of active edges */ -static Edge *active; /* active edge list:edges crossing scanline y */ - -int compare_ind(const void* /*u*/, const void* /*v*/), \ - compare_active(const void* /*u*/, const void* /*v*/); - -#define CONCAVE(TYPE, PIC, MSK, POINT, NVERT, WINDOW, VALUE, CMD) \ -{ \ - \ - int k, y0, y1, y, i, j, xl, xr; \ - int *ind; /* list of vertex indices, sorted by pt[ind[j]].y */ \ - \ - n = (int)NVERT; \ - pt = POINT; \ - if (n<=0) return; \ - ALLOC(ind, int, n); \ - ALLOC(active, Edge, n); \ - \ - /* create y-sorted array of indices ind[k] into vertex list */ \ - for (k=0; k<n; k++) \ - ind[k] = k; \ - qsort(ind, n, sizeof ind[0], compare_ind); /* sort ind by pt[ind[k]].y */ \ - \ - nact = 0; /* start with empty active list */ \ - k = 0; /* ind[k] is next vertex to process */ \ - y0 = MAX(win->y0, ceil(pt[ind[0]].y-.5)); /* ymin of polygon */ \ - y1 = MIN(win->y1, floor(pt[ind[n-1]].y-.5)); /* ymax of polygon */ \ - \ - for (y=y0; y<=y1; y++) { /* step through scanlines */ \ - /* scanline y is at y+.5 in continuous coordinates */ \ - /* check vertices between previous scanline and current one, if any */ \ - for (; k<n && pt[ind[k]].y<=y+.5; k++) { \ - /* to simplify, if pt.y=y+.5, pretend it's above */ \ - /* invariant: y-.5 < pt[i].y <= y+.5 */ \ - i = ind[k]; \ - /* \ - * insert or delete edges before and after vertex i (i-1 to i, \ - * and i to i+1) from active list if they cross scanline y \ - */ \ - j = i>0 ? i-1 : n-1; /* vertex previous to i */ \ - if (pt[j].y <= y-.5) /* old edge, remove from active list */ \ - cdelete(j); \ - else if (pt[j].y > y+.5) /* new edge, add to active list */ \ - cinsert(j, y); \ - j = i<n-1 ? i+1 : 0; /* vertex next after i */ \ - if (pt[j].y <= y-.5) /* old edge, remove from active list */ \ - cdelete(i); \ - else if (pt[j].y > y+.5) /* new edge, add to active list */ \ - cinsert(i, y); \ - } \ - \ - /* sort active edge list by active[j].x */ \ - qsort(active, nact, sizeof active[0], compare_active); \ - \ - /* draw horizontal segments for scanline y */ \ - for (j=0; j<nact; j+=2) { /* draw horizontal segments */ \ - /* span 'tween j & j+1 is inside, span tween j+1 & j+2 is outside */ \ - xl = ceil(active[j].x-.5); /* left end of span */ \ - if (xl<win->x0) xl = win->x0; \ - xr = floor(active[j+1].x-.5); /* right end of span */ \ - if (xr>win->x1) xr = win->x1; \ - if (xl<=xr) \ - DRAWPROC(TYPE, PIC, MSK, xl, xr, y, VALUE, CMD);/* draw pixels in span */ \ - active[j].x += active[j].dx; /* increment edge coords */ \ - active[j+1].x += active[j+1].dx; \ - } \ - } \ -} \ - -static void cdelete(i) /* remove edge i from active list */ -int i; -{ - int j; - - for (j=0; j<nact && active[j].i!=i; j++); - if (j>=nact) return; /* edge not in active list; happens at win->y0*/ - nact--; - memmove( &active[j], &active[j+1], (nact-j)*sizeof active[0]); -} - -static void cinsert(i, y) /* append edge i to end of active list */ -int i, y; -{ - int j; - double dx; - Point2 *p, *q; - - j = i<n-1 ? i+1 : 0; - if (pt[i].y < pt[j].y) {p = &pt[i]; q = &pt[j];} - else {p = &pt[j]; q = &pt[i];} - /* initialize x position at intersection of edge with scanline y */ - active[nact].dx = dx = (q->x-p->x)/(q->y-p->y); - active[nact].x = dx*(y+.5-p->y)+p->x; - active[nact].i = i; - nact++; -} - -/* comparison routines for qsort */ -int compare_ind(arg1, arg2) const void *arg1, *arg2; -{ - int* u = (int*)arg1; - int* v = (int*)arg2; - return pt[*u].y <= pt[*v].y ? -1 : 1; -} - -int compare_active(arg1, arg2) const void *arg1, *arg2; -{ - Edge* u = (Edge*)arg1; - Edge* v = (Edge*)arg2; - return u->x <= v->x ? -1 : 1; -} - - -void ipMITKSegmentationCombineRegion (mitkIpPicDescriptor* segmentation, const mitkIpInt4_t* const points, const int num, mitkIpPicDescriptor* mask, const int operation, int value) -{ - int idx; - Point2* pl; - Window *win; - mitkIpPicTSV_t* tag; - - assert (segmentation); - if (ipMITKSegmentationUndoIsEnabled (segmentation)) { - ipMITKSegmentationUndoSave (segmentation); - } - tag = mitkIpPicQueryTag (segmentation, tagSEGMENTATION_EMPTY); - tag = mitkIpPicDelTag (segmentation, tagSEGMENTATION_EMPTY); - if (tag) { - mitkIpPicFreeTag (tag); - } - - win = (Window *) malloc (sizeof (Window)); - if (!win) { - ipMITKSegmentationError (ipMITKSegmentationOUT_OF_MEMORY); - } - win->x0 = 0; - win->y0 = 0; - win->x1 = (int) segmentation->n[0] - 1; - win->y1 = (int) segmentation->n[1] - 1; - - pl = (Point2 *) malloc (num * sizeof (Point2)); - if (!pl) { - ipMITKSegmentationError (ipMITKSegmentationOUT_OF_MEMORY); - } - - for (idx = 0; idx < num; idx++) - { - pl[idx].x = points[2*idx]; - pl[idx].y = points[2*idx+1]; - } - - switch (operation) { - - case IPSEGMENTATION_OP: - //mitkIpPicFORALL_6(CONCAVE, segmentation, mask, pl, num, win, value, OP ) ; - CONCAVE(ipMITKSegmentationTYPE, segmentation, mask, pl, num, win, value, OP); - break; - - case IPSEGMENTATION_AND: - //mitkIpPicFORALL_6(CONCAVE, segmentation, mask, pl, num, win, value, AND ) ; - CONCAVE(ipMITKSegmentationTYPE, segmentation, mask, pl, num, win, value, AND); - break; - - case IPSEGMENTATION_OR: - //mitkIpPicFORALL_6(CONCAVE, segmentation, mask, pl, num, win, value, OR ) ; - CONCAVE(ipMITKSegmentationTYPE, segmentation, mask, pl, num, win, value, OR); - break; - - case IPSEGMENTATION_XOR: - //mitkIpPicFORALL_6(CONCAVE, segmentation, mask, pl, num, win, value, XOR ) ; - CONCAVE(ipMITKSegmentationTYPE, segmentation, mask, pl, num, win, value, XOR); - break; - - default: - assert (0); // never get here! - } -} diff --git a/Utilities/IpSegmentation/ipSegmentationContourExtraction.cpp b/Utilities/IpSegmentation/ipSegmentationContourExtraction.cpp deleted file mode 100755 index c3442d29bd..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationContourExtraction.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <mitkIpPicTypeMultiplex.h> -#include "ipSegmentation.h" - - -// only make macros available in local scope: -namespace { - -// returns true if segmentation pixel at ofs is set, includes check for border pixels, i.e. border pixels do not result in returning true -#define SEGSET(ofs) ( \ -((ofs)>=0 && (ofs)<maxOfs) && \ -( *(((PicType*)seg->data) + (ofs)) != 0 ) && \ -( (ofs)%line != 0 || (pos+1)%line != 0 ) && \ -( (ofs+1)%line != 0 || (pos)%line != 0 ) \ -) - - -// appends a point to result, sets finished to true if this point is the same as the first one -// allocates new momory if necessary -#define ADD_CONTOUR_POINT \ -result[numPts*2] = xPos+xCorner[dir]; \ -result[numPts*2+1] = yPos+yCorner[dir]; \ -if (result[numPts*2]==result[0] && result[numPts*2+1]==result[1] && numPts>0) finished = true; \ -numPts++; \ -if (numPts==resSize) { \ - resSize+=16+resSize/2; \ - result = (float*)realloc( result, resSize*2*sizeof(float) ); \ - if (!result) finished = true; \ -} - -} - -template<typename PicType> -float* tmGetContour4N( const mitkIpPicDescriptor *seg, int startOfs, int &numPts, int &resSize, float *result ) -// returns the number of contour points (xy-pairs) in result -// optimized macros: DON'T TOUCH THE CODE (removed smiley, this is not funny but cruel for any maintainer!) -{ - numPts = 0; - int line = seg->n[0]; - int maxOfs = seg->n[0] * seg->n[1]; - - int straight[4] = { 1, -line, -1, line }; - int right[4] = { line, 1, -line, -1 }; - float xMod[4] = { 1.0, 0.0, -1.0, 0.0 }; - float yMod[4] = { 0.0, -1.0, 0.0, 1.0 }; - float xCorner[4] = { 1.0, 1.0, 0.0, 0.0 }; - float yCorner[4] = { 1.0, 0.0, 0.0, 1.0 }; - - int dir = 0; - int pos = startOfs; - float xPos = (float)(pos % line); - float yPos = (float)(pos / line); - - while ( dir<4 && SEGSET( pos+right[dir] ) ) dir++; - if (dir==4) return result; // no contour pixel - - bool finished = false; - if (result==nullptr) { - resSize = 2048; - result = (float*)malloc( resSize*2*sizeof(float) ); - } - - do { - if ( SEGSET( pos+right[dir] ) ) { - // modify direction (turn right): - dir = (dir-1) & 3; - // modify position: - pos += straight[dir]; - xPos += xMod[dir]; - yPos += yMod[dir]; - } - else if ( SEGSET( pos+straight[dir] ) ) { - ADD_CONTOUR_POINT - // modify position: - pos += straight[dir]; - xPos += xMod[dir]; - yPos += yMod[dir]; - } - else { - ADD_CONTOUR_POINT - // modify direction (turn left): - dir = (dir+1) & 3; - } - } while (!finished); - return result; -} - - -float* ipMITKSegmentationGetContour4N( const mitkIpPicDescriptor *seg, int startOfs, int &numPoints, int &sizeBuffer, float *pointBuffer ) -{ - float *newBuffer = nullptr; - mitkIpPicTypeMultiplexR4( tmGetContour4N, seg, newBuffer, startOfs, numPoints, sizeBuffer, pointBuffer ); - return newBuffer; -} - - -template<typename PicType> -float* tmGetContour8N( const mitkIpPicDescriptor *seg, int startOfs, int &numPts, int &resSize, float *result ) -// returns the number of contour points (xy-pairs) in result -// optimized macros: DON'T TOUCH THE CODE ;-) -{ - numPts = 0; - int line = seg->n[0]; // width of segmentation in pixels - int maxOfs = seg->n[0] * seg->n[1]; // memory offset of pixel just beyond bottom-right-most pixel of segmentation (not a valid offset) - - int straight[4] = { 1, -line, -1, line }; // right, top, left, down (memory offsets) - int right[4] = { line, 1, -line, -1 }; // down, right, top, left - float xMod[4] = { 1.0, 0.0, -1.0, 0.0 }; - float yMod[4] = { 0.0, -1.0, 0.0, 1.0 }; - float xCorner[4] = { 1.0, 1.0, 0.0, 0.0 }; - float yCorner[4] = { 1.0, 0.0, 0.0, 1.0 }; - - int dir = 0; - int pos = startOfs; // initial position, this is where the contour search starts - float xPos = (float)(pos % line); // calculate x and y from the memory offset - float yPos = (float)(pos / line); - - while ( dir<4 && SEGSET( pos+right[dir] ) ) dir++; - if (dir==4) { - // check diagonal pixels: - dir = 0; - while ( dir<4 && SEGSET( pos+right[dir]+straight[dir] ) ) dir++; - if (dir==4) return result; // no contour pixel - // chose next suitable neighbour: - pos += straight[dir]; - xPos += xMod[dir]; - yPos += yMod[dir]; - } - - bool finished = false; - if (result==nullptr) { - resSize = 2048; - result = (float*)malloc( resSize*2*sizeof(float) ); - } - - // here xPos,yPos are on some pixel next to a segmentation pixel. Where is "next to"? This is defined by the value of dir and the offsets in right[dir]. - - // tries to complete the contour until a point is added that is identical to the first point - do { - if ( SEGSET( pos+right[dir] ) ) { // valgrind complaint: jump dependent on uninitialized value (from my current understanding this could only be some pixel value outside the image - // modify direction (turn right): // this if will evaluate to true during the first iteration - dir = (dir-1) & 3; // ok, some weird logic selects a new direction - // modify position: - pos += straight[dir]; // definitions of right and straight (plus xMod and yMod) lead to a counter-clockwise movement around the contour - xPos += xMod[dir]; - yPos += yMod[dir]; - } - else if ( SEGSET( pos+straight[dir] ) ) { - ADD_CONTOUR_POINT - // modify position: - pos += straight[dir]; - xPos += xMod[dir]; - yPos += yMod[dir]; - } - else if ( SEGSET( pos+right[dir]+straight[dir] ) ) { // valgrind complaint: jump dependent on uninitialized value - ADD_CONTOUR_POINT - // modify position: - pos += straight[dir]; - xPos += xMod[dir]; - yPos += yMod[dir]; - // modify direction (turn right): - dir = (dir-1) & 3; - // modify position second time: - pos += straight[dir]; - xPos += xMod[dir]; - yPos += yMod[dir]; - } - else { - ADD_CONTOUR_POINT - // modify direction (turn left): - dir = (dir+1) & 3; - } - } while (!finished); - return result; -} - - -float* ipMITKSegmentationGetContour8N( const mitkIpPicDescriptor *seg, int startOfs, int &numPoints, int &sizeBuffer, float *pointBuffer ) -{ - float *newBuffer = nullptr; - mitkIpPicTypeMultiplexR4( tmGetContour8N, seg, newBuffer, startOfs, numPoints, sizeBuffer, pointBuffer ); - return newBuffer; -} diff --git a/Utilities/IpSegmentation/ipSegmentationContourUtils.cpp b/Utilities/IpSegmentation/ipSegmentationContourUtils.cpp deleted file mode 100755 index 22a5dc0563..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationContourUtils.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "ipSegmentation.h" - - -/** - * Input: one contour (start and end point identical). array of floats. [x1 y1 x2 y2 ...] - * Output: two contours (start and end point not neccessarily identical) - * cutCoords: two points that define the cut (must not [should not be] be identical) - * - * S.....O - * . . - * . . - * . . - * . ------C2 S: Start of contour (two times in the array) - * . ------- . C1: cut point 1 - * C1------ . C2: cut point 2 - * . O - * . .. - * . .. - * . .. - * . .. - * O - */ -void ipMITKSegmentationSplitContour( float *contour, int sizeContour, float *cutCoords, float *part1, int &size1, float *part2, int &size2 ) -{ - int cut1, cut2, i=0; - bool cutReached; - size1 = 0; - size2 = 0; - - do { - part1[2*size1] = contour[2*i]; - part1[2*size1+1] = contour[2*i+1]; - i++; - size1++; - cutReached = ( (cutCoords[0]==contour[2*i] && cutCoords[1]==contour[2*i+1]) || - (cutCoords[2]==contour[2*i] && cutCoords[3]==contour[2*i+1]) ); - } while (!cutReached); - cut1 = i; - part1[2*size1] = contour[2*i]; - part1[2*size1+1] = contour[2*i+1]; - size1++; - - do { - part2[2*size2] = contour[2*i]; - part2[2*size2+1] = contour[2*i+1]; - i++; - size2++; - cutReached = ( (cutCoords[0]==contour[2*i] && cutCoords[1]==contour[2*i+1]) || - (cutCoords[2]==contour[2*i] && cutCoords[3]==contour[2*i+1]) ); - } while (!cutReached); - cut2 = i; - part2[2*size2] = contour[2*i]; - part2[2*size2+1] = contour[2*i+1]; - size2++; - - do { - part1[2*size1] = contour[2*i]; - part1[2*size1+1] = contour[2*i+1]; - i++; - size1++; - } while (i<sizeContour); -} - - -/* - * This is taken from the FAQ of comp.graphics.algorithms - * - * http://www.exaflop.org/docs/cgafaq/cga2.html - * - * This FAQ references: - * - * Graphics Gems IV, Paul S. Heckbert (ed.), Academic Press 1994, ISBN 0-12-336155-9 - * Computational Geometry in C (2nd Ed.), Joseph O'Rourke, Cambridge University Press 1998, ISBN 0-521-64010-5 - * An Introduction to Ray Tracing, Andrew Glassner (ed.), Academic Press 1989, ISBN 0-12-286160-4 - * -*/ -bool ipMITKSegmentationIsInsideContour( float *contour, int sizeContour, float x, float y ) -{ - - int i, j; - bool res = false; - for ( i=0, j=sizeContour-1; - i<sizeContour; - j=i++) - { - if ( - ( ((contour[2*i+1]<=y) && (y<contour[2*j+1])) - || ((contour[2*j+1]<=y) && (y<contour[2*i+1])) ) - && - ( x < (contour[2*j] - contour[2*i]) * (y - contour[2*i+1]) / (contour[2*j+1] - contour[2*i+1]) + contour[2*i]) - ) - - res = !res; - } - return res; -} - diff --git a/Utilities/IpSegmentation/ipSegmentationError.c b/Utilities/IpSegmentation/ipSegmentationError.c deleted file mode 100644 index 759b0c10e1..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationError.c +++ /dev/null @@ -1,53 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <stdio.h> -#include "ipSegmentationP.h" - -static const char* messages [] = { - "ok.", - "sorry, out of memory.", - "sorry, wrong data type of segmentation image.", - "sorry, undo is disabled.", - "sorry, PIC descriptor is null.", - "sorry, unknown error occurred." -}; - -void -ipMITKSegmentationError (int error) -{ - switch (error) { - case ipMITKSegmentationOK: - case ipMITKSegmentationOUT_OF_MEMORY: - case ipMITKSegmentationWRONG_TYPE: - case ipMITKSegmentationUNDO_DISABLED: - printf ("ipMITKSegmentation: %s\n", messages [error]); - break; - default: - printf ("ipMITKSegmentation: %s\n", messages [ipMITKSegmentationUNKNOWN_ERROR]); - break; - } - if (error > 0) { - exit (-1); - } -} - -void -ipMITKSegmentationCheckImage (mitkIpPicDescriptor* segmentation) -{ - if ((segmentation->type != ipMITKSegmentationTYPE_ID) || (segmentation->bpe != ipMITKSegmentationBPE)) { - ipMITKSegmentationError (ipMITKSegmentationWRONG_TYPE); - } - if (!segmentation->data) { - ipMITKSegmentationError (ipMITKSegmentationUNKNOWN_ERROR); - } -} diff --git a/Utilities/IpSegmentation/ipSegmentationError.h b/Utilities/IpSegmentation/ipSegmentationError.h deleted file mode 100644 index 864218516f..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationError.h +++ /dev/null @@ -1,37 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#ifndef IPSEGMENTATION_ERROR_H -#define IPSEGMENTATION_ERROR_H - -enum { - ipMITKSegmentationOK = 0 /*! No errors at all. */, - ipMITKSegmentationOUT_OF_MEMORY /*! Not enough memory available. */, - ipMITKSegmentationWRONG_TYPE /*! Segmentation image has a wrong type. */, - ipMITKSegmentationUNDO_DISABLED /*! Undo cannot be performed. */, - ipMITKSegmentationPIC_NULL /*! PIC descriptor is null. */, - ipMITKSegmentationUNKNOWN_ERROR /*! Some unknown error occurred. */ -}; - -/*! -\brief Prints an error message and exits -if an error has occurred. -@param error error code -*/ -void ipMITKSegmentationError (int error); - -/*! -\brief Checks the segmentation image. -@param segmentation the segmentation image. -*/ -void ipMITKSegmentationCheck (mitkIpPicDescriptor* segmentation); - -#endif diff --git a/Utilities/IpSegmentation/ipSegmentationFree.c b/Utilities/IpSegmentation/ipSegmentationFree.c deleted file mode 100644 index 106d8562ff..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationFree.c +++ /dev/null @@ -1,22 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <mitkIpPic.h> - -void ipMITKSegmentationFree (mitkIpPicDescriptor* segmentation) -{ - if (!segmentation) return; - - mitkIpPicFree (segmentation); -} - - diff --git a/Utilities/IpSegmentation/ipSegmentationGrowerHistory.cpp b/Utilities/IpSegmentation/ipSegmentationGrowerHistory.cpp deleted file mode 100755 index 577441d829..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationGrowerHistory.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <queue> -#include "ipSegmentation.h" - - -mitkIpPicDescriptor* -ipMITKSegmentationCreateGrowerHistory( mitkIpPicDescriptor *seg, int startOfs, mitkIpPicDescriptor *histBuffer ) -{ - std::queue<int> ofsQueue; - - if (!seg) return nullptr; - if (!histBuffer) { - histBuffer = mitkIpPicCopyHeader( seg, histBuffer ); - histBuffer->type = mitkIpPicUInt; - histBuffer->bpe = 16; - mitkIpUInt4_t size = _mitkIpPicSize( histBuffer ); - histBuffer->data = malloc( size ); - memset( histBuffer->data, 0, size ); // clear buffer - } - else { - // check if dimension of histBuffer is valid, if not: change it! - if (histBuffer->n[0] != seg->n[0] || histBuffer->n[1] != seg->n[1]) { - histBuffer->n[0] = seg->n[0]; - histBuffer->n[1] = seg->n[1]; - mitkIpUInt4_t size = _mitkIpPicSize( histBuffer ); - histBuffer->data = realloc( histBuffer->data, size ); - if (histBuffer->data == nullptr) return nullptr; - memset( histBuffer->data, 0, size ); // clear buffer - } - } - - // create a clear buffer to check wether a point has already been visited - // (seg cannot be modifier and histBuffer can contain any value) - mitkIpPicDescriptor *flagBuffer = mitkIpPicCopyHeader( seg, nullptr ); - mitkIpUInt4_t size = _mitkIpPicSize( flagBuffer ); - flagBuffer->data = malloc( size ); - memset( flagBuffer->data, 0, size ); - *((mitkIpUInt1_t*)flagBuffer->data+startOfs) = 1; // flag pixel as visited - - int line = seg->n[0]; - int maxOfs = (int)(line * seg->n[1]); - int testOfs; - mitkIpUInt1_t segVal, flagVal; - int iteration = 0; - int currentWave = 1; - int nextWave = 0; - - ofsQueue.push( startOfs ); - - while (!ofsQueue.empty()) { - int nextOfs = ofsQueue.front(); - ofsQueue.pop(); - currentWave--; - *((mitkIpUInt2_t*)histBuffer->data+nextOfs) = (mitkIpUInt2_t)(iteration+1); // seed point should get history = 1 - - // check right: - testOfs = nextOfs+1; - if (testOfs%line!=0) { - segVal = *((mitkIpUInt1_t*)seg->data+testOfs); - flagVal = *((mitkIpUInt1_t*)flagBuffer->data+testOfs); - if ( segVal != 0 && flagVal == 0) { - ofsQueue.push( testOfs ); - *((mitkIpUInt1_t*)flagBuffer->data+testOfs) = 1; // flag pixel as visited - nextWave++; - } - } - // check top: - testOfs = nextOfs-line; - if (testOfs > 0) { - segVal = *((mitkIpUInt1_t*)seg->data+testOfs); - flagVal = *((mitkIpUInt1_t*)flagBuffer->data+testOfs); - if ( segVal != 0 && flagVal == 0) { - ofsQueue.push( testOfs ); - *((mitkIpUInt1_t*)flagBuffer->data+testOfs) = 1; // flag pixel as visited - nextWave++; - } - } - // check left: - testOfs = nextOfs-1; - if (nextOfs%line!=0) { - segVal = *((mitkIpUInt1_t*)seg->data+testOfs); - flagVal = *((mitkIpUInt1_t*)flagBuffer->data+testOfs); - if ( segVal != 0 && flagVal == 0) { - ofsQueue.push( testOfs ); - *((mitkIpUInt1_t*)flagBuffer->data+testOfs) = 1; // flag pixel as visited - nextWave++; - } - } - // check bottom: - testOfs = nextOfs+line; - if (testOfs < maxOfs) { - segVal = *((mitkIpUInt1_t*)seg->data+testOfs); - flagVal = *((mitkIpUInt1_t*)flagBuffer->data+testOfs); - if ( segVal != 0 && flagVal == 0) { - ofsQueue.push( testOfs ); - *((mitkIpUInt1_t*)flagBuffer->data+testOfs) = 1; // flag pixel as visited - nextWave++; - } - } - // check for number of iterations: - if (currentWave == 0) { - currentWave = nextWave; - nextWave = 0; - iteration++; - } - } - - mitkIpPicFree( flagBuffer ); - return histBuffer; -} diff --git a/Utilities/IpSegmentation/ipSegmentationInterpolate.c b/Utilities/IpSegmentation/ipSegmentationInterpolate.c deleted file mode 100644 index 8962636e76..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationInterpolate.c +++ /dev/null @@ -1,319 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <assert.h> -#include <math.h> -#include <mitkIpFunc.h> -#include "ipSegmentationP.h" - -/*! -The algorithm implements the shape-based interpolation technique. -Further detailed information can be found in: - -G.T. Herman, J. Zheng, C.A. Bucholtz: "Shape-based interpolation" -IEEE Computer Graphics & Applications, pp. 69-79,May 1992 -*/ - -#define MAX 2048 - -extern float truncf (float x); -static mitkIpPicDescriptor* setup (mitkIpPicDescriptor* pic_old); -static mitkIpInt2_t distance (const mitkIpInt2_t* const old_distance, const mitkIpInt2_t* mask_dist, const mitkIpInt2_t* mask_offset, const mitkIpUInt4_t mask_elements); - -// DON'T ever touch this code again - rather rewrite it! Then use ITK or some other library! - -// Works ONLY with 2D images. -mitkIpPicDescriptor* -ipMITKSegmentationPadBy1Pixel (mitkIpPicDescriptor* pic_in) -{ - //prepare the images - mitkIpPicDescriptor* pic_out; - ipMITKSegmentationTYPE* out_pixel_pointer; - ipMITKSegmentationTYPE* in_pixel_pointer; - unsigned int x, y; - - pic_out = mitkIpPicCopyHeader(pic_in, NULL); - if (pic_out == NULL) - { - ipMITKSegmentationError (ipMITKSegmentationPIC_NULL); - } - - if ((pic_out->type != ipMITKSegmentationTYPE_ID) || (pic_out->bpe != ipMITKSegmentationBPE)) - { - ipMITKSegmentationError (ipMITKSegmentationWRONG_TYPE); - } - - // pad by 1 pixel - pic_out->n[0] += 4; - pic_out->n[1] += 4; - - // allocate image data - pic_out->data = malloc ( pic_out->n[0] * pic_out->n[1] * ((pic_out->bpe)/8) ); - // copy pixel data - out_pixel_pointer = (ipMITKSegmentationTYPE*) (pic_out->data); - in_pixel_pointer = (ipMITKSegmentationTYPE*) (pic_in->data); - - for (y = 0; y < pic_out->n[1]; ++y) - for (x = 0; x < pic_out->n[0]; ++x) - { - if ( x < 2 || y < 2 || (x > pic_out->n[0]-3) || (y > pic_out->n[1]-3) ) // set border pixels to 0 - { - *out_pixel_pointer = 0; - } - else - { - *out_pixel_pointer = *in_pixel_pointer; - ++in_pixel_pointer; - } - ++out_pixel_pointer; - } - - return pic_out; -} - -// Works ONLY with 2D images. -mitkIpPicDescriptor* -ipMITKSegmentationShrinkBy1Pixel (mitkIpPicDescriptor* pic_in ) -{ - mitkIpPicDescriptor* pic_out; - ipMITKSegmentationTYPE* out_pixel_pointer; - ipMITKSegmentationTYPE* in_pixel_pointer; - unsigned int x, y; - - //prepare the images - pic_out = mitkIpPicCopyHeader(pic_in, NULL); - if (pic_out == NULL) { - ipMITKSegmentationError (ipMITKSegmentationPIC_NULL); - } - - if ((pic_out->type != ipMITKSegmentationTYPE_ID) || (pic_out->bpe != ipMITKSegmentationBPE)) - { - ipMITKSegmentationError (ipMITKSegmentationWRONG_TYPE); - } - - // pad by 1 pixel - pic_out->n[0] -= 4; - pic_out->n[1] -= 4; - - // allocate image data - pic_out->data = malloc ( pic_out->n[0] * pic_out->n[1] * (pic_out->bpe/8) ); - - // copy pixel data - out_pixel_pointer = pic_out->data; - in_pixel_pointer = pic_in->data; - - for (y = 0; y < pic_in->n[1]; ++y) - for (x = 0; x < pic_in->n[0]; ++x) - { - if ( x < 2 || y < 2 || (x > pic_in->n[0]-3) || (y > pic_in->n[1]-3) ) // ignore border pixels - { - } - else - { - *out_pixel_pointer = *in_pixel_pointer; - ++out_pixel_pointer; - } - ++in_pixel_pointer; - } - - return pic_out; -} - -mitkIpPicDescriptor* -ipMITKSegmentationInterpolate (mitkIpPicDescriptor* pPic1, mitkIpPicDescriptor* pPic2, const mitkIpFloat4_t ratio) -{ - mitkIpPicDescriptor *pic_out, *pic[2]; /* pointer to image data */ - mitkIpUInt4_t frame [_mitkIpPicNDIM]; /* pointer for definition of frame-size */ - mitkIpInt4_t x, y; - mitkIpUInt4_t i; /* loop counters */ - mitkIpFloat4_t weight[] = {1.0f-ratio, ratio}; /* weights of the interpolants */ - mitkIpInt2_t mask_width = 1; /* mask width from center to border */ - mitkIpInt2_t mask_x[] = {0, -1, +1, 0, -1}; /* relativ position in x-axis of mask */ - mitkIpInt2_t mask_y[] = {0, 0, -1, -1, -1}; /* relativ position in y-axis of mask */ - mitkIpInt2_t mask_dist[] = {0, 10, 14, 10, 14};/* distance to central element */ - mitkIpInt2_t mask_offset [5]; /* relative start position in given image */ - mitkIpUInt4_t mask_elements = 5; /* elements in distance mask */ - mitkIpInt2_t first_x, first_y; /* first pixel for distance calculation in enlarged image version */ - mitkIpInt2_t last_x, last_y; /* last pixel for distance calculation in enlarged image version */ - mitkIpInt2_t *pixel[2]; /* pointer to the current pixels */ - ipMITKSegmentationTYPE* pixel_out; - mitkIpPicDescriptor* returnImage; - - mitkIpPicDescriptor* pic1 = ipMITKSegmentationPadBy1Pixel( pPic1 ); - mitkIpPicDescriptor* pic2 = ipMITKSegmentationPadBy1Pixel( pPic2 ); - - /* prepare the images */ - pic_out = mitkIpPicCopyHeader(pic1, NULL); - if (pic_out == NULL) { - ipMITKSegmentationError (ipMITKSegmentationPIC_NULL); - } - if ((pic_out->type != ipMITKSegmentationTYPE_ID) || (pic_out->bpe != ipMITKSegmentationBPE)) { - ipMITKSegmentationError (ipMITKSegmentationWRONG_TYPE); - } - pic_out->data = malloc (_mitkIpPicSize (pic_out)); - for (i = 0; i < pic1->dim; i++) { - frame [i] = 1; - } - pic[0] = setup (pic1); - pic[1] = setup (pic2); - - /* apply the mask in both directions */ - for (i=0; i< mask_elements; i++) { - mask_offset [i] = mask_x[i] + mask_y[i]*pic[0]->n[0]; - } - first_x = mask_width; - first_y = mask_width; - last_x = pic[0]->n[0] - mask_width-1; - last_y = pic[0]->n[1] - mask_width-1; - /* top-left to bottom-right, borders are neglected */ - for (y = first_y; y <= last_y; y++) { - pixel [0] = (mitkIpInt2_t *) pic [0]->data + (first_x + y * pic [0]->n [0]); - pixel [1] = (mitkIpInt2_t *) pic [1]->data + (first_x + y * pic [1]->n [0]); - for (x = first_x; x <= last_x; x++) { - *(pixel [0])++ = distance (pixel [0], mask_dist, mask_offset, mask_elements); - *(pixel [1])++ = distance (pixel [1], mask_dist, mask_offset, mask_elements); - } - } - /* bottom-right to top-left, borders are neglected */ - for (i=0; i< mask_elements; i++) { - mask_offset [i] = -mask_offset [i]; - } - pixel_out = (ipMITKSegmentationTYPE *) pic_out->data + _mitkIpPicElements(pic_out) - 1; - for (y = last_y; y >= first_y; y--) { - pixel [0] = (mitkIpInt2_t *) pic [0]->data + (last_x + y * pic [0]->n [0]); - pixel [1] = (mitkIpInt2_t *) pic [1]->data + (last_x + y * pic [1]->n [0]); - for (x = last_x; x >= first_x; x--) { - *(pixel [0]) = distance (pixel [0], mask_dist, mask_offset, mask_elements); - *(pixel [1]) = distance (pixel [1], mask_dist, mask_offset, mask_elements); - *pixel_out-- = (weight [0] * *(pixel [0]) + weight [1] * *(pixel[1]) > 0 ? 1 : 0); - pixel[0]--; - pixel[1]--; - } - } - mitkIpPicFree(pic [0]); - mitkIpPicFree(pic [1]); - - mitkIpPicFree(pic1); - mitkIpPicFree(pic2); - - returnImage = ipMITKSegmentationShrinkBy1Pixel( pic_out ); - - mitkIpPicFree(pic_out); - - return returnImage; -} - -static mitkIpPicDescriptor* -setup (mitkIpPicDescriptor* pic_old) -{ - mitkIpPicDescriptor* pic; - ipMITKSegmentationTYPE* src; - mitkIpInt2_t* dst; - mitkIpUInt4_t x, y; - - /* Allocate new image for distance transform */ - - pic = mitkIpPicCopyHeader (pic_old, NULL); - pic->type = mitkIpPicInt; - pic->bpe = 16; - pic->n[0] += 2; - pic->n[1] += 2; - pic->data = malloc (_mitkIpPicSize (pic)); - - /* Set the frame to -1 */ - - dst = (mitkIpInt2_t *) pic->data; - for (x = 0; x < pic->n[0]; x++) { - *dst++ = -MAX; - } - dst = (mitkIpInt2_t *) pic->data + _mitkIpPicElements (pic) - pic->n[0]; - for (x = 0; x < pic->n[0]; x++) { - *dst++ = -MAX; - } - dst = (mitkIpInt2_t *) pic->data; - for (y = 0; y < pic->n[1]; y++) { - *dst = -MAX; - dst += pic->n[0]; - } - dst = (mitkIpInt2_t *) pic->data + (pic->n[0] - 1); - for (y = 0; y < pic->n[1]; y++) { - *dst = -MAX; - dst += pic->n[0]; - } - - /* Set the image data to initial values */ - - src = (ipMITKSegmentationTYPE *) pic_old->data; - dst = (mitkIpInt2_t *) pic->data + (1 + pic->n[0]); - for (y = 0; y < pic_old->n[1]; y++) { - for (x = 0; x < pic_old->n[0]; x++) { - *dst++ = (*src++ > 0 ? MAX : -MAX); - } - dst += 2; - } - dst = (mitkIpInt2_t *) pic->data + (1 + pic->n[0]); - for (y = 0; y < pic_old->n[1]; y++) { - for (x = 0; x < pic_old->n[0]; x++) { - if ((dst[0] < dst[1]) || (dst[0] < dst[pic->n[0]])) { - *dst = -5; - } else if ((dst[0] > dst[1]) || (dst[0] > dst[pic->n[0]])) { - *dst = 5; - } - dst++; - } - dst += 2; - } - dst -= 2; - for (y = 0; y < pic_old->n[1]; y++) { - for (x = 0; x < pic_old->n[0]; x++) { - dst--; - if (abs (dst[0]) > 5) { - if ((dst[0] < dst[-1]) || (dst[0] < dst[-(int)(pic->n[0])])) { - *dst = -5; - } else if ((dst[0] > dst[-1]) || (dst[0] > dst[-(int)(pic->n[0])])) { - *dst = 5; - } - } - } - } - return pic; -} - -static mitkIpInt2_t distance (const mitkIpInt2_t* const old_distance, const mitkIpInt2_t* mask_dist, const mitkIpInt2_t* mask_offset, const mitkIpUInt4_t mask_elements) -{ - mitkIpInt2_t cur_distance, new_distance; - mitkIpUInt4_t i; - - cur_distance = old_distance [0]; - if (abs (cur_distance) != 5) { - if (cur_distance > 0) { - for (i = 0; i < mask_elements; i++) { - new_distance = *mask_dist + old_distance [*mask_offset]; - if (new_distance < cur_distance) { - cur_distance = new_distance; - } - mask_dist++; - mask_offset++; - } - } else if (cur_distance < 0) { - for (i = 0; i < mask_elements; i++) { - new_distance = old_distance [*mask_offset] - *mask_dist; - if (new_distance > cur_distance) { - cur_distance = new_distance; - } - mask_dist++; - mask_offset++; - } - } - } - return cur_distance; -} diff --git a/Utilities/IpSegmentation/ipSegmentationNew.c b/Utilities/IpSegmentation/ipSegmentationNew.c deleted file mode 100644 index 58f543fcc0..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationNew.c +++ /dev/null @@ -1,30 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "ipSegmentationP.h" - -mitkIpPicDescriptor* -ipMITKSegmentationNew (mitkIpPicDescriptor* image) -{ - mitkIpPicDescriptor* s = NULL; - - if (image) { - s = mitkIpPicNew (); - s->type = ipMITKSegmentationTYPE_ID; - s->bpe = ipMITKSegmentationBPE; - s->dim = 2; - s->n[0] = image->n[0]; - s->n[1] = image->n[1]; - s->data = malloc (_mitkIpPicSize (s)); - } - return s; -} diff --git a/Utilities/IpSegmentation/ipSegmentationP.h b/Utilities/IpSegmentation/ipSegmentationP.h deleted file mode 100644 index fdfc7128d2..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationP.h +++ /dev/null @@ -1,86 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#ifndef IPSEGMENTATIONP_H -#define IPSEGMENTATIONP_H - -#include <mitkIpPic.h> -#include "ipSegmentationError.h" - -#ifndef IPSEGMENTATION_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" -{ -#endif - -#define ipMITKSegmentationTYPE mitkIpUInt1_t -#define ipMITKSegmentationTYPE_ID mitkIpPicUInt -#define ipMITKSegmentationBPE 8 -#define tagSEGMENTATION_EMPTY "SEGMENTATION_EMPTY" - -enum LogicalOp { - IPSEGMENTATION_OP /*! copy of input image */, - IPSEGMENTATION_AND /*! logical and operator */, - IPSEGMENTATION_OR /*! the or operator */, - IPSEGMENTATION_XOR /*! the exclusive-or operator */ -}; - -extern void ipMITKSegmentationUndoSave (mitkIpPicDescriptor* segmentation); -extern mitkIpBool_t ipMITKSegmentationUndoIsEnabled (mitkIpPicDescriptor* segmentation); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* IPSEGMTATION_H */ - -#define AND(TYPE, PIC, VALUE, X, Y) \ -{ \ - TYPE* data = (TYPE*) (PIC)->data; \ - mitkIpUInt4_t width = (PIC)->n[0]; \ - int temp = (int) data [width * (mitkIpUInt4_t) Y + (mitkIpUInt4_t) X]; \ - temp &= (int) VALUE; \ - data [width * (mitkIpUInt4_t) Y + (mitkIpUInt4_t) X] = temp; \ -} \ - -#define OR(TYPE, PIC, VALUE, X, Y) \ -{ \ - TYPE* data = (TYPE*) (PIC)->data; \ - mitkIpUInt4_t width = (PIC)->n[0]; \ - int temp = (int) data [width * (mitkIpUInt4_t) Y + (mitkIpUInt4_t) X]; \ - temp |= (int) VALUE; \ - data [width * (mitkIpUInt4_t) Y + (mitkIpUInt4_t) X] = temp; \ -} \ - -#define XOR(TYPE, PIC, VALUE, X, Y) \ -{ \ - TYPE* data = (TYPE*) (PIC)->data; \ - mitkIpUInt4_t width = (PIC)->n[0]; \ - int temp = (int) data [width * (mitkIpUInt4_t) Y + (mitkIpUInt4_t) X]; \ - temp ^= (int) VALUE; \ - data [width * (mitkIpUInt4_t) Y + (mitkIpUInt4_t) X] = temp; \ -} \ - -#define OP(TYPE, PIC, VALUE, X, Y) \ -{ \ - TYPE* data = (TYPE*) (PIC)->data; \ - mitkIpUInt4_t width = (PIC)->n[0]; \ - data [width * (mitkIpUInt4_t) Y + (mitkIpUInt4_t) X] = VALUE; \ -} \ - -#define MASK(TYPE, PIC, MSK, VALUE, X, Y, CMD) \ -{ \ -if (!(MSK) || (((ipMITKSegmentationTYPE *)(MSK)->data)[(PIC)->n[0] * (mitkIpUInt4_t) (Y) + (mitkIpUInt4_t) (X)] > 0.0)) \ -CMD(TYPE, PIC, VALUE, X, Y) \ -} - -#endif diff --git a/Utilities/IpSegmentation/ipSegmentationRegionCutter.cpp b/Utilities/IpSegmentation/ipSegmentationRegionCutter.cpp deleted file mode 100755 index b9518ac97f..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationRegionCutter.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <mitkIpPicTypeMultiplex.h> -#include <ANN/ANN.h> -#include "ipSegmentation.h" - - - -static ANNkd_tree *annTree; -static ANNpoint queryPt; -static ANNidxArray nnIdx; -static ANNdistArray dists; - - - -// find next pixel in ANN: -#define QUERY_DIST(qOfs) \ - queryPt[0] = (float)(qOfs % line) + 0.5; \ - queryPt[1] = (float)(qOfs / line) + 0.5; \ - annTree->annkSearch( queryPt, 1, nnIdx, dists ); - - -#define PROCESS_PIXEL \ - histVal = *((mitkIpUInt2_t*)history->data+testOfs); \ - segVal = *((mitkIpUInt1_t*)seg->data+testOfs); \ - if ( segVal > 0 && histVal <= maxHist && testOfs!=oldOfs ) { \ - grad = ipMITKSegmentationGetDistGradient( testOfs, seg ); \ - QUERY_DIST(testOfs) \ - if (grad<minGrad) { \ - minGrad = grad; \ - gradCand = testOfs; \ - } \ - if (dists[0] > maxDist) { \ - maxDist = dists[0]; \ - candOfs = testOfs; \ - } \ - } - - -float ipMITKSegmentationGetDistGradient( int ofs, mitkIpPicDescriptor *seg ) -{ - mitkIpUInt4_t unsignedOfs = ofs < 0 ? seg->n[0]*seg->n[1] - seg->n[0] : ofs; - if (unsignedOfs < seg->n[0] || unsignedOfs >= seg->n[0]*seg->n[1] - seg->n[0]) // exclude image borders - { - return 1.0; // initialization value of minGrad (high gradient) - } - float x = (float)(ofs % seg->n[0]) + 0.5; - float y = (float)(ofs / seg->n[0]) + 0.5; - mitkIpUInt1_t segVal = 0; // initialize to stop valgrind's warning about "Conditional jump or move depends on uninitialised value(s)" - - queryPt[0] = x+1; queryPt[1] = y; - annTree->annkSearch( queryPt, 1, nnIdx, dists ); - float d1 = sqrt( dists[0] ); // right dist - segVal = *((mitkIpUInt1_t*)seg->data+ofs+1); - if (!segVal) d1 = -10.0; - queryPt[0] = x-1; queryPt[1] = y; - annTree->annkSearch( queryPt, 1, nnIdx, dists ); - float d2 = sqrt( dists[0] ); // left dist - segVal = *((mitkIpUInt1_t*)seg->data+ofs-1); - if (!segVal) d2 = -10.0; - queryPt[0] = x; queryPt[1] = y+1; - annTree->annkSearch( queryPt, 1, nnIdx, dists ); - float d3 = sqrt( dists[0] ); // lower dist - segVal = *((mitkIpUInt1_t*)seg->data+ofs+seg->n[0]); - if (!segVal) d3 = -10.0; - queryPt[0] = x; queryPt[1] = y-1; - annTree->annkSearch( queryPt, 1, nnIdx, dists ); - float d4 = sqrt( dists[0] ); // upper dist - segVal = *((mitkIpUInt1_t*)seg->data+ofs-seg->n[0]); - if (!segVal) d4 = -10.0; - float res = 0.5*(float)sqrt( (d1-d2)*(d1-d2) + (d3-d4)*(d3-d4) ); - return res; -} - - - -tCutResult ipMITKSegmentationGetCutPoints( mitkIpPicDescriptor *seg, mitkIpPicDescriptor *history, int ofs ) -{ - bool debug(false); - tCutResult res; - int resContourSize = 5000; - res.traceline = (float*)malloc( resContourSize*sizeof(float)*2 ); - res.onGradient = (bool*)malloc( resContourSize*sizeof(bool) ); - res.numPoints = 0; - res.absMin = 0; - res.cutIt = false; - res.deleteCurve = nullptr; - - if (!history) return res; // no history! - if (*((mitkIpUInt2_t*)history->data + ofs) == 0) return res; // ofs not inside known history - - // get one point on the contour: - mitkIpUInt1_t *ptr = (mitkIpUInt1_t*)seg->data + ofs; - int endLine = ((ofs / seg->n[0]) + 1) * seg->n[0] -1; - int contourOfs = ofs; - while (contourOfs!=endLine && *ptr!=0) { - ptr++; - contourOfs++; - } - if (*ptr == 0) contourOfs--; // get back on the contour! - - // extract the contour: - int sizeContour, sizeBuffer; - float *contour = ipMITKSegmentationGetContour8N( seg, contourOfs, sizeContour, sizeBuffer ); - // init ANN tree with contour points: - queryPt = annAllocPt( 2 ); - ANNpointArray dataPts = annAllocPts( sizeContour, 2 ); - nnIdx = new ANNidx[10]; - dists = new ANNdist[10]; - for (int i=0; i<sizeContour; i++) { - (dataPts[i])[0] = contour[2*i]; - (dataPts[i])[1] = contour[2*i+1]; - } - annTree = new ANNkd_tree( dataPts, sizeContour, 2 ); - - // trace to center: - int line = history->n[0]; - - int maxOfs = line * history->n[1]; - QUERY_DIST(ofs) - float maxDist = dists[0]; - float minDist = 10000; // current minimum distance from border - float oldDist = 0; - int candOfs = ofs; - int nextOfs = -1; - int oldOfs, testOfs, gradCand=-1; - float grad, minGrad; - bool skelettonReached = false; - mitkIpUInt2_t histVal; - mitkIpUInt1_t segVal; - mitkIpUInt2_t maxHist = 10000; - if (maxHist==0 && debug) printf( "maxHist = 0!\n" ); - do { - oldOfs = nextOfs; - nextOfs = candOfs; - // store point info: - if (res.numPoints < resContourSize) { - res.traceline[2*res.numPoints] = (float)(nextOfs % line) + 0.5; - res.traceline[2*res.numPoints+1] = (float)(nextOfs / line) + 0.5; - if (nextOfs==gradCand) res.onGradient[res.numPoints] = true; - else res.onGradient[res.numPoints] = false; - - if (debug) - { - printf( "(%.f,%.f): H=%i, G=%i\n", res.traceline[2*res.numPoints], - res.traceline[2*res.numPoints+1], - *((mitkIpUInt2_t*)history->data+nextOfs), - res.onGradient[res.numPoints] ); - } - res.numPoints++; - - if (res.numPoints == resContourSize) - { - resContourSize *= 2; // explodes, but such contours must be very strange - res.traceline = (float*)realloc( res.traceline, resContourSize*sizeof(float)*2 ); - res.onGradient = (bool*)realloc( res.onGradient, resContourSize*sizeof(bool) ); - if ((res.traceline == nullptr) || (res.onGradient == nullptr)) - { - res.numPoints = 0; - res.cutIt = false; - return res; - } - } - } - - maxHist = *((mitkIpUInt2_t*)history->data + nextOfs); // don't exceed this history! - maxDist = 0; // clear maxDist - minGrad = 1.0; // clear minGrad - - int traceSinceMin = res.numPoints - 1 - res.absMin; - float weight = 20.0 / (20.0+traceSinceMin); - if (weight < 0.5) weight = 0.5; - QUERY_DIST(nextOfs) - if (!skelettonReached && dists[0] < oldDist) { - skelettonReached = true; - if (debug) printf( "skeletton reached at %i, oldDist=%.1f, currentDist=%.1f\n", - res.numPoints - 1, oldDist, dists[0] ); - } - oldDist = dists[0]; - if (skelettonReached && weight*dists[0] < minDist) { - minDist = dists[0]; - res.absMin = res.numPoints - 1; // has already been increased - } - - // check right: - testOfs = nextOfs+1; - if (testOfs%line!=0) { - // check top right: - PROCESS_PIXEL - testOfs = nextOfs-line; - if (testOfs > 0) { - testOfs++; - PROCESS_PIXEL - } - // check bottom right: - testOfs = nextOfs+line; - if (testOfs < maxOfs) { - testOfs++; - PROCESS_PIXEL - } - } - // check top: - testOfs = nextOfs-line; - if (testOfs > 0) { - PROCESS_PIXEL - } - // check left: - testOfs = nextOfs-1; - if (nextOfs%line!=0) { - PROCESS_PIXEL - // check top left: - testOfs = nextOfs-line; - if (testOfs > 0) { - testOfs--; - PROCESS_PIXEL - } - // check bottom left: - testOfs = nextOfs+line; - if (testOfs < maxOfs) { - testOfs--; - PROCESS_PIXEL - } - } - // check bottom: - testOfs = nextOfs+line; - if (testOfs < maxOfs) { - PROCESS_PIXEL - } - // check for run on gradient: - if (minGrad < 0.5) { - candOfs = gradCand; - if (debug) printf( "." ); - } - else if (debug) printf( "x" ); - } while (candOfs != nextOfs && maxHist > 0); - - if (res.absMin < (res.numPoints-10)) { - res.absMin += (int)(sqrt(minDist)/2.0); -// int cutX = (int)(res.traceline[2*res.absMin]-0.5); -// int cutY = (int)(res.traceline[2*res.absMin+1]-0.5); -// int cutOfs = cutX + line*cutY; -// histVal = *((mitkIpUInt2_t*)history->data+cutOfs); -// printf( "histVal at Cut=%i\n", histVal ); -// if (histVal > 1) { - res.cutIt = true; - float cutXf = (float)res.traceline[2*res.absMin]; - float cutYf = (float)res.traceline[2*res.absMin+1]; - queryPt[0] = cutXf; - queryPt[1] = cutYf; - annTree->annkSearch( queryPt, 1, nnIdx, dists ); - int cutIdx1 = nnIdx[0]; - res.cutCoords[0] = contour[2*cutIdx1]; - res.cutCoords[1] = contour[2*cutIdx1+1]; - int cutIdx2 = cutIdx1; - float minDist = 100000000; - int testCnt = 0; - for (int i=0; i<sizeContour; i++) { - int idxDif = abs(cutIdx1-i); - // take wraparound into account: - if (idxDif > (sizeContour/2)) idxDif = sizeContour - idxDif; - if ( idxDif > 50 ) { - float dist = (cutXf-contour[2*i])*(cutXf-contour[2*i]) + (cutYf-contour[2*i+1])*(cutYf-contour[2*i+1]); - if (dist < minDist) { - minDist = dist; - cutIdx2 = i; - } - } - else testCnt++; - } - res.cutCoords[2] = contour[2*cutIdx2]; - res.cutCoords[3] = contour[2*cutIdx2+1]; - if (debug) printf( "idx1=%i, idx2=%i, %i pts not evaluated.\n", cutIdx1, cutIdx2, testCnt ); - - if ((res.cutCoords[0] == res.cutCoords[2]) && - (res.cutCoords[1] == res.cutCoords[3])) - { - free( contour ); - // free ANN stuff: - annDeallocPt( queryPt ); - annDeallocPts( dataPts ); - delete[] nnIdx; - delete[] dists; - delete annTree; - - res.cutIt = false; - - return res; - } - float *curve1 = (float*)malloc( 2*sizeof(float)*sizeContour ); - float *curve2 = (float*)malloc( 2*sizeof(float)*sizeContour ); - int sizeCurve1, sizeCurve2; - ipMITKSegmentationSplitContour( contour, sizeContour, res.cutCoords, curve1, sizeCurve1, curve2, sizeCurve2 ); - float clickX = (float)(ofs % line) + 0.5; - float clickY = (float)(ofs / line) + 0.5; - if (ipMITKSegmentationIsInsideContour( curve1, sizeCurve1, clickX, clickY )) { - res.deleteCurve = curve1; - res.deleteSize = sizeCurve1; - free( curve2 ); - } - else { - res.deleteCurve = curve2; - res.deleteSize = sizeCurve2; - free( curve1 ); - } - } - - - free( contour ); - // free ANN stuff: - annDeallocPt( queryPt ); - annDeallocPts( dataPts ); - delete[] nnIdx; - delete[] dists; - delete annTree; - - return res; -} diff --git a/Utilities/IpSegmentation/ipSegmentationRegionGrower.cpp b/Utilities/IpSegmentation/ipSegmentationRegionGrower.cpp deleted file mode 100755 index f4779482f5..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationRegionGrower.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <assert.h> -#include <queue> -#include <mitkIpPicTypeMultiplex.h> -#include "ipSegmentation.h" - -/* -Starts a 4 neighbourhood region growing at startOfs (y*picWidth+x) of the 2D image src. -If relativeBounds is true, the region grows in [base-lowerBound, base+upperBound], in which base is the average -color of the 9 pixels around startOfs. If relativeBounds is false, the region grows in [lowerBound, upperBound]. -If maxIterations is > 0, the growing process is stopped after maxIterations. -If segBuffer is 0, new memory for the segmented image is allocated and returned, else the segBuffer is used -to store the result (has to be an 8-bit datatype, e.g. mitkIpUInt1_t). -histBuffer must be 0 or a pointer to a 16-bit mitkIpUInt1_t image of the same size as src. In case of the latter, -history data is written to that buffer: the seed pixel gets a 1, all direct neighbours 2 etc. The buffer is -not cleared in this function and can thus hold history data of several growing processes in different areas. -*/ -template<typename PicType> -mitkIpPicDescriptor* -tmGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBoundFlt, float upperBoundFlt, int maxIterations, mitkIpPicDescriptor *segBuffer, int &contourOfs, float &startCol, mitkIpPicDescriptor *histBuffer ) -{ - PicType lowerBound = static_cast<PicType>(lowerBoundFlt); - PicType upperBound = static_cast<PicType>(upperBoundFlt); - std::queue<int> ofsQueue; - - if (maxIterations <= 0) maxIterations = 32000; - if (!src) return nullptr; - if (!segBuffer) { - segBuffer = mitkIpPicCopyHeader( src, segBuffer ); - segBuffer->type = mitkIpPicUInt; - segBuffer->bpe = 8; - mitkIpUInt4_t size = _mitkIpPicSize( segBuffer ); - segBuffer->data = malloc( size ); - } - else { - // check if dimension of segBuffer is valid, if not: change it! - if (segBuffer->n[0] != src->n[0] || segBuffer->n[1] != src->n[1]) { - segBuffer->n[0] = src->n[0]; - segBuffer->n[1] = src->n[1]; - mitkIpUInt4_t size = _mitkIpPicSize( segBuffer ); - segBuffer->data = realloc( segBuffer->data, size ); - if (segBuffer->data == nullptr) return nullptr; - } - } - if (histBuffer) { - // check if dimension of histBuffer is valid, if not: change it! - if (histBuffer->n[0] != src->n[0] || histBuffer->n[1] != src->n[1]) { - histBuffer->n[0] = src->n[0]; - histBuffer->n[1] = src->n[1]; - mitkIpUInt4_t size = _mitkIpPicSize( histBuffer ); - histBuffer->data = realloc( histBuffer->data, size ); - if (histBuffer->data == nullptr) return nullptr; - memset( histBuffer->data, 0, size ); // clear buffer - } - } - - int line = segBuffer->n[0]; - int maxOfs = (int)(line * segBuffer->n[1]); - //PicType *start = ((PicType*)src->data) + startOfs; - // init borders: - PicType lowest, highest; - if (relativeBounds) { - - // average base color from 3x3 block: - // check for edges of image - int offset; - int numberOfValidOffsets = 0; - int baseCol = 0; - offset = startOfs; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - offset = startOfs+1; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - offset = startOfs+1-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - offset = startOfs-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - offset = startOfs-1-line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - offset = startOfs-1; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - offset = startOfs-1+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - offset = startOfs+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - offset = startOfs+1+line; if ( (offset >= 0) && (offset < (int)(src->n[0] * src->n[1])) ) { baseCol += *((PicType*)(src->data)+offset); ++numberOfValidOffsets; } - - if ( numberOfValidOffsets > 0 ) - baseCol = (PicType)( (float)baseCol / (float)numberOfValidOffsets ); - - lowest = baseCol - lowerBound; - highest = baseCol + upperBound; - startCol = (float)baseCol; - } - else { - lowest = lowerBound; - highest = upperBound; - startCol = 0.0f; - } - - memset( segBuffer->data, 0, _mitkIpPicSize(segBuffer) ); // clear buffer - - PicType value = *((PicType*)src->data+startOfs); - if ( value >=lowest && value <=highest ) { - ofsQueue.push( startOfs ); - } - - contourOfs = -1; - int testOfs; - mitkIpUInt1_t segVal; - int iteration = 0; - int currentWave = 1; - int nextWave = 0; - - while (!ofsQueue.empty() && iteration<=maxIterations) { - int nextOfs = ofsQueue.front(); - ofsQueue.pop(); - currentWave--; - *((mitkIpUInt1_t*)segBuffer->data+nextOfs) = 1; - if (histBuffer) { - *((mitkIpUInt2_t*)histBuffer->data+nextOfs) = (mitkIpUInt2_t)(iteration+1); // seed point should get history = 1 - } - if (nextOfs > contourOfs) contourOfs = nextOfs; - // check right: - testOfs = nextOfs+1; - if (testOfs%line!=0) { - segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs); - if ( segVal == 0 ) { - value = *((PicType*)src->data+testOfs); - if ( value >=lowest && value <=highest ) { - ofsQueue.push( testOfs ); - nextWave++; - *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2; - } - } - } - // check top: - testOfs = nextOfs-line; - if (testOfs > 0) { - segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs); - if ( segVal == 0 ) { - value = *((PicType*)src->data+testOfs); - if ( value >=lowest && value <=highest ) { - ofsQueue.push( testOfs ); - nextWave++; - *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2; - } - } - } - // check left: - testOfs = nextOfs-1; - if (nextOfs%line!=0) { - segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs); - if ( segVal == 0 ) { - value = *((PicType*)src->data+testOfs); - if ( value >=lowest && value <=highest ) { - ofsQueue.push( testOfs ); - nextWave++; - *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2; - } - } - } - // check bottom: - testOfs = nextOfs+line; - if (testOfs < maxOfs) { - segVal = *((mitkIpUInt1_t*)segBuffer->data+testOfs); - if ( segVal == 0 ) { - value = *((PicType*)src->data+testOfs); - if ( value >=lowest && value <=highest ) { - ofsQueue.push( testOfs ); - nextWave++; - *((mitkIpUInt1_t*)segBuffer->data+testOfs) = 2; - } - } - } - // check for number of iterations: - if (currentWave == 0) { - currentWave = nextWave; - nextWave = 0; - iteration++; - } - } - - return segBuffer; -} - - -mitkIpPicDescriptor* -ipMITKSegmentationGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBound, float upperBound, int maxIterations, mitkIpPicDescriptor *segBuffer, mitkIpPicDescriptor *histBuffer ) -{ - mitkIpPicDescriptor *result = nullptr; - int contourOfs; - float startCol; - - if (ipMITKSegmentationUndoIsEnabled (segBuffer)) { - ipMITKSegmentationUndoSave (segBuffer); - } - - mitkIpPicTypeMultiplexR9( tmGrowRegion4N, src, result, startOfs, relativeBounds, lowerBound, upperBound, maxIterations, segBuffer, contourOfs, startCol, histBuffer ); - return result; -} - - - -mitkIpPicDescriptor* -ipMITKSegmentationGrowRegion4N( mitkIpPicDescriptor *src, int startOfs, bool relativeBounds, float lowerBound, float upperBound, int maxIterations, mitkIpPicDescriptor *segBuffer, int &contourOfs, float &startCol, mitkIpPicDescriptor *histBuffer ) -{ - mitkIpPicDescriptor *result = nullptr; - - if (ipMITKSegmentationUndoIsEnabled (segBuffer)) { - ipMITKSegmentationUndoSave (segBuffer); - } - - mitkIpPicTypeMultiplexR9( tmGrowRegion4N, src, result, startOfs, relativeBounds, lowerBound, upperBound, maxIterations, segBuffer, contourOfs, startCol, histBuffer ); - return result; -} diff --git a/Utilities/IpSegmentation/ipSegmentationReplaceRegion.cpp b/Utilities/IpSegmentation/ipSegmentationReplaceRegion.cpp deleted file mode 100755 index e697b93e6d..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationReplaceRegion.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <queue> -#include "ipSegmentation.h" - -int -ipMITKSegmentationReplaceRegion4N( mitkIpPicDescriptor *seg, int startOfs, mitkIpInt1_t newValue ) -{ - mitkIpPicTSV_t* tag; - - std::queue<int> ofsQueue; - - if (ipMITKSegmentationUndoIsEnabled (seg)) { - ipMITKSegmentationUndoSave (seg); - } - tag = mitkIpPicDelTag (seg, tagSEGMENTATION_EMPTY); - if (tag) { - mitkIpPicFreeTag (tag); - } - - if (seg->bpe != 8) return 0; - - int line = seg->n[0]; - int maxOfs = (int)(line * seg->n[1]); - int testOfs; - mitkIpInt1_t replaceMe = *((mitkIpInt1_t*)seg->data + startOfs); - if (replaceMe == newValue) return 0; - - mitkIpInt1_t segVal; - ofsQueue.push( startOfs ); - *((mitkIpInt1_t*)seg->data+startOfs) = newValue; - int regionSize = 0; - - while (!ofsQueue.empty()) { - int nextOfs = ofsQueue.front(); - ofsQueue.pop(); - regionSize++; - // check right: - testOfs = nextOfs+1; - if (testOfs%line!=0) { - segVal = *((mitkIpInt1_t*)seg->data+testOfs); - if ( segVal == replaceMe ) { - ofsQueue.push( testOfs ); - *((mitkIpInt1_t*)seg->data+testOfs) = newValue; - } - } - // check top: - testOfs = nextOfs-line; - if (testOfs >= 0) { - segVal = *((mitkIpInt1_t*)seg->data+testOfs); - if ( segVal == replaceMe ) { - ofsQueue.push( testOfs ); - *((mitkIpInt1_t*)seg->data+testOfs) = newValue; - } - } - // check left: - testOfs = nextOfs-1; - if (nextOfs%line!=0) { - segVal = *((mitkIpInt1_t*)seg->data+testOfs); - if ( segVal == replaceMe ) { - ofsQueue.push( testOfs ); - *((mitkIpInt1_t*)seg->data+testOfs) = newValue; - } - } - // check bottom: - testOfs = nextOfs+line; - if (testOfs < maxOfs) { - segVal = *((mitkIpInt1_t*)seg->data+testOfs); - if ( segVal == replaceMe ) { - ofsQueue.push( testOfs ); - *((mitkIpInt1_t*)seg->data+testOfs) = newValue; - } - } - } - return regionSize; -} diff --git a/Utilities/IpSegmentation/ipSegmentationUndo.c b/Utilities/IpSegmentation/ipSegmentationUndo.c deleted file mode 100644 index 0f7e1a75ec..0000000000 --- a/Utilities/IpSegmentation/ipSegmentationUndo.c +++ /dev/null @@ -1,240 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include <string.h> -#include <assert.h> -#include "ipSegmentationP.h" - -static char* tagUNDO = "SEGMENTATION_UNDO"; -static char* tagUNDO_DATA = "DATA"; -static char* tagUNDO_LEVEL = "LEVEL"; - -// Implemented in mitkIpPicDelT.c -static mitkIpPicTSV_t *_mitkIpPicRemoveTag( _mitkIpPicTagsElement_t **head, - _mitkIpPicTagsElement_t *which, - char *tag ); - -void -ipMITKSegmentationUndoEnable (mitkIpPicDescriptor* segmentation, const mitkIpUInt1_t level) -{ - mitkIpPicTSV_t *undo, *data, *max; - - assert (segmentation); - undo = mitkIpPicQueryTag (segmentation, tagUNDO); - if (!undo) { - undo = (mitkIpPicTSV_t *) malloc (sizeof (mitkIpPicTSV_t)); - if (!undo) { - ipMITKSegmentationError (ipMITKSegmentationOUT_OF_MEMORY); - } - strcpy (undo->tag, tagUNDO); - undo->type = mitkIpPicTSV; - undo->bpe = 32; - undo->dim = 1; - undo->n[0] = 0; - undo->value = NULL; - mitkIpPicAddTag (segmentation, undo); - } - - data = mitkIpPicQuerySubTag (undo, tagUNDO_DATA); - if (!data) { - data = (mitkIpPicTSV_t *) malloc (sizeof (mitkIpPicTSV_t)); - if (!data) { - ipMITKSegmentationError (ipMITKSegmentationOUT_OF_MEMORY); - } - strcpy (data->tag, tagUNDO_DATA); - data->type = mitkIpPicTSV; - data->bpe = 32; - data->dim = 1; - data->n[0] = 0; - data->value = NULL; - mitkIpPicAddSubTag (undo, data); - } - if (data->n[0] > level) { - /* remove levels which exceed the maximum */ - mitkIpUInt1_t i; - - for (i = data->n[0] - level; i > 0; i--) { - _mitkIpPicTagsElement_t *head = (_mitkIpPicTagsElement_t *) data->value; - mitkIpPicTSV_t* tag = _mitkIpPicRemoveTag (&head, head, head->tsv->tag); - data->value = head; - data->n[0]--; - mitkIpPicFreeTag (tag); - } - } - - max = mitkIpPicQuerySubTag (undo, tagUNDO_LEVEL); - if (max) { - /* change the maximum of levels */ - mitkIpUInt1_t* value = (mitkIpUInt1_t *) max->value; - *value = level; - } else { - mitkIpUInt1_t* value = (mitkIpUInt1_t *) malloc (sizeof (mitkIpUInt1_t)); - if (!value) { - ipMITKSegmentationError (ipMITKSegmentationOUT_OF_MEMORY); - } - *value = level; - - max = (mitkIpPicTSV_t *) malloc (sizeof (mitkIpPicTSV_t)); - if (!max) { - ipMITKSegmentationError (ipMITKSegmentationOUT_OF_MEMORY); - } - strcpy (max->tag, tagUNDO_LEVEL); - max->type = mitkIpPicUInt; - max->bpe = 8; - max->dim = 1; - max->n[0] = 1; - max->value = value; - mitkIpPicAddSubTag (undo, max); - } -} - -void -ipMITKSegmentationUndoDisable (mitkIpPicDescriptor* segmentation) -{ - mitkIpPicTSV_t *undo; - - assert (segmentation); - undo = mitkIpPicDelTag (segmentation, tagUNDO); - mitkIpPicFreeTag (undo); -} - -mitkIpBool_t -ipMITKSegmentationUndoIsEnabled (mitkIpPicDescriptor* segmentation) -{ - mitkIpPicTSV_t *undo = NULL; - - if (segmentation) { - undo = mitkIpPicQueryTag (segmentation, tagUNDO); - } - return (undo ? mitkIpTrue : mitkIpFalse); -} - -void -ipMITKSegmentationUndoSave (mitkIpPicDescriptor* segmentation) -{ - mitkIpPicTSV_t *undo, *data, *level, *tag; - - assert (segmentation); - undo = mitkIpPicQueryTag (segmentation, tagUNDO); - if (!undo) { - ipMITKSegmentationError (ipMITKSegmentationUNDO_DISABLED); - } - - /* if no level is available ... */ - data = mitkIpPicQuerySubTag (undo, tagUNDO_DATA); - level = mitkIpPicQuerySubTag (undo, tagUNDO_LEVEL); - if (*((mitkIpUInt1_t *) level->value) > 0) { - if (data->n[0] == *((mitkIpUInt1_t *) level->value)) { - /* ... remove the first one. */ - _mitkIpPicTagsElement_t* head = (_mitkIpPicTagsElement_t *) data->value; - mitkIpPicTSV_t* tag = _mitkIpPicRemoveTag (&head, head, head->tsv->tag); - data->value = head; - data->n[0]--; - mitkIpPicFreeTag (tag); - } - /* build and store the level */ - tag = (mitkIpPicTSV_t *) malloc (sizeof (mitkIpPicTSV_t)); - if (!tag) { - ipMITKSegmentationError (ipMITKSegmentationOUT_OF_MEMORY); - } - strcpy (tag->tag, "IMAGE"); - tag->type = segmentation->type; - tag->bpe = segmentation->bpe; - tag->dim = segmentation->dim; - tag->n[0] = segmentation->n[0]; - tag->n[1] = segmentation->n[1]; - tag->value = malloc (_mitkIpPicSize (segmentation)); - memmove (tag->value, segmentation->data, _mitkIpPicSize (segmentation)); - mitkIpPicAddSubTag (data, tag); - } -} - -void -ipMITKSegmentationUndo (mitkIpPicDescriptor* segmentation) -{ - mitkIpPicTSV_t *undo, *data; - - assert (segmentation); - undo = mitkIpPicQueryTag (segmentation, tagUNDO); - if (!undo) { - ipMITKSegmentationError (ipMITKSegmentationUNDO_DISABLED); - } - - /* if any level is stored ... */ - data = mitkIpPicQuerySubTag (undo, tagUNDO_DATA); - if (data->n[0]) { - /* ... replace the image data and remove this level */ - _mitkIpPicTagsElement_t* head = (_mitkIpPicTagsElement_t *) data->value; - _mitkIpPicTagsElement_t* current = head; - mitkIpPicTSV_t* tag; - - while( current->next != NULL ) { - current = current->next; - } - tag = _mitkIpPicRemoveTag (&head, current, current->tsv->tag); - data->value = head; - data->n[0]--; - memmove (segmentation->data, tag->value, _mitkIpPicSize (segmentation)); - mitkIpPicFreeTag (tag); - - tag = mitkIpPicDelTag (segmentation, tagSEGMENTATION_EMPTY); - if (tag) { - mitkIpPicFreeTag (tag); - } - } -} - -mitkIpBool_t -ipMITKSegmentationUndoAvailable (mitkIpPicDescriptor* segmentation) -{ - mitkIpPicTSV_t *undo, *data; - - assert (segmentation); - undo = mitkIpPicQueryTag (segmentation, tagUNDO); - if (!undo) { - ipMITKSegmentationError (ipMITKSegmentationUNDO_DISABLED); - } - data = mitkIpPicQuerySubTag (undo, tagUNDO_DATA); - return (data->n[0] ? mitkIpTrue : mitkIpFalse); -} - -mitkIpPicTSV_t * -_mitkIpPicRemoveTag( _mitkIpPicTagsElement_t **head, _mitkIpPicTagsElement_t *which, char *tag) -{ - mitkIpPicTSV_t *tsv = NULL; - - if( which != NULL ) - { - tsv = which->tsv; - - if( which->prev == NULL ) /* which is the current head */ - { - *head = which->next; - - if( *head ) - (*head)->prev = NULL; - } - else if( which->next == NULL ) /* which is the current tail */ - { - which->prev->next = NULL; - } - else /* which is somewhere if the list */ - { - which->prev->next = which->next; - which->next->prev = which->prev; - } - - free( which ); - } - - return( tsv ); -}