pax_global_header00006660000000000000000000000064150102424570014512gustar00rootroot0000000000000052 comment=1d0f4a90a511c9ba07989e2a67cf3a01d791b2c5 openigtlink-3.0.0/000077500000000000000000000000001501024245700140355ustar00rootroot00000000000000openigtlink-3.0.0/.travis.yml000066400000000000000000000023741501024245700161540ustar00rootroot00000000000000os: - linux - osx language: cpp compiler: - gcc - clang install: ############################################################################ # Install a recent CMake (unless already installed on OS X) ############################################################################ - | if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR} CMAKE_URL="http://www.cmake.org/files/v3.5/cmake-3.5.2-Linux-x86_64.tar.gz" mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake export PATH=${DEPS_DIR}/cmake/bin:${PATH} cd .. else if ! brew ls --version cmake &>/dev/null; then brew install cmake; fi fi before_script: - mkdir build - cd build script: - cmake -DOpenIGTLink_PROTOCOL_VERSION_3=ON .. - make - cd .. - mkdir TestBuild - cd TestBuild - cmake -DCMAKE_PREFIX_PATH:PATH=../build ../Testing - make - make test ######################### # Test for version2 build - cd ../build - cmake -DOpenIGTLink_PROTOCOL_VERSION_3=OFF .. - make - cd ../TestBuild - cmake -DCMAKE_PREFIX_PATH:PATH=../build ../Testing - make - make test openigtlink-3.0.0/BUILD.md000066400000000000000000000031271501024245700152210ustar00rootroot00000000000000The OpenIGTLink Library Build Instruction ========================================= Linux / Mac OS X ---------------- First, obtain the source code from the repository using Git. To simply download the code, run the following command from a terminal: ~~~~ $ git clone https://github.com/openigtlink/OpenIGTLink.git ~~~~ Then configure using CMake. The library requires CMake version higher than 2.4. ~~~~ $ mkdir OpenIGTLink-build $ cd OpenIGTLink-build $ cmake -DBUILD_EXAMPLES:BOOL=ON ../OpenIGTLink $ make ~~~~ You may install the library into your disk (optional). The default target directory is /usr/local, but you can configure it from the CMake configuration screen. To install the files, run ~~~~ $ make install ~~~~ You might need super user access. Windows ------- * Download the source code from Git repository. * URL of repository: git://github.com/openigtlink/OpenIGTLink.git * Run CMake * Where is the source code: C:\Devel\OpenIGT\OpenIGTLink * Where to build the binaries: C:\Devel\OpenIGT\OpenIGTLink-build * Click "Configure" and select your compiler (usually just click "OK") * Message: "Build directory does not exit, should I create it?" - click "OK" * Click "Configure" * Click "OK" to close CMake * Start Visual C and compile the project (C:\Devel\OpenIGT\OpenIGTLink-build\OpenIGTLink.sln) If all went OK you will have the executable and the library: * C:\Devel\OpenIGT\OpenIGTLink-build\bin\debug\igtlSocketTest.exe * C:\Devel\OpenIGT\OpenIGTLink-build\bin\debug\OpenIGTLink.lib Other Platforms --------------- Please see [Build Instruction](http://openigtlink.org/library/build.html). openigtlink-3.0.0/CMake/000077500000000000000000000000001501024245700150155ustar00rootroot00000000000000openigtlink-3.0.0/CMake/OpenIGTLinkCMakeTests.cmake000066400000000000000000000042511501024245700220300ustar00rootroot00000000000000# See if we need to link the socket library INCLUDE(CheckLibraryExists) INCLUDE(CheckSymbolExists) INCLUDE(CheckFunctionExists) CHECK_LIBRARY_EXISTS("socket" getsockname "" OpenIGTLink_HAVE_LIBSOCKET) IF( NOT OpenIGTLink_HAVE_GETSOCKNAME_WITH_SOCKLEN_T ) IF(OpenIGTLink_HAVE_LIBSOCKET) SET(OpenIGTLink_GETSOCKNAME_LIBS "socket") ELSE() SET(OpenIGTLink_GETSOCKNAME_LIBS) ENDIF() MESSAGE(STATUS "Checking for getsockname with socklen_t") TRY_COMPILE(OpenIGTLink_HAVE_GETSOCKNAME_WITH_SOCKLEN_T ${OpenIGTLink_BINARY_DIR}/CMakeTmp/SocklenT ${OpenIGTLink_CMAKE_DIR}/igtlTestSocklenT.cxx CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${OpenIGTLink_GETSOCKNAME_LIBS}" OUTPUT_VARIABLE OUTPUT) IF(OpenIGTLink_HAVE_GETSOCKNAME_WITH_SOCKLEN_T) MESSAGE(STATUS "Checking for getsockname with socklen_t -- yes") SET(OpenIGTLink_HAVE_GETSOCKNAME_WITH_SOCKLEN_T 1 CACHE INTERNAL "Support for getsockname with socklen_t") WRITE_FILE(${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log "Determining if getsockname accepts socklen_t type " "passed with the following output:\n" "${OUTPUT}\n" APPEND) ELSE() MESSAGE(STATUS "Checking for getsockname with socklen_t -- no") SET(OpenIGTLink_HAVE_GETSOCKNAME_WITH_SOCKLEN_T 0 CACHE INTERNAL "Support for getsockname with socklen_t") WRITE_FILE(${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log "Determining if getsockname accepts socklen_t type " "failed with the following output:\n" "${OUTPUT}\n" APPEND) ENDIF() ENDIF() # e.g. Mac OS X Snow Leopard does not have strnlen(). CHECK_FUNCTION_EXISTS(strnlen OpenIGTLink_HAVE_STRNLEN) # e.g. IBM BlueGene/L doesn't have SO_REUSEADDR, because "setsockopt is not needed for # BlueGene/L applications" according to the BlueGene/L Application Development handbook CHECK_SYMBOL_EXISTS(SO_REUSEADDR "sys/types.h;sys/socket.h" OpenIGTLink_HAVE_SO_REUSEADDR) SET(HAVE_SOCKETS TRUE) # Cray Xt3/ Catamount doesn't have any socket support # this could also be determined by doing something like # check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKETS) IF(CMAKE_SYSTEM MATCHES Catamount) SET(HAVE_SOCKETS FALSE) ENDIF(CMAKE_SYSTEM MATCHES Catamount)openigtlink-3.0.0/CMake/igtlTestSocklenT.cxx000077500000000000000000000004561501024245700210130ustar00rootroot00000000000000#include #include #if !defined(_WIN32) || defined(__CYGWIN__) # include # include #endif int main() { /* Test whether getsockname takes socklen_t. */ if(getsockname(0, 0, (socklen_t*)0)) return 0; if(sizeof (socklen_t)) return 0; return 0; } openigtlink-3.0.0/CMakeLists.txt000066400000000000000000000240331501024245700165770ustar00rootroot00000000000000PROJECT( OpenIGTLink ) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) #----------------------------------------------------------------------------- # OpenIGTlink version number. SET(OpenIGTLink_VERSION_MAJOR "3") SET(OpenIGTLink_VERSION_MINOR "0") SET(OpenIGTLink_VERSION_PATCH "0") option(OpenIGTLink_PROTOCOL_VERSION_2 "Build Library for Protocol Version 2" ON) option(OpenIGTLink_PROTOCOL_VERSION_3 "Build Library for Protocol Version 3" ON) SET(OpenIGTLink_HEADER_VERSION "1") IF(OpenIGTLink_PROTOCOL_VERSION_3) SET(OpenIGTLink_PROTOCOL_VERSION "3") SET(OpenIGTLink_HEADER_VERSION "2") ELSEIF(OpenIGTLink_PROTOCOL_VERSION_2) SET(OpenIGTLink_PROTOCOL_VERSION "2") ELSE() SET(OpenIGTLink_PROTOCOL_VERSION "1") ENDIF() #----------------------------------------------------------------------------- # OpenIGTLink build configuration options. OPTION(BUILD_SHARED_LIBS "Build OpenIGTLink with shared libraries." OFF) SET(OpenIGTLink_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) if(NOT OpenIGTLink_BUILD_SHARED_LIBS) OPTION(BUILD_GENERATE_PIC "Generate position independent code (for static)." ON) SET(OpenIGTLink_BUILD_GENERATE_PIC ${BUILD_GENERATE_PIC}) endif(NOT OpenIGTLink_BUILD_SHARED_LIBS) OPTION(BUILD_EXAMPLES "Build OpenIGTLink example programs." OFF) SET(OpenIGTLink_BUILD_EXAMPLES ${BUILD_EXAMPLES}) #----------------------------------------------------------------------------- # Output directories. IF(NOT LIBRARY_OUTPUT_PATH) SET (LIBRARY_OUTPUT_PATH ${OpenIGTLink_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all libraries.") ENDIF(NOT LIBRARY_OUTPUT_PATH) IF(NOT EXECUTABLE_OUTPUT_PATH) SET (EXECUTABLE_OUTPUT_PATH ${OpenIGTLink_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.") ENDIF(NOT EXECUTABLE_OUTPUT_PATH) MARK_AS_ADVANCED(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH) SET(OpenIGTLink_LIBRARY_PATH "${LIBRARY_OUTPUT_PATH}") SET(OpenIGTLink_EXECUTABLE_PATH "${EXECUTABLE_OUTPUT_PATH}") SET(OpenIGTLink_CMAKE_DIR "${OpenIGTLink_SOURCE_DIR}/CMake") SET(CMAKE_MODULE_PATH "${OpenIGTLink_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) #----------------------------------------------------------------------------- # Installation vars. # OpenIGTLink_INSTALL_BIN_DIR - binary dir (executables) # OpenIGTLink_INSTALL_LIB_DIR - library dir (libs) # OpenIGTLink_INSTALL_DATA_DIR - share dir (say, examples, data, etc) # OpenIGTLink_INSTALL_INCLUDE_DIR - include dir (headers) # OpenIGTLink_INSTALL_PACKAGE_DIR - package/export configuration files # OpenIGTLink_INSTALL_NO_DEVELOPMENT - do not install development files # OpenIGTLink_INSTALL_NO_RUNTIME - do not install runtime files # OpenIGTLink_INSTALL_NO_DOCUMENTATION - do not install documentation files IF(NOT OpenIGTLink_INSTALL_BIN_DIR) SET(OpenIGTLink_INSTALL_BIN_DIR "bin") ENDIF(NOT OpenIGTLink_INSTALL_BIN_DIR) IF(NOT OpenIGTLink_INSTALL_LIB_DIR) SET(OpenIGTLink_INSTALL_LIB_DIR "lib/igtl") ENDIF(NOT OpenIGTLink_INSTALL_LIB_DIR) IF(NOT OpenIGTLink_INSTALL_DATA_DIR) SET(OpenIGTLink_INSTALL_DATA_DIR "share/igtl") ENDIF(NOT OpenIGTLink_INSTALL_DATA_DIR) IF(NOT OpenIGTLink_INSTALL_INCLUDE_DIR) SET(OpenIGTLink_INSTALL_INCLUDE_DIR "include/igtl") ENDIF(NOT OpenIGTLink_INSTALL_INCLUDE_DIR) IF(NOT OpenIGTLink_INSTALL_PACKAGE_DIR) SET(OpenIGTLink_INSTALL_PACKAGE_DIR "${OpenIGTLink_INSTALL_LIB_DIR}/cmake/igtl-${OpenIGTLink_VERSION_MAJOR}.${OpenIGTLink_VERSION_MINOR}" CACHE INTERNAL "") ENDIF(NOT OpenIGTLink_INSTALL_PACKAGE_DIR) IF(NOT OpenIGTLink_INSTALL_NO_DOCUMENTATION) SET(OpenIGTLink_INSTALL_NO_DOCUMENTATION 0) ENDIF(NOT OpenIGTLink_INSTALL_NO_DOCUMENTATION) SET(OpenIGTLink_DIR "${CMAKE_BINARY_DIR}" CACHE INTERNAL "OpenIGTLink dir to be used by subprojects") #----------------------------------------------------------------------------- # Include directories SET(OpenIGTLink_INCLUDE_DIRS_BUILD_TREE ${OpenIGTLink_INCLUDE_DIRS_BUILD_TREE} ${OpenIGTLink_BINARY_DIR} ${OpenIGTLink_SOURCE_DIR}/Source ${OpenIGTLink_SOURCE_DIR}/Source/igtlutil ) INCLUDE_DIRECTORIES( ${OpenIGTLink_INCLUDE_DIRS_BUILD_TREE} ) #----------------------------------------------------------------------------- # OpenIGTLink requires special compiler flags on some platforms. INCLUDE (FindThreads) IF(CMAKE_COMPILER_IS_GNUCXX) # '-fno-tree-vectorize' option is added to avoid segmentation fault that occurs in # igtl_image_convert_byte_order() (Source/igtlutil/igtl_image.c) built with 'Release' # option on 64-bit Linux. INCLUDE (CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-fno-tree-vectorize" OpenIGTLink_GNUCXX_TREE_VECTORIZE_SUPPORT) IF (OpenIGTLink_GNUCXX_TREE_VECTORIZE_SUPPORT) SET(OpenIGTLink_REQUIRED_C_FLAGS "${OpenIGTLink_REQUIRED_C_FLAGS} -w -fno-tree-vectorize") SET(OpenIGTLink_REQUIRED_CXX_FLAGS "${OpenIGTLink_REQUIRED_CXX_FLAGS} -ftemplate-depth-50 -fno-tree-vectorize") ENDIF (OpenIGTLink_GNUCXX_TREE_VECTORIZE_SUPPORT) # If the library is built as a static library, pass -fPIC option to the compiler IF(OpenIGTLink_BUILD_GENERATE_PIC) SET(OpenIGTLink_REQUIRED_C_FLAGS "${OpenIGTLink_REQUIRED_C_FLAGS} -fPIC") SET(OpenIGTLink_REQUIRED_CXX_FLAGS "${OpenIGTLink_REQUIRED_CXX_FLAGS} -fPIC") ENDIF(OpenIGTLink_BUILD_GENERATE_PIC) # pthread IF(CMAKE_HAVE_THREADS_LIBRARY) SET(OpenIGTLink_REQUIRED_LINK_FLAGS "${OpenIGTLink_REQUIRED_LINK_FLAGS} ${CMAKE_THREAD_LIBS_INIT}") ENDIF(CMAKE_HAVE_THREADS_LIBRARY) ENDIF(CMAKE_COMPILER_IS_GNUCXX) # for the gnu compiler a -D_PTHREADS is needed on sun # for the native compiler a -mt flag is needed on the sun IF(CMAKE_USE_PTHREADS) IF(CMAKE_SYSTEM MATCHES "SunOS.*") IF(CMAKE_COMPILER_IS_GNUCXX) SET(OpenIGTLink_REQUIRED_CXX_FLAGS "${OpenIGTLink_REQUIRED_CXX_FLAGS} -D_PTHREADS") ELSE(CMAKE_COMPILER_IS_GNUCXX) SET(OpenIGTLink_REQUIRED_CXX_FLAGS "${OpenIGTLink_REQUIRED_CXX_FLAGS} -mt") SET(OpenIGTLink_REQUIRED_C_FLAGS "${OpenIGTLink_REQUIRED_C_FLAGS} -mt") ENDIF(CMAKE_COMPILER_IS_GNUCXX) ENDIF(CMAKE_SYSTEM MATCHES "SunOS.*") ENDIF(CMAKE_USE_PTHREADS) #----------------------------------------------------------------------------- # Platform configuration tests. # Socket tests etc. INCLUDE(${OpenIGTLink_CMAKE_DIR}/OpenIGTLinkCMakeTests.cmake) SET(OpenIGTLink_LIBRARY_TARGETS_FILE "${CMAKE_BINARY_DIR}/OpenIGTLinkTargets.cmake") #----------------------------------------------------------------------------- # Generate Configuration Header files. include (${OpenIGTLink_SOURCE_DIR}/OpenIGTLinkConfigPlatform.cmake) CONFIGURE_FILE(${OpenIGTLink_SOURCE_DIR}/igtlConfigure.h.in ${OpenIGTLink_BINARY_DIR}/igtlConfigure.h) CONFIGURE_FILE(${OpenIGTLink_SOURCE_DIR}/igtl_typeconfig.h.in ${OpenIGTLink_BINARY_DIR}/igtl_typeconfig.h) CONFIGURE_FILE(${OpenIGTLink_SOURCE_DIR}/igtlTypeConfig.h.in ${OpenIGTLink_BINARY_DIR}/igtlTypeConfig.h) #----------------------------------------------------------------------------- # Help other projects use OpenIGTLink. # Copy the UseOpenIGTLink.cmake file to the binary tree for backward compatability. CONFIGURE_FILE(${OpenIGTLink_SOURCE_DIR}/UseOpenIGTLink.cmake.in ${OpenIGTLink_BINARY_DIR}/UseOpenIGTLink.cmake COPYONLY IMMEDIATE) # Create the OpenIGTLinkConfig.cmake file containing the OpenIGTLink configuration. INCLUDE (${OpenIGTLink_SOURCE_DIR}/GenerateOpenIGTLinkConfig.cmake) # Save the compiler settings so another project can import them. INCLUDE(${CMAKE_ROOT}/Modules/CMakeExportBuildSettings.cmake) CMAKE_EXPORT_BUILD_SETTINGS(${OpenIGTLink_BINARY_DIR}/OpenIGTLinkBuildSettings.cmake) # Save library dependencies. #EXPORT_LIBRARY_DEPENDENCIES(${OpenIGTLink_BINARY_DIR}/OpenIGTLinkLibraryDepends.cmake) INSTALL(FILES ${OpenIGTLink_BINARY_DIR}/OpenIGTLinkBuildSettings.cmake ${OpenIGTLink_BINARY_DIR}/UseOpenIGTLink.cmake ${OpenIGTLink_BINARY_DIR}/Utilities/OpenIGTLinkConfig.cmake DESTINATION ${OpenIGTLink_INSTALL_PACKAGE_DIR} COMPONENT Development ) INSTALL(FILES ${OpenIGTLink_BINARY_DIR}/igtlConfigure.h DESTINATION ${OpenIGTLink_INSTALL_INCLUDE_DIR} COMPONENT Development ) INSTALL(FILES ${OpenIGTLink_BINARY_DIR}/igtl_typeconfig.h DESTINATION ${OpenIGTLink_INSTALL_INCLUDE_DIR} COMPONENT Development ) INSTALL(FILES ${OpenIGTLink_BINARY_DIR}/igtlTypeConfig.h DESTINATION ${OpenIGTLink_INSTALL_INCLUDE_DIR} COMPONENT Development ) #----------------------------------------------------------------------------- # Add compiler flags OpenIGTLink needs to work on this platform. This must be # done AFTER the call to CMAKE_EXPORT_BUILD_SETTINGS. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenIGTLink_REQUIRED_C_FLAGS}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenIGTLink_REQUIRED_CXX_FLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenIGTLink_REQUIRED_LINK_FLAGS}") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OpenIGTLink_REQUIRED_LINK_FLAGS}") SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OpenIGTLink_REQUIRED_LINK_FLAGS}") #----------------------------------------------------------------------------- # Configure Subdirectories ADD_SUBDIRECTORY(Source) ADD_SUBDIRECTORY(Tools) IF(OpenIGTLink_BUILD_EXAMPLES) ADD_SUBDIRECTORY(Examples) ENDIF(OpenIGTLink_BUILD_EXAMPLES) #----------------------------------------------------------------------------- # Export targets export(TARGETS OpenIGTLink FILE "${OpenIGTLink_LIBRARY_TARGETS_FILE}" ) # Export targets for install INSTALL(EXPORT OpenIGTLink DESTINATION "${OpenIGTLink_INSTALL_PACKAGE_DIR}" FILE "OpenIGTLinkTargets.cmake" ) #----------------------------------------------------------------------------- # Tests OPTION(BUILD_TESTING "Build the testing tree." ON) SET(OpenIGTLink_BUILD_TESTING ${BUILD_TESTING}) IF(OpenIGTLink_BUILD_TESTING) ENABLE_TESTING() ADD_SUBDIRECTORY(Testing) INCLUDE (${CMAKE_ROOT}/Modules/Dart.cmake) ENDIF() #----------------------------------------------------------------------------- # Doxygen OPTION(BUILD_DOCUMENTATION "Build OpenIGTLink Documentation" OFF) IF(BUILD_DOCUMENTATION) ADD_SUBDIRECTORY( Documents/Doxygen ) ENDIF(BUILD_DOCUMENTATION) openigtlink-3.0.0/DartConfig.cmake000066400000000000000000000036431501024245700170650ustar00rootroot00000000000000# Dashboard is opened for submissions for a 24 hour period starting at # the specified NIGHLY_START_TIME. Time is specified in 24 hour format. SET (NIGHTLY_START_TIME "0:30:00 EDT") # USE HTTP for submittion IF(NOT DROP_METHOD) SET(DROP_METHOD http) ENDIF(NOT DROP_METHOD) # Dart server to submit results (used by client) IF(DROP_METHOD MATCHES http) SET (DROP_SITE "public.kitware.com") SET (DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi") ELSE(DROP_METHOD MATCHES http) SET (DROP_SITE "public.kitware.com") SET (DROP_LOCATION "/incoming") SET (DROP_SITE_USER "ftpuser") SET (DROP_SITE_PASSWORD "public") ENDIF(DROP_METHOD MATCHES http) SET (TRIGGER_SITE "http://${DROP_SITE}/cgi-bin/Submit-OpenIGTLink-TestingResults.pl") # Project Home Page #SET (PROJECT_URL "http://${DROP_SITE}/IFSTK") # Dart server configuration SET (ROLLUP_URL "http://${DROP_SITE}/cgi-bin/OpenIGTLink-rollup-dashboard.sh") SET (CVS_WEB_URL "http://${DROP_SITE}/cgi-bin/viewcvs.cgi/") SET (CVS_WEB_CVSROOT "OpenIGTLink") SET (USE_DOXYGEN "On") SET (DOXYGEN_URL "http://public.kitware.com/OpenIGTLink/NightlyDoc/" ) SET (USE_GNATS "On") SET (GNATS_WEB_URL "http://public.kitware.com/Bug/index.php") # Continuous email delivery variables SET (CONTINUOUS_FROM "luis.ibanez@kitware.com") SET (SMTP_MAILHOST "public.kitware.com") SET (CONTINUOUS_MONITOR_LIST "luis.ibanez@kitware.com") SET (CONTINUOUS_BASE_URL "http://public.kitware.com/OpenIGTLink") SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_TEST_FAILURES ON) SET (DELIVER_BROKEN_BUILD_EMAIL "Continuous Nightly") SET (EMAIL_FROM "cmake-dashboard@public.kitware.com") SET (DARTBOARD_BASE_URL "http://public.kitware.com/OpenIGTLink") SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_CONFIGURE_FAILURES 1) SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_BUILD_ERRORS 1) SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_BUILD_WARNINGS 1) SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_TEST_NOT_RUNS 1) SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_TEST_FAILURES 1) openigtlink-3.0.0/Documents/000077500000000000000000000000001501024245700157765ustar00rootroot00000000000000openigtlink-3.0.0/Documents/Doxygen/000077500000000000000000000000001501024245700174135ustar00rootroot00000000000000openigtlink-3.0.0/Documents/Doxygen/CMakeLists.txt000066400000000000000000000017601501024245700221570ustar00rootroot00000000000000#-- Add an Option to toggle the generation of the API documentation if(BUILD_DOCUMENTATION) FIND_PACKAGE(Doxygen QUIET) if (NOT DOXYGEN_FOUND) message(FATAL_ERROR "Doxygen is needed to build the documentation. Please install it correctly") endif() #IF (BUILD_DOXYGEN) CONFIGURE_FILE(${OpenIGTLink_SOURCE_DIR}/Utilities/Doxygen/doxygen.config.in ${OpenIGTLink_BINARY_DIR}/Utilities/Doxygen/doxygen.config) CONFIGURE_FILE(${OpenIGTLink_SOURCE_DIR}/Utilities/Doxygen/igtldoxygen.pl.in ${OpenIGTLink_BINARY_DIR}/Utilities/Doxygen/igtldoxygen.pl) ADD_CUSTOM_TARGET(Documentation COMMAND ${DOXYGEN_EXECUTABLE} ${OpenIGTLink_BINARY_DIR}/Utilities/Doxygen/doxygen.config MAIN_DEPENDENCY ${OpenIGTLink_BINARY_DIR}/Utilities/Doxygen/doxygen.config DEPENDS ${OpenIGTLink_BINARY_DIR}/Utilities/Doxygen/igtldoxygen.pl WORKING_DIRECTORY ${OpenIGTLink_BINARY_DIR}/Utilities/Doxygen ) #ENDIF (BUILD_DOXYGEN) endif() openigtlink-3.0.0/Documents/Doxygen/DoxygenFooter.html000066400000000000000000000006071501024245700231000ustar00rootroot00000000000000
Generated at $datetime for $projectname by doxygen $doxygenversion written by Dimitri van Heesch, © 1997-2012
openigtlink-3.0.0/Documents/Doxygen/DoxygenHeader.html000066400000000000000000000021341501024245700230270ustar00rootroot00000000000000 $title
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  
openigtlink-3.0.0/Documents/Doxygen/DoxygenStyle.css000066400000000000000000000214221501024245700225640ustar00rootroot00000000000000BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 120%; } H3 { font-size: 100%; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: #eef3f5; border-width: 1px; border-style: solid; border-color: #dedeee; -moz-border-radius: 8px 8px 8px 8px; } .memname { white-space: nowrap; font-weight: bold; } .memdoc{ padding-left: 10px; } .memproto { background-color: #d5e1e8; width: 100%; border-width: 1px; border-style: solid; border-color: #84b0c7; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } openigtlink-3.0.0/Documents/Doxygen/MainPage.dox000066400000000000000000000031201501024245700216040ustar00rootroot00000000000000/** * * \mainpage The OpenIGTLink Library * * \section intro Introduction * * The OpenIGTLink protocol is a simple but extensible network communication protocol * to exchange various types of data among software and devices for image-guided therapy * (IGT) e.g. surgical navigation software, tracking device, robotic device, imaging scanner. * The protocol can handle images, tool positions, transforms, commands, device status, * monitoring command, and other user-defined data types. * It is designed to work in the application layer of the TCP/IP stack. * * The goal of the OpenIGTLink protocol is to make system integration for IGT application easier * and faster. To achieve this objective, we set the following rules: * * \arg \c Open. The protocol and the OpenIGTLink library is provided free of charge for * any purpose including commercial use. This would encourage engineers and researchers * to participate the community and help making the protocol more universal, compatible and * reliable. * * \arg \c Simple. The protocol only defines a limited number of simple memory layouts * for messaging and does not require interface software to handle the all types of messages. * Such simple specification allows implementing OpenIGTLink interface for wide variety of * computer systems ranging from embedded systems to high-performance computers. * * \arg \c Extensible. The protocol has a mechanism to define a user-defined message * type. * * \section homepage More Information * * The Home Page of the OpenIGTLink is * * http://openigtlink.org/ * * */ openigtlink-3.0.0/Documents/Doxygen/Modules.dox000066400000000000000000000000001501024245700215250ustar00rootroot00000000000000openigtlink-3.0.0/Documents/Protocol/000077500000000000000000000000001501024245700175775ustar00rootroot00000000000000openigtlink-3.0.0/Documents/Protocol/bind.md000066400000000000000000000116301501024245700210360ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Bind Message ============ - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The Bind message is designed to bind any OpenIGTLink messages into a single message. Messages bound in a BIND message are called 'child messages.' The BIND message format is useful, when one needs to care about synchronization of multiple messages (e.g. multi-channel sensors), or sending associative array (pairs of key string and value). The bind message format consists of the bind header section, which contains types and sizes of child messages, the child message name table section, and the child message body section. Message Types ============= BIND ---- Data | Type | Description --------------|---------------|------------------------------------------------- N_CHLID | uint16 | Number of child messages BIND_HEADER | BIND HEADER | Types and sizes of child messages NAME_TABLE | NAME TABLE | Name tables for child messages DATA | DATA | Child messages - BIND HEADER Section Data | Type | Description ------------------|-----------|------------------------------------------------- CTYPE_0 | char[12] | Device type string for child message 0 CSIZE_0 | uint64 | Data size for child message 0 ... | ... | CTYPE_(N_CHILD-1)| char[12] | Device type string for child message (N_CHILD-1) CSIZE_(N_CHILD-1)| uint 64 | Data size for child message (N_CHILD-1) - NAME TABLE Section (NULL-separated values) Data | Type | Description ----------------|---------------|----------------------------------------------- NTABLE_SIZE | uint16 | Size of name table (including the padding) NAME_0 | char[*] | Name for child message 0 (null) | uint8 | separator ... | ... | NAME_(N_CM-1) | char[*] | Name for child message (N_CHILD-1) (null) | uint8 | Separator (Padding*) | uint8 or none | Padding to align with WORD * Padding field is inserted only if the previous field does not aligned with WORD border. - DATA Section Data | Type | Description ------------------|---------------|----------------------------------------------- CDATA 0 | CTYPE_0 | Data array for child message 0 (size: CSIZE_0) (Padding*) | uint8 or none | Padding to align DATA with WORD CDATA 1 | CTYPE_1 | Data array for child message 1 (size: CSIZE_1) (Padding*) | uint8 or none | Padding to align DATA with WORD ... | ... | CDATA_(N_CHILD-1)| CTYPE_(N_CHILD-1)|Data array for child message (N_CHILD-1) (Padding*) | uint8 or none | Padding to align DATA with WORD GET_BIND -------- GET_BIND is used to request the receiver for associative array data. If a GET_BIND message does not have a body, it requests all data. Data | Type | Description --------------|---------------|------------------------------------------------- N_CHLID | uint16 | Number of child messages BIND_HEADER_2| BIND HEADER 2 | Types and sizes of child messages NAME_TABLE | NAME TABLE | Name tables for child messages - BIND HEADER 2 Section Data | Type | Description ------------------|-----------|------------------------------------------------- CTYPE_0 | char[12] | Device type string for child message 0 ... | ... | CTYPE_(N_CHILD-1)| char[12] | Device type string for child message (N_CHILD-1) - NAME_TABLE (see BIND message) STT_BIND -------- GET_BIND is used to request the receiver for associative array data. If a GET_BIND message does not have a body, it requests all data. Data | Type | Description --------------|---------------|------------------------------------------------- RESOL | uint64 | Minimum interval between message (ns)* See [Time Stamp](timestamp.md) or Data | Type | Description --------------|---------------|------------------------------------------------- N_CHLID | uint16 | Number of child messages BIND_HEADER_2| BIND HEADER 2 | Types and sizes of child messages NAME_TABLE | NAME TABLE | Name tables for child messages - BIND HEADER 2 Section (see BIND message) - NAME_TABLE Section (see BIND message) STP_BIND -------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_BIND -------- Data | Type | Description --------------|---------------|------------------------------------------------- | | Implementations =================== * [igtlBindMessage.h](/Source/igtlBindMessage.h) * [igtlBindMessage.cxx](/Source/igtlBindMessage.cxx) Contributors =================== * Junichi Tokuda openigtlink-3.0.0/Documents/Protocol/capability.md000066400000000000000000000031371501024245700222460ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Capability Message ================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The CAPABILITY type lists the names of message types that the receiver can interpret. Although the OpenIGTLink protocol guarantees that any receiver can at least skip messages with unknown type and continue to interpret the following messages, it is a good idea to get the capability information at system startup to ensure application-level compatibility of various devices. In a CAPABILITY message type, each message type name comes with format version number. If the receiver can interpret multiple versions for a certain message type, they should be listed as independent types. Message Types =================== CAPABILITY ---------- Data | Type | Description --------------|---------------|------------------------------------------------- TYPE_0 | uint8[12] | Type name #0 ... | ... | TYPE_(N_TYPE)| uint8[12] | Type name #(N_TYPE) * Number of type names (N_TYPE) is calculated by BODY_SIZE / 12. GET_CAPABIL ----------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_CAPABIL ----------- N/A STP_CAPABIL ------------------- N/A RTS_CAPABIL ------------------- N/A Implementations =================== * [igtlCapabilityMessage.h](/Source/igtlCapabilityMessage.h) * [igtlCapabilityMessage.cxx](/Source/igtlCapabilityMessage.cxx) Contributors =================== Junichi Tokuda openigtlink-3.0.0/Documents/Protocol/colortable.md000066400000000000000000000021571501024245700222540ustar00rootroot00000000000000 ColorTable Message ================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary =================== COLORT is used to transfer a color table. Message Types =================== COLORT ------ Data | Type | Description --------------|---------------|------------------------------------------------- INDEX_TYPE | uint8 | Index type (3:uint8 5:uint16) MAP_TYPE | uint8 | Map type (3:uint8 5:uint16 19:RGB color) TABLE | uint8[] | Color index table GET_COLORT ------------------- To get the COLORT, GET_COLORT is used with the Id in the device name field. Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_COLORT ------------------- N/A STP_COLORT ------------------- N/A RTS_COLORT ------------------- N/A Implementations =================== * [igtlColorTableMessage.h](/Source/igtlColorTableMessage.h) * [igtlColorTableMessage.cxx](/Source/igtlColorTableMessage.cxx) Contributors =================== * Alexander Schaal openigtlink-3.0.0/Documents/Protocol/command.md000066400000000000000000000026201501024245700215370ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Command Message =============== - Protocol Version: 3.0 - Release Date: January 20, 2017 - Available: 3.0 and later Summary ======= The COMMAND is a message type that can be used to transfer a command string structured in XML. While STRING offers a similar functionality, COMMAND has additional fields to include command ID and name providing an easy way to reference previous messages exchanged between the two hosts during the session. IGSIO (http://igsio.github.io/) demonstrates representative usage of the COMMAND type. Message Types ============= COMMAND ------- Data | Type | Description ---------------|------------------------|--------------------------------------- COMMAND_ID | uint32 | The unique ID of this command COMMAND_NAME | uint8[IGT_COMMAND_SIZE]| The name of the command ENCODING | uint16 | Character encoding type as MIBenum | | (defined by IANA). Default=3 LENGTH | uint32 | The length of command COMMAND | uint8[LENGTH] | The command encoded with ENCODING For MIBenum values, please refer http://www.iana.org/assignments/character-sets Implementations =============== * [igtlCommandMessage.h](/Source/igtlCommandMessage.h) * [igtlCommandMessage.cxx](/Source/igtlCommandMessage.cxx) openigtlink-3.0.0/Documents/Protocol/header.md000066400000000000000000000107271501024245700213600ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Message Header ============== - Protocol Version: 3.0 - Release Date: January 20, 2017 Header Fields ============= Data | Type | Description --------------|---------------|------------------------------------------------- V | uint16 | Header version number (2 for version 2 and 3) TYPE | char[12] | Type name of data DEVICE_NAME | char[20] | Unique device name TIME_STAMP | uint64 | Timestamp or 0 if unused BODY_SIZE | uint64 | Size of the body in bytes CRC | uint64 | 64 bit CRC for body data Header version number --------------------- The header version number field specifies the Header Version. Please note that the *Header Version* is not the same as the *Protocol Version*, as the Protocol Version reflects not only the format of the header but also the available message types. Two header versions exist as of Protocol Version 3.x: - _Header Version 1_ is used in Protocol Version 1 and 2. - _Header Version 2_ is used in Protocol Version 3.x. The major difference between header versions 1 and 2 is the mechanism to include the extended header and meta data in the message. This feature has been introduced in Protocol Version 3. Type name --------- The type name field is an ASCII character string specifying the type of the data contained in the message body e.g. "TRANSFORM". The length of the type name must be within 12 characters. Device name ----------- The device name field contains an ASCII character string specifying the name of the the message. Timestamp --------- The timestamp field contains a 64-bit timestamp indicating when the data is generated. Please refer [Timestamp](timestamp.html) for the format of the 64-bit timestamp. Body size --------- The body size field contains the size of the body in bytes. The Body is a section of the OpenIGTLink message following the Header. Until Version 2, the Body only contains the message content, and hence many old programs assumed that the Body size represents the content size. Since Version 3, the Body is redefined as a set of Extended Header, Content, and Metadata. The content size must be calculated by BODY_SIZE - (EXT_HEADER_SIZE + METADAT_SIZE). CRC --- The 64-bit CRC used in OpenIGTLink protocol is based on [ECMA-182 standard](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf). An example code is available in [igtl_util.c](/Source/igtlutil/igtl_unit.h) in the OpenIGTLink library. Extended Header Fields ====================== Data | Type | Description -----------------|---------------|---------------------------------------------- EXT_HEADER_SIZE | uint16 | Length of Extended Header section METADATA_SIZE | uint16 | Length of Metadata section MSG_ID | uint32 | Message ID (Reserved) | Uint32 | (Reserved) Metadata Fields =============== Data | Type | Description ----------------------------|-------------|------------------------------------- INDEX_COUNT | uint16 | Number of meta data META_HEADER_0 | META_HEADER | Header for metadata 0 ... | ... | ... META_HEADER_(INDEX_COUNT-1)| META_HEADER | Header for metadata (INDEX_COUNT-1) META_DATA_0 | META_DATA | Content for metadata 0 ... | ... | ... META_DATA_(INDEX_COUNT-1) | META_DATA | Content for metadata (INDEX_COUNT-1) - META_HEADER Data | Type | Description ----------------|-------------|-------------------------------------------------- KEY_SIZE | uint16 | Size of key (bytes) VALUE_ENCODING | uint16 | Character encoding type for value as MIBenum value. VALUE_SIZE | uint32 | Size of value (bytes) - META_DATA Data | Type | Description -------|----------------------|-------------------------------------------------- KEY | uint16[KEY_SIZE] | Key (ASCII) VALUE | uint16[VALUE_SIZE] | Value (Encoded according to VALUE_ENCODING) * For MIBenum character encoding, please refer [IANA Character Sets](http://www.iana.org/assignments/character-sets). US-ASCII (ANSI-X3.4-1968; MIBenum = 3) is strongly recommended. Byte Order ========== Big endian should be used for all [numerical values](http://www.opengroup.org/onlinepubs/007908799/xns/htonl.html) (version, body size, crc). Unused spaces are padded with 0 (binary). openigtlink-3.0.0/Documents/Protocol/image.md000066400000000000000000000074541501024245700212150ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Image Message ============= - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary =================== The IMAGE format supports 2D or 3D images with metric information including image matrix size, voxel size, coordinate system type, position, and orientation. The body section of the IMAGE data consists of two parts: image header to transfer the metric information and image body to transfer the array of pixel or voxel values. The data type of pixel or voxel can be either scalar or vector, and numerical values can be 8-, 16-, 32-bit integer, or 32- or 64-bit floating point. The pixel values can be either big-endian or little-endian, since the sender software can specify the byte order in the image header. The format also supports "partial image transfer", in which a region of the image is transferred instead of the whole image. This mechanism is suitable for real-time applications, in which images are updated region-by-region. The sub-volume must be box-shaped and defined by 6 parameters consisting of the indices for the corner voxel of the sub-volume and matrix size of the sub-volume. Message Types =================== IMAGE ------------------- Data | Type | Description --------------|-----------|----------------------------------------------------- V | uint16 | version number T | uint8 | Number of Image Components (1:Scalar, >1:Vector). (NOTE: Vector data is stored fully interleaved.) S | uint8 | Scalar type (2:int8 3:uint8 4:int16 5:uint16 6:int32 7:uint32 10:float32 11:float64) E | uint8 | Endian for image data (1:BIG 2:LITTLE) (NOTE: values in image header is fixed to BIG endian) O | uint8 | Image coordinate (1:RAS 2:LPS) RI, RJ, RK | uint16[3] | Number of pixels in each direction TX, TY, TZ | float32[3]| Transverse vector (direction for 'i' index) / The length represents pixel size in 'i' direction in millimeter SX, SY, SZ | float32[3]| Transverse vector (direction for 'j' index) / The length represents pixel size in 'j' direction in millimeter NX, NY, NZ | float32[3]| Normal vector of image plane(direction for 'k' index) / The length represents pixel size in 'z' direction or slice thickness in millimeter PX, PY, PZ | float32[3]| Center position of the image (in millimeter) (*) DI, DJ, DK | uint16[3] | Starting index of subvolume DRI, DRJ, DRK | uint16[3] | Number of pixels of subvolume IMAGE_DATA | uint8[] | Binary image data () Image data (Endian is determined by "E" field) GET_IMAGE ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_IMAGE ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STP_IMAGE ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_IMAGE ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error Notes =================== The example application of vector type is: * Vector field * Image with complex pixel values (e.g. MRI raw data) * Color image * Vector data is stored fully interleaved. For example, if you are storing RGB color image, the order should be RGBRGBRGB... (not RRR....GGG...BBB...) Implementations =================== * [igtlImageMessage.h](/Source/igtlImageMessage.h) * [igtlImageMessage.cxx](/Source/igtlImageMessage.cxx) Contributors =================== * Junichi Tokuda openigtlink-3.0.0/Documents/Protocol/imagemeta.md000066400000000000000000000040661501024245700220600ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) ImageMeta Message ================= - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The IMGMETA message is used to transfer image meta information which is not available in IMAGE message type, such as patient name, medical record number, modality etc. An IMGMETA message can contain meta-data for multiple images. This message type may be used to obtain a list of images available in the remote system, such as image database or commercial image-guided surgery (IGS) system. Message Types ============= IMGMETA ------- Data | Type | Description --------------|---------------|------------------------------------------------- NAME | char[64] | Name or description of the image ID | char[20] | ID to query the IMAGE and COLORT MODALITY | char[32] | String which specifies the modality PATIENT_NAME | char[64] | Name of the patient PATIENT_ID | char[64] | ID of the patient TIMESTMP | uint64 | Scan time, see [Timestamp](timestamp.md) RI, RJ, RK | uint16[3] | Number of pixels in each direction (same as in IMAGE) S | uint8 | Scalar type (e.g. 3:uint8, 5:uint16, same as in IMAGE) -- | uint8 | Reserved * More than one item can be transmitted. The number is bodySize/itemSize. * To get the IMAGE, GET_IMAGE is used with the Id in the device name field. GET_IMGMETA ------------------- GET_IMGMETA is used to query for meta data of image sets. If DEVICE_NAME in the header is empty, a list of meta data for all available images is returned. Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_IMGMETA ------------------- N/A STP_IMGMETA ------------------- N/A Implementations =================== * [igtlImageMetaMessage.h](/Source/igtlImageMetaMessage.h) * [igtlImageMetaMessage.cxx](/Source/igtlImageMetaMessage.cxx) Contributors =================== * Alexander Schaal openigtlink-3.0.0/Documents/Protocol/index.md000066400000000000000000000246221501024245700212360ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) OpenIGTLink Protocol Description ================================ - Protocol Version: 3.0 - Release Date: January 20, 2017 Overview ======== OpenIGTLink is an open-source network communication interface specifically designed for image-guided interventions. It aims to provide a plug-and-play unified real-time communications (URTC) in operating rooms (ORs) for image-guided interventions, where imagers, sensors, surgical robots,and computers from different vendors work cooperatively. This URTC will ensure the seamless data flow among those components and enable a closed-loop process of planning, control, delivery, and feedback. The specification of OpenIGTLink is open, and can be used without any license fee; hence OpenIGTLink is suitable for both industrial and academic developers. We provide [the OpenIGTLink C/C++ library](https://github.com/openigtlink/OpenIGTLink) as free open-source software under the BSD-style license. The OpenIGTLink library provides application program interface (API) to communicate with other software over the network. The OpenIGTLink library supports major platforms including Microsoft Windows, Linux, and macOS (Mac OS X). Those open-interface and multi-platform strategies will lead to the widespread use of OpenIGTLink, and ultimately help to establish the interoperability among a wide variety of components developed by different groups and companies in the community. Message Structure ================= The OpenIGTLink protocol defines a set of message formats for several data types that are frequently used for image-guided and robot-assisted interventions. Those formats are used to compose messages that are transferred from one device to another over the local area network. The application developers can choose their own transportation layer that fits for their application and environment (e.g. TCP, UDP, WebSocket). While the developers are encouraged to use the data types defined in the standard protocol, they have an option to define a new message format. User-defined messages can be mixed with the standard message types, since the protocol has a mechanism to skip a message, if the receiver does not know its format. In OpenIGTLink Version 3, each OpenIGTLink message consists of the following four sections: ~~~~ Bytes 0 58 72 +----------+-------------+-------------------+-----------+ | HEADER | EXT_HEADER | CONTENT | META_DATA | +----------+-------------+-------------------+-----------+ |<----------------- Body -------------------->| ~~~~ * Header (58 bytes) * Extended Header (variable length) (New in Version 3) * Content (variable length) * Metadata (variable length) (New in Version 3) The last three sections are called "Body" for the sake of convention. Since there were no Extended Header and Metadata in the older versions before to Version 3, the Body section was solely used by the message content. Therefore, the Body Size in the Header represented the size of the message content as well as the size of the rest of the message. As a result, many old applications assume that the Body Size in the Header equals the size of the message content. When the message structure was revised for Version 3, we redefined the Body Size as the total size of Extended Header, Content, and Metadata, because this new definition allows the old OpenIGTLink programs can still tell the size of the rest of the message, and skip reading the byte stream until the beginning of the next message. The size of the content can be computed as: BODY_SIZE - (EXT_HEADER_SIZE + METADAT_SIZE). Header + Extended Header ------------------------ ~~~~ Bytes 0 2 14 34 +---+-----------------------+---------------------------------------+ | V | TYPE | DEVICE_NAME | +---+-----------------------+---------------------------------------+ 34 42 50 58 +---------------+---------------+---------------+ | TIME_STAMP | BODY_SIZE | CRC64 | +---------------+---------------+---------------+ 58 60 64 68 72 +-----------------+---------------+---------+-----------+ | EXT_HEADER_SIZE | METADATA_SIZE | MSG_ID | RESERVED | +-----------------+---------------+---------+-----------+ ~~~~ The formats of the Header and Extended Header sections are consistent among all message types, and can be interpreted by any software that has an OpenIGTLink interface. The Header contains device type (or data type) name, which specifies the format of the body. The Extended Header section provides a mechanism to attach application-specific meta-data to the message along with the Metadata section. Content ------- The format of contenst section is type-dependent. Please see below for the detail. Meta-Data --------- Meta-data are given in the form of an associative array (i.e. pairs of "key" and "value") in the protocol. The Content section contains the data. The format of the Content section is defined for each data type. Metadata header: ~~~~ Bytes 0 2 4 6 10 +-------------+-------------+-------------------+---------------+---- | INDEX_COUNT | KEY_SIZE_0 | VALUE_ENCODING_0 | VALUE_SIZE_0 | ... +-------------+-------------+-------------------+---------------+---- |<-------------- Metadata 0 --------------------->| 10 12 14 18 ----+-------------+-------------------+---------------+---- ... | KEY_SIZE_1 | VALUE_ENCODING_1 | VALUE_SIZE_1 | ... ----+-------------+-------------------+---------------+---- |<--------------- Metadata 1 -------------------->| INDEX_COUNT*8+2 ----+-------------+-------------------+---------------+ ... |KEY_SIZE_N-1 |VALUE_ENCODING_N-1 |VALUE_SIZE_N-1 | ----+-------------+-------------------+---------------+ |<----------Metadata N-1 (=INDEX_COUNT-1)-------->| ~~~~ Metadata body: ~~~~ Bytes +--------+---------+--------+----------+---- ----+--------+-----------+ | KEY_0 | VALUE_0 | KEY_1 | VALUE_1 | ... |KEY_N-1 | VALUE_N-1 | +--------+---------+--------+----------+---- ----+--------+-----------+ |<-- Metadata 0 -->|<-- Metadata 1 --->| |<-- Metadata N-1 -->| ~~~~ Please refer to the [Header](header.md) pages for the detailed format of the Header, Extended Header, and Meta-Data sections. Content ======= The Content section contains the actual message data such as transforms, images, strings, etc. The format of the Content section depends on the type of the message, and it is specified in the TYPE section in the message header. Whlie the OpenIGTLink protocol allows application developers to define and use their own data types, it also provides a number of standard message types listed below. Application developers should not use the type names of these standard types for their own message types, because the receiver programs are expected to de-serialize the Content section according to the standard format. Message types inherited from version 1 -------------------------------------- * [CAPABILITY](/Documents/Protocol/capability.md) * [IMAGE](/Documents/Protocol/image.md) * [POSITION](/Documents/Protocol/position.md) (alias of QTRANS) * [QTRANS](/Documents/Protocol/qtransform.md) (formerly POSITION) * [STATUS](/Documents/Protocol/status.md) * [TRANSFORM](/Documents/Protocol/transform.md) Message types introduced in version 2 ------------------------------------- * [BIND](/Documents/Protocol/bind.md) * [COLORT](/Documents/Protocol/colortable.md) * [IMGMETA](/Documents/Protocol/imagemeta.md) * [LBMETA](/Documents/Protocol/labelmeta.md) * [NDARRAY](/Documents/Protocol/ndarray.md) * [POINT](/Documents/Protocol/point.md) * [POLYDATA](/Documents/Protocol/polydata.md) * [QTDATA](/Documents/Protocol/qtrackingdata.md) * [SENSOR](/Documents/Protocol/sensordata.md) * [STRING](/Documents/Protocol/string.md) * [TDATA](/Documents/Protocol/trackingdata.md) * [TRAJ](/Documents/Protocol/trajectory.md) Message types introduced in version 3 ------------------------------------- * [COMMAND](/Documents/Protocol/command.md) Query Mechanism =============== See [Query Mechanism](query.md) for detail. Protocol Compatibility ====================== The protocol has been revised several times since the OpenIGTLink protocol was originally proposed. The current protocol version is Version 3. The differences among versions 1, 2, and 3 are as follows: - Difference between Version 1 and 2 - [Querying mechanism](query.md) was introduced in Version 2. - More message types are supported in Version 2. - The formats of the message types available in both Version 1 and 2 remained unchanged. - Difference between Version 2 and 3.0 - The header format was extended in Version 3. - Version 3 messages consist of 4 sections (Header, Extended Header, Content, and Metadata), while Version 2 messages consist of 2 sections (Header and Body). - The formats of the message content remained unchanged. All OpenIGTLink interfaces are expected to be backward-compatible, and must be able to handle older message formats. Older interfaces might not interpret a message in a newer format, but they are expected to skip the content and continue to read the following messages. Version Numbers =============== Protocol Version ---------------- Starting at Protocol/Library Version 3, we changed the versioning rule for the protocol version as follows to make it easier to revise the protocol: - The protocol version may have a minor version number. - The major version reflects a major change to the protocol such as: - Change to the header format - Major change to the message format - Adding new rules in the message exchange scheme (e.g. querying) - The minor version reflects a minior change to the format such as: - Fixing minor issues of minor format in the prior versions. - Adding new message types. Library Version --------------- The Library's version number consists of major, minor, and patch versions (e.g. 3.0.1 means major version 3, minor version 0, and revision 1). Both major and minor versions match the protocol version after the protocol/library version 3.0. In ealier protocol/header versions (i.e. 1 and 2), Only the major versions should match the protocol version. openigtlink-3.0.0/Documents/Protocol/labelmeta.md000066400000000000000000000033261501024245700220530ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) LabelMeta Message ================= - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary =================== The LBMETA is used to transfer meta information for label maps, which are not available in the IMAGE message type. To retrieve voxel objects or a label map, GET_IMAGE / IMAGE can be used. But the client should be able to get a list of available structures. Message Types =================== LBMETA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- NAME | char[64] | Name or description of the image ID | char[20] | ID to query the IMAGE LABEL | uint8 | Label of the structure (0 if unused) -- | uint8 | Reserved. R,G,B,A | uint8[4] | Color in RGBA (0 0 0 0 if no color is defined) RI, RJ, RK | uint16[3] | Number of pixels in each direction (same as in IMAGE), bounding box of the structure(s) OWNER_IMAGE | char[20] | ID of the owner image/sliceset. Voxel objects from different slicesets can be sent if slicesets are fused. Can be empty if n/a GET_LBMETA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_LBMETA ------------------- N/A STP_LBMETA ------------------- N/A Implementations =================== IMGMETA message type is implemented in the following source code. * [igtlLabelMetaMessage.h](/Source/igtlLabelMetaMessage.h) * [igtlLabelMetaMessage.cxx](/Source/igtlLabelMetaMessage.cxx) Contributors =================== * Alexander Schaal openigtlink-3.0.0/Documents/Protocol/ndarray.md000066400000000000000000000037421501024245700215670ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) NDArray Message =============== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= NDARRAY is a data type, which is designed to transfer N-dimensional numerical array. Message Types ============= NDARRAY ------- Data | Type | Description --------------|---------------|------------------------------------------------- SCALAR_TYPE | uint8 | Scalar type (2:int8 3:uint8 4:int16 5:uint16 6:int32 7:uint32 10:float32 11:float64 13:complex float 64*) DIM | uint8 | Dimension of array SIZE | uint16[DIM] | Size of array DATA | ARRAY | Array data. (Must be in the network byte order.) * ARRAY is a byte array SCALAR_TYPE[SIZE[0]][SIZE[1]]....[[SIZE[DIM-1]]] * Complex is a 128-bit variable consisting of a real part in the first 64-bit and an imaginal part in the last 64-bit. GET_NDARRAY ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_NDARRAY ------------------- N/A STP_NDARRAY ------------------- N/A RTS_NDARRAY ------------------- N / A Notes =================== Memory layout of DATA field ------------------- Like multi-dimensional array in C/C++, DATA field is laid out in sequentially in a byte stream. For example, if the value of DATA is defined by: char data[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; The layout in the byte stream can be visualized as follows: +-+-+-+-+-+-+-+-+-+ |1|2|3|4|5|6|7|8|9| +-+-+-+-+-+-+-+-+-+ Implementations =================== The NDARRAY message type is implemented in the following source code. * [igtlNDArrayMessage.h](/Source/igtlNDArrayMessage.h) * [igtlNDArrayMessage.cxx](/Source/igtlNDArrayMessage.cxx) Contributors =================== * Junichi Tokuda * Yuichiro Hayashi openigtlink-3.0.0/Documents/Protocol/point.md000066400000000000000000000036331501024245700212570ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Point Message ============= - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The POINT message type is designed to transfer information about fiducials, which are often used in surgical planning and navigation in the image-guided therapy. Message Types ============= POINT ----- Data | Type | Description --------------|---------------|------------------------------------------------- POINT_0 | POINT_DATA | Data for point 0 ... | | POINT_(N-1) | POINT_DATA | Data for point N-1 - POINT_DATA Data | Type | Description --------------|---------------|------------------------------------------------- NAME | char[64] | Name or description of the point GROUP | char[32] | Can be "Labeled Point", "Landmark", "Fiducal", ... R,G,B,A | uint8[4] | Color in RGBA X,Y,Z | float32[3] | Coordinate of the point in millimeter DIAMETER | float32 | Diameter of the point in millimeter. Diameter can be 0. OWNER | char[20] | Id of the owner image/sliceset. Points from different slicesets can be sent if slicesets are fused. GET_POINT --------- GET_POINT is used to query for meta data of label data. If the DEVICE_NAME field in the header is empty, a list of all available point data is returned. Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_POINT ------------------- N / A STP_POINT ------------------- N/A RTS_POINT ------------------- N/A Implementations =================== IMGMETA message type is implemented in the following source code. * [igtlPointMessage.h](/Source/igtlPointMessage.h) * [igtlPointMessage.cxx](/Source/igtlPointMessage.cxx) Contributors =================== * Alexander Schaal openigtlink-3.0.0/Documents/Protocol/polydata.md000066400000000000000000000156121501024245700217430ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) PolyData Message ================ - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= POLYDATA is used to transfer 3D polygonal data. The message format is designed based on the [POLY DATA format](http://www.vtk.org/VTK/img/file-formats.pdf) defined in VTK file format and equivalent to [VTK's vtkPolyData class](http://noodle.med.yale.edu/vtk5/classvtkPolyData.html). The message also supports dataset attribute field in VTK, including scalars, calar_scalars, vectors, vectors, normals, texture coordinates, and tensor, but not lookup table. Message Types ============= POLYDATA -------- Data | Type | Description ----------------------|--------------|------------------------------------------ NPOINTS | uint32 | Number of points NVERTICES | uint32 | Number of vertices SIZE_VERTICES | uint32 | Total size of vertices data NLINES | uint32 | Number of lines SIZE_LINES | uint32 | Total size of line data NPOLYGONS | uint32 | Number of polygons SIZE_POLYGONS | uint32 | Total size of polygon data NTRIANGLE_STRIPS | uint32 | Number of triangle strips SIZE_TRIANGLE_STRIPS | uint32 | Total size of triangle strips data NATTRIBUTES | uint32 | Number of dataset attributes POINTS | POINTS | Coordinates of point 0 - (NPOINTS-1) VERTICES | STRUCT_ARRAY | Array of vertices LINES | STRUCT_ARRAY | Array of lines POLYGONS | STRUCT_ARRAY | Array of polygons TRIANGLE_STRIPS | STRUCT_ARRAY | Array of triangle strips ATTRIBUTES | ATTRIBUTES | Attributes - POINTS Data | Type | Description --------------|---------------|------------------------------------------------- P0X,P0Y,P0Z | float32[3] | Coordinates for point 0 ... | ... | ... P(NPOINTS-1)X,P(NPOINTS-1)Y,P(NPOINTS-1)Z | float32[3] | Coordinates for point (NPOINTS-1) - STRUCT_ARRAY STRUCT_ARRAY contains an array of point indices that represent a geometric structure, including vertices, lines, polygons, and triangle strips. The number of structures (N_STRUCT) are specified by either NVERTICES, NLINES, NPOLYGONS, or NTRIANGLE_STRIPS (see the table above). Data | Type | Description --------------------------|--------------|--------------------------------------- STRUCT_0 | POINT_INDICES| Point indices for 0th structure ... | ... | ... STRUCT_(N_STRUCT-1) | POINT_INDICES| Point indices for N_STRUCT-1 th structure - POINT_INDICES Data | Type | Description --------------------------|-------------|--------------------------------------- NINDICES | uint32 | Number of point indices POINT_INDEX_0 | uint32 | Index for point #0 ... | ... | POINT_INDEX_(NINDICES-1) | uint32 | Index for point # (NINDICES - 1) - ATTRIBUTES Data | Type | Description -------------------------|----------------|---------------------------------------- ATTRIBUTE_HEADER |ATTRIBUTE_HEADER| Attribute header ATTRIBUTE_NAMES | ATTRIBUTE_NAMES| List of attribute names ATTRIBUTE_0 | ATTRIBUTE_DATA | Data for attribute #0 ... | ... | ... ATTRIBUTE_(NATTRIBUTE-1)| ATTRIBUTE_DATA | Data for attribute #(NATTRIBUTE-1) - ATTRIBUTE_HEADER Data | Type | Description ----------------------|---------------|------------------------------------------ TYPE_ATTRIBUTE_0 | uint16 | Type of dataset attribute #0 (including number of components for scalar type) NATTRIBUTE_0 | uint32 | Number of data for attribute #0 ... | ... | ... ... | ... | ... TYPE_ATTRIBUTE(NATTRIBUTES-1)| uint16| Type of dataset attribute #(NATTRIBUTES-1) NATTRIBUTE(NATTRIBUTES-1)| uint32 | Number of data for attribute #(NATTRIBUTES-1) - ATTRIBUTE_NAMES Data | Type | Description ----------------------|---------------|------------------------------------------ NAME_ATTRIBUTE_0 | char[] | Name of attribute 0 (null) | char | (null) ... | ... | ... ... | ... | ... NAME_ATTRIBUTE_(NATTRIBUTES-1)| char[] | Name of attribute (NATTRIBUTES-1) (null) | char | (null) Padding | (int8) NULL | Padding (inserted to make the size of ATTRIBUTE_NAMES even) - ATTRIBUTE_DATA Data | Type | Description ------|-------------------------------|------------------------------------------ DATA | float32[NATTRIBUTE_0][NCOMP] | Attribute data ... | ... | DATA | float32[NATTRIBUTE_(NATTRIBUTES-1)][NCOMP] | Attribute data * Values for TYPE_ATTRIBUTE (16-bit) * 0-7 bit: Attribute Type: * 0x00: POINT_DATA / Scalars * 0x01: POINT_DATA / Vectors * 0x02: POINT_DATA / Normals * 0x03: POINT_DATA / Tensors * 0x04: POINT_DATA / RGBA * 0x10: CELL_DATA / Scalars * 0x11: CELL_DATA / Vectors * 0x12: CELL_DATA / Normals * 0x13: CELL_DATA / Tensors * 0x14: CELL_DATA / RGBA * 8-15 bit: Number of components -- must be 3 for Vectors and Normal, 9 for Tensor, 4 for RGBA. * Maximum length for attribute name is 255 * If there are a pair of scalar and RGBA data with the same name and type (either POINT or CELL), those are used as scalar values and a look up table. * elements in RGBA data must be in the rage of \[0.0, 1.0\] GET_POLYDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_POLYDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | or Data | Type | Description --------------|---------------|------------------------------------------------- RESOL | uint64 | Minimum interval between message (ns)* See [Time Stamp](timestamp.md) STP_POLYDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_POLYDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error Implementations =================== * [igtlPolyDataMessage.h](/Source/igtlPolyDataMessage.h) * [igtlPolyDataMessage.cxx](/Source/igtlPolyDataMessage.cxx) openigtlink-3.0.0/Documents/Protocol/position.md000066400000000000000000000041661501024245700217740ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Position Message ================ - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The POSITION message type is used to transfer position and orientation information. The data are a combination of three-dimensional vector for the position and quaternion for the orientation. Although equivalent position and orientation can be described with the TRANSFORM data type, the POSITION data type has the advantage of smaller data size (19%). It is, therefore, more suitable for pushing high frame-rate data from tracking devices. Message Types ============= POSITION -------- Data | Type | Description --------------|---------------|------------------------------------------------- X | float32 | X position in millimeter Y | float32 | Y position in millimeter Z | float32 | Z position in millimeter OX | float32 | X element in quaternion OY | float32 | Y element in quaternion OZ | float32 | Z element in quaternion W | float32 | W element in quaternion GET_POSITION ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_POSITION ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STP_POSITION ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_POSITION ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error Implementations =================== * [igtlPositionMessage.h](/Source/igtlPositionMessage.h) * [igtlPositionMessage.cxx](/Source/igtlPositionMessage.cxx) Contributors =================== * Junichi Tokuda openigtlink-3.0.0/Documents/Protocol/qtrackingdata.md000066400000000000000000000053471501024245700227470ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) QuaternionTrackingData Message ============================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary =================== The QTDATA message type is intended for transferring 3D positions of surgical tools, markers etc. Its role is almost identical to TDATA, except that QTDATA describes orientation by using quaternion. Message Types =================== QTDATA ------------------- Data | Type | Description ---------------|---------------|------------------------------------------------- NAME_0 | char[20] | Name (=Id) of the instrument/tracker # 0 TYPE_0 | uint8 | Type of instrument for #0 (--) | uint8 | Researved POSITION_0 | float32[3] | (X, Y, Z) QUATERNION_0 | float32[4] |Quaternion (QX, QY, QZ, W) ... | ... | ... NAME_(N-1) | char[20] | Name (=Id) of the instrument/tracker TYPE_(N-1) | uint8 | Type of instrument for #0 (--) | uint8 | Reserved POSITION_(N-1)| float32[3] | (X, Y, Z) QUATERNION_(N-1)| float32[4] | Quaternion (QX, QY, QZ, W) - TYPE_X should be one of the followings: - 1: tracker - 2: 6D instrument (regular instrument) - 3: 3D instrument (only tip of the instrument defined) - 4: 5D instrument (tip and handle are defined, but not the normal vector) GET_QTDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_QTDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error RESOL | uint32 | Minimum time between two frames. Use 0 for as fast as possible. If e.g. 50 ms is specified, the maximum update rate will be 20 Hz. COORD_NAME | char[32] | Name of coordinate system to use. Can be empty for default coordinate system. (not included if action = 2) STP_QTDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_QDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error Implementations =================== * [igtlQuaternionTrackingDataMessage.h](/Source/igtlQuaternionTrackingDataMessage.h) * [igtlQuaternionTrackingDataMessage.cxx](/Source/igtlQuaternionTrackingDataMessage.cxx) Contributors =================== * Alexander Schaal openigtlink-3.0.0/Documents/Protocol/qtransform.md000066400000000000000000000041671501024245700223250ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) QuaternionTransform Message =========================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The QTRANS data type is used to transfer position and orientation information. The data are a combination of three-dimensional vector for the position and quaternion for the orientation. Although equivalent position and orientation can be described with the TRANSFORM data type, the QTRANS data type has the advantage of smaller data size (19%). It is, therefore, more suitable for pushing high frame-rate data from tracking devices. Message Types ============= QTRANS ------ Data | Type | Description --------------|---------------|------------------------------------------------- X | float32 | X position in millimeter Y | float32 | Y position in millimeter Z | float32 | Z position in millimeter OX | float32 | X element in quaternion OY | float32 | Y element in quaternion OZ | float32 | Z element in quaternion W | float32 | W element in quaternion GET_QTRANS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_QTRANS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STP_QTRANS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_QTRANS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error Implementations =================== * [igtlPositionMessage.h](/Source/igtlPositionMessage.h) * [igtlPositionMessage.cxx](/Source/igtlPositionMessage.cxx) Contributors =================== Junichi Tokuda openigtlink-3.0.0/Documents/Protocol/query.md000066400000000000000000000060401501024245700212660ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Query Message ============= - Protocol Version: 3.0 - Release Date: January 20, 2017 Simple Querying Mechanism ========================= In OpenIGTLink version 2, special prefixes GET_, STT_, STP_, and RTS_ are used in the message type field in the header for messages to query and control data flow. Those messages with those special prefix should be defined along with primary message types (for example, STT_TDATA, STP_TDATA and RTS_TDATA should be defined with TDATA). GET_ prefix: Query a single message =================================== "GET_<datatype>" query message is used to request for a single message with type <datatype>. The receiver of "GET_<datatype>" message must return a message with type <datatype> and the same name as the query message. A "GET_<datatype>" message without device name requests any available data. If data is not available, a returned message must be null body (data size = 0). A format of "GET_<datatype>" may be defined per data type, if necessary. STT_ and STP_ prefixes: Control data flow ========================================= "STT_<datatype>" and "STP_<datatype>" query message is used to request to start and stop sending a series of messages. The receiver of "STT_<datatype>" or "STP_<datatype>" message must return "RTS_<datatype>" message with the same name as the query message to notify that the receiver receives the query. Formats of "STT_<datatype>", "STP_<datatype>" and "RTS_<datatype>" may be defined per data type, if necessary. Available Message Type (Including sub-types) ============================================ Type name | GET query | STT query | STP query | RTS message | Description ----------|-------------|-------------|-------------|--------------|-------------------------------------- IMAGE | GET_IMAGE | STT_IMAGE | STP_IMAGE | RTS_IMAGE | 2D/3D image data TRANSFORM | GET_TRANSFOR| STT_TRANSFOR| STP_TRANSFOR| RTS_TRANSFOR | Affine transform data. POSITION | GET_POSITION| STT_POSITION| STP_POSITION| RTS_POSITION | Position and orientation (quaternion) CAPABILITY| GET_CAPABIL | -- | -- | RTS_CAPABIL | Points or fiducials. STATUS | GET_STATUS | -- | -- | RTS_STATUS | Device status TDATA | GET_TDATA | STT_TDATA | STP_TDATA | RTS_TDATA | Tracking data IMGMETA | GET_IMGMETA | -- | -- | RTS_IMGMETA | List of image meta data including patient name, ID (medical record number), size, etc. LBMETA | GET_LBMETA | -- | -- | RTS_LBMETA | List of label meta data. POINT | GET_POINT | -- | -- | RTS_POINT | Points or fiducials. TRAJ | GET_TRAJ | -- | -- | RTS_TRAJ | Trajectory data (needle path etc.) NDARRAY | GET_NDARRAY | STT_NDARRAY | STP_NDARRAY | RTS_NDARRAY | Associative array to transfer a set of values with key names. COMMAND | -- | -- | -- | RTS_COMMAND | Command openigtlink-3.0.0/Documents/Protocol/sensordata.md000066400000000000000000000054631501024245700222740ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) SensorData Message ================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= SENSOR is a message type, which is used to transfer sensor reading, 3-axis position, velocity, acceleration, angle, angle velocity and angle acceleration. The message format is intended for manipulator control and various types of sensors. Message Types =================== SENSOR ------------------- Data | Type | Description --------------|----------------|------------------------------------------------- LARRAY | uint8 | Length of array (0-255) STATUS | uint8 | Sensor status (Reserved) UNIT | uint64 | See [64-bit UNIT field](unit.md). DATA | float64[LARRAY]| value array for sensor 0 GET_SENSOR ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_SENSOR ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | or Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error STP_SENSOR ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_SENSOR ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error Implementations =================== * [igtlSensorMessage.h](/Source/igtlSensorMessage.h) * [igtlSensorMessage.cxx](/Source/igtlSensorMessage.cxx) Contributors =================== * Junichi Tokuda * Yuichiro Hayashi Examples =================== Sending 3-axis troque --------------------- A device with 3-axis torque (N\*m) sensor is sending data to a data logger program. The following table shows example data format to send 3-axis torque: Data | Type | Contents --------------|---------------|------------------------------------------------- LARRAY | uint8 | 3 STATUS | uint8 | 0 UNIT | uint64 | 00000010 11000000 00010000 00000000 00000000 00000000 00000000 00000000 DATA | float64[3] | {0.0, 0.0, 0.0} Sending 3-axis force, troque and acceleration --------------------------------------------- By binding SENSOR data using BIND type, values from multiple types of sensors can be transferred simultaneously. See [BIND](bind.md) message description page for detail. openigtlink-3.0.0/Documents/Protocol/status.md000066400000000000000000000047701501024245700214540ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Status Message ============== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The STATUS data type is used to notify the receiver about the current status of the sender. The data consist of status code in a 16-bit unsigned integer, sub- code in a 64-bit integer, error name in a 20-byte-length character string, and a status message. The length of the status message is determined by the size information in the general header. The status code is defined as a part of the OpenIGTLink protocol specification listed bellow. The sub-code is device specific and is defined by developers. In addition, developers can build their own error name/code into the status message and additional optional description in the following data field. Message Types ============= STATUS ------ Data | Type | Description ------------|---------------|--------------------------------------------------- C | uint16 | Status code groups: 1-Ok, 2-Generic Error, ... (see below) SUB_CODE | int64 | Sub-code for the error (ex. 0x200 - file not found) ERROR_NAME | char[20] | "Error", "OK", "Warning" - can be anything, don't relay on this MESSAGE | char[BODY_SIZE-30]| Optional (English) description (ex. "File C:\test.ini not found") Status codes: ------------------- - 00: Invalid packet - 0 is not used - 01: OK (Default status) - 02: Unknown error - 03: Panic mode (emergency) - 04: Not found (file, configuration, device etc) - 05: Access denied - 06: Busy - 07: Time out / Connection lost - 08: Overflow / Can't be reached - 09: Checksum error - 10: Configuration error - 11: Not enough resource (memory, storage etc) - 12: Illegal/Unknown instruction (or feature not implemented / Unknown command received) - 13: Device not ready (starting up) - 14: Manual mode (device does not accept commands) - 15: Device disabled - 16: Device not present - 17: Device version not known - 18: Hardware failure - 19: Exiting / shut down in progress GET_STATUS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_STATUS ------------------- N/A STP_STATUS ------------------- N/A RTS_STATUS ------------------- N/A Implementations =================== * [igtlStatusMessage.h](/Source/igtlStatusMessage.h) * [igtlStatusMessage.cxx](/Source/igtlStatusMessage.cxx) Contributors =================== * Junichi Tokuda openigtlink-3.0.0/Documents/Protocol/string.md000066400000000000000000000025731501024245700214360ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) String Message ============== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The STRING message type is used for transferring a character string. It supports character strings up to 65535 bytes. Message Types ============= STRING ------ Data | Type | Description --------------|---------------|------------------------------------------------- ENCODING | uint16 | Character encoding type as MIBenum value. Default=3. LENGTH | uint16 | Length of string (bytes) STRING | uint8[LENGTH] | Byte array of the string * For MIBenum character encoding, please refer [IANA Character Sets](http://www.iana.org/assignments/character-sets). US-ASCII (ANSI-X3.4-1968; MIBenum = 3) is strongly recommended. GET_STRING ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_STRING ------------------- N/A STP_STRING ------------------- N/A RTS_STRING ------------------- N/A Implementations =================== The TDATA message type is implemented in the following source code. * [igtlStringMessage.h](/Source/igtlStringMessage.h) * [igtlStringMessage.cxx](/Source/igtlStringMessage.cxx) Contributors =================== * Junichi Tokuda openigtlink-3.0.0/Documents/Protocol/summary.md000066400000000000000000000150021501024245700216140ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) OpenIGTLink Protocol Summary ============================ - Protocol Version: 3.0 - Release Date: January 20, 2017 Overview =================== The OpenIGTLink Protocol is ideal for building a research prototype system, because of its simple and standardized specification that requires less effort on design and development of communication mechanism for systems integration. By using OpenIGTLink, developers can save their time for more essential part of research. The OpenIGTLink's simple specification has been well accepted by the community, resulting a number of applications in the IGT research community, since it's initial release in early 2008. While we keep the protocol as simple as possible, it is also important to support as many IGT devices as possible to maximize the connectivity among software and devices, which potentially frees the developers from tedious coding just for system integration. There have been a number of feature requests that would benefit many IGT research projects, such as connectivity with commercial products, and connectivity with other major research tools, such as MATLAB. To respond to those request, and to increase the number of potential applications, we decided review the requests and release version 2 protocol during NA-MIC Summer Project Week 2010. The new protocol defines a set of new message types with new querying scheme, while maintaining a backward compatibility with version 1. This page summarizes the features in version 2. Simple Query Scheme =================== OpenIGTLink V.2 defines a simple querying scheme on top of the existing message format, by introducing a few prefix to the device type field. Request a single message =================== A client can request to send data contained in a single message, by issuing a query message with a device type string starting with "GET_". If specified data is not available, a message with a device type string starting with "RTS_" is returned. For example, when a client requests an IMAGE message to a server, it sends GET_IMAGE message to the server as a query. If the image exist, an IMAGE message is returned from the server to the client. Otherwise, a RTS_IMAGE message with error code is returned. Request a stream of messages (introduced in version 2) =================== A client can start and stop data streaming (sent as a series of messages) from a server, by issuing a query message with a device type starting with "STT_" and "STP_" respectively. If data requested by a "STT_" message is not available, the server returns a message with a device type string starting with "RTS_" prefix. A STP_ message is also acknowledged by a "RTS_" message. This is useful to start and stop position tracking or real-time imaging remotely from the client. For example, once the server receives "STT_TDATA" message from the client, it start sending "TDATA" messages to the client. The server keep sending "TDATA" messages until it receives "STP_TDATA" from the client. New message types =================== The following tables show lists of message types available in version 2. New Messages for image-guided systems -------------------
Type name GET query STT query STP query RTS message Description
TDATA GET_TDATA STT_TDATA STP_TDATA RTS_TDATA Tracking data
IMGMETA GET_IMGMETA -- -- RTS_IMGMETA List of image meta data including patient name, ID (medical record number), size, etc.
LBMETA GET_LBMETA -- -- RTS_LBMETA List of label meta data.
POINT GET_POINT -- -- RTS_POINT Points or fiducials.
TRAJ GET_TRAJ -- -- RTS_TRAJ Trajectory data (needle path etc.)
New Messages for general applications -------------------
Type name GET query STT query STP query RTS message Description
NDARRAY GET_NDARRAY STT_NDARRAY STP_NDARRAY RTS_NDARRAY Associative array to transfer a set of values with key names.
Messages from version 1 -------------------
Type name GET query STT query STP query RTS message Description
IMAGE GET_IMAGE STT_IMAGE STP_IMAGE RTS_IMAGE 2D/3D image data
TRANSFORM GET_TRANSFOR STT_TRANSFOR STP_TRANSFOR RTS_TRANSFOR Affine transform data.
POSITION GET_POSITION STT_POSITION STP_POSITION RTS_POSITION Position and orientation (quaternion)
CAPABILITY GET_CAPABIL -- -- RTS_CAPABIL Points or fiducials.
STATUS GET_STATUS -- -- RTS_STATUS Device status
openigtlink-3.0.0/Documents/Protocol/timestamp.md000066400000000000000000000037461501024245700221360ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Time Stamp Field in Header ========================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Timestamp field summary =================== * *Big Endian format:* bits numbered in big-endian fashion from 0 starting at the left, or high-order, position. * *Seconds and fraction of seconds:* timestamps are represented as a 64-bit unsigned fixed-point number, in seconds relative to 00:00:00 January 1, 1970, UTC. The integer part is in the first 32 bits (Unix-style timestamp) and the fraction part in the last 32 bits. In the fraction part, the non-significant low order can be set to 0. * *Wrap around:* The first 32-bit field will overflow some time in 2106 (second 4,294,967,296) Obtaining timestamp =================== * [itk::RealTimeClock](http://www.itk.org/Doxygen34/html/classitk_1_1RealTimeClock.html) * *Linux* / *Mac*: [ftime()](http://man7.org/linux/man-pages/man3/ftime.3.html) * *Windows*: [ftime() - 10 ms resolution](http://msdn.microsoft.com/en-us/library/z54t9z5f.aspx) * *Old Timestamp* - 1 sec resoultion: Now, [Time](http://msdn2.microsoft.com/en-us/library/1f4c8f33.aspx), Timer * *System time* - 10 msec resolution: GetTickCount, [GetTickCount64](http://msdn2.microsoft.com/en-us/library/ms724411.aspx) or [timeGetTime()](http://msdn2.microsoft.com/en-us/library/ms713418.aspx) * *Highres* - hardware dependent: [QueryPerformanceCounter](http://msdn2.microsoft.com/en-us/library/ms644904.aspx) (Intel IA32 instruction: [RDTSC](http://www.intel.com/design/pentium4/manuals/245471.htm)) Time synchronization =================== Two solutions: 0. Install NTP on all devices 0. Compute timestamp differences (local NTP can be used) Resources =================== * NTP4 Timestamp: [RFC 2030](http://www.faqs.org/rfcs/rfc2030.html) and [RFC 1305](http://www.faqs.org/rfcs/rfc1305.html). (See "3. NTP Timestamp Format") * [Obtaining Accurate Timestamps under Windows XP](http://www.lochan.org/2005/keith-cl/useful/win32time.html) openigtlink-3.0.0/Documents/Protocol/trackingdata.md000066400000000000000000000070051501024245700225570ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) TrackingData Message ==================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The TDATA message type is intended for transferring 3D positions of surgical tools, markers etc. Those positions are often measured by the optical, electromagnetic, or other types of 3D position sensor continuously and transferred as series of messages. Since it is important for software that receives TDATA to control data flow, STT_TDATA query data type has interval field to control the frame rate of consecutive messages. Message Types ============= TDATA ----- Data | Type | Description --------------|---------------|------------------------------------------------- NAME_0 | char[20] | Name (=Id) of the instrument/tracker # 0 TYPE_0 | uint8 | Type of instrument for #0 (--) | uint8 | Researved MATRIX_0 | float32[12] | Upper 3 rows of 4x4 transform matrix ... | ... | ... NAME_(N-1) | char[20] | Name (=Id) of the instrument/tracker TYPE_(N-1) | uint8 | Type of instrument for # (N-1) (--) | uint8 | Reserved MATRIX_(N-1) | float32[12] | Upper 3 rows of 4x4 transform matrix - TYPE_X should be one of the followings: - 1: tracker - 2: 6D instrument (regular instrument) - 3: 3D instrument (only tip of the instrument defined) - 4: 5D instrument (tip and handle are defined, but not the normal vector) - MATRIX follows the TRANSFORM message format. See [TRANSFORM message](transform.md). GET_TDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_TDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error RESOL | uint32 | Minimum time between two frames. Use 0 for as fast as possible. If e.g. 50 ms is specified, the maximum update rate will be 20 Hz. COORD_NAME | char[32] | Name of coordinate system to use. Can be empty for default coordinate system. (not included if action = 2) * All tracking data from one frame is included. * Invisible/unavailable trackers/instruments are not included. * Easy to develop. Sample pseudo code: while(true) { recv(trackingdata); updateView(trackingdata); } * Usually the tracking data will be sent using the standard coordinate system, which is also used for POINT, IMAGE, ... But this does only work after patient registration. Therefore the body of START_PUSH has an optional field for specifing the coordinate system "CAMERA". To switch back to the standard coordinate system, one has to send STOP_PUSH and afterwards START_PUSH without explicitly specifing the camera coordinate system. STP_TDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_TDATA ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error Implementations =================== * [igtlTrackingDataMessage.h](/Source/igtlTrackingDataMessage.h) * [igtlTrackingDataMessage.cxx](/Source/igtlTrackingDataMessage.cxx) Contributors =================== * Alexander Schaal openigtlink-3.0.0/Documents/Protocol/trajectory.md000066400000000000000000000031561501024245700223140ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Trajectory Message ================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The TRAJECTORY message type support to transfer information about 3D trajectory, which is often used for surgical planning and guidance in image-guided therapy. Message Types ============= TRAJ ---- Data | Type | Description --------------|---------------|------------------------------------------------- NAME | char[64] | Name or description of the trajectory. GROUP_NAME | char[32] | Can be "Trajectory", ... TYPE | uint8 | 1: trajectory with only entry point, 2: trajectory with only target point, 3: trajectory with entry and target point Reserved | uint8 | Reserved R,G,B,A | uint8[4] | Color in RGBA X1,Y1,Z1 | float32[3] | Entry point of the trajectory X2,Y2,Z2 | float32[3] | Target point of a trajectory DIAMETER | float32 | Diameter of trajectory, can be 0 OWNER_IMAGE | char[20] | Id of the owner image/sliceset. Trajectories from different slicesets can be sent if slicesets are fused. GET_TRAJ ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_TRAJ ------------------- N/A STP_TRAJ ------------------- N/A Implementations =================== * [igtlTrajectoryMessage.h](/Source/igtlTrajectoryMessage.h) * [igtlTrajectoryMessage.cxx](/Source/igtlTrajectoryMessage.cxx) Contributors =================== * Alexander Schaal openigtlink-3.0.0/Documents/Protocol/transform.md000066400000000000000000000047501501024245700221420ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Transform Message ================= - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= The TRANSFORM data type is used to transfer a homogeneous linear transformation in 4-by-4 matrix form. One such matrix was shown earlier in equation (1). Note that if a device is sending only translation and rotation, then TRANSFORM is equivalent to POSITION. But TRANSFORM can also be used to transfer affine transformations or simple scaling. Like IMAGE and POSITION, TRANSFORM carries information about the coordinate system used. Message Types ============= TRANSFORM --------- The message contains the elements for the upper 3 rows of 4x4 linear transform matrix. Data | Type | Description --------------|---------------|------------------------------------------------- R11 | float32 | Element (1, 1) R21 | float32 | Element (2, 1) R31 | float32 | Element (3, 1) R12 | float32 | Element (1, 2) R22 | float32 | Element (2, 2) R32 | float32 | Element (3, 2) R13 | float32 | Element (1, 3) R23 | float32 | Element (2, 3) R33 | float32 | Element (3, 3) TX | float32 | Element (1, 4) (translation along x-axis in millimeter) TY | float32 | Element (2, 4) (translation along y-axis in millimeter) TZ | float32 | Element (3, 4) (translation along z-axisin millimeter) GET_TRANS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STT_TRANS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | STP_TRANS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- | | RTS_TRANS ------------------- Data | Type | Description --------------|---------------|------------------------------------------------- STATUS | uint8 | 0: Success; 1: Error Implementations =================== * [igtlTransformMessage.h](/Source/igtlTransformMessage.h) * [igtlTransformMessage.cxx](/Source/igtlTransformMessage.cxx) Contributors =================== * Junichi Tokuda openigtlink-3.0.0/Documents/Protocol/unit.md000066400000000000000000000067111501024245700211050ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) UNIT Field for SENSOR Message ============================= - Protocol Version: 3.0 - Release Date: January 20, 2017 Summary ======= SENSOR message can handle a part of units defined in The International System of Unites (SI) in its 8-byte (or 64-bit) field. The field is designed to specify a unit consisting of SI-prefix (e.g. milli, micro, kilo etc...) and a combination of SI-base and/or SI-derived units. The bites in the field are assigned as follows: ~~~~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... |PREFIX | UNIT0 | EXP0 | UNIT1 | EXP1 | UNIT2 | EXP2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... 0 1 2 3 4 ...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ EXP2 | UNIT3 | EXP3 | UNIT4 | EXP4 | UNIT5 | EXP5 | ...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4 5 6 7 ~~~~ PREFIX (4bit) ------------- Value | SI-Prefix --------------|----------------- 0x0 | None 0x1 | deka (deca)(1e1) 0x2 | hecto (1e2) 0x3 | kilo (1e3) 0x4 | mega (1e6) 0x5 | giga (1e9) 0x6 | tera (1e12) 0x7 | peta (1e15) -- | -- 0x9 | deci (1e-1) 0xA | centi (1e-2) 0xB | milli (1e-3) 0xC | micro (1e-6) 0XD | nano (1e-9) 0XE | pico (1e-12) 0XF | femto (1e-15) UNIT(6bit) ---------- - SI Base Units Value | SI Base Unit Name --------------|------------------- 0x01 | meter 0x02 | gram 0x03 | second 0x04 | ampere 0x05 | kelvin 0x06 | mole 0x07 | candela - SI-Derived Units Value | Unit Name | Dimension --------------|-----------------|--------------------------- 0x08 | radian | meter/meter 0x09 | steradian | meter^2/meter^2 0x0A | hertz | /second 0x0B | newton | meter-kilogram/second^2 0x0C | pascal | kilogram/meter-second^2 0x0D | joule | meter^2-kilogram/second^2 0x0E | watt | meter^2-kilogram/second^3 0x0F | coulomb | second-ampere 0x10 | volt | meter^2-kilogram/second^3-ampere 0x11 | farad | second^4-ampere^2/meter^2-kilogram 0x12 | ohm | meter^2-kilogram/second^3-ampere^2 0x13 | siemens | second^3-ampere^2/meter^2-kilogram 0x14 | weber | meter^2-kilogram/second^2-ampere 0x15 | tesla | kilogram/second^2-ampere 0x16 | henry | meter^2-kilogram/second^2-ampere^2 0x17 | lumen | candela-steradian 0x18 | lux | candela-steradian/meter^2 0x19 | becquerel | /second 0x1A | gray | meter^2/second^2 0x1B | sievert | meter^2/second^2 - EXP (4-bit) Value | Exponent --------------|--------------- 0x0 | ^0 0x1 | ^1 0x2 | ^2 0x3 | ^3 0x4 | ^4 0x5 | ^5 0x6 | ^6 0x7 | ^7 -- | -- 0xF | ^-1 0xE | ^-2 0xD | ^-3 0xC | ^-4 0XB | ^-5 0XA | ^-6 openigtlink-3.0.0/Documents/Protocol/v3_proposal.md000066400000000000000000000223041501024245700223710ustar00rootroot00000000000000[Back to Index](/Documents/Protocol/index.md) Overview of Version 3 Protocol ============================== - Protocol Version: 3.0 - Release Date: January 20, 2017 Background =================== Since the release of version 2 protocol, we have learned that the protocol has several limitations: * While the naming convention for querying (i.e. GET_, STT_, STP_, and RTS_ prefixes) in version 2 provides a standardized way to identify query and response messages, there is still no standard way to manage multiple queries simaltaneously. This is mainly due to the lack of mechanism to reference the original query message from the response message. One workaround is to embed a unique message ID in the device names of query and response messages (e.g. "GET_STATUS_1234" and "RTS_STATUS_1234"). This approach requires the receiver process to parse the device name every time it receives a message, and reduces the actual length of device name. * When developers design new message exchange schemes for specific applications, they often need to attach some application-specific information to the existing data types. While it can be achieved by bundling the data message with string messages using a BIND message, it is not ideal from the performance aspect. It would make more sense to have a way to add custom 'tags' to any messages. Overview of Version 3 Proposal =================== At [Winter Project Week 2016](http://wiki.na-mic.org/Wiki/index.php/2016_Winter_Project_Week/Projects/TrackedUltrasoundStandardization) (January 5-9, 2016, Cambridge, MA), we discussed the limitations above, and potential extension to the existing protocols _with backward compatibility_. The following changes were proposed: * A new message structure. The body in the former protocol was splitted into extended header, content, and metadata. The message now consists of the following sections: * Header (58 bytes) * Extended Header (variable length) * Content (variable length) * Metadata (variable length) * The _header_ section has the same format as version 2 protocol, and should contain the following information: * The header version (the first two bytes) will be incremented to '0x0002' * The Body size is the total byte size for the extended header, content, and Metadata. This will allow old clients to skip the entire message and read the sucessive message properly. * The other fields are filled in the same as the previous version. * The _extended header_ section contains the following fields: * Extended header size (EXT_HEADER_SIZE) (2 bytes) * Metadata size (METADATA_SIZE) (2 bytes) * Message ID (MSG_ID) (4 bytes) * The _content_ section is equivalent to the body section in the previous version. * The size of content can be computed as: BODY_SIZZE - (EXT_HEADER_SIZE + METADAT_SIZE) * The _metadata_ section contains pairs of 'key' and 'value' strings. Keys are ASCII string, while values can be stored using different encodings. Messaging Format =================== Overall Message Format ------------------- ~~~~ Bytes 0 58 72 +----------+-------------+-------------------+-----------+ | HEADER | EXT_HEADER | CONTENT | META_DATA | +----------+-------------+-------------------+-----------+ ~~~~ Header + Extended Header ------------------- ~~~~ Bytes 0 2 14 34 42 50 58 +---+-----------------------+---------------------------------------+---------------+---------------+---------------+ | V | TYPE | DEVICE_NAME | TIME_STAMP | BODY_SIZE | CRC64 | +---+-----------------------+---------------------------------------+---------------+---------------+---------------+ 58 60 64 68 72 +-----------------+---------------+---------+-----------+ | EXT_HEADER_SIZE | METADATA_SIZE | MSG_ID | RESERVED | +-----------------+---------------+---------+-----------+ ~~~~ Content ------------------- The format of contenst section is type-dependent. Please see individual type definition page. Metadata ------------------- The metadata section consists of metadata header and metadata body. Metadata header: ~~~~ Bytes 0 2 4 6 10 12 14 18 +-------------+-------------+-------------------+---------------+-------------+-------------------+---------------+---- | INDEX_COUNT | KEY_SIZE_0 | VALUE_ENCODING_0 | VALUE_SIZE_0 | KEY_SIZE_1 | VALUE_ENCODING_1 | VALUE_SIZE_1 | ... +-------------+-------------+-------------------+---------------+-------------+-------------------+---------------+---- |<-------------- Metadata 0 --------------------->|<--------------- Metadata 1 -------------------->| INDEX_COUNT*8+2 ----+-------------+-------------------+---------------+ ... |KEY_SIZE_N-1 |VALUE_ENCODING_N-1 |VALUE_SIZE_N-1 | ----+-------------+-------------------+---------------+ |<----------Metadata N-1 (=INDEX_COUNT)---------->| ~~~~ Metadata body: ~~~~ Bytes +--------+---------+--------+----------+---- ----+--------+-----------+ | KEY_0 | VALUE_0 | KEY_1 | VALUE_1 | ... |KEY_N-1 | VALUE_N-1 | +--------+---------+--------+----------+---- ----+--------+-----------+ |<-- Metadata 0 -->|<-- Metadata 1 --->| |<-- Metadata N-1 -->| ~~~~ Available Message Types =================== New Messages Proposed for V3 -------------------
Type name GET query STT query STP query RTS message Description
COMMAND -- -- -- RTS_COMMAND Command
Messages from version 1 and 2 -------------------
Type name GET query STT query STP query RTS message Description
IMAGE GET_IMAGE STT_IMAGE STP_IMAGE RTS_IMAGE 2D/3D image data
TRANSFORM GET_TRANSFOR STT_TRANSFOR STP_TRANSFOR RTS_TRANSFOR Affine transform data.
POSITION GET_POSITION STT_POSITION STP_POSITION RTS_POSITION Position and orientation (quaternion)
CAPABILITY GET_CAPABIL -- -- RTS_CAPABIL Points or fiducials.
STATUS GET_STATUS -- -- RTS_STATUS Device status
TDATA GET_TDATA STT_TDATA STP_TDATA RTS_TDATA Tracking data
IMGMETA GET_IMGMETA -- -- RTS_IMGMETA List of image meta data including patient name, ID (medical record number), size, etc.
LBMETA GET_LBMETA -- -- RTS_LBMETA List of label meta data.
POINT GET_POINT -- -- RTS_POINT Points or fiducials.
TRAJ GET_TRAJ -- -- RTS_TRAJ Trajectory data (needle path etc.)
NDARRAY GET_NDARRAY STT_NDARRAY STP_NDARRAY RTS_NDARRAY Associative array to transfer a set of values with key names.
Acknowledgement =================== The version 3 propsal is drafted by the following members: * Andras Lasso, Tamas Ungi (PerkLab, Queen's University) * Christian Askeland, Ingerid Reinertsen, Ole Vegard Solberg (CustusX, IGT research, SINTEF) * Simon Drouin (Mcgill University, Montreal, Canada) * Junichi Tokuda (Brigham and Women's Hospital, Boston, MA) * Steve Pieper (Isomics, Cambridge, MA) * Adam Rankin (VASST Laboratory, Western University, Canada) * Thomas Kirchner, Janek Gröhl (MITK, DKFZ, Heidelberg, Germany) openigtlink-3.0.0/Documents/protocols/000077500000000000000000000000001501024245700200225ustar00rootroot00000000000000openigtlink-3.0.0/Documents/protocols/bind.md000077500000000000000000000215151501024245700212670ustar00rootroot00000000000000--- layout: page title: Specification > Bind header: Pages --- {% include JB/setup %} ## Summary Bind message format is designed to bind any OpenIGTLink messages into a single message. Messages bound in a BIND message are called 'child messages.' The BIND message format is useful, when one needs to care about synchronization of multiple messages (e.g. multi-channel sensors), or sending associative array (pairs of key string and value). The bind message format consists of the bind header section, which contains types and sizes of child messages, the child message name table section, and the child message body section. ## Message Types ### BIND
Data Type Description
NCMESSAGES uint16 Number of child messages
Bind Header Section
TYPE 0 char[12] Data type (OpenIGTLink Device Type string) for child message 0
DATA SIZE 0 uint 64 Data size for child message 0
...
TYPE (NCMESSAGES-1) char[12] Data type (OpenIGTLink Device Type string) for child message (NCMESSAGES-1)
DATA SIZE (NCMESSAGES-1) uint 64 Data size for child message (NCMESSAGES-1)
NAME Table Section (NULL-separated values)
NAME_TABLE_SIZE uint16 Size of name table (including the padding)
NAME 0 char[*] Name for child message 0
(null) uint8 separator
...
NAME (NCMESSAGES-1) char[*] Name for child message (NCMESSAGES-1)
(null) uint8 separator
Padding* uint8 or none padding to align DATA with WORD
Data Section
DATA 0 TYPE 0 ( SIZE 0 ) Data array for child message 0
(Padding*) uint8 or none padding to align DATA with WORD
DATA 1 TYPE 1 ( SIZE 1 ) Data array for child message 1
(Padding*) uint8 or none padding to align DATA with WORD
...
DATA (NCMESSAGES-1) TYPE NCMESSAGE-1 (SIZE NCMESSAGE-1) Data array for child message NCMESSAGE-1
Padding* uint8 or none padding to align DATA with WORD
* Padding field is inserted only if the previous field does not aligned with WORD border. ### GET_BIND GET_BIND is used to request the receiver for associative array data. If a GET_BIND message does not have a body, it requests all data.
Data Type Description
NCMESSAGES uint16 Number of elements
Bind Header Section
TYPE 0 char[12] Data type (OpenIGTLink device type string)
...
TYPE (NCMESSAGES-1) char[12] Data type (OpenIGTLink device type string)
NAME Table
NAME_TABLE_SIZE uint16 Size of name table (including the padding)
NAME 0 char[NAMELEN] Name
NULL uint 8 Separator
...
NAME (NCMESSAGES-1) char[NAMELEN (NCMESSAGES-1)] Name
NULL uint 8 Separator
### STT_BIND GET_BIND is used to request the receiver for associative array data. If a GET_BIND message does not have a body, it requests all data.
Data Type Description
RESOL uint64 Minimum interval between message (ns). Same format as TimeStamp
or
Data Type Description
RESOL uint64 Minimum interval between message (ns). Same format as TimeStamp
NCMESSAGES uint16 Number of elements
Bind Header Section
TYPE 0 char[12] Data type (OpenIGTLink device type string)
...
TYPE (NCMESSAGES-1) char[12] Data type (0: string, 1: scalar, 2: vector)
NAME Table Section (NULL-separated values)
NAME_TABLE_SIZE uint16 Size of name table (including the padding)
NAME 0 char[*] Name
(null) uint8 separator
...
NAME (NCMESSAGES-1) char[*] Name
(null) uint8 separator
### STP_BIND
Data Type Description
### RTS_BIND
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Implementations * [igtlBindMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlBindMessage.h) * [igtlBindMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlBindMessage.cxx) ## Contributors * Junichi Tokuda openigtlink-3.0.0/Documents/protocols/capability.md000077500000000000000000000034411501024245700224720ustar00rootroot00000000000000--- layout: page title: Specification > Capability header: Pages --- {% include JB/setup %} ## Summary The CAPABILITY data type lists the names of message types that the receiver can interpret. Although the OpenIGTLink protocol guarantees that any receiver can at least skip messages with unknown type and continue to interpret the following messages, it is a good idea to get the capability information at system startup to ensure application-level compatibility of various devices. In a CAPABILITY message type, each message type name comes with format version number. If the receiver can interpret multiple versions for a certain message type, they should be listed as independent types. ## Message Types ### CAPABILITY
Data Type Description
TYPE_0 unsigned char [12] Type name #0
Type_1 unsigned char [12] Type name #1
... ... ...
Type_(N-1) unsigned char [12] Type name #N-1
* Number of type names N is calculated by (Body size) / 12. ### GET_CAPABIL
Data Type Description
### STT_CAPABIL N/A ### STP_CAPABIL N/A ### RTS_CAPABIL N/A ## Implementations ## Contributors Junichi Tokuda openigtlink-3.0.0/Documents/protocols/colortable.md000077500000000000000000000030541501024245700224770ustar00rootroot00000000000000--- layout: page title: Specification > ColorTable header: Pages --- {% include JB/setup %} ## Summary COLORT is used to transfer a color table. ## Message Types ### COLORT To get the COLORT, GET_COLORT is used with the Id in the device name field.
Data Type Description
I 8-bit unsigned int Index Type (3:uint8 5:uint16)
M 8-bit unsigned int Map Type (3:uint8 5:uint16 19:RGB color)
TABLE Array of 8-bit unsigned int Color index table
### GET_COLORT
Data Type Description
### STT_COLORT N/A ### STP_COLORT N/A ### RTS_COLORT N/A ## Implementations IMGMETA message type is implemented in the following source code. * [igtlLabelMetaMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlLabelMetaMessage.h) * [igtlLabelMetaMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlLabelMetaMessage.cxx) ## Contributors * Alexander Schaal openigtlink-3.0.0/Documents/protocols/header.md000077500000000000000000000055321501024245700216040ustar00rootroot00000000000000--- layout: page title: Specification > Header --- {% include JB/setup %} Back to [Specification](../spec.html) ## Header Structure Bytes 0 2 14 34 42 50 58 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..... | V | TYPE | DEVICE_NAME | TIME_STAMP | BODY_SIZE | CRC64 | BODY +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..... ## Byte Order Big endian should be used for all [numerical values](http://www.opengroup.org/onlinepubs/007908799/xns/htonl.html) (version, body size, crc). Unused spaces are padded with 0 (binary). ## Header Fields
Data Type Description
V Unsigned short (16bit) Version number (1)
TYPE char[12] Type name of data
DEVICE_NAME char[20] Unique device name
TIME_STAMP 64 bit unsigned int Timestamp or 0 if unused
BODY_SIZE 64 bit unsigned int Size of body in bytes
CRC 64 bit unsigned int 64 bit CRC for body data
## Description of Fields ### Version number The version number field specifies the header format version. Currently the version number is *1*. Please note that this is different from the protocol version. ### Type name The type name field is an ASCII character string specifying the type of the data contained in the message body e.g. "TRANSFORM". The length of the type name must be within 12 characters. ### Device name The device name field contains an ASCII character string specifying the name of the the message. ### Timestamp The timestamp field contains a 64-bit timestamp indicating when the data is generated. Please refer [Timestamp](v2_timestamp.html) for the format of the 64-bit timestamp. ### Body size ### CRC The 64-bit CRC used in OpenIGTLink protocol is based on [ECMA-182 standard](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf). An example code is available in [igtl_util.c](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlutil/igtl_unit.h) in the OpenIGTLink library. openigtlink-3.0.0/Documents/protocols/image.md000077500000000000000000000125001501024245700214270ustar00rootroot00000000000000--- layout: page title: Specification > Image header: Pages --- {% include JB/setup %} ## Summary The IMAGE format supports 2D or 3D images with metric information including image matrix size, voxel size, coordinate system type, position, and orientation. The body section of the IMAGE data consists of two parts: image header to transfer the metric information and image body to transfer the array of pixel or voxel values. The data type of pixel or voxel can be either scalar or vector, and numerical values can be 8-, 16-, 32-bit integer, or 32- or 64-bit floating point. The pixel values can be either big-endian or little-endian, since the sender software can specify the byte order in the image header. The format also supports "partial image transfer", in which a region of the image is transferred instead of the whole image. This mechanism is suitable for real-time applications, in which images are updated region-by-region. The sub-volume must be box-shaped and defined by 6 parameters consisting of the indices for the corner voxel of the sub-volume and matrix size of the sub-volume. ## Message Types ### IMAGE
Data Type Description
V unsigned short version number
T 8bit unsigned int Number of Image Components (1:Scalar, >1:Vector). (NOTE: Vector data is stored fully interleaved.)
S 8bit unsigned int Scalar type (2:int8 3:uint8 4:int16 5:uint16 6:int32 7:uint32 10:float32 11:float64)
E 8bit unsigned int Endian for image data (1:BIG 2:LITTLE) (NOTE: values in image header is fixed to BIG endian)
O 8bit unsigned int image coordinate (1:RAS 2:LPS)
RI, RJ, RK 16 bit unsigned int Number of pixels in each direction
TX, TY, TZ 32 bit float Transverse vector (direction for 'i' index) / The length represents pixel size in 'i' direction in millimeter
SX, SY, SZ 32 bit float Transverse vector (direction for 'j' index) / The length represents pixel size in 'j' direction in millimeter
NX, NY, NZ 32 bit float Normal vector of image plane(direction for 'k' index) / The length represents pixel size in 'z' direction or slice thickness in millimeter
PX, PY, PZ 32 bit float center position of the image (in millimeter) (*)
DI, DJ, DK 16 bit unsigned int Starting index of subvolume
DRI, DRJ, DRK 16 bit unsigned int number of pixels of subvolume
IMAGE_DATA Binary image data () Image data (endian is determined by "E" field)
* NOTE 1/10/11: There was a discrepancy between the protocol document and the library. Since the library has been used by most of OpenIGTLink software, the protocol document was modified to be consistent with the library. ### GET_IMAGE
Data Type Description
### STT_IMAGE
Data Type Description
### STP_IMAGE
Data Type Description
### RTS_IMAGE
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Notes The example application of vector type is: * Vector field * Image with complex pixel values (e.g. MRI raw data) * Color image * Vector data is stored fully interleaved. For example, if you are storing RGB color image, the order should be RGBRGBRGB... (not RRR....GGG...BBB...) ## Implementations IMAGE type is implemented in the following files: * [igtlImageMessage.h](/Source/igtlImageMessage.h) * [igtlImageMessage.cxx](/Source/igtlImageMessage.cxx) ## Contributors * Junichi Tokuda openigtlink-3.0.0/Documents/protocols/imagemeta.md000077500000000000000000000056521501024245700223100ustar00rootroot00000000000000--- layout: page title: Specification > ImageMeta header: Pages --- {% include JB/setup %} ## Summary The IMGMETA message is used to transfer image meta information which are not available in IMAGE message type, such as patient name, medical record number, modality etc. An IMGMETA message can contain meta data for multiple images. This message type may be used to obtain a list of images available in the remote system, such as image database or commercial image-guided surgery (IGS) system. ## Message Types ### IMGMETA
Data Type Description
Name/Description char[64] Name or description of the image
Id char[20] Id to query the IMAGE and COLORT
Modality char[32] String which specifies the modality
Patient name char[64] Name of the patient
Patient id char[64] Id of the patient
Timestamp 64 bit unsigned Scan time, see OpenIGTLink/Timestamp
RI, RJ, RK 16 bit unsigned Number of pixels in each direction (same as in IMAGE)
S 8 bit unsigned Scalar type (e.g. 3:uint8, 5:uint16, same as in IMAGE)
-- 8 bit unsigned Reserved
* More than one item can be transmitted. The number is bodySize/itemSize. * To get the IMAGE, GET_IMAGE is used with the Id in the device name field. ### GET_IMGMETA GET_IMGMETA is used to query for meta data of image sets. If DEVICE_NAME in the header is empty, a list of meta data for all available images is returned.
Data Type Description
### STT_IMGMETA N/A ### STP_IMGMETA N/A ## Implementations IMGMETA message type is implemented in the following source code. * [igtlImageMetaMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlImageMetaMessage.h) * [igtlImageMetaMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlImageMetaMessage.cxx) ## Contributors * Alexander Schaal openigtlink-3.0.0/Documents/protocols/labelmeta.md000077500000000000000000000044661501024245700223070ustar00rootroot00000000000000--- layout: page title: Specification > LabelMeta header: Pages --- {% include JB/setup %} ## Summary The LBMETA is used to transfer meta information for lable maps, which are not available in the IMAGE message type. To retreive voxel objects or a label map, GET_IMAGE / IMAGE can be used. But the client should be able to get a list of available structures. ## Message Types ### LBMETA
Data Type Description
Name/Description char[64] Name or description of the image
Id char[20] Id to query the IMAGE
Label 8 bit unsigned int Label of structure (0 if unused)
-- 8 bit unsigned int Reserved.
R,G,B,A 8 bit unsigned Color in RGBA (0 0 0 0 if no color is defined)
RI, RJ, RK 16 bit unsigned Number of pixels in each direction (same as in IMAGE), bounding box of the structure(s)
Owner image char[20] Id of the owner image/sliceset. Voxel objects from different slicesets can be sent if slicesets are fused. Can be empty if n/a.
### GET_LBMETA
Data Type Description
### STT_LBMETA N/A ### STP_LBMETA N/A ## Implementations IMGMETA message type is implemented in the following source code. * [igtlLabelMetaMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlLabelMetaMessage.h) * [igtlLabelMetaMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlLabelMetaMessage.cxx) ## Contributors * Alexander Schaal openigtlink-3.0.0/Documents/protocols/ndarray.md000077500000000000000000000044211501024245700220100ustar00rootroot00000000000000--- layout: page title: Specification > NDArray header: Pages --- {% include JB/setup %} ## Summary NDARRAY is a data type, which is designed to transfer N-dimensional numerical array. ## Message Types ### NDARRAY
Data Type Description
TYPE UINT8 Scalar type (2:int8 3:uint8 4:int16 5:uint16 6:int32 7:uint32 10:float32 11:float64 13:complex float 64*)
DIM UINT8 Dimension of array
SIZE UINT16[DIM] Size of array
DATA TYPE[SIZE[0]][SIZE[1]]....[[SIZE[DIM-1]]] Array data. (Must be in network byte order.)
* Complex is a 128-bit variable consisting of a real part in the first 64-bit and an imaginal part in the last 64-bit. ### GET_NDARRAY
Data Type Description
### STT_NDARRAY N/A ### STP_NDARRAY N/A ### RTS_NDARRAY N / A ## Notes ### Memory layout of DATA field Like multi-dimensional array in C/C++, DATA field is laid out in sequentially in a byte stream. For example, if the value of DATA is defined by: char data[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; The layout in the byte stream can be visualized as follows: +-+-+-+-+-+-+-+-+-+ |1|2|3|4|5|6|7|8|9| +-+-+-+-+-+-+-+-+-+ ## Implementations The NDARRAY message type is implemented in the following source code. * [igtlNDArrayMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlNDArrayMessage.h) * [igtlNDArrayMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlNDArrayMessage.cxx) ## Contributors * Junichi Tokuda * Yuichiro Hayashi openigtlink-3.0.0/Documents/protocols/point.md000077500000000000000000000063651501024245700215120ustar00rootroot00000000000000--- layout: page title: Specification > ImageMeta header: Pages --- {% include JB/setup %} ## Summary The POINT message type is designed to transfer information about fiducials, which are often used in surgical planning and navigation in the image-guided therapy. ## Message Types ### POINT
Data Type Description
SENSOR_1
Name char[64] Name or description of the point
Group name char[32] Can be "Labeled Point", "Landmark", "Fiducal", ...
R,G,B,A 8 bit unsigned Color in RGBA
X,Y,Z 32 bit float Coordinate of the point in millimeter
Diameter 32 bit float Diameter of the point in millimeter. Diameter can be 0.
Owner image char[20] Id of the owner image/sliceset. Points from different slicesets can be sent if slicesets are fused.
...
SENSOR_N
Name char[64] Name or description of the point
Group name char[32] Can be "Labeled Point", "Landmark", "Fiducal", ...
R,G,B,A 8 bit unsigned Color in RGBA
X,Y,Z 32 bit float Coordinate of the point in millimeter.
Diameter 32 bit float Diameter of the point in millimeter. Diameter can be 0.
Owner image char[20] Id of the owner image/sliceset. Points from different slicesets can be sent if slicesets are fused.
### GET_POINT GET_POINT is used to query for meta data of label data. If the DEVICE_NAME field in the header is empty, a list of all available point data is returned.
Data Type Description
### STT_POINT N / A ### STP_POINT N/A ### RTS_POINT N/A ## Implementations IMGMETA message type is implemented in the following source code. * [igtlPointMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlPointMessage.h) * [igtlPointMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlPointMessage.cxx) ## Contributors * Alexander Schaal openigtlink-3.0.0/Documents/protocols/polydata.md000077500000000000000000000214761501024245700221760ustar00rootroot00000000000000--- layout: page title: Specification > PolyData header: Pages --- {% include JB/setup %} ## Summary POLYDATA is used to transfer 3D polygonal data. The message format is designed based on the [POLY DATA format](http://www.vtk.org/VTK/img/file-formats.pdf) defined in VTK file format and equivalent to [VTK's vtkPolyData class](http://noodle.med.yale.edu/vtk5/classvtkPolyData.html). The message also supports dataset attribute field in VTK, including scalars, calar_scalars, vectors, vectors, normals, texture coordinates and tensor, but not lookup table. ## Message Types ### POLYDATA
Data Type Description
NPOINTS uint32 Number of points
NVERTICES uint32 Number of vertices
SIZE_VERTICES uint32 Total size of vertices data
NLINES uint32 Number of lines
SIZE_LINES uint32 Total size of line data
NPOLYGONS uint32 Number of polygons
SIZE_POLYGONS uint32 Total size of polygon data
NTRIANGLE_STRIPS uint32 Number of triangle strips
SIZE_TRIANGLE_STRIPS uint32 Total size of triangle strips data
NATTRIBUTES uint32 Number of dataset attributes
POINTS float32 * NPOINTS * 3 Coordinates of points (P0x, P0y, P0z, P1x, P1y, P1z, ... P(n-1)x, P(n-1)y, P(n-1)z
VERTICES uint32 * ((NPOINTS_0+1) + (NPOINTS_1+1) + (NPOINTS_(N-1)+1)) array of vertices ((NPOINTS_0, index_0_0, index_0_1, ....), (NPOINTS_1, index_1_0, index_1_1, ....), ..., (NPOINTS_(N-1), index_(N-1)_0, index_(N-1)_1, ....))
LINES uint32 * ((NPOINTS_0+1) + (NPOINTS_1+1) + (NPOINTS_(N-1)+1)) array of vertices ((NPOINTS_0, index_0_0, index_0_1, ....), (NPOINTS_1, index_1_0, index_1_1, ....), ..., (NPOINTS_(N-1), index_(N-1)_0, index_(N-1)_1, ....))
POLYGONS uint32 * ((NPOINTS_0+1) + (NPOINTS_1+1) + (NPOINTS_(N-1)+1)) array of vertices ((NPOINTS_0, index_0_0, index_0_1, ....), (NPOINTS_1, index_1_0, index_1_1, ....), ..., (NPOINTS_(N-1), index_(N-1)_0, index_(N-1)_1, ....))
TRIANGLE_STRIPS uint32 * ((NPOINTS_0+1) + (NPOINTS_1+1) + (NPOINTS_(N-1)+1)) array of vertices ((NPOINTS_0, index_0_0, index_0_1, ....), (NPOINTS_1, index_1_0, index_1_1, ....), ..., (NPOINTS_(N-1), index_(N-1)_0, index_(N-1)_1, ....))
TYPE_ATTRIBUTE0 uint16 Type of dataset attribute 0 (including number of components for scalar type)
NATTRIBUTE0 uint32 Number of data for attribute 0
TYPE_ATTRIBUTE1 uint16 Type of dataset attribute 1 (including number of components for scalar type)
NATTRIBUTE1 uint32 Number of data for attribute1
... ... ...
TYPE_ATTRIBUTE(NATTRIBUTES-1) uint16 Type of dataset attribute 1 (including number of components for scalar type)
NATTRIBUTE(NATTRIBUTES-1) uint32 Number of data for attribute2
NAME_ATTRIBUTE0 char * (name length) Name of attribute 0
(null) char (null)
NAME_ATTRIBUTE1 char * (name length) Name of attribute 1
(null) char (null)
... ... ...
NAME_ATTRIBUTE(NATTRIBUTES-1) char * (name length) Name of attribute (NATTRIBUTES-1)
(null) char (null)
(Padding) char or 0 Padding (inserted if (NAMESIZE_ATTRIBUTE0+1+NAMESIZE_ATTRIBUTE1+1+...NAMESIZE_ATTRIBUTE(NATTRIBUTES-1)+1) % 2 == 1)
ATTRIBUTE0 SIZE_ATTRIBUTE0 * (number of components) * (float32) Actual attribute data
ATTRIBUTE1 NATTRIBUTE0 * (number of components) * (float32) Actual attribute data
... ... ...
ATTRIBUTE(NATTRIBUTES-1) NATTRIBUTE(NATTRIBUTES-1) * (number of components) * (float32) Actual attribute data
* Values for TYPE_ATTRIBUTE (16-bit) * 0-7 bit: Attribute Type: * 0x00: POINT_DATA / Scalars * 0x01: POINT_DATA / Vectors * 0x02: POINT_DATA / Normals * 0x03: POINT_DATA / Tensors * 0x04: POINT_DATA / RGBA * 0x10: CELL_DATA / Scalars * 0x11: CELL_DATA / Vectors * 0x12: CELL_DATA / Normals * 0x13: CELL_DATA / Tensors * 0x14: CELL_DATA / RGBA * 8-15 bit: Number of components -- must be 3 for Vectors and Normal, 9 for Tensor, 4 for RGBA. * Maximum length for attribute name is 255 * If there are a pair of scalar and RGBA data with the same name and type (either POINT or CELL), those are used as scalar values and a look up table. * elements in RGBA data must be in the rage of \[0.0, 1.0\] ### GET_POLYDATA
Data Type Description
### STT_POLYDATA
Data Type Description
or
Data Type Description
RESOL uint64 Minimum interval between message (ns). Same format as TimeStamp
### STP_POLYDATA
Data Type Description
### RTS_POLYDATA
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Implementations The POLYDATA message type is implemented in the following source code. * [igtlPolyDataMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlPolyDataMessage.h) * [igtlPolyDataMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlPolyDataMessage.cxx) ## Contributors * Junichi Tokuda openigtlink-3.0.0/Documents/protocols/position.md000077500000000000000000000057511501024245700222230ustar00rootroot00000000000000--- layout: page title: Specification > Position header: Pages --- {% include JB/setup %} ## Summary The POSITION data type is used to transfer position and orientation information. The data are a combination of 3-dimensional vector for the position and quaternion for the orientation. Although equivalent position and orientation can be described with the TRANSFORM data type, the POSITION data type has the advantage of smaller data size (19%). It is therefore more suitable for pushing high frame-rate data from tracking devices. ## Message Types ### POSITION
Data Type Description
X 32-bit float X position in millimeter
Y 32-bit float Y position in millimeter
Z 32-bit float Z position in millimeter
OX 32-bit float X element in quaternion
OY 32-bit float Y element in quaternion
OZ 32-bit float Z element in quaternion
W 32-bit float W element in quaternion
### GET_POSITION
Data Type Description
### STT_POSITION
Data Type Description
### STP_POSITION
Data Type Description
### RTS_POSITION
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Implementations POSITION type is implemented in the following files: * [igtlPositionMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlPositionMessage.h) * [igtlPositionMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlPositionMessage.cxx) ## Contributors * Junichi Tokudaopenigtlink-3.0.0/Documents/protocols/qtrackingdata.md000077500000000000000000000102101501024245700231560ustar00rootroot00000000000000--- layout: page title: Specification > QTrackingData header: Pages --- {% include JB/setup %} ## Summary The QTDATA message type is intended for transferring 3D positions of surgical tools, markers etc. Its role is almost identical to TDATA, except that QTDATA describes orientation by using quaternion. ## Message Types ### QTDATA
Data Type Description
NAME_1 char[32] Name (=Id) of the instrument/tracker
TYPE_1 8 bit unsigned 1: tracker, 2: 6D instrument (regular instrument), 3: 3D instrument (only tip of the instrument defined), 4: 5D instrument (tip and handle are defined, but not the normal vector)
-- 8 bit unsigned Reserved
POSITION_1 float32[3] (X, Y, Z)
QUATERNION_1 float32[4] Quaternion (QX, QY, QZ, W)
...
NAME_N char[32] Name (=Id) of the instrument/tracker
TYPE_N 8 bit unsigned 1: tracker, 2: 6D instrument (regular instrument), 3: 3D instrument (only tip of the instrument defined), 4: 5D instrument (tip and handle are defined, but not the normal vector)
-- 8 bit unsigned Reserved
POSITION_N float32[3] (X, Y, Z)
QUATERNION_N float32[4] Quaternion (QX, QY, QZ, W)
* Feb 2, 2011: The length of the coordinate system field was corrected. (It should be the same as TDATA.) ### GET_QTDATA
Data Type Description
### STT_QTDATA
Data Type Description
Resolution 32 bit unsigned Minimum time between two frames. Use 0 for as fast as possible. If e.g. 50 ms is specified, the maximum update rate will be 20 Hz.
Coordinate system name char[32] Coordinate system to use. Can be empty for default coordinate system. (not included if action = 2)
### STP_QTDATA
Data Type Description
### RTS_QDATA
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Implementations * [igtlQuaternionTrackingDataMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlQuaternionTrackingDataMessage.h) * [igtlQuaternionTrackingDataMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlQuaternionTrackingDataMessage.cxx) ## Contributors * Alexander Schaal openigtlink-3.0.0/Documents/protocols/qtransform.md000077500000000000000000000056461501024245700225560ustar00rootroot00000000000000--- layout: page title: Specification > QTransform header: Pages --- {% include JB/setup %} ## Summary The QTRANS data type is used to transfer position and orientation information. The data are a combination of 3-dimensional vector for the position and quaternion for the orientation. Although equivalent position and orientation can be described with the TRANSFORM data type, the QTRANS data type has the advantage of smaller data size (19%). It is therefore more suitable for pushing high frame-rate data from tracking devices. ## Message Types ### TRANSFORM
Data Type Description
X 32-bit float X position in millimeter
Y 32-bit float Y position in millimeter
Z 32-bit float Z position in millimeter
OX 32-bit float X element in quaternion
OY 32-bit float Y element in quaternion
OZ 32-bit float Z element in quaternion
W 32-bit float W element in quaternion


### GET_QTRANS
Data Type Description
### STT_QTRANS
Data Type Description
### STP_QTRANS
Data Type Description
### RTS_QTRANS
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Implementations QTRANS type is implemented in the following files: * [igtlPositionMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlPositionMessage.h) * [igtlPositionMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlPositionMessage.cxx) ## Contributors Junichi Tokuda openigtlink-3.0.0/Documents/protocols/query.md000077500000000000000000000027651501024245700215260ustar00rootroot00000000000000--- layout: page title: Specification > Query header: Pages --- {% include JB/setup %} ## Simple Querying Mechanism in OpenIGTLink Protocol version 2 In OpenIGTLink version 2, special prefixes GET_, STT_, STP_, and RTS_ are used in the message type field in the header for messages to query and control data flow. Those messages with those special prefix should be defined along with primary message types (for example, STT_TDATA, STP_TDATA and RTS_TDATA should be defined with TDATA). ## GET_ prefix: Query a single message "GET_<datatype>" query message is used to request for a single message with type <datatype>. The receiver of "GET_<datatype>" message must return a message with type <datatype> and the same name as the query message. A "GET_<datatype>" message without device name requests any available data. If data is not available, a returned message must be null body (data size = 0). A format of "GET_<datatype>" may be defined per data type, if necessary. ## STT_ and STP_ prefixes: Control data flow "STT_<datatype>" and "STP_<datatype>" query message is used to request to start and stop sending a series of messages. The receiver of "STT_<datatype>" or "STP_<datatype>" message must return "RTS_<datatype>" message with the same name as the query message to notify that the receiver receives the query. Formats of "STT_<datatype>", "STP_<datatype>" and "RTS_<datatype>" may be defined per data type, if necessary. openigtlink-3.0.0/Documents/protocols/sensordata.md000077500000000000000000000105531501024245700225160ustar00rootroot00000000000000--- layout: page title: Specification > SensorData header: Pages --- {% include JB/setup %} ## Summary SENSOR is a message type, which is used to transfer sensor reading, 3-axis position, velocity, acceleration, angle, angle velocity and angle acceleration. The message format is intended for manipulator control and various types of sensors. ## Message Types ### SENSOR
Data Type Description
LARRAY uint8 Length of array (0-255)
STATUS uint8 Sensor status (Reserved)
UNIT uint64 See 64-bit UNIT field.
DATA float64[LARRAY] value array for sensor 0
### GET_SENSOR
Data Type Description
### STT_SENSOR
Data Type Description
or
Data Type Description
RESOL uint64 Minimum interval between message (ns). Same format as TimeStamp
### STP_SENSOR
Data Type Description
### RTS_SENSOR
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Implementations The TDATA message type is implemented in the following source code. * [igtlSensorMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlSensorMessage.h) * [igtlSensorMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlSensorMessage.cxx) ## Contributors * Junichi Tokuda * Yuichiro Hayashi ## Examples ### Sending 3-axis troque A device with 3-axis torque (N\*m) sensor is sending data to a data logger program. The following table shows example data format to send 3-axis torque:
Data Type Value
LARRAY uint8 3
STATUS uint8 0
UNIT uint64 00000010 11000000 00010000 00000000 00000000 00000000 00000000 00000000
DATA double[3] {0.0, 0.0, 0.0}
### Sending 3-axis force, troque and acceleration By binding SENSOR data using BIND type, values from multiple types of sensors can be transferred simultaneously. See [BIND](v2_bind.html) message description page for detail. openigtlink-3.0.0/Documents/protocols/status.md000077500000000000000000000060411501024245700216730ustar00rootroot00000000000000--- layout: page title: Specification > Status header: Pages --- {% include JB/setup %} ## Summary The STATUS data type is used to notify the receiver about the current status of the sender. The data consist of status code in a 16-bit unsigned integer, sub code in a 64-bit integer, error name in a 20-byte-length character string, and a status message. The length of the status message is determined by the size information in the general header. The status code is defined as a part of the OpenIGTLink protocol specification listed bellow. The sub code is device specific and is defined by developers. In addition, developers can build their own error name/code into the status message and additional optional description in the following data field. ## Message Types ### STATUS
Data Type Description
C Unsigned short (16bit) Status code groups: 1-Ok, 2-Generic Error, ... (see below)
Sub Code 64 bit integer Sub code for the error (ex. 0x200 - file not found)
Error name char[20] "Error", "OK", "Warning" - can be anything, don't relay on this
Status Message (optional) char[ BodySize - 30 ] Optional (English) description (ex. "File C:\test.ini not found")
### Status codes: (7/6/2013: The list was updated due to the discrepancy between this document and the actual specification.) - 00: Invalid packet - 0 is not used - 01: OK (Default status) - 02: Unknown error - 03: Panic mode (emergency) - 04: Not found (file, configuration, device etc) - 05: Access denied - 06: Busy - 07: Time out / Connection lost - 08: Overflow / Can't be reached - 09: Checksum error - 10: Configuration error - 11: Not enough resource (memory, storage etc) - 12: Illegal/Unknown instruction (or feature not implemented / Unknown command received) - 13: Device not ready (starting up) - 14: Manual mode (device does not accept commands) - 15: Device disabled - 16: Device not present - 17: Device version not known - 18: Hardware failure - 19: Exiting / shut down in progress ### GET_STATUS
Data Type Description
### STT_STATUS N/A ### STP_STATUS N/A ### RTS_STATUS N/A ## Implementations POSITION type is implemented in the following files: * [igtlStatusMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlStatusMessage.h) * [igtlStatusMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlStatusMessage.cxx) ## Contributors * Junichi Tokudaopenigtlink-3.0.0/Documents/protocols/string.md000077500000000000000000000033641501024245700216630ustar00rootroot00000000000000--- layout: page title: Specification > Image header: Pages --- {% include JB/setup %} ## Summary STRING message type is used for transferring a character string. It supports character strings up to 65535 bytes. ## Message Types ### STRING
Data Type Description
ENCODING uint16 Character encoding type as MIBenum value (defined by IANA). Default=3.
LENGTH uint16 Length of string (bytes)
STRING uint8[LENGTH] Byte array of the string
* For character encoding, please refer [IANA Character Sets](http://www.iana.org/assignments/character-sets). US-ASCII (ANSI-X3.4-1968; MIBenum = 3) is strongly recommended. ### GET_STRING
Data Type Description
### STT_STRING N/A ### STP_STRING N/A ### RTS_STRING N/A ## Implementations The TDATA message type is implemented in the following source code. * [igtlStringMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlStringMessage.h) * [igtlStringMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlStringMessage.cxx) ## Contributors * Junichi Tokuda openigtlink-3.0.0/Documents/protocols/summary.md000077500000000000000000000144741501024245700220560ustar00rootroot00000000000000--- layout: page title: Specification > Version 2 Summary header: Pages --- {% include JB/setup %} ## Overview The OpenIGTLink Protocol is ideal for building a research prototype system, because of its simple and standardized specification that requires less effort on design and development of communication mechanism for systems integration. By using OpenIGTLink, developers can save their time for more essential part of research. The OpenIGTLink's simple specification has been well accepted by the community, resulting a number of applications in the IGT research community, since it's initial release in early 2008. While we keep the protocol as simple as possible, it is also important to support as many IGT devices as possible to maximize the connectivity among software and devices, which potentially frees the developers from tedious coding just for system integration. There have been a number of feature requests that would benefit many IGT research projects, such as connectivity with commercial products, and connectivity with other major research tools, such as MATLAB. To respond to those request, and to increase the number of potential applications, we decided review the requests and release version 2 protocol during NA-MIC Summer Project Week 2010. The new protocol defines a set of new message types with new querying scheme, while maintaining a backward compatibility with version 1. This page summarizes the features in version 2. ## Simple Query Scheme OpenIGTLink V.2 defines a simple querying scheme on top of the existing message format, by introducing a few prefix to the device type field. ## Request a single message A client can request to send data contained in a single message, by issuing a query message with a device type string starting with "GET_". If specified data is not available, a message with a device type string starting with "RTS_" is returned. For example, when a client requests an IMAGE message to a server, it sends GET_IMAGE message to the server as a query. If the image exist, an IMAGE message is returned from the server to the client. Otherwise, a RTS_IMAGE message with error code is returned. ## Request a stream of messages (introduced in version 2) A client can start and stop data streaming (sent as a series of messages) from a server, by issuing a query message with a device type starting with "STT_" and "STP_" respectively. If data requested by a "STT_" message is not available, the server returns a message with a device type string starting with "RTS_" prefix. A STP_ message is also acknowledged by a "RTS_" message. This is useful to start and stop position tracking or real-time imaging remotely from the client. For example, once the server receives "STT_TDATA" message from the client, it start sending "TDATA" messages to the client. The server keep sending "TDATA" messages until it receives "STP_TDATA" from the client. ## New message types The following tables show lists of message types available in version 2. ### New Messages for image-guided systems
Type name GET query STT query STP query RTS message Description
TDATA GET_TDATA STT_TDATA STP_TDATA RTS_TDATA Tracking data
IMGMETA GET_IMGMETA -- -- RTS_IMGMETA List of image meta data including patient name, ID (medical record number), size, etc.
LBMETA GET_LBMETA -- -- RTS_LBMETA List of label meta data.
POINT GET_POINT -- -- RTS_POINT Points or fiducials.
TRAJ GET_TRAJ -- -- RTS_TRAJ Trajectory data (needle path etc.)
### New Messages for general applications
Type name GET query STT query STP query RTS message Description
NDARRAY GET_NDARRAY STT_NDARRAY STP_NDARRAY RTS_NDARRAY Associative array to transfer a set of values with key names.
### Messages from version 1
Type name GET query STT query STP query RTS message Description
IMAGE GET_IMAGE STT_IMAGE STP_IMAGE RTS_IMAGE 2D/3D image data
TRANSFORM GET_TRANSFOR STT_TRANSFOR STP_TRANSFOR RTS_TRANSFOR Affine transform data.
POSITION GET_POSITION STT_POSITION STP_POSITION RTS_POSITION Position and orientation (quaternion)
CAPABILITY GET_CAPABIL -- -- RTS_CAPABIL Points or fiducials.
STATUS GET_STATUS -- -- RTS_STATUS Device status
openigtlink-3.0.0/Documents/protocols/timestamp.md000077500000000000000000000035611501024245700223570ustar00rootroot00000000000000--- layout: page title: Specification > Timestamp --- {% include JB/setup %} Back to [Header](v2_header.html) ## Timestamp field summary * *Big Endian format:* bits numbered in big-endian fashion from 0 starting at the left, or high-order, position. * *Seconds and fraction of seconds:* timestamps are represented as a 64-bit unsigned fixed-point number, in seconds relative to 00:00:00 January 1, 1970, UTC. The integer part is in the first 32 bits (Unix-style timestamp) and the fraction part in the last 32 bits. In the fraction part, the non-significant low order can be set to 0. * *Wrap around:* The first 32-bit field will overflow some time in 2106 (second 4,294,967,296) ## Obtaining timestamp * [itk::RealTimeClock](http://www.itk.org/Doxygen34/html/classitk_1_1RealTimeClock.html) * *Linux* / *Mac*: [ftime()](http://man7.org/linux/man-pages/man3/ftime.3.html) * *Windows*: [ftime() - 10 ms resolution](http://msdn.microsoft.com/en-us/library/z54t9z5f.aspx) * *Old Timestamp* - 1 sec resoultion: Now, [Time](http://msdn2.microsoft.com/en-us/library/1f4c8f33.aspx), Timer * *System time* - 10 msec resolution: GetTickCount, [GetTickCount64](http://msdn2.microsoft.com/en-us/library/ms724411.aspx) or [timeGetTime()](http://msdn2.microsoft.com/en-us/library/ms713418.aspx) * *Highres* - hardware dependent: [QueryPerformanceCounter](http://msdn2.microsoft.com/en-us/library/ms644904.aspx) (Intel IA32 instruction: [RDTSC](http://www.intel.com/design/pentium4/manuals/245471.htm)) ## Time synchronization Two solutions: 0. Install NTP on all devices 0. Compute timestamp differences (local NTP can be used) ## Resources * NTP4 Timestamp: [RFC 2030](http://www.faqs.org/rfcs/rfc2030.html) and [RFC 1305](http://www.faqs.org/rfcs/rfc1305.html). (See "3. NTP Timestamp Format") * [Obtaining Accurate Timestamps under Windows XP](http://www.lochan.org/2005/keith-cl/useful/win32time.html) openigtlink-3.0.0/Documents/protocols/trackingdata.md000077500000000000000000000113051501024245700230030ustar00rootroot00000000000000--- layout: page title: Specification > TrackingData header: Pages --- {% include JB/setup %} ## Summary The TDATA message type is intended for transferring 3D positions of surgical tools, markers etc. Those positions are often measured by optical, electromagnetic or other type of 3D position sensor continuously and transferred as series of messages. Since it is important for software that receives TDATA to control data flow, STT_TDATA query data type has interval field to control the frame rate of consecutive messages. ## Message Types ### TDATA
Data Type Description
NAME_1 char[20] Name (=Id) of the instrument/tracker
TYPE_1 8 bit unsigned 1: tracker, 2: 6D instrument (regular instrument), 3: 3D instrument (only tip of the instrument defined), 4: 5D instrument (tip and handle are defined, but not the normal vector)
-- 8 bit unsigned Reserved
MATRIX_1 32 bit float 12 values like in TRANSFORM message
...
NAME_N char[20] Name (=Id) of the instrument/tracker
TYPE_N 8 bit unsigned 1: tracker, 2: 6D instrument (regular instrument), 3: 3D instrument (only tip of the instrument defined), 4: 5D instrument (tip and handle are defined, but not the normal vector)
-- 8 bit unsigned Reserved
MATRIX_N 32 bit float 12 values like in TRANSFORM message
### GET_TDATA
Data Type Description
### STT_TDATA
Data Type Description
Resolution 32 bit unsigned Minimum time between two frames. Use 0 for as fast as possible. If e.g. 50 ms is specified, the maximum update rate will be 20 Hz.
Coordinate system name char[32] Coordinate system to use. Can be empty for default coordinate system. (not included if action = 2)
* All tracking data from one frame is included. * Invisible/unavailable trackers/instruments are not included. * Easy to develop. Sample pseudo code: while(true) { recv(trackingdata); updateView(trackingdata); } * Usually the tracking data will be sent using the standard coordinate system, which is also used for POINT, IMAGE, ... But this does only work after patient registration. Therefore the body of START_PUSH has an optional field for specifing the coordinate system "CAMERA". To switch back to the standard coordinate system, one has to send STOP_PUSH and afterwards START_PUSH without explicitly specifing the camera coordinate system. ### STP_TDATA
Data Type Description
### RTS_TDATA
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Implementations The TDATA message type is implemented in the following source code. * [igtlTrackingDataMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlTrackingDataMessage.h) * [igtlTrackingDataMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlTrackingDataMessage.cxx) ## Contributors * Alexander Schaal openigtlink-3.0.0/Documents/protocols/trajectory.md000077500000000000000000000047051501024245700225430ustar00rootroot00000000000000--- layout: page title: Specification > Trajectory header: Pages --- {% include JB/setup %} ## Summary The TRAJECTORY message type support to transfer information about 3D trajectory, which is often used in surgical planning and guidance in image-guided therapy. ## Message Types ### TRAJ
Data Type Description
Name char[64] Name or description of the trajectory.
Group name char[32] Can be "Trajectory", ...
Type 8 bit unsigned 1: trajectory with only entry point, 2: trajectory with only target point, 3: trajectory with entry and target point
-- 8 bit unsigned Reserved
R,G,B,A 8 bit unsigned Color in RGBA
X1,Y1,Z1 32 bit float Entry point of the trajectory
X2,Y2,Z2 32 bit float Target point of a trajectory
Diameter 32 bit float Diameter of trajectory, can be 0
Owner image char[20] Id of the owner image/sliceset. Trajectories from different slicesets can be sent if slicesets are fused.
### GET_TRAJ
Data Type Description
### STT_TRAJ N/A ### STP_TRAJ N/A ## Implementations TRAJECTORY message type is implemented in the following source code. * [igtlTrajectoryMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlTrajectoryMessage.h) * [igtlTrajectoryMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlTrajectoryMessage.cxx) ## Contributors * Alexander Schaal openigtlink-3.0.0/Documents/protocols/transform.md000077500000000000000000000100101501024245700223520ustar00rootroot00000000000000--- layout: page title: Specification > Transform header: Pages --- {% include JB/setup %} Back to [Specification](../spec.html) ## Summary The TRANSFORM data type is used to transfer a homogeneous linear transformation in 4-by-4 matrix form. One such matrix was shown earlier in equation (1). Note that if a device is sending only translation and rotation, then TRANSFORM is equivalent to POSITION. But TRANSFORM can also be used to transfer affine transformations or simple scaling. Like IMAGE and POSITION, TRANSFORM carries information about the coordinate system used. ## Message Types ### TRANSFORM
Data Type Description
R11 32-bit float Element (1, 1) in 4-by-4 linear transformation matrix
R21 32-bit float Element (2, 1) in 4-by-4 linear transformation matrix
R31 32-bit float Element (3, 1) in 4-by-4 linear transformation matrix
R12 32-bit float Element (1, 2) in 4-by-4 linear transformation matrix
R22 32-bit float Element (2, 2) in 4-by-4 linear transformation matrix
R32 32-bit float Element (3, 2) in 4-by-4 linear transformation matrix
R13 32-bit float Element (1, 3) in 4-by-4 linear transformation matrix
R23 32-bit float Element (2, 3) in 4-by-4 linear transformation matrix
R33 32-bit float Element (3, 3) in 4-by-4 linear transformation matrix
TX 32-bit float Element (1, 4) in 4-by-4 linear transformation matrix (translation along x-axis in millimeter)
TY 32-bit float Element (2, 4) in 4-by-4 linear transformation matrix (translation along y-axis in millimeter)
TZ 32-bit float Element (3, 4) in 4-by-4 linear transformation matrix (translation along z-axisin millimeter)
### GET_TRANS
Data Type Description
### STT_TRANS
Data Type Description
### STP_TRANS
Data Type Description
### RTS_TRANS
Data Type Description
Status 8 bit unsigned 0: Success 1: Error
## Implementations IMAGE type is implemented in the following files: * [igtlTransformMessage.h](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlTransformMessage.h) * [igtlTransformMessage.cxx](https://github.com/openigtlink/OpenIGTLink/blob/master/Source/igtlTransformMessage.cxx) ## Contributors * Junichi Tokuda openigtlink-3.0.0/Documents/protocols/unit.md000077500000000000000000000177411501024245700213400ustar00rootroot00000000000000--- layout: page title: Specification > Unit header: Pages --- {% include JB/setup %} SENSOR message can handle a part of unites defined in The International System of Unites (SI) in its 8-byte (or 64-bit) field. The field is designed to specifiy a unit consisting of SI-prefix (e.g. milli, micro, kilo etc...) and combination of SI-base and/or SI-derived unites. The bites in the field are assigned as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... |PREFIX | UNIT0 | EXP0 | UNIT1 | EXP1 | UNIT2 | EXP2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... 0 1 2 3 4 ...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ EXP2 | UNIT3 | EXP3 | UNIT4 | EXP4 | UNIT5 | EXP5 | ...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4 5 6 7 ### PREFIX (4bit)
Value SI-prefix Value SI-prefix
0x0 None -- --
0x1 deka (deca) (1e1) 0x9 deci (1e-1)
0x2 hecto (1e2) 0xA centi (1e-2)
0x3 kilo (1e3) 0xB milli (1e-3)
0x4 mega (1e6) 0xC micro (1e-6)
0x5 giga (1e9) 0XD nano (1e-9)
0x6 tera (1e12) 0XE pico (1e-12)
0x7 peta (1e15) 0XF femto (1e-15)
### UNIT(6bit)
Value SI base unit name Value SI base unit name
0x01 meter 0x05 kelvin
0x02 gram 0x06 mole
0x03 second 0x07 candela
0x04 ampere -- --
### UNIT(6bit) SI base units
Value SI base unit name Value SI base unit name
0x01 meter 0x05 kelvin
0x02 gram 0x06 mole
0x03 second 0x07 candela
0x04 ampere -- --
SI derived units
Value Unit name dimension Value Unit name dimension
0x08 radian meter/meter 0x12 ohm meter^2-kilogram/second^3-ampere^2
0x09 steradian meter^2/meter^2 0x13 siemens second^3-ampere^2/meter^2-kilogram
0x0A hertz /second 0x14 weber meter^2-kilogram/second^2-ampere
0x0B newton meter-kilogram/second^2 0x15 tesla kilogram/second^2-ampere
0x0C pascal kilogram/meter-second^2 0x16 henry meter^2-kilogram/second^2-ampere^2
0x0D joule meter^2-kilogram/second^2 0x17 lumen candela-steradian
0x0E watt meter^2-kilogram/second^3 0x18 lux candela-steradian/meter^2
0x0F coulomb second-ampere 0x19 becquerel /second
0x10 volt meter^2-kilogram/second^3-ampere 0x1A gray meter^2/second^2
0x11 farad second^4-ampere^2/meter^2-kilogram 0x1B sievert meter^2/second^2
EXP (4-bit)
Value Exponent Value Exponent
0x0 ^0 -- --
0x1 ^1 0xF ^-1
0x2 ^2 0xE ^-2
0x3 ^3 0xD ^-3
0x4 ^4 0xC ^-4
0x5 ^5 0XB ^-5
0x6 ^6 0XA ^-6
0x7 ^7 0X9 ^-7
openigtlink-3.0.0/Documents/protocols/v3_proposal.md000077500000000000000000000216461501024245700226270ustar00rootroot00000000000000--- layout: page title: Specification > Version 3 Proposal header: Pages --- {% include JB/setup %} ## Background Since the release of version 2 protocol, we have learned that the protocol has several limitations: * While the naming convention for querying (i.e. GET_, STT_, STP_, and RTS_ prefixes) in version 2 provides a standardized way to identify query and response messages, there is still no standard way to manage multiple queries simaltaneously. This is mainly due to the lack of mechanism to reference the original query message from the response message. One workaround is to embed a unique message ID in the device names of query and response messages (e.g. "GET_STATUS_1234" and "RTS_STATUS_1234"). This approach requires the receiver process to parse the device name every time it receives a message, and reduces the actual length of device name. * When developers design new message exchange schemes for specific applications, they often need to attach some application-specific information to the existing data types. While it can be achieved by bundling the data message with string messages using a BIND message, it is not ideal from the performance aspect. It would make more sense to have a way to add custom 'tags' to any messages. ## Overview of Version 3 Proposal At [Winter Project Week 2016](http://wiki.na-mic.org/Wiki/index.php/2016_Winter_Project_Week/Projects/TrackedUltrasoundStandardization) (January 5-9, 2016, Cambridge, MA), we discussed the limitations above, and potential extension to the existing protocols _with backward compatibility_. The following changes were proposed: * A new message structure. The body in the former protocol was splitted into extended header, content, and metadata. The message now consists of the following sections: * Header (58 bytes) * Extended Header (variable length) * Content (variable length) * Metadata (variable length) * The _header_ section has the same format as version 2 protocol, and should contain the following information: * The header version (the first two bytes) will be incremented to '0x0002' * The Body size is the total byte size for the extended header, content, and Metadata. This will allow old clients to skip the entire message and read the sucessive message properly. * The other fields are filled in the same as the previous version. * The _extended header_ section contains the following fields: * Extended header size (EXT_HEADER_SIZE) (2 bytes) * Metadata size (METADATA_SIZE) (2 bytes) * Message ID (MSG_ID) (4 bytes) * The _content_ section is equivalent to the body section in the previous version. * The size of content can be computed as: BODY_SIZZE - (EXT_HEADER_SIZE + METADAT_SIZE) * The _metadata_ section contains pairs of 'key' and 'value' strings. Keys are ASCII string, while values can be stored using different encodings. ## Messaging Format ### Overall Message Format Bytes 0 58 72 +----------+-------------+-------------------+-----------+ | HEADER | EXT_HEADER | CONTENT | META_DATA | +----------+-------------+-------------------+-----------+ ### Header + Extended Header Bytes 0 2 14 34 42 50 58 +---+-----------------------+---------------------------------------+---------------+---------------+---------------+ | V | TYPE | DEVICE_NAME | TIME_STAMP | BODY_SIZE | CRC64 | +---+-----------------------+---------------------------------------+---------------+---------------+---------------+ 58 60 64 68 72 +-----------------+---------------+---------+-----------+ | EXT_HEADER_SIZE | METADATA_SIZE | MSG_ID | RESERVED | +-----------------+---------------+---------+-----------+ ### Content The format of contenst section is type-dependent. Please see individual type definition page. ### Metadata The metadata section consists of metadata header and metadata body. Metadata header: Bytes 0 2 4 6 10 12 14 18 +-------------+-------------+-------------------+---------------+-------------+-------------------+---------------+---- | INDEX_COUNT | KEY_SIZE_0 | VALUE_ENCODING_0 | VALUE_SIZE_0 | KEY_SIZE_1 | VALUE_ENCODING_1 | VALUE_SIZE_1 | ... +-------------+-------------+-------------------+---------------+-------------+-------------------+---------------+---- |<-------------- Metadata 0 --------------------->|<--------------- Metadata 1 -------------------->| INDEX_COUNT*8+2 ----+-------------+-------------------+---------------+ ... |KEY_SIZE_N-1 |VALUE_ENCODING_N-1 |VALUE_SIZE_N-1 | ----+-------------+-------------------+---------------+ |<----------Metadata N-1 (=INDEX_COUNT)---------->| Metadata body: Bytes +--------+---------+--------+----------+---- ----+--------+-----------+ | KEY_0 | VALUE_0 | KEY_1 | VALUE_1 | ... |KEY_N-1 | VALUE_N-1 | +--------+---------+--------+----------+---- ----+--------+-----------+ |<-- Metadata 0 -->|<-- Metadata 1 --->| |<-- Metadata N-1 -->| ## Available Message Types ### New Messages Proposed for V3
Type name GET query STT query STP query RTS message Description
COMMAND -- -- -- RTS_COMMAND Command
### Messages from version 1 and 2
Type name GET query STT query STP query RTS message Description
IMAGE GET_IMAGE STT_IMAGE STP_IMAGE RTS_IMAGE 2D/3D image data
TRANSFORM GET_TRANSFOR STT_TRANSFOR STP_TRANSFOR RTS_TRANSFOR Affine transform data.
POSITION GET_POSITION STT_POSITION STP_POSITION RTS_POSITION Position and orientation (quaternion)
CAPABILITY GET_CAPABIL -- -- RTS_CAPABIL Points or fiducials.
STATUS GET_STATUS -- -- RTS_STATUS Device status
TDATA GET_TDATA STT_TDATA STP_TDATA RTS_TDATA Tracking data
IMGMETA GET_IMGMETA -- -- RTS_IMGMETA List of image meta data including patient name, ID (medical record number), size, etc.
LBMETA GET_LBMETA -- -- RTS_LBMETA List of label meta data.
POINT GET_POINT -- -- RTS_POINT Points or fiducials.
TRAJ GET_TRAJ -- -- RTS_TRAJ Trajectory data (needle path etc.)
NDARRAY GET_NDARRAY STT_NDARRAY STP_NDARRAY RTS_NDARRAY Associative array to transfer a set of values with key names.
## Acknowledgement The version 3 propsal is drafted by the following members: * Andras Lasso, Tamas Ungi (PerkLab, Queen's University) * Christian Askeland, Ingerid Reinertsen, Ole Vegard Solberg (CustusX, IGT research, SINTEF) * Simon Drouin (Mcgill University, Montreal, Canada) * Junichi Tokuda (Brigham and Women's Hospital, Boston, MA) * Steve Pieper (Isomics, Cambridge, MA) * Adam Rankin (VASST Laboratory, Western University, Canada) * Thomas Kirchner, Janek Gröhl (MITK, DKFZ, Heidelberg, Germany) openigtlink-3.0.0/Examples/000077500000000000000000000000001501024245700156135ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Bind/000077500000000000000000000000001501024245700164675ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Bind/BindClient.cxx000066400000000000000000000076421501024245700212370ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlBindMessage.h" #include "igtlStringMessage.h" #include "igtlTransformMessage.h" #include "igtlClientSocket.h" #define N_STRINGS 5 const char * testString[N_STRINGS] = { "OpenIGTLink", "Network", "Communication", "Protocol", "Image Guided Therapy", }; void GetRandomTestMatrix(igtl::Matrix4x4& matrix); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 4) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Child Message Classes (String and Transform) igtl::StringMessage::Pointer stringMsg; stringMsg = igtl::StringMessage::New(); igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); //------------------------------------------------------------ // Allocate Bind message class igtl::BindMessage::Pointer bindMsg; bindMsg = igtl::BindMessage::New(); //------------------------------------------------------------ // loop int i = 0; while (1) { stringMsg->SetDeviceName("StringMessage"); stringMsg->SetString(testString[i]); stringMsg->Pack(); transMsg->SetDeviceName("Tracker"); igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix); transMsg->SetMatrix(matrix); transMsg->Pack(); bindMsg->Init(); bindMsg->SetDeviceName("BindMessage"); bindMsg->AppendChildMessage(stringMsg); bindMsg->AppendChildMessage(transMsg); bindMsg->Pack(); socket->Send(bindMsg->GetPackPointer(), bindMsg->GetPackSize()); igtl::Sleep(interval); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestMatrix(igtl::Matrix4x4& matrix) { float position[3]; float orientation[4]; // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); phi = phi + 0.2; // random orientation static float theta = 0.0; orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; //igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Bind/BindServer.cxx000066400000000000000000000061551501024245700212650ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlTransformMessage.h" #include "igtlServerSocket.h" void GetRandomTestMatrix(igtl::Matrix4x4& matrix); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; exit(0); } int port = atoi(argv[1]); double fps = atof(argv[2]); int interval = (int) (1000.0 / fps); igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); transMsg->SetDeviceName("Tracker"); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix); transMsg->SetMatrix(matrix); transMsg->Pack(); socket->Send(transMsg->GetPackPointer(), transMsg->GetPackSize()); igtl::Sleep(interval); // wait } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } void GetRandomTestMatrix(igtl::Matrix4x4& matrix) { float position[3]; float orientation[4]; // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); phi = phi + 0.2; // random orientation static float theta = 0.0; orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; //igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Bind/CMakeLists.txt000066400000000000000000000006101501024245700212240ustar00rootroot00000000000000PROJECT(Bind) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(BindClient BindClient.cxx) TARGET_LINK_LIBRARIES(BindClient OpenIGTLink) #ADD_EXECUTABLE(BindServer BindServer.cxx) #TARGET_LINK_LIBRARIES(BindServer OpenIGTLink) openigtlink-3.0.0/Examples/CMakeLists.txt000066400000000000000000000012611501024245700203530ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.4) # # Examples # SET(EXAMPLE_DIRS Tracker Imager Status Receiver Thread ) if (${OpenIGTLink_PROTOCOL_VERSION} GREATER 1) SET(EXAMPLE_DIRS ${EXAMPLE_DIRS} ImageMeta Point TrackingData QuaternionTrackingData ImageDatabaseServer String Bind PolyData Capability Trajectory SessionManager ) endif (${OpenIGTLink_PROTOCOL_VERSION} GREATER 1) ## Imager program isn't supported by QNX if(NOT OpenIGTLink_PLATFORM_QNX) SUBDIRS( ${EXAMPLE_DIRS} ) else(NOT OpenIGTLink_PLATFORM_QNX) SUBDIRS( Tracker Status Receiver ) endif(NOT OpenIGTLink_PLATFORM_QNX) openigtlink-3.0.0/Examples/Capability/000077500000000000000000000000001501024245700176745ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Capability/CMakeLists.txt000066400000000000000000000006601501024245700224360ustar00rootroot00000000000000PROJECT(Capability) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(CapabilityClient CapabilityClient.cxx) TARGET_LINK_LIBRARIES(CapabilityClient OpenIGTLink) ADD_EXECUTABLE(CapabilityServer CapabilityServer.cxx) TARGET_LINK_LIBRARIES(CapabilityServer OpenIGTLink) openigtlink-3.0.0/Examples/Capability/CapabilityClient.cxx000066400000000000000000000044631501024245700236470ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Sending Capability Messasge Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlCapabilityMessage.h" #include "igtlClientSocket.h" #include "igtlTransformMessage.h" #include "igtlImageMessage.h" #include "igtlLabelMetaMessage.h" // // Test comment // int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); int interval = (int) (1000); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Capability Message Class igtl::CapabilityMessage::Pointer capabilityMsg; capabilityMsg = igtl::CapabilityMessage::New(); capabilityMsg->SetDeviceName("Device"); std::vector types; types.push_back(std::string("TRANSFORM")); types.push_back(std::string("GET_IMAGE")); types.push_back(std::string("GET_LBMETA")); capabilityMsg->SetTypes(types); capabilityMsg->Pack(); socket->Send(capabilityMsg->GetPackPointer(), capabilityMsg->GetPackSize()); //------------------------------------------------------------ // Close connection socket->CloseSocket(); } openigtlink-3.0.0/Examples/Capability/CapabilityServer.cxx000066400000000000000000000050151501024245700236710ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlCapabilityMessage.h" #include "igtlServerSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); int interval = (int) 1000; //------------------------------------------------------------ // Allocate Capability Message Class igtl::CapabilityMessage::Pointer capabilityMsg; capabilityMsg = igtl::CapabilityMessage::New(); capabilityMsg->SetDeviceName("Device"); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { std::vector types; types.push_back(std::string("TRANSFORM")); types.push_back(std::string("GET_IMAGE")); types.push_back(std::string("GET_LBMETA")); capabilityMsg->SetTypes(types); capabilityMsg->Pack(); socket->Send(capabilityMsg->GetPackPointer(), capabilityMsg->GetPackSize()); igtl::Sleep(interval); // wait } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } openigtlink-3.0.0/Examples/ImageDatabaseServer/000077500000000000000000000000001501024245700214515ustar00rootroot00000000000000openigtlink-3.0.0/Examples/ImageDatabaseServer/CMakeLists.txt000066400000000000000000000005741501024245700242170ustar00rootroot00000000000000PROJECT(ImageDatabaseServer) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ## igtl::ImageDatabaseMessage examples ADD_EXECUTABLE(ImageDatabaseServer ImageDatabaseServer.cxx) TARGET_LINK_LIBRARIES(ImageDatabaseServer OpenIGTLink) openigtlink-3.0.0/Examples/ImageDatabaseServer/ImageDatabaseServer.cxx000066400000000000000000000263541501024245700260450ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Image Meta Data Server Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlImageMessage.h" #include "igtlImageMetaMessage.h" #include "igtlLabelMetaMessage.h" #include "igtlServerSocket.h" int SendImageMeta(igtl::Socket::Pointer& socket, const char* name); int SendLabelMeta(igtl::Socket::Pointer& socket, const char* name); int SendImage(igtl::Socket::Pointer& socket, const char* name, const char* filedir); int SendLabel(igtl::Socket::Pointer& socket, const char* name, const char* filedir); int GetTestImage(igtl::ImageMessage::Pointer& msg, const char* dir, int i); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : file directory, where \"igtlTestImage[1-3].raw\" are placed." << std::endl; exit(0); } int port = atoi(argv[1]); char* filedir = argv[2]; igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { socket->CloseSocket(); } if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); std::cerr << "Receiving a message: " << std::endl; std::cerr << " Device Type: \"" << headerMsg->GetDeviceType() << "\"" << std::endl; std::cerr << " Device Name: \"" << headerMsg->GetDeviceName() << "\"" << std::endl; // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "GET_IMGMETA") == 0) { //socket->Skip(headerMsg->GetBodySizeToRead(), 0); SendImageMeta(socket, headerMsg->GetDeviceName()); } else if (strcmp(headerMsg->GetDeviceType(), "GET_LBMETA") == 0) { SendLabelMeta(socket, headerMsg->GetDeviceName()); } else if (strcmp(headerMsg->GetDeviceType(), "GET_IMAGE") == 0) { SendImage(socket, headerMsg->GetDeviceName(), filedir); } else { // if the data type is unknown, skip reading. socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } } //------------------------------------------------------------ // Close connection (The example code never reaches to this section ...) socket->CloseSocket(); } int SendImageMeta(igtl::Socket::Pointer& socket, const char* name) { //------------------------------------------------------------ // Allocate Status Message Class igtl::ImageMetaMessage::Pointer imgMetaMsg; imgMetaMsg = igtl::ImageMetaMessage::New(); // NOTE: the server should send a message with the same device name // as the received query message. imgMetaMsg->SetDeviceName(name); //--------------------------- // Create 1st meta data igtl::ImageMetaElement::Pointer imgMeta0; imgMeta0 = igtl::ImageMetaElement::New(); imgMeta0->SetName("IMAGE_DESCRIPTION_0"); imgMeta0->SetDeviceName("IMAGE_0"); imgMeta0->SetModality("CT"); imgMeta0->SetPatientName("PATIENT_0"); imgMeta0->SetPatientID("PATIENT_ID_0"); igtl::TimeStamp::Pointer ts0; ts0 = igtl::TimeStamp::New(); ts0->SetTime(1291739370.2345); imgMeta0->SetTimeStamp(ts0); imgMeta0->SetSize(512, 512, 64); imgMeta0->SetScalarType(igtl::ImageMessage::TYPE_UINT16); //--------------------------- // Create 2nd meta data igtl::ImageMetaElement::Pointer imgMeta1; imgMeta1 = igtl::ImageMetaElement::New(); imgMeta1->SetName("IMAGE_DESCRIPTION_1"); imgMeta1->SetDeviceName("IMAGE_1"); imgMeta1->SetModality("MRI"); imgMeta1->SetPatientName("PATIENT_1"); imgMeta1->SetPatientID("PATIENT_ID_1"); igtl::TimeStamp::Pointer ts1; ts1 = igtl::TimeStamp::New(); ts1->SetTime(1291739380.3456); imgMeta1->SetTimeStamp(ts1); imgMeta1->SetSize(256, 128, 32); imgMeta1->SetScalarType(igtl::ImageMessage::TYPE_UINT16); //--------------------------- // Create 3rd meta data igtl::ImageMetaElement::Pointer imgMeta2; imgMeta2 = igtl::ImageMetaElement::New(); imgMeta2->SetName("IMAGE_DESCRIPTION_2"); imgMeta2->SetDeviceName("IMAGE_2"); imgMeta2->SetModality("PET"); imgMeta2->SetPatientName("PATIENT_2"); imgMeta2->SetPatientID("PATIENT_ID_2"); igtl::TimeStamp::Pointer ts2; ts2 = igtl::TimeStamp::New(); ts2->SetTime(1291739390.4567); imgMeta2->SetTimeStamp(ts2); imgMeta2->SetSize(256, 256, 32); imgMeta2->SetScalarType(igtl::ImageMessage::TYPE_UINT16); imgMetaMsg->AddImageMetaElement(imgMeta0); imgMetaMsg->AddImageMetaElement(imgMeta1); imgMetaMsg->AddImageMetaElement(imgMeta2); imgMetaMsg->Pack(); std::cerr << "Size of pack: " << imgMetaMsg->GetPackSize() << std::endl; std::cerr << "Name of type: " << imgMetaMsg->GetDeviceType() << std::endl; std::cerr << "Sending a IMGMETA message..." << std::endl; socket->Send(imgMetaMsg->GetPackPointer(), imgMetaMsg->GetPackSize()); return 1; } int SendLabelMeta(igtl::Socket::Pointer& socket, const char* name) { //------------------------------------------------------------ // Allocate Status Message Class igtl::LabelMetaMessage::Pointer lbMetaMsg; lbMetaMsg = igtl::LabelMetaMessage::New(); // NOTE: the server should send a message with the same device name // as the received query message. lbMetaMsg->SetDeviceName(name); //--------------------------- // Create 1st meta data igtl::LabelMetaElement::Pointer lbMeta0; lbMeta0 = igtl::LabelMetaElement::New(); lbMeta0->SetName("LABEL_DESCRIPTION_0"); lbMeta0->SetDeviceName("LABEL_0"); lbMeta0->SetOwner("IMAGE_0"); lbMeta0->SetSize(512, 512, 64); //--------------------------- // Create 2nd meta data igtl::LabelMetaElement::Pointer lbMeta1; lbMeta1 = igtl::LabelMetaElement::New(); lbMeta1->SetName("LABEL_DESCRIPTION_1"); lbMeta1->SetDeviceName("LABEL_1"); lbMeta1->SetOwner("IMAGE_1"); lbMeta1->SetSize(256, 128, 32); //--------------------------- // Create 3rd meta data igtl::LabelMetaElement::Pointer lbMeta2; lbMeta2 = igtl::LabelMetaElement::New(); lbMeta2->SetName("LABEL_DESCRIPTION_2"); lbMeta2->SetDeviceName("LABEL_2"); lbMeta2->SetOwner("IMAGE_2"); lbMeta2->SetSize(256, 256, 32); lbMetaMsg->AddLabelMetaElement(lbMeta0); lbMetaMsg->AddLabelMetaElement(lbMeta1); lbMetaMsg->AddLabelMetaElement(lbMeta2); lbMetaMsg->Pack(); std::cerr << "Size of pack: " << lbMetaMsg->GetPackSize() << std::endl; std::cerr << "Name of type: " << lbMetaMsg->GetDeviceType() << std::endl; std::cerr << "Sending a LBMETA message..." << std::endl; socket->Send(lbMetaMsg->GetPackPointer(), lbMetaMsg->GetPackSize()); return 1; } int SendImage(igtl::Socket::Pointer& socket, const char* name, const char* filedir) { int index = 0; if (strcmp(name, "IMAGE_0") == 0) { index = 1; } else if (strcmp(name, "IMAGE_1") == 0) { index = 2; } else if (strcmp(name, "IMAGE_2") == 0) { index = 3; } if (strcmp(name, "LABEL_0") == 0) { index = 4; } else if (strcmp(name, "LABEL_1") == 0) { index = 5; } else if (strcmp(name, "LABEL_2") == 0) { index = 6; } if (index > 0) { int size[] = {256, 256, 1}; // image dimension float spacing[] = {1.0, 1.0, 5.0}; // spacing (mm/pixel) int svsize[] = {256, 256, 1}; // sub-volume size int svoffset[] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage::TYPE_UINT8;// scalar type igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New(); imgMsg->SetDimensions(size); imgMsg->SetSpacing(spacing); imgMsg->SetScalarType(scalarType); imgMsg->SetDeviceName(name); imgMsg->SetSubVolume(svsize, svoffset); imgMsg->AllocateScalars(); // Following line may be called in case of 16-, 32-, and 64-bit scalar types. // imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_BIG); //------------------------------------------------------------ // Set image data (See GetTestImage() bellow for the details) GetTestImage(imgMsg, filedir, index); igtl::Matrix4x4 matrix; igtl::IdentityMatrix(matrix); imgMsg->SetMatrix(matrix); //------------------------------------------------------------ // Pack (serialize) and send imgMsg->Pack(); socket->Send(imgMsg->GetPackPointer(), imgMsg->GetPackSize()); } else { //------------------------------------------------------------ // Return RTS_IMAGE message with error code // TODO } return 1; } //------------------------------------------------------------ // Function to read test image data int GetTestImage(igtl::ImageMessage::Pointer& msg, const char* dir, int i) { //------------------------------------------------------------ // Check if image index is in the range if (i < 0 || i >= 7) { std::cerr << "Image index is invalid." << std::endl; return 0; } //------------------------------------------------------------ // Generate path to the raw image file char filename[128]; sprintf(filename, "%s/igtlTestImage%d.raw", dir, i+1); std::cerr << "Reading " << filename << "..."; //------------------------------------------------------------ // Load raw data from the file FILE *fp = fopen(filename, "rb"); if (fp == NULL) { std::cerr << "File opeining error: " << filename << std::endl; return 0; } int fsize = msg->GetImageSize(); //size_t b = fread(msg->GetScalarPointer(), 1, fsize, fp); fread(msg->GetScalarPointer(), 1, fsize, fp); fclose(fp); std::cerr << "done." << std::endl; return 1; } openigtlink-3.0.0/Examples/ImageMeta/000077500000000000000000000000001501024245700174445ustar00rootroot00000000000000openigtlink-3.0.0/Examples/ImageMeta/CMakeLists.txt000066400000000000000000000013011501024245700221770ustar00rootroot00000000000000PROJECT(ImageMeta) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ## igtl::ImageMetaMessage examples ADD_EXECUTABLE(ImageMetaServer ImageMetaServer.cxx) TARGET_LINK_LIBRARIES(ImageMetaServer OpenIGTLink) ADD_EXECUTABLE(ImageMetaClient ImageMetaClient.cxx) TARGET_LINK_LIBRARIES(ImageMetaClient OpenIGTLink) ## igtl::LabelMetaMessage example ADD_EXECUTABLE(LabelMetaServer LabelMetaServer.cxx) TARGET_LINK_LIBRARIES(LabelMetaServer OpenIGTLink) ADD_EXECUTABLE(LabelMetaClient LabelMetaClient.cxx) TARGET_LINK_LIBRARIES(LabelMetaClient OpenIGTLink) openigtlink-3.0.0/Examples/ImageMeta/ImageMetaClient.cxx000066400000000000000000000120731501024245700231630ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Image Meta Data Client Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include "igtlOSUtil.h" #include "igtlImageMessage.h" #include "igtlImageMetaMessage.h" #include "igtlClientSocket.h" int ReceiveImageMeta(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // loop for (int i = 0; i < 10; i ++) { //------------------------------------------------------------ // Send request data igtl::GetImageMetaMessage::Pointer getImageMetaMsg; getImageMetaMsg = igtl::GetImageMetaMessage::New(); getImageMetaMsg->SetDeviceName("Client"); getImageMetaMsg->Pack(); socket->Send(getImageMetaMsg->GetPackPointer(), getImageMetaMsg->GetPackSize()); //------------------------------------------------------------ // Wait for a reply igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { std::cerr << "Connection closed." << std::endl; socket->CloseSocket(); exit(0); } if (rs != headerMsg->GetPackSize()) { std::cerr << "Message size information and actual data size don't match." << std::endl; exit(0); } headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "IMGMETA") == 0) { ReceiveImageMeta(socket, headerMsg); } else { std::cerr << "Invalid response from the server:" << headerMsg->GetDeviceName() << std::endl; exit(0); } igtl::Sleep(500); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } int ReceiveImageMeta(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving IMGMETA data type." << std::endl; // Create a message buffer to receive transform data igtl::ImageMetaMessage::Pointer imgMeta; imgMeta = igtl::ImageMetaMessage::New(); imgMeta->SetMessageHeader(header); imgMeta->AllocatePack(); // Receive transform data from the socket socket->Receive(imgMeta->GetPackBodyPointer(), imgMeta->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = imgMeta->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = imgMeta->GetNumberOfImageMetaElement(); for (int i = 0; i < nElements; i ++) { igtl::ImageMetaElement::Pointer imgMetaElement; imgMeta->GetImageMetaElement(i, imgMetaElement); igtlUint16 size[3]; imgMetaElement->GetSize(size); igtl::TimeStamp::Pointer ts; imgMetaElement->GetTimeStamp(ts); double time = ts->GetTimeStamp(); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << imgMetaElement->GetName() << std::endl; std::cerr << " DeviceName : " << imgMetaElement->GetDeviceName() << std::endl; std::cerr << " Modality : " << imgMetaElement->GetModality() << std::endl; std::cerr << " PatientName: " << imgMetaElement->GetPatientName() << std::endl; std::cerr << " PatientID : " << imgMetaElement->GetPatientID() << std::endl; std::cerr << " TimeStamp : " << std::fixed << time << std::endl; std::cerr << " Size : ( " << size[0] << ", " << size[1] << ", " << size[2] << ")" << std::endl; std::cerr << " ScalarType : " << (int) imgMetaElement->GetScalarType() << std::endl; std::cerr << "================================" << std::endl; } return 1; } return 0; } openigtlink-3.0.0/Examples/ImageMeta/ImageMetaServer.cxx000066400000000000000000000133011501024245700232060ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Image Meta Data Server Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlImageMessage.h" #include "igtlServerSocket.h" #include "igtlImageMetaMessage.h" int SendImageMeta(igtl::Socket::Pointer& socket, const char* name); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { socket->CloseSocket(); } if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "GET_IMGMETA") == 0) { std::cerr << "Received a GET_IMGMETA message." << std::endl; //socket->Skip(headerMsg->GetBodySizeToRead(), 0); SendImageMeta(socket, headerMsg->GetDeviceName()); } else { // if the data type is unknown, skip reading. std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } } //------------------------------------------------------------ // Close connection (The example code never reaches to this section ...) socket->CloseSocket(); } int SendImageMeta(igtl::Socket::Pointer& socket, const char* name) { //------------------------------------------------------------ // Allocate Status Message Class igtl::ImageMetaMessage::Pointer imgMetaMsg; imgMetaMsg = igtl::ImageMetaMessage::New(); // NOTE: the server should send a message with the same device name // as the received query message. imgMetaMsg->SetDeviceName(name); //--------------------------- // Create 1st meta data igtl::ImageMetaElement::Pointer imgMeta0; imgMeta0 = igtl::ImageMetaElement::New(); imgMeta0->SetName("IMAGE_DESCRIPTION_0"); imgMeta0->SetDeviceName("IMAGE_0"); imgMeta0->SetModality("CT"); imgMeta0->SetPatientName("PATIENT_0"); imgMeta0->SetPatientID("PATIENT_ID_0"); igtl::TimeStamp::Pointer ts0; ts0 = igtl::TimeStamp::New(); ts0->SetTime(1.2345); imgMeta0->SetTimeStamp(ts0); imgMeta0->SetSize(512, 512, 64); imgMeta0->SetScalarType(igtl::ImageMessage::TYPE_UINT16); //--------------------------- // Create 2nd meta data igtl::ImageMetaElement::Pointer imgMeta1; imgMeta1 = igtl::ImageMetaElement::New(); imgMeta1->SetName("IMAGE_DESCRIPTION_1"); imgMeta1->SetDeviceName("IMAGE_1"); imgMeta1->SetModality("MRI"); imgMeta1->SetPatientName("PATIENT_1"); imgMeta1->SetPatientID("PATIENT_ID_1"); igtl::TimeStamp::Pointer ts1; ts1 = igtl::TimeStamp::New(); ts1->SetTime(2.3456); imgMeta1->SetTimeStamp(ts1); imgMeta1->SetSize(256, 128, 32); imgMeta1->SetScalarType(igtl::ImageMessage::TYPE_UINT16); //--------------------------- // Create 3rd meta data igtl::ImageMetaElement::Pointer imgMeta2; imgMeta2 = igtl::ImageMetaElement::New(); imgMeta2->SetName("IMAGE_DESCRIPTION_2"); imgMeta2->SetDeviceName("IMAGE_2"); imgMeta2->SetModality("PET"); imgMeta2->SetPatientName("PATIENT_2"); imgMeta2->SetPatientID("PATIENT_ID_2"); igtl::TimeStamp::Pointer ts2; ts2 = igtl::TimeStamp::New(); ts2->SetTime(3.4567); imgMeta2->SetTimeStamp(ts2); imgMeta2->SetSize(256, 256, 32); imgMeta2->SetScalarType(igtl::ImageMessage::TYPE_UINT16); imgMetaMsg->AddImageMetaElement(imgMeta0); imgMetaMsg->AddImageMetaElement(imgMeta1); imgMetaMsg->AddImageMetaElement(imgMeta2); imgMetaMsg->Pack(); std::cerr << "Size of pack: " << imgMetaMsg->GetPackSize() << std::endl; std::cerr << "Name of type: " << imgMetaMsg->GetDeviceType() << std::endl; std::cerr << "Sending a IMGMETA message..." << std::endl; socket->Send(imgMetaMsg->GetPackPointer(), imgMetaMsg->GetPackSize()); return 1; } openigtlink-3.0.0/Examples/ImageMeta/LabelMetaClient.cxx000066400000000000000000000116161501024245700231620ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Label Meta Data Client Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include "igtlOSUtil.h" #include "igtlImageMessage.h" #include "igtlLabelMetaMessage.h" #include "igtlClientSocket.h" int ReceiveLabelMeta(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // loop for (int i = 0; i < 10; i ++) { //------------------------------------------------------------ // Send request data igtl::GetLabelMetaMessage::Pointer getLabelMetaMsg; getLabelMetaMsg = igtl::GetLabelMetaMessage::New(); getLabelMetaMsg->SetDeviceName("Client"); getLabelMetaMsg->Pack(); socket->Send(getLabelMetaMsg->GetPackPointer(), getLabelMetaMsg->GetPackSize()); //------------------------------------------------------------ // Wait for a reply igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { std::cerr << "Connection closed." << std::endl; socket->CloseSocket(); exit(0); } if (rs != headerMsg->GetPackSize()) { std::cerr << "Message size information and actual data size don't match." << std::endl; exit(0); } headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "LBMETA") == 0) { ReceiveLabelMeta(socket, headerMsg); } else { std::cerr << "Invalid response from the server:" << headerMsg->GetDeviceName() << std::endl; exit(0); } igtl::Sleep(500); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } int ReceiveLabelMeta(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving LBMETA data type." << std::endl; // Create a message buffer to receive transform data igtl::LabelMetaMessage::Pointer lbMeta; lbMeta = igtl::LabelMetaMessage::New(); lbMeta->SetMessageHeader(header); lbMeta->AllocatePack(); // Receive transform data from the socket socket->Receive(lbMeta->GetPackBodyPointer(), lbMeta->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = lbMeta->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = lbMeta->GetNumberOfLabelMetaElement(); for (int i = 0; i < nElements; i ++) { igtl::LabelMetaElement::Pointer lbMetaElement; lbMeta->GetLabelMetaElement(i, lbMetaElement); igtlUint8 rgba[4]; lbMetaElement->GetRGBA(rgba); igtlUint16 size[3]; lbMetaElement->GetSize(size); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << lbMetaElement->GetName() << std::endl; std::cerr << " DeviceName : " << lbMetaElement->GetDeviceName() << std::endl; std::cerr << " Label : " << (int) lbMetaElement->GetLabel() << std::endl; std::cerr << " RGBA : ( " << (int)rgba[0] << ", " << (int)rgba[1] << ", " << (int)rgba[2] << ", " << (int)rgba[3] << " )" << std::endl; std::cerr << " Size : ( " << size[0] << ", " << size[1] << ", " << size[2] << ")" << std::endl; std::cerr << " Owner : " << lbMetaElement->GetOwner() << std::endl; std::cerr << "================================" << std::endl; } return 1; } return 0; } openigtlink-3.0.0/Examples/ImageMeta/LabelMetaServer.cxx000066400000000000000000000116441501024245700232130ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Label Meta Data Server Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlImageMessage.h" #include "igtlServerSocket.h" #include "igtlLabelMetaMessage.h" int SendLabelMeta(igtl::Socket::Pointer& socket); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { socket->CloseSocket(); } if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "GET_LBMETA") == 0) { std::cerr << "Received a GET_LBMETA message." << std::endl; //socket->Skip(headerMsg->GetBodySizeToRead(), 0); SendLabelMeta(socket); } else { // if the data type is unknown, skip reading. std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } } //------------------------------------------------------------ // Close connection (The example code never reaches to this section ...) socket->CloseSocket(); } int SendLabelMeta(igtl::Socket::Pointer& socket) { //------------------------------------------------------------ // Allocate Status Message Class igtl::LabelMetaMessage::Pointer lbMetaMsg; lbMetaMsg = igtl::LabelMetaMessage::New(); lbMetaMsg->SetDeviceName("MetaServer"); //--------------------------- // Create 1st meta data igtl::LabelMetaElement::Pointer lbMeta0; lbMeta0 = igtl::LabelMetaElement::New(); lbMeta0->SetName("LABEL_DESCRIPTION_0"); lbMeta0->SetDeviceName("LABEL_0"); lbMeta0->SetLabel(1); lbMeta0->SetRGBA(0xFF, 0x00, 0x00, 0xFF); lbMeta0->SetSize(512, 512, 64); lbMeta0->SetOwner("IMAGE_0"); //--------------------------- // Create 2nd meta data igtl::LabelMetaElement::Pointer lbMeta1; lbMeta1 = igtl::LabelMetaElement::New(); lbMeta1->SetName("LABEL_DESCRIPTION_1"); lbMeta1->SetDeviceName("LABEL_1"); lbMeta1->SetLabel(2); lbMeta1->SetRGBA(0x00, 0xFF, 0, 0xFF); lbMeta1->SetSize(256, 128, 32); lbMeta1->SetOwner("IMAGE_1"); //--------------------------- // Create 3rd meta data igtl::LabelMetaElement::Pointer lbMeta2; lbMeta2 = igtl::LabelMetaElement::New(); lbMeta2->SetName("LABEL_DESCRIPTION_2"); lbMeta2->SetDeviceName("LABEL_2"); lbMeta2->SetLabel(3); lbMeta2->SetRGBA(0, 0, 0xFF, 0xFF); lbMeta2->SetSize(256, 256, 32); lbMeta2->SetOwner("IMAGE_2"); lbMetaMsg->AddLabelMetaElement(lbMeta0); lbMetaMsg->AddLabelMetaElement(lbMeta1); lbMetaMsg->AddLabelMetaElement(lbMeta2); lbMetaMsg->Pack(); std::cerr << "Size of pack: " << lbMetaMsg->GetPackSize() << std::endl; std::cerr << "Name of type: " << lbMetaMsg->GetDeviceType() << std::endl; std::cerr << "Sending a LBMETA message..." << std::endl; socket->Send(lbMetaMsg->GetPackPointer(), lbMetaMsg->GetPackSize()); return 1; } openigtlink-3.0.0/Examples/Imager/000077500000000000000000000000001501024245700170175ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Imager/CMakeLists.txt000066400000000000000000000012761501024245700215650ustar00rootroot00000000000000PROJECT(Imager) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(ImagerClient ImagerClient.cxx) TARGET_LINK_LIBRARIES(ImagerClient OpenIGTLink) ADD_EXECUTABLE(ImagerClient2 ImagerClient2.cxx) TARGET_LINK_LIBRARIES(ImagerClient2 OpenIGTLink) ADD_EXECUTABLE(ImagerServer ImagerServer.cxx) TARGET_LINK_LIBRARIES(ImagerServer OpenIGTLink) ADD_EXECUTABLE(ImagerClient3 ImagerClient3.cxx) TARGET_LINK_LIBRARIES(ImagerClient3 OpenIGTLink) ADD_EXECUTABLE(ImagerServer3 ImagerServer3.cxx) TARGET_LINK_LIBRARIES(ImagerServer3 OpenIGTLink) openigtlink-3.0.0/Examples/Imager/ImagerClient.cxx000066400000000000000000000136231501024245700221130ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Imager Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlImageMessage.h" #include "igtlClientSocket.h" int GetTestImage(igtl::ImageMessage::Pointer& msg, const char* dir, int i); void GetRandomTestMatrix(igtl::Matrix4x4& matrix); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 5) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; std::cerr << " : file directory, where \"igtlTestImage[1-5].raw\" are placed." << std::endl; std::cerr << " (usually, in the Examples/Imager/img directory.)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); char* filedir = argv[4]; //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { //------------------------------------------------------------ // size parameters int size[] = {256, 256, 1}; // image dimension float spacing[] = {1.0, 1.0, 5.0}; // spacing (mm/pixel) int svsize[] = {256, 256, 1}; // sub-volume size int svoffset[] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage::TYPE_UINT8;// scalar type //------------------------------------------------------------ // Create a new IMAGE type message igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New(); imgMsg->SetDimensions(size); imgMsg->SetSpacing(spacing); imgMsg->SetScalarType(scalarType); imgMsg->SetDeviceName("ImagerClient"); imgMsg->SetSubVolume(svsize, svoffset); imgMsg->AllocateScalars(); // Following line may be called in case of 16-, 32-, and 64-bit scalar types. // imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_BIG); //------------------------------------------------------------ // Set image data (See GetTestImage() bellow for the details) GetTestImage(imgMsg, filedir, i % 5); //------------------------------------------------------------ // Get random orientation matrix and set it. igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix); imgMsg->SetMatrix(matrix); //------------------------------------------------------------ // Pack (serialize) and send imgMsg->Pack(); socket->Send(imgMsg->GetPackPointer(), imgMsg->GetPackSize()); igtl::Sleep(interval); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } //------------------------------------------------------------ // Function to read test image data int GetTestImage(igtl::ImageMessage::Pointer& msg, const char* dir, int i) { //------------------------------------------------------------ // Check if image index is in the range if (i < 0 || i >= 5) { std::cerr << "Image index is invalid." << std::endl; return 0; } //------------------------------------------------------------ // Generate path to the raw image file char filename[128]; sprintf(filename, "%s/igtlTestImage%d.raw", dir, i+1); std::cerr << "Reading " << filename << "..."; //------------------------------------------------------------ // Load raw data from the file FILE *fp = fopen(filename, "rb"); if (fp == NULL) { std::cerr << "File opeining error: " << filename << std::endl; return 0; } int fsize = msg->GetImageSize(); size_t b = fread(msg->GetScalarPointer(), 1, fsize, fp); fclose(fp); std::cerr << "done." << std::endl; return 1; } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestMatrix(igtl::Matrix4x4& matrix) { //float position[3]; //float orientation[4]; /* // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 0; phi = phi + 0.2; // random orientation static float theta = 0.0; orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; */ matrix[0][0] = 1.0; matrix[1][0] = 0.0; matrix[2][0] = 0.0; matrix[3][0] = 0.0; matrix[0][1] = 0.0; matrix[1][1] = -1.0; matrix[2][1] = 0.0; matrix[3][1] = 0.0; matrix[0][2] = 0.0; matrix[1][2] = 0.0; matrix[2][2] = 1.0; matrix[3][2] = 0.0; matrix[0][3] = 0.0; matrix[1][3] = 0.0; matrix[2][3] = 0.0; matrix[3][3] = 1.0; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Imager/ImagerClient2.cxx000066400000000000000000000140761501024245700222000ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Imager Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlImageMessage2.h" #include "igtlClientSocket.h" int GetTestImage(char * image, const char* dir, int i); void GetRandomTestMatrix(igtl::Matrix4x4& matrix); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 5) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; std::cerr << " : file directory, where \"igtlTestImage[1-5].raw\" are placed." << std::endl; std::cerr << " (usually, in the Examples/Imager/img directory.)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); char* filedir = argv[4]; //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } char * image = new char [256 * 256]; //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { //------------------------------------------------------------ // size parameters int size[] = {256, 256, 1}; // image dimension float spacing[] = {1.0, 1.0, 5.0}; // spacing (mm/pixel) int svsize[] = {256, 256, 1}; // sub-volume size int svoffset[] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage2::TYPE_UINT8;// scalar type //------------------------------------------------------------ // Create a new IMAGE type message igtl::ImageMessage2::Pointer imgMsg = igtl::ImageMessage2::New(); imgMsg->SetDimensions(size); imgMsg->SetSpacing(spacing); imgMsg->SetScalarType(scalarType); imgMsg->SetDeviceName("ImagerClient"); imgMsg->SetSubVolume(svsize, svoffset); imgMsg->AllocateScalars(); // Following line may be called in case of 16-, 32-, and 64-bit scalar types. // imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_BIG); //------------------------------------------------------------ // Set image data (See GetTestImage() bellow for the details) GetTestImage(image, filedir, i % 5); imgMsg->SetScalarPointer(image); //------------------------------------------------------------ // Get random orientation matrix and set it. igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix); imgMsg->SetMatrix(matrix); //------------------------------------------------------------ // Pack (serialize) and send imgMsg->Pack(); //socket->Send(imgMsg->GetPackPointer(), imgMsg->GetPackSize()); for (int i = 0; i < imgMsg->GetNumberOfPackFragments(); i ++) { socket->Send(imgMsg->GetPackFragmentPointer(i), imgMsg->GetPackFragmentSize(i)); } igtl::Sleep(interval); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } //------------------------------------------------------------ // Function to read test image data int GetTestImage(char * image, const char* dir, int i) { //------------------------------------------------------------ // Check if image index is in the range if (i < 0 || i >= 5) { std::cerr << "Image index is invalid." << std::endl; return 0; } //------------------------------------------------------------ // Generate path to the raw image file char filename[128]; sprintf(filename, "%s/igtlTestImage%d.raw", dir, i+1); std::cerr << "Reading " << filename << "..."; //------------------------------------------------------------ // Load raw data from the file FILE *fp = fopen(filename, "rb"); if (fp == NULL) { std::cerr << "File opeining error: " << filename << std::endl; return 0; } size_t b = fread(image, 1, 256*256, fp); fclose(fp); std::cerr << "done." << std::endl; return 1; } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestMatrix(igtl::Matrix4x4& matrix) { //float position[3]; //float orientation[4]; /* // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 0; phi = phi + 0.2; // random orientation static float theta = 0.0; orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; */ matrix[0][0] = 1.0; matrix[1][0] = 0.0; matrix[2][0] = 0.0; matrix[3][0] = 0.0; matrix[0][1] = 0.0; matrix[1][1] = -1.0; matrix[2][1] = 0.0; matrix[3][1] = 0.0; matrix[0][2] = 0.0; matrix[1][2] = 0.0; matrix[2][2] = 1.0; matrix[3][2] = 0.0; matrix[0][3] = 0.0; matrix[1][3] = 0.0; matrix[2][3] = 0.0; matrix[3][3] = 1.0; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Imager/ImagerClient3.cxx000066400000000000000000000152701501024245700221760ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Imager Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtl_header.h" #include "igtlOSUtil.h" #include "igtlImageMessage.h" #include "igtlClientSocket.h" int ReceiveImageData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header, int loop); int SaveTestImage(igtl::ImageMessage::Pointer& msg, int i); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 5) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; std::cerr << " Version : Version number send to the server" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int version = atoi(argv[4]); int interval = (int) (1000.0 / fps); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (version > IGTL_HEADER_VERSION_2 || version < IGTL_HEADER_VERSION_1) { std::cerr << "Invalid version number" << std::endl; exit(0); } if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Ask the server to start pushing tracking data std::cerr << "Sending Get_Image message....." << std::endl; igtl::GetImageMessage::Pointer getImageMsg; getImageMsg = igtl::GetImageMessage::New(); getImageMsg->SetDeviceName("ImageClient"); getImageMsg->SetHeaderVersion(version); getImageMsg->Pack(); socket->Send(getImageMsg->GetPackPointer(), getImageMsg->GetPackSize()); int loop = 0; while (1) { //------------------------------------------------------------ // Wait for a reply igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { std::cerr << "Connection closed." << std::endl; socket->CloseSocket(); exit(0); } if (rs != headerMsg->GetPackSize()) { std::cerr << "Message size information and actual data size don't match." << std::endl; socket->CloseSocket(); exit(0); } headerMsg->Unpack(); if (headerMsg->GetHeaderVersion() != version) { std::cerr << "Version of the client and server don't match." << std::endl; socket->CloseSocket(); exit(0); } if (strcmp(headerMsg->GetDeviceName(), "ImagerClient") == 0) { ReceiveImageData(socket, headerMsg, loop); igtl::Sleep(interval); } else { std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } if (++loop >= 100) // if received 100 times { //------------------------------------------------------------ // Ask the server to stop pushing tracking data std::cerr << "Sending STP_IMAGE message....." << std::endl; igtl::StopImageMessage::Pointer stopImageMsg; stopImageMsg = igtl::StopImageMessage::New(); stopImageMsg->SetDeviceName("ImageClient"); stopImageMsg->Pack(); socket->Send(stopImageMsg->GetPackPointer(), stopImageMsg->GetPackSize()); loop = 0; } } } //------------------------------------------------------------ // Function to read test image data int ReceiveImageData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header,int loop) { std::cerr << "Receiving TDATA data type." << std::endl; //------------------------------------------------------------ // Allocate TrackingData Message Class igtl::ImageMessage::Pointer imageData; imageData = igtl::ImageMessage::New(); imageData->SetMessageHeader(header);//Here the version is also set imageData->AllocatePack(); // Receive body from the socket socket->Receive(imageData->GetPackBodyPointer(), imageData->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = imageData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { #if OpenIGTLink_HEADER_VERSION >= 2 if (imageData->GetHeaderVersion() >= IGTL_HEADER_VERSION_2) { int i = 0; for (std::map >::const_iterator it = imageData->GetMetaData().begin(); it != imageData->GetMetaData().end(); ++it, ++i) { std::cerr<<"The message ID is:"<< " " << imageData->GetMessageID() << std::endl; std::cerr<< it->first << " coding scheme: " << it->second.first << " " << it->second.second << std::endl; } } #endif SaveTestImage(imageData, loop); return 1; } return 0; } //------------------------------------------------------------ // Function to read test image data int SaveTestImage(igtl::ImageMessage::Pointer& msg, int i) { //------------------------------------------------------------ // Check if image index is in the range if (i < 0 || i >= 100) { std::cerr << "Image index is invalid." << std::endl; return 0; } //------------------------------------------------------------ // Generate path to the raw image file char filename[128]; sprintf(filename, "igtlSaveImage%d.raw", i+1); std::cerr << "Saving " << filename << "..."; //------------------------------------------------------------ // Load raw data from the file FILE *fp = fopen(filename, "wb"); if (fp == NULL) { std::cerr << "File opeining error: " << filename << std::endl; return 0; } int fsize = msg->GetImageSize(); size_t b = fwrite(msg->GetScalarPointer(), 1, fsize, fp); fclose(fp); std::cerr << "done." << std::endl; return 1; } openigtlink-3.0.0/Examples/Imager/ImagerServer.cxx000066400000000000000000000144461501024245700221470ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlImageMessage.h" #include "igtlServerSocket.h" int GetTestImage(igtl::ImageMessage::Pointer& msg, const char* dir, int i); void GetRandomTestMatrix(igtl::Matrix4x4& matrix); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 4) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; std::cerr << " : file directory, where \"igtlTestImage[1-5].raw\" are placed." << std::endl; std::cerr << " (usually, in the Examples/Imager/img directory.)" << std::endl; exit(0); } int port = atoi(argv[1]); double fps = atof(argv[2]); int interval = (int) (1000.0 / fps); char* filedir = argv[3]; //------------------------------------------------------------ // Prepare server socket igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { //------------------------------------------------------------ // size parameters int size[] = {256, 256, 1}; // image dimension float spacing[] = {1.0, 1.0, 5.0}; // spacing (mm/pixel) int svsize[] = {256, 256, 1}; // sub-volume size int svoffset[] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage::TYPE_UINT8;// scalar type //------------------------------------------------------------ // Create a new IMAGE type message igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New(); imgMsg->SetDimensions(size); imgMsg->SetSpacing(spacing); imgMsg->SetScalarType(scalarType); imgMsg->SetDeviceName("ImagerClient"); imgMsg->SetSubVolume(svsize, svoffset); imgMsg->AllocateScalars(); // Following line may be called in case of 16-, 32-, and 64-bit scalar types. // imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_BIG); //------------------------------------------------------------ // Set image data (See GetTestImage() bellow for the details) GetTestImage(imgMsg, filedir, i % 5); //------------------------------------------------------------ // Get randome orientation matrix and set it. igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix); imgMsg->SetMatrix(matrix); //------------------------------------------------------------ // Pack (serialize) and send imgMsg->Pack(); socket->Send(imgMsg->GetPackPointer(), imgMsg->GetPackSize()); igtl::Sleep(interval); // wait } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } //------------------------------------------------------------ // Function to read test image data int GetTestImage(igtl::ImageMessage::Pointer& msg, const char* dir, int i) { //------------------------------------------------------------ // Check if image index is in the range if (i < 0 || i >= 5) { std::cerr << "Image index is invalid." << std::endl; return 0; } //------------------------------------------------------------ // Generate path to the raw image file char filename[128]; sprintf(filename, "%s/igtlTestImage%d.raw", dir, i+1); std::cerr << "Reading " << filename << "..."; //------------------------------------------------------------ // Load raw data from the file FILE *fp = fopen(filename, "rb"); if (fp == NULL) { std::cerr << "File opeining error: " << filename << std::endl; return 0; } int fsize = msg->GetImageSize(); size_t b = fread(msg->GetScalarPointer(), 1, fsize, fp); fclose(fp); std::cerr << "done." << std::endl; return 1; } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestMatrix(igtl::Matrix4x4& matrix) { /* float position[3]; float orientation[4]; // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 0; phi = phi + 0.2; // random orientation static float theta = 0.0; orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; */ matrix[0][0] = 1.0; matrix[1][0] = 0.0; matrix[2][0] = 0.0; matrix[3][0] = 0.0; matrix[0][1] = 0.0; matrix[1][1] = -1.0; matrix[2][1] = 0.0; matrix[3][1] = 0.0; matrix[0][2] = 0.0; matrix[1][2] = 0.0; matrix[2][2] = 1.0; matrix[3][2] = 0.0; matrix[0][3] = 0.0; matrix[1][3] = 0.0; matrix[2][3] = 0.0; matrix[3][3] = 1.0; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Imager/ImagerServer3.cxx000066400000000000000000000167111501024245700222270ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtl_header.h" #include "igtlOSUtil.h" #include "igtlImageMessage.h" #include "igtlServerSocket.h" int GetTestImage(igtl::ImageMessage::Pointer& msg, const char* dir, int i); void GetRandomTestMatrix(igtl::Matrix4x4& matrix); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 4) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; std::cerr << " : file directory, where \"igtlTestImage[1-5].raw\" are placed." << std::endl; std::cerr << " (usually, in the Examples/Imager/img directory.)" << std::endl; exit(0); } int port = atoi(argv[1]); double fps = atof(argv[2]); int interval = (int) (1000.0 / fps); char* filedir = argv[3]; //------------------------------------------------------------ // Prepare server socket igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == headerMsg->GetPackSize()) { headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "GET_IMAGE") == 0) { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { //------------------------------------------------------------ // size parameters int size[] = {256, 256, 1}; // image dimension float spacing[] = {1.0, 1.0, 5.0}; // spacing (mm/pixel) int svsize[] = {256, 256, 1}; // sub-volume size int svoffset[] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage::TYPE_UINT8;// scalar type //------------------------------------------------------------ // Create a new IMAGE type message igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New(); imgMsg->SetDimensions(size); imgMsg->SetSpacing(spacing); imgMsg->SetScalarType(scalarType); imgMsg->SetDeviceName("ImagerClient"); imgMsg->SetSubVolume(svsize, svoffset); imgMsg->SetHeaderVersion(headerMsg->GetHeaderVersion()); #if OpenIGTLink_HEADER_VERSION >= 2 if (headerMsg->GetHeaderVersion() == IGTL_HEADER_VERSION_2) { imgMsg->SetMetaDataElement("Patient age", IANA_TYPE_US_ASCII, "25"); imgMsg->SetMessageID(i); } #endif imgMsg->AllocateScalars(); // Following line may be called in case of 16-, 32-, and 64-bit scalar types. // imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_BIG); //------------------------------------------------------------ // Set image data (See GetTestImage() bellow for the details) GetTestImage(imgMsg, filedir, i % 5); //------------------------------------------------------------ // Get random orientation matrix and set it. igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix); imgMsg->SetMatrix(matrix); //------------------------------------------------------------ // Pack (serialize) and send imgMsg->Pack(); socket->Send(imgMsg->GetPackPointer(), imgMsg->GetPackSize()); igtl::Sleep(interval); // wait } } } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } //------------------------------------------------------------ // Function to read test image data int GetTestImage(igtl::ImageMessage::Pointer& msg, const char* dir, int i) { //------------------------------------------------------------ // Check if image index is in the range if (i < 0 || i >= 5) { std::cerr << "Image index is invalid." << std::endl; return 0; } //------------------------------------------------------------ // Generate path to the raw image file char filename[128]; sprintf(filename, "%s/igtlTestImage%d.raw", dir, i+1); std::cerr << "Reading " << filename << "..."; //------------------------------------------------------------ // Load raw data from the file FILE *fp = fopen(filename, "rb"); if (fp == NULL) { std::cerr << "File opeining error: " << filename << std::endl; return 0; } int fsize = msg->GetImageSize(); size_t b = fread(msg->GetScalarPointer(), 1, fsize, fp); fclose(fp); std::cerr << "done." << std::endl; return 1; } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestMatrix(igtl::Matrix4x4& matrix) { /* float position[3]; float orientation[4]; // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 0; phi = phi + 0.2; // random orientation static float theta = 0.0; orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; */ matrix[0][0] = 1.0; matrix[1][0] = 0.0; matrix[2][0] = 0.0; matrix[3][0] = 0.0; matrix[0][1] = 0.0; matrix[1][1] = -1.0; matrix[2][1] = 0.0; matrix[3][1] = 0.0; matrix[0][2] = 0.0; matrix[1][2] = 0.0; matrix[2][2] = 1.0; matrix[3][2] = 0.0; matrix[0][3] = 0.0; matrix[1][3] = 0.0; matrix[2][3] = 0.0; matrix[3][3] = 1.0; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Imager/img/000077500000000000000000000000001501024245700175735ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Imager/img/igtlTestImage1.raw000066400000000000000000002000001501024245700231210ustar00rootroot00000000000000 "#%&*())))))*&$#"   !$,7CN[gq{‚‹’˜Ÿ¢£§¬­¬¬¬¬¬­­¨£¡ž˜Šwl^RE4)"  .G]qƒ“ž£¤¦¥§¨©©ª««¬¬­­®­®­­­­®®­­¬¬¬«ª©¨¨¦¥¤ Ž€hP6(?Ufp{ƒŽ•œ¤«¯²±±²°¯°°°°¯¯¯¯¯¯¯®¯¯®¯®®¯¯®°¯¯¯°¯°±²²°®©£™…wkZE(  (@So‚—ª®±±±±¯¯®¯®­¯®¯®®®¯®­¯®®¯®®®¯®®®®®¯¯®®®¯®®¯®¯¯®¯¯°°°°±²ªœ‡gG4 $@e†— ¤§©«­®®®¯­¯¯®¯¯®¯¯®¯®¯®®¯¯®¯®¯®¯®¯¯¯®¯®¯­¯¯®¯¯¯¯®¯®®¯®®¯¯®®­¬©¦£˜‚\1>Xk}Š˜¦­°±°°®®­¯®®®­®®¯¯¯¯¯¯¯®¯¯®®¯®­®®®¯¯®¯®®¯®®®®¯®¯¯®¯¯®¯®®®­®®¯¯®®¯°°­¤”kN0 &A\š­±±°¯¯®¯¯­®®®®®¯®®¯®®®®®¯¯¯¯®®®¯¯®®¯®¯®®¯®®®¯®¯¯®®¯®®¯¯®®®¯¯¯®¯®®¯¯®¯¯¯¯°±°ªpI% Cq‘ž¦©¬®¯¯®®¯­®®¯¯­¯®¯¯®¯­¯¯®¯®¯¯®®®¯®®¯¯¯®¯®¯®®®¯¯¯®¯­®¯¯®®®®¯¯¯¯¯®®¯®¯¯®®®¯¯¯¯¯¯­«§¢k;FcxŠ©¯°°¯®®¯®®®®¯¯¯®¯®¯¯®®®¯¯®®®­®®¯¯®¯®¯®®®­¯®®¯®®¯®®­®¯®®¯®¯®¯®®¯®®¯®®¯®¯¯®®¯¯®®®¯®¯°¯©™„mF$ "?aŠ£°°°®¯®¯¯®®®®¯¯¯¯®­¯­¯®®®®®®¯®­®¯¯®®¯¯®¯­¯¯®¯¯­®®®®®¯®¯®®¯¯¯¯®¯®®¯®®¯¯®¯®®®¯®®®®®®®®¯®¯®®±¯ª†b5 "Lƒ™¥ª¬­¯®®®¯®®¯¯¯¯¯¯®­®¯®¯¯¯¯®¯¯¯®¯®®¯®¯¯¯¯¯¯®®®®¯¯¯®¯®¯®¯¯®¯¯®¯®®¯¯®®¯®¯®­®®®®¯®¯¯¯¯¯¯¯¯¯®¯®¯¯®®©£˜h? C\z¥®²°°®®®®¯¯¯¯®®¯¯¯®®¯­®¯¯®®®®®¯®¯®¯¯®®¯¯¯®¯¯¯¯®¯¯®¯®®¯®®®®®¯¯¯¯¯¯¯¯®®®®¯¯®®®¯¯®¯¯¯®¯®¯®®®®¯®®®¯®°°­™…eF.Q‡¯±¯®¯®®¯¯®®¯®®¯®¯¯®®®®®®®®®®®¯®¯®¯®¯®®®®¯®®¯®¯¯¯¯¯®®®®®¯®¯®®¯¯¯­¯®¯®¯¯¯¯¯¯®®¯®®®¯¯®®¯®­®®®¯®¯¯¯®®®®®¯±®£‹Q)g‰£ª¬¯¯­¯¯®®®¯¯®®®¯®¯®¯¯®¯®®¯¯¯¯¯®¯¯®®®®®®®®¯®¯®¯®¯®®¯¯¯®­­¯¯¯¯¯®¯¯¯­¯¯­¯¯­¯¯®®®¯¯®¯®®¯®¯®®®®¯­®®¯®®¯¯¯¯­¯­®­ªŸ['Vw—¦°±°®­¯­¯®¯¯®®®¯®¯®®®®¯®®®®¯¯®®¯®¯®¯¯¯¯®®®®®¯®®®®¯¯¯¯®¯®¯®®¯¯®¯®­¯¯­®®¯­¯¯¯¯®¯®®¯¯¯¯¯®®®¯®®¯®®®¯¯®®¯®®¯¯¯¯­¯°°£‘kF!^®°¯®¯®¯¯®®¯®®¯®®®¯¯®®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯¯¯®®®®®¯®®¯¯®¯®®®¯®¯®¯®®®¯¯®¯®¯¯®¯®®®¯®®¯­¯¯®®®®®®®®¯¯¯¯¯¯­®°®§}BX{™¥®¯®¯¯®®®¯®¯®®¯¯­¯®¯¯®¯®¯®®®­®®¯¯¯®®®®®¯®¯­®¯®¯¯®¯¯¯¯®¯¯®¯®¯¯®¯®¯®®®¯®®®¯¯®¯¯¯®¯­¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯¯¯®®¯¯¯®¯¯®¯®¯®®¬¡f@6[Ž¥°¯¯¯®¯¯®®¯®®®®®¯®¯¯®®®®®®®¯®®¯®¯¯¯®¯¯¯¯®­®®¯¯®¯¯®¯¯¯°°±±±±°¯¯¯­¯¯¯¯¯¯®®®¯¯¯¯®®¯¯¯®¯®®®¯¯­®¯¯®¯¯®®¯¯®®®¯¯®®®®®®®¯¯®®¯¯°­–zG&D†§­¯¯¯®®¯®®¯®®¯¯®®¯¯®®®®¯®®¯¯¯­®¯®¯¯¯¯¯­¯®®­¯¯®¯®¯¯¯¯¯¯¯¬«©©©©ª«­®®®®¯¯­¯®¯®®¯®®®¯®¯¯®­¯¯¯®¯®®¯®®¯¯¯®¯¯¯®¯®¯®®®®®¯¯¯¯¯¯¯­¯¯¯©œo*,\ަ­®¯¯®®®®®¯®¯¯¯®¯¯¯®®¯¯¯¯®¯®®®¯®¯¯¯­¯®®¯¯¯®®¯¯¯®¯¯®¯¯¯¯«}^OIM[r”¥¯¯®®®¯¯®¯¯¯¯®¯¯®¯¯¯®®¯¯®®­®¯®¯­¯®®¯®®¯¯¯¯®®¯®¯¯®¯®®®®®®¯¯¯®ªŸƒK (l‘¬±¯¯®¯¯®¯®¯®®¯®¯¯­®¯®®¯¯¯®®¯®¯®¯®¯®¯®®¯®¯®®®®¯¯¯¯¯¯®¯¯­›„\B# 8]x”£¯¯®®®®¯®®¯®¯®¯¯¯¯¯¯®®®®¯¯¯¯®®¯¯¯®¯®®®¯¯®®¯¯¯®¯¯®®¯¯¯¯®¯®¯¯¯§…[%@|¢¯¯¯¯¯®®¯¯¯¯¯®®¯¯¯¯®®¯¯¯®®¯­®®¯®¯¯¯¯®¯¯¯®¯®¯¯¯­®¯¯¯®­¯®ªžb) P~©­¯¯¯®®®®¯¯¯¯®®®¯¯¯¯¯®¯®¯¯¯¯¯®®®®­¯®®®¯®¯¯®¯¯®¯¯®¯¯¯®®®¯®®¯®¯›s6T¡«®®®¯®¯®¯®­¯®®¯¯¯¯¯¯®¯®®®¯¯®®®¯¯¯®¯®®®¯¯¯®¯¯®®®¯¯®¯®¯®ª‘Q& >s ±®¯¯¯®®­¯¯¯®®¯¯¯¯¯®®®¯®¯®®®®®®¯¯¯¯®®®¯¯®¯¯®®®¯®¯®®®®®¯®¯®¯¯ªŸ~XOФ±¯®¯®®¯®®®¯¯®¯®¯¯­®¯®¯®®¯®®®¯®¯®®¯¯®­®¯¯¯®¯¯®¯®¯¯®¯®¯¯¬`?«®¯®®¯¯¯®®®®®¯®®¯¯¯®¯¯¯®®®¯®¯¯®¯®®®¯¯¯®®¯¯¯¯®®¯®¯®¯¯®®®¯®¯¯°±¢U#Z‘«¯¯®¯®¯¯®¯®¯¯®¯®®®¯®¯®¯¯¯®¯®®®®¯®¯¯®®­¯¯®¯®®®®®¯¯¯¯®®®¯« Usœ®¯¯¯®®¯®¯®­®¯®®¯®®¯®¯®¯¯¯¯¯¯®¯®®®¯¯®®¯¯®®¯®¯¯®®¯®¯¯­¯®®®¯®®¯¯«i$!\‹¨®¯¯¯¯®®¯®¯®¯¯®¯¯®®¯®®®®®¯¯®¯®®®®®¯®®­®¯®®®¯®®®®¯®®®®¯¯°“l, Z†¬¯¯®¯¯¯®®¯®¯¯®¯®®¯¯¯®®¯®®¯¯­¯¯®®­¯¯¯®®¯¯¯¯¯®®­¯¯®¯¯¯®®­®¯¯®¯¯®ª—}< TŽ¥±®¯­¯®®¯®®¯¯®®¯®¯¯®®®®¯¯¯¯¯¯®¯­®¯¯®®®®¯¯¯®¯¯®®¯­®¯®®®®¬ªw5 Kx¬°®¯­¯¯¯®¯®®®®®®¯®¯®¯®¯¯®®®¯¯¯®¯¯®®¯®®®­¯®®­¯¯¯®®­¯¯¯®¯¯¯®¯¯®¯¯­¦r> Y‰®¯®¯­®¯®®¯¯®¯¯®¯®®¯®®¯®®¯®®®¯®®®®®®¯®¯®¯¯¯¯¯®®¯®¯¯®®¯¯®°¨˜U  Hv«¯¯¯®®®¯¯¯®®¯¯¯®¯®¯®¯®®¯¯®®¯®¯®¯¯¯®®®¯®¯¯®¯¯¯®­¯¯®¯¯®®¯®¯®¯®¯®®®¯¤Ž6?¤¯®¯­­¯¯®¯¯¯­¯®®®¯®­®¯¯¯®­¯¯®¯®®¯®¯¯¯¯®¯¯®®®¯¯¯¯¯­®®®¯¯¯±šh3Gj|S2 W„¬®®¯­¯®¯¯¯®¯®¯®®®¯®¯¯¯®®®®®®®¯®¯®¯¯¯®­¯¯¯¯¯®¯®®¯®¯¯¯¯¯®®¯®¯®¯®®¯®¬¦…H ;z©¯®®®®®¯¯¯®®¯¯¯¯®®¯®¯¯®¯®®®¯®¯¯®¯®®®®¯¯®¯®¯®®¯¯¯¯®­®®¯®¯­®‹7,{žª‹bp–®®®¯¯¯¯¯¯®®®®®®®¯¯®­®®¯¯®®¯¯®¯¯®¯®¯¯®¯®¯®®¯¯¯¯¯¯¯®¯¯¯¯¯¯®¯®¯­¯®®¯¯®ª{B "tª¯¯®¯¯¯®¯¯®®®®¯®®¯®®¯®¯®®¯®¯¯®¯®­®¯®¯¯®¯¯¯¯¯¯®¯¯®®¯®¯®®®¯®¤tH£¯¯­’MA’­¯¯¯®®¯®®¯¯®®¯®¯®¯®®®®¯­¯¯¯®­¯¯®®®¯®¯®®®¯¯®¯¯¯®®®®®¯¯®®®¯¯®®®®¯®®®¯®¯¥9 n–®¯¯¯¯¯®¯¯®¯®®¯¯®®¯®¯®®¯®®¯®¯¯¯®®®¯¯¯®¯®¯®®¯®®®¯¯¯®­¯®®®®°«†P&^§¯¯¯¦_; $BdŒ¥¯®®¯¯®¯¯®®®®®¯¯®®¯¯¯¯¯®®¯¯¯¯®®¯¯¯®¯¯¯®¯®®®®¯®¯¯®®¯¯¯¯¯®®¯®®®¯®®¯­¯®¯®¬¦}QI›¨°¯®­¯¯®¯¯¯¯¯®®¯®®®¯®¯®¯®¯®¯®¯¯¯®®¯®¯¯¯­®®®®­¯¯¯®®¯®®¯¯®¯¯¨g-5n©°®¯®­uVKGP_{”®®¯®®¯®®®¯®¯¯®®¯¯¯®®¯®¯¯¯¯®®¯­¯¯®¯¯®®®®¯®®®®®®¯¯­­¯¯¯¯®®®®¯¯¯®®®¯®®¯®¯¯°¯¡5 J{¬¯®¯®®¯®¯¯®®®®®­®¯¯®®®¯®®®®¯­¯®®¯¯¯®¯¯¯¯¯®¯¯¯¯¯®¯¯¯®¯¯®®¯¯«žC D|ª¯¯®®¯®­ª¨§¨«®¯¯®¯¯¯¯®¯®®®®®®®¯®¯¯®¯®¯¯¯®®®®¯®®¯®®®®¯¯¯®¯®¯®®®®¯¯®®®¯¯¯®®¯®¯®¯®¯®¯®¯¯®¯®®¢|5*ž¯¯¯¯¯®®®®®¯¯¯®®®®®¯®®¯¯®¯­®®¯¯®®¯¯®¯¯¯®®®¯¯®¯®®¯®®®¯¯®¯¯®°¢„/Q‰«°®¯®®¯®®­­®¯®¯®¯®®¯¯¯®¯¯¯¯¯¯¯®®®®¯¯¯®¯®¯®¯¯®®¯®®¯®¯¯¯®®®®­¯¯®®¯¯®¯¯­¯®¯¯®¯¯¯®¯¯¯®¯®­®¯®®« f0W›¯®¯®®®®®®¯¯¯®¯¯¯®®¯®¯®¯®®®®¯®¯®¯®®®®®®¯®¯®¯¯®®®¯¯®®®®¯¯®¯¯¯–d^”«¯¯®®¯®¯®¯®®®¯¯®¯®®®¯®®­¯®¯¯®®¯®¯®®®¯®¯®¯¯¯¯¯®®¯¯®®®®®¯®®®¯¯®¯¯¯®®­¯¯®®¯¯®¯¯®®®®¯¯¯¯¯®¯¯¯¯¯ŒeH¨°®®¯­®®®¯®¯­¯®¯®¯¯¯¯­®¯®®®®¯¯®®¯¯¯¯®¯¯®®¯¯®¯®¯®¯¯®¯¯¯®®¯®¯±ˆ9iž­®¯®®®¯¯®¯¯¯®¯®®¯®®¯¯®®®®®¯®¯­®¯®®®®¯¯®¯¯®®®¯¯®®®­®®¯®®¯¯¯®¯¯¯¯®¯®®¯®¯®¯¯¯®¯®¯®®®¯®®¯¯®¯®¯¯ª›C,m¦¬¯¯®®¯®®®¯¯®®¯®¯¯®¯®¯¯®¯®®¯®®®®­¯®¯¯¯¯®¯®®®®®®®¯®®¯¯®¯¯¯®¯¯­v r¥®¯®­®®¯®®¯®¯¯®¯¯®®®®®¯®¯¯®®®®¯¯¯¯¯®¯¯¯®®®®¯¯¯®¯®¯¯®®¯¯®­¯¯¯¯¯®¯¯¯¯¯¯¯¯®­®®¯¯¯¯®®¯¯®®®®®¯®¯®®¨{J]‹±®®¯®®¯¯®®®¯¯¯®¯®®®¯®¯¯¯®®®®®®¯®®¯¯®¯®¯¯®¯®¯®®®¯®®®¯®¯¯¯¯¯¯¬¡dz­®¯®®®®®®®®®¯®¯¯¯®¯®¯¯¯¯¯®®¯¯¯¯®®®®®®®¯¯¯¯®®®®­¯¯­¯¯®¯®®¯®®¯®®¯®®®¯®®¯¯¯¯®¯®¯¯®®®¯®¯®¯®®®¯¯¯°®Ÿu8’¦¯®¯®¯¯®®®®®®®®®¯¯¯¯®®¯®­®­¯®¯¯®®®®¯¯®®®®®®¯¯®¯¯®¯¯¯®¯­¯®¯¯®¨…J‚±¯®¯®®¯¯¯®¯¯®¯®¯®¯®®¯®¯®¯¯¯®¯®¯¯¯¯®®¯®¯­®¯®®¯¯®®®®®¯¯¯¯¯®®®¯®¯®¯¯®®¯®¯¯¯®¯¯®®®®¯¯®¯®®®¯®¯¯¯¯¯®¯”D&^¤¬®¯¯®®¯¯®®®®¯®®¯¯¯®¯®®®¯®¯¯¯¯¯®®®¯®®®­¯¯®¯®®­¯¯¯¯­¯®¯¯¯¯®¯®±¤i3 #‡²¯­¯¯¯¯¯¯¯¯®®¯®¯¯®¯®¯®¯¯¯¯®¯®®¯¯®¯®¯­¯®¯®®¯®®®®®¯¯¯¯¯®¯¯®¯¯¯®¯®®¯®®¯®®¯¯®®®¯¯®¯¯¯®¯®¯®¯¯®®¯®®¯¯¤~5O€­¯®®®¯®¯®®¯®¯®®®®¯¯®®®¯¯®®¯®¯¯®¯¯¯®¯®¯¯®¯¯®¯­¯¯¯®¯¯¯®¯®¯¯®®®°žK1‹³®®¯­®®¯®¯¯®¯¯®®¯¯®®¯®¯®®®¯¯¯®®¯®¯¯®¯¯®¯®¯®¯­¯¯¯®¯¯¯¯®¯®¯¯¯®¯¯®®¯¯¯®¯¯®®®¯®®®¯®®®®¯¯¯¯®¯¯®¯®¯®¯­ŸV¢­¯®®¯¯®¯®¯¯®¯¯¯¯¯®¯­®¯®®­¯¯¯®¯­¯®¯®¯¯®¯¯®®¯­¯®­®®¯¯¯¯®¯¯®¯®¯¬–0 A±®¯¯®¯¯¯®®¯®®¯®¯¯¯®®®®®®¯®®¯¯®¯®¯¯¯¯®®¯®®®­®®¯®®¯¯®®®®®®¯¯¯®¯¯¯­¯¯¯®®¯®®®¯®®®¯¯¯®¯¯¯¯¯®®®®¯¯¯®®°¬w96”¬¯¯¯¯®®¯¯¯®¯®¯®®¯®®®¯¯¯¯®®¯®¯¯¯®®®®®¯®¯¯®¯®¯®®¯®­®®¯¯¯®®®¯¯¯¯¥„ $R“²¯®¯®¯¯®®¯®¯¯¯®¯®¯¯®¯¯¯¯®®®®®®®®¯®®®¯¯¯¯®®®¯¯®¯¯®®¯®®®®¯¯®¯®¯¯¯¯®®­®¯®®®¯®®¯®®®®®¯¯¯¯®­¯¯®¯®®®®¯­–l"b¡°¯¯®®®®®®¯¯®®®¯®®¯®®¯­®®®¯­¯®®®®®¯®®®¯­®¯®¯®¯®®®®®¯¯¯®®¯¯¯®¯°šm,b˜²¯¯®¯¯®¯¯®®®¯®®®®®¯¯®¯¯®¯¯®¯¯®¯¯®¯¯®¯¯®®­®¯®®®¯­®¯®®¯¯¯®¯­®¯¯¯®¯®®¯®®®¯®¯®¯¯¯®¯®¯¯¯®®®¯®¯®®¯®¯®®¯ª)D©°¯®¯®¯¯¯®¯¯®­¯®®¯¯®¯¯®¯¯®¯¯¯®¯®¯®®¯¯®®¯®®®¯®®¯¯¯®¯¯®®®®¯¯¯¯¯¯ŠO4q›°®®¯¯®¯¯®®¯®®®®¯­¯¯®¯¯®®®¯¯¯¯®®¯®®¯®®®¯®®¯¯®¯¯®¯¯¯®®¯®®¯¯¯¯®®®¯®®¯®®®¯¯¯®¯¯®®¯¯¯®®¯¯­­®®¯¯®¯®¯®®¯°žW-b¤­®®®¯®®®­¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯¯®¯®®¯¯®®®¯®¯®®­¯®®®®¯®¯¯¯¯¯¯¯®®¯®z3 =~ °¯¯®®®¯­®¯®®¯¯¯®®¯®¯®®¯®¯®¯®®¯¯®®®®®¯®®®®®®®®®®®¯®­®¯®¯­¯¯®®¯¯­¯®®®®®®®®¯®®¯®®®®¯®¯¯¯¯¯®¯®®¯¯¯®¯¯¯¦†S,u­®®®®¯®®®¯®­¯®®®®¯¯¯¯®¯¯¯¯®®®¯¯®®¯¯®®®¯®¯®®®®®®¯¯¯¯¯®¯®®¯®®¯¯®­nD‰£°®®¯¯®­¯®®®¯®¯¯®®¯®¯®¯®®®®¯®¯®®¯¯®¯®¯®®¯¯­¯¯®¯®®®¯¯¯¯¯¯®®¯¯¯®¯¯¯¯®®®®®¯¯®®®®®®¯¯®¯¯®¯­®®¯¯®¯®®¯¯®¯¬¢l WŒ¯¯¯¯¯¯¯¯¯¯®®®®¯®¯®®®®¯¯®®¯¯®¯¯®®®®®®¯®­¯®¯¯®®®¯¯®¯¯®¯¯®®®¯¯¯¯¬¦^M•¦°®®®¯®¯¯¯¯®¯¯¯®®¯¯¯®¯¯¯®¯¯¯®¯®¯¯®®¯¯®®¯®®¯¯®¯¯¯®¯¯¯¯¯®¯®¯¯®¯®¯®¯®¯®¯®®®®®¯®¯­®¯®¯¯­®¯®¯¯®®¯®®¯®®¯¯®°„2}Ÿ¯®®®¯®¯®¯®¯¯¯¯¯®®¯­¯®®®®®®¯¯®®®¯®¯¯¯®¯¯®¯®®®®®®®®®¯¯¯®¯®¯¯®¯°¨˜OU ª®®®®®¯®¯®­¯­®®®¯¯¯¯¯¯®¯¯¯¯®®¯®®®¯¯®¯®®­¯¯®®¯®¯¯¯®®¯®¯®®¯¯¯®®¯¯¯®¯®¯®¯®¯¯®®®®¯®®¯¯¯¯®®®®®¯®®®®®®®®®®±–d)(˜¬¯®¯®®¯®®®¯®®­¯¯¯®¯¯®¯®®¯¯®®®¯®®¯®®¯¯®®®¯®¯®®®®®¯®¯¯®®¯®®­¯®®°¡„A]¨¬°®®¯¯¯¯¯¯®®¯¯¯®¯¯®®®®®¯®®®¯®®®¯¯¯¯®®¯¯¯®®®¯®®¯®¯¯®®¯®¯®®¯®®¯¯®®¯¯¯®¯¯®®®®¯®®¯¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯°£?I¡¯¯®¯¯®­¯®¯¯¯¯®¯®¯®®¯®¯®®®¯®­¯®®¯­®®¯®®¯­®®¯®®®¯¯¯®¯®®®¯¯®®¯®¯°˜d0 d¯®®®¯¯®®¯®¯¯¯¯¯®¯­®¯®®¯¯®®¯®¯®¯¯¯¯®¯¯­¯¯®¯®®®¯¯¯®¯®®­¯¯¯¯®¯®®¯®¯¯¯¯¯®¯¯¯¯®®®®®¯¯¯®¯®®®¯®®®¯­¯®¯¯®¯¯¯¯¯­¨\8j¦°¯¯®®¯¯®®¯¯¯®¯®®®¯­¯®®¯®¯®®®®®®®¯®®®®®®®¯¯®¯®®®®®¯¯®®¯®¯®¯®¯¯±‘J! l±¯¯®­®®®¯¯®®®¯¯¯¯®®¯®®®¯®¯¯¯¯¯­®®®®®®®®®®®¯®¯®¯®¯¯®®¯®®¯®¯¯®®¯®®®®¯¯®®®¯¯¯¯®¯¯®¯®¯¯¯®¯®®¯¯®®¯¯®®­¯®®¯¯®®u/Y‰©¯®®¯®¯¯¯¯®­¯¯¯¯®®®¯¯­¯¯®®®¯®®®¯®®­®®¯®®¯®¯®¯®¯¯®®®¯¯®¯®®®®¯®®°‰0,u±¯®®®®¯­®®®®®­­®®¯¯¯®¯®¯®¯®¯®®¯¯®¯®®®¯®¯®®®®¯®®¯®®®¯¯®®®¯®¯®¯®®¯®®¯®®¯®¯¯¯®¯®¯®¯¯®®®¯¯®¯¯¯®®®®¯¯¯¯¯¯®¯¯¯ŠSv¦¬®®®®¯®¯®®­¯®¯®®®¯¯®®®­¯¯®­®¯¯­¯¯®¯®®®¯®®¯®®¯¯¯¯®¯­®®¯®¯®¯¯®¯®­~>~±¯¯¯®®®¯®®®®¯®¯¯¯®¯­¯®¯¯®¯®¯®­®¯¯®®®®¯®®®®®¯¯¯®¯¯¯¯®¯¯®®¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®¯®¯¯®¯®®®®®®¯®®®®¯¡|„®®¯®¯¯¯¯¯¯¯¯®¯®¯®¯®®¯­¯®®¯¯®®®®®®®¯¯®¯®®®®®®®®¯®®®®®®¯®®¯¯¯®®¯¬£p P…°®®®®¯®¯¯¯¯®®®¯®¯¯­®®¯®¯®®¯®¯¯¯¯®®¯­¯®®¯®­¯®®¯¯¯®®¯¯®®¯¯®¯®¯®¯¯¯®®­¯®¯®¯®¯¯¯®®¯®®¯®¯¯¯®®®­¯®®¯®®¯¯®®®¯®®«-7±®¯¯®¯®¯¯®®®®®¯¯®¯®¯®¯¯®®®¯®®®®®®¯¯®®¯¯®¯®¯¯®®®¯®®®¯¯­®¯®¯¯®®¯ª•`bް¯®¯¯®¯®¯®®¯¯¯®®¯¯¯®®¯¯®®®®¯®®¯®­®®¯®¯¯®®®®¯®®®®¯¯®®¯¯¯¯®®¯®®®¯¯®¯¯¯¯®¯®¯¯®®¯¯¯®®¯®®¯®®®­®¯­¯®®¯¯­®®®¯®®¯›H*Z—²®¯®¯®®®¯®®®¯¯®¯¯¯¯®®¯¯®¯¯®¯®¯®®®¯¯¯®¯­¯¯¯¯®¯®¯®¯®¯®¯®¯®¯®®®¯¯§}M%s–®¯¯¯®®®®¯¯®¯®®®¯¯­¯¯®®¯¯¯®®®¯¯¯®¯®¯®¯¯®¯¯®¯®®¯®®®¯­®¯®®®¯®¯®®¯¯®¯®®¯¯¯¯®®¯®¯¯®­¯¯¯®®®¯®®®¯¯¯®®¯¯®®¯­®¯¯¯¯¢n1Euž«¯°¯®¯¯¯¯®®¬¢e3€ª®¯¯°¯¯¯¯®®­¤’\4(o©°®¯®­¯¯­¯®®®®¯®¯¯®¯¯®¯®®¯¯®¯®®¯®¯®¯®¯­¬l' `“°¯®¯®¯®¯¯­¯®¯®®¯®­¯¯¯®®®¯®¯®®®®¯®¯¯¯¯®®®®®¯®®®¯¯®¯®¯®¯¬rD cŠ­¯¯®¯¯¯¯¯®®®®®¯®¯¯¯®¯¯®®­®®®¯®¯¯°¥o65p›­®¯®¯­®­¬©„M f”§«­®®®¯¯®­¨YaŽ®¯®®®¯­¯­®¯®¯¯®®®®®®¯¯®®¯­®®¯®®¯¯®¯¯¯¯®¯hGˆ±¯®®®®®¯®®®¯¯¯®®®¯¯¯®®¯¯¯®®®¯®®®¯®®®¯¯¯®¯®®¯®®®®¯¯®¯®°¬a0{𮝝¯®®¯¯®¯¯®®®®®®®®¯®®¯­¯®¯¯¯¯¯®®¬Ÿj &Gax‚‚~uj^N@. !7KYfp{€‚‚|mU2C‘¥¯¯®®¯¯®¯®®¯®®¯¯¯¯¯¯­®¯®®®®¯®®¯®¯®®¯­¯¯®®§–?'}¯¯­¯¯¯®¯®®¯¯¯®­®¯¯®®¯®¯®¯®®®¯®¯¯®¯¯¯®¯®®®®¯®¯¯¯®¯¯®®®®©R #Œ¦®®¯­¯®®¯®¯¯¯®®¯¯¯®®¯®®®®¯®®¯¯®­®¯®°Z/">GJJF9,  '2?HJJA0Hw©¯®¯¯®®®®¯¯®®¯¯¯®¯®¯®®®®®®®®¯®¯®®¯®­®®¯®®¯±«h+m±¯¯®­¯®¯®¯¯¯­­¯®¯¯®®®¯®®®®®®¯¯¯¯¯¯¯®®®¯¯®®®®¯¯¯®¯®®¯®¬¤C.š®®®¯¯®®®¯®¯­¯¯¯®¯®®¯¯®®®¯¯¯¯¯®¯®®¯¯¯ª£k6Lˆ©¯®¯¯¯®®®¯¯®¯¯¯¯¯®¯¯®®®¯®®¯¯¯¯¯¯¯¯®®®®®®¯®¯¯­™cY¥¬°®¯¯¯¯®®®­¯®¯®®¯¯®¯®¯¯¯®¯¯¯®¯®¯¯¯¯®®¯¯®®®®®®¯®¯®®¯¯©œ5F °®®®®®®¯®¯®®¯®¯®¯®¯¯®®¯®¯®¯¯®®¯¯¯®¯¯¯­œ‡\2 Ih‘¤¯®¯¯¯®®®¯®®¯®®®®®­¯¯®¯¯®®¯®¯®¯®¯­®®®¯¯¯­®¯¯¯®«†; K’¦°¯¯®¯¯¯¯­®¯¯¯¯®¯¯®¯¯®®¯¯®¯¯®­¯¯¯®¯¯¯¯¯®®®¯®®¯¯®¯®®¯¥’,*`¤°®®®®­­¯¯¯®¯¯¯®®¯®®¯¯®¯¯¯¯¯®®¯®¯®¯®¯¯¯°­c+  #&  &   A𝝝¯®¯¯®®¯¯¯®¯¯¯®¯®®¯¯¯¯®®¯®®®®®¯¯¯¯®®¯¯®­¯®¯®¯°p(8rž±¯¯®®®­®®®®¯¯®¯®®¯®®®¯®®®®®®¯®¯¯¯­®¯®®®¯®®¯¯®¯®¯®¯°ž‚$>{¨®®®®¯¯¯®®¯¯¯®®¯®®®¯¯¯¯®®®¯®¯¯®®¯®­¯®¯®¯¯®ŽV !A\s}„\'Am‚r`I(Dp£¯¯¯®¯®¯¯¯¯®¯®­®¯¯®®®®®®®®­¯®¯¯¯®®¯®®®®®¯¯®¯¯¯®¯®®¬¢OL•±¯¯¯®®­­¯¯¯®¯®¯¯¯®¯¯®¯®®¯®¯¯¯®®®®®¯®®¯®®®¯®¯¯¯®¯¯¯°•kR“«°¯®¯®¯¯®¯®¯®®¯­¯®¯®¯®®¯¯¯¯®®¯¯®®¯®®®¯®¯¯°ˆ9 A`— ¤¥s1T‹¥Ÿ˜†nM$-X¢³¯¯®¯®¯¯®¯¯®¯®¯¯®®¯¯¯­®¯­¯¯¯®®¯®®®¯®®®¯­®®­®®¯­¯®¯­K )Н®®¯®¯¯¯®®®®¯®®¯®®®®¯®¯®¯¯¯®¯¯¯¯®¯¯¯®®¯®®®®®¯®¯¯¯¯±W c¢­¯®®®¯®®¯®­®¯®®®®®®¯¯®¯¯¯¯¯¯®¯¯®¯­¯®¯¯¯¯¯®{*v™®°°¯°­z5Z”²°¯°°£‡P?›±®¯®®­®®¯®¯®®®®®¯¯¯¯¯¯®®¯¯®¯®¯¯®®®¯¯­®¯¯®¯¯­¯¯¯®®¯¯~!«®®®®¯®¯®¯®¯¯®¯®®¯¯®®®¯¯®¯®®¯¯¯®®®¯®®®¯®¯¯¯®¯¯¯¯®®±…Cr­¯®®®®¯¯¯®®¯¯¯®®®®®®®¯®®¯¯¯®­®®®®®¯®¯¯¯®¯®©o 4b𮮝­®®­y3Z”±¯®¯®­­C +“­¯®®¯®®­®®®¯¯¯®¯®®¯¯®¯®¯¯¯®¯®®®¯®®®¯®¯®®®¯¯¯®®®®¯®®®ŸKPœ«°¯¯®¯¯¯¯¯­®®¯®®¯¯®¯¯®®®®¯­¯®¯¯®¯¯¯¯¯¯¯®¯®®¯®¯®®¯±2 6~°®¯®¯®¯¯¯¯¯®¯¯¯®¯®¯¯®®­¯®®®®¯®¯¯®­¯¯¯¯®®¯­¡g Bx¢±®¯¯®¯¬|9Z”±¯¯®®¯°‹Z!ª¯¯®¯¯®¯®¯¯­®¯®¯¯¯¯®¯®®¯®®®®®¯®®®®¯®¯®­¯®¯®®®¯®®¯®®°©yK-|§¯®¯¯®®®¯®®¯¯®¯­®¯®¯®¯¯¯¯®¯®®®­®¯®®¯¯®®¯¯®¯¯®¯¯®®°tX¯­®®®®¯­®®®®®¯®¯¯¯®®¯®¯¯¯®¯¯®®®®¯®®¯®¯®¯®­˜_K…¥°®­®®¯¬€? Z”±¯¯¯¯¯¯”m†¥¯¯®®®¯¯®®®®¯®®¯­¯®®¯®®¯®®¯¯¯®¯®¯®®¯¯¯¯®®¯®¯®¯®¯¯¯®¯®¦|V¤¯®¯®¯¯¯¯®¯®®®¯®®®¯¯¯®®®®¯®®®®¯®¯­®®®®®¯¯®®®®¯­®®ªjx𰝝¯¯®®¯¯¯¯¯®®­¯®¯®®¯¯®­¯®®¯¯®¯¯®¯®®®­®¯°«“YK‚£°®¯®®¯­C Z”°¯®¯®¯¯g„¤®®¯®¯®®®®¯¯¯¯®¯®®®®®¯®¯¯¯®®¯¯®®®¯¯®¯®¯®¯¯¯®®®¯¯¯­®¯®­–^0œ­®¯¯®®¯®®®¯®®¯¯¯¯®¯¯¯¯¯¯¯®¯¯®®¯®®¯¯®¯­®®®¯®®®®¯­¥a,’¦¯®¯¯¯®®¯®®¯®­®¯®®®®¯®¯®®¯®®®®¯®®®¯¯®®¯®®®¬–\>qŸ±®¯®¯¯­A `–²¯¯¯¯°°‡P†¥¯¯¯®®¯®¯¯®¯¯¯¯¯­®¯®®®¯®®®®®®¯®®¯®®¯®®®¯¯¯®®¯®®®®®¯¯­¯¦ŽC †¥®¯¯¯®¯®®®®¯¯¯®®¯­®®®¯®­®®®¯¯¯¯¯¯¯¯®®®®®®®®®®¯®­›V >£¬¯®®®®®®®¯¯®¯¯¯¯®®¯¯®¯­¯¯®®¯¯¯®¯¯®¯®¯®®®¯®­¡i (P—±¯®¯¯®­‚B g—°¯®¯¯®­v/ %©®®¯¯¯®­®¯®¯­®¯®¯®¯®®®¯­¯¯¯®®¯®­¯¯¯®¯®®®®¯®¯®®®¯¯®®¯¯®°«l:\¯®®¯®­¯®¯¯¯¯®¯­®¯®®­¯®®®¯¯¯¯®®®¯¯®®¯¯¯¯¯®¯®®­°«ŒI(W©®®¯¯®¯®®®®®®¯¯¯®®®¯®¯¯®®¯®¯®¯¯¯¯®®¯¯®¯¯¯®®¯­z "„¨¯¯®®¯­C "i˜°¯¯®°©šV =™¯¯¯®®®®¯¯®®®¯®®®¯®¯­®¯®¯¯¯®¯®¯®¯®®®®¯®®®¯¯®¯®¯®¯­®¯¯®®¯­š{.z­®®®¯®®®¯¯¯¯®®­¯®®¯¯®¯¯¯®¯®®®¯®®¯¯®¯¯®¯¯®¯®®¯¯©{=Fv¬¯¯¯¯¯¯¯¯¯®¯¯®®®¯®¯®¯®®¯®®®¯¯¯®®¯®¯®¯®¯®®¯®¯±ŽO Qy£­°¯¯®C "j™±¯±°«Ža.?l¤±¯®®¯®¯¯¯¯¯®­¯¯®¯®¯¯®®¯¯®®®¯®®®®¯®®¯®®¯¯¯®¯®®®¯¯®¯®®¯¯¯®­œN [©®¯­®®¯®®®®¯®¯¯¯¯¯®¯¯¯¯¯¯®¯®®®®¯®¯­­®¯®®®¯­®¯°¨i1 f“­®®¯®¯¯®¯¯¯¯®®¯¯¯®¯¯­¯®®®¯®®®¯¯¯¯¯®¯¯¯®®®®¯®¯¢…20š§ª««D i—­«¨£^k˜«¯¯®¯¯®¯¯®®¯­®®­¯­®¯®®®¯®¯¯¯¯®®¯®®¯¯®®®¯¯¯¯®®®¯®®®¯¯®®¯®¯¯©ˆQ/ލ¯¯®®¯¯®¯¯¯¯¯¯¯¯®¯®¯®®¯¯®®®¯¯¯¯¯®¯¯¯¯®¯®®¯¯¯¯¦W#}¥¯¯¯®¯¯¯¯®¯®¯¯®¯®®¯®®¯®¯®®®®¯®®®®¯¯¯¯­­¯®¯®®®¯¬¥Z! "Dd…—¢‚J !e sS3A«®¯®®¯¯¯­®®¯¯®¯®¯­¯®®¯®®®®¯¯®®®¯®¯®®¯®¯¯®®­®®®®®®®®®®®­¯®¯¯­©0b¡°®®¯¯®¯®¯®¯¯¯¯¯®®­¯¯¯¯¯®¯®¯¯®¯®¯®¯¯¯®¯®®­¯¯¯£D/ޝ¯®¯®®®­¯¯®®®®¯®®¯¯®¯®®®¯®®®®®®¯®¯¯®¯¯¯®®®¯®®®¯¯ˆX'ES`M+:S[L4 ;z¢±¯®¯­®¯¯®¯®®¯®¯®¯¯®¯®®¯¯¯¯®®®¯¯®¯®®¯®®®¯®¯®®¯¯¯®®¯¯®®¯®®®®®¯²ši#•®®¯¯®®®®¯¯¯¯®®®®¯®¯¯¯®¯®¯®¯®­¯®®¯¯®¯®®¯¯®®®­ž3 (U™±®¯¯­¯¯®¯¯®®¯®®¯¯¯¯¯®­®¯¯®®¯¯¯¯®¯¯®®¯®¯¯®®¯¯¯¯¯¯­@5i¥¯¯¯®¯­®¯®¯¯®®¯®®®®¯¯®¯®¯®¯­®¯®¯®¯®®¯¯®¯¯®¯®®¯¯¯®¯¯®¯¯¯¯¯¯¯®¯®®ª˜-y ®¯¯®®®®®¯®®®­®®¯¯®®¯®¯¯®¯®¯®¯®¯®­®®¯®®®®®¯¨•'C}¢°¯®®®­®®¯®®®­¯®¯®¯®®®®®®®¯®®®¯¯®®¯®¯®®¯¯¯®¯®®®®®®§•mF/aŠ ­¯¯®®¯¯¯®®®¯®¯®¯®®¯®¯®®®®¯¯¯¯®®®¯®®®®®®®¯®¯®¯®®®®®®¯¯®®¯®®¯®®®¯®¥FRƒ¬¯¯¯®¯¯®¯¯®®¯¯­­¯®¯®¯®®®¯®¯¯¯®®®®¯®®®®¯¯¯¯¢ˆZ˜©°®®®®®¯®®®®®®¯®­¯®®¯¯¯¯®®®®®¯¯¯¯¯¯¯®¯¯¯®¯¯®¯­¯¯­®¯°‹bB¨±¯®®¯¯®®¯¯¯¯®®®­¯®¯¯­®¯¯¯¯¯®¯®¯®¯®¯¯¯¯®®¯®¯¯¯®­®¯®®¯®¯®®®­¯®®®¯¯¯ªZ%X§°¯¯¯®­®®®¯®¯®¯­®®®®®­®®®¯¯®¯®­¯¯®¯®®®¯¯¯®•rr©®¯®¯¯¯®¯¯®¯­¯¯®®¯­®®¯¯®®¯¯¯®®¯¯®¯®¯¯¯®®¯¯¯®¯¯®®®¯®¯¯‰^?¤°®¯¯¯®®¯®®¯¯®¯®®®®®¯®¯¯®®¯®¯®®¯®®¯®®®®®¯®®¯¯¯¯­®®®®®®®®®®®®¯®¯¯®¯©b.4—¦¯®®®¯®¯¯¯®®¯®¯®¯®¯¯®¯®®®¯®¯¯¯®®¯­¯®¯®®°¯‡XH‡­®®¯®®®®¯¯®­¯¯®¯®¯®¯¯¯®¯®®®®®®®®¯¯®®®¯®¯®¯®®¯®®®¯®¯®°s7%=6!.83(WŸ±®®®¯¯®¯¯®¯®¯®¯¯¯®¯®®¯¯¯¯®¯®®®¯®®¯¯®¯®¯¯®®®®¯®®®¯¯¯®¯®®®¯®¯®¯¯®®°ªX$k“°®¯­®¯®®®®¯¯¯®¯®¯¯¯¯®¯®®¯¯°¯¯¯®®®®®¯¯¯¯¯u8 pœ¯¯¯®®¯®¯®¯¯¯¯¯®®®­®¯®®¯®®¯¯¯¯¯®®®¯¯¯¯®¯¯¯¯®¯¯®¯¯®®¯®­` Rj|iB ]qu\78—°®¯®®¯®®¯¯®¯®®¯®®®¯¯¯¯®®¯®¯¯¯¯¯®¯­¯¯¯¯®¯®®¯®¯¯¯¯®¯¯¯¯®®®¯®®¯¯¯®¯¯£D#s­®®¯®¯¯®­®¯¯¯®¯¯­¯®®¯¯®¯¯®­¬«¬­®®®¯¯¯¯®ªb2‘«®¯®¯®®®¯®¯¯®¯®®®®¯®¯¯¯®®®®®®¯­¯¯®­®¯¯®®¯®¯¯®­®¯®®®¯­¦P%Q ¯®‘],„¡¯¬w3 ެ®¯®®®¯¯¯¯®¯¯¯®®¯¯¯¯¯¯®®®¯¯¯®¯®¯¯¯­®¯¯®¯®®®®¯¯¯¯®®¯®­¯¯®®®¯­¯¯¯°¨&Q›©¯¯¯®¯¯®¯¯®¯®¯®®®¯®®¯¯°±ªŸ™¤±®¯®®¯¯©žO'SŸ¯¯®®¯¯¯®®¯¯®®®¯¯¯®®¯¯­®¯®¯®®®¯¯®®¯¯®¯¯®®¯¯®¯®¯¯®¯®¯°©—DA~§°­’].†¡°¯Œ\„¦®¯¯®¯¯®®®¯¯­®®¯®®¯¯®¯®­®®®®¯®®­¯¯®®¯¯¯®¯®®®¯®¯®®®¯¯¯®®¯¯¯®¯¯¯¯³“R +t£±®®¯¯®®¯¯¯®¯¯®¯¯®®¯®­¦ˆt^NMYn§°¯®¯¯Ÿ‚;Ly¨±¯¯¯¯¯®¯¯¯¯®®¯¯®®¯®®®®¯¯¯®®®¯®®®®­¯®®®®¯¯®®¯®®®¯®¯®°¥‰;KŒª¯­‘]-†¢°°“k$ z ­®®®®¯®¯¯®¯¯®¯®®®¯®®¯¯¯¯®¯¯¯®¯¯®®®¯®®¯¯®¯¯®®®¯¯¯¯®¯®¯®®¯¯¯¯¯¯ª”g3­¯®¯®¯¯®­¯®®­¯®­®®¯®¢Š9O‘«®¯¯°W#t«°®®¯¯¯¯¯®®¯¯®®¯¯®®®¯®¯¯¯®¯¯®®®®¯®¯®¯®¯®¯¯®¯®®®®®®¯®¯¤ƒ6B~¨°­“^-‡¢¯°Ž_vœ­¯®¯¯®®®®®¯¯®¯¯¯¯¯¯¯®®®­¯®®®¯¯®¯¯­¯®­®®®®¯¯®¯®¯®¯¯®¯®­¯¯¯­®¬¥•U)Y˜®®¯®®¯¯¯®¯¯®®¯®®¯°¬t=\‰¯¯®­{) 1Œ¬®¯¯¯¯®®¯®¯¯¯®®®®®®¯®®¯®®¯¯®¯¯®®®®®®¯®®®®¯®¯®¯¯®®®­®¯¯¦Œ<)X¢±®—f-†¢±±{6 zŸ®°¯®¯¯®®¯®®¯¯¯®¯®¯®®®®®¯®¯®¯®¯®®¯¯¯¯®®®®®¯®®®¯¯®®¯®®®®®¯¯±¦[:.t¬®­®®¯®­¯®­¯¯¯¯®°¬ŸR )^¤®¬‘U+bœ±®®­¯¯¯®­¯®¯®®®®¯¯¯¯¯®®¯¯®®®®¯¯­¯®¯®®¯¯®¯®®®®¯®®­®¯®¯°©˜I0†¡®šj.‡¤«”W†§®®®®®®®¯®¯®®®¯®­­®¯®®­¯®¯®®¯®¯¯¯®®®®¯®®¯®®¯®¯®®®¯¯®®¯®¯¯¬•{N8Ÿª¯¯®®¯¯¯¯®¯®¯®®°©Œ>0†œœ^&K“¨®®¯¯­®®¯®®®®­¯­®®¯®¯®¯¯¯®¯¯®¯¯¯¯®®®®¯®¯¯®®®­®¯¯¯®®®®¯¯®«^ P|£•g-…œ—V(5–®®¯¯¯®¯¯®¯®®¯¯¯¯®®¯®¯®®®®¯¯¯®®®¯¯®®®®¯®®¯­®¯®®®¯¯¯¯¯®®­¯ªœ[1i–±¯¯®¯®­¯®¯¯¯¯¯¯§…:1BE #j©­¯®®®®¯¯¯¯®¯®®­®¯¯¯®¯®¯¯®®¯®®¯¯®®®®¯¯®¯®®¯®®®¯®®®®®¯¯¯®®®N1VbS %m\C 3m ¯®®®®¯¯¯­­¯®¯¯®®®¯¯¯®¯¯¯®®®®®®®¯®¯¯®®¯®®¯¯­®®®®¯®®®¯®®¯®O +|ª®¯¯¯®¯¯®®®®®¯¯¨‰<  Tа°¯¯¯®¯®¯¯®¯®¯¯¯¯¯­¯¯¯®®¯¯®¯¯¯¯¯®®®¯®¯¯®®¯®¯®¯®¯¯®®¯®¯¯¯¯°›0 ..=&[–ª¯®®¯®¯®®¯¯®®®®¯®®®®¯®¯¯¯®¯¯®¯¯®¯¯¯¯®®®¯¯®®¯¯¯¯¯­®­®¯®°¤ŠJS–­®®®¯®¯¯®®®®­¯«—H ˆ¥®¯¯®®¯®¯¯¯¯¯®®¯¯¯®¯¯®¯®¯¯¯¯®®®¯®¯®®¯®¯®®®¯®®®®®¯®¯¯®®¯¯¯®¯®¥[,I„¯¯¯¯®®¯®®¯¯®®¯¯¯¯®¯¯¯¯¯®¯¯¯®¯®­¯®®®¯¯¯®®®¯®¯¯®¯®¯¯¯¯¯¯®±‘J[¨®¯®¯¯¯®®®®¯®¯¯¦[/]ž­¯®®¯®¯¯®¯¯¯®®®¯®¯­®¯®¯¯¯®¯¯¯¯¯®®®¯¯¯¯®®®¯®®®®¯®®¯®®®¯®®®®®®¬—{, O‹¢¯®®®¯¯¯®®¯­®¯®®®®®¯¯¯¯¯®®­®¯®®¯¯®¯¯¯®¯¯®¯®¯¯¯¯®¯¯®®®®¯®°‘IŠ¡°¯®®¯¯®®¯®¯®¯¬x?\«°®¯¯¯®®­®¯¯¯¯®¯®¯¯®¯¯®­®¯®¯®¯®¯®®®¯­¯®¯¯¯®¯®¯®®¯®¯®®®®®®¯®¯®®®¡kG(8Z„ª®®¯­¯®¯¯®¯®®¯®¯¯¯®®¯®¯¯®®®¯¯®®¯®®®®¯¯®®¯¯¯®¯®¯®®®®®¯¯¯®¯±—^O…®®®¯¯®®®®®¯®¯®˜tL‰®¯®¯®®®¯¯¯®®¯¯¯¯¯¯¯®®®¯¯®¯¯®¯¯®®®¯®®®®¯®¯¯­­¯®®¯®­®¯®¯®¯¯¯®®®¯®­¯¬”oM‹¢®®®®­®®¯®®®¯®¯®®¯®¯¯®­¯¯®¯®¯¯¯¯­­®¯®¯¯¯®®¯¯®®®¯®®¯¯¯®®¯­¯®¯¡+Z©¯¯¯®®¯¯®®®¯¯ªšU(,b’¥¯®¯®¯¯¯¯¯¯®®®¯®®­®¯®­¯®¯¯®®®¯¯¯¯¯¯¯¯¯¯®®®®®¯®¯®®¯®®®¯®®¯®®®¯¯¯¯¯¯¯¤! a£«°¯®¯¯®®®¯®®®¯®®®®¯¯®¯®¯¯®®­¯®¯¯®®®®®®®¯®®¯­¯®¯®¯®¯¯¯¯¯®®®®¯« B-o—®¯®¯®¯®®®®®®¯ª‰d8&'5Gl“­°¯¯®®¯®®®®¯®®¯®¯®¯®¯®¯¯®­­¯¯­®¯­®®®¯¯®¯¯®¯¯¯®¯®¯®®¯®®®¯®¯¯®¯®¯¯®¯®¯­ŸE +v­®­¯®¯­®®¯¯¯¯¯¯®¯®®¯¯¯¯¯­®¯¯¯®®¯®¯®®¯¯¯¯­®¯®¯®¯®¯®¯®¯®®®¯®®®®¯­`$~«®®¯®®®¯®¯¯®¯®­¡fR>98EUn‹Ÿ¨®®¯¯®®®®¯®¯®®¯¯®¯®®¯®®®¯®®®¯®­¯¯®®®®¯¯®®¯¯®®¯®¯®®®®¯®®­®®®®¯¯®¯¯¯¯¯®¯¯©sBV‹¯¯®¯¯®®¯®¯­®®¯®®¯®¯¯®¯­®®¯®¯¯®®¯¯¯®®¯¯®®¯¯¯¯¯®®®¯¯®¯®¯®¯¯®¯®®¯¯yBX‘ª¯¯®®®®®®®¯®¯®ª¢’‰„‹•¡ª­®¯¯¯¯®¯¯®®®®®­®®®®®®®¯¯¯®®®®¯¯®®®¯¯¯®¯®®¯®¯®®®®¯®¯®¯®®®®®®®®¯®¯¯¯®®®¯®©uB#}œ¯®¯¯®¯¯¯¯®®¯¯¯¯®¯¯¯®¯¯®®¯®®®¯­®¯­®¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®¯®®¯¯¯®¯®¯¯¯Žd $l¦¯¯®®®®®®¯®­®¯®¯±²±²±±°±¯¯¯¯®¯®®®®­®®®¯®®®¯¯®®®¯¯¯®¯¯¯®­­¯¯¯®¯®®®®®®®®®¯¯®¯®¯¯®¯¯¯¯¯®®®¯¯®®¯®¯®®°©vD+—¨®¯®¯¯®¯¯¯¯®¯­¯®­¯¯®®®®®¯®®­¯¯¯®¯¯­¯®¯®®®®¯¯®®¯¯®¯¯®¯®­¯®¯®®¯®®¯¡ƒBœ«®¯¯¯®¯¯¯¯¯¯¯®®¯®¯¯®®¯¯®®®¯®¯®®®¯®®®¯¯®®®¯¯¯¯¯­®¯¯®®¯­®®®¯®¯®¯¯®¯¯¯¯¯®®®¯®¯¯®®¯¯®¯¯®¯®®¯¯®­¯¯®®°ª€J!‹¢¯¯®¯¯¯®®¯¯®¯®¯®®¯¯¯¯®®¯®¯¯®®¯¯¯®¯¯®¯¯¯¯®®¯¯®®®®¯®®®®¯¯¯­¯¯®®¯¯¯¬•  ¯¯®¯¯®¯¯®®®®¯¯¯®®¯­¯¯¯¯¯¯®®¯®¯®¯¯¯¯®¯¯®¯¯¯¯®¯®¯®¯¯®®¯®¯¯®¯®®®¯®¯®®®®¯®®®®®®®¯®®®¯®¯®®¯­¯¯¯¯¯®¯¯¬še $Ž¥°¯¯¯®®­¯®¯®¯®¯®¯®®®¯®¯®®¯¯¯¯¯®®®®®¯¯®®®¯¯®¯¯®®¯®¯®®®®¯¯¯¯¯®®¯¯®§W°¯®¯®¯¯®®®­¯­®¯®¯®¯¯¯®¯¯®¯¯¯®¯®®¯¯¯¯¯¯¯­¯¯¯¯¯®®®®¯¯­®¯®®¯¯®¯¯®®®®®®¯¯¯¯¯¯¯¯¯®®¯®¯®®®®¯®®¯®¯­®¯®­¨u2˜¨®¯¯¯®¯¯¯®®¯®®¯¯®®¯¯¯®¯®¯¯®®¯¯®®®®¯¯®¯®®¯®®®®¯®®®®®®¯®®®®¯¯¯®®¯¯—t*v¯®¯®®®®¯®®¯®­¯®®¯®¯¯®¯¯®¯®¯¯¯®®¯®¯®®®®®¯®¯®®­®®®®¯¯®®¯®¯¯¯®¯¯¯¯®¯¯®¯®®¯®¯¯®®®®¯­®¯®¯¯¯¯®®¯¯®®¯®¬ZR§®¯®¯®¯­®¯¯¯¯¯®®®®¯¯­¯¯¯¯®¯¯®®®®¯¯®®®®¯®®¯¯®®®®¯¯¯¯¯¯®®®¯®®®¯¯®¯®q5]¦¬¯®¯¯¯¯®¯®¯¯¯­®®¯®®¯®®®®®¯¯¯¯¯®®®¯¯¯®¯¯¯¯¯®¯®¯¯®®®¯®¯¯®®¯®¯®¯¯¯¯®¯¯®®¯¯®®®®®¯®¯®®®¯®¯­®­¯¯®¯¯¯«ˆSA£­®¯®¯¯®®¯®¯®®¯®¯®®®¯®®¯¯¯®®®¯¯®®¯¯¯®¯®®­®¯®¯®¯­¯®®¯­¯¯¯®¯®®®¯°¤‰G3•§°¯®¯®®¯®¯¯¯®®®¯¯®®¯¯®¯®¯¯®®¯®®®¯®¯®¯®¯®®¯¯®¯®®®­¯®¯®¯¯¯®¯¯¯®¯­¯®¯®®¯®¯®¯¯¯®®®®®¯¯®®¯¯®®®¯¯¯¯®«ŒW-ª¯¯®®¯®®®®®¯¯®®¯®®¯¯¯®®¯¯¯®¯¯¯®®®¯®¯¯¯®®¯­¯¯®®¯®®®¯®®­¯®®¯¯°­£†Po °®¯®¯®¯®®¯®®®¯®­¯¯®®¯¯¯®®®¯¯®®®®¯®¯­®®¯®¯¯®®®®®®¯¯¯¯®¯¯®®®®®®®®¯®¯¯¯®¯¯¯®¯®®¯¯¯¯­¯¯®®¯¯¯¯¯¯­¯¬Ÿj ,›ª¯®¯¯®¯®¯®®®®¯¯¯¯¯¯¯®®¯¯®¯®¯¯¯¯¯¯®¯®¯¯®®®®®¯®®®¯®¯¯®¯¯¯®®®¯­¥m8 F—°¯¯®®®¯¯®¯®¯®®¯®®¯®®¯®¯­¯®¯¯®®®¯¯¯®¯®¯¯¯®®¯®®¯®®¯¯¯¯®¯®®®¯¯®¯®®¯®®®®®¯¯¯®®¯¯¯®®®®¯¯­®®¯¯¯®¯¯¯¬™d 9 ¬®¯®­®¯¯®®®®¯¯¯¯­¯®®¯®¯¯®­®®®¯®®®®¯­¯¯®®®®­¯¯¯¯®¯¯®¯®¯®¯¯¬¨‰f4‰¬¯¯®®®®®¯¯¯¯®¯®¯®¯¯¯®®®®®¯®¯¯¯¯¯¯®¯®®¯¯®¯¯®®®®®®¯®®®®¯®®¯­®®¯¯¯¯¯®¯®®®¯¯®®¯¯¯®¯®®¯®®¯®¯®¯®®¯¯¬[D¤®¯®¯¯®¯®®®®®¯®®®¯­¯®¯¯¯®¯®¯®®¯®®­¯®¯¯¯¯®¯­®¯¯¯®®¯¯®¯®¯¯®® ŽSs ­¯®¯­®¯¯®¯¯¯®®®¯¯¯®¯¯®®¯¯¯®®¯¯®®¯¯¯®¯¯¯¯­®¯®¯¯®®¯®®®®¯®¯®¯¯¯®¯®¯¯®¯¯¯®®®¯¯¯®¯®®®®¯¯®¯®®®®®®¯¬h5žª¯­®­®¯®¯®¯®®®®¯®¯¯®®®®®¯¯¯®¯®¯¯®­¯¯®®®®®¯®®¯®¯¯®®®®®®®­¦|+XŒ«°®®¯¯®®¯¯­­¯®®¯®¯®¯®®¯¯®¯®®®®®®¯®¯®®®®®®¯­¯¯¯¯¯¯®¯®¯¯®®®®¯¯®®¯¯®®¯¯¯¯®®¯®¯¯®­®®®¯¯¯®¯®¯®¯¯®®ª1 :¡¬®®­¯®¯¯®¯¯®¯®®¯¯¯®¯®­¯®®®¯®¯¯®¯®¯¯¯­¯®®¯®¯®®¯¯®®®®®¯¯¯®ª`E) ;q©°®®¯­¯¯¯®®®®¯¯¯¯¯®®®¯¯¯®¯¯®®¯®®¯¯¯®®®¯®®®®®®®¯¯¯®¯®®¯¯®¯®®¯®®®¯¯®®¯®¯®¯¯®®¯¯¯¯¯¯¯®®®¯¯­®¯¯®¯²•X'O¤­®¯¯¯®®®¯®®¯¯¯¯­¯®®®®®¯®¯®®¯¯¯¯®­¯®®¯®¯®®®®®®®®¯®¯®¯®®®®­©£ˆg8V¥°®®¯®¯¯¯®®¯®¯®¯®®¯¯¯¯­®®®¯®®®®¯®¯¯¯¯¯®®­¯®¯®®®®®¯®®¯¯®®®¯¯®®¯®¯­®¯®®¯®¯¯®®®­¯¯®®¯®¯¯¯®®®®®¯¯±˜e/K†«¯¯¯®®®®¯¯®¯®®®®¯®®®¯¯®®¯®¯®®®®¯®®¯¯®®®®®­¯®®¯¯¯®¯®¯®®¯¯®¯®­ª£‘a ;›¬¯®®®®¯¯¯®®¯¯®¯®¯¯®¯®®®®¯®¯¯®®¯¯¯¯®¯¯®¯®®¯¯®¯®®¯¯®¯¯¯®®®¯®¯®¯®­¯¯¯­¯®®®®®®¯®®®®¯¯¯­¯¯®¯®®®®¯²™f/U­°¯­®¯®®®®®®¯¯®¯¯¯®¯¯¯®®®¯®­¯®®®¯¯¯®¯¯®®®®®®®¯®®®®¯¯®¯¯­®¯¯¯°¯©‚/ #Œ§®®¯®¯®®®¯®®¯®¯®¯®­¯®®®¯­¯¯¯¯¯­¯¯®¯¯®¯®¯®®¯®®¯¯¯­¯®®®¯¯®®¯¯¯®®®¯¯¯¯®¯®®¯¯®®®¯®¯®®¯¯¯®¯®®¯¯®¯°œo3Z”­®®¯®¯¯®¯®®®®¯®¯®®¯¯®®¯®®®®®¯®¯¯®®¯®®¯¯®¯®¯¯®¯®®®®®¯¯¯¯®¯­®®®¯±“Onž°®¯¯®¯®¯®¯¯®¯®¯¯¯®®¯®¯­®¯¯¯®®®¯¯®®¯­¯®¯¯¯¯®®¯®®¯¯­®®®¯¯®¯®¯¯®¯®¯¯®­¯®®¯®®¯®®¯®®¯¯®®®¯¯®¯¯®®¯§•T t¥®®®¯¯¯®¯¯¯®¯®¯®®¯¯®­®®¯®¯¯®¯¯¯®¯­¯®¯¯®¯¯®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®¯­®°—`N“°¯¯­¯®®¯¯®®®¯®®¯®®¯¯¯®®®®®®¯¯¯¯®®®¯®¯®¯®¯¯¯­­¯¯¯¯¯®®®®¯¯®®®­¯¯¯®®¯¯®®¯®®­®®¯®¯¯¯¯¯­®®®¯¯­¯®¯¬¥„Y;Ei”­¯¯®®¯¯®®¯®¯¯¯¯®¯®®®®®¯¯®®¯®®®¯¯®®¯®¯¯®®®¯®®¯®®®®®¯®¯¯®¯®¯¯®¯®®±™b)ˆ°­®®®¯®®®®¯®¯¯®®®¯®¯®¯®®¯¯¯¯®®¯®®¯¯¯®®­¯¯®¯®¯®¯®®®¯¯¯®¯¯®®®®¯®®®¯¯¯®¯¯®®¯¯¯®¯®®®®®®¯®¯®¯®®®¯­®¬žˆ§­®­®®®¯¯¯®¯®®¯®®¯®¯¯¯®®¯¯®®®¯®¯­¯­®®¯¯¯¯¯®®®®®¯®¯®®®¯®¯®¯®¯¯¯®®®°—[{¬®¯®¯®¯¯¯¯®¯¯¯¯¯¯®®¯¯¯®¯®¯¯¯¯®¯¯®®®®¯¯¯®¯¯¯®®­®®®®¯®®®®¯¯¯¯¯¯¯®¯®®¯®®¯®¯¯¯­¯®®¯®®¯¯®®®¯®¯®¯®®®®¬§©®®®¯®¯®®­®®­®¯¯®®®¯¯¯¯¯®¯®¯¯¯¯®¯¯¯¯¯¯®®®®¯¯®¯¯®®¯®®¯¯¯¯¯¯®®¯¯®®¯®±‘Bk¢«¯­¯®¯®¯®®®®®¯®®®®¯¯®®¯¯¯®¯¯¯®®¯®¯¯®®¯®®®®¯®¯®¯­®¯­®¯®¯¯®­®¯¯®®®­¯®®¯®®®¯®­®®®®®®¯¯®®¯­®®®®¯®¯®°°®¯®®®®®¯¯®®¯®¯®¯®¯®®®¯¯®¯®¯¯®®¯®¯®®®®¯¯®®¯¯®¯®¯®¯­¯¯®¯¯¯¯¯¯¯®°°®©˜l!\”¨°®®®®¯®®¯­®¯¯¯®®®®¯®¯¯¯¯®¯®¯®¯¯®¯¯¯®®¯®¯®®¯®®¯¯®¯®¯¯¯¯®®¯®¯¯¯¯®®¯¯®®®¯®¯¯¯®¯­¯¯®¯®¯¯®®®®®®®¯¯®®¯¯¯®¯¯®¯®¯®¯®®®®¯®®®¯®¯®¯¯®¯¯®¯¯®¯¯®¯®¯®¯­®®¯®¯¯®¯®¯®®¯®¯®¯¯®¯«¦›h8I}¥±¯®¯®®¯®®¯®®­¯¯¯¯®¯¯®®®¯®¯®¯¯¯¯­®®¯®¯®®¯®¯­®¯¯®¯¯®¯®¯®¯®¯¯¯¯®®¯¯®®®®¯¯®¯®¯®®¯®®®¯®¯¯¯®¯®¯®®¯®®¯®®¯®®®¯®®¯¯¯­®®®®®¯®¯®®®¯®¯®®¯¯¯¯¯®¯®®®­®­¯®®¯¯®¯¯¯®¯®¯®®¯®®®®•hC7f ±¯®®¯®¯®¯¯¯®¯¯¯¯®®¯®¯®®®¯®­®®®¯¯®¯¯®¯®®®¯®¯®¯¯¯¯®¯¯¯®¯¯®­­­®®®¯®®®¯¯¯¯¯¯®¯¯¯®®®¯¯¯¯®®¯¯¯®¯®¯®¯¯¯¯®¯¯¯®®¯®­¯®®¯®¯¯®®®¯®¯¯¯¯®¯¯¯®®¯¯¯®¯¯¯®®¯®®¯®¯®®¯®¯®¯¯®¯®¯¬•i-Mœ²¯®®¯®®¯®®¯®¯¯¯­¯¯®®®®®¯­®®®¯¯®®®®®®®¯®®¯¯®®¯¯®¯®®®¯®¯®¯®®®¯­¯®®®¯­¯¯®¯®¯¯¯®¯®¯¯¯­¯¯®¯¯¯®®®®¯¯®¯®®¯¯®¯¯¯®®¯®®¯¯¯¯¯®®¯¯¯®®¯¯®®¯¯®®®®¯¯¯¯¯­®¯®®®¯¯®¯¯®¯¯¯®¯¯®©t5 :—±¯®®¯¯­®®®¯¯®¯¯¯­¯¯¯®¯¯­¯®¯¯®®®®¯¯®¯®¯®¯¯®¯¯¯­¯®®¯®®¯®­®¯¯®®¯¯¯®¯®¯®®®¯¯¯®®®¯¯®®®®¯¯®®®®®®®¯¯¯®®®®¯¯¯®®¯¯®®®®®¯®¯®­¯¯¯®®¯­­¯®®®®®­®¯­¯®®¯®¯¯¯®®¯¯®®¯¯®®¯®®°¨j++’®®®¯®¯¯®­®¯¯®¯¯¯®¯®®®¯®®¯®¯¯®¯¯®®¯®¯®¯¯¯®®®®®®®®®¯®®¯®¯®¯¯®®¯¯¯¯®¯¯®¯¯®¯®¯¯¯¯®¯®®¯­®®¯®¯®®¯­®®®¯¯®¯¯®®®®¯®®®®®®®®¯¯¯®¯®®®¯®¯®¯®®¯¯¯®®®¯¯®®¯¯®®®®®¯¯¯¯®®®®¯¯©v8‹«®®¯¯®¯®¯¯­¯¯¯¯®®¯®¯®®¯®¯®®®®¯®¯­¯®¯®®®®¯®¯®¯®®®®®¯®¯®®¯®­¯¯¯¯¯®®¯­®®®¯¯¯¯¯®®®®®®®®®®®­¯®¯¯¯¯¯®®®¯®®¯­®¯­®®®®¯¯®®¯¯®¯¯¯®®¯®¯­¯®®®¯¯®®®¯®®®¯¯®¯¯­®®®¯¯®¯®®®¯«ŒQ¦®¯®®¯¯®¯®¯®¯®®®®®¯¯®®¯¯¯¯®¯¯­¯®®®¯®®¯¯¯®¯¯®­¯®®®¯®®®¯­®¯®®®¯¯®®¯¯¯¯¯¯®®®®¯¯¯®¯®®®®®®¯®¯®¯¯¯­¯¯®¯®¯¯®¯¯¯®¯¯­¯¯®¯®®®­®¯¯®¯®®¯®¯¯¯®¯®¯¯®®®®®¯­¯®®¯®®®®®®¯®¯¯¯®¦n_ ®¯¯®®¯¯®®¯®®®¯¯®®¯®®®®®¯¯®¯®¯®®®®®®®¯®¯­®¯®¯¯¯®®¯¯¯®¯¯¯¯¯®®®®¯®¯¯¯¯®®¯¯®¯®¯®®¯­¯¯®¯®¯®®®®­®¯¯¯¯¯¯¯®®®¯¯®­®®­®®¯¯¯¯®¯®¯¯®®­®¯®¯®®®¯¯¯®¯¯®®¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯®®}U™­¯®®®¯®¯®®­¯¯®®®¯¯®­¯®¯¯®¯®®®®¯®®®¯®¯¯®¯¯¯¯¯®®¯¯®®¯¯¯¯®­¯¯®®¯¯¯®®®¯®®­¯¯¯¯¯¯®®®¯­¯®®®¯®®¯¯®®¯®®¯¯®®®®®¯®®®¯¯®¯®®¯¯®¯¯®¯®¯®¯¯¯®®¯¯­¯®®¯¯®®®®®¯¯¯®¯®¯®®®®¯®®¯²‰/ J­¯¯¯¯®®®®¯®¯¯®¯®®®®¯¯¯®¯®®®¯¯®¯­®®¯¯¯¯¯¯¯¯®®®¯¯¯¯®¯¯®¯¯®®¯¯¯®®¯¯¯®¯¯¯¯¯¯®¯®¯­¯®¯¯¯¯®¯¯¯¯®®¯®®®¯®¯¯¯¯¯®¯®¯¯®®®®¯¯¯®¯®®®¯®®¯®®®¯®¯¯¯®¯®¯®­¯¯®¯®¯®¯®¯®¯®¯®¯­®®²ECˆ¬¯®¯®®®®®®®®®¯¯®¯¯¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯®®®®®¯¯­®®¯¯®¯®¯¯¯®¯¯®®®®®¯¯¯®¯®®¯®®®¯¯®¯®¯®¯¯¯¯¯¯¯®®¯®®¯®®®¯¯¯®®¯­®¯¯®¯¯¯®­®¯®¯­¯­®®®¯®¯®¯¯®¯®®®¯®¯¯¯®®®¯­¯¯®¯¯¯¯®®¯®®¯¯²‘P#=¬®¯¯¯®®®­®®¯¯¯­®¯¯®¯¯®®¯®®¯®®¯®¯¯®¯¯®®®¯®®®¯®¯®®®¯®¯¯¯¯¯®­®¯®¯®¯®¯®¯¯¯®¯®¯¯¯¯®¯¯®¯¯®¯®®¯®®®®®®®®¯®¯®®®¯­¯¯¯¯¯®¯®®¯¯¯®¯¯®¯®¯®¯®®¯¯¯¯¯®®¯®­®®­®¯®®®¯®®®¯®®®¯¯²‘N"6z«°¯¯®¯­®¯¯®®¯®¯¯®¯®®®®¯®¯®®¯¯¯®®¯¯¯¯®®¯®­¯¯¯®®®®¯®®®¯¯®®®¯¯®®®®®¯¯­®®®®¯­®®¯®®¯¯¯®­¯®®¯¯¯¯®®¯®¯¯®¯¯¯®¯®¯¯¯®®¯¯¯®¯®¯®®¯¯®¯¯®®®¯®®¯®®®¯®¯®®¯®®¯®®¯®¯¯®®¯¯¯¯®¯³‰3 1t«¯®¯¯¯¯¯¯®®¯®®¯®®®¯®¯®¯¯¯®®¯®¯¯®¯®®¯¯®¯®®®¯¯­¯®¯®¯¯®¯¯¯¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®®­®®®­¯®®®­®®¯®®¯¯¯­¯®®®®¯¯¯®®¯®¯¯®¯¯¯¯¯­¯®®®®¯®¯®¯®¯­¯¯®®¯¯­¯­®®¯®¯¯¯®¨x,o«®®®®®¯®¯®®®®®¯¯®®®®¯¯¯®®®¯®¯¯®®¯¯®¯¯¯¯¯®¯®¯¯­®®¯®¯®®¯®¯®¯¯®®®¯¯¯®®¯®®®®­¯®¯®®¯®®®¯®®¯®¯®¯®¯®­®®¯®®¯®®®¯®¯®®¯®­®®¯­¯¯¯®®®®¯®¯®®¯®®®¯®®®®®¯¯®®®¯¯¯®®®¯®¯®­®¬’W)kª¯®¯®¯®®®®®®¯®®®®®®®¯®¯¯¯®¯¯¯®¯¯¯®®®®®®®®®¯®®®®¯®¯®¯¯¯®®®®¯¯®¯®­®®®¯®¯®®¯®®¯¯®®®®¯¯¯¯¯®¯®®®¯®®®­®¯®¯®¯®®¯®¯¯®¯®¯¯®®¯®­®¯®®®®¯®®¯®¯¯®®¯¯®¯­¯®¯¯®¯®®­®®­®®®­£\ (iª¯®®¯®¯®®®®¯®®®¯®¯¯¯®®®¯­®¯¯¯¯¯¯¯®¯­®¯®¯®¯¯®¯®¯®¯¯®¯­®®¯®®®®¯¯®®®¯¯¯¯®¯¯®¯®®®¯®¯®®­¯¯®¯®®®®®¯®®®®¯¯®®®¯¯¯¯®¯®¯¯¯®®®®®¯¯¯­®¯®¯¯¯¯®®¯¯®¯®¯­¯®¯¯®¯®¯®®¯¯¯®¯°Ÿ/(i«®®®®®¯®¯®®®®®®¯®­¯¯¯¯®¯®®®¯®®®®¯¯®¯®®®¯®®®¯®¯®¯¯¯¯¯¯¯®­®®®¯®¯­¯®®®®®¯®¯®®¯­®¯®®¯®¯®®®®¯¯®®¯®¯¯¯¯¯¯¯®¯®­¯­®¯®®®®®®®¯¯®®®¯¯¯­¯®®¯¯¯¯¯®®¯®®¯®®®®®®¯®¯®®¯®¯¬7'iª°®¯¯®®®®¯®¯®¯­®®¯®®¯¯®®®¯®®¯®®®¯¯®®¯¯®®®®¯®®¯¯®¯¯®¯®¯¯®®¯¯®¯®¯¯¯¯®®®¯®®®®®®¯­¯¯¯®®®¯®®®¯¯¯¯­®¯¯¯®¯®¯¯¯¯¯®®¯®®¯¯®®¯¯®®¯¯®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯®®°¯¡t> (i«¯®¯¯®¯®¯¯®¯®¯®¯¯®®¯¯®¯¯®®¯¯®¯¯®®®¯¯¯¯®¯®®¯®®®¯®¯¯¯¯¯®­¯®®¯¯®®¯®¯¯¯¯¯®¯¯®¯­®®­®®¯®¯¯­­¯¯®®®¯®®¯®®®¯®¯®¯®¯¯¯¯®®¯¯®¯¯¯®¯¯°¯°¯¯®­­¬¬­®®¯¯°°°°¯°°¯®¯°°¯®«¤–x;(iª°¯¯®®®¯®®¯¯¯®®®¯¯®¯®¯®¯®®®®¯®®®®¯®®¯®®¯­¯®®®®®¯®®®¯¯®®¯®®®¯¯®®®®¯®¯®®®®¯®®®­®¯®®®¯®¯®¯¯¯®¯®¯¯®®¯®®¯¯­­¯¯¯®®¯®®¯®­¯®¯¯¯­­­«©¥¡ ¡¡¥¦§ªª¬¬­¬­­­­®­­­ª¦™„U+n«°®¯¯®®®®®®¯®®®¯¯®®®¯¯¯¯¯®®®¯®¯­®¯®®®¯®­®®®¯¯®®®¯¯¯®®®¯¯¯¯®¯¯¯­®¯®®®¯¯¯¯¯¯®®¯®®¯®¯­¯¯®®®¯¯¯¯¯¯¯®®®¯®®®¯®®¯®¯¯®¯®®¯®®¯®¨Ž{`UKFCA@BEGHMOTX[cehnprof\PF;).r«¯¯¯¯®®®®¯­®®®¯®¯¯®®¯®¯®®­®¯­®®®¯®¯®®¯¯®¯®¯¯­®¯¯®¯¯¯¯®­®®®®¯¯®¯®®¯®¯®¯®®¯¯¯®®¯®®®®®¯¯®®®¯¯®¯®®®®®®¯®®¯®®¯¯®¯®¯®®®®¯®©˜€W@$  $)*2653, 7{«°®­®®®¯®¯®®®¯®¯®¯¯¯®®®®®®¯¯¯®®¯®®®®®®®¯®®®®®®®®®¯¯®­®¯®®®®®®¯¯®¯­®¯®®¯®¯®¯¯¯®¯®®¯¯®¯¯¯®¯®¯®®¯¯®®¯¯®¯®®®®®®®¯®¯®®®¯ª•b"J­¯¯®®¯¯®¯¯®¯¯®¯­¯¯¯¯®¯®®®¯¯®¯¯®®®¯¯¯¯­®®®¯®®¯®¯¯®¯®®®¯­®¯®®®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®¯®®®®¯¯®®®¯®®¯®¯¯¯¯¯¯®¯®¯¯¯®®¯®¯¯®®¥Ecž­®®¯®®®®®®®¯¯¯¯®¯­®¯¯®®®¯¯¯¯¯®¯®¯®¯®¯¯®®¯¯­¯®®®¯¯®®®®¯®¯¯¯¯®®®®¯¯¯¯®®®¯®¯¯®®¯¯®¯®¯¯¯¯®®¯¯®®®¯®¯¯¯¯¯®¯®®®®¯®®®¯®®®©Š`Š©®¯®¯®®®®¯¯®®®¯®®®¯¯®®¯®®®­®®®®®®­®®®¯®®®¯®®¯®¯¯¯®®®®¯¯¯®®®¯®®®¯®®¯®®®¯¯¯¯¯®¯®®¯®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®®®®¯¯¯¯®®¯®¯®¯«šO)’¯®¯¯­®®¯¯®¯¯®¯¯®¯®®­¯®®®®­¯¯®¯®¯¯¯®®®¯¯¯­¯­®¯®®®¯¯¯¯®¯®®¯®¯®®¯¯¯®®®¯¯¯¯®¯®®®®®¯¯¯¯¯®¯®¯®¯­®­¯¯¯®¯®®®¯¯¯®¯¯®­®®®®¯š^$ :•¯®¯°¯®¯®®¯¯®®®®¯¯®®®®¯¯®®¯®¯®®¯®®®®¯®®®®®¯®¯¯®®®¯¯¯®®¯¯®®¯¯®®¯¯®¯¯­®®®¯¯®®®®­®®®¯¯¯®¯¯¯®®¯¯®®­¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®¬¥ƒ+ >§©¬®¯®¯®¯®®®¯­¯®®®®¯®®¯®¯­¯®¯®¯¯¯¯®®¯®®®®®¯­¯®®¯®¯®¯¯®®®®®¯¯®®¯¯®®®®¯¯¯®¯¯®®¯®¯®¯®¯¯®¯®¯¯®®¯¯®®®¯®¯®¯®®®¯®®®®¯°©‰] (CTgxŽœª°°°°¯¯®¯¯¯®¯®®¯®¯¯®¯¯®¯®¯®®®®®¯¯¯®®®¯¯®®¯®®¯®¯®¯¯¯®®¯¯¯¯®¯¯¯¯¯¯­¯®®®®®¯®¯¯®¯¯®®®®®¯®®®¯¯®¯¯¯®¯®¯®®®®¯¯¯±£]1$=Wi–¤«®¯¯®¯¯¯¯®¯®¯¯¬««­®°¯¯­¯¯®®®¯¯®®®¯­¯¯®®®¯®¯®¯®®¯®¯®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯¯¯®¯®®®¯®¯¯®®®®®®¯®®®¯¯¯®®­®®¯š:%@i€œ§­®®¯®¯®¯®®®¯¦£¢§«­®®¯®¯¯¯¯®®¯¯®®¯®­¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯®¯¯®®®®¯¯­¯¯¯¯®¯¯¯¯¯¯®­¯®¯®¯¯®¯®®¯®¯®¯§Œ$ "4Qm‰ž«¯°¯®®¯¯®«¢’|nr~–£¬±±¯¯¯¯®®¯®®¯¯®®®®¯¯®®®®®®¯­¯®¯¯¯¯¯¯®®®¯®®®¯®¯¯¯®¯®¯®®®®®¯®®¯¯¯®®®®®¯¯®¯®®®®”r *Rm‡• §­°¯¯¯®§•yc\\jz‹™¡ª­°®®®¯®¯®¯®¯®¯¯®®¯¯®®¯¯¯®®¯¯¯®¯¯®¯¯¯¯­¯®¯¯¯­¯¯¯¯¯®¯¯®®®¯¯®¯­¯¯¯®®¯¯®¯¯¯®~T>n¡­¯®¯®®®«¥‚Z$Pr𥝮®®®®®¯¯®®®®®¯®®¯®®¯­®®¯®®®¯®®¯®®®¯¯®­¯®®¯®¯®®¯®®­®¯®¯®­®®­¯®¯®¯¯®®®®¬b( ,Ll‘£°°¯¯¯­¡”xS.'=[Ÿ¬¯°¯®®®®®®®®®®¯¯®¯®¯®¯¯¯¯®®®¯¯®¯®¯¯¯¯®¯®¯®®¯¯®¯®¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯®¯¬£K'Z~•£ª®®¯°¯¨…Y(Hw£«°®¯®¯®®¯®¯¯®®¯®®­¯¯¯¯¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯®¯®®®®¯®®®¯¯®¯®®®¯®®¯®®°§’4 3z•¨®®¯®®­£}S>x­¯®®®®¯®®®®®¯¯¯®¯¯¯®®®­¯¯®®®®®¯®®¯¯®¯®®®®®¯®¯¯®®¯¯¯¯®¯®¯®®¯¯®®¯±œq">h¥­°®°­¢Žm= -S|¤¬¯¯®®®®¯®¯®¯®®®¯¯®¯¯®®¯¯¯®­¯­®®¯­¯®®¯®¯®¯¯®¯®®¯¯®¯®®¯¯®¯¯¯¯¯®°J '^‰Ÿ©®¯¯±ªŸn.Lˆœª­¯®¯®®®¯¯®®¯®®¯¯®¯®¯¯¯®®®¯®®®¯¯®­¯¯¯®¯¯®®¯®¯®¯®®®¯®®¯¯®®¯¯¯­„-a‰«®¯¯®¬¢†@$^”§±­¯®®®¯¯¯®®®®®®®¯®®®¯¯®®¯®¯¯®¯¯®¯¯¯¯¯®¯¯¯®®®¯®¯¯®¯¯®¯®®®®®¤r;s”¬®°°­¤„V&L}®°®®®®®®¯¯¯®®¯¯®¯¯®®®¯®¯®®¯¯®¯®®¯¯¯®¯®­®¯®®¯¯¯®¯®®¯®®®¯®¬‹U'g—©­®¯®­ŒP!Ey «¯¯¯¯®®®¯®®¯®¯®¯®®­¯¯®®®¯®®¯¯®¯®¯®®®¯¯®®®¯®¯®¯¯¯¯¯¯¯¯®¯ªo7 <Œ£®°®®©›\& +f–°°®®¯®¯¯¯¯¯®¯®®®­®®¯®¯¯®¯¯¯®¯®®¯¯¯¯®¯¯®®®¯®¯®®¯®¯­®¯¯¯¨P @mš§°¯¯¬e(&b‹¨¯¯¯®®¯®®®®®­®¯®®¯¯®¯¯®®¯¯­®¯®®¯¯®®®¯¯¯¯®®¯®®®¯®®®¯®¬¡9 (o“«®®®¯–\0#S”¨®¯¯¯®®¯®®¯®®­®®¯¯®¯¯®¯®­®®®¯®®®¯®¯®®¯®¯¯¯®®¯¯®®¯¯¯¦’( Q©¯­¯ª¢o/ Pzª°®®¯®­¯®®¯®®¯¯­®¯®®¯¯®®­¯­¯¯®®®¯®¯®¯¯­¯®¯®®¯®®¯¯¯œzO‹¢¯¯¯¯—v9 D¡®®¯®¯®®¯¯®®­®¯¯¯¯®¯®®®¯®¯¯¯®®¯®®­¯®¯¯®®¯¯®¯®®®°®Œ^Vˆ©®®¯®¦j-Cƒ£®¯®¯¯¯­®®®®®¯®®®¯®®¯¯¯¯¯®¯®¯¯¯­®¯®¯®­®®®¯¯®¯®¯°~? @‹¦¯¯®­ x" Eq¥°¯®­®¯¯®®®®¯®¯®¯¯®®­¯¯®¯¯®®¯®®¯®®®¯¯®®®®¯¯­¯¯¯oG…¤®¯¯®™k/5}𝝭¯®®¯¯¯®¯®¯¯®¯¯®®®®¯®¯®®¯®®®¯¯®¯¯¯¯¯¯®­®®¬¥`UЍ®¯®¬¡_Bu¨­¯®¯®®¯¯®¯¯¯¯¯®¯®®®¯­®¯¯®¯®¯¯¯¯¯®®®®¯¯¯®®°¦•MF–¦¯¯¯­”q3¦±®®®®®¯¯¯¯¯¯®¯¯¯¯®®®¯®­®®¯®¯®®¯®®®®®®¯¯®°Ÿ};R„©­¯¯¨˜T* >„¡®¯¯¯¯¯®¯­®®¯¯¯¯®¯®¯®®®¯®¯­¯®®®¯¯¯¯¯¯¯®®²˜`*O–¦°¯®«‰_S§®­¯®®¯®¯®¯®®®¯¯®®¯®®¯¯¯®¯¯®¯¯®®¯®¯¯¯®®±ŽC>®¯¯®©ŽM :Œ¢¯¯®®®¯¯®®®®¯®¯®®¯®®®¯¯®®®®¯¯¯¯®®¯®¯®¯°ƒ& S«¯¯°¤‡BIw¤­¯®®®¯¯¯®¯¯®¯¯¯®®¯¯¯®®¯¯®¯¯¯®­®¯¯¯®­¦rY¬¯®®«r@ A‡¢­®¯®¯¯®­®¯®¯®®®®¯®®®¯®®¯¯®®®¯¯¯¯®¯¬˜_f—²¯¯¯¢‰- 2|°¯¯¯®®®¯¯®¯­®®®¯®¯¯­­¯®¯­¯®­¯®¯¯¯ª‚Fnž¬¯®®£m? o¤¬¯­®¯¯­«©£ŒpM% Js«°²±®¯¯¯¦œ‘ƒvdPA.:€’ž¨­¯®¯°¯±²­¡Žl_J<0*($#  3b§®¯®¯®¯®¯®«ªª©§¥¢–Žƒ}tnjh`]]]]]]]]]]\]]\]]]\]\]]]]]\]]]]]\\]\]]\\\\\]]][]]]]]\]\]\]]]\]]]]]]\]]]]^]]\]]\]]\]\]_P Qj…šª°³°°±°¯°°°±°«¨¥¢žšš˜––––––––––—––—•––––•––—––•—––•–––––—•––•—•–——––•––——–––––––––•––—–––––––––––•—––––––˜ƒ-Cy—ž£©­®¯¯¯®¯¯¯¯±¯°°°±±±±²±°±°±±°±°°±±°¯°°°±°±°°±°°±°²°±±°±±±°°°±±°±±°°±°°°±±°±±±°±±±±°±°±±±±°°°°±±±°°±°±±²!?`w¡®¯®¯®¯¯®®®¯®¯®¯®¯®®®®®¯¯®¯®¯®®¯¯¯®®®¯¯®¯¯¯®®®¯®®®®®®¯¯®­¯®®®®®®®¯¯®®®¯®¯¯®¯¯¯®®¯¯¯®®¯®¯¯®®¯®®¯®¯®¯®±› !Nbm|†Ž™Ÿ¥ª®°²´··¸·¸····¹¸¸¸¸¸¸¸¸·¸¹¸¸¸¸·¸¸¸¸¸¸¸·¸¸¸¸·¸¹¸¸¹¸¸¸¸¸¹¸¸¸¹·¸¹¸¸¸¸¸¸·¸¸·¸¸¸¸¸¸·¸¸¸·¸·¸¸¸¸¸º¥" #-6@ELPUXZ\^a``a`_aa`aa```a``_a`````aa_`_````````a``aa`a`_a``a```a```a`a````aa_````a````a`a`````bS openigtlink-3.0.0/Examples/Imager/img/igtlTestImage2.raw000066400000000000000000002000001501024245700231220ustar00rootroot00000000000000 "#%&*())))))*&$#"   !$,7CN[gq{‚‹’˜Ÿ¢£§¬­¬¬¬¬¬­­¨£¡ž˜Šwl^RE4)"  .G]qƒ“ž£¤¦¥§¨©©ª««¬¬­­®­®­­­­®®­­¬¬¬«ª©¨¨¦¥¤ Ž€hP6(?Ufp{ƒŽ•œ¤«¯²±±²°¯°°°°¯¯¯¯¯¯¯®¯¯®¯®®¯¯®°¯¯¯°¯°±²²°®©£™…wkZE(  (@So‚—ª®±±±±¯¯®¯®­¯®¯®®®¯®­¯®®¯®®®¯®®®®®¯¯®®®¯®®¯®¯¯®¯¯°°°°±²ªœ‡gG4 $@e†— ¤§©«­®®®¯­¯¯®¯¯®¯¯®¯®¯®®¯¯®¯®¯®¯®¯¯¯®¯®¯­¯¯®¯¯¯¯®¯®®¯®®¯¯®®­¬©¦£˜‚\1>Xk}Š˜¦­°±°°®®­¯®®®­®®¯¯¯¯¯¯¯®¯¯®®¯®­®®®¯¯®¯®®¯®®®®¯®¯¯®¯¯®¯®®®­®®¯¯®®¯°°­¤”kN0 &A\š­±±°¯¯®¯¯­®®®®®¯®®¯®®®®®¯¯¯¯®®®¯¯®®¯®¯®®¯®®®¯®¯¯®®¯®®¯¯®®®¯¯¯®¯®®¯¯®¯¯¯¯°±°ªpI% Cq‘ž¦©¬®¯¯®®¯­®®¯¯­¯®¯¯®¯­¯¯®¯®¯¯®®®¯®®¯¯¯®¯®¯®®®¯¯¯®¯­®¯¯®®®®¯¯¯¯¯®®¯®¯¯®®®¯¯¯¯¯¯­«§¢k;FcxŠ©¯°°¯®®¯®®®®¯¯¯®¯®¯¯®®®¯¯®®®­®®¯¯®¯®¯®®®­¯®®¯®®¯®®­®¯®®¯®¯®¯®®¯®®¯®®¯®¯¯®®¯¯®®®¯®¯°¯©™„mF$ "?aŠ£°°°®¯®¯¯®®®®¯¯¯¯®­¯­¯®®®®®®¯®­®¯¯®®¯¯®¯­¯¯®¯¯­®®®®®¯®¯®®¯¯¯¯®¯®®¯®®¯¯®¯®®®¯®®®®®®®®¯®¯®®±¯ª†b5 "Lƒ™¥ª¬­¯®®®¯®®¯¯¯¯¯¯®­®¯®¯¯¯¯®¯¯¯®¯®®¯®¯¯¯¯¯¯®®®®¯¯¯®¯®¯®¯¯®¯¯®¯®®¯¯®®¯®¯®­®®®®¯®¯¯¯¯¯¯¯¯¯®¯®¯¯®®©£˜h? C\z¥®²°°®®®®¯¯¯¯®®¯¯¯®®¯­®¯¯®®®®®¯®¯®¯¯®®¯¯¯®¯¯¯¯®¯¯®¯®®¯®®®®®¯¯¯¯¯¯¯¯®®®®¯¯®®®¯¯®¯¯¯®¯®¯®®®®¯®®®¯®°°­™…eF.Q‡¯±¯®¯®®¯¯®®¯®®¯®¯¯®®®®®®®®®®®¯®¯®¯®¯®®®®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯®¯¯¯¯¯¯®®¯®®®¯¯®®¯®­®®®¯®¯¯¯®®®®®¯±®£‹Q)g‰£ª¬¯¯­¯¯®®®¯¯®®®¯®¯®¯¯®¯®®¯¯¯¯¯®¯¯®®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯­¯¯®®®¯¯®¯®®¯®¯®®®®¯­®®¯®®¯¯¯¯­¯­®­ªŸ['Vw—¦°±°®­¯­¯®¯¯®®®¯®¯®®®®¯®®®®¯¯®®¯®¯®¯¯¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯®®®¯®®¯®®®¯¯®®¯®®¯¯¯¯­¯°°£‘kF!^®°¯®¯®¯¯®®¯®®¯®®®¯¯®®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®¯®®¯­¯¯®®®®®®®®¯¯¯¯¯¯­®°®§}BX{™¥®¯®¯¯®®®¯®¯®®¯¯­¯®¯¯®¯®¯®®®­®®¯¯¯®®®®®¯®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯¯¯®®¯¯¯®¯¯®¯®¯®®¬¡f@6[Ž¥°¯¯¯®¯¯®®¯®®®®®¯®¯¯®®®®®®®¯®®¯®¯¯¯®¯¯¯¯®­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­®¯¯®¯¯®®¯¯®®®¯¯®®®®®®®¯¯®®¯¯°­–zG&D†§­¯¯¯®®¯®®¯®®¯¯®®¯¯®®®®¯®®¯¯¯­®¯®¯¯¯¯¯­¯®®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®¯¯¯®¯¯¯®¯®¯®®®®®¯¯¯¯¯¯¯­¯¯¯©œo*,\ަ­®¯¯®®®®®¯®¯¯¯®¯¯¯®®¯¯¯¯®¯®®®¯®¯¯¯­¯®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯­¯®®¯®®¯¯¯¯®®¯®¯¯®¯®®®®®®¯¯¯®ªŸƒK (l‘¬±¯¯®¯¯®¯®¯®®¯®¯¯­®¯®®¯¯¯®®¯®¯®¯®¯®¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®®®¯¯®®¯¯¯®¯¯®®¯¯¯¯®¯®¯¯¯§…[%@|¢¯¯¯¯¯®®¯¯¯¯¯®®¯¯¯¯®®¯¯¯®®¯­®®¯®¯¯¯¯®¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®­¯®®®¯®¯¯®¯¯®¯¯®¯¯¯®®®¯®®¯®¯›s6T¡«®®®¯®¯®¯®­¯®®¯¯¯¯¯¯®¯®®®¯¯®®®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯¯¯®®®¯¯®¯¯®®®¯®¯®®®®®¯®¯®¯¯ªŸ~XOФ±¯®¯®®¯®®®¯¯®¯®¯¯­®¯®¯®®¯®®®¯®¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®®®¯¯¯®®¯¯¯¯®®¯®¯®¯¯®®®¯®¯¯°±¢U#Z‘«¯¯®¯®¯¯®¯®¯¯®¯®®®¯®¯®¯¯¯®¯®®®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯®®¯¯®®¯®¯¯®®¯®¯¯­¯®®®¯®®¯¯«i$!\‹¨®¯¯¯¯®®¯®¯®¯¯®¯¯®®¯®®®®®¯¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯¯¯®®¯¯¯¯¯®®­¯¯®¯¯¯®®­®¯¯®¯¯®ª—}< TŽ¥±®¯­¯®®¯®®¯¯®®¯®¯¯®®®®¯¯¯¯¯¯®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®­¯®®­¯¯¯®®­¯¯¯®¯¯¯®¯¯®¯¯­¦r> Y‰®¯®¯­®¯®®¯¯®¯¯®¯®®¯®®¯®®¯®®®¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®¯¯¯®­¯¯®¯¯®®¯®¯®¯®¯®®®¯¤Ž6?¤¯®¯­­¯¯®¯¯¯­¯®®®¯®­®¯¯¯®­¯¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯¯¯¯¯®¯®®¯®¯¯¯¯¯®®¯®¯®¯®®¯®¬¦…H ;z©¯®®®®®¯¯¯®®¯¯¯¯®®¯®¯¯®¯®®®¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯¯¯¯¯®¯®¯­¯®®¯¯®ª{B "tª¯¯®¯¯¯®¯¯®®®®¯®®¯®®¯®¯®®¯®¯¯®¯®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯®®®®®¯¯®®®¯¯®®®®¯®®®¯®¯¥9 n–®¯¯¯¯¯®¯¯®¯®®¯¯®®¯®¯®®¯®®¯®¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®®¯¯¯¯¯®®¯®®®¯®®¯­¯®¯®¬¦}QI›¨°¯®­¯¯®¯¯¯¯¯®®¯®®®¯®¯®¯®¯®¯®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯¯®®®®¯¯¯®®®¯®®¯®¯¯°¯¡5 J{¬¯®¯®®¯®¯¯®®®®®­®¯¯®®®¯®®®®¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®¯¯¯®®¯®¯®¯®¯®¯®¯¯®¯®®¢|5*ž¯¯¯¯¯®®®®®¯¯¯®®®®®¯®®¯¯®¯­®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯¯®¯¯¯¯¯¯¯®¯®®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯­¯®¯¯®¯¯¯®¯¯¯®¯®­®¯®®« f0W›¯®¯®®®®®®¯¯¯®¯¯¯®®¯®¯®¯®®®®¯®¯®¯®®¯¯¯¯¯¯®®¯®¯®¯¯¯¯¯¯®¯¯¯¯¯®¯¯¯¯®¯¯¯¯®¯®®¯®­¯¯®¯¯¯¯¯¯¯¯¯¯®¯­¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯¯®®¯¯®¯¯®®®®¯¯¯¯¯®¯¯¯¯¯ŒeH¨°®®¯­®®®¯®¯­¯®¯®¯¯¯¯­®¯®®®®¯¯®®¯¯¯¯¯¯¯¯¯®®®®¯¯®¯¯®®¯¯®¯®¯¯®®®­®¯®¯®®¯®¯®®¯¯­¯¯¯®®¯®¯®­¯®®¯¯¯¯®®¯®¯®¯¯¯¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯®¯®¯®®®¯®®¯¯®¯®¯¯ª›C,m¦¬¯¯®®¯®®®¯¯®®¯®¯¯®¯®¯¯®¯®®¯®®®®­¯®¯¯¯¯¯®¯®¯®¯®¯¯¯¯®®®¯®®®®®¯¯®®¯¯¯¯®®¯¯¯¯®¯¯­®¯¯¯®®®¯¯®¯®®®®®¯®¯¯®®®®¯¯®¯®®¯¯­¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®®¯¯¯¯®®¯¯®®®®®¯®¯®®¨{J]‹±®®¯®®¯¯®®®¯¯¯®¯®®®¯®¯¯¯®®®®®®¯®®¯¯¯¯¯¯®¯®¯®¯®®®­¯®¯­®¯®¯¯®®¯¯®¯¯¯¯¯¯®¯®®¯­®®®¯¯¯®®®¯®¯¯¯¯¯¯®¯®¯¯¯¯®¯¯¯¯®¯¯®®¯®¯®¯¯®®®­®®¯®®¯®®¯¯¯¯¯¯¯®¯®®¯¯¯¯®¯®¯¯®®®¯®¯®¯®®®¯¯¯°®Ÿu8’¦¯®¯®¯¯®®®®®®®®®¯¯¯¯®®¯®­®­¯®¯¯®®®®¯¯¯®¯¯¯­¯®¯®®®®¯®¯¯¯®®¯¯®®®¯¯¯®¯¯®®¯®®¯®­®®¯®¯®¯®¯¯®®®®¯®®¯¯®¯®¯¯¯¯®®¯®®¯®¯¯¯¯®®®¯®®¯¯¯¯®®¯®®¯®¯¯¯¯¯¯¯¯®¯¯¯®¯¯®®®®¯¯®¯®®®¯®¯¯¯¯¯®¯”D&^¤¬®¯¯®®¯¯®®®®¯®®¯¯¯®¯®®®¯®¯¯¯¯¯®®®¯¯¯¯®¯¯¯®®®®®¯¯¯¯¯¯®®¯®®¯®®¯®®®¯®¯®¯®¯®®®®¯®®¯®¯®¯®¯®®®®®¯¯®¯¯¯®®®¯¯¯®®¯®®¯®®¯®¯®®®¯®®¯¯®®®®¯¯¯®¯®­¯¯¯¯¯¯®®¯¯®®®¯¯®¯¯¯®¯®¯®¯¯®®¯®®¯¯¤~5O€­¯®®®¯®¯®®¯®¯®®®®¯¯®®®¯¯®®¯®¯¯®¯¯¯¯¯¯¯­¯®¯¯®¯¯¯¯®¯®¯¯¯¯¯¯®®®¯¯®®¯®¯¯®¯®®¯®®®®®¯®®®¯®®®¯¯¯¯®¯¯®®¯®®®¯¯­¯¯¯¯¯®®®®®®¯®®®¯®®¯¯¯®®®¯®¯¯®¯¯¯®¯¯¯¯¯¯®®®¯®®®¯®®®®¯¯¯¯®¯¯®¯®¯®¯­ŸV¢­¯®®¯¯®¯®¯¯®¯¯¯¯¯®¯­®¯®®­¯¯¯®¯­¯®¯¯®¯¯°¯²°¯³±°¯¯¯¯¯®¯®¯¯¯®®®¯¯¯¯¯¯®®¯¯®¯¯¯®®¯®¯®¯­¯¯­®¯¯®®¯®¯®®¯®®®¯®¯®¯®¯®®®®®®®®¯®®®¯®¯®¯¯¯®®¯¯®®®¯¯®®®®¯¯¯¯®®¯®®®¯¯¯®¯¯¯¯¯®®®®¯¯¯®®°¬w96”¬¯¯¯¯®®¯¯¯®¯®¯®®¯®®®¯¯¯¯®®¯®¯¯¯®¯¯¯®°±²¬©¨˜§ž©°®°¯¯¯­®®®¯¯¯®®®¯®®®®®®¯¯¯¯­®®®®®¯®¯­¯¯­¯¯¯¯®®¯¯¯®¯¯¯¯¯®¯®®®®¯®­®®®¯¯¯®®®®¯¯®¯®¯¯¯¯®®®®®®­®¯®¯®®¯®®®®¯®®®®®¯¯¯¯®­¯¯®¯®®®®¯­–l"b¡°¯¯®®®®®®¯¯®®®¯®®¯®®¯­®®®¯­¯®®®¯¯¯°±µ¨Œ‡^^\`œ¤¯±¯¯¯­¯¯®®®®®®®®®¯®®®¯®®®¯®¯®­¯¯®¯®®®¯¯¯®¯¯¯¯¯®®¯¯¯®¯®¯¯®¯¯¯®®®­®¯¯®®¯®¯¯®®®®®®¯®¯®®¯®¯®¯°°°¯¯¯®®®¯®¯®¯®¯¯¯®®®¯®¯®®¯®¯®®¯ª)D©°¯®¯®¯¯¯®¯¯®­¯®®¯¯®¯¯®¯¯®¯¯¯®¯¯¯®°±¶—hJC" &f˜±¯¯¯®¯¯®®®¯®®¯®¯¯®¯®®¯®®®¯®®®¯®¯¯®®®¯®¯®¯¯¯®¯®¯®®®®¯®®¯®¯®®¯¯¯®¯­¯®®¯®¯®¯®¯¯®®¯®®¯®¯®°¯¯´«¨±±®¯®¯®®®¯¯¯®®¯¯­­®®¯¯®¯®¯®®¯°žW-b¤­®®®¯®®®­¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯¯®¯¯¯°±±‡G$ !Ttž°®®¯®®¯¯®®¯¯®®­¯¯®®®¯®¯®®¯®®¯®®®¯®®¯®®®®®®®®¯¯®®®¯®®¯®®­®¯®¯¯¯¯®¯®¯¯¯®®¯®®¯¯¯®¯®¯®°²®ª¯–~«³®®®®¯¯®¯®®¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯¯¦†S,u­®®®®¯®®®¯®­¯®®®®¯¯¯¯®¯¯¯¯®®®¯¯¯¯°¯ª‚<%W„«°¯¯¯®®¯®¯¯¯®®¯¯®¯¯®¯¯®®¯¯­®¯®®®¯¯¯¯¯®®¯®®®®®®¯¯®®®®¯®®®®®®®®®®¯®¯¯®¯®®¯®¯®®¯¯¯®®²²­¡¤uB>Q‡®°®®®¯¯¯¯®¯¯¯¯¯¯¯¯®¯¯®¯®®¯¯®¯¬¢l WŒ¯¯¯¯¯¯¯¯¯¯®®®®¯®¯®®®®¯¯®®¯¯®¯¯®¯¯¯«R0@’­¯®¯®®¯®¯¯®¯®¯¯¯¯¯¯¯®¯¯®®­¯®®¯¯®®u/Y‰©¯®®¯®¯¯¯¯®­¯¯¯¯®®®¯¯­¯¯®®®¯®®¯¯®¯­£J 1ež¯®¯¯®®®®¯¯®¯¯¯®¯®®®®¯®®¯¯¯®®¯®¯¯®¯¯¯¯®¯®®¯®¯¯®®¯¯¯®®®¯®®¯¯±´¦–‹|j`[:7, Z˜®¯®®¯®¯®¯®¯¯®¯¯¯¯¯¯¯®®®¯¯¯¯¯¯®¯¯¯ŠSv¦¬®®®®¯®¯®®­¯®¯®®®¯¯®®®­¯¯®­®¯¯¯¯­¯®•I#X—²¯®®¯®®®¯®¯¯®®®®®¯¯®®®¯¯®¯¯®¯¯®®®®¯¯¯®®®®¯¯®¯¯¯¯®¯®¯®®¯¯®¯²­•ogP*7- \£®¯¯¯¯¯¯®®®¯®¯®¯¯¯¯¯¯¯®®®®®®¯®®®®¯¡|„®®¯®¯¯¯¯¯¯¯¯®¯®¯®¯®®¯­¯®®¯¯®®®®¯¯­¯¯Œ4! ,`œ²¯¯¯®¯®¯®¯¯®¯®¯®®®¯¯®¯®¯®¯¯®®®®®®®®¯®®®¯®®®®®¯®®°­¯®¯¯®®¯¯´ }H#!5­®¯®¯¯®¯®®¯¯®®®®¯¯¯¯¯®®¯®®¯¯®®®¯®®«-7±®¯¯®¯®¯¯®®®®®¯¯®¯®¯®¯¯®®®¯®®®¯¯¯®¯®Ž5LeeS9?LPz©°®®®¯¯¯®¯®®¯®®®¯®¯¯¯®®¯®¯®¯¯¯®®®¯®®­¯¯®®®­¯­®¯¯¯²¯®°¯¯¯®¯¯³œm,U ­®®®¯¯¯®¯¯®¯¯®®®¯¯¯¯¯­¯®®¯¯­®®®¯®®¯›H*Z—²®¯®¯®®®¯®®®¯¯®¯¯¯¯®®¯¯®¯¯®¯®¯¯®¯®¯«„: K•£¡ž‰–´®¯®¯®®¯¯®¯¯®®®®¯¯®®¯¯®®¯®®¯¯®¯®®¯®®¯­®¯®¯®­¯®¯°²³§ µ°®°®®¯°œg(,~¦¯®®®®­¯®®¯®¯¯¯®¯®¯¯¯¯¯®®¯¯®®¯­®¯¯¯¯¢n1u®±¯®¯®®®¯¯®¯¯¯¯¯®¯¯¯®®¯¯™a=”®³›WŽ·±®®­¯®®®¯®¯¯®¯®¯¯®¯¯°¤Ž:H“®²±ŠL& %'F”©®®¯®¯®¯­¯®®¯®¯®®¯®¯¯®®­¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¦UWŒ©°¯¯¯¯¯¯¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯¯¯¯®¯¯¯®®¯®¯®¦ˆI `¤²¯®®¯®¯®¯®¯¯®¯¯®®®®¯¯£Y*v¡¯®¯¯‚:)0ZslZAd£®°®®¯¯¯®¯¯®¯­®®®¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¤E Q‡©®®¯®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯®¯®®®¯®®¯®®®¯®¯¯«ŽV%I¬²¯®¯¯¯¯®®¯¯¯®¯¯¯®®®§o".@v¤²¯¯¯µš_ +Ni‡¡§§šuS.†®²¯®¯¯¯®¯¯®®®®¯®®¯¯®®¯®®¯¯¯¯¯¯¯¯¯­¯®¯¯®¡6 K€¨°¯¯¯¯®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®­®®¯®®¯¯®®¯®¯®¯®®¯±¤h6 -e¯¯®®®®¯¯¯®¯®®®¯®®®«‹J5e\]lt’©´°­¯¯­œQBw‹Ÿ¬¶­¶¯˜€A $lª°¯®­®¯®®¯®¯®¯®®¯®¯®®®®®¯¯¯¯¯¯¯¯®®®®¯®«˜. Ex¦°¯®¯®®¯¯­¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®¯®¯®¯®®¯¯¯¯®¯²­Ž7 T¨®®®®®¯¯®®®®®¯®­®±¤y11‡¡Ÿ¤¡ª­´¯¯­¯³£d  2zž­®²¯®¯±¬Ž]*o¥®¯¯®­¯®¯¯®¯®¯®®®®¯¯¯®®­®¯¯¯¯¯¯¯®®¯¯¯®¨*;n¥°¯®®®®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®¯®¯¯¯¯®®®¯®¯®°°­f)u¡±®®¯¯®¯®®¯®¯®®¯´¬‹C T›´±±±°²®¯¯¯´Ÿe% ;sŸ´²®¯¯¯°²¢t&w¦°®®¯¯¯¯®¯®¯®¯®¯®®¯¯®¯®®®¯¯¯¯¯¯¯¯¯®¯®¯«™00b¤±®¯¯¯¯®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯®®®®®¯®¯®¯®¯®¯°®–AF›±®®¯®®®¯®¯®®®®±«P VŸ¯®°¯¯®¯¯°±™e4 R„©²°¯¯¯¯±±ˆ0 c ²¯®®®®®®®®¯¯®®¯®¯¯®®¯¯®¯¯¯¯¯¯¯¯®¯¯¯®¯® G"S¡±®®®¯®¯¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®®®®¯­®¯­¯®®¯®®¯­­§vq¥²¯¯®®¯¯®¯®®¯¯«’e  j£¯¯®¯®®®²®–h=PZ3 )_«³¯®¯¯¯°Bd£°¯®¯®®¯¯¯¯®¯­®®¯®¯­®¯¯®¯¯¯¯¯¯¯¯¯®®¯®¯¯¨k, BŸ±¯¯¯¯¯®¯®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯®¯¯®¯®¯¯®®®®¯¯®®®¯¦‡H >Œ¯°¯®¯¯®¯¯¯®¯«¢z2 !Dj6Tž²³¯±¯°µ§jB%]˜Žf. 7j—¯±¯®¯°ª~0]«¯¯®¯®®¯®¯¯¯¯¯¯®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¬–_1œ°­¯¯¯®¯¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®®®¯®¯®¯­¯®®¯®°®”c &q °°¯¯¯®¯¯¯®¬ª€:  )[‘§g (}µ­²³¯¸ž‚d7#[’§¯’S$@{ž³±®®±§}r§¯®¯¯¯¯®¯®®¯®¯¯¯®¯¯®®®®¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®«|# —®®¯®®¯¯®¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®¯®®¯¯¯®®®®®¯®®¯±©x3 VŽ©¯®¯®¯¯¯¯­­{/ $;p¢¸£~E  <}œ–¡‚cT)I†§®´ª‚S U†¨±°°¯¡VE•±°®®®®¯®¯®¯¯®®®®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®±“Y'Ѝ¯¯¯®®®®®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯¯®¯­¯¯®¯¯®¯®®®¯µ—U 8ª­¯¯®¯¯¯¯­y1 @W…¯´´­“i) *RKTN3'+~¥°®­±§|H +i•ª³¯£s'^•®²°®¯®®¯®¯®®¯®¯®¯¯®¯®¯¯®¯®¯¯¯¯¯¯¯¯®®®¯¯®°¦“LwŸ®¯®®®®®¯®¯®­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯®®¯®¯¯®¯¯¯®®®®®°­€.b£¬®¯¯¯®¯®™S!<[v˜µ±°¯±¨€W% g¡²¯®®°³v= Auš®¬ˆL Bw‹­±¯¯®¯®®®®®¯®®®®®®¯®®¯®¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯­¬l' `“°¯®¯®¯®¯¯­¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯®®®¯¯¯®¯¯¯¯®®®®¯°žY4…¶°®¯¯®¯°Ÿm, 2ey‘¥´°°®®°´ž„T ;…­®®¯®®¯±—c1 J…Ÿ™i"CRQE1 E}¥±°®®®¯­±ª€L %36† «¯°®®®¯¯®¯®®¯¯¯¯¯®¯®®¯¯¯¯¯¯¯®¯®­®®¯®®¯±«h+m±¯¯®­¯®¯®¯¯¯­­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯¯¯®¯¯¯¯®®¯¯¯®®±£e* %]–±¯¯®¯¯¯°¯°²©­ª¦³®®²°±¯¯®®®®¯¯®¯¯°±¯«­šŽ™‡œ––‡N4gšª±°¯®¯®±´ž~F@Ž¡¯¯®¯®¯¯®¯­®®¯¯¯¯¯¯­®¯¯¯¯¯¯¯¯®®®®®®¯®¯¯­™cY¥¬°®¯¯¯¯®®®­¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®­®¯¯®¯®®¯¯®®¯¯¯®®²®‹7LЧ¯¯®¯¯­®¯°°¯²¯²°¯±®¯¯¯¯¯®®¯¯®®®®®¯¯±®³°¯±¯²µ£nQ–°³¯²¯±²©­ŠH " Y—­®¯®®®®®¯­®®®®¯¯®¯®®¯¯¯¯¯¯¯®®®¯¯¯­®¯¯¯®«†; K’¦°¯¯®¯¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯­®®¯¯¯®¯¯®®®®¯¯®¯¯°«k)wŸ¯¯®¯®®¯­¯¯¯®¯¯¯¯¯¯¯®¯®¯®¯®®¯®¯¯®¯­¯¯°¯±°°°¯²•;St•©´°­³—ƒY3Miy\B­®®®¯¯®®¯®¯®®®®¯®¯®®®¯¯¯¯¯¯¯®®¯¯®­¯®¯®¯°p(8rž±¯¯®®®­®®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯®¯®®®®¯¯®®®®°°•? Jœ°°®®®¯®®¯¯¯®¯¯¯¯®®¯¯®®®®­¯®®®®¯¯®­®¯¯®¯¯®¯¯´¦r$ CL†Œ…ŸzaX4 2aŽ­¯’tESŸ¯¯®®¯¯®¯¯¯®¯¯®¯®®®®®®¯¯¯¯¯®®®¯¯®¯¯¯®¯®®¬¢OL•±¯¯¯®®­­¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯¯¯®¯¯®¯®®¯®¯¡vv«°¯¯­¯¯¯¯®¯¯¯¯®®¯®®¯­®®¯­¯®­®¯¯¯®®¯®¯®®®®¯¯¯«˜X/<0A$"3z¤²¶¨‘`P•®¯¯¯¯¯®®®¯¯®¯¯¯®¯®¯¯®¯¯¯¯¯®®¯­®®­®®¯­¯®¯­K )Н®®¯®¯¯¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯¯­®®®¯®¯¯­¯¯®¯¯¯¦„J D“°°¯­¯®®®®®¯¯¯®¯®¯¯¯®®¯®¯­®­®¯¯¯¯¯¯®®®®®¯¯¯¯®¥{A ()a›¦¯³£d" L˜³¯®¯®¯®®¯¯¯®®¯¯¯¯¯®¯¯¯¯¯¯¯­®¯¯®¯¯­¯¯¯®®¯¯~!«®®®®¯®¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®®®®­­®®®®¯°®Ž`% +r§°¯®¯­¯®¯¯¯®®¯®®®¯®®®®®¯®®¯¯®¯¯®¯¯¯®®¯®¯®®¯°«š}5  B^f: )r𩳱v&F•°®®¯®®¯¯¯®¯¯­¯¯®®¯®¯¯¯¯¯¯¯®¯®®®¯¯¯®®®®¯®®®ŸKPœ«°¯¯®¯¯¯¯¯­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯­¯®¯¯®¯¯®®®¯¯®±¥q5 Z”ª¯¯®¯¯®®¯®®®®®¯®¯¯®¯®®¯®®®¯¯¯®®¯®®¯­¯¯¯®®¯°®¬Ÿ~D(,gš–j, 6£¬ªv% M™­®­®®®¯®®¯®¯­®¯®¯­¯®¯®¯¯¯¯¯®­¯®¯®®®¯®®¯®®°©yK-|§¯®¯¯®®®¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯¯®®®¯¯¯¯¯®®¯®®°´–G@‚ª¯¯®®®¯®¯¯¯¯¯®¯®¯®®¯¯®®®®®¯®¯®¯¯¯®¯®¯¯¯¯­¯®¯¯¯­Šu]0, ) U ¸¦c KŠ¢ª]až®®®¯®®¯­®¯­®¯®®®¯­¯¯®¯¯¯¯¯¯¯¯®®¯®¯®¯®¯¯¯®¯®¦|V¤¯®¯®¯¯¯¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯­®®®¯®®®¯®¯®­°°®v$f¤°®¯­®­¯®¯¯®¯®­®¯®®¯¯¯¯®®®¯¯¯®¯¯¯®®­®®¯®®®®¯®°µ©«£}eWnb: e¯°°¥‚TZ˜†= g§®®¯®®¯¯®®¯¯®¯¯®®®®¯¯®®¯¯¯®¯®¯®¯¯¯®®®¯¯¯­®¯®­–^0œ­®¯¯®®¯®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯¯®¯®®®¯®¯®®®¯® N 7г°®­¯®¯®®¯®®®­¯¯®¯®®®¯®®¯¯¯¯¯®®¯®¯­®®®®¯®¯®¯®®±°±°¬ ¬¡‹`$i𰳝Ÿ‹H%eV$ >‰¯°®®®®¯¯¯¯®®®®®®¯®®¯¯¯®¯¯¯¯®®®¯¯¯®®¯®®®®®¯¯­¯¦ŽC †¥®¯¯¯®¯®®®®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®¯¯®¯®®®¯¯¯¯­¥{-[¢µ®®¯¯¯®®®¯­®¯®®¯®®®®¯®®¯®®¯¯¯­®¯¯¯®¯¯®®¯¯®®¯®¯®°°°²¯´Ÿ^!O‡§¯µ²Ÿ~4 %5k¥­®¯¯®¯¯¯®¯¯¯®¯®®¯®¯¯®®¯®®¯®¯®®®®¯®¯®®®¯¯®®¯¯®°«l:\¯®®¯®­¯®¯¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®­®®®¯®¯¯®®±£‰Q :‚«²¯¯¯¯¯¯¯¯¯®¯®®®¯¯®®¯¯®¯®¯¯¯®®®®®¯®¯¯®®®®®®®¯®¯¯®®®¯±²|1!`t𭦬€U]ž³­®¯®®¯®¯®®¯¯®¯®¯¯®¯®®®®­®®¯®®®¯¯®¯®¯®¯­®¯¯®®¯­š{.z­®®®¯®®®¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯®­®®®¯®®®®®±­“d' ,i—±¯®®¯¯¯®¯¯®®®®®¯¯¯®®¯¯®®¯¯¯®¯®®¯®®®®¯¯®®¯¯®¯¯®®¯®¯®®±£V $1RprjM95‰®¯®¯¯¯¯­¯¯¯¯¯®¯¯¯¯­¯¯¯®®®®¯®®¯¯¯®¯®®®¯¯®¯®®¯¯¯®­œN [©®¯­®®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯¯¯®®¯®¯¯®®®¯¯®²©t7 Z‘§¯®¯¯®¯®¯¯®¯®®¯®®¯®®¯¯®¯®¯®®¯¯®¯®¯®®®¯¯­¯®®¯¯®­¯®¯®¯¯³4 ( %w¡±¯®®¯®®¯¯¯®®¯®¯¯®®¯¯¯®®¯¯®®®¯¯¯¯®®®¯®®®¯¯®®¯®¯¯©ˆQ/ލ¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯¯®¯®¯®¯¯®®¯®¯´™U 9‡¦­¯¯¯¯®¯¯¯¯¯¯¯¯¯®¯®®®¯®®®®¯®®¯®¯®¯®¯®¯­®®¯®®¯¯®®®¯®®°ª˜d"l›¯¯¯®¯¯¯­®¯®®®®¯¯®®¯®¯®®¯¯®¯¯®®­®®®®®®®®®®®­¯®¯¯­©0b¡°®®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯®®¯¯¯¯¯­®°°~-`¥¯¯¯¯¯®¯¯¯®¯­¯¯¯®®¯®®¯¯®®¯¯®®®¯¯¯®¯¯®¯®¯¯¯¯¯¯¯¯®¯¯®®±®¥‰NM¦§­±¯¯¯¯¯®®¯®®®®®®®¯­®®®¯®®®¯®¯®®¯¯¯®®¯¯®®¯®®®®®¯²ši#•®®¯¯®®®®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®¯®®¯®®¯¯¯®¯°ŸZ2…´¯¯®®¯®¯¯®®®®¯®®­¯®®®®®¯®®¯®¯®¯®®¯¯¯®¯®®¯®¯®®¯®¯®¯®®¯­žŠRj™©¯¯®®¯¯®¯¯®®®¯®¯¯¯®®¯¯¯­¯¯®¯®®¯¯¯®¯¯®¯¯¯¯¯¯¯®¯®®ª˜-y ®¯¯®®®®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®¯®¯¯¯®¯¯¯¯®¯¬¦7XŸ³°¯®®®®®¯¯¯®¯®¯­®®®¯®¯¯®®¯®¯®¯¯¯®®¯®®®®¯¯¯®®¯­¯®¯¯¯¯°¬­”aV:$($|¬­¯®®®¯®¯¯®®®¯®¯¯®¯¯®¯®®®¯®¯®¯®®®®®®¯¯®®¯®®¯®®®¯®¥FRƒ¬¯¯¯®¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®¯®¯¯¯­¯®®¯¯®¯«’RC~­°¯¯­¯®®¯¯¯¯¯®®®®¯®®®¯®¯¯¯®®¯®¯®¯®¯®¯®¯®¯¯¯®®­¯®¯®®¯¯°®±¢‹‰fhbQk|? F¢¯®¯¯®¯­¯¯®¯®¯®®®¯¯¯¯¯®¯¯®¯¯¯®­®¯®®¯®¯®®®­¯®®®¯¯¯ªZ%X§°¯¯¯®­®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®®®¯¯®®¯®¯®®®¯®¯°j, 5p𮝝®¯®®®®®®®¯®®®¯¯¯®¯®®®®®®®¯®®¯¯®¯¯¯®®¯¯®¯¯®®®®®®®®¯®²±«· ¨¨š®VC#4q¯°¯¯¯®®®¯®¯¯®®®¯¯®®¯®¯¯®®¯¯¯¯­®®®®®®®®®®®®¯®¯¯®¯©b.4—¦¯®®®¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®¯®¯¯®®¯®®¯®®¯®°­? c•ª¯®¯®®­¯®¯®­¯¯¯®¯®¯®¯®¯®®®¯®¯®¯¯®®¯¯¯¯®¯¯®®®®®®®­¯®®¯¯¯¯±®±²®¸°­¶™xO*u¦¬®¯®¯­®¯®¯¯®®®¯¯®¯®¯¯¯®®®¯®®®¯¯¯®¯®®®¯®¯®¯¯®®°ªX$k“°®¯­®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯¯®¯¯¯®¯®¯¯®®®®®²§k:«¯®®®®¯¯¯¯®¯®¯¯®®®®¯¯¯®®®®®®®¯¯¯¯¯®®®¯®®®¯®®®¯®®­®®¯¯¯¯®®¯¯®¯¯¯°¯°™fA,„³®¯®®®®®®¯®®®¯®¯®¯¯¯®®®¯®¯¯¯¯®¯¯¯¯®®®¯®®¯¯¯®¯¯£D#s­®®¯®¯¯®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯®®¯¯¯±¬”I`¬°¯®®®®¯®¯®¯®®®®¯®®¯¯¯®¯¯®®®¯®®¯¯¯¯®¯¯®®®¯¯¯®¯®¯®®®®®¯®®®®¯¯¯¯¯¯¯±¯wKK ®­®®¯¯®®®¯®¯¯¯®®®¯®¯®®®®¯¯¯¯®®¯®­¯¯®®®¯­¯¯¯°¨&Q›©¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®®®¯®®¯¯¯¯¯®¯¯¯¯®¯¥z$.‰¯±®®¯®¯¯¯¯®®¯®­¯¯®®®¯®®¯¯¯®®®¯¯¯¯¯¯®¯¯®¯¯¯¯®¯¯¯®®¯®®®®¯®®¯¯®¯¯®®°°«¤‹G(a©°®®¯®¯®¯¯¯®¯®®®®¯®¯¯®®®¯®¯®®®¯¯¯®®¯¯¯®¯¯¯¯³“R +t£±®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®­¯¯®®¯®®®®­¯®®®¯¯¯®®±¨†R#a£°¯¯®®¯¯¯®®¯¯®®¯®¯®¯¯¯®®¯¯¯®®®¯®®®­®¯®®®®®®®®¯®¯®¯®¯®®¯®¯®¯¯¯®¯®®¯°¬¤k u¨®®¯­¯¯®¯®®®¯¯®®®¯®®¯¯®®®¯¯¯¯®¯®¯®®¯¯¯¯¯¯ª”g3­¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯®®¯®®¯¯®¯¯¯­¯®®¯®®®®¯°¬“j,LŽ«°¯®®®¯®¯¯®¯¯¯¯®¯®¯®¯®­®®®®®®®®®¯®¯®®¯®®®®­®¯¯¯¯®®®®¯®®¯®¯¯¯®¯®®¯®¯¤~QA”±°¯®®¯®®®¯­¯¯®¯®¯®®®¯¯®¯®¯®¯¯®¯®­¯¯¯­®¬¥•U)Y˜®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯¯®®¯®®¯¯®¯®¯®¯¯®®¯®®®±©t<:¨¯®®¯®®®¯¯¯¯®¯®¯¯®¯®¯®®®®¯¯®®¯­¯®¯®®¯®¯¯®®®®®®¯¯®®¯®¯¯®¯®¯®¯­¯¯­¯¯¯¯™†U3¬°®¯¯¯¯¯®®®®®®®¯¯¯®®¯®®®¯¯®®¯®®®®®¯¯±¦[:.t¬®­®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®®®®®®®®®®®®¯¯¯®¯®°´–Sb¡³®¯®®®®®®¯®®¯®¯¯®¯¯¯®¯¯®¯®¯¯¯®®®®¯®¯¯¯¯®¯¯®®¯®®¯®¯®®¯¯®®¯®®®¯¯­®¯¯®¬¨>4{œ®®®®¯¯®®®¯®­®¯¯¯®¯®®¯®¯®®®¯¯®®¯®¯¯¬•{N8Ÿª¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯®®®®¯®¯®¯¯®®¯®®¯¯®°°~*9а¯­®¯¯®®®®®¯®¯®®®¯¯®¯¯®¯®¯¯®®¯®®®®®®¯®®®®¯®®¯¯­¯®¯¯®®®®¯®¯¯¯®¯®®¯¯­°«™r( L†®¯¯®®®­¯®¯®­®¯¯¯®¯­®¯®®®¯¯¯¯¯®®­¯ªœ[1i–±¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯®¯¯¯®¯¯¯¯¯¯®¯®¯®®²¦Ve²¯¯¯¯®®®¯¯¯¯¯¯®¯®¯®®¯®¯®®®®®¯®®®®¯®¯¯®¯¯®®¯®®®®®®®®®®®®®­®¯®¯¯¯¯¯®¯®§•sI0y¨¯­®¯®¯®®¯®®®¯®®®¯¯­®®®®¯®®®¯®®¯®O +|ª®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­®¯®¯®®¯®®¯®®¯®®®¯¯®¯¯®®¯­©Ž4OŒ«°®®®¯®¯¯¯®¯®®®¯­¯®®¯®¯®®¯®®®®®¯®®¯®¯®®¯®®¯¯®¯¯®­®®¯®¯®¯¯®®®®®¯¯®¯¯¯®««ˆcAs¦®®®®®¯®¯®®¯®®®¯¯®®¯¯¯¯¯­®­®¯®°¤ŠJS–­®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯®®®¯®¯®¯®®¯®¯¯®®¯¯«¤g6ˆ¥®¯®¯¯¯®¯®®®¯­¯®­®®¯®®®¯®®®®¯®­¯®®¯¯¯®®¯¯¯®®®®¯®®®¯¯®¯®®¯¯­®®¯¯¯®®®¯®±µ©]1 >†®®¯®¯®¯®¯®®®®®®®¯®¯¯®¯®¯¯¯¯¯¯®±‘J[¨®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®®¯¯°ž> n¨®®¯¯¯¯¯®¯®®®­¯®®¯®¯®¯®¯¯®¯¯¯¯®¯®®®®¯®®®®¯¯®¯®¯®¯¯®¯®®®¯¯¯®®¯¯¯®¯®®¯¯®°³¦ƒjG/Jk ®®®®¯®®®¯®¯¯®®®¯®¯¯¯¯®¯¯®®®®¯®°‘IŠ¡°¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®¯®¯®¯¯­¯¯¯®®®¯®¯¯¯®®²ª’]<𴮝¯®¯¯­¯¯®®®¯®®¯­®¯®®¯¯®®®®¯¯®®®¯®®¯¯­­®¯®®¯¯®¯¯®¯¯®®®®®¯®®¯¯®®¯®¯¯¯®³¯£¤‰‹•—ª°®¯¯®¯®¯®¯®®®¯¯¯®¯®¯®®®®®¯¯¯®¯±—^O…®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯­®¯¯®®®®®®¯¯®¯¯¯®®¯¯®¯²¥r6$m©¯®¯®®®®®¯®®®¯®®®¯®¯®®¯®¯®®®¯¯®®®¯¯®¯¯®®®¯®®¯¯®®®®®®¯®®®¯¯­®®¯®®¯®®®®®¯¯°«¬±®¯°¯¯®¯¯¯®¯®®®­®¯¯®®®¯®®¯¯¯®®¯­¯®¯¡+Z©¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­®®¯®¯¯¯®®®¯®¯®¯®¯®¯¯®®®¯¯±³•W$b™°¯¯¯­¯®®®®¯®¯¯®®®®®¯®®®¯¯¯®¯¯®¯¯¯®¯®®¯¯®¯¯®®¯®¯®¯¯­®®¯­¯¯®¯®¯¯¯®®®®¯®®®¯¯¯¯¯®¯®®®®®¯¯¯®­¯¯®¯­¯®¯®¯®¯¯¯¯¯®®®®¯« B-o—®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­®®¯®¯¯¯®¯®®®¯®®®®®®®¯¯®¯¯­±±*W‘¯¯®¯­­®¯¯®­®¯®®¯®¯®¯¯®¯®¯¯¯¯¯®®®¯®¯®®¯¯®®®¯¯®®¯®®¯®®®¯­®¯®¯¯®®¯®®¯®¯¯­¯®¯®¯®¯®¯¯¯®®¯¯¯¯­¯¯¯®¯®¯®¯®¯®¯®®®¯®®®®¯­`$~«¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®¯¯¯¯¯¯¯®®®®®¯®¯¯¯¯¯¯®®¯¶ž` 1Ž®°®¯®­®®¯¯®¯®®¯®®®¯®®®¯®®¯¯®¯®®®®¯¯¯®®®®¯®¯®®¯¯®®¯®¯¯®®®®®¯¯®¯¯¯®®¯®¯®®®¯®¯¯¯®¯¯¯®®®¯®¯®®¯¯¯¯®®®¯¯®¯®¯®¯¯®¯®®¯¯yBX‘¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯®¯­¯®®¯¯®¯¯¯¯¯®®¯®¯¯®¯¯®®¯®­­=e£³¯®®¯¯®¯®¯¯®®¯¯¯®¯¯®¯¯®®¯®¯¯¯¯®¯¯®¯¯¯®®®®®®¯¯®®¯®®¯®®¯®®®¯¯®¯®¯®¯¯¯®¯¯®®®®®¯®¯®®®¯®¯¯¯®¯¯¯¯®¯®¯¯¯®¯®®¯¯¯®¯®¯¯¯Žd $l¦¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯¯¯®®¯®®®®¯¯¯®¯®®®®®¯¯®¯®®¯°¢e"I’®°®¯¯®®¯®¯¯®®®¯®¯¯¯®®®¯¯¯¯¯®®¯¯¯¯®¯¯®®®®®¯¯¯®®¯¯®¯¯¯®®­®¯¯¯¯®¯¯®®®¯®®®®®®®¯®®¯¯®®®®®¯¯®®¯¯®®¯¯®¯¯®¯®­¯®¯®®¯®®¯¡ƒBœ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯®®¯¯®®®¯¯®¯®®®¯®®¯®®®®¯¯¦ƒIAˆ¨°¯¯®¯®¯®¯¯®¯®®¯¯¯®¯®®¯®¯®¯®¯¯®¯¯®®®®¯®¯¯¯¯¯®¯¯®®¯¯¯®®®¯¯®¯¯¯¯®­®®®¯¯­®¯®®¯®®¯®¯®¯®¯¯¯®®¯¯®®®®¯®®®®¯¯¯­¯¯®®¯¯¯¬•  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯®¯¯¯®¯¯®®®¯®¯®®®¯®®®®®°®œZ%6§¯®¯®¯®®®¯®¯®®®¯®¯®¯¯®¯®®¯¯¯®®®¯¯®®¯¯®®¯®®¯®¯¯¯®®®¯¯¯¯¯¯¯®¯®¯¯¯®¯®®®¯®®¯¯¯®®®®¯¯¯¯¯¯¯®¯¯®¯¯®®¯®¯®®®®¯¯¯¯¯®®¯¯®§W°¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®®®®¯¯¯¯¯¯®¯®®®®®¯®¯¯®¯®®®­¯²¯{:c£±®¯¯®¯®¯®®¯®®®®¯®¯®¯¯®¯®¯¯¯­®®¯®®¯¯®®®¯®®¯®¯¯¯¯®¯¯®®¯­®®®¯®¯¯®®¯¯¯¯¯¯®¯¯¯®®¯¯¯­¯¯¯¯¯®¯®®®®¯®®®®®®¯®®®®¯¯¯®®¯¯—t*v¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯¯¯¯¯¯®¯­¯¯®®®¯®¯¯¯®®®¯®®®°¯£W H’®¯¯¯¯¯®¯®¯¯®®­®¯­¯®®­®¯®®­¯®¯¯®®¯®¯®®¯¯¯®¯¯®¯¯¯®®¯®®®¯®¯®¯¯¯®®®®¯®®¯®®¯®®¯®¯¯¯®¯¯¯¯¯®¯¯®®®®¯¯¯¯¯¯®®®¯®®®¯¯®¯®q5]¦¬¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®®¯¯¯®®¯¯®¯¯¯®®®®®®®®®­¯¯°µ‹0;ª®®®¯¯¯¯®¯¯®®­¯¯®­¯¯®®®®®®¯®¯®®¯¯®®®¯®¯¯¯¯®®®¯®®®¯¯®®¯®®®®¯®¯®®¯®¯®¯¯¯®®®®¯®¯­¯¯¯¯¯¯­®¯®¯®¯­¯®®¯­¯¯¯®¯®®®¯°¤‰G3•§°¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®­¯¯®®®®¯¯¯¯®®¯­®¯¯¯®¯®®¯¯®¤j +~©°®¯¯¯®¯­®®¯¯¯¯¯®­¯¯¯¯­¯­¯®¯¯¯®®¯®¯®¯¯®®¯®¯®¯¯¯¯®¯¯®¯®¯®®®¯®¯®¯¯®¯¯­¯¯®®®®¯®®¯¯¯¯¯¯¯®¯­¯¯®®¯®®®¯®®­¯®®¯¯°­£†Po °®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®¯®¯¯®®¯¯®®®®®®¯¯¯®®®®­®®¯«—;^¦²¯®¯¯¯®¯®®®¯®¯®¯®®¯®­­¯®¯®¯¯¯®¯¯¯¯¯®¯®¯®®¯®¯¯®¯¯®®¯¯®­®¯­¯®®®¯®®¯¯­®­®®®¯®®¯¯¯¯¯¯¯¯®®®®¯®®®¯®¯¯®¯¯¯®®®¯­¥m8 F—°¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯®¯¯¯¯¯¯®®¯­®¯¯®¯¯®¯®¯¯®¯®®°¬cH’®°¯¯¯¯®¯¯®®®®¯®¯®­¯¯­®®¯­®®®¯¯®¯®¯®®®®¯¯¯¯®¯®®®®®®®¯®­¯¯®­¯®®¯®®¯®®¯­®®®¯¯¯¯¯¯¯¯¯¯¯®®®­¯¯¯¯®¯¯®¯®¯®¯¯¬¨‰f4‰¬¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®¯®®¯®¯­¯¯®¯¯¯®®®®¯®®¯¯®®¯°°žw-U‘ª¯¯­®®¯¯¯¯¯®®¯¯¯¯­¯®®®¯®­®¯®¯¯®®¯¯®®¯¯¯®¯¯¯®¯®®®¯¯®¯®®¯®¯®¯®¯¯¯®®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯®¯­®¯¯¯®®¯¯®¯®¯¯®® ŽSs ­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®®¯®®®¯¯¯¯¯¯¯®­¯¯¯¯®®®¯¯¯°¯†::®°®¯®®®¯¯¯¯¯®¯®®¯®®®®¯¯®®®®®¯®¯¯¯®¯®¯¯®®¯¯¯­¯¯¯®®®®¯¯®®®¯¯®¯¯®®¯®¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯®¯¯®®®®®®®­¦|+XŒ«°®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯¯®®¯®®¯®¯¯®®¯®®¯®¯®¯¯®®®®®¯µ£^"y«°®®®®®¯¯¯¯¯¯®­¯¯®¯¯®®®®¯®¯®®®¯¯®¯®®¯¯®®®®¯®¯¯¯®¯®®®¯®®¯®¯®¯¯®®¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯¯®®®®®¯¯¯®ª`E) ;q©°®®¯­¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®®®®¯®¯¯¯¯®¯®¯¯®¯®¯­®®®®®®¯¯®©‚0j¦­¯®¯¯®¯¯¯¯¯¯®®¯®®¯¯¯®¯¯­®¯¯®¯¯®®¯­¯¯¯¯®¯®­®¯¯¯®¯¯®®®®®¯®¯®¯®¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®¯®¯®¯®®®®­©£ˆg8V¥°®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®¯®®¯¯¯®®®¯¯®®¯®­¯®®¯®¯¯¯¯¨@k£­¯¯®¯¯®®®¯®®¯®¯®¯®®¯¯¯¯¯¯®®¯®¯®®¯¯®®®¯®®¯®®¯¯®¯¯®¯®®®®¯¯¯¯¯®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯®®¯¯¯®¯®¯®®¯¯®¯®­ª£‘a ;›¬¯®®®®¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯®¯¯®®¯¯®®®¯¯¯¯®¯®®¯¯­®®¯®¯°¬ŠFV³¯¯¯®®®¯®®®®¯®®®¯­¯®®®¯®¯®®¯®¯¯¯®®®¯¯¯¯®¯¯®¯¯®¯®­¯¯®®¯¯¯®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®¯¯®¯¯­®¯¯¯°¯©‚/ #Œ§®®¯®¯®®®¯¯¯¯¯¯¯¯®®®¯®¯®¯¯­®¯®¯¯®¯¯¯­®®®­¯®¯®®®¯®®¯³U Eް¯®¯¯¯¯¯®®¯®®®®¯¯¯¯®®®®­¯¯¯¯®®®¯¯®®®¯¯¯¯®¯­¯®®®®®®®®®®¯®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®®®¯¯¯¯®¯­®®®¯±“Onž°®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®®¯¯®¯¯­¯¯®¯±°²¯°°®¥g>𫝮¯®¯¯®¯®®®¯¯¯¯®¯®®®¯®­®¯¯®®®®¯¯¯®®®®¯¯®®®¯¯¯®¯®¯®®¯­¯®¯®¯®¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®¯­®°—`N“°¯¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯®¯¯¯¯¯¯¯®®®¯®¯¯¯¯®­¬«§±°°²¨^$¬°®®¯¯®®®®­®¯¯¯¯¯®­®¯®®®®¯¯®®¯®®¯¯®®¯¯®®®®¯¯¯¯¯®®¯®®¯®¯­®¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®®®¯®¯¯®¯®¯¯®¯®®±™b)ˆ°­®®®¯®®®®¯¯¯¯¯¯¯¯¯¯®®®­¯®¯®¯¯¯®¯¯¯®¯¯®°®ª¡kzŠŒ­¯›I 7€¬¯¯®¯®®¯®®®®®¯¯¯¯®®®¯®®¯®®®¯¯¯¯®¯¯®¯¯¯¯¯®¯¯­®¯¯®®¯®®¯®¯­¯¯¯¯¯¯¯¯¯¯¯®¯®¯­¯¯¯¯¯¯¯¯¯®®®®®¯®¯®®®¯®¯®¯®¯¯¯®®®°—[{¬®¯®¯®¯¯¯¯®¯¯¯¯¯¯¯¯¯®¯®¯®¯¯®¯¯¯¯¯®®¯®¯¯¯«•uN$)=DkyN%<…±®¯®¯®®®®¯¯®®®¯®¯¯¯®®®®®®¯¯¯¯®¯®¯®®®®®®¯¯¯®¯®¯®®®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯®®®®¯¯®¯¯®®¯®®¯¯¯¯¯¯®®¯¯®®¯®±‘Bk¢«¯­¯®¯®¯®®®®®¯¯¯¯¯¯®¯®¯®®®¯¯¯®¯®®®®®¯¯±¢q3   7‰¯®¯®®¯®®®¯®¯¯®¯¯¯®¯¯¯®®®¯¯¯¯®®¯®¯­®®®¯®®®¯®®¯­­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®®®¯¯®®¯¯®¯®¯®¯­¯¯®¯¯¯¯¯¯¯®°°®©˜l!\”¨°®®®®¯®®¯­®¯¯¯®¯¯¯¯¯¯¯¯®­¯®¯®¯­®¯¯®¯±©2 @–­¯¯®®¯­®®¯®¯®®¯¯®¯¯®¯®¯®¯®®®®®¯­¯®¯¯¯®®¯¯¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®¯®¯®¯­®®¯®¯¯®¯®¯®®¯®¯®¯¯®¯«¦›h8I}¥±¯®¯®®¯®®¯®®­¯¯¯¯®¯¯¯¯®®¯¯®¯®®¯®®¯®¯°‘C^ °¯¯¯®®¯®¯¯¯®®®¯¯®¯¯®¯­¯­®®®¯®¯¯®¯¯®¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯®¯®®®­®­¯®®¯¯®¯¯¯®¯®¯®®¯®®®®•hC7f ±¯®®¯®¯®¯¯¯®¯¯¯¯®®¯®¯¯®®¯®¯®®¯¯¯®¯¯®« !n§®¯¯®®®¯¯¯¯®¯¯®®®®¯¯¯¯®¯®®¯®¯®¯®¯¯®®®¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®¯¯¯®¯¯¯®®¯®®¯®¯®®¯®¯®¯¯®¯®¯¬•i-Mœ²¯®®¯®®¯®®¯®¯¯¯­¯¯®®®®­®­­®®¯¯¯®¯®¯¯¨p! ?‘®®¯¯®®¯®®¯¯®¯¯¯­¯®¯¯¯®®®®®¯®®®®­¯¯®®­®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®¯¯¯¯¯­®¯®®®¯¯®¯¯®¯¯¯®¯¯®©t5 :—±¯®®¯¯­®®®¯¯®¯¯¯­¯¯¯®¯­¯­®¯®®¯®®¯®®°­j 7}«­¯®®¯®®®®¯®¯®¯¯®¯®®¯®¯®®®®®¯¯¯­®®­®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­­¯®®®®®­®¯­¯®®¯®¯¯¯®®¯¯®®¯¯®®¯®®°¨j++’®®®¯®¯¯®­®¯¯®¯¯¯®¯®®®¯®¯®®¯®¯¯®¯¯®®°¬ˆ7/e›©¯¯¯®¯¯®®¯®®¯®¯¯®¯¯¯®®¯®®®¯®¯¯¯¯®®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®®¯¯¯®®®¯¯®®¯¯®®®®®¯¯¯¯®®®®¯¯©v8‹«®®¯¯®¯®¯¯­¯¯¯¯®®¯®¯®®¯®¯¯¯®¯¯®¯­®®°­`$&S‚¢®¯®¯®¯¯¯¯¯®®®®¯¯®¯®¯®¯¯¯¯®®¯®¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯­¯®®®¯¯®®®¯®®®¯¯®¯¯­®®®¯¯®¯®®®¯«ŒQ¦®¯®®¯¯®¯®¯®¯®®®®®¯¯®®¯¯¯¯¯¯®¯­¯®®®¯°§ŠX&O{¢²¯®¯¯¯®¯¯¯¯¯®®¯¯®®¯¯¯¯¯¯®¯¯®¯®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯¯®¯®¯¯®®®®®¯­¯®®¯®®®®®®¯®¯¯¯®¦n_ ®¯¯®®¯¯®®¯®®®¯¯®®¯®®®®®¯¯®¯®®®®¯¯®®°®¦Y) (4X„¦´¯¯¯¯¯¯®¯¯®¯¯®¯¯¯®®®¯¯¯®¯®­®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­®¯®¯®®®¯¯¯®¯¯®®¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯®®}U™­¯®®®¯®¯®®­¯¯®®®¯¯®­¯®¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¬›mX6&'*K\m“­µ®¯¯®¯®®®¯¯®®¯¯¯¯®®®®®¯¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®¯¯­¯®®¯¯®®®®®¯¯¯®¯®¯®®®®¯®®¯²‰/ J­¯¯¯¯®®®®¯®¯¯®¯®®®®¯¯¯®¯®®®®¯­®¯¯¯®®®¯±³¡rv}Š¢³³¯­¯¯®¯®®®¯®¯®®¯®®®¯®®¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®¯®¯¯¯®¯®¯®­¯¯®¯®¯®¯®¯®¯®¯®¯­®®²ECˆ¬¯®¯®®®®®®®®®¯¯®¯¯¯¯¯¯¯®¯¯¯­¯¯®¯®®®®®¯¯±²­±ª§®§©¶¯®¯®¯¯®®¯®¯®­®®¯®®¯®®¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯­®®®¯®¯®¯¯®¯®®®¯®¯¯¯®®®¯­¯¯®¯¯¯¯®®¯®®¯¯²‘P#=¬®¯¯¯®®®­®®¯¯¯­®¯¯®¯¯®®¯®®¯®¯®¯®®®®®®¯®®¯®°¯³¯­±¯®®¯¯¯®®¯¯¯¯®®®¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯®¯®¯®¯®®¯¯¯¯¯®®¯®­®®­®¯®®®¯®®®¯®®®¯¯²‘N"6z«°¯¯®¯­®¯¯®®¯®¯¯®¯®®®®¯®¯®®¯¯­¯¯¯®®¯®®®®®¯®¯®¯¯®¯¯®®¯¯¯®¯®®¯®¯®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯¯¯®¯®¯®®¯¯®¯¯®®®¯®®¯®®®¯®¯®®¯®®¯®®¯®¯¯®®¯¯¯¯®¯³‰3 1t«¯®¯¯¯¯¯¯®®¯®®¯®®®¯®¯®¯¯¯®®¯®¯®¯®¯®®®®®®¯¯¯®­¯¯¯®¯®­®¯¯¯¯®¯¯¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯­¯®®®®¯¯¯®®¯®¯¯®¯¯¯¯¯­¯®®®®¯®¯®¯®¯­¯¯®®¯¯­¯­®®¯®¯¯¯®¨x,o«®®®®®¯®¯®®®®®¯¯®®®®¯¯¯®®®¯®¯¯®®¯¯®®¯®®®®®¯®¯®®¯­®¯­®¯­®®¯¯®®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯®®¯®­®®¯­¯¯¯®®®®¯®¯®®¯®®®¯®®®®®¯¯®®®¯¯¯®®®¯®¯®­®¬’W)kª¯®¯®¯®®®®®®¯®®®®®®®¯®¯¯¯®¯¯¯®¯¯¯®®®¯®®®®®¯¯®®­¯­¯¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯®¯¯®¯®¯¯®®¯®­®¯®®®®¯®®¯®¯¯®®¯¯®¯­¯®¯¯®¯®®­®®­®®®­£\ (iª¯®®¯®¯®®®®¯®®®¯®¯¯¯®®®¯­®¯¯¯¯¯¯¯®¯®®®®¯®¯¯¯®®®¯¯¯¯®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯®¯®¯¯¯®®®®®¯¯¯­®¯®¯¯¯¯®®¯¯®¯®¯­¯®¯¯®¯®¯®®¯¯¯®¯°Ÿ/(i«®®®®®¯®¯®®®®®®¯®­¯¯¯¯®¯®®®¯®®®®¯¯®¯®®®¯®®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®­¯­®¯®®®®®®®¯¯®®®¯¯¯­¯®®¯¯¯¯¯®®¯®®¯®®®®®®¯®¯®®¯®¯¬7'iª°®¯¯®®®®¯®¯®¯­®®¯®®¯¯®®®¯®®¯®®®¯¯®®¯¯®®®®¯®®¯¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®®¯®®¯¯®®¯¯®®¯¯®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯®®°¯¡t> (i«¯®¯¯®¯®¯¯®¯®¯®¯¯®®¯¯®¯¯®®¯¯®¯¯®®®¯¯¯¯®¯®®¯®®®¯®¯¯¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯¯¯¯®®¯¯®¯¯¯®¯¯°¯°¯¯®­­¬¬­®®¯¯°°°°¯°°¯®¯°°¯®«¤–x;(iª°¯¯®®®¯®®¯¯¯®®®¯¯®¯®¯®¯®®®®¯®®®®¯®®¯®®¯­¯®®®®®¯®®®¯¯®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯®®¯®®¯®­¯®¯¯¯­­­«©¥¡ ¡¡¥¦§ªª¬¬­¬­­­­®­­­ª¦™„U+n«°®¯¯®®®®®®¯®®®¯¯®®®¯¯¯¯¯®®®¯®¯­®¯®®®¯®­®®®¯¯®®®¯¯¯®®®¯¯¯¯®¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®®¯®¯¯®¯®®¯®®¯®¨Ž{`UKFCA@BEGHMOTX[cehnprof\PF;).r«¯¯¯¯®®®®¯­®®®¯®¯¯®®¯®¯®®­®¯­®®®¯®¯®®¯¯®¯®¯¯­®¯¯®¯¯¯¯®­®®®®¯¯®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯®®¯¯®¯®¯®®®®¯®©˜€W@$  $)*2653, 7{«°®­®®®¯®¯®®®¯®¯®¯¯¯®®®®®®¯¯¯®®¯®®®®®®®¯®®®®®®®®®¯¯®­®¯®®®®®®¯¯®¯­®¯®®¯®¯®¯¯¯®¯®®¯¯®¯¯¯®¯®¯®®¯¯®®¯¯®¯®®®®®®®¯®¯®®®¯ª•b"J­¯¯®®¯¯®¯¯®¯¯®¯­¯¯¯¯®¯®®®¯¯®¯¯®®®¯¯¯¯­®®®¯®®¯®¯¯®¯®®®¯­®¯®®®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®¯®®®®¯¯®®®¯®®¯®¯¯¯¯¯¯®¯®¯¯¯®®¯®¯¯®®¥Ecž­®®¯®®®®®®®¯¯¯¯®¯­®¯¯®®®¯¯¯¯¯®¯®¯®¯®¯¯®®¯¯­¯®®®¯¯®®®®¯®¯¯¯¯®®®®¯¯¯¯®®®¯®¯¯®®¯¯®¯®¯¯¯¯®®¯¯®®®¯®¯¯¯¯¯®¯®®®®¯®®®¯®®®©Š`Š©®¯®¯®®®®¯¯®®®¯®®®¯¯®®¯®®®­®®®®®®­®®®¯®®®¯®®¯®¯¯¯®®®®¯¯¯®®®¯®®®¯®®¯®®®¯¯¯¯¯®¯®®¯®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®®®®¯¯¯¯®®¯®¯®¯«šO)’¯®¯¯­®®¯¯®¯¯®¯¯®¯®®­¯®®®®­¯¯®¯®¯¯¯®®®¯¯¯­¯­®¯®®®¯¯¯¯®¯®®¯®¯®®¯¯¯®®®¯¯¯¯®¯®®®®®¯¯¯¯¯®¯®¯®¯­®­¯¯¯®¯®®®¯¯¯®¯¯®­®®®®¯š^$ :•¯®¯°¯®¯®®¯¯®®®®¯¯®®®®¯¯®®¯®¯®®¯®®®®¯®®®®®¯®¯¯®®®¯¯¯®®¯¯®®¯¯®®¯¯®¯¯­®®®¯¯®®®®­®®®¯¯¯®¯¯¯®®¯¯®®­¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®¬¥ƒ+ >§©¬®¯®¯®¯®®®¯­¯®®®®¯®®¯®¯­¯®¯®¯¯¯¯®®¯®®®®®¯­¯®®¯®¯®¯¯®®®®®¯¯®®¯¯®®®®¯¯¯®¯¯®®¯®¯®¯®¯¯®¯®¯¯®®¯¯®®®¯®¯®¯®®®¯®®®®¯°©‰] (CTgxŽœª°°°°¯¯®¯¯¯®¯®®¯®¯¯®¯¯®¯®¯®®®®®¯¯¯®®®¯¯®®¯®®¯®¯®¯¯¯®®¯¯¯¯®¯¯¯¯¯¯­¯®®®®®¯®¯¯®¯¯®®®®®¯®®®¯¯®¯¯¯®¯®¯®®®®¯¯¯±£]1$=Wi–¤«®¯¯®¯¯¯¯®¯®¯¯¬««­®°¯¯­¯¯®®®¯¯®®®¯­¯¯®®®¯®¯®¯®®¯®¯®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯¯¯®¯®®®¯®¯¯®®®®®®¯®®®¯¯¯®®­®®¯š:%@i€œ§­®®¯®¯®¯®®®¯¦£¢§«­®®¯®¯¯¯¯®®¯¯®®¯®­¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯®¯¯®®®®¯¯­¯¯¯¯®¯¯¯¯¯¯®­¯®¯®¯¯®¯®®¯®¯®¯§Œ$ "4Qm‰ž«¯°¯®®¯¯®«¢’|nr~–£¬±±¯¯¯¯®®¯®®¯¯®®®®¯¯®®®®®®¯­¯®¯¯¯¯¯¯®®®¯®®®¯®¯¯¯®¯®¯®®®®®¯®®¯¯¯®®®®®¯¯®¯®®®®”r *Rm‡• §­°¯¯¯®§•yc\\jz‹™¡ª­°®®®¯®¯®¯®¯®¯¯®®¯¯®®¯¯¯®®¯¯¯®¯¯®¯¯¯¯­¯®¯¯¯­¯¯¯¯¯®¯¯®®®¯¯®¯­¯¯¯®®¯¯®¯¯¯®~T>n¡­¯®¯®®®«¥‚Z$Pr𥝮®®®®®¯¯®®®®®¯®®¯®®¯­®®¯®®®¯®®¯®®®¯¯®­¯®®¯®¯®®¯®®­®¯®¯®­®®­¯®¯®¯¯®®®®¬b( ,Ll‘£°°¯¯¯­¡”xS.'=[Ÿ¬¯°¯®®®®®®®®®®¯¯®¯®¯®¯¯¯¯®®®¯¯®¯®¯¯¯¯®¯®¯®®¯¯®¯®¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯®¯¬£K'Z~•£ª®®¯°¯¨…Y(Hw£«°®¯®¯®®¯®¯¯®®¯®®­¯¯¯¯¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯®¯®®®®¯®®®¯¯®¯®®®¯®®¯®®°§’4 3z•¨®®¯®®­£}S>x­¯®®®®¯®®®®®¯¯¯®¯¯¯®®®­¯¯®®®®®¯®®¯¯®¯®®®®®¯®¯¯®®¯¯¯¯®¯®¯®®¯¯®®¯±œq">h¥­°®°­¢Žm= -S|¤¬¯¯®®®®¯®¯®¯®®®¯¯®¯¯®®¯¯¯®­¯­®®¯­¯®®¯®¯®¯¯®¯®®¯¯®¯®®¯¯®¯¯¯¯¯®°J '^‰Ÿ©®¯¯±ªŸn.Lˆœª­¯®¯®®®¯¯®®¯®®¯¯®¯®¯¯¯®®®¯®®®¯¯®­¯¯¯®¯¯®®¯®¯®¯®®®¯®®¯¯®®¯¯¯­„-a‰«®¯¯®¬¢†@$^”§±­¯®®®¯¯¯®®®®®®®¯®®®¯¯®®¯®¯¯®¯¯®¯¯¯¯¯®¯¯¯®®®¯®¯¯®¯¯®¯®®®®®¤r;s”¬®°°­¤„V&L}®°®®®®®®¯¯¯®®¯¯®¯¯®®®¯®¯®®¯¯®¯®®¯¯¯®¯®­®¯®®¯¯¯®¯®®¯®®®¯®¬‹U'g—©­®¯®­ŒP!Ey «¯¯¯¯®®®¯®®¯®¯®¯®®­¯¯®®®¯®®¯¯®¯®¯®®®¯¯®®®¯®¯®¯¯¯¯¯¯¯¯®¯ªo7 <Œ£®°®®©›\& +f–°°®®¯®¯¯¯¯¯®¯®®®­®®¯®¯¯®¯¯¯®¯®®¯¯¯¯®¯¯®®®¯®¯®®¯®¯­®¯¯¯¨P @mš§°¯¯¬e(&b‹¨¯¯¯®®¯®®®®®­®¯®®¯¯®¯¯®®¯¯­®¯®®¯¯®®®¯¯¯¯®®¯®®®¯®®®¯®¬¡9 (o“«®®®¯–\0#S”¨®¯¯¯®®¯®®¯®®­®®¯¯®¯¯®¯®­®®®¯®®®¯®¯®®¯®¯¯¯®®¯¯®®¯¯¯¦’( Q©¯­¯ª¢o/ Pzª°®®¯®­¯®®¯®®¯¯­®¯®®¯¯®®­¯­¯¯®®®¯®¯®¯¯­¯®¯®®¯®®¯¯¯œzO‹¢¯¯¯¯—v9 D¡®®¯®¯®®¯¯®®­®¯¯¯¯®¯®®®¯®¯¯¯®®¯®®­¯®¯¯®®¯¯®¯®®®°®Œ^Vˆ©®®¯®¦j-Cƒ£®¯®¯¯¯­®®®®®¯®®®¯®®¯¯¯¯¯®¯®¯¯¯­®¯®¯®­®®®¯¯®¯®¯°~? @‹¦¯¯®­ x" Eq¥°¯®­®¯¯®®®®¯®¯®¯¯®®­¯¯®¯¯®®¯®®¯®®®¯¯®®®®¯¯­¯¯¯oG…¤®¯¯®™k/5}𝝭¯®®¯¯¯®¯®¯¯®¯¯®®®®¯®¯®®¯®®®¯¯®¯¯¯¯¯¯®­®®¬¥`UЍ®¯®¬¡_Bu¨­¯®¯®®¯¯®¯¯¯¯¯®¯®®®¯­®¯¯®¯®¯¯¯¯¯®®®®¯¯¯®®°¦•MF–¦¯¯¯­”q3¦±®®®®®¯¯¯¯¯¯®¯¯¯¯®®®¯®­®®¯®¯®®¯®®®®®®¯¯®°Ÿ};R„©­¯¯¨˜T* >„¡®¯¯¯¯¯®¯­®®¯¯¯¯®¯®¯®®®¯®¯­¯®®®¯¯¯¯¯¯¯®®²˜`*O–¦°¯®«‰_S§®­¯®®¯®¯®¯®®®¯¯®®¯®®¯¯¯®¯¯®¯¯®®¯®¯¯¯®®±ŽC>®¯¯®©ŽM :Œ¢¯¯®®®¯¯®®®®¯®¯®®¯®®®¯¯®®®®¯¯¯¯®®¯®¯®¯°ƒ& S«¯¯°¤‡BIw¤­¯®®®¯¯¯®¯¯®¯¯¯®®¯¯¯®®¯¯®¯¯¯®­®¯¯¯®­¦rY¬¯®®«r@ A‡¢­®¯®¯¯®­®¯®¯®®®®¯®®®¯®®¯¯®®®¯¯¯¯®¯¬˜_f—²¯¯¯¢‰- 2|°¯¯¯®®®¯¯®¯­®®®¯®¯¯­­¯®¯­¯®­¯®¯¯¯ª‚Fnž¬¯®®£m? o¤¬¯­®¯¯­«©£ŒpM% Js«°²±®¯¯¯¦œ‘ƒvdPA.:€’ž¨­¯®¯°¯±²­¡Žl_J<0*($#  3b§®¯®¯®¯®¯®«ªª©§¥¢–Žƒ}tnjh`]]]]]]]]]]\]]\]]]\]\]]]]]\]]]]]\\]\]]\\\\\]]][]]]]]\]\]\]]]\]]]]]]\]]]]^]]\]]\]]\]\]_P Qj…šª°³°°±°¯°°°±°«¨¥¢žšš˜––––––––––—––—•––––•––—––•—––•–––––—•––•—•–——––•––——–––––––––•––—–––––––––––•—––––––˜ƒ-Cy—ž£©­®¯¯¯®¯¯¯¯±¯°°°±±±±²±°±°±±°±°°±±°¯°°°±°±°°±°°±°²°±±°±±±°°°±±°±±°°±°°°±±°±±±°±±±±°±°±±±±°°°°±±±°°±°±±²!?`w¡®¯®¯®¯¯®®®¯®¯®¯®¯®®®®®¯¯®¯®¯®®¯¯¯®®®¯¯®¯¯¯®®®¯®®®®®®¯¯®­¯®®®®®®®¯¯®®®¯®¯¯®¯¯¯®®¯¯¯®®¯®¯¯®®¯®®¯®¯®¯®±› !Nbm|†Ž™Ÿ¥ª®°²´··¸·¸····¹¸¸¸¸¸¸¸¸·¸¹¸¸¸¸·¸¸¸¸¸¸¸·¸¸¸¸·¸¹¸¸¹¸¸¸¸¸¹¸¸¸¹·¸¹¸¸¸¸¸¸·¸¸·¸¸¸¸¸¸·¸¸¸·¸·¸¸¸¸¸º¥" #-6@ELPUXZ\^a``a`_aa`aa```a``_a`````aa_`_````````a``aa`a`_a``a```a```a`a````aa_````a````a`a`````bS openigtlink-3.0.0/Examples/Imager/img/igtlTestImage3.raw000066400000000000000000002000001501024245700231230ustar00rootroot00000000000000 "#%&*())))))*&$#"   !$,7CN[gq{‚‹’˜Ÿ¢£§¬­¬¬¬¬¬­­¨£¡ž˜Šwl^RE4)"  .G]qƒ“ž£¤¦¥§¨©©ª««¬¬­­®­®­­­­®®­­¬¬¬«ª©¨¨¦¥¤ Ž€hP6(?Ufp{ƒŽ•œ¤«¯²±±²°¯°°°°¯¯¯¯¯¯¯®¯¯®¯®®¯¯®°¯¯¯°¯°±²²°®©£™…wkZE(  (@So‚—ª®±±±±¯¯®¯®­¯®¯®®®¯®­¯®®¯®®®¯®®®®®¯¯®®®¯®®¯®¯¯®¯¯°°°°±²ªœ‡gG4 $@e†— ¤§©«­®®®¯­¯¯®¯¯®¯¯®¯®¯®®¯¯®¯®¯®¯®¯¯¯®¯®¯­¯¯®¯¯¯¯®¯®®¯®®¯¯®®­¬©¦£˜‚\1>Xk}Š˜¦­°±°°®®­¯®®®­®®¯¯¯¯¯¯¯®¯¯®®¯®­®®®¯¯®¯®®¯®®®®¯®¯¯®¯¯®¯®®®­®®¯¯®®¯°°­¤”kN0 &A\š­±±°¯¯®¯¯­®®®®®¯®®¯®®®®®¯¯¯¯®®®¯¯®®¯®¯®®¯®®®¯®¯¯®®¯®®¯¯®®®¯¯¯®¯®®¯¯®¯¯¯¯°±°ªpI% Cq‘ž¦©¬®¯¯®®¯­®®¯¯­¯®¯¯®¯­¯¯®¯®¯¯®®®¯®®¯¯¯®¯®¯®®®¯¯¯®¯­®¯¯®®®®¯¯¯¯¯®®¯®¯¯®®®¯¯¯¯¯¯­«§¢k;FcxŠ©¯°°¯®®¯®®®®¯¯¯®¯®¯¯®®®¯¯®®®­®®¯¯®¯®¯®®®­¯®®¯®®¯®®­®¯®®¯®¯®¯®®¯®®¯®®¯®¯¯®®¯¯®®®¯®¯°¯©™„mF$ "?aŠ£°°°®¯®¯¯®®®®¯¯¯¯®­¯­¯®®®®®®¯®­®¯¯®®¯¯®¯­¯¯®¯¯­®®®®®¯®¯®®¯¯¯¯®¯®®¯®®¯¯®¯®®®¯®®®®®®®®¯®¯®®±¯ª†b5 "Lƒ™¥ª¬­¯®®®¯®®¯¯¯¯¯¯®­®¯®¯¯¯¯®¯¯¯®¯®®¯®¯¯¯¯¯¯®®®®¯¯¯®¯®¯®¯¯®¯¯®¯®®¯¯®®¯®¯®­®®®®¯®¯¯¯¯¯¯¯¯¯®¯®¯¯®®©£˜h? C\z¥®²°°®®®®¯¯¯¯®®¯¯¯®®¯­®¯¯®®®®®¯®¯®¯¯®®¯¯¯®¯¯¯¯®¯¯®¯®®¯®®®®®¯¯¯¯¯¯¯¯®®®®¯¯®®®¯¯®¯¯¯®¯®¯®®®®¯®®®¯®°°­™…eF.Q‡¯±¯®¯®®¯¯®®¯®®¯®¯¯®®®®®®®®®®®¯®¯®¯®¯®®®®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯®¯¯¯¯¯¯®®¯®®®¯¯®®¯®­®®®¯®¯¯¯®®®®®¯±®£‹Q)g‰£ª¬¯¯­¯¯®®®¯¯®®®¯®¯®¯¯®¯®®¯¯¯¯¯®¯¯®®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯­¯¯®®®¯¯®¯®®¯®¯®®®®¯­®®¯®®¯¯¯¯­¯­®­ªŸ['Vw—¦°±°®­¯­¯®¯¯®®®¯®¯®®®®¯®®®®¯¯®®¯®¯®¯¯¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯®®®¯®®¯®®®¯¯®®¯®®¯¯¯¯­¯°°£‘kF!^®°¯®¯®¯¯®®¯®®¯®®®¯¯®®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®¯®®¯­¯¯®®®®®®®®¯¯¯¯¯¯­®°®§}BX{™¥®¯®¯¯®®®¯®¯®®¯¯­¯®¯¯®¯®¯®®®­®®¯¯¯®®®®®¯®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯¯¯®®¯¯¯®¯¯®¯®¯®®¬¡f@6[Ž¥°¯¯¯®¯¯®®¯®®®®®¯®¯¯®®®®®®®¯®®¯®¯¯¯®¯¯¯¯®­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­®¯¯®¯¯®®¯¯®®®¯¯®®®®®®®¯¯®®¯¯°­–zG&D†§­¯¯¯®®¯®®¯®®¯¯®®¯¯®®®®¯®®¯¯¯­®¯®¯¯¯¯¯­¯®®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®¯¯¯®¯¯¯®¯®¯®®®®®¯¯¯¯¯¯¯­¯¯¯©œo*,\ަ­®¯¯®®®®®¯®¯¯¯®¯¯¯®®¯¯¯¯®¯®®®¯®¯¯¯­¯®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯­¯®®¯®®¯¯¯¯®®¯®¯¯®¯®®®®®®¯¯¯®ªŸƒK (l‘¬±¯¯®¯¯®¯®¯®®¯®¯¯­®¯®®¯¯¯®®¯®¯®¯®¯®¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®®®¯¯®®¯¯¯®¯¯®®¯¯¯¯®¯®¯¯¯§…[%@|¢¯¯¯¯¯®®¯¯¯¯¯®®¯¯¯¯®®¯¯¯®®¯­®®¯®¯¯¯¯®¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®­¯®®®¯®¯¯®¯¯®¯¯®¯¯¯®®®¯®®¯®¯›s6T¡«®®®¯®¯®¯®­¯®®¯¯¯¯¯¯®¯®®®¯¯®®®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯¯¯®®®¯¯®¯¯®®®¯®¯®®®®®¯®¯®¯¯ªŸ~XOФ±¯®¯®®¯®®®¯¯®¯®¯¯­®¯®¯®®¯®®®¯®¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®®¯®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®®®¯¯¯®®¯¯¯¯®®¯®¯®¯¯®®®¯®¯¯°±¢U#Z‘«¯¯®¯®¯¯®¯®¯¯®¯®®®¯®¯®¯¯¯®¯®®®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯¯®¯¯®®­®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯®®¯¯®®¯®¯¯®®¯®¯¯­¯®®®¯®®¯¯«i$!\‹¨®¯¯¯¯®®¯®¯®¯¯®¯¯®®¯®®®®®¯¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯®¯¯®®¯¯¯¯®¯¯¯¯¯¯­®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯¯¯®®¯¯¯¯¯®®­¯¯®¯¯¯®®­®¯¯®¯¯®ª—}< TŽ¥±®¯­¯®®¯®®¯¯®®¯®¯¯®®®®¯¯¯¯¯¯®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®¯¯®®¯¯¯¯¯¯¯®¯®®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®­¯®®­¯¯¯®®­¯¯¯®¯¯¯®¯¯®¯¯­¦r> Y‰®¯®¯­®¯®®¯¯®¯¯®¯®®¯®®¯®®¯®®®¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯®®®¯¯®¯®®®¯®®¯¯®®®®¯®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®¯¯¯®­¯¯®¯¯®®¯®¯®¯®¯®®®¯¤Ž6?¤¯®¯­­¯¯®¯¯¯­¯®®®¯®­®¯¯¯®­¯¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®¯¯¯®¯®¯¯®®¯®®¯¯®®®®¯¯®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯¯¯¯¯®¯®®¯®¯¯¯¯¯®®¯®¯®¯®®¯®¬¦…H ;z©¯®®®®®¯¯¯®®¯¯¯¯®®¯®¯¯®¯®®®¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯°°²°®¯¯®¯®¯¯¯®¯­®¯®®¯¯®®®¯¯¯®®®¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯¯¯¯¯®¯®¯­¯®®¯¯®ª{B "tª¯¯®¯¯¯®¯¯®®®®¯®®¯®®¯®¯®®¯®¯¯®¯®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®­¥š¤­°¯®¯®®¯®®®®®®®¯¯®®¯®®®¯¯¯®®¯®¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯®®®®®¯¯®®®¯¯®®®®¯®®®¯®¯¥9 n–®¯¯¯¯¯®¯¯®¯®®¯¯®®¯®¯®®¯®®¯®¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®¯¯®]T„¢®¯¯®¯¯¯¯¯¯®¯®®¯®­®®¯¯­­¯¯®®¯®¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®®¯¯¯¯¯®®¯®®®¯®®¯­¯®¯®¬¦}QI›¨°¯®­¯¯®¯¯¯¯¯®®¯®®®¯®¯®¯®¯®¯®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®­¯®¯h3$Gk•ª°¯¯®¯®­®®¯®®®®¯®®®¯®®®¯¯¯¯®­¯¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯¯®®®®¯¯¯®®®¯®®¯®¯¯°¯¡5 J{¬¯®¯®®¯®¯¯®®®®®­®¯¯®®®¯®®®®¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯­«R `“ª¯®®®®®®®®®®¯®¯¯®®¯®¯®®®®®¯¯®¯¯®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®¯¯¯®®¯®¯®¯®¯®¯®¯¯®¯®®¢|5*ž¯¯¯¯¯®®®®®¯¯¯®®®®®¯®®¯¯®¯­®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯°­¨M^’«¯®®­®¯¯®®¯¯®¯®¯¯¯®­®¯®®¯®®¯®®®¯®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯­¯®¯¯®¯¯¯®¯¯¯®¯®­®¯®®« f0W›¯®¯®®®®®®¯¯¯®¯¯¯®®¯®¯®¯®®®®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®­¯®°¬¢IW™¯¯¯­­®®¯­®®®¯¯¯®®®®¯®¯¯®®®®®®®¯¯®¯¯¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯¯®®¯¯®¯¯®®®®¯¯¯¯¯®¯¯¯¯¯ŒeH¨°®®¯­®®®¯®¯­¯®¯®¯¯¯¯­®¯®®®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®²«“B"x§¯¯¯®¯¯®®®¯®¯®®­®®¯¯¯®®®®®­®®¯®®®¯®¯¯®­®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯®¯®¯®®®¯®®¯¯®¯®¯¯ª›C,m¦¬¯¯®®¯®®®¯¯®®¯®¯¯®¯®¯¯®¯®®¯®®®®­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯®®¯®®³©9JŠ­°®¯®®®®®®¯¯¯¯®¯®®¯¯¯®®¯¯¯¯¯®®¯®¯¯¯¯®®¯¯®­­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®®¯¯¯¯®®¯¯®®®®®¯®¯®®¨{J]‹±®®¯®®¯¯®®®¯¯¯®¯®®®¯®¯¯¯®®®®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®®¯®®¯³§o&!h©²¯¯¯®®¯®­¯®®¯®¯®®¯¯®¯¯®®®®®®¯¯®®¯¯¯¯¯¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯®¯®¯¯®®®¯®¯®¯®®®¯¯¯°®Ÿu8’¦¯®¯®¯¯®®®®®®®®®¯¯¯¯®®¯®­®­¯®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®­®®¯¯®®¯®³¦_G°®®®®¯¯®®®®®¯¯®¯¯®¯®®­®®¯¯®®¯®¯­­®®¯¯®®¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®®®®¯¯®¯®®®¯®¯¯¯¯¯®¯”D&^¤¬®¯¯®®¯¯®®®®¯®®¯¯¯®¯®®®¯®¯¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®®¯®¯¯°œL.‹©¯°®®¯¯¯¯®¯¯®¯®¯¯¯®¯¯¯¯¯®®®®®¯¯®®¯®¯¯¯®¯®¯®¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯®®¯¯®®®¯¯®¯¯¯®¯®¯®¯¯®®¯®®¯¯¤~5O€­¯®®®¯®¯®®¯®¯®®®®¯¯®®®¯¯®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯¯®¯¯¯®®®¯¯®©‰=y¡±®¯®®¯®®¯®®®®¯¯®¯®®®®®¯¯®®­¯¯®¯¯®¯¯¯¯¯¯¯®¯¯®¯¯¯¯¯­®¯®¯¯¯¯¯¯¯¯®®®¯®®®¯®®®®¯¯¯¯®¯¯®¯®¯®¯­ŸV¢­¯®®¯¯®¯®¯¯®¯¯¯¯¯®¯­®¯®®­¯¯¯®¯­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®®¯¯¯¯° n/d–²°®¯¯®®¯­­®¯®¯®­®®¯¯®¯¯®®¯®®®®®®®®®¯®®¯®­®¯®¯¯®®®®®®¯®®¯¯¯¯¯¯®®®¯®®®¯¯¯®¯¯¯¯¯®®®®¯¯¯®®°¬w96”¬¯¯¯¯®®¯¯¯®¯®¯®®¯®®®¯¯¯¯®®¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®®¯®®®¯°•G Pв°®¯®®¯¯¯¯¯¯¯®®­¯®¯®¯¯¯­¯­®¯¯®¯¯®¯®¯®®¯¯­®®®¯¯¯­®¯­®®¯®®¯¯¯¯¯®®¯®®¯®®®®®¯¯¯¯®­¯¯®¯®®®®¯­–l"b¡°¯¯®®®®®®¯¯®®®¯®®¯®®¯­®®®¯­¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯®®®®¯®¯ªˆ&?|±°®¯®¯¯¯¯­®®¯¯¯¯®®¯­®¯¯¯®®­®®®¯®®¯®®¯®¯®®¯®®®®®¯¯¯®¯®®¯¯¯¯®¯¯¯®¯®¯¯¯®¯®¯¯¯®®®¯®¯®®¯®¯®®¯ª)D©°¯®¯®¯¯¯®¯¯®­¯®®¯¯®¯¯®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯¯®¯®¯ w/q°°®­®®®¯­¯¯®®¯¯®¯¯®¯®¯®®®¯¯¯¯¯®­®¯¯®®¯¯¯¯¯®¯¯®®¯®¯®¯®®®®¯®®®®¯®­®¯®®¯¯¯®®¯¯­­®®¯¯®¯®¯®®¯°žW-b¤­®®®¯®®®­¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®®¯®¯®¯¯¯¯ŒQ !c®¯¯¯¯®¯¯®®¯®®®®¯¯®®¯®®¯¯®¯®¯®®¯®¯®®¯®®®¯®¯¯®¯®¯¯¯¯¯®®¯¯¯¯®¯®¯¯®®®¯¯®®®®¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯¯¦†S,u­®®®®¯®®®¯®­¯®®®®¯¯¯¯®¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯®®®®®¯®¯®®®®®¯ªw'Uª°®¯¯¯®­¯®®®®®®¯®¯®®®®¯®¯¯®®®®®®®¯®¯­¯¯¯®¯¯®¯®¯®¯®¯¯®¯®¯­¯¯¯®®®¯®¯¯®­®¯¯¯¯¯¯¯¯®¯¯®¯®®¯¯®¯¬¢l WŒ¯¯¯¯¯¯¯¯¯¯®®®®¯®¯®®®®¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®¯®¯¯®­§h  M¨±¯¯¯¯¯®¯®®¯¯¯¯¯¯®­¯¯®®­¯¯¯®¯¯¯¯®®¯¯¯¯¯®®®®®¯®¯¯®®®¯¯¯®¯¯®¯¯®¯¯®®®®¯­®¯¯¯¯¯¯¯¯¯®®¯®®¯®®¯¯®°„2}Ÿ¯®®®¯®¯®¯®¯¯¯¯¯®®¯­¯®®®®®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®®®¯®®®¯¯®¯¯¯­†H G¢°«©¦¤¥ª°°°¯¯¯¯¯¯®®®¯®¯®®¯¯­®¯®¯¯¯®®¯®®®¯®¯®®¯®®®¯¯¯¯¯®®¯®®¯¯­¯¯®®®®¯®¯¯®®®¯¯¯¯¯®®®®®®®®®®±–d)(˜¬¯®¯®®¯®®®¯®®­¯¯¯®¯¯®¯®®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®¯¯®®®¯®¯®¯°­j1 Cž¦•…yt|œ¦¬¯®¯®®®­®¯®¯®¯®®®¯¯®®¯®®¯¯®¯®¯®¯­¯®®¯®®®®®­®¯®®®®¯­¯®¯®®¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯°£?I¡¯¯®¯¯®­¯®¯¯¯¯®¯®¯®®¯®¯®®®¯®­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯¯¯®®®®®°­¢E+gfSD945?Sx›¯°®®¯¯®¯¯®®®¯®¯¯¯¯¯¯¯®¯¯¯®¯®®¯®­®¯­®¯¯®®¯­®®¯®¯¯¯¯®¯¯­®¯¯®¯®¯®®®®¯¯¯¯­¯®¯¯®¯¯¯¯¯­¨\8j¦°¯¯®®¯¯®®¯¯¯®¯®®®¯­¯®®¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®®®®¯­¯®¯®¯®²¢+ 9iª±¯®®®®®®¯¯¯®®¯¯­­¯®¯¯®¯®®®®®¯¯®¯¯®®¯¯¯¯¯¯¯¯®®®¯¯®®®¯®¯®®®¯®¯®¯®¯¯¯¯®¯¯®®­¯®®¯¯®®u/Y‰©¯®®¯®¯¯¯¯®­¯¯¯¯®®®¯¯­¯¯®®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®­®¯¯¯¯®®®´—TMŒ«®¯¯¯®¯¯®¯®¯®®®®®®®¯®®¯¯¯®¯®¯¯®®®¯¯®¯¯¯®­®®®¯®¯¯®®®¯®®®¯¯®®®®®¯¯¯¯¯®®®¯¯¯¯¯¯®¯¯¯ŠSv¦¬®®®®¯®¯®®­¯®¯®®®¯¯®®®­¯¯®­®¯¯­¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯¯®®­®¯¯®®¯®¯®°¬(SŒ­²¯®¯¯°®¯®¯°°®¯¯¯¯®®¯®¯®®¯®®¯¯®®®®®¯®®¯¯¯®¯®¯®®¯®®¯®®¯®¯¯®®¯®®¯¯¯¯¯®®®®®®¯®®®®¯¡|„®®¯®¯¯¯¯¯¯¯¯®¯®¯®¯®®¯­¯®®¯¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®¯®®¯¯®¯¯¯¯¯¯–]"X™®³´±¯ª¦¤¦ª°°¯®®®¯¯¯¯®®®¯¯®¯¯®¯¯¯®®¯®­®®®®¯®®¯®®®®¯¯¯®®¯¯¯¯®®®®¯¯¯®®¯®®¯¯®®®¯®®«-7±®¯¯®¯®¯¯®®®®®¯¯®¯®¯®¯¯®®®¯®®®®®®¯¯¯¯¯¯¯¯¯¯®¯®®¯¯®®¯¯®¯®¯¯®®®¯®¯¯°x++]‚Y!)x£²®¦ž“Š…ƒˆ“¡¬±°®®¯¯®®¯¯®¯¯®¯®¯®¯®¯®¯®®¯¯¯®¯¯®®®®¯¯®¯®®®¯®¯¯®®¯¯®¯­¯®®¯¯­®®®¯®®¯›H*Z—²®¯®¯®®®¯®®®¯¯®¯¯¯¯®®¯¯®¯¯®¯®¯®®®¯¯¯¯¯¯¯¯®®¯¯®¯®®¯¯¯®®¯®¯¯¯¯®®¯°¬žU O‰§°¤„NDs„fL8)#Cwœ¬°°¯®¯®¯¯¯®°¯®¯®®®¯¯¯®¯®¯¯¯®®¯®®®®®®¯®®®®¯®®®®®®®®®®¯®®¯¯®®¯­®¯¯¯¯¢n1s𮲱²²®©¢ž¡©®®¯¯®®­¯­®¯¯®­¯®®®®¯®®¯®¯®®¯®®®®¯¯¯¯®®®¯¯¯¯®®¯¯®¯­¯¯¬¤_[¦¬¯¯®¯®®¯®¯¯®¯¯®®®®¯®®®®¯¯¯­®¯¯®®®®®¯¯®¯®®®¯¯¯®¯¯®®¯®®¯¯¯®®®®®¯®¯³¢W *•²¯®®¯®±žJ.c¥²­¬¦ƒ||„ª±¯¯­¯®®¯®¯®¯­®®¯¯¯¯¯®®®¯®®¯®®®¯­®®®®®­®¯®®¯®®¯¯¯¯¯¯q k¬®®¯®®®®¯¯®®®®¯¯®®¯¯®®¯®­®®®¯¯¯­®¯¯®¯®¯¯®®®­¯®¯®¯®¯®¯¯®­¯®¯¯®¯¯®®± Ql™°¯¯¯¯°¥e*  /…›mO3  6k’©­¯®®®¯®¯¯®®¯¯¯®®®®®®®¯¯¯¯¯­¯¯¯®®¯¯­®¯®¯®­®¯¯­¯®®¯°~/"v°®¯¯¯¯®¯¯®®®®¯¯¯®¯­®¯¯¯¯¯®¯®¯®¯¯®®®¯®®¯¯¯¯®¯¯¯¯®®®®¯¯¯¯®®¯¯¯¯®¯¯¯°¡R=u©®®¯¯¯©v:;ShcN0PdX3 +Nx¡°®®¯¯¯¯¯¯¯®¯®¯­¯­®¯®¯®¯¯¯®¯®®¯¯¯®¯¯¯¯®®¯¯®¯®®®®®±‹L:°¯®¯¯¯¯¯®®­®¯¯¯®®¯®®¯®¯®®®¯¯®¯®®®®¯®®®¯¯¯¯®¯®®¯¯¯¯®¯¯®¯®¯¯¯®¯®®®®¯¦\:Ц¯®¯¯¬}CDv…‘މ|a6 <|Ÿ¯°®®¯®®¯¯¯®®¯®¯®­¯®­¯¯®®®®¯®®¯®®®¯¯¯¯­¯®¯¯¯¯¯¯¯¯˜n N‹¯¯®¯®­®¯¯®®¯®®¯¯®®¯¯®®®®®®®®®®®¯®¯®®®¯¯¯®¯®®¯¯®¯¯¯¯¯®®®®®¯¯®®®¯®®°«m `›°¯®¯­FB|§­­®±°¡l' 7qª¯®¯®¯¯¯¯®¯¯®¯®®®¯¯®¯®®®¯®®¯®¯®®­¯®¯¯®®¯®¯¯¯¯®¯¯¢†&b•¯¯®¯¯®¯®¯¯¯¯¯®¯¯¯®¯®¯¯¯®¯®¯¯®¯®®®®®¯¯¯¯¯¯®¯®¯®®®®®®¯¯®®®¯¯®®®®®¯¯¯¯„D 2Œ°®¯¯¯€Haœ®°¯¯°®¬šu# C–¬³³±¯°±¯¯®¯¯®¯®®®¯°®®¯®®®¯®¯®¯®¯®®¯¯¯®®¯¯®¯¯¯®®¬™/vŸ¯®¯®®®®®®¯¯¯®¯®®®®®®¯¯¯®¯®­®¯¯­®®¯¯¯¯¯¯¯®­¯¯¯¯¯¯¯¯¯¯®¯¯®®¯¯®¯®®¯®®±›s‚¯®®¯±}@w«®®¯®¯¯°° I Ja];!j‡”¤«¨¨©­­ª©¬¯«®°±²°¯¯­¯®¯®¯¯¯¯®¯®¯¯¯¯¯®®¯®¯®¯®­£B …¦®®®¯¯®®¯¯¯®®®®¯®¯¯¯¯­¯®¯¯¯¯¯¯®®¯®®¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®¯¯®®®¯®¯®®¯®®®¯°©–= (!  $¯¯®°³x7 2‚®°®¯¯¯¯®²®m/Z€e8 ",Cfˆ¤™ž©¥™’…€‚™££¬±®®®®®¯¯¯¯®¯¯¯¯¯¯®¯®®¯®¯®®¯¦U’¬¯®®®®¯®®¯¯®¯¯¯¯¯¯®¯®¯®¯®¯®®¯®¯®¯¯¯¯¯¯¯®®¯®¯­®®¯®®®¯¯®®¯¯®®®¯¯¯¯¯®®®®«s= )jw\, @Š­°®¯´t- GЬ¯¯¯®¯®¯²¯ŒP ;”«­®³£q/ %941240/* (*(%!  O’°¯¯¯®®¯®®®®¯¯¯¯¯¯¯¯®®¯¯¯­®¨o2f¤°®¯®®¯¯¯¯¯¯®®®®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®­¯¯¯®¯¯®¯¯®®¯®®¯¯¯­®¯®¯¯³Z       !EHNQU_W DsŒ‹Œ“› ŠL  .^|…”©­­®¯®®®®®¯¯®®¯¯¯¯¯¯¯¯¯®®¯®¯±~ Cx¦¯®®­¯®¯¯¯­­¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯¯¯®®¯®®®¯®®¯®¯®¯®¯®®¯²”<!)2-'Udinw~‚†ŒŽ‘–…7T¯ª«­¯¯Š7 *+1@_gSVfyrrˆž©©«¬®¯¯®®®®¯®®®¯¯®¯¯¯¯¯¯¯®®®¯¯®®±€ I}§¯®®¯®¯¯¯¯®®­®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯­­®®¯®¯¯®®®¯¯®®®¯¯¯®®®®®°²—A .48( m ¦£Ÿš„€Š™­³²¯®¯®¯®¯¯®¯¯®®®®¯®®¯®®¯®®®®®¯®®®¯¯®®®®®¯¯¯¯¯¯¯¯¯®®¯¯©u7\’ª°¯¯¯¯¯¯®¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®®¯®¯­¯®¯¯®¯¯®®¯®®¯¯®¯¯®®®®¯¯¯®®®®³™a,z¤¯°®¯´‘X S“±³±±¯ª¤£¥©®®¯®®®®®¯®®¯¯®­¯­®®®¯®¯®®®¯¯¯®®®¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯®¯®®¯§d&YŽ©¯®®­®¯­®¯¯¯®¯­¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®¯®®®®®¯®¯®®®®®¯¯®®®®®¯®¯®¯®®¯®®¯¯¯¯µ‘DY›±°®®°¶‰F X–¬®¯¯¯¯°¯¯¯°°®¯¯®¯®®¯¯¯¯®¯¯¯¯¯®­­¯¯®®¯®¯¯®®®¯®®®¯®®®®¯¯¯¯¯¯¯®¯®¯®¯¦UWŒ©°¯¯¯¯¯¯¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®®®¯®®®¯¯®¯¯®¯¯®®¯®®®­®®®¯®¯®®®®¯®®µ1D’¬®¯¯¯¯´{+ :h¬±­®¯®®¯®®¯¯¯¯¯¯®®¯®®¯®®®®®¯¯®¯¯®®¯¯¯¯¯®¯®¯¯­®¯®¯¯®¯¯¯¯¯¯¯¯®¯®®¯®¯¤E Q‡©®®¯®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®¯®¯®¯®¯¯¯¯®¯®®®®¯¯®®®®¯®¯®®¯®¯®®­®¯¯³‹+Lž°¯¯®°¯¢`38H¨³±®®®¯¯®®¯¯®®®¯¯¯®®¯¯¯¯®®¯¯®¯¯®®¯¯®®¯®®¯¯®¯®®¯¯®¯®¯¯®¯¯¯¯¯¯¯¯­¯®¯¯®¡6 K€¨°¯¯¯¯®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯®®®¯¯®¯®®¯¯®®®¯®¯¯®®¯®®®®®¯®®¯¯®®¯®®³15…¦¯¯°±¤z6 5k|kb^\Z^l”¤¬®®®¯¯®¯¯®¯®­®¯®¯®¯¯®®¯®®®®¯¯®®¯®­®®®¯¯®®®¯®¯®®®®¯¯®¯¯¯¯¯¯¯¯¯®®®®¯®«˜. Ex¦°¯®¯®®¯¯­¯¯®¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®¯¯¯®¯®¯®®¯¯®®¯¯®®¯®¯¯®®¯¯­®¯¯¯®®¯®®¯¯¯´–@Duœ¬±§ƒDf—¬©¥¡š•–Ÿ­´³¯®®¯­®®®¯¯®¯®®®®®¯®®®¯®¯®®¯¯®®¯®¯¯®®®®¯¯®¯®¯®®­¯¯¯¯®¯¯®¯¯¯¯¯¯®®¯¯¯®¨*;n¥°¯®®®®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯¯¯¯­®¯¯¯®¯¯¯®¯®¯®®¯¯®¯¯¯®®¯®­®®®®®®®³Ÿ[;o†ˆsI @‘¯±±°®¬¬¬­¯¯®®®®¯­®¯®®®¯®®®­®®®¯®®®¯®®®¯¯¯¯®®®¯®¯®®¯®®®®®¯­®¯®®¯¯®¯®¯¯¯¯¯¯¯¯®¯®¯«™00b¤±®¯¯¯¯®®¯®®®®¯¯¯¯¯¯¯¯¯®®¯¯®¯¯®®®®¯¯®¯®¯®®®®®®¯¯®®¯®¯®¯®¯¯¯®¯¯­­®®¯¯®±¦z8  +k¦³¯¯¯¯¯¯°®®®®¯®¯¯¯®¯¯®­¯®®®®¯®®¯®¯¯¯®­®¯®®®­¯®¯®®¯®¯­¯®¯®¯¯¯¯¯¯®¯¯¯®¯¯¯¯¯¯®¯¯¯®¯® G"S¡±®®®¯®¯¯®®®®®®¯¯¯¯¯¯¯®®®­®®®®®®®®®¯¯®®¯¯®¯¯®¯¯®¯¯¯®®¯­®¯®¯¯¯®¯¯¯¯¯¯¯°¬d  Zœ­°®®¯®®¯¯®¯®¯®®¯¯®¯®®¯®®®®¯®¯®¯®¯¯¯®®®®¯¯®¯¯®®¯¯¯®¯¯®¯®®­¯¯®®®¯¯¯®¯®¯¯¯¯¯¯¯®®¯®¯¯¨k, BŸ±¯¯¯¯¯®¯®¯¯¯¯®®¯¯¯¯¯¯¯¯®®¯¯¯¯®¯®¯®¯¯¯®¯®¯¯¯®¯¯®®®®¯¯¯­®¯®¯®®¯¯®®®¯­¯®¯­†/ J†±°¯¯¯¯¯®®®®®¯®®¯®®®¯¯®®¯¯¯®¯¯¯®¯¯®®­®¯®®¯¯®®®¯®®¯¯¯¯®®®¯®®®¯®¯¯¯®®¯®¯¯¯¯¯¯¯¯¯¯®®®¯¬–_1œ°­¯¯¯®¯¯¯®¯®¯®¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯®®®¯®®®®¯®¯®®®¯¯¯¯®¯®¯¯¯®¯®¯¯®®®¯®®®®®¯°žh("Y¨®¯¯®®¯¯¯¯­¯®¯®®®®®¯®¯¯¯¯®®¯®®®¯®®®¯­¯®¯¯®®¯®®®®®¯¯¯®®¯®¯¯®®®®®¯¯¯®¯®¯¯¯¯¯¯¯¯®¯®¯¯¯®«|# —®®¯®®¯¯®¯®®®®®®¯¯¯¯®®¯¯®®®¯¯¯¯®®®®¯¯®¯®¯¯®®®¯¯®®¯¯®¯¯®®¯®®¯¯®®®¯®¯¯®¯®¯ªJ  '>cŽ­²¯¯®¯®®¯¯®®®®¯¯®®®¯¯¯¯®¯®¯®®¯®­®¯®¯®¯¯®®®¯®®¯®®¯¯®®¯¯¯¯®®®¯¯¯¯®®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®±“Y'Ѝ¯¯¯®®®®®®®®¯®¯¯¯¯¯¯¯¯­¯¯¯¯®®¯®¯¯®¯®®¯¯¯¯®¯®¯®¯®¯¯®¯¯¯¯®®®®¯®®¯¯®®®¯®®¯¯©s-B{pbZ\gv–§¯®®¯®¯­®¯®¯¯®®¯®®¯­¯®®¯®¯¯¯¯¯¯®®®®®®®¯¯®¯®¯¯¯®¯®®¯®®®®®®®®®®®¯®®®®¯­¯¯­¯¯¯¯¯¯¯¯¯®®®¯¯®°¦“LwŸ®¯®®®®®¯®¯®­¯®¯¯¯®¯®®®¯®¯¯®¯¯¯¯®¯®®®®¯®¯®®¯®®®®®¯¯®®®®®®¯®¯®¯®®¯®®®¯¯¯®¯—kR¡›‘•¨®±®¯®¯®®¯­¯¯®®¯®¯¯¯®¯®®¯®®¯®®¯¯¯®®®¯®®¯®¯®®®®¯®¯¯®¯¯¯¯®®®¯®¯¯®®®®¯®®¯®¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯­¬l' `“°¯®¯®¯®¯¯­¯®¯®¯®®®¯®®®¯®¯­®­¯®®®®¯®®¯¯¯¯¯®¯¯®¯®¯®¯¯¯¯¯¯®¯®¯¯®¯¯¯®¯¯¯¯®®¯§“6N§±¯±²²±±¯¯®­®¯¯¯®¯®­®¯¯¯¯®¯¯¯¯¯®¯¯®®®®®®¯®¯®®®®¯®¯®¯¯®®¯¯®®¯¯¯®¯¯¯¯®®¯¯¯¯¯®®®¯®®¯¯¯¯¯¯¯¯®¯¯®¯¯¯¯®¯hGˆ±¯®®®®®¯®®®¯¯¯®®®¯¯¯®¯®¯®¯¯¯¯®¯¯®¯¯¯®¯®®®®¯¯¯®¯¯®®¯®®¯®¯¯¯¯¯¯®®®¯®®®¯¯¯¯­¨b- I¤±¯®®®®¯®¯¯­¯¯®®®®®®¯®®®®¯®¯®®®¯¯®¯¯¯®¯®®¯®¯¯®¯®¯®¯®®¯®¯®¯¯¯¯®¯¯®®®¯­¯¯®­®¯®®®¯®¯¯¯¯¯¯¯¯®¯®®¯­¯¯®®§–?'}¯¯­¯¯¯®¯®®¯¯¯®­¯®®®®®¯®¯¯®¯®®¯¯¯¯¯®¯®¯¯¯¯®¯®¯®®¯¯®®®¯®¯¯®®®­®¯®¯¯®®®®¯®¯¯®’X E ²®®®®¯®®®¯¯®®¯®¯¯®¯®¯®¯®®¯¯¯®¯¯¯®¯¯¯®®®¯¯®®®¯®­¯¯®®¯®®¯¯¯®®®®¯¯¯¯®¯¯®¯®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯®¯®­®®¯®®¯±«h+m±¯¯®­¯®¯®¯¯¯­­¯®¯¯¯®¯¯¯¯¯°°¯¯¯®®¯®®®®®®®®®®¯®¯¯®¯®®®®¯®®®®¯¯®¯®®®®¯¯®­®®¯¯¨vHž²¯¯¯¯®®¯¯¯¯®®®¯¯¯®¯®¯®¯¯¯¯¯¯¯¯¯®®¯®®®¯®¯®¯®®®¯®®¯¯®¯®®¯®®¯¯®®¯¯®¯¯¯¯®®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®¯¯­™cY¥¬°®¯¯¯¯®®®­¯®¯®¯­¯®¯®®®ª¦¢£¨¯¯¯¯®®®®¯®¯®®¯¯¯®®¯¯®¯¯¯­®®¯­¯®¯®¯®®¯®¯¯®¯®®¯³‘MOœ±¯¯®®®®®®¯¯¯¯®¯®®®®®®¯®¯®¯®®®®¯¯¯¯­®¯®¯®¯®¯®®¯¯®¯®®®®¯¯®®®¯®¯®®®®®¯®¯®®®¯®®­®¯¯¯¯¯¯¯¯¯¯®®®¯¯¯­®¯¯¯®«†; K’¦°¯¯®¯¯¯¯­®¯¯¯®¯®®®¯±® ‡ris†£­¯®¯¯¯®®¯®¯¯¯®¯¯¯¯¯®¯¯¯®­®¯¯¯®¯®®¯®®®¯®¯®¯¯¯³£€/Wœ²¯®®¯­®®®¯®¯¯¯®®¯­®®¯®¯¯®¯®¯®¯¯®¯®®¯®®®®®¯¯¯®¯®®®®¯®¯®¯¯¯®¯®®¯®¯¯®®¯¯®¯¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯®®¯¯®­¯®¯®¯°p(8rž±¯¯®®®­®®®®¯¯¯¯¯®¯¯§—yXC8;Jh‘®°®®®¯¯®¯¯¯®®­®®¯¯¯®­¯®¯¯­®¯¯®®¯®®®®¯¯®¯®®®°«ŸI !bž±¯®®¯¯®®®®¯¯®¯¯¯¯®®¯¯®¯¯¯¯®®¯¯¯¯®®¯¯®®®¯®¯®®¯®¯®®¯®®¯¯®®¯¯®®¯¯¯¯¯®­®¯¯¯¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®¯¯¯®¯®®¬¢OL•±¯¯¯®®­­¯¯¯®¯®¯®®¯³T_š®°¯®¯¯¯¯®¯¯®¯®®®¯®¯®®¯¯¯¯®¯¯¯¯¯®®¯¯®®®®¯®®¯¯¯n. 'mŸ±¯®®¯®¯¯­®®¯¯¯®®¯¯®¯¯®¯®¯¯®®¯®®¯®®¯¯®¯¯®®®¯¯¯¯®¯¯¯¯®®¯®¯¯®®¯¯®¯¯®¯®¯®­¯¯®¯®­¯¯¯¯¯¯¯¯¯¯¯®®¯­®®­®®¯­¯®¯­K )Н®®¯®¯¯¯®®®®¯¯¯®¯¬˜^!3u¤²¯¯®¯®®®®®®®¯¯®®®®¯®¯¯®¯®¯¯®¯¯®®¯¯¯®¯¯®®¯¯°³‰P*{¥°¯¯®¯®®®®­®®¯¯¯®¯¯¯®®®®¯¯®¯¯¯¯®®®¯®®¯®®¯¯®®®¯®®¯¯®®®¯¯®®¯¯¯®®¯¯®®¯®¯¯®¯®®¯®­¯¯¯¯¯¯¯¯¯¯¯­®¯¯®¯¯­¯¯¯®®¯¯~!«®®®®¯®¯®¯®¯¯®­­±©w2Q•³¯®¯®®¯¯¯¯®®¯¯¯¯¯®¯®®¯®®¯®¯¯®®¯®¯®®¯®®¯¯¯®®¯¢/2ެ°¯®¯®®¯®¯¯¯®®¯¯®¯¯¯®¯¯¯®®®®®¯¯®®®®¯¯¯®®­®¯®®®¯¯®¯¯®®®¯¯®®®­®®¯®®¯®¯¯®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯¯®®®®¯®®®ŸKPœ«°¯¯®¯¯¯¯¯­®¯®®°›K  3…³®®¯¯¯®¯¯®¯®®¯¯¯®¯¯®­®¯¯­®¯®®¯¯®®®®®®¯®¯¯®®®®˜H:›±¯¯¯¯®¯¯®®¯®®®®®¯®¯®¯®­®¯¯®¯®®®¯®¯®¯®®¯®®¯¯®®¯®®®¯¯¯¯®®®®¯¯¯®¯¯¯¯¯¯®¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯®¯®®®¯®®¯®®°©yK-|§¯®¯¯®®®¯®®¯¯¯°©ˆ3#x´®¯¯®¯¯®®¯¯®®®¯®¯®¯®®¯®¯®®®¯®¯®®®¯®¯¯¯®¯®®¯®±¦`T£²¯®®®­®®®®¯¯¯¯®¯¯®®®®¯®®¯®®®®¯¯®®¯®¯®®®®¯¯¯¯¯®®®¯¯®¯®®¯¯®¯¯®®®®¯¯®¯¯®®¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®¯¯¯®¯®¦|V¤¯®¯®¯¯¯¯®¯®®¯±œbr´®¯¯¯®¯¯¯¯®®¯®®®®®¯®®®®¯¯®®®®®¯¯®®®®¯¯¯®¯¯®­±­z3/r§±®¯¯¯®®®¯®®¯¯¯¯¯¯¯¯¯®®¯®­®¯®®¯¯®®¯®¯®®®¯¯®¯¯¯¯®¯¯¯®®¯®¯®¯¯®¯®¯®¯®¯®®®¯¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®®¯¯¯­®¯®­–^0œ­®¯¯®®¯®®®¯®°³”E#q´®®®®®®¯¯®¯®®¯®®­¯¯®®®¯®®®®¯¯¯®®®®¯®¯®­¯¯®¯®±®ŠM K›®¯¯¯¯®¯®®®¯¯®®®¯®¯®¯®®¯¯®¯¯®®¯®¯®¯®®®®¯®¯®®®®¯®¯¯®¯®®¯¯®®¯¯¯¯®¯®®®¯®®¯¯®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯®®¯®®®®®¯¯­¯¦ŽC †¥®¯¯¯®¯®®®®¯¯³’58}´®¯¯®®¯¯®®®¯®®®¯¯¯®¯®®¯®¯®®®¯®¯®®¯¯¯®¯®¯®®¯®¯®›k0s¬¯®®®®¯¯¯¯®®¯®¯®®®®¯®®¯®®¯®¯®®®®­®¯®¯®®®¯®¯®¯®¯®¯®®¯­®¯®¯®®®®¯®®¯¯®®®®¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯®¯®®®¯¯®®¯¯®°«l:\¯®®¯®­¯®¯¯¯°²•1[‘²¯®¯¯®¯¯¯¯®¯¯®®¯¯¯¯¯®®¯¯¯®®¯¯¯¯®¯¯¯¯¯¯¯®®®¯®®®¤‚]’¯¯¯¯®¯¯®¯¯®®¯®¯¯¯¯®®®®¯®®®¯®¯­¯¯­®¯¯®¯®¯¯¯¯®¯¯¯®¯¯¯¯®®®¯®¯¯¯¯®®®®®®¯¯¯®®®¯®­®®¯¯¯¯¯¯¯¯®®®®¯®®®¯¯®¯®¯®¯­®¯¯®®¯­š{.z­®®®¯®®®¯¯¯°²š: 8ƒ§°®¯®®®¯¯®¯¯®¯¯­¯®¯®®­¯¯®®¯¯®®¯®®®®®¯®¯¯¯®®¯®®¯¨&FЍ¯¯¯¯®¯®¯®®¯®®®¯®®®®¯®®®¯¯®¯¯®¯®¯¯®¯¯¯®¯®¯¯®¯®®®¯¯®¯¯¯¯®¯¯®¯¯®¯¯®®¯¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯¯®¯®®®¯¯®¯®®¯¯¯®­œN [©®¯­®®¯®®®®®± L9t¤±®®®®®®®¯®¯¯¯®®®®¯¯®®®®®¯®®¯¯®¯­®¯®¯®¯®¯®®¯®®®¯­ž:A€¥°¯¯¯¯®¯®¯¯®¯¯¯®¯®¯®¯­®®¯¯®®®®¯¯®®¯®®®¯®¯­®¯®¯¯®¯¯¯¯®®­¯®¯®¯®¯®¯¯¯¯®¯®®¯®­¯®®®®¯¯¯¯¯¯¯¯¯®¯¯®®®¯¯¯¯®®®¯®®®¯¯®®¯®¯¯©ˆQ/ލ¯¯®®¯¯®¯¯¯°§o5Cy¦­®®¯®®­®®¯­®®¯¯®¯¯®¯¯®®®¯®®¯¯®¯®¯¯®¯¯®¯®¯®®®¯®¯®­©U'#V„¢­°®®¯¯¯¯®®¯­¯®®®®¯®¯®¯®®®¯¯®®®®®¯¯¯¯®®¯¯¯¯®®¯®¯¯¯¯®®®®®­¯­®¯®®¯¯®®®®®¯®®¯®¯®®­¯®¯¯¯¯¯¯¯¯®®¯®¯¯®®­®®®®®®®®®®®­¯®¯¯­©0b¡°®®¯¯®¯®¯¯°«ŠS c›±°®¯®¯¯®®¯¯¯¯¯®¯®¯®®®¯­®®®¯®¯¯®®¯¯®®®®¯¯¯¯¯®®®¯¯¯®¯}aa‘ª±¯¯¯¯¯¯®®®¯®®®®®®¯¯¯¯®®®®¯®­¯¯®¯¯®¯¯®¯­®®®¯®¯®®¯¯®¯¯¯¯®¯­¯­®®¯¯¯®¯¯®®¯¯¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®¯®®¯¯¯®®¯¯®®¯®®®®®¯²ši#•®®¯¯®®®®¯¯¯®§€& wª°°°°°¯®¯¯®­®¯®¯®¯®®®®®­®¯®¯¯®¯¯­¯®¯®®®¯®®¯®®¯®¯¯¯¯¯¦¤¤«­¯¯¯¯¯®¯¯®¯®¯­®¯®®¯®®¯¯®¯¯¯¯®®¯¯®¯®®¯¯®®¯­¯®®®®¯®®®®¯­®¯®¯®®­¯®®®¯¯¯®®®®¯¯®®¯¯®®®¯¯¯¯¯¯¯¯®¯¯®¯¯®¯®®¯¯¯®¯¯®¯¯¯¯¯¯¯®¯®®ª˜-y ®¯¯®®®®®¯¯¯°œa*V®²³±±¯¯¯®¯¯®®°°¯°°°®¯®¯®¯®®¯¯®¯­®®¯­¯¯®®®¯®®¯®®¯¯¯¯°²²±®¯®¯¯®¯¯­¯¯¯®®¯®®¯¯®®®¯¯®¯¯®®­¯¯®¯¯¯®®­®®®®®¯®¯¯¯¯¯¯¯­®¯­®®¯¯®­®¯®¯¯®¯¯¯®®¯®¯®­®®®¯¯¯¯¯¯®®®®®®¯®¯®¯®®®®®®¯¯®®¯®®¯®®®¯®¥FRƒ¬¯¯¯®¯¯®®¯¯¯­¢\!,W|ˆŽ”šŸ¦ª°³³³¯°¯­­­­­¯®¯®¯®¯¯®®¯®¯®¯®®¯®®¯¯®®¯¯®¯¯®¯¯®¯¯­¯­¯®®¯®¯®¯®®¯¯¯®®®¯¯¯¯®­®®®¯®¯¯®®®¯®¯¯®¯®®¯®®®¯®®¯®®¯¯®®®®¯®®¯¯®¯¯¯¯®¯¯®®¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯¯®­®¯®®¯®¯®®®­¯®®®¯¯¯ªZ%X§°¯¯¯®­®¯®¯¯°­—p* ":L[hs}ƒˆ‹‹‰ˆ‰–›¡©°µ¸·¶´³°°¯¯®®°¯¯¯¯®®®®¯®¯¯®®¯¯®¯®¯¯­¯®¯®¯®¯®®®®®¯¯¯¯®®¯®¯®¯®®¯®¯¯®®¯®¯®¯¯®¯®®®¯®¯®¯¯¯¯¯¯¯®¯¯®®¯®¯¯¯¯­®®®®¯®®¯¯®­­®¯¯¯¯¯¯¯¯®®®®®¯®®¯¯¯¯­®®®®®®®®®®®®¯®¯¯®¯©b.4—¦¯®®®¯®¯¯¯¯¯¯­œkA  "+5CP\gox‡ŠŒ”—›¡§­±²²²²°¯®®®¯¯®®¯¯¯¯®¯®¯¯®®¯¯®®¯®­®¯®¯¯®¯¯¯¯¯¯¯®®¯®¯®¯®¯®¯¯¯®¯®­¯¯¯®®¯¯®¯®¯®®­®®®®¯¯®®¯®®®®®®®¯¯®®®®®¯¯¯¯®¯¯¯¯¯¯¯®¯®¯¯®®®®¯®®®¯¯¯®¯®®®¯®¯®¯¯®®°ªX$k“°®¯­®¯®¯¯®®¯¯®¬ˆT! !#$&&&'/az‹ž¬²±¯®¯¯®®¯®¯¯®¯®®®®¯¯®®®¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯®®®¯¯®¯®¯®¯¯®¯®®¯¯yBX‘¯¯¯¯¯¯¯¯¯¯®®¯¯®¯¯®®¯¯¯¯¯¯®¯®®¯¯¯®®¯¯®¯®¯¯®¯¯®®®®®¯¯¯®¯®¯®¯®®®®¯®°±²²³°­¨¤Ÿžœ˜“†uaM;- ?p”£ª¯¯¯®¯®®®®®®®¯¯®®¯¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®¯®®¯¯¯®¯®¯¯¯Žd $l¦¯¯¯¯¯¯¯¯¯¯®®®®®®¯®¯®®¯¯¯®¯¯¯®®®¯¯®®¯®¯®®®®¯®®®­®¯¯®®®®®®¯®®­­¯®¯¯®®®¯¯®°°°±°®«£š’‹ˆ„~zseTE7) )BdŽ©¯°®®¯®¯®®¯®®¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯¯®®®®¯¯®®¯¯®¯¯®¯®­¯®¯®®¯®®¯¡ƒBœ¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯¯®¯¯¯®¯¯®®®®¯¯®¯®¯®­¯¯¯¯¯®­®®¯®®¯®®¯¯®®¯¯®®¯¯®®¯¯®­®®®¯¯°±²³µµ²­§Ÿ”‰‚|wtpg[N?0  !In’«´¯¯¯¯®®®®¯¯®¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®¯®®®®¯¯¯­¯¯®®¯¯¯¬•  ¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯®®®®¯®¯®¯¯¯®¯¯¯®­®¯¯®¯¯®®¯®®®®®¯®­®®®®®¯¯¯®¯®®¯¯¯¯®®¯¯¯¯®®¯¯¯¯¯®®­­­­®°²±®ª¡—Œ‚{tpj`P<" \‹§®±¯¯¯¯¯¯¯¯®®®¯¯®®®¯¯¯¯¯¯¯¯¯®¯¯®¯¯®®¯®¯®®®®¯¯¯¯¯®®¯¯®§W°¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯­­®®¯¯¯®¯¯¯¯®®¯¯®®¯®®¯®®¯¯®®®¯¯®®¯¯¯®®®®®¯¯¯¯¯¯®®¯®®¯¯¯®¯®®®¯®¯°¯°°¯®¯®®®¯°±²²±­¥™‡ubRE6 F{ª²®¯®®®¯¯¯¯®®®¯¯¯®¯¯¯¯¯¯¯¯¯®¯®®®®¯®®®®®®¯®®®®¯¯¯®®¯¯—t*v¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®­®®¯®¯®®®®¯­­¯¯®¯¯®¯®®¯¯®¯®®®®®®¯¯¯®¯®¯¯®®¯®®¯®¯¯®®®¯¯¯®®®¯¯®®®®®®¯¯®®®®¯¯°°±°°®­¬©¨§£•xO)Cˆ§±®¯¯®¯®®¯®­®®¯¯®¯¯¯¯¯¯¯¯¯®¯¯®®®®¯¯¯¯¯¯®®®¯®®®¯¯®¯®q5]¦¬¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯®¯®¯®®¯¯®®¯®®¯®­¯¯¯¯¯¯®¯®®¯®®¯®®®®¯®®¯¯¯¯¯®®¯®®¯¯®¯¯®®¯®®®®¯®®¯¯¯¯¯®¯­®¯­¯¯¯¯®¯°°±°­¦‘€Y)Nˆ°®¯®¯®¯®®¯¯®®®®¯¯¯¯¯¯¯¯¯¯­®¯®¯®¯­¯®®¯­¯¯¯®¯®®®¯°¤‰G3•§°¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®¯®¯¯®®¯®®®®®®¯®¯¯¯¯®®¯®¯¯®®¯¯¯¯®®®®®¯¯®¯®¯­®®®¯¯¯®¯®®¯®¯¯¯¯¯¯®®®¯¯¯¯¯®®®®­¯®®®¯¯®¯¯¯¯²¯”f"aª¬¯®¯¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯¯®®¯®®®¯®®­¯®®¯¯°­£†Po °®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯­®¯®®®¯®®¯®¯¯®®¯®¯®®¯¯¯¯®¯®®®®®®®®¯¯­®®®¯®®®¯®¯¯®¯¯®®¯¯¯¯¯®®®®®®¯¯¯®¯®®®®®®®®¯­¯®¯¯®¯¯¯¯¯®¯œ@ C˜¦°®¯¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®®¯®¯¯®¯¯¯®®®¯­¥m8 F—°¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®®®®®®®¯¯®¯®®®¯®®¯®¯¯®®®¯¯®®¯®®®®®¯¯¯®¯¯¯®®®®®¯®®¯¯®®¯¯¯®®¯¯¯®¯¯¯¯¯®®®¯¯¯®®¯®®®¯¯¯®®¯¯­—;.y™±¯¯®¯®¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯®®®­¯¯¯¯®¯¯®¯®¯®¯¯¬¨‰f4‰¬¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­®®®®®®®¯¯®¯¯®®®¯¯¯®¯®­¯­¯­®¯¯®¯®®®¯®¯®¯®¯¯¯¯¯­¯®®®¯¯®®¯®¯¯®®¯¯®®®¯®¯®®®®¯¯®®®®®®¯®¯®¬™t(Y‹¯¯¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­®¯¯¯®®¯¯®¯®¯¯®® ŽSs ­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®®®®®¯¯¯®®®¯®¯¯®®®®®¯®®¯®¯®®®®®¯®¯®®¯¯¯¯¯®¯®®®®¯®¯®®®®®®¯¯®®¯®®¯®®®®®¯¯®¯®®¯®®¯®®¯°¬†U! C®®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯®¯¯®®®®®®®­¦|+XŒ«°®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®®®®®¯¯¯®­­®®®­®¯¯­®®¯¯®¯®¯¯¯¯®®¯¯®¯¯®®¯¯®®®¯¯®¯¯®¯®®®¯®¯®¯¯¯¯®®¯¯®®®¯®®¯­®®¯©“Z$1t¬¯­¯¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯¯®®®®®¯¯¯®ª`E) ;q©°®®¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®®¯®¯®®¯¯®¯®®®®®®¯®®®¯®¯®¯¯®¯¯®¯¯¯®®®¯®¯®¯®¯®¯¯¯¯¯®®®®®®¯®¯¯®®¯®¯¯¯®®¯®¯®®´›X +p«±¯®®¯¯­®¯®¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®¯®¯®¯®®®®­©£ˆg8V¥°®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯­¯­®®¯¯¯¯¯®®®®¯¯®®®®¯¯¯®®¯®¯®®®¯®®®®¯¯®®¯®¯¯®¯®®®¯®®®¯®®­®¯¯®¯¯®­®¯®®®¬‚' +m¨±®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯®®­¯®®¯¯¯®¯®¯®®¯¯®¯®­ª£‘a ;›¬¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯­¯¯¯¯¯¯¯¯®®¯¯¯¯®®¯®®®¯®¯¯¯®®®®¯®®¯¯®¯¯®®®¯®®®®®®¯¯¯®®¯®¯¯­®®¯­®¯®¯¯¥s 8t©±®®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®¯¯®¯¯­®¯¯¯°¯©‚/ #Œ§®®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®®¯¯®®®¯¯¯¯¯®®¯®®®®¯¯®®¯­¯®¯®¯¯¯®¯®®¯¯®®®®®®®¯®¯¯­®°°žiF~©²¯¯®­®®®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®®®¯¯¯¯®¯­®®®¯±“Onž°®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯®¯¯¯¯®¯®®®®®­®¯¯®¯®®®¯¯¯®®®®¯¯®¯¯®¯¯®¯®®®®¯¯± mb𫝝®¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®¯­®°—`N“°¯¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®¯®®¯¯¯¯®¯®®®®®¯¯®®¯¯®¯®¯¯®¯¯¯¯®¯®¯¯¯¯¯°°«„)2©­®¯®­®¯¯¯®®¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®®®¯®¯¯®¯®¯¯®¯®®±™b)ˆ°­®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯®¯¯®®®¯¯¯¯®®¯¯®¯®®¯®®¯¯¯¯­­¯¯®®¯¯®®¯¯®¯¯±˜G_˜°¯¯®®¯®¯¯®¯®¯­¯¯¯¯¯¯¯¯¯®®®®®¯®¯®®®¯®¯®¯®¯¯¯®®®°—[{¬®¯®¯®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®®¯®®¯®®¯¯®¯®¯®­¯¯®¯¯®®¯®®¯¯®­¯¯¯¯¯³¦j* 0f•ª°¯®¯­®¯¯¯¯¯®¯¯¯¯¯¯®®®®¯¯®¯¯®®¯®®¯¯¯¯¯¯®®¯¯®®¯®±‘Bk¢«¯­¯®¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®®¯®®¯¯®®¯¯®®¯®¯¯¯®¯®®®®®®¯¯®¯®¯¯¯®®¯®®°®£w/  Arœ®°¯­®¯®®®¯¯®®¯®¯®®®®¯¯®®¯¯®¯®¯®¯­¯¯®¯¯¯¯¯¯¯®°°®©˜l!\”¨°®®®®¯®®¯­®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­­®®®¯®®®¯­­¯¯®¯¯¯®¯¯¯¯¯®¯®®®¯®¯®®®¯®®¯¯®®®®¯­šv_SVawŸ¬¯¯®¯®¯®®®¯¯®¯¯®¯¯®¯®¯®¯­®®¯®¯¯®¯®¯®®¯®¯®¯¯®¯«¦›h8I}¥±¯®¯®®¯®®¯®®­¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®­¯®­®®¯¯®¯®®®¯®¯¯¯¯®¯¯¯®®®¯¯®¯®¯¯®®®®¯¯¯®°°¤˜˜Ÿ«²²°¯®¯®¯¯¯®¯®®¯¯¯¯¯®¯®®®­®­¯®®¯¯®¯¯¯®¯®¯®®¯®®®®•hC7f ±¯®®¯®¯®¯¯¯®¯¯¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯¯®®¯®­®®®¯¯¯®¯®®¯¯®®®¯¯¯®¯®®®¯®®¯®¯®¯¯°®®­®¯°®®®®¯®®¯¯¯¯®¯¯¯®®¯¯¯®¯¯¯®®¯®®¯®¯®®¯®¯®¯¯®¯®¯¬•i-Mœ²¯®®¯®®¯®®¯®¯¯¯­¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®®®¯®¯¯¯®¯¯¯­¯¯¯¯¯®®¯®¯¯®®®¯¯®­®¯®®®®¯°°°°®®¯¯®®®®®¯¯¯¯¯®®¯¯®®®®¯¯¯¯¯­®¯®®®¯¯®¯¯®¯¯¯®¯¯®©t5 :—±¯®®¯¯­®®®¯¯®¯¯¯­¯¯¯®¯¯­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®­¯¯®¯¯¯®®®¯®®®¯®®­¯®®®¯®¯¯¯®®¯®¯¯®¯®®®®®¯¯­¯®®®®¯®¯¯¯¯­­¯®®®®®­®¯­¯®®¯®¯¯¯®®¯¯®®¯¯®®¯®®°¨j++’®®®¯®¯¯®­®¯¯®¯¯¯®¯®®®¯®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®­®¯®¯¯¯¯¯®¯¯®¯®¯¯®®¯¯¯¯¯¯®®¯¯¯®¯­®¯®¯®®¯¯®¯®®®¯¯®®¯®¯®¯®®¯¯¯®®®¯¯®®¯¯®®®®®¯¯¯¯®®®®¯¯©v8‹«®®¯¯®¯®¯¯­¯¯¯¯®®¯®¯®®¯®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®¯­®¯®®¯¯®®¯¯®¯®¯­®¯¯®¯¯®¯®®¯­®¯®¯¯¯¯®®®¯®¯¯®¯¯¯®®¯®¯­¯®®®¯¯®®®¯®®®¯¯®¯¯­®®®¯¯®¯®®®¯«ŒQ¦®¯®®¯¯®¯®¯®¯®®®®®¯¯®®¯¯¯¯®¯¯­¯®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯®®­¯®®®¯®®¯¯®®¯®¯®®¯¯¯¯¯®®®¯®¯®®¯®¯®¯®®®®®®®®¯¯¯®¯®®¯®¯¯¯®¯®¯¯®®®®®¯­¯®®¯®®®®®®¯®¯¯¯®¦n_ ®¯¯®®¯¯®®¯®®®¯¯®®¯®®®®®¯¯®¯®¯®®®®®®®¯®¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®®®¯®®®¯®¯®¯¯®®¯¯®®¯¯®®¯¯¯¯­®¯¯¯®®®¯®®¯¯¯¯¯¯®®­®¯®¯®®®¯¯¯®¯¯®®¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯®®}U™­¯®®®¯®¯®®­¯¯®®®¯¯®­¯®¯¯®¯®®®®¯®®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯¯®®¯¯®¯®¯®­¯¯®­¯¯®­¯®®®¯®¯­®®®¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®¯¯­¯®®¯¯®®®®®¯¯¯®¯®¯®®®®¯®®¯²‰/ J­¯¯¯¯®®®®¯®¯¯®¯®®®®¯¯¯®¯®®®¯¯®¯­®®¯¯¯¯¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®®¯®¯¯®®¯®¯®®®­¯®¯¯¯®®¯®¯®¯¯¯¯¯¯¯¯®®®¯®®¯®®®¯®¯¯¯®¯®¯®­¯¯®¯®¯®¯®¯®¯®¯®¯­®®²ECˆ¬¯®¯®®®®®®®®®¯¯®¯¯¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯®®®®®¯¯­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯¯¯®®®¯®¯®®¯®¯¯¯®¯¯®¯¯­®¯¯¯¯®¯­¯­®®®¯®¯®¯¯®¯®®®¯®¯¯¯®®®¯­¯¯®¯¯¯¯®®¯®®¯¯²‘P#=¬®¯¯¯®®®­®®¯¯¯­®¯¯®¯¯®®¯®®¯®®¯®¯¯®¯¯®®®¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯®­®®¯¯¯®­®¯®¯¯¯¯­®®¯¯¯¯®¯®®¯¯¯®¯¯®¯®¯®¯®®¯¯¯¯¯®®¯®­®®­®¯®®®¯®®®¯®®®¯¯²‘N"6z«°¯¯®¯­®¯¯®®¯®¯¯®¯®®®®¯®¯®®¯¯¯®®¯¯¯¯®®¯®­¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®¯¯¯¯¯®¯¯¯¯¯®¯®¯¯¯®®¯¯¯®¯®¯®®¯¯®¯¯®®®¯®®¯®®®¯®¯®®¯®®¯®®¯®¯¯®®¯¯¯¯®¯³‰3 1t«¯®¯¯¯¯¯¯®®¯®®¯®®®¯®¯®¯¯¯®®¯®¯¯®¯®®¯¯®¯®®®¯¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯­¯®®®®¯¯¯®®¯®¯¯®¯¯¯¯¯­¯®®®®¯®¯®¯®¯­¯¯®®¯¯­¯­®®¯®¯¯¯®¨x,o«®®®®®¯®¯®®®®®¯¯®®®®¯¯¯®®®¯®¯¯®®¯¯®¯¯¯¯¯®¯®¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯®®¯®­®®¯­¯¯¯®®®®¯®¯®®¯®®®¯®®®®®¯¯®®®¯¯¯®®®¯®¯®­®¬’W)kª¯®¯®¯®®®®®®¯®®®®®®®¯®¯¯¯®¯¯¯®¯¯¯®®®®®®®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯®¯¯®¯®¯¯®®¯®­®¯®®®®¯®®¯®¯¯®®¯¯®¯­¯®¯¯®¯®®­®®­®®®­£\ (iª¯®®¯®¯®®®®¯®®®¯®¯¯¯®®®¯­®¯¯¯¯¯¯¯®¯­®¯®¯®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯®¯®¯¯¯®®®®®¯¯¯­®¯®¯¯¯¯®®¯¯®¯®¯­¯®¯¯®¯®¯®®¯¯¯®¯°Ÿ/(i«®®®®®¯®¯®®®®®®¯®­¯¯¯¯®¯®®®¯®®®®¯¯®¯®®®¯®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®­¯­®¯®®®®®®®¯¯®®®¯¯¯­¯®®¯¯¯¯¯®®¯®®¯®®®®®®¯®¯®®¯®¯¬7'iª°®¯¯®®®®¯®¯®¯­®®¯®®¯¯®®®¯®®¯®®®¯¯®®¯¯®®®®¯®®¯¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®®¯®®¯¯®®¯¯®®¯¯®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯®®°¯¡t> (i«¯®¯¯®¯®¯¯®¯®¯®¯¯®®¯¯®¯¯®®¯¯®¯¯®®®¯¯¯¯®¯®®¯®®®¯®¯¯¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯¯¯¯®®¯¯®¯¯¯®¯¯°¯°¯¯®­­¬¬­®®¯¯°°°°¯°°¯®¯°°¯®«¤–x;(iª°¯¯®®®¯®®¯¯¯®®®¯¯®¯®¯®¯®®®®¯®®®®¯®®¯®®¯­¯®®®®®¯®®®¯¯®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯®®¯®®¯®­¯®¯¯¯­­­«©¥¡ ¡¡¥¦§ªª¬¬­¬­­­­®­­­ª¦™„U+n«°®¯¯®®®®®®¯®®®¯¯®®®¯¯¯¯¯®®®¯®¯­®¯®®®¯®­®®®¯¯®®®¯¯¯®®®¯¯¯¯®¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®®¯®¯¯®¯®®¯®®¯®¨Ž{`UKFCA@BEGHMOTX[cehnprof\PF;).r«¯¯¯¯®®®®¯­®®®¯®¯¯®®¯®¯®®­®¯­®®®¯®¯®®¯¯®¯®¯¯­®¯¯®¯¯¯¯®­®®®®¯¯®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯®®¯¯®¯®¯®®®®¯®©˜€W@$  $)*2653, 7{«°®­®®®¯®¯®®®¯®¯®¯¯¯®®®®®®¯¯¯®®¯®®®®®®®¯®®®®®®®®®¯¯®­®¯®®®®®®¯¯®¯­®¯®®¯®¯®¯¯¯®¯®®¯¯®¯¯¯®¯®¯®®¯¯®®¯¯®¯®®®®®®®¯®¯®®®¯ª•b"J­¯¯®®¯¯®¯¯®¯¯®¯­¯¯¯¯®¯®®®¯¯®¯¯®®®¯¯¯¯­®®®¯®®¯®¯¯®¯®®®¯­®¯®®®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®¯®®®®¯¯®®®¯®®¯®¯¯¯¯¯¯®¯®¯¯¯®®¯®¯¯®®¥Ecž­®®¯®®®®®®®¯¯¯¯®¯­®¯¯®®®¯¯¯¯¯®¯®¯®¯®¯¯®®¯¯­¯®®®¯¯®®®®¯®¯¯¯¯®®®®¯¯¯¯®®®¯®¯¯®®¯¯®¯®¯¯¯¯®®¯¯®®®¯®¯¯¯¯¯®¯®®®®¯®®®¯®®®©Š`Š©®¯®¯®®®®¯¯®®®¯®®®¯¯®®¯®®®­®®®®®®­®®®¯®®®¯®®¯®¯¯¯®®®®¯¯¯®®®¯®®®¯®®¯®®®¯¯¯¯¯®¯®®¯®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®®®®¯¯¯¯®®¯®¯®¯«šO)’¯®¯¯­®®¯¯®¯¯®¯¯®¯®®­¯®®®®­¯¯®¯®¯¯¯®®®¯¯¯­¯­®¯®®®¯¯¯¯®¯®®¯®¯®®¯¯¯®®®¯¯¯¯®¯®®®®®¯¯¯¯¯®¯®¯®¯­®­¯¯¯®¯®®®¯¯¯®¯¯®­®®®®¯š^$ :•¯®¯°¯®¯®®¯¯®®®®¯¯®®®®¯¯®®¯®¯®®¯®®®®¯®®®®®¯®¯¯®®®¯¯¯®®¯¯®®¯¯®®¯¯®¯¯­®®®¯¯®®®®­®®®¯¯¯®¯¯¯®®¯¯®®­¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®¬¥ƒ+ >§©¬®¯®¯®¯®®®¯­¯®®®®¯®®¯®¯­¯®¯®¯¯¯¯®®¯®®®®®¯­¯®®¯®¯®¯¯®®®®®¯¯®®¯¯®®®®¯¯¯®¯¯®®¯®¯®¯®¯¯®¯®¯¯®®¯¯®®®¯®¯®¯®®®¯®®®®¯°©‰] (CTgxŽœª°°°°¯¯®¯¯¯®¯®®¯®¯¯®¯¯®¯®¯®®®®®¯¯¯®®®¯¯®®¯®®¯®¯®¯¯¯®®¯¯¯¯®¯¯¯¯¯¯­¯®®®®®¯®¯¯®¯¯®®®®®¯®®®¯¯®¯¯¯®¯®¯®®®®¯¯¯±£]1$=Wi–¤«®¯¯®¯¯¯¯®¯®¯¯¬««­®°¯¯­¯¯®®®¯¯®®®¯­¯¯®®®¯®¯®¯®®¯®¯®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯¯¯®¯®®®¯®¯¯®®®®®®¯®®®¯¯¯®®­®®¯š:%@i€œ§­®®¯®¯®¯®®®¯¦£¢§«­®®¯®¯¯¯¯®®¯¯®®¯®­¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯®¯¯®®®®¯¯­¯¯¯¯®¯¯¯¯¯¯®­¯®¯®¯¯®¯®®¯®¯®¯§Œ$ "4Qm‰ž«¯°¯®®¯¯®«¢’|nr~–£¬±±¯¯¯¯®®¯®®¯¯®®®®¯¯®®®®®®¯­¯®¯¯¯¯¯¯®®®¯®®®¯®¯¯¯®¯®¯®®®®®¯®®¯¯¯®®®®®¯¯®¯®®®®”r *Rm‡• §­°¯¯¯®§•yc\\jz‹™¡ª­°®®®¯®¯®¯®¯®¯¯®®¯¯®®¯¯¯®®¯¯¯®¯¯®¯¯¯¯­¯®¯¯¯­¯¯¯¯¯®¯¯®®®¯¯®¯­¯¯¯®®¯¯®¯¯¯®~T>n¡­¯®¯®®®«¥‚Z$Pr𥝮®®®®®¯¯®®®®®¯®®¯®®¯­®®¯®®®¯®®¯®®®¯¯®­¯®®¯®¯®®¯®®­®¯®¯®­®®­¯®¯®¯¯®®®®¬b( ,Ll‘£°°¯¯¯­¡”xS.'=[Ÿ¬¯°¯®®®®®®®®®®¯¯®¯®¯®¯¯¯¯®®®¯¯®¯®¯¯¯¯®¯®¯®®¯¯®¯®¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯®¯¬£K'Z~•£ª®®¯°¯¨…Y(Hw£«°®¯®¯®®¯®¯¯®®¯®®­¯¯¯¯¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯®¯®®®®¯®®®¯¯®¯®®®¯®®¯®®°§’4 3z•¨®®¯®®­£}S>x­¯®®®®¯®®®®®¯¯¯®¯¯¯®®®­¯¯®®®®®¯®®¯¯®¯®®®®®¯®¯¯®®¯¯¯¯®¯®¯®®¯¯®®¯±œq">h¥­°®°­¢Žm= -S|¤¬¯¯®®®®¯®¯®¯®®®¯¯®¯¯®®¯¯¯®­¯­®®¯­¯®®¯®¯®¯¯®¯®®¯¯®¯®®¯¯®¯¯¯¯¯®°J '^‰Ÿ©®¯¯±ªŸn.Lˆœª­¯®¯®®®¯¯®®¯®®¯¯®¯®¯¯¯®®®¯®®®¯¯®­¯¯¯®¯¯®®¯®¯®¯®®®¯®®¯¯®®¯¯¯­„-a‰«®¯¯®¬¢†@$^”§±­¯®®®¯¯¯®®®®®®®¯®®®¯¯®®¯®¯¯®¯¯®¯¯¯¯¯®¯¯¯®®®¯®¯¯®¯¯®¯®®®®®¤r;s”¬®°°­¤„V&L}®°®®®®®®¯¯¯®®¯¯®¯¯®®®¯®¯®®¯¯®¯®®¯¯¯®¯®­®¯®®¯¯¯®¯®®¯®®®¯®¬‹U'g—©­®¯®­ŒP!Ey «¯¯¯¯®®®¯®®¯®¯®¯®®­¯¯®®®¯®®¯¯®¯®¯®®®¯¯®®®¯®¯®¯¯¯¯¯¯¯¯®¯ªo7 <Œ£®°®®©›\& +f–°°®®¯®¯¯¯¯¯®¯®®®­®®¯®¯¯®¯¯¯®¯®®¯¯¯¯®¯¯®®®¯®¯®®¯®¯­®¯¯¯¨P @mš§°¯¯¬e(&b‹¨¯¯¯®®¯®®®®®­®¯®®¯¯®¯¯®®¯¯­®¯®®¯¯®®®¯¯¯¯®®¯®®®¯®®®¯®¬¡9 (o“«®®®¯–\0#S”¨®¯¯¯®®¯®®¯®®­®®¯¯®¯¯®¯®­®®®¯®®®¯®¯®®¯®¯¯¯®®¯¯®®¯¯¯¦’( Q©¯­¯ª¢o/ Pzª°®®¯®­¯®®¯®®¯¯­®¯®®¯¯®®­¯­¯¯®®®¯®¯®¯¯­¯®¯®®¯®®¯¯¯œzO‹¢¯¯¯¯—v9 D¡®®¯®¯®®¯¯®®­®¯¯¯¯®¯®®®¯®¯¯¯®®¯®®­¯®¯¯®®¯¯®¯®®®°®Œ^Vˆ©®®¯®¦j-Cƒ£®¯®¯¯¯­®®®®®¯®®®¯®®¯¯¯¯¯®¯®¯¯¯­®¯®¯®­®®®¯¯®¯®¯°~? @‹¦¯¯®­ x" Eq¥°¯®­®¯¯®®®®¯®¯®¯¯®®­¯¯®¯¯®®¯®®¯®®®¯¯®®®®¯¯­¯¯¯oG…¤®¯¯®™k/5}𝝭¯®®¯¯¯®¯®¯¯®¯¯®®®®¯®¯®®¯®®®¯¯®¯¯¯¯¯¯®­®®¬¥`UЍ®¯®¬¡_Bu¨­¯®¯®®¯¯®¯¯¯¯¯®¯®®®¯­®¯¯®¯®¯¯¯¯¯®®®®¯¯¯®®°¦•MF–¦¯¯¯­”q3¦±®®®®®¯¯¯¯¯¯®¯¯¯¯®®®¯®­®®¯®¯®®¯®®®®®®¯¯®°Ÿ};R„©­¯¯¨˜T* >„¡®¯¯¯¯¯®¯­®®¯¯¯¯®¯®¯®®®¯®¯­¯®®®¯¯¯¯¯¯¯®®²˜`*O–¦°¯®«‰_S§®­¯®®¯®¯®¯®®®¯¯®®¯®®¯¯¯®¯¯®¯¯®®¯®¯¯¯®®±ŽC>®¯¯®©ŽM :Œ¢¯¯®®®¯¯®®®®¯®¯®®¯®®®¯¯®®®®¯¯¯¯®®¯®¯®¯°ƒ& S«¯¯°¤‡BIw¤­¯®®®¯¯¯®¯¯®¯¯¯®®¯¯¯®®¯¯®¯¯¯®­®¯¯¯®­¦rY¬¯®®«r@ A‡¢­®¯®¯¯®­®¯®¯®®®®¯®®®¯®®¯¯®®®¯¯¯¯®¯¬˜_f—²¯¯¯¢‰- 2|°¯¯¯®®®¯¯®¯­®®®¯®¯¯­­¯®¯­¯®­¯®¯¯¯ª‚Fnž¬¯®®£m? o¤¬¯­®¯¯­«©£ŒpM% Js«°²±®¯¯¯¦œ‘ƒvdPA.:€’ž¨­¯®¯°¯±²­¡Žl_J<0*($#  3b§®¯®¯®¯®¯®«ªª©§¥¢–Žƒ}tnjh`]]]]]]]]]]\]]\]]]\]\]]]]]\]]]]]\\]\]]\\\\\]]][]]]]]\]\]\]]]\]]]]]]\]]]]^]]\]]\]]\]\]_P Qj…šª°³°°±°¯°°°±°«¨¥¢žšš˜––––––––––—––—•––––•––—––•—––•–––––—•––•—•–——––•––——–––––––––•––—–––––––––––•—––––––˜ƒ-Cy—ž£©­®¯¯¯®¯¯¯¯±¯°°°±±±±²±°±°±±°±°°±±°¯°°°±°±°°±°°±°²°±±°±±±°°°±±°±±°°±°°°±±°±±±°±±±±°±°±±±±°°°°±±±°°±°±±²!?`w¡®¯®¯®¯¯®®®¯®¯®¯®¯®®®®®¯¯®¯®¯®®¯¯¯®®®¯¯®¯¯¯®®®¯®®®®®®¯¯®­¯®®®®®®®¯¯®®®¯®¯¯®¯¯¯®®¯¯¯®®¯®¯¯®®¯®®¯®¯®¯®±› !Nbm|†Ž™Ÿ¥ª®°²´··¸·¸····¹¸¸¸¸¸¸¸¸·¸¹¸¸¸¸·¸¸¸¸¸¸¸·¸¸¸¸·¸¹¸¸¹¸¸¸¸¸¹¸¸¸¹·¸¹¸¸¸¸¸¸·¸¸·¸¸¸¸¸¸·¸¸¸·¸·¸¸¸¸¸º¥" #-6@ELPUXZ\^a``a`_aa`aa```a``_a`````aa_`_````````a``aa`a`_a``a```a```a`a````aa_````a````a`a`````bS openigtlink-3.0.0/Examples/Imager/img/igtlTestImage4.raw000066400000000000000000002000001501024245700231240ustar00rootroot00000000000000 "#%&*())))))*&$#"   !$,7CN[gq{‚‹’˜Ÿ¢£§¬­¬¬¬¬¬­­¨£¡ž˜Šwl^RE4)"  .G]qƒ“ž£¤¦¥§¨©©ª««¬¬­­®­®­­­­®®­­¬¬¬«ª©¨¨¦¥¤ Ž€hP6(?Ufp{ƒŽ•œ¤«¯²±±²°¯°°°°¯¯¯¯¯¯¯®¯¯®¯®®¯¯®°¯¯¯°¯°±²²°®©£™…wkZE(  (@So‚—ª®±±±±¯¯®¯®­¯®¯®®®¯®­¯®®¯®®®¯®®®®®¯¯®®®¯®®¯®¯¯®¯¯°°°°±²ªœ‡gG4 $@e†— ¤§©«­®®®¯­¯¯®¯¯®¯¯®¯®¯®®¯¯®¯®¯®¯®¯¯¯®¯®¯­¯¯®¯¯¯¯®¯®®¯®®¯¯®®­¬©¦£˜‚\1>Xk}Š˜¦­°±°°®®­¯®®®­®®¯¯¯¯¯¯¯®¯¯®®¯®­®®®¯¯®¯®®¯®®®®¯®¯¯®¯¯®¯®®®­®®¯¯®®¯°°­¤”kN0 &A\š­±±°¯¯®¯¯­®®®®®¯®®¯®®®®®¯¯¯¯®®®¯¯®®¯®¯®®¯®®®¯®¯¯®®¯®®¯¯®®®¯¯¯®¯®®¯¯®¯¯¯¯°±°ªpI% Cq‘ž¦©¬®¯¯®®¯­®®¯¯­¯®¯¯®¯­¯¯®¯®¯¯®®®¯®®¯¯¯®¯®¯®®®¯¯¯®¯­®¯¯®®®®¯¯¯¯¯®®¯®¯¯®®®¯¯¯¯¯¯­«§¢k;FcxŠ©¯°°¯®®¯®®®®¯¯¯®¯®¯¯®®®¯¯®®®­®®¯¯®¯®¯®®®­¯®®¯®®¯®®­®¯®®¯®¯®¯®®¯®®¯®®¯®¯¯®®¯¯®®®¯®¯°¯©™„mF$ "?aŠ£°°°®¯®¯¯®®®®¯¯¯¯®­¯­¯®®®®®®¯®­®¯¯®®¯¯®¯­¯¯®¯¯­®®®®®¯®¯®®¯¯¯¯®¯®®¯®®¯¯®¯®®®¯®®®®®®®®¯®¯®®±¯ª†b5 "Lƒ™¥ª¬­¯®®®¯®®¯¯¯¯¯¯®­®¯®¯¯¯¯®¯¯¯®¯®®¯®¯¯¯¯¯¯®®®®¯¯¯®¯®¯®¯¯®¯¯®¯®®¯¯®®¯®¯®­®®®®¯®¯¯¯¯¯¯¯¯¯®¯®¯¯®®©£˜h? C\z¥®²°°®®®®¯¯¯¯®®¯¯¯®®¯­®¯¯®®®®®¯®¯®¯¯®®¯¯¯®¯¯¯¯®¯¯®¯®®¯®®®®®¯¯¯¯¯¯¯¯®®®®¯¯®®®¯¯®¯¯¯®¯®¯®®®®¯®®®¯®°°­™…eF.Q‡¯±¯®¯®®¯¯®®¯®®¯®¯¯®®®®®®®®®®®¯®¯®¯®¯®®®®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯®¯¯¯¯¯¯®®¯®®®¯¯®®¯®­®®®¯®¯¯¯®®®®®¯±®£‹Q)g‰£ª¬¯¯­¯¯®®®¯¯®®®¯®¯®¯¯®¯®®¯¯¯¯¯®¯¯®®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯­¯¯®®®¯¯®¯®®¯®¯®®®®¯­®®¯®®¯¯¯¯­¯­®­ªŸ['Vw—¦°±°®­¯­¯®¯¯®®®¯®¯®®®®¯®®®®¯¯®®¯®¯®¯¯¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯®®®¯®®¯®®®¯¯®®¯®®¯¯¯¯­¯°°£‘kF!^®°¯®¯®¯¯®®¯®®¯®®®¯¯®®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®¯®®¯­¯¯®®®®®®®®¯¯¯¯¯¯­®°®§}BX{™¥®¯®¯¯®®®¯®¯®®¯¯­¯®¯¯®¯®¯®®®­®®¯¯¯®®®®®¯®¯­®¯¯¯¯¯¯®¯®®¯¯¯¯®®®®®­¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯¯¯®®¯¯¯®¯¯®¯®¯®®¬¡f@6[Ž¥°¯¯¯®¯¯®®¯®®®®®¯®¯¯®®®®®®®¯®®¯®¯¯¯®¯¯¯¯®­®®¯¯¯¯¯¯¯®¯®®¯¯¯®¯®®®®¯®¯­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­®¯¯®¯¯®®¯¯®®®¯¯®®®®®®®¯¯®®¯¯°­–zG&D†§­¯¯¯®®¯®®¯®®¯¯®®¯¯®®®®¯®®¯¯¯­®¯®¯¯¯¯¯­¯®®­¯¯¯¯¯¯¯¯¯¯®®®®®®®®¯®®¯®¯¯®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®¯¯¯®¯¯¯®¯®¯®®®®®¯¯¯¯¯¯¯­¯¯¯©œo*,\ަ­®¯¯®®®®®¯®¯¯¯®¯¯¯®®¯¯¯¯®¯®®®¯®¯¯¯­¯®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®®­¯­®®¯®®®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯­¯®®¯®®¯¯¯¯®®¯®¯¯®¯®®®®®®¯¯¯®ªŸƒK (l‘¬±¯¯®¯¯®¯®¯®®¯®¯¯­®¯®®¯¯¯®®¯®¯®¯®¯®¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯­®®¯®®®®¯¯®®®¯®®¯®¯®¯¯¯®¯®®¯­¯­®¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®®®¯¯®®¯¯¯®¯¯®®¯¯¯¯®¯®¯¯¯§…[%@|¢¯¯¯¯¯®®¯¯¯¯¯®®¯¯¯¯®®¯¯¯®®¯­®®¯®¯¯¯¯®¯¯¯®¯®¯¯¯¯¯¯¯¯¯®¯®¯¯®¯¯®®¯¯®¯¯®¯¯®®®¯¯¯®®¯¯®¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®­¯®®®¯®¯¯®¯¯®¯¯®¯¯¯®®®¯®®¯®¯›s6T¡«®®®¯®¯®¯®­¯®®¯¯¯¯¯¯®¯®®®¯¯®®®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯®®­®®¯®¯¯¯¯¯¯®®®®¯®­¯¯¯®¯®¯¯¯¯¯¯¯¯¯®®®®®¯¯¯¯®®®¯¯®¯¯®®®¯®¯®®®®®¯®¯®¯¯ªŸ~XOФ±¯®¯®®¯®®®¯¯®¯®¯¯­®¯®¯®®¯®®®¯®¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯®¯®¯¯®¯®®­®¯®®¯®®¯®¯¯®¯¯®¯®®¯®®¯®¯¯¯¯¯¯¯¯¯®¯¯®¯®®®¯¯¯®®¯¯¯¯®®¯®¯®¯¯®®®¯®¯¯°±¢U#Z‘«¯¯®¯®¯¯®¯®¯¯®¯®®®¯®¯®¯¯¯®¯®®®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®®®®¯¯®¯¯®¯®®¯®¯®­®®®®¯®¯®®¯¯¯®¯®®®¯­®®®®®¯®¯¯¯¯¯¯¯®¯®®®¯¯®®¯¯®®¯®¯¯®®¯®¯¯­¯®®®¯®®¯¯«i$!\‹¨®¯¯¯¯®®¯®¯®¯¯®¯¯®®¯®®®®®¯¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®®®®¯¯®®®¯¯®®¯¯®¯®¯®¯¯¯®¯®®¯®®®®®®¯®®®®®®®®¯¯¯¯¯¯¯®®­¯¯¯®®¯¯¯¯¯®®­¯¯®¯¯¯®®­®¯¯®¯¯®ª—}< TŽ¥±®¯­¯®®¯®®¯¯®®¯®¯¯®®®®¯¯¯¯¯¯®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯¯®¯¯®®¯®®¯®®¯¯¯®®®®®®¯±¯®¯®¯®¯®¯¯®®®­®®®®¯®®¯¯¯¯¯¯¯¯¯®®¯®®®­¯®®­¯¯¯®®­¯¯¯®¯¯¯®¯¯®¯¯­¦r> Y‰®¯®¯­®¯®®¯¯®¯¯®¯®®¯®®¯®®¯®®®¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®®¯®®¯¯®¯¯¯®®¯¯¯¯®¯¯¯®µ«®¯®¯¯®®¯®¯¯¯®¯¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®¯¯¯®­¯¯®¯¯®®¯®¯®¯®¯®®®¯¤Ž6?¤¯®¯­­¯¯®¯¯¯­¯®®®¯®­®¯¯¯®­¯¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯­¯®®®®®¯®¯¯®®¯¯­¯®®°¬“Œ‘¦­¯®¯®®®¯®®®¯®®®®¯®®®¯¯®¯¯¯¯¯¯¯¯¯®­¯¯¯¯¯®¯®®¯®¯¯¯¯¯®®¯®¯®¯®®¯®¬¦…H ;z©¯®®®®®¯¯¯®®¯¯¯¯®®¯®¯¯®¯®®®¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯®¯¯®¯®¯®¯®®®®®®­¯¯°ª’c=C]’¯®®¯®®®®®¯¯¯¯®¯¯®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯¯¯¯¯®¯®¯­¯®®¯¯®ª{B "tª¯¯®¯¯¯®¯¯®®®®¯®®¯®®¯®¯®®¯®¯¯®¯®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®®®¯¯¯¯¯®®®¯®¯®¯¯¯¯¯°®—hdž­­®¯®®­®®¯¯®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯®®®®®¯¯®®®¯¯®®®®¯®®®¯®¯¥9 n–®¯¯¯¯¯®¯¯®¯®®¯¯®®¯®¯®®¯®®¯®¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯®®¯®®®®®®®®®¯®®­¯®¯±¦>A‘ª®¯®®¯®¯®¯®¯¯®®®®®¯®¯¯®¯®®®¯¯¯¯¯¯¯¯®®¯®¯¯®®¯¯¯¯¯®®¯®®®¯®®¯­¯®¯®¬¦}QI›¨°¯®­¯¯®¯¯¯¯¯®®¯®®®¯®¯®¯®¯®¯®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯¯®®¯®®¯®®®®¯®¯¯­®®®¬¨lM A‡§¯®¯­¯®¯®®¯¯®¯®¯®¯¯¯¯¯¯®¯®­®¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯¯®®®®¯¯¯®®®¯®®¯®¯¯°¯¡5 J{¬¯®¯®®¯®¯¯®®®®®­®¯¯®®®¯®®®®¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®®®®¯®®¯®¯®®¯®¯®®¯®®®®ƒ.N„©°®®­¯¯¯®®¯¯®®¯­®®¯®¯®¯®®®¯¯®®¯¯¯¯¯¯¯¯®®¯¯®®®¯¯¯®®¯®¯®¯®¯®¯®¯¯®¯®®¢|5*ž¯¯¯¯¯®®®®®¯¯¯®®®®®¯®®¯¯®¯­®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­®¯®®®¯¯®¯¯¯®¯¯¯®¯®®¯®®®¯¯®«V5f•¯°®¯¯®¯®®¯®¯®®®®¯®¯®¯¯¯¯¯­¯¯®¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯­¯®¯¯®¯¯¯®¯¯¯®¯®­®¯®®« f0W›¯®¯®®®®®®¯¯¯®¯¯¯®®¯®¯®¯®®®®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯®®®¯®®¯¯®®¯®¯®¯¯¯¯®®¯®¯®¯®°7=y§³¯®¯¯®®¯®­®®®®¯®®­¯¯®®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®­¯¯®®¯¯®¯¯®®®®¯¯¯¯¯®¯¯¯¯¯ŒeH¨°®®¯­®®®¯®¯­¯®¯®¯¯¯¯­®¯®®®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯®­¯¯®¯®¯®¯¯­®¯¯®¯¯­¬[ .‚®±¯®®®®®¯®®®¯¯®®¯®®®¯®¯®®®¯®®®®¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯®¯®¯®®®¯®®¯¯®¯®¯¯ª›C,m¦¬¯¯®®¯®®®¯¯®®¯®¯¯®¯®¯¯®¯®®¯®®®®­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯®¯¯®®¯®¯¯®®¯®¯®¯®¯®®¯®¯¯ª%'ˆ®®®¯®®®¯®®¯®¯¯¯¯¯®¯®¯®®®®®®®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®®¯¯¯¯®®¯¯®®®®®¯®¯®®¨{J]‹±®®¯®®¯¯®®®¯¯¯®¯®®®¯®¯¯¯®®®®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯®¯¯¯®®®¯®®¯¯¯®¯¯®®­®®¯¯®¯®²i >Šª®®¯¯®­®¯¯­¯®®®®®¯®¯¯¯®®¯®¯¯¯¯®®®®®¯¯¯¯¯¯¯®¯®®¯¯¯¯®¯®¯¯®®®¯®¯®¯®®®¯¯¯°®Ÿu8’¦¯®¯®¯¯®®®®®®®®®¯¯¯¯®®¯®­®­¯®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®®¯®¯®®®®¯¯®®®®¯¯®¯¯®¯¯¯®®§Nm“¬¯®®®¯­¯¯¯¯¯¯®¯®¯®®®®®®¯®®¯®®®¯®¯­­®¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®®®®¯¯®¯®®®¯®¯¯¯¯¯®¯”D&^¤¬®¯¯®®¯¯®®®®¯®®¯¯¯®¯®®®¯®¯¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯®®®®¯®®®¯¯®¯¯®®®¯¯¯®¯¯®¯±«§s/F©¯¯¯®®®®¯®®®®¯¯®®¯®¯®­®¯¯¯®¯­®®¯¯¯¯®­®¯¯¯¯¯¯¯¯®®¯¯®®®¯¯®¯¯¯®¯®¯®¯¯®®¯®®¯¯¤~5O€­¯®®®¯®¯®®¯®¯®®®®¯¯®®®¯¯®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯®¯¯®®®¯¯¯®¯¯®¯®¯®®¯¯®¯®¯®¯¯®¯®£4 _˜¬¯®¯®¯®®®®¯®¯¯®¯®®¯®®¯¯®®®®¯¯®¯®¯¯®¯®¯¯¯®¯¯¯¯¯¯¯®®®¯®®®¯®®®®¯¯¯¯®¯¯®¯®¯®¯­ŸV¢­¯®®¯¯®¯®¯¯®¯¯¯¯¯®¯­®¯®®­¯¯¯®¯­¯®¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯¯®®®®¯®¯¯®®­®¯¯®®¯®®®®®¯¯¯®¯®¤d .o›¯¯­¯®¯¯¯®¯®¯¯®¯¯¯­®¯®¯¯®®¯¯¯¯®®®¯¯®®®®®¯®¯¯¯¯¯¯¯®®®¯®®®¯¯¯®¯¯¯¯¯®®®®¯¯¯®®°¬w96”¬¯¯¯¯®®¯¯¯®¯®¯®®¯®®®¯¯¯¯®®¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®­®¯¯¯¯®®¯¯¯¯®®¯¯¯®®¯¯¯¯¯®¯®¢šB^‡¨¯¯¯¯¯¯¯¯®¯®¯®®®­®¯®®®®®®¯®­¯®®®®¯¯¯®¯¯¯¯®¯®¯¯¯¯¯®®¯®®¯®®®®®¯¯¯¯®­¯¯®¯®®®®¯­–l"b¡°¯¯®®®®®®¯¯®®®¯®®¯®®¯­®®®¯­¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯®­®¯¯¯¯¯®¯­¯®¯¯®¯®¯®®®®¯¯®®®­¯®¯¯®´£†Z<”§¯®¯¯®¯®¯¯®®®®¯®®­­¯¯®¯¯¯®®®¯¯¯®¯¯®®®¯¯¯®¯¯®®¯¯¯¯¯¯®¯®¯¯¯®¯®¯¯¯®®®¯®¯®®¯®¯®®¯ª)D©°¯®¯®¯¯¯®¯¯®­¯®®¯¯®¯¯®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®­¯®®¯¯¯¯®¯®®®®¯­®®®¯¯®¯®®®¯¯®³±®¬ƒL#R“¯®¯¯®®¯®®®®®¯¯®®®¯¯®¯®¯¯®®¯¯­¯¯¯¯®¯­®®®¯®®®­¯®¯®¯¯¯¯®¯¯®®¯¯¯®®¯¯­­®®¯¯®¯®¯®®¯°žW-b¤­®®®¯®®®­¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®¯¯¯¯®®®¯®¯¯®¯®®¯¯¯®®¯®¯¯¯±­±¥¦ªŠH\­¯¯®­¯¯®­­¯¯®¯­®®¯®¯¯¯¯®®¯®®¯¯¯®®®¯¯®®¯¯®¯®®¯®®¯®®¯¯¯®®¯®®®®¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯¯¦†S,u­®®®®¯®®®¯®­¯®®®®¯¯¯¯®¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®¯¯¯¯®®®¯®¯¯®¯®¯®¯®¯®®®¯°±¬”k]cT5hš±°®®®¯®®®®®®®®®¯¯®¯¯¯®¯®®¯¯¯®®­¯­¯®¯¯¯®¯®¯¯¯¯®­¯®®®¯¯¯¯®®®¯¯¯¯¯¯¯¯¯®¯¯®¯®®¯¯®¯¬¢l WŒ¯¯¯¯¯¯¯¯¯¯®®®®¯®¯®®®®¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®¯¯®¯¯®¯®¯®­¯¯®®®®¯®®¯¯¯®¯©ŸT@!T€«°®®¯¯¯¯¯®®¯¯¯®¯®®¯¯¯¯®®¯®¯¯¯®®¯¯®¯®¯¯®®¯®®®¯®®®®­®¯®¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®®¯¯®°„2}Ÿ¯®®®¯®¯®¯®¯¯¯¯¯®®¯­¯®®®®®®¯¯®®¯¯¯¯¯¯¯¯®®®¯®®®¯¯®¯¯®¯®®®®¯®®¯®¯®®®¯®®®¯°¯†e; O•±¯¯®¯®­®¯­®¯®¯®®®¯®®®¯®®¯¯®¯¯®®¯¯®®®®®¯®¯¯®®­¯¯®¯­®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®®®±–d)(˜¬¯®¯®®¯®®®¯®®­¯¯¯®¯¯®¯®®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®®®­¯®®®¯¯¯®¯¯®®®®¯®¯®¯°®©™C(  <ž¯¯®®®®¯®¯¯¯®®®®¯­¯®¯®¯¯¯¯¯®®®¯¯¯¯®®¯®¯®®®®®®­¯¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯°£?I¡¯¯®¯¯®­¯®¯¯¯¯®¯®¯®®¯®¯®®®¯®­¯®¯¯¯¯¯¯¯®®¯®®®¯®®¯®¯®¯¯®®®¯®¯®¯®¯¯®¯®®®¯°©™cP¢­¯®¯¯¯¯¯¯¯®®¯¯®¯®®®®®®¯¯®¯®®®¯¯¯®¯®¯¯®¯®®®¯¯®®¯®®­­¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯¯®¯¯¯¯¯­¨\8j¦°¯¯®®¯¯®®¯¯¯®¯®®®¯­¯®®¯®¯®®®®®¯¯¯¯¯¯®¯®¯¯¯®®¯®¯®¯®®®¯¯­®¯®®¯¯¯®¯®¯®®®­¡‹')04 Z›®°¯¯®¯¯¯®¯®®¯®¯¯®¯®®®®®®®¯¯¯¯®®¯¯¯®¯¯®®®¯¯¯®®¯®¯¯¯®¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®­¯®®¯¯®®u/Y‰©¯®®¯®¯¯¯¯®­¯¯¯¯®®®¯¯­¯¯®®®¯®®®¯¯¯¯¯®¯¯¯¯®®®®¯®®®¯¯®®®®¯®®¯¯¯®¯®®¯®®¯¯¬›f-Xtƒp`-l¤¯®¯¯¯®¯®¯®®®¯¯®¯®¯®¯¯¯¯¯¯¯®®¯¯®®®¯®¯®®®¯¯®®®¯¯®¯®®®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯¯¯®¯¯¯ŠSv¦¬®®®®¯®¯®®­¯®¯®®®¯¯®®®­¯¯®­®¯¯­¯¯¯¯®®®®®®®¯­¯¯®­¯®®®¯®¯®®¯¯¯¯®¯¯®¯®®¯®­›:!Bpž§­›XG/ 3°­®¯¯¯¯®¯®®®®¯¯¯¯®®®¯¯¯®¯®®¯¯®®®®¯®®­¯®¯¯®¯®¯®®®¯®¯®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®¯¡|„®®¯®¯¯¯¯¯¯¯¯®¯®¯®¯®®¯­¯®®¯¯®®®®®®¯¯¯¯¯¯¯®¯¯®­®¯®¯¯­®¯®¯®®®¯®®®¯®®®¯®®¯¯­…I|œ»¯£…4 Kx](p¡¯®¯®®®®¯¯®®®®®¯¯®®¯®®®¯¯®¯¯¯®¯­®®®¯®¯®¯®®¯®¯¯¯®®®¯¯®¯®¯­¯®¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®®®¯®®«-7±®¯¯®¯®¯¯®®®®®¯¯®¯®¯®¯¯®®®¯®®®®®®¯®®®¯®¯¯®®®®¯®¯®®¯®®®¯¯®¯®®¯®¯¯®¯¯¯¯®²«g&f­²ªša!vž›X =Š®®¯®¯¯¯¯¯®¯®­®®¯®¯®¯®®®®¯¯®¯¯¯¯¯®¯®®®®¯®®®¯¯¯¯®®¯®¯®¯®¯­¯®®¯¯¯¯¯¯¯¯¯­¯®®¯¯­®®®¯®®¯›H*Z—²®¯®¯®®®¯®®®¯¯®¯¯¯¯®®¯¯®¯¯®¯®¯®®®®¯¯®®®¯®®¯®®¯­¯®®®¯­¯¯®®®®¯¯®­¯®®¯®¯®°¢V"#k›´¯¡‹< Dˆ««‡:&~¯®®®¯®®¯®®¯®®¯®¯®¯®¯®¯®®¯®®®¯®¯¯®¯¯®®¯¯®¯®®®®¯¯¯®®¯­®®¯®¯®®¯¯¯¯¯¯¯¯¯¯®®¯¯®®¯­®¯¯¯¯¢n1g{d^«°°—[O¥±®¯¯®®®¯®¯®¯­¯®®¯¯®¯¯®¯®®®®¯®¯®®®¯¯¯®¯®¯®¯®®¯®®®¯­¯®®®®¯¯®¯¯®¯¯¯¯¯¯®®­®¯®®¯®®¯¯¯¯¯¯q k¬®®¯®®®®¯¯®®®®¯¯®®¯¯®®¯®­®®®¯¯®¯¯®¯®®®®®¯­®¯¯¯®®¯®®¯¯¯¯¯¯­®¯®®®®±¯­£ˆ\; .C( (x¤³°ªŽT h§®¯¯¯¯¯®¯®¯®®®®¯®¯®®¯¯®®¯¯®®®®¯®®®¯¯®®¯®¯®®­®®®®¯¯¯®¯¯®®¯¯¯¯®®¯¯¯¯¯¯¯®¯®¯®­®¯¯­¯®®¯°~/"v°®¯¯¯¯®¯¯®®®®¯¯¯®¯­®¯¯¯¯¯®¯®¯¯®®®®®®®¯¯¯®®®¯¯¯¯®¯®¯®­®®®®®¯¯¯¯¯¯±«Žx@0c•©¹Žk/+y£®°¯®¯®®®¯¯®®¯®¯®¯­­®®®®¯¯®®¯®®¯¯®¯®¯®¯­®¯®®¯®¯®®®®®¯¯®¯¯¯®®®®®®®¯¯¯¯¯¯¯®®¯¯®¯®®®®®±‹L:°¯®¯¯¯¯¯®®­®¯¯¯®®¯®®¯®¯®®®¯®®­®®®®®¯®¯®¯¯¯®®®®®®®®¯¯­¯¯®¯®¯®¯¯®¯¬ˆJ5A[`sO7 N§¯¯®¯®®¯®®¯®¯®®®®¯®®¯¯®®¯®¯®¯®¯¯®¯¯®®®¯­®¯¯®¯¯¯®¯¯®¯¯®®®¯¯®®®¯®¯¯®®¯¯¯¯¯¯­¯®¯¯¯¯¯¯¯¯˜n N‹¯¯®¯®­®¯¯®®¯®®¯¯®®¯¯®®®®®®®®¯¯®®®®¯®®®®¯¯­®¯®®¯¯¯®®®®®¯®®¯®®¯®°ª›Q  $ (wœ­°®®­®­®¯¯¯¯¯®¯®¯¯®®¯®®¯®¯¯¯®®®®®®¯®­®­®®¯®®®®­¯®¯®¯®®¯®¯®®®¯®®¯¯®®­¯¯¯¯¯®®¯®¯¯¯¯®¯¯¢†&b•¯¯®¯¯®¯®¯¯¯¯¯®¯¯¯®¯®¯¯¯®¯®¯®®¯®®¯¯¯­®®¯¯¯®®®®¯¯¯­®¯®¯®®­®¯¯®¯¯­£x=Jvxlgj\1 [ ©°®¯®®®®®®¯®­®®¯®®®®®®¯¯­®®®¯¯®®®®¯®¯®­®¯®¯¯®®®®®®¯¯®¯®­¯¯¯¯¯¯¯®®¯®¯®®¯¯¯¯¯®®¯¯®¯¯¯®®¬™/vŸ¯®¯®®®®®®¯¯¯®¯®®®®®®¯¯¯®¯¯®®®¯¯¯¯®¯®®¯¯¯®¯¯¯®®®¯®®¯®¯®¯®­®¯®¯°«œG!V†—£¯° £wA >³®°¯¯®¯®®¯¯®®®®®¯®®®¯¯®¯¯¯¯®®¯®¯¯®¯®¯­¯®¯¯¯¯¯®¯®¯¯®¯®¯¯®®¯®¯¯®¯¯¯¯¯®¯¯¯®¯¯¯¯¯¯®®¯®¯®¯®­£B …¦®®®¯¯®®¯¯¯®®®®¯®¯¯¯¯­¯®¯¯¯®®¯¯¯®®®¯®¯®®¯¯¯¯¯¯¯®¯®¯¯®¯¯¯¯­®®®¯¯§†-[“¯°¯±±°³¥ˆF%$Nv¯®¯®®®¯¯®®®®®¯®®¯®¯®¯®¯®¯®®¯®®®¯®®¯¯­®¯®¯®®®®¯®­¯®¯¯¯®¯®®¯¯®¯®®®®¯®¯¯®®®¯¯¯¯¯¯®¯®®¯®¯®®¯¦U’¬¯®®®®¯®®¯¯®¯¯¯¯¯¯®¯®¯®¯®¯®¯®¯¯®®¯®®®¯¯®®¯¯®®®®®¯¯¯®¯®¯¯¯®¯®¯®±©_ \†©´°¯®¯°°˜o,/asNL~œ·®¯®®®¯¯¯®¯¯¯®¯¯®®¯¯¯®¯¯¯®®¯®®¯¯¯®¯¯®®®­­®®®¯¯¯¯¯¯¯¯¯¯®¯®®¯¯®®®®¯¯®¯®®®¯¯®¯¯¯¯¯®®¯®¯®¯®¯§e)+›¯¯®®®¯¯¯¯®¯¯¯¯®®¯®¯¯®®¯¯®¯¯¯¯¯®¯­®¯®®®¯¯¯®¯®¯¯®¯¯¯®®®®¯¯®®¯®¯°±œ= 9²°¯¯®¯²¨ŠMJ„¨Žg0 `‰±°®¯¯®¯¯®­®¯®®¯¯®¯®®¯®®®®®®®®¯¯®¯¯¯¯®®¯®¯®®¯¯®®®®®®¯¯¯¯®¯¯¯®¯®®®®¯¯®®­¯®®¯®¯¯¯¯¯¯¯¯¯¯¯®­®©w:6Ÿ°­¯¯®¯¯®®¯®®®®®¯®¯¯¯®¯®¯®®®¯®¯¯®®®®¯®®­¯®­®®¯®­¯®®®®®¯¯¯®¯¯°¯³²†1J„ª±¯®¯¯°±›s1$a˜°¨”V" <‚¬¯®¯®®®®®¯®¯¯¯¯¯®®®¯®¯®¯®®¯®¯¯¯¯®®¯¯®¯®­¯¯¯®®®¯®¯®®®¯®®®¯¯®¯¯®¯®¯¯®®®®¯®¯¯¯¯¯®¯¯®¯®¯®®¯¯°ª…J B ±¯®¯®®®¯¯¯¯¯®®®®¯¯¯¯¯®®®®®¯¯¯®®®¯®®®®®¯®®®­¯®®­¯­¯¯®¯¯¯®°¯°®³«ª{= S±°¯¯¯®³ª†Q By©±¯®•]?™­®®¯®®¯¯®®¯¯¯®®®®®®®¯®®®®®¯¯¯®®¯®¯¯¯¯¯­®¯®®­¯¯¯®®®®®®®®¯¯®¯¯¯®®®¯¯¯¯®¯¯¯®®¯®¯®¯¯¯¯¯¯¯®¯¯«’XQ£°®¯®®¯¯¯­­¯®¯®®®®¯­¯®¯¯¯¯¯¯¯®®¯¯®¯®®¯¯¯®®¯®¯®¯¯¯­¯®®®¯®°¯²¦—–†wW=;‹±­®®¯¯±œm0 _“±¯¯°­ž= -‚¯®®®®®¯¯®®¯¯¯¯®¯¯®¯®­®¯®®®¯®¯®¯¯®¯¯¯®¯®¯®¯®®¯®­®¯®¯®¯­®¯®®®¯¯®®¯®¯¯®®®®¯®¯¯®¯®¯¯®®¯¯¯®¯¯­žf)]¢¯¯¯¯®®¯®¯®¯®®®¯¯¯®¯®¯¯®®¯®¯®¯®¯¯®¯­®¯¯¯®®®¯¯®®¯¯®®¯®¯³¬¬™{nQ ,m“¨±°‹S,n ³¯®®¯¯±—: Ož¬¯®®¯®®¯¯®¯¯¯¯®®¯®®¯®®¯®®®®®¯¯®¯®®®¯®¯¯®¯¯¯®®®¯¯¯®®¯¯®®®¯®¯®¯®¯¯¯®¯¯¯®®¯¯¯®¯®®®¯¯¯¯®®¯®¯±~ Cx¦¯®®­¯®¯¯¯­­¯¯®¯®®¯¯¯¯®¯¯¯¯®¯®¯®¯¯®®¯¯®¯¯®®¯®¯¯®®®¯¯¬šh& .d¤ s: D†®¯®®¯®±®ŒE ?‹­¯®®¯®®¯¯®®¯®¯¯®¯¯®®¯¯¯®®¯®¯¯¯¯¯®®¯¯®¯¯¯®¯¯®®¯®¯¯¯­¯¯¯¯¯¯®®®¯¯¯®¯¯®®¯¯¯¯¯®¯®­®¯¯¯®®®¯¯®®±€ I}§¯®®¯®¯¯¯¯®®­®®®®®¯¯¯¯®®¯®®®¯®®®®¯¯®°¯³°®¯°¯¯®¯­¯¯°¯œq2#/H\b[SM4 'Q{Q!_±¯®®­®±§‡S4Œ²¯¯®¯®¯®¯®¯®®¯¯¯¯®¯®®¯¯¯®®®¯®¯®®¯®¯®¯¯®­¯­®¯®¯¯¯¯®®­®¯®¯¯®®¯¯¯¯¯¯¯°±¯¯¯­®¯¯®¯¯¯¯¯®®¯¯¯®®²„! N„¨°¯®¯¯®®¯®¯¯®®¯¯®®¯¯¯¯¯®®®®¯¯®¯°°°¬°«£©ª®©®²°°¯®¯¯¯«ŠOfy•˜«¦–…p[7+9( <~«²¯­¯®±¯¡|DC—³¯®¯®®¯­­¯®®®¯®®¯¯¯®®®®®¯®®®®­¯®®®®¯®®®®¯­®¯®¯®¯¯¯¯¯®¯¯®¯®¯¯¯±°¯³¬ª«³´¯­¯®®¯®®­¯®¯¯®®®®®±„# R‡¨®®®¯®¯®®®¯®®¯®¯¯¯¯¯¯¯¯­¯¯®®®°°­§ž‹wxpfxŒŒ”œ©´±¯°¯® r4[š¨²¯¯°´® ‹mN& LŽ«®®²²®³©e#a›¬®®¯®¯®¯®¯¯¯¯®®¯¯¯®®®¯¯®®¯¯¯¯¯¯¯®¯®¯¯®®®®®¯®®¯¯¯®¯®¯®¯®¯®¯¯¶©¬ŸŠ˜š˜£°¶°®®¯¯­®®®¯¯¯®®®®²„#X©°¯®¯®¯¯®®¯¯®¯®¯®¯¯¯¯¯¯­®¯®°°ª©ŠvSA &,Jbft‹¡´³±®œdƒ«±®±®¯®¯³° „Y3 -i‹”™§¬°¥’lA/x£®®¯®¯¯®¯¯¯®¯¯®¯®¯¯®®¯®®¯®®®¯®¯¯®®®¯®¯¯®¯¯¯¯®®®¯¯¯®®¯®¯®®¯°¬¢ŒoaL4>TYak† ®µ±®¯¯®­®®¯®¯¯®¯°ƒ"XŽ©¯®®®¯®­®¯¯¯®¯®®¯¯¯¯¯¯®¯®¯¯²£Œ~;. ':DWyš´²”M4Š©­¯®¯¯¯®¯¯³³v?7S_fz‚wP3 Z©°®®¯®®®¯®¯®¯¯®®®®®¯®¯®®¯¯®¯¯¯¯®­®®®¯®¯®®¯®¯®¯­¯®­®®®¯¯¯¯°§ŒiE" ).Ca‚ ®°®¯¯®®®¯®®®®¯²€\©¯®®®®¯¯¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯±³†O4*Cn’ˆ1.k¦¯¯¯¯°®¯¯®¯¯²´’S #.3ƒ¦¯¯¯®®®®¯¯¯®®¯®¯¯®¯®®®®¯¯®®¯¯®®­®¯¯®®®¯®®®¯¯®¯¯®®¯¯­¯®®°²¬•‚6' (Qw—ª®¯®¯¯¯®¯¯­¯¯­y`•ª¯®¯¯¯¯®®®¯¯¯®®®¯¯¯¯¯¯¯¯®¯°¥p@ $<>Tž°±°°­®´¯®®®¯¯ª-fž¯¯®¯®­®®¯¯®¯¯¯¯®¯®®®®®¯®¯­­®®®®®¯®¯®¯¯¯®¯¯¯®¯®¯¯¯¯¯­®®¯®¬Z0 'H‹§­¯­­¯¯®¯¯¯®­¤la˜«°®®®¯¯®®¯®¯¯®®¯¯¯¯¯¯¯¯®¯¯®¨€I C…©¬¢¦•œ§®µ°¯¯³«o&   H–±¯¯®®¯®¯®®¯®®¯®¯¯®¯®®¯®®¯®®®¯¯®¯¯­®®¯¯¯®¯¯¯®¯®¯¯¯¯®®¯¯±®œƒQN­®®¯®®®¯¯¯®«•Zdšª®¯¯®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯®¯¯Y$ E†{iYWR]‡¤­°¯µW*anZ<2( L©³¯¯®¯¯¯¯®®¯¯¯®¯®¯¯¯®®®¯®¯®¯¯®¯¯¯¯®¯¯®¯­®®¯®¯¯®®¯¯¯¯¯°®¬¡g?$cž¯¯®®®®¯¯®¯«‡Jb˜ª°®®®®®¯®®®¯­¯®¯¯¯¯¯¯¯¯¯¯®¯¯®­§€H)!/j˜¬²¬~3S¨­™€dXM/G±¯¯®¯¯¯®¯¯­¯®®®¯®®¯®®¯®¯®®­¯®¯®¯®¯®¯­®®®¯®¯¯®®¯®¯®®¯±±£Žo #6/ C›­®®¯®¯®®¯¯©u7\’ª°¯¯¯¯¯¯®¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯®®®¯®«£ŽZ' 2|¬´¡Z!(y®°®³µ¥”€lX24r¨±¯®¯®®¯®®®®¯®®®¯®®¯®¯­®¯®¯®¯®®®¯¯¯®¯®®®®®¯®¯®®¯®¯¯¯°ªyX,Dj€O3©°¯®®¯®®®¯§d&YŽ©¯®®­®¯­®¯¯¯®¯­¯¯¯¯¯¯¯¯¯¯®­­®¯°®¥‹c% qª¬5 D•³¯¯®¯±³¬ˆjCK”¬¯¯®¯®®®¯®®®®¯®¯®®¯­®®¯®¯¯®¯®¯¯¯®¯®®®¯¯¯®®®®¯¯¯®®°®¢‚9#)Oˆ¨­¯’).w¨°¯®®®®¯®¯¦UWŒ©°¯¯¯¯¯¯¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯®®®®¯®±³¬Ÿq42v©¡Z!k©°°®®®®¯°³¯žu9 bœ¯¯¯®­®¯®¯¯¯®­®®®¯¯®¯¯®¯¯¯®®®¯®®®®¯®®¯¯®¯­­®®®®¯¯¯›zD 7h‡ª´°³Ž8&v¯¯®¯®¯¯¯®¯¤E Q‡©®®¯®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯±³Ÿ}Gc’ªˆ2 =µ°¯±²¯®¯¯®°´®y3 9‡­®¯®¯®¯®¯¯®®¯®¯¯®¯®®¯®®®®®®¯¯¯®¯¯¯¯¯®¯­®¯­®®®°°®Ÿk9(ož¤±¯¯²’R-„±°®¯®®®®®®¡6 K€¨°¯¯¯¯®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯®¯¯®­®®¯®®­›e0 #S‘®¤cc¦±°ž¦¬´³®¯®®°­Ÿ^Xž¯¯®¯¯¯®®¯®®¯¯¯¯®®­®¯®®¯®®¯¯¯¯¯®¯®¯¯®¯¯¯®¯¯¯¯±©™x,  (^œ¯­°¯®®¤mH‘ª¯®¯®¯®®®«˜. Ex¦°¯®¯®®¯¯­¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®¯¯®®›eLr±³Œ;7ˆ°¢catšª°°¯®¯°©}6B”²®¯®¯¯®¯®¯®¯¯¯¯¯®¯®®¯®¯¯¯­®­®®¯®®®¯¯¯¯¯®¯®¯³­h@,`³¯¯¯®®±«„-b®°­®®®®¯®¨*;n¥°¯®®®®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯¯¯®¥p' <†ž­¸¨d  R¢©—HH£®¯¯®®°’K4€«®¯­­¯®®¯¯¯¯®®¯®®¯¯®®®¯®®¯®®¯¯®¯®®®¯¯¯®¯®¯¯¯ŸX3d‰¦´¯¯¯¯¯¯®žd# C†¥®°®®®®®®¯«™00b¤±®¯¯¯¯®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®¯®¯¯¯¯ª’^l­°°³>(|± |  C‹§±®¯¯³¢?!m«°®¯®¯¯¯¯¯®¯¯¯¯¯¯®¯®®®®®¯¯®®¯¯¯®¯®®®®¯¯¯®°¬™kK”¢°°®®¯®¯®¯±•rC"<{¤¯°®¯¯®®¯¯®® G"S¡±®®®¯®¯¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®¯®¯®®°ª[o¬´´ªh L˜µ©\T”®¯¯²¬„%r©°¯®¯¯¯®®¯¯¯¯¯®¯¯¯®®¯®®®®¯¯®®®®¯®®¯®®®¯®¯°Žt- %…¦®±¯¯¯¯®®®®­ªueOP{ƒ¤±°¯®¯¯¯¯®¯®¯¨k, BŸ±¯¯¯¯¯®¯®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯®®¯®¯®®±®ŽQ">u›¯˜= x°±£L)m¬°°¥”N"¤°®®¯®¯¯¯¯®®®®®¯¯®®®¯­¯®¯®¯®¯¯®­¯®¯¯¯®¯¯²–Z8 ]«¬¯¯¯¯¯®®®®®®¯®¦¦£ŸŸª°°°¯®¯¯®¯¯®®®¯¬–_1œ°­¯¯¯®¯¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®®®®¯¯®®¨}7 FdnY C–µ¯¢] N”œ‹lP<¤±¯®¯®®®®®®®®®¯¯¯®¯®®¯®®®®­®®¯¯¯¯®®¯¯¯¯«©c(B’°°®®®®®®®¯®¯®¯¯±°®µ°°¯°¯®­®¯¯¯­¯¯®¯®«|# —®®¯®®¯¯®¯®®®®®®¯¯¯¯¯¯¯¯¯¯®®®®®¯®®®¯¯®¯®®¯­€3 '2p­²¯©u 8VH!V‡¬¯¯®®¯®®­®®®®¯®¯®¯¯®®¯®¯¯¯¯®¯®¯¯®¯®®­²«žy&Et¯°¯¯­¯¯®¯®®¯¯¯®¯°°¯¯¯¯¯®®®®®¯®¯®¯®¯®®±“Y'Ѝ¯¯¯®®®®®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯®®®¯®®®¯¯¯p"%~´´²©i 0o›²®®®®®®¯®®®¯¯¯®®¯¯®¯¯®¯¯®¯®®¯¯¯¯®®®¯®±šz<4f›²°¯¯®®®®®®®®®®­®¯®¯®®®¯®®¯¯¯®­®¯®¯®¯®°¦“LwŸ®¯®®®®®¯®¯®­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®®®®¯¯¯°ª’W#U„²šNY†¨²®¯¯®®¯®¯®¯®®®¯®®®¯®¯¯®®¯¯¯®¯¯®¯®®®¯´¤r@d’¬¯°®­¯®¯¯®¯®®®¯®¯¯®¯®®¯®®®¯®®®¯®®¯®®¯®¯­¬l' `“°¯®¯®¯®¯¯­¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯®¯¯®®®®°°ˆO )R_f[+ C…Ÿ²®®¯®®¯¯®­¯®®®¯®¯®®®®®¯­¯¯®¯®­¯¯®®¯°­­†AAŒ¨±¯®®­¯®¯®¯¯¯¯¯¯®¯¯¯¯®®®®¯¯¯­¯¯®¯¯¯­¯¯¯¯®¯hGˆ±¯®®®®®¯®®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®®¯®¯®®®¯­¯¤t"!u¥¯´°®¯¯®®®¯­¯¯®¯®®®®¯®®®¯¯®®¯®®®®®®®¯°ª‘R u©®®¯­®¯¯®®®¯¯¯®¯®¯®®¯®¯®®­¯¯¯®¯¯®¯®¯®¯­¯¯®®§–?'}¯¯­¯¯¯®¯®®¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯¯­®®®®®¯®¯¯¯®®®®¯­§i&X…¨·²±°®¯®¯®¯®®®®¯®¯¯¯®®®®¯®¯®®®¯®®®®°¬“e#Nœ²®¯®®®¯®¯¯®¯­®¯®®¯®®¯®®¯®®®®®¯¯®¯¯¯¯­®®¯®®¯±«h+m±¯¯®­¯®¯®¯¯¯­­¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯®®®®®¯®¯¯¯¬”k! !4X£µ±°¯®®®¯®­¯®¯¯®¯¯®¯®®®¯¯¯®¯®¯®®°²•a3C±¯®­¯®®®®¯¯¯¯¯­®®¯¯¯¯¯®¯¯¯®®¯®®­¯®¯¯®®®®®¯®¯¯­™cY¥¬°®¯¯¯¯®®®­¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®®¯®¯¯¯®¯¯§^. 0W„¡²°¯¯¯¯¯¯¯¯®¯®®­®®¯¯¯¯¯¯®®®¯®®°«i1 6j¡¶®®¯¯®®¯®®®¯¯¯®¯¯¯®¯¯®®¯®¯®¯®®¯­®®¯®®¯¯¯­®¯¯¯®«†; K’¦°¯¯®¯¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯¯®¯¯¯¯¯¯¯²¯ž}N+ ,35<#De¤¯¯¯®®¯®¯®¯¯¯®¯­¯¯¯¯¯®¯®¯¯°¬©‡*%dŒ¯°®®¯®®¯®®®®­®®®¯¯®®®®®®®¯¯®¯®®¯®­¯¯®®¯¯®­¯®¯®¯°p(8rž±¯¯®®®­®®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯®®®¯¯®¯¯°´­œ†gamcfwŠ€{46_} ®¯®¯¯¯®¯®®®¯¯®®¯¯®¯®¯®¯¯°¡˜K T‹£´¯¯¯¯®¯¯®¯¯¯­¯®¯¯¯®®¯®®¯®¯¯¯¯¯®¯¯®®¯®®¯¯®¯¯¯®¯®®¬¢OL•±¯¯¯®®­­¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯¯®¯¯®®®®¯¯®¯¯³³¥Ÿœ§«§µ°•EK ±±®¯®®¯¯®®¯®¯®®¯¯®®¯¯¯²¦…i5Œž®°¯¯¯®¯¯®®¯¯®®®®¯¯¯¯¯®¯®¯®¯¯®®¯­®®®­®®¯­®®­®®¯­¯®¯­K )Н®®¯®¯¯¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®®­®¯¯®®®¯®®¯®¯°²´®¯¯±¯³“V-k›«¯®®¯®®¯®®¯¯®®¯¯¯¯¯¯°¶Šf1i©«°¯®¯®¯¯®®¯¯®¯®¯®®®®¯¯¯¯¯¯®¯¯¯¯¯¯®®¯®­®¯¯®¯¯­¯¯¯®®¯¯~!«®®®®¯®¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®¯®®®¯®®¯¯¯®®¯®¯¯®¯°¯¢tE 0e–­®¯¯¯¯¯®®¯®®¯¯¯®¯¯¯°¤[8 Iœ¬®°®¯¯®¯¯¯®®¯®¯¯¯¯®­¯®®®¯®®¯®¯¯®¯®®¯¯¯®¯®®®¯¯¯®®®®¯®®®ŸKPœ«°¯¯®¯¯¯¯¯­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®®­®¯¯®¯­¯®®¯®¯®®®®¯«¯s< 9_uG /pª®¯¯¯¯¯¯®®¯®¯¯¯¯®°¬°x,<~³®®¯®®®¯¯®¯®¯®®¯®®¯¯¯¯­¯®¯¯®®­®¯®¯¯¯¯¯¯¯®­¯®¯®®®¯®®¯®®°©yK-|§¯®¯¯®®®¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®®®®®®®®®®¯¯¯®¦‰0Apœ¥u5 2ƒ¦¯¯¯®¯®¯®¯­¯¯¯¯¯®¢“@Ad¢²®®¯®®¯®¯®¯®®®®¯®®®¯¯®®®®®®¯¯®®¯®®®®¯¯¯¯¯¯®®¯®¯®¯®¯¯¯®¯®¦|V¤¯®¯®¯¯¯¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯®®¯¯®­®¯¯¯¯®®®®¯¯°ª¤XHН¹œc!]¯°®®¯®¯®¯®®¯®¯³¤b6g޲¯®¯®¯¯®¯¯®®¯®¯®¯®®¯¯®®¯¯®®¯¯®®¯¯®®®¯®¯®¯®¯®¯¯¯®®®¯¯¯­®¯®­–^0œ­®¯¯®®¯®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯¯¯®¯®®¯¯®®®¯®¯®¯®­˜. A”²®ªŠ6*|©¯¯¯¯¯®¯¯®¯­®²¬Šh0e‡§±®®®®¯¯®¯¯¯®®®®®®®®¯®®¯®¯¯¯®®¯®®®¯¯®®¯¯¯®®®¯¯¯®®¯®®®®®¯¯­¯¦ŽC †¥®¯¯¯®¯®®®®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®®¯¯¯¯¯¯®®®¯¯®®¯—G M²¯®¨}8  ^˜­®¯¯¯®®¯®¯®®µc9F“¢°¯®¯®¯®¯®¯¯¯®®®®¯¯¯¯­®®®¯¯¯®®¯®¯¯®¯¯®¯¯¯®¯®®®®¯®¯®®®¯¯®®¯¯®°«l:\¯®®¯®­¯®¯¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯®¯®®®¯¯¯®¯®¯®­®¯t1j¯¯¯«œt.  =а¯¯­¯¯¯®¯®¯±¬s3 %}£¯°¯®®®¯®¯¯®®¯®¯®®¯¯®¯¯®¯¯®®¯®¯¯®®®¯¯®¯®®®®¯®®®¯¯®¯®¯®¯­®¯¯®®¯­š{.z­®®®¯®®®¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®­®¯®¯¯®®¯®¯®¯­sC<ˆ¤¯®¯°¬˜o;  +«®¯¯®®¯¯®¯¯°?%X¢¯°®®®¯®¯¯¯®®®®®®®®¯¯®®¯®¯¯®¯¯¯¯¯®¯¯¯¯®¯¯®®¯®®¯¯¯®¯®®®¯¯®¯®®¯¯¯®­œN [©®¯­®®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯­¯®¯¯¯®®®®¯®¯®¯®®¯³ª“uRQX}«¯¯¯®°´¦‹d<%&& 3./=B8CTE@NM79JN7 %" q¤¯®®¯®¯­¯¯¨˜`!K‰®±¯¯®®®¯¯¯®®¯¯®¯®¯®®¯®®¯¯¯¯¯®®®®¯®¯®®®¯¯®¯¯®®®¯¯¯¯®®®¯®®®¯¯®®¯®¯¯©ˆQ/ލ¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯®¯¯¯®®®®®¯¯¯®®¯®¯¯¯²¯ —“«±¯®¯®­¯®±²¤“}my~mx‚„†ž—œ–”›‰‡‘”nh_F&h§²¯®®®¯®°®›l.K|¥±¯¯¯¯®®®¯®¯®¯¯¯®¯®®¯¯®¯¯¯¯®¯­¯¯®®®®¯¯®¯¯®®¯®¯¯®®­®®®®®®®®®®®­¯®¯¯­©0b¡°®®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®¯®¯®¯¯®®¯¯®¯¯®®¯¯®¯¯¯°¯´´®¯¯¯®¯®®¯®¯®°µ­¥¤¬²¨­²¬¬­´­²µ­­­´®«²­¨›šž…dJTŒ¬°¯¯¯®¯°°¢tB 4{™¯±®¯¯¯¯¯¯¯¯®®®¯®¯®¯®®¯¯®®¯®¯¯¯¯¯®¯®¯¯®¯®®®¯®®®¯®¯®®¯¯¯®®¯¯®®¯®®®®®¯²ši#•®®¯¯®®®®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®¯¯¯¯¯®®®¯®®¯®®®¯®­¯¯­¯°¯®¯®¯®¯¯®¯®¯¯°´¯°°¯°¯±°¯¯¯¯¯°°¯°®¯®°µ¯­©«± ”§°®®¯®®¯³¯€Bg£¨¯®¯®®¯®¯¯¯®¯¯¯®¯¯­®®¯¯¯¯®¯®¯®¯¯¯¯®¯®®®¯¯®¯¯®¯¯®¯®®¯¯¯®¯¯®¯¯¯¯¯¯¯®¯®®ª˜-y ®¯¯®®®®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®®¯¯¯¯¯®¯¯¯¯®®¯¯®®¯®­®®¯¯¯®¯¯®¯­¯¯®®¯¯®¯®®¯¯®¯®¯®®¯®®¯®®¯­®®¯°¯¯®¯³¯°¯¯®¯¯¯­›LH•­®¯­¯®®®¯®®®®®¯®®¯®¯®®®¯®¯¯®®®®¯®®®®¯¯®¯¯®®®®®®¯®¯®¯®®®®®®¯¯®®¯®®¯®®®¯®¥FRƒ¬¯¯¯®¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®¯®®¯¯¯®¯¯¯¯®­¯¯®¯®­®®®®®¯®¯®®®®®¯®¯¯¯¯­¯®®¯®¯®®¯¯®¯®¯®®¯¯¯®®®®¯®¯¯¯®®®¯¯±«¡hBz°­¯¯®¯®¯¯¯®®®¯®¯¯®®¯¯®®¯¯¯®®¯¯®®¯®®®¯®®¯¯¯¯¯¯®®¯®¯¯¯®­®¯®®¯®¯®®®­¯®®®¯¯¯ªZ%X§°¯¯¯®­®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯¯®®¯®¯®®¯®¯¯®¯®®®®®®®®¯®®¯¯¯®­¯®®®¯¯®­®¯®¯®¯®®®¯®¯¯®¯¯®®¯¯¯¯®®¯¯¯¯¯®¯¯®¯¯œƒ1@i¶®¯®¯®¯¯¯¯¯®¯®¯®¯¯¯®¯¯¯¯¯®¯®¯¯¯®®¯®®¯®¯¯¯®®®®®¯®®¯¯¯¯­®®®®®®®®®®®®¯®¯¯®¯©b.4—¦¯®®®¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®¯®¯®®®®¯®¯®®®®®¯¯¯¯¯­¯®®®¯®¯¯¯®®¯¯®®¯®¯¯¯®®®¯®®®®¯¯®¯¯¯®®®¯¯®¯¯¯¯¯¯¯®µ¡O 2qް®®®¯¯®¯®®¯®¯®¯¯®®¯¯­®¯®®¯®¯­®¯®®­®®¯¯¯¯¯¯¯®¯®¯¯®®®®¯®®®¯¯¯®¯®®®¯®¯®¯¯®®°ªX$k“°®¯­®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®®®¯®¯¯¯®¯¯¯¯¯®¯¯®®®¯®¯¯¯¯®®®®®¯®­®¯®®®®®¯®®®¯¯®®¯®¯®¯®¯®¯®®®¯®®®¯®®®¯®¯³„Xc’¤³®®­¯¯®¯®¯®¯¯®¯®®®®®®¯¯¯­®¯®¯®®®¯®®®®¯¯¯¯­¯¯¯¯®¯®®¯®¯¯¯¯®¯¯¯¯®®®¯®®¯¯¯®¯¯£D#s­®®¯®¯¯®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯®¯®¯¯¯®®¯¯¯®®®®®¯®®¯®¯®®¯¯®®®¯®¯®®®­®®®¯®®¯®¯®®¯®®¯®®¯¯¯¯¯­®®¯®®®®¯®¯¯¯¯®¶œX* K˜¢¯°¯¯¯¯¯¯®®¯®¯¯®®¯®®®®¯®¯¯­®®¯®¯®¯®®¯¯¯¯¯¯¯¯­®¯¯®¯®®®®¯¯¯¯®®¯®­¯¯®®®¯­¯¯¯°¨&Q›©¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯®®®¯®¯­®®¯¯¯®®¯¯¯®®®®®¯®®®®¯®®¯¯¯®®¯®¯®¯¯®®®®¯¯®¯®®¯¯¯®¯¯®®®®®¯¯¯®®­±o) 1}®¯°®®¯®¯®®®®®®¯¯®®®®®®¯¯¯®®¯®®®¯®¯®¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®®®¯®¯®®®¯¯¯®®¯¯¯®¯¯¯¯³“R +t£±®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®¯®¯®¯®¯®®¯®¯®¯®®®­¯®¯®¯®¯®¯¯¯¯¯®®®¯®¯®®®®®®®¯¯®®®¯®¯®¯¯¯¯¯¯®®®®®°®§:4a¦¯¯¯®®¯®¯®¯¯¯®¯¯®¯®¯®®®¯®¯®®®®¯®®­®­¯¯¯¯¯¯¯¯®®®¯®®¯¯®¯¯®®®¯¯¯¯®¯®¯®®¯¯¯¯¯¯ª”g3­¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯­¯¯¯¯¯¯®®¯®¯¯¯®®®®®®®®®¯¯®¯®®®®¯®®®®¯®¯®¯®¯¯®®®®®¯®­¯¯¯¯®¯®¯¯¯®®¯¯±¦•\/[‘³°¯®®¯¯®¯¯®®¯¯®¯¯¯®®®¯®®®¯®®­¯¯®¯¯®®¯¯¯¯¯¯¯®¯¯­¯®­®®®®¯¯®¯®¯®¯¯®¯®­¯¯¯­®¬¥•U)Y˜®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯¯®®¯¯¯¯¯®¯¯®®®®®¯®®¯®®¯¯­¯®­®¯¯¯®¯¯¯®¯¯®¯®®®¯®®¯®®®®¯¯®¯¯¯¯¯®®¯®®²­g)_€¨±°­®¯®®®¯®®¯®¯¯¯®¯®®®®¯¯®¯®®¯¯®®¯®¯¯¯¯¯¯¯¯¯®®¯¯¯¯®®®®®¯®®®¯¯®®¯®®®®®¯¯±¦[:.t¬®­®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯¯®­¯®®¯¯®¯®¯®®¯®®®¯®®®®®®®¯®¯®¯®¯¯¯¯­®¯®®¯¯®¯®¯®®®¯®®¯®¯¯®®¯®®³¡i= H‡Ÿ°®®®®¯®¯¯¯¯¯®¯¯¯®¯¯®¯®¯¯®®®¯­®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯®®¯®¯®®®¯¯®®¯®¯¯¬•{N8Ÿª¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®¯¯®®¯¯®¯®¯®¯®¯®®®®®¯¯¯¯¯®®¯®®®®¯®¯¯®¯®¯¯®¯®¯¯®®¯®®¯®®®®®®®²ª}2„ ®°®®¯®¯®¯®¯®¯®®¯®®®¯¯¯¯­¯¯®®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®®¯®®¯­®¯®®®¯¯¯¯¯®®­¯ªœ[1i–±¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®¯¯¯®®®®¯¯¯®¯­¯¯®®¯®®¯®¯®­¯®¯®®¯¯¯®®¯¯¯¯¯®®¯¯®®¯®®®®®®®®¯®®®®›D Z¨®¯¯¯¯¯®®®®®®®¯¯®®¯¯®¯¯¯¯¯®®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®®¯®®¯¯­®®®®¯®®®¯®®¯®O +|ª®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯¯®®®®¯¯®®®®®¯®®®®®¯®¯®®®¯­®¯¯®®®¯¯®¯­¯¯¯¯¯®®®®¯®¯®®¯®®­¯®¯°¬™m$A’®°®¯®®®®¯¯¯®®®¯¯®¯®®¯¯®¯¯¯®¯­®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®®¯¯®®¯¯¯¯¯­®­®¯®°¤ŠJS–­®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®¯¯¯®¯®¯®®¯®¯®¯¯®¯¯¯¯¯®¯¯¯®®¯®¯®¯®¯¯®¯®¯®¯¯®¯¯®¯¯®¯®¯®®®°±Ÿ}7Fu­²­¯®®®®¯¯®®®­®®®¯¯®®®¯¯¯¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯®®®¯®¯¯®¯®¯¯¯¯¯¯®±‘J[¨®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯®®®®®¯®¯®¯®®¯®¯®¯¯¯¯®®¯®¯®­¯®¯¯¯­¯®®¯®¯®®®¯®®¯®¯²¦S =r›±±®®®®¯®¯¯®®¯®¯®¯¯¯¯®®¯®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®¯®¯¯¯¯®¯¯®®®®¯®°‘IŠ¡°¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®¯®¯®¯®®­®¯®¯¯®¯®®¯®®¯®¯¯®¯¯®¯®¯¯­­®¯¯®®®®®®®®¯¯®¯®¯®®¯¯³X$o›¬±®¯®®¯­®¯®®¯¯®¯®®®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯®®¯¯¯®¯®¯®®®®®¯¯¯®¯±—^O…®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®®®¯­¯­®®®¯®¯®®®®®¯®¯®¯®®®®®®¯¯®¯®®¯®¯®®¯¯®¯®®®¯¯®®¯­®¯¯³£c2 Q˜¨°¯¯®¯®®®®­®¯¯®¯®®®¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯¯®®®¯®®¯¯¯®®¯­¯®¯¡+Z©¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®®¯®®¯®¯®®¯¯¯¯®¯®®®¯®¯¯®¯¯¯®¯®¯®®¯¯¯®¯¯¯®®¯®®¯®¯®¯¯¯¯¯®¯¶€4 =±®¯¯¯¯¯®¯¯¯®¯¯®¯¯®®¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®®¯­¯®¯®¯®¯¯¯¯¯®®®®¯« B-o—®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯®¯­®¯®®¯¯®¯¯®¯®®¯®¯¯®¯®®¯®¯®¯®®®®®¯®®¯®­®®®®¯®¯®®®¯®¯®¯¯¬¡M 8h¤²¯¯®¯¯¯®®¯®®¯®®®®®¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯®¯®¯®¯®¯®¯®®®¯®®®®¯­`$~«¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯®®®¯®¯®®¯®¯¯®¯¯¯®¯¯®¯®®®¯¯¯¯¯®¯®®¯¯®­®®®®¯¯®¯®®¯¯®±ª¨r)j‘³¯®¯¯­¯¯®®®®¯®®®­®¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯®®®¯¯®¯®¯®¯¯®¯®®¯¯yBX‘¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®¯®­¯¯­®¯¯¯®®®®¯¯¯¯¯®¯®¯¯®¯¯¯¯®¯®¯¯®®®®®¯®¯®¯®¯¯¯@aŒ§³¯®®®­®­®®®®¯®¯¯¯¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®¯®®¯¯¯®¯®¯¯¯Žd $l¦¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®®®¯¯¯®®¯®¯®¯¯®®®®®¯®®¯®®¯®¯¯®¯®¯¯¯¯¯®¯®®®®®®®®¯³£Ž_@”¤¯®¯®®®®¯®¯¯®®¯®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯®®¯¯®¯¯®¯®­¯®¯®®¯®®¯¡ƒBœ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®¯®®¯®¯¯®¯®®¯¯®®®®®®¯®¯®¯®®®¯®­¯®®¯®¯®®¯®®¯®¯°q2!z©­¯¯®®®®¯®¯¯¯¯®¯®­¯®­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®¯®®®®¯¯¯­¯¯®®¯¯¯¬•  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯¯¯®®®¯¯¯®®¯¯®®¯¯¯¯®¯®¯¯®®¯¯¯®®®®¯¯¯®®®­®®¯µ¢nE*Z¥®­­¯®¯¯®¯®®®®¯®¯®®®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®®¯®¯®®®®¯¯¯¯¯®®¯¯®§W°¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯®¯®®®¯®®®¯®®¯®®®¯®®¯¯¯¯¯­¯®¯¯®¯®¯®¯®¯¯®¯­®¯°³„M$/P°°¯­®®¯®¯¯¯¯¯¯®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯®®®®®®¯®®®®¯¯¯®®¯¯—t*v¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®®¯¯¯¯¯¯®¯¯¯®¯®®®®¯®®®®®¯®®®®¯¯®¯®¯®®®¯µ¡Y#Y}«±¯®®¯¯®®¯¯¯®¯®¯¯®¯®­®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®®¯¯¯¯¯¯®®®¯®®®¯¯®¯®q5]¦¬¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯¯®®®®¯®¯¯®¯¯®¯®®¯®¯®®¯®®®¯®¯­¯¯®®®®°®³)NŸ¯²®®®®¯®­¯®®®¯¯¯®¯®®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯®¯®¯­¯®®¯­¯¯¯®¯®®®¯°¤‰G3•§°¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®¯®¯®®®¯­¯®®®®¯¯¯®®¯¯®¯¯¯®¯¯¯®¯®®­¯®¯®®®¯®¯˜M*…£¬¯¯®®¯®¯®®®¯¯¯¯¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯¯®®¯®®®¯®®­¯®®¯¯°­£†Po °®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®¯¯®®¯¯¯¯¯®¯¯¯¯¯¯®¯®¯¯®®¯®¯®®¯¯¯®®®¯®®°©¥vf¡°®¯®®®®¯¯®¯®®®¯¯®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®®¯®¯¯®¯¯¯®®®¯­¥m8 F—°¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®®¯®¯¯¯¯®¯¯¯®¯®®®¯®¯®®¯®¯®¯¯®¯¯¯®¯®¯¯¯¯¯°­¡…E 0P–±¯¯®®¯¯¯¯®¯®¯®­®®¯®®®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®­¯¯¯¯®¯¯®¯®¯®¯¯¬¨‰f4‰¬¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯®®¯¯®®®®¯¯¯­®®¯®®®¯®®¯®¯®®¯¯®¯®¯¯¯®®®±§’`*Tª´®®®¯¯¯¯¯¯®®¯¯¯¯¯®®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­®¯¯¯®®¯¯®¯®¯¯®® ŽSs ­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯¯¯®®¯¯®®¯®¯®¯¯®®®¯¯¯®¯¯®¯¯®¯¯¯®¯®¯²­•r;ZŠŸ°°¯®¯®®®¯®®®¯¯¯®¯®®®®®®®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯®¯¯®®®®®®®­¦|+XŒ«°®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®®®®®¯®¯®¯¯®®®¯®¯®®¯®¯®¯¯¯®®®¯¯¯´¤L9ˆ£®±®®¯¯®®®¯®¯¯®®®®¯®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯¯®®®®®¯¯¯®ª`E) ;q©°®®¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯®¯¯®®®¯¯®®¯®®¯®¯¯®®®¯¯¯¯¯®¯®±°ŠV, .rª«°¯®¯®®®¯®¯®¯®­¯®®®¯¯®¯¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®¯®¯®¯®®®®­©£ˆg8V¥°®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®¯®¯®®¯®¯¯®®¯®¯®¯¯®¯¯¯®®®®¯®¯¯­­¶¤e2+Zœµ®¯¯®¯¯®®¯®®®®¯®¯®¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯®®¯¯¯®¯®¯®®¯¯®¯®­ª£‘a ;›¬¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯¯¯¯®®¯®®¯°°²³®¯®®¯®¯¯®®®®¯­±±‡8!a‰®°¯¯®¯¯¯®¯¯®®®¯¯®®®¯¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®¯¯®¯¯­®¯¯¯°¯©‚/ #Œ§®®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®¯®¯®¯¯²®­¨ž¡²´­®¯¯¯¯®®­®¯®µ¦S  V¦´¯®®¯®¯®®¯®¯®¯¯®¯®®¯®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®®®¯¯¯¯®¯­®®®¯±“Onž°®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯®®­¯®®°«¥|tmanŠª³®®®¯®®®®¯¯¬ƒ:‘¤¯°®¯¯¯¯¯®®¯¯®¯®¯®¯¯¯®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®¯­®°—`N“°¯¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®­®®®¯¯­¯¯®°§‰n,"#(0V„©²¯®®®¯¯°­™M=v¯°¯¯¯¯¯¯®®¯¯¯®¯¯¯®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®®®¯®¯¯®¯®¯¯®¯®®±™b)ˆ°­®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯¯®¯®°°Šh06pž¯®®¯¯¯¬ž{ Hq¡±¯®¯®¯®¯®®®®¯®¯¯¯®¯®®®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯­¯¯¯¯¯¯¯¯¯®®®®®¯®¯®®®¯®¯®¯®¯¯¯®®®°—[{¬®¯®¯®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®®¯®¯±¢mC L€¬®®¯¯±£F9~›¯²®®®®¯¯®¯®¯¯¯¯¯®®¯®¯®®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯®®®®¯¯®¯¯®®¯®®¯¯¯¯¯¯®®¯¯®®¯®±‘Bk¢«¯­¯®¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯°”d*]Ÿ­¯¯°¬‹b)v¦ª¯¯¯¯®¯¯®®¯¯¯®®®®¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®®®¯¯®®¯¯®¯®¯®¯­¯¯®¯¯¯¯¯¯¯®°°®©˜l!\”¨°®®®®¯®®¯­®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯®®¯¬’`3Ž®°°³›e57i µ¯¯¯¯®¯®¯¯¯®¯¯®®­®®¯®®®­®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®¯®¯®¯­®®¯®¯¯®¯®¯®®¯®¯®¯¯®¯«¦›h8I}¥±¯®¯®®¯®®¯®®­¯¯¯¯®¯¯¯¯¯¯¯¯¯¯®®¯®®®¯¯¯¯œO(}ª¯³¬x@ 7v”¯±®®®¯¯¯­¯¯®¯¯¯¯®­®¯®¯®¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯®¯®®®­®­¯®®¯¯®¯¯¯®¯®¯®®¯®®®®•hC7f ±¯®®¯®¯®¯¯¯®¯¯¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®±S ]—°¨‹B-r£©±¯¯¯®¯¯®®¯®¯¯­¯®¯®®¯®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®¯¯¯®¯¯¯®®¯®®¯®¯®®¯®¯®¯¯®¯®¯¬•i-Mœ²¯®®¯®®¯®®¯®¯¯¯­¯¯®®®®®¯¯¯¯¯¯¯®¯¯¯®®¯¯¡c !h‚vIGo£®¯°¯¯®¯®¯¯¯¯®®®®¯¯¯¯¯®­¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®¯¯¯¯¯­®¯®®®¯¯®¯¯®¯¯¯®¯¯®©t5 :—±¯®®¯¯­®®®¯¯®¯¯¯­¯¯¯®¯¯­¯®¯¯¯¯®®¯®¯¯®¯±‰A %+ Hƒ›³°¯¯®¯®¯®®¯¯®®®®¯®¯®®­­¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­­¯®®®®®­®¯­¯®®¯®¯¯¯®®¯¯®®¯¯®®¯®®°¨j++’®®®¯®¯¯®­®¯¯®¯¯¯®¯®®®¯®®¯®¯¯®¯®®®¯®¯®®¯q .K‰©­°¯®®¯®¯¯¯®®®®¯®¯®®®®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®®¯¯¯®®®¯¯®®¯¯®®®®®¯¯¯¯®®®®¯¯©v8‹«®®¯¯®¯®¯¯­¯¯¯¯®®¯®¯®®¯®¯®®®®¯®®¯¯¯®¯®¯­šb  6nˆª³®¯®®®®®®¯®¯®®¯¯®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯­¯®®®¯¯®®®¯®®®¯¯®¯¯­®®®¯¯®¯®®®¯«ŒQ¦®¯®®¯¯®¯®¯®¯®®®®®¯¯®®¯¯¯¯®¯¯­¯®¯®®¯¯®®°­’`$/Qz¥¦°°¯¯¯®®¯¯­¯®®¯®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯¯®¯®¯¯®®®®®¯­¯®®¯®®®®®®¯®¯¯¯®¦n_ ®¯¯®®¯¯®®¯®®®¯¯®®¯®®®®®¯¯®¯®¯®®®®®¯®¯®®®©ˆO'  *BzŒ¤³­¯®¯¯®®®®¯®®¯®¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­®¯®¯®®®¯¯¯®¯¯®®¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯®®}U™­¯®®®¯®¯®®­¯¯®®®¯¯®­¯®¯¯®¯®®®®¯®®®¯®¯®®¯¯±™rC,)).>X†®¬°°¯®®®¯®®®­®¯®¯¯®®®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®¯¯­¯®®¯¯®®®®®¯¯¯®¯®¯®®®®¯®®¯²‰/ J­¯¯¯¯®®®®¯®¯¯®¯®®®®¯¯¯®¯®®®¯¯®¯­®®¯¯¯¯¯¯¯°³µ~mnuty˜›«­²¯¯®®®®®¯®¯¯®¯¯¯¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®¯®¯¯¯®¯®¯®­¯¯®¯®¯®¯®¯®¯®¯®¯­®®²ECˆ¬¯®¯®®®®®®®®®¯¯®¯¯¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯®®®®®¯®¯°±³µ¨ §«¯¯²®°®®®¯®®¯®®¯­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯­®®®¯®¯®¯¯®¯®®®¯®¯¯¯®®®¯­¯¯®¯¯¯¯®®¯®®¯¯²‘P#=¬®¯¯¯®®®­®®¯¯¯­®¯¯®¯¯®®¯®®¯®®¯®¯¯®¯¯®®®¯®®®¯¯±°²¯±°°¯®¯­¯¯®¯¯¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯®¯®¯®¯®®¯¯¯¯¯®®¯®­®®­®¯®®®¯®®®¯®®®¯¯²‘N"6z«°¯¯®¯­®¯¯®®¯®¯¯®¯®®®®¯®¯®®¯¯¯®®¯¯¯¯®®¯®­¯¯¯®¯¯°¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯¯¯®¯®¯®®¯¯®¯¯®®®¯®®¯®®®¯®¯®®¯®®¯®®¯®¯¯®®¯¯¯¯®¯³‰3 1t«¯®¯¯¯¯¯¯®®¯®®¯®®®¯®¯®¯¯¯®®¯®¯¯®¯®®¯¯®¯®®®¯¯­¯¯¯¯¯®¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯­¯®®®®¯¯¯®®¯®¯¯®¯¯¯¯¯­¯®®®®¯®¯®¯®¯­¯¯®®¯¯­¯­®®¯®¯¯¯®¨x,o«®®®®®¯®¯®®®®®¯¯®®®®¯¯¯®®®¯®¯¯®®¯¯®¯¯¯¯¯®¯®¯¯­®¯¯®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯®®¯®­®®¯­¯¯¯®®®®¯®¯®®¯®®®¯®®®®®¯¯®®®¯¯¯®®®¯®¯®­®¬’W)kª¯®¯®¯®®®®®®¯®®®®®®®¯®¯¯¯®¯¯¯®¯¯¯®®®®®®®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯®¯¯®¯®¯¯®®¯®­®¯®®®®¯®®¯®¯¯®®¯¯®¯­¯®¯¯®¯®®­®®­®®®­£\ (iª¯®®¯®¯®®®®¯®®®¯®¯¯¯®®®¯­®¯¯¯¯¯¯¯®¯­®¯®¯®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯®¯®¯¯¯®®®®®¯¯¯­®¯®¯¯¯¯®®¯¯®¯®¯­¯®¯¯®¯®¯®®¯¯¯®¯°Ÿ/(i«®®®®®¯®¯®®®®®®¯®­¯¯¯¯®¯®®®¯®®®®¯¯®¯®®®¯®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®­¯­®¯®®®®®®®¯¯®®®¯¯¯­¯®®¯¯¯¯¯®®¯®®¯®®®®®®¯®¯®®¯®¯¬7'iª°®¯¯®®®®¯®¯®¯­®®¯®®¯¯®®®¯®®¯®®®¯¯®®¯¯®®®®¯®®¯¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®®¯®®¯¯®®¯¯®®¯¯®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯®®°¯¡t> (i«¯®¯¯®¯®¯¯®¯®¯®¯¯®®¯¯®¯¯®®¯¯®¯¯®®®¯¯¯¯®¯®®¯®®®¯®¯¯¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯¯¯¯®®¯¯®¯¯¯®¯¯°¯°¯¯®­­¬¬­®®¯¯°°°°¯°°¯®¯°°¯®«¤–x;(iª°¯¯®®®¯®®¯¯¯®®®¯¯®¯®¯®¯®®®®¯®®®®¯®®¯®®¯­¯®®®®®¯®®®¯¯®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯®®¯®®¯®­¯®¯¯¯­­­«©¥¡ ¡¡¥¦§ªª¬¬­¬­­­­®­­­ª¦™„U+n«°®¯¯®®®®®®¯®®®¯¯®®®¯¯¯¯¯®®®¯®¯­®¯®®®¯®­®®®¯¯®®®¯¯¯®®®¯¯¯¯®¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®®¯®¯¯®¯®®¯®®¯®¨Ž{`UKFCA@BEGHMOTX[cehnprof\PF;).r«¯¯¯¯®®®®¯­®®®¯®¯¯®®¯®¯®®­®¯­®®®¯®¯®®¯¯®¯®¯¯­®¯¯®¯¯¯¯®­®®®®¯¯®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯®®¯¯®¯®¯®®®®¯®©˜€W@$  $)*2653, 7{«°®­®®®¯®¯®®®¯®¯®¯¯¯®®®®®®¯¯¯®®¯®®®®®®®¯®®®®®®®®®¯¯®­®¯®®®®®®¯¯®¯­®¯®®¯®¯®¯¯¯®¯®®¯¯®¯¯¯®¯®¯®®¯¯®®¯¯®¯®®®®®®®¯®¯®®®¯ª•b"J­¯¯®®¯¯®¯¯®¯¯®¯­¯¯¯¯®¯®®®¯¯®¯¯®®®¯¯¯¯­®®®¯®®¯®¯¯®¯®®®¯­®¯®®®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®¯®®®®¯¯®®®¯®®¯®¯¯¯¯¯¯®¯®¯¯¯®®¯®¯¯®®¥Ecž­®®¯®®®®®®®¯¯¯¯®¯­®¯¯®®®¯¯¯¯¯®¯®¯®¯®¯¯®®¯¯­¯®®®¯¯®®®®¯®¯¯¯¯®®®®¯¯¯¯®®®¯®¯¯®®¯¯®¯®¯¯¯¯®®¯¯®®®¯®¯¯¯¯¯®¯®®®®¯®®®¯®®®©Š`Š©®¯®¯®®®®¯¯®®®¯®®®¯¯®®¯®®®­®®®®®®­®®®¯®®®¯®®¯®¯¯¯®®®®¯¯¯®®®¯®®®¯®®¯®®®¯¯¯¯¯®¯®®¯®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®®®®¯¯¯¯®®¯®¯®¯«šO)’¯®¯¯­®®¯¯®¯¯®¯¯®¯®®­¯®®®®­¯¯®¯®¯¯¯®®®¯¯¯­¯­®¯®®®¯¯¯¯®¯®®¯®¯®®¯¯¯®®®¯¯¯¯®¯®®®®®¯¯¯¯¯®¯®¯®¯­®­¯¯¯®¯®®®¯¯¯®¯¯®­®®®®¯š^$ :•¯®¯°¯®¯®®¯¯®®®®¯¯®®®®¯¯®®¯®¯®®¯®®®®¯®®®®®¯®¯¯®®®¯¯¯®®¯¯®®¯¯®®¯¯®¯¯­®®®¯¯®®®®­®®®¯¯¯®¯¯¯®®¯¯®®­¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®¬¥ƒ+ >§©¬®¯®¯®¯®®®¯­¯®®®®¯®®¯®¯­¯®¯®¯¯¯¯®®¯®®®®®¯­¯®®¯®¯®¯¯®®®®®¯¯®®¯¯®®®®¯¯¯®¯¯®®¯®¯®¯®¯¯®¯®¯¯®®¯¯®®®¯®¯®¯®®®¯®®®®¯°©‰] (CTgxŽœª°°°°¯¯®¯¯¯®¯®®¯®¯¯®¯¯®¯®¯®®®®®¯¯¯®®®¯¯®®¯®®¯®¯®¯¯¯®®¯¯¯¯®¯¯¯¯¯¯­¯®®®®®¯®¯¯®¯¯®®®®®¯®®®¯¯®¯¯¯®¯®¯®®®®¯¯¯±£]1$=Wi–¤«®¯¯®¯¯¯¯®¯®¯¯¬««­®°¯¯­¯¯®®®¯¯®®®¯­¯¯®®®¯®¯®¯®®¯®¯®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯¯¯®¯®®®¯®¯¯®®®®®®¯®®®¯¯¯®®­®®¯š:%@i€œ§­®®¯®¯®¯®®®¯¦£¢§«­®®¯®¯¯¯¯®®¯¯®®¯®­¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯®¯¯®®®®¯¯­¯¯¯¯®¯¯¯¯¯¯®­¯®¯®¯¯®¯®®¯®¯®¯§Œ$ "4Qm‰ž«¯°¯®®¯¯®«¢’|nr~–£¬±±¯¯¯¯®®¯®®¯¯®®®®¯¯®®®®®®¯­¯®¯¯¯¯¯¯®®®¯®®®¯®¯¯¯®¯®¯®®®®®¯®®¯¯¯®®®®®¯¯®¯®®®®”r *Rm‡• §­°¯¯¯®§•yc\\jz‹™¡ª­°®®®¯®¯®¯®¯®¯¯®®¯¯®®¯¯¯®®¯¯¯®¯¯®¯¯¯¯­¯®¯¯¯­¯¯¯¯¯®¯¯®®®¯¯®¯­¯¯¯®®¯¯®¯¯¯®~T>n¡­¯®¯®®®«¥‚Z$Pr𥝮®®®®®¯¯®®®®®¯®®¯®®¯­®®¯®®®¯®®¯®®®¯¯®­¯®®¯®¯®®¯®®­®¯®¯®­®®­¯®¯®¯¯®®®®¬b( ,Ll‘£°°¯¯¯­¡”xS.'=[Ÿ¬¯°¯®®®®®®®®®®¯¯®¯®¯®¯¯¯¯®®®¯¯®¯®¯¯¯¯®¯®¯®®¯¯®¯®¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯®¯¬£K'Z~•£ª®®¯°¯¨…Y(Hw£«°®¯®¯®®¯®¯¯®®¯®®­¯¯¯¯¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯®¯®®®®¯®®®¯¯®¯®®®¯®®¯®®°§’4 3z•¨®®¯®®­£}S>x­¯®®®®¯®®®®®¯¯¯®¯¯¯®®®­¯¯®®®®®¯®®¯¯®¯®®®®®¯®¯¯®®¯¯¯¯®¯®¯®®¯¯®®¯±œq">h¥­°®°­¢Žm= -S|¤¬¯¯®®®®¯®¯®¯®®®¯¯®¯¯®®¯¯¯®­¯­®®¯­¯®®¯®¯®¯¯®¯®®¯¯®¯®®¯¯®¯¯¯¯¯®°J '^‰Ÿ©®¯¯±ªŸn.Lˆœª­¯®¯®®®¯¯®®¯®®¯¯®¯®¯¯¯®®®¯®®®¯¯®­¯¯¯®¯¯®®¯®¯®¯®®®¯®®¯¯®®¯¯¯­„-a‰«®¯¯®¬¢†@$^”§±­¯®®®¯¯¯®®®®®®®¯®®®¯¯®®¯®¯¯®¯¯®¯¯¯¯¯®¯¯¯®®®¯®¯¯®¯¯®¯®®®®®¤r;s”¬®°°­¤„V&L}®°®®®®®®¯¯¯®®¯¯®¯¯®®®¯®¯®®¯¯®¯®®¯¯¯®¯®­®¯®®¯¯¯®¯®®¯®®®¯®¬‹U'g—©­®¯®­ŒP!Ey «¯¯¯¯®®®¯®®¯®¯®¯®®­¯¯®®®¯®®¯¯®¯®¯®®®¯¯®®®¯®¯®¯¯¯¯¯¯¯¯®¯ªo7 <Œ£®°®®©›\& +f–°°®®¯®¯¯¯¯¯®¯®®®­®®¯®¯¯®¯¯¯®¯®®¯¯¯¯®¯¯®®®¯®¯®®¯®¯­®¯¯¯¨P @mš§°¯¯¬e(&b‹¨¯¯¯®®¯®®®®®­®¯®®¯¯®¯¯®®¯¯­®¯®®¯¯®®®¯¯¯¯®®¯®®®¯®®®¯®¬¡9 (o“«®®®¯–\0#S”¨®¯¯¯®®¯®®¯®®­®®¯¯®¯¯®¯®­®®®¯®®®¯®¯®®¯®¯¯¯®®¯¯®®¯¯¯¦’( Q©¯­¯ª¢o/ Pzª°®®¯®­¯®®¯®®¯¯­®¯®®¯¯®®­¯­¯¯®®®¯®¯®¯¯­¯®¯®®¯®®¯¯¯œzO‹¢¯¯¯¯—v9 D¡®®¯®¯®®¯¯®®­®¯¯¯¯®¯®®®¯®¯¯¯®®¯®®­¯®¯¯®®¯¯®¯®®®°®Œ^Vˆ©®®¯®¦j-Cƒ£®¯®¯¯¯­®®®®®¯®®®¯®®¯¯¯¯¯®¯®¯¯¯­®¯®¯®­®®®¯¯®¯®¯°~? @‹¦¯¯®­ x" Eq¥°¯®­®¯¯®®®®¯®¯®¯¯®®­¯¯®¯¯®®¯®®¯®®®¯¯®®®®¯¯­¯¯¯oG…¤®¯¯®™k/5}𝝭¯®®¯¯¯®¯®¯¯®¯¯®®®®¯®¯®®¯®®®¯¯®¯¯¯¯¯¯®­®®¬¥`UЍ®¯®¬¡_Bu¨­¯®¯®®¯¯®¯¯¯¯¯®¯®®®¯­®¯¯®¯®¯¯¯¯¯®®®®¯¯¯®®°¦•MF–¦¯¯¯­”q3¦±®®®®®¯¯¯¯¯¯®¯¯¯¯®®®¯®­®®¯®¯®®¯®®®®®®¯¯®°Ÿ};R„©­¯¯¨˜T* >„¡®¯¯¯¯¯®¯­®®¯¯¯¯®¯®¯®®®¯®¯­¯®®®¯¯¯¯¯¯¯®®²˜`*O–¦°¯®«‰_S§®­¯®®¯®¯®¯®®®¯¯®®¯®®¯¯¯®¯¯®¯¯®®¯®¯¯¯®®±ŽC>®¯¯®©ŽM :Œ¢¯¯®®®¯¯®®®®¯®¯®®¯®®®¯¯®®®®¯¯¯¯®®¯®¯®¯°ƒ& S«¯¯°¤‡BIw¤­¯®®®¯¯¯®¯¯®¯¯¯®®¯¯¯®®¯¯®¯¯¯®­®¯¯¯®­¦rY¬¯®®«r@ A‡¢­®¯®¯¯®­®¯®¯®®®®¯®®®¯®®¯¯®®®¯¯¯¯®¯¬˜_f—²¯¯¯¢‰- 2|°¯¯¯®®®¯¯®¯­®®®¯®¯¯­­¯®¯­¯®­¯®¯¯¯ª‚Fnž¬¯®®£m? o¤¬¯­®¯¯­«©£ŒpM% Js«°²±®¯¯¯¦œ‘ƒvdPA.:€’ž¨­¯®¯°¯±²­¡Žl_J<0*($#  3b§®¯®¯®¯®¯®«ªª©§¥¢–Žƒ}tnjh`]]]]]]]]]]\]]\]]]\]\]]]]]\]]]]]\\]\]]\\\\\]]][]]]]]\]\]\]]]\]]]]]]\]]]]^]]\]]\]]\]\]_P Qj…šª°³°°±°¯°°°±°«¨¥¢žšš˜––––––––––—––—•––––•––—––•—––•–––––—•––•—•–——––•––——–––––––––•––—–––––––––––•—––––––˜ƒ-Cy—ž£©­®¯¯¯®¯¯¯¯±¯°°°±±±±²±°±°±±°±°°±±°¯°°°±°±°°±°°±°²°±±°±±±°°°±±°±±°°±°°°±±°±±±°±±±±°±°±±±±°°°°±±±°°±°±±²!?`w¡®¯®¯®¯¯®®®¯®¯®¯®¯®®®®®¯¯®¯®¯®®¯¯¯®®®¯¯®¯¯¯®®®¯®®®®®®¯¯®­¯®®®®®®®¯¯®®®¯®¯¯®¯¯¯®®¯¯¯®®¯®¯¯®®¯®®¯®¯®¯®±› !Nbm|†Ž™Ÿ¥ª®°²´··¸·¸····¹¸¸¸¸¸¸¸¸·¸¹¸¸¸¸·¸¸¸¸¸¸¸·¸¸¸¸·¸¹¸¸¹¸¸¸¸¸¹¸¸¸¹·¸¹¸¸¸¸¸¸·¸¸·¸¸¸¸¸¸·¸¸¸·¸·¸¸¸¸¸º¥" #-6@ELPUXZ\^a``a`_aa`aa```a``_a`````aa_`_````````a``aa`a`_a``a```a```a`a````aa_````a````a`a`````bS openigtlink-3.0.0/Examples/Imager/img/igtlTestImage5.raw000066400000000000000000002000001501024245700231250ustar00rootroot00000000000000 "#%&*())))))*&$#"   !$,7CN[gq{‚‹’˜Ÿ¢£§¬­¬¬¬¬¬­­¨£¡ž˜Šwl^RE4)"  .G]qƒ“ž£¤¦¥§¨©©ª««¬¬­­®­®­­­­®®­­¬¬¬«ª©¨¨¦¥¤ Ž€hP6(?Ufp{ƒŽ•œ¤«¯²±±²°¯°°°°¯¯¯¯¯¯¯®¯¯®¯®®¯¯®°¯¯¯°¯°±²²°®©£™…wkZE(  (@So‚—ª®±±±±¯¯®¯®­¯®¯®®®¯®­¯®®¯®®®¯®®®®®¯¯®®®¯®®¯®¯¯®¯¯°°°°±²ªœ‡gG4 $@e†— ¤§©«­®®®¯­¯¯®¯¯®¯¯®¯®¯®®¯¯®¯®¯®¯®¯¯¯®¯®¯­¯¯®¯¯¯¯®¯®®¯®®¯¯®®­¬©¦£˜‚\1>Xk}Š˜¦­°±°°®®­¯®®®­®®¯¯¯¯¯¯¯®¯¯®®¯®­®®®¯¯®¯®®¯®®®®¯®¯¯®¯¯®¯®®®­®®¯¯®®¯°°­¤”kN0 &A\š­±±°¯¯®¯¯­®®®®®¯®®¯®®®®®¯¯¯¯®®®¯¯®®¯®¯®®¯®®®¯®¯¯®®¯®®¯¯®®®¯¯¯®¯®®¯¯®¯¯¯¯°±°ªpI% Cq‘ž¦©¬®¯¯®®¯­®®¯¯­¯®¯¯®¯­¯¯®¯®¯¯®®®¯®®¯¯¯®¯®¯®®®¯¯¯®¯­®¯¯®®®®¯¯¯¯¯®®¯®¯¯®®®¯¯¯¯¯¯­«§¢k;FcxŠ©¯°°¯®®¯®®®®¯¯¯®¯®¯¯®®®¯¯®®®­®®¯¯®¯®¯®®®­¯®®¯®®¯®®­®¯®®¯®¯®¯®®¯®®¯®®¯®¯¯®®¯¯®®®¯®¯°¯©™„mF$ "?aŠ£°°°®¯®¯¯®®®®¯¯¯¯®­¯­¯®®®®®®¯®­®¯¯®®¯¯®¯­¯¯®¯¯­®®®®®¯®¯®®¯¯¯¯®¯®®¯®®¯¯®¯®®®¯®®®®®®®®¯®¯®®±¯ª†b5 "Lƒ™¥ª¬­¯®®®¯®®¯¯¯¯¯¯®­®¯®¯¯¯¯®¯¯¯®¯®®¯®¯¯¯¯¯¯®®®®¯¯¯®¯®¯®¯¯®¯¯®¯®®¯¯®®¯®¯®­®®®®¯®¯¯¯¯¯¯¯¯¯®¯®¯¯®®©£˜h? C\z¥®²°°®®®®¯¯¯¯®®¯¯¯®®¯­®¯¯®®®®®¯®¯®¯¯®®¯¯¯®¯¯¯¯®¯¯®¯®®¯®®®®®¯¯¯¯¯¯¯¯®®®®¯¯®®®¯¯®¯¯¯®¯®¯®®®®¯®®®¯®°°­™…eF.Q‡¯±¯®¯®®¯¯®®¯®®¯®¯¯®®®®®®®®®®®¯®¯®¯®¯®®®®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯®¯¯¯¯¯¯®®¯®®®¯¯®®¯®­®®®¯®¯¯¯®®®®®¯±®£‹Q)g‰£ª¬¯¯­¯¯®®®¯¯®®®¯®¯®¯¯®¯®®¯¯¯¯¯®¯¯®®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯­¯¯®®®¯¯®¯®®¯®¯®®®®¯­®®¯®®¯¯¯¯­¯­®­ªŸ['Vw—¦°±°®­¯­¯®¯¯®®®¯®¯®®®®¯®®®®¯¯®®¯®¯®¯¯¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯®®®¯®®¯®®®¯¯®®¯®®¯¯¯¯­¯°°£‘kF!^®°¯®¯®¯¯®®¯®®¯®®®¯¯®®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®¯®®¯­¯¯®®®®®®®®¯¯¯¯¯¯­®°®§}BX{™¥®¯®¯¯®®®¯®¯®®¯¯­¯®¯¯®¯®¯®®®­®®¯¯¯®®®®®¯®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯¯¯®®¯¯¯®¯¯®¯®¯®®¬¡f@6[Ž¥°¯¯¯®¯¯®®¯®®®®®¯®¯¯®®®®®®®¯®®¯®¯¯¯®¯¯¯¯®­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­®¯¯®¯¯®®¯¯®®®¯¯®®®®®®®¯¯®®¯¯°­–zG&D†§­¯¯¯®®¯®®¯®®¯¯®®¯¯®®®®¯®®¯¯¯­®¯®¯¯¯¯¯­¯®®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯®¯®®®®¯¯¯®¯®¯®®®®®¯¯¯¯¯¯¯­¯¯¯©œo*,\ަ­®¯¯®®®®®¯®¯¯¯®¯¯¯®®¯¯¯¯®¯®®®¯®¯¯¯­¯®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯®®¯®®¯®®¯®®¯¯¯®®®®®®®¯®¯¯®¯®®®®®®¯¯¯®ªŸƒK (l‘¬±¯¯®¯¯®¯®¯®®¯®¯¯­®¯®®¯¯¯®®¯®¯®¯®¯®¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯¯®¯®¯¯¯®­®¯®­¯­®®®¯¯¯®®®¯®¯¯®®¯¯®¯¯®®¯¯¯¯®¯®¯¯¯§…[%@|¢¯¯¯¯¯®®¯¯¯¯¯®®¯¯¯¯®®¯¯¯®®¯­®®¯®¯¯¯¯®¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯®®¯®¯®¯¯®¯®®®¯®¯®¯¯­¯®¯®®®¯¯®®¯¯¯®¯¯®¯¯¯®®®¯®®¯®¯›s6T¡«®®®¯®¯®¯®­¯®®¯¯¯¯¯¯®¯®®®¯¯®®®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯®®®®¯®®®®¯®¯®¯¯¯®¯®®¯®¯®®®®®®®®¯®¯®¯®¯®®®®®¯®¯®¯¯ªŸ~XOФ±¯®¯®®¯®®®¯¯®¯®¯¯­®¯®¯®®¯®®®¯®¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®®®®®¯¯¯¯®®¯®¯®¯¯®¯¯¯®®¯¯¯¯¯±¯¯®¯®¯®¯®®®¯¯¯­®¯®¯®¯¯®®®¯®¯¯°±¢U#Z‘«¯¯®¯®¯¯®¯®¯¯®¯®®®¯®¯®¯¯¯®¯®®®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯®®¯®®®®¯¯¯­®¯¯®®¯¯¯¯¯®®µ¯«ª³ª³¯¯°®®®¯®®®®®®¯¯®®¯®¯¯­¯®®®¯®®¯¯«i$!\‹¨®¯¯¯¯®®¯®¯®¯¯®¯¯®®¯®®®®®¯¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯¯®¯®¯®¯®¯®®¯®®®®®¯®¯¯­®°µ©–‘š‹‡ ¤­²¯¯®­®®®¯®¯®®¯¯¯®¯¯¯®®­®¯¯®¯¯®ª—}< TŽ¥±®¯­¯®®¯®®¯¯®®¯®¯¯®®®®¯¯¯¯¯¯®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®®®¯­®¯®¯¯¯®®®¯¯¯¯¯¯®¯¯®®®¯®¯¯®³³žyiZD;@M|…£´¯¯®®¯¯®¯­®®¯®®®­¯¯¯®¯¯¯®¯¯®¯¯­¦r> Y‰®¯®¯­®¯®®¯¯®¯¯®¯®®¯®®¯®®¯®®®¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯¯¯®¯¯¯¯¯¯¯®¯¯®®¯¯®¯¯®¯®¯¯¯¯³©c?1 )@s ª°¯¯¯¯¯¯®¯®¯¯¯¯®¯¯®®¯®¯®¯®¯®®®¯¤Ž6?¤¯®¯­­¯¯®¯¯¯­¯®®®¯®­®¯¯¯®­¯¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®¯®¯®¯¯®¯¯¯¯®®®¯¯¯¯®®®®¯¯¯¯¯¯¯¯®¯²¢€V*  1oœª¯¯®¯¯®®®¯¯®¯®¯¯¯¯¯®®¯®¯®¯®®¯®¬¦…H ;z©¯®®®®®¯¯¯®®¯¯¯¯®®¯®¯¯®¯®®®¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®­®¯®¯¯¯®¯®®®¯®®®¯¯®¯¯®®®®¯®¯¯¯®¯®¯®¢„W)7x ¯°®®¯¯®¯®¯¯¯¯®¯¯¯¯¯¯®¯®¯­¯®®¯¯®ª{B "tª¯¯®¯¯¯®¯¯®®®®¯®®¯®®¯®¯®®¯®¯¯®¯®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®­®®®®­®®®¯¯®®®®®®¯®®¯®¯¯®¯®®®®¯®¯®¯¯®¨e/M’¬°®®­¯®¯®®¯¯¯®¯¯®®®¯¯®®®®¯®®®¯®¯¥9 n–®¯¯¯¯¯®¯¯®¯®®¯¯®®¯®¯®®¯®®¯®¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®®®¯¯­¯®®®¯®®®®®¯¯¯®¯®¯¯¯®¯¯®®¯®¯¯®®­ªv3 '|¬°®®¯¯®¯¯®¯®¯¯¯¯¯®®¯®®®¯®®¯­¯®¯®¬¦}QI›¨°¯®­¯¯®¯¯¯¯¯®®¯®®®¯®¯®¯®¯®¯®¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯¯®¯¯®¯¯®¯®¯®­¯­¯®¯¯®®¯®¯¯®¯¯¯®®®®¯¯®¬‡4f«°¯®¯®®¯®®¯®®¯®®®®®¯¯¯®®®¯®®¯®¯¯°¯¡5 J{¬¯®¯®®¯®¯¯®®®®®­®¯¯®®®¯®®®®¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­®®®¯®¯®®¯¯¯®¯­¯®®®®®¯­®­¯®¯¯®¯¯®®®¯¯¯¯¯®®¯¯¯¯¡e(„©®¯®®®¯¯¯®®­­®­¯¯®®¯®¯®¯®¯®¯®¯¯®¯®®¢|5*ž¯¯¯¯¯®®®®®¯¯¯®®®®®¯®®¯¯®¯­®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®­®¯®®¯®®®¯®®®®¯®¯®®¯®¯¯®®®®®®®®¯¯®®¯¯¯®®­®®¯¯¯°šJ /•¬¯¯¯®¯¯¯®®¯®¯®®¯®¯¯®¯¯¯®¯¯¯®¯®­®¯®®« f0W›¯®¯®®®®®®¯¯¯®¯¯¯®®¯®¯®¯®®®®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®®®®¯¯¯­®¯¯¯¯®®®®®¯®¯®¯¯¯¯¯®®¯®¯¯®¯®¯¯¯¯®¯®®®¯®®¯¯ª„/fŸ°¯¯¯®®®®®¯®¯¯®®¯¯¯¯®¯¯®®®®¯¯¯¯¯®¯¯¯¯¯ŒeH¨°®®¯­®®®¯®¯­¯®¯®¯¯¯¯­®¯®®®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®®®¯¯¯®®¯®®¯¯¯®¯¯¯®®¯®¯¯®®®¯®®¯®¯¯¯®®¯®®¯¯®®¯®¯®¯¯­u& a™²¯®®¯¯®­¯®®®®®®®¯¯¯¯¯®¯®¯®®®¯®®¯¯®¯®¯¯ª›C,m¦¬¯¯®®¯®®®¯¯®®¯®¯¯®¯®¯¯®¯®®¯®®®®­¯®¯¯¯¯¯¯¯¯®®®®¯¯¯®®®¯¯®¯®¯¯¯®®®¯®®¯®¯¯®®¯®®®¯®®®®®¯¯­®¯¯¯¯®®®®®®¯®¯®®¯§r+ .SuK2$ 3d‹­®¯®®®®®®¯¯¯¯¯­¯®¯®¯®®¯¯¯¯®®¯¯®®®®®¯®¯®®¨{J]‹±®®¯®®¯¯®®®¯¯¯®¯®®®¯®¯¯¯®®®®®®¯®®¯¯¯¯¯¯¯¯¯®¯¯®¯®®®®®®¯®¯®®¯¯®­®®¯®®®®®¯®¯®®®®¯®®®®¯®®­¯¯¯¯¯®®®®®®®¯¯®®°¦fc¤«šxpZKa~“¦®°¯¯¯®¯®¯¯®¯¯®¯¯®®®¯¯¯®¯¯®®®¯®¯®¯®®®¯¯¯°®Ÿu8’¦¯®¯®¯¯®®®®®®®®®¯¯¯¯®®¯®­®­¯®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯­®¯®®¯¯­¯¯¯®¯®¯®®¯®®®®¯¯¯®®®¯®®¯¯®¯¯¯®­¯®®®¯¯®¯®¯©s,ƒ«±²§«™Ÿª©¯¯°®®¯®¯®¯¯¯¯®®¯®¯®®­¯¯®®®®¯¯®¯®®®¯®¯¯¯¯¯®¯”D&^¤¬®¯¯®®¯¯®®®®¯®®¯¯¯®¯®®®¯®¯¯¯¯¯®®®¯¯¯¯¯¯®¯¯¯¯®¯¯¯®¯¯®®¯¯®®¯®¯¯¯®®¯¯®¯®¯®®¯®¯®¯¯¯®®®®®®®®®¯®®®®¯¯¯¯¯¯®¯¯®¯¦s 3‚±¯±±±±±±¯¯¯¯®¯¯¯¯¯®¯®¯¯¯¯¯®®®®®®®¯¯®¯¯¯®¯®¯®¯¯®®¯®®¯¯¤~5O€­¯®®®¯®¯®®¯®¯®®®®¯¯®®®¯¯®®¯®¯¯®¯¯¯¯¯¯¯­¯®®®¯¯®¯®¯¯¯¯®¯®®¯¯¯®¯®®®®®®®®¯®®¯®®¯®®®¯¯®¯¯®®¯­®®®®®®¯®®¯¯®®¯®¯¯¨u"'®°¯®¯¯¯¯®¯®­®¯¯®¯¯®¯®®¯®¯®¯¯®¯¯¯®¯®¯®®®®¯¯¯¯®¯¯®¯®¯®¯­ŸV¢­¯®®¯¯®¯®¯¯®¯¯¯¯¯®¯­®¯®®­¯¯¯®¯­¯®¯¯¯¯¯®¯®®¯¯®¯¯®¯®®¯®¯®®®¯¯¯¯¯®­®¯®¯¯¯¯­®®®¯¯¯®¯®®®¯¯®¯®¯®®®®®¯®®®­®®¯®¯°°*q¡°°®®®®®¯®¯­®®¯®®¯¯®¯®¯®®­®¯¯®¯¯¯®¯¯¯¯®¯¯¯¯¯®®®®¯¯¯®®°¬w96”¬¯¯¯¯®®¯¯¯®¯®¯®®¯®®®¯¯¯¯®®¯®¯¯¯®¯¯¯¯¯¯®®®¯®¯¯®¯¯¯®¯®®¯®¯¯®¯­¯¯¯¯®®®®®®¯®­¯®®®¯®¯¯®­®®®¯®¯¯®¯¯¯®¯¯®®­¯¯®¯®¯­‹<*nœ­°¯¯®®®¯®®®¯®®¯®¯¯®¯®¯¯®®¯®®¯®¯¯®¯®®®®¯¯¯¯®­¯¯®¯®®®®¯­–l"b¡°¯¯®®®®®®¯¯®®®¯®®¯®®¯­®®®¯­¯®®®¯¯¯¯®®®®®®®®®¯®¯®¯¯®¯¯¯®¯¯®¯®¯®¯®¯¯¯®¯®¯¯¯®®¯®®®®®¯¯®¯®¯¯¯®®®®®¯¯¯¯¯¯®¯®®®¯«…8 a§®¯¯¯¯®®®¯®­¯®®¯¯®®®®¯¯®®¯¯®¯¯®¯®¯®¯¯®¯¯¯®®®¯®¯®®¯®¯®®¯ª)D©°¯®¯®¯¯¯®¯¯®­¯®®¯¯®¯¯®¯¯®¯¯¯®¯¯¯¯®¯¯®®­¯®®¯®®¯®¯®­®¯¯®®®®®¯®¯®¯®¯®¯®¯¯®¯®®¯¯¯¯¯®®®¯­¯¯®¯¯®¯¯­¯¯¯¯¯¯¯®¯®¯¯®°™@B–²¯®®¯®®®®®¯¯®®¯¯®¯®®¯¯¯®®¯¯®®¯¯®¯¯®¯¯®®¯¯­­®®¯¯®¯®¯®®¯°žW-b¤­®®®¯®®®­¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯¯®¯¯®®¯®®®®®¯­¯¯®®¯­®®®®¯¯­®¯¯®®®®®¯¯®¯¯¯¯®®®¯®®¯®®¯®¯®­­®®®®¯®®¯¯¯®®¯¯¯¯¯®­¯®®°ž] *t­³®¯¯®®¯®¯¯¯¯®¯¯®®®¯®®®®¯­¯®®®¯®¯®®®®¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯¯¦†S,u­®®®®¯®®®¯®­¯®®®®¯¯¯¯®¯¯¯¯®®®¯¯¯­®®¯®®¯®¯¯®¯¯®¯¯®®®¯®¯®¯®¯¯®¯®¯®¯¯¯¯®®¯¯¯­¯¯¯¯¯®¯®®¯­¯®®­®¯­®¯¯¯®®¯¯¯¯¯®®®¯¯­˜b#c™¯¯¯¯®®®®¯¯¯­®¯®¯¯¯¯®¯®®¯­®¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯®¯¯®¯®®¯¯®¯¬¢l WŒ¯¯¯¯¯¯¯¯¯¯®®®®¯®¯®®®®¯¯®®¯¯®¯¯¯®®¯¯¯¯®®¯®®¯®¯¯®®®¯®¯®¯®®®®®¯¯®®¯¯¯®¯®¯®®¯¯¯¯¯¯®®¯®¯®¯®¯­®®¯®®¯®¯¯¯®®¯®®¯¯¯®°°ž[Y¨°®®¯¯®®®¯®®®®®¯¯®¯®­®®¯¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®®¯¯®°„2}Ÿ¯®®®¯®¯®¯®¯¯¯¯¯®®¯­¯®®®®®®¯¯®¯¯­¯¯¯®®®¯¯®¯¯¯®¯®¯®®¯¯¯®¯®¯®®®¯®®®¯®®®¯¯¯®®¯®®®¯¯®¯¯®®¯­¯­¯¯¯¯®®¯¯¯¯¯®®­®®¯¯®¯±­s5Œ§¯®®®®®¯®¯®¯¯®¯¯¯­¯®­¯¯¯¯®¯®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®®®±–d)(˜¬¯®¯®®¯®®®¯®®­¯¯¯®¯¯®¯®®¯¯®®®¯¯¯®¯®¯®®¯¯¯®¯¯¯¯®¯®®¯¯®¯®®®­®®®¯¯®¯¯¯¯®¯®¯¯®¯®¯®®¯®¯¯®¯®®®¯®®¯¯®®¯¯®®®®¯­¯¯¯¯¯®°«‡5 j¨­®¯­¯¯®¯¯¯¯®®®®®®¯¯®®¯¯®¯®®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯°£?I¡¯¯®¯¯®­¯®¯¯¯¯®¯®¯®®¯®¯®®®¯®®¯®¯®¯®¯®®®®¯¯®®¯®®®®­¯¯¯®¯®®¯¯¯¯®¯®®®¯¯¯®¯®®¯®®®¯¯®®¯¯®­¯®®®¯®®®®¯­¯®­®®¯¯®¯¯¯¯®¯¯«C 3’±°¯¯®¯®¯¯¯®­¯®®¯¯¯¯®®¯®®¯­®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯¯®¯¯¯¯¯­¨\8j¦°¯¯®®¯¯®®¯¯¯®¯®®®¯­¯®®¯®¯®¯¯®®®®®¯¯®®¯®®®®­®®¯®®­®¯¯¯¯®¯¯®®®¯¯®®®¯¯¯¯¯®®¯®®¯¯®®¯¯®®­¯¯¯®¯¯¯¯®¯®¯®®®®¯®®¯®¯¯¯¯¯°”J a«¯°®­®¯®®®®®®®¯¯¯®¯¯®®¯¯¯­®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®­¯®®¯¯®®u/Y‰©¯®®¯®¯¯¯¯®­¯¯¯¯®®®¯¯­¯¯®®®¯¯¯®¯®®¯¯®®®®®®®¯®®¯®¯®¯¯®¯¯¯¯®­¯®¯¯¯¯®¯¯®®¯¯¯¯®¯¯®®®¯¯®¯¯®¯®®®¯®®¯®¯®¯®®®¯®¯¯®®®®¯®±¢e>‰±±¯®®¯®¯®¯¯¯®¯®®®¯¯­¯®¯¯®¯¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯¯¯®¯¯¯ŠSv¦¬®®®®¯®¯®®­¯®¯®®®¯¯®®®­¯¯¯®¯®¯®®®®¯¯®¯®®®¯®®¯¯¯¯¯®¯®¯®¯¯®®®¯®®¯®®¯®®¯®¯®®®®®®¯®®¯¯¯¯®®¯¯¯¯¯®®¯¯¯¯¯®®¯®¯¯®®®¯®¯¯®¦}0-i¥°°­®®®¯®¯¯®¯®®®®®¯­¯®¯¯¯¯¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®¯¡|„®®¯®¯¯¯¯¯¯¯¯®¯®¯®¯®®¯­¯®¯¯¯­¯¯¯®®®¯¯¯®¯®¯®¯®®­¯®®¯®¯¯¯®¯¯®®®®®¯¯®®®®®¯¯®®®®®®®¯¯®¯¯®¯¯®¯¯¯¯¯¯®®¯¯¯®¯®®®¯¯®¯®®®®¯¯§€; Yެ°¯®®®®¯®¯¯¯®¯¯®®¯¯®¯¯¯®¯®®®®­®¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®®®¯®®«-7±®¯¯®¯®¯¯®®®®®¯¯®¯®¯®¯¯®®®®®®¯¯¯¯¯®®®¯¯¯®®¯®¯®¯¯®¯®¯¯®¯®¯®¯®®¯¯®®¯®®¯¯®®¯®¯®®®®¯¯¯®®®¯¯®®®¯®¯¯¯¯¯®¯¯¯®®¯¯®¯®¯¯®®±¬‡;9z«®¯®¯¯®¯®¯¯®®®®®¯¯®®®¯¯®¯¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯­¯®®¯¯­®®®¯®®¯›H*Z—²®¯®¯®®®¯®®®¯¯®¯¯¯¯®®¯¯®­®®®®®¯¯¯¯®¯¯¯±°²¯®°®®¯®®®­¯®®¯®®®¯¯®¯®¯­¯®®®®¯®¯®®®®¯®®¯®¯®®®®®¯¯®¯¯®¯®®®®¯¯®®¯¯¯¯®¯®®®¯± Qd¡­¯­¯¯®¯®®®¯®¯®®¯¯®®®¯®¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®¯­®¯¯¯¯¢n1 X£³®®¯¯®¯¯¯¯¯®®®®®®¯¯¯®¯¯®®®®¯®®®¯¯¯¯¯¯®®®®¯¯¯¯®®¯¯®¯­¯¯¬¤_[¦¬¯¯®¯®®¯®¯¯®¯¯®®®®¯®®®®®®®®­®®®®¯®®®®ªk+ 1[…¨³°®¯¯®®¯¯¯¯®¯®®¯®®®¯®®¯¯¯®®¯®®¯­¯¯®¯¯®®®®¯¯®®¯¯¯¯®®¯¯®®®®¯­®®¯®¯¯®®¯®¬„H1®³®¯¯®¯®¯®®®®®®¯®®®¯®¯®¯®¯®¯­¯¯¯¯¯¯¯¯¯¯¯®®­®¯®®¯®®¯¯¯¯¯¯q k¬®®¯®®®®¯¯®®®®¯¯®®¯¯®®¯®®®®¯­¯®®®®®¯­®‘E 5e­³®¯®®®®¯¯®®®®¯®®®®¯¯¯¯®®¯®¯¯®®­¯®®¯¯¯®®¯¯¯®®¯®¯¯­¯®¯­®¯¯¯®®®¯®­®¯®®®³›K[›²¯¯¯¯¯¯¯®¯®®¯®¯®¯®®®¯®¯¯¯®¯­¯®¯¯¯¯¯¯¯¯¯¯®¯®¯®­®¯¯­¯®®¯°~/"v°®¯¯¯¯®¯¯®®®®¯¯¯®¯­®¯¯¯¯¯®®®¯®¯¯®¯®®®¯‘?A^¥«°¯¯¯¯¯¯®­®¯®®®¯®®¯®®®®®¯®®®¯®¯®®¯®¯®®¯¯®¯¯¯¯¯¯®¯¯®¯®®¯®­®®¯¯®¯¯¯¯¯®­pB¦³¯®¯®¯¯¯¯¯®¯¯®¯®®®®¯¯®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯®®®®®±‹L:°¯®¯¯¯¯¯®®­®¯¯¯®®¯®®¯®®¯¯¯®­¯®®®®®®®¯®›b={—­¯¯®¯¯¯¯¯®®­¯®¯®®®®­®®®®¯®¯®®®®®¯¯®®®®®®®®®¯®®¯®¯¯®¯­¯®®®®¯®¯¯¯¯¯®¯¯—7.n™¯¯®¯®¯®®¯®®®¯®¯­¯®¯¯®®­®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯¯¯¯¯¯¯¯˜n N‹¯¯®¯®­®¯¯®®¯®®¯¯®®¯¯®¯¯¯®®®®¯®®®¯®®®®°¥}EAˆ¥¯¯¯¯®¯¯®¯¯®¯¯®®®®®®¯®®­®®®®¯¯®¯®¯®¯®®®®¯®®®®®¯¯¯®­®®®®¯®®¯¯®¯¯®®®¯«–]S—§°¯®®¯¯®®¯®¯¯®¯¯®¯¯¯¯¯¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯¯¯®¯¯¢†&b•¯¯®¯¯®¯®¯¯¯¯¯®¯¯¯®¯®¯®¯®®®®®®®®¯¯¯¯¯®°®”Y f™§®¯¯®­®®¯®¯¯¯¯¯®®¯®¯¯®¯®¯®®®¯®¯®®®®®¯®®®®®®®¯®¯¯®®®¯¯¯®¯®¯¯¯®¯®®¯¯°šn,†¨­¯¯®¯¯®¯¯®®¯®¯¯®¯®¯¯¯®¯­¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯¯¯®®¬™/vŸ¯®¯®®®®®®¯¯¯®¯®®®®®®¯®¯®¯¯¯¯­¯®®®¯®¯®°°¥H-r¨°¯¯­¯¯®®®¯®¯¯¯®®¯®®®®®®¯¯®¯¯¯¯®¯¯®®®¯®®¯¯®¯®¯¯®¯¯¯®¯®¯¯®¯®®®¯¯¯¯¯«y/ T¥­®®¯®¯®¯®®®®¯®®®¯­¯¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®­£B …¦®®®¯¯®®¯¯¯®®®®¯®¯¯¯¯¯®®®®¯¯¯®®¯¯®¯¯­¯¯®¬t!8o›±®¯®®¯®¯¯¯¯¯®®¯¯¯®®¯®®®¯®®®¯®®®®¯­®®­¯¯¯®¯®¯¯®®¯¯®®¯®®¯®®®®®¯¯®®®µ•P)€³°®¯®¯¯¯¯¯®®¯®¯¯¯®®¯®¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯®®¯¦U’¬¯®®®®¯®®¯¯®¯¯¯¯¯¯®¯®¯¯®¯®®®¯¯®¯¯®®¯®¯¯®¬£W U¬°¯®®¯®®¯¯®¯®®¯®®®®¯¯¯¯®­®®¯®¯®®¯¯®¯­¯®®¯¯®®®­¯®¯®¯¯®®®®¯®¯®®®®®®°©wP¢´®®¯®®¯¯¯¯¯¯®¯¯¯®®¯¯®¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®¯§e)+›¯¯®®®¯¯¯¯®¯¯¯¯®®¯®¯¯®®®®¯¯®¯¯¯®®®®®®¯¯®®®±š@ 3€œ©°¯®®®¯®¯¯¯®¯®®¯®¯®¯®¯®®®®¯®¯®¯®­®®®®®®®®®®®­¯®¯®¯®®¯¯®®®¯­¯®¯®®¯­‡D>z®±®¯®¯¯¯®¯¯®®®¯®®®®®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®©w:6Ÿ°­¯¯®¯¯®®¯®®®®®¯®¯¯¯®¯¯¯®¯®¯®®®®®¯®®¯®®®¯®¯v :p‹­±¯¯®¯®¯¯®®¯®®®®¯®®¯¯¯®¯®¯¯®¯¯®®®¯®¯®®®¯¯¯®®¯®¯®¯®¯¯®¯¯¯®­¯®®®®°¬“Y2b›±¯®®¯®®¯¯®¯®®®®®®®®®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯¯°ª…J B ±¯®¯®®®¯¯¯¯¯®®®®¯¯¯¯¯®¯¯®¯®¯¯®®®¯¯®¯®­¯®¯®­£S=d˜°¯°®¯¯®¯¯®®¯¯¯®®®®¯®¯®¯®¯¯®®¯¯¯¯¯¯¯¯®®®¯¯¯®®¯®®®¯¯®­¯¯®¯¯¯¯®®®¯®¥d#_‹©°¯®®®®¯®®¯®¯®¯®®®¯®¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯«’XQ£°®¯®®¯¯¯­­¯®¯®®®®¯­¯®¯¯®®¯¯®¯¯¯®®®¯®®®®®¯¯­°™P'Myœµ­±´­±®®¯®¯¯¯¯®®­®®¯®®®¯®®®¯®®®¯¯¯®¯¯®®®¯®®¯¯®®¯¯®®®®¯¯¯®¯®¯®®°¯„.?¤±®¯¯¯¯®®®¯­®¯®®¯®®¯¯­®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯¯­žf)]¢¯¯¯¯®®¯®¯®¯®®®¯¯¯®¯®¯¯®®¯®¯®®®¯®¯®¯®¯¯­¯®¯¯®²-&E^— ³¥²«®µ®³¯®¯®®¯®®®®¯®®®¯¯®¯®¯®¯®¯¯¯®®®®®®®¯¯¯®®®®¯®®¯®¯®¯¯®®®¯°¨V j£®®¯¯¯¯®¯¯¯¯®®®®®®®¯¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯­®¨o2f¤°®¯®®¯¯¯¯¯¯®®®®¯¯¯¯®¯¯­®®¯¯®®¯¯®¯®®®¯¯®¯®®¯¯®¥R Pˆwe~€ˆ¡¡¯°¯¯¯®­®®®®®¯¯®¯¯®®¯¯¯®®¯®®¯®¯®¯®¯®¯®¯®¯®¯¯¯®®¯¯¯¯®®®®°«†+;ª±¯¯¯®®¯¯¯®¯¯®¯¯®¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯­®x =q¥°¯¯¯¯¯¯®¯®®¯¯¯¯¯¯®¯¯¯¯®¯®¯¯­¯®¯®¯®®®®¯®¯¯®®¯­£†.1").=ayˆ´¯¯°¯®®¯®¯­®®¯®¯®®®®¯¯®¯®®®®®®®®®®¯®¯¯¯®®¯¯­®¯®®­®®¯®¯§“T c¨²®®®®®¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯±~ Cx¦¯®®­¯®¯¯¯­­¯¯®¯®®¯¯¯¯¯¯¯®®¯®®®®¯®®®®®®®¯¯¯¯¯±¨¤x ,Cˆ¡«°®¯®¯®®­¯®®¯¯¯¯®®®¯®®®¯®¯¯¯¯®¯®®®®®¯®®®¯¯¯®¯®®®¯®¯¯­“g& >«±®¯¯®¯®®¯®®¯¯®¯¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®±€ I}§¯®®¯®¯¯¯¯®®­®®®®®¯¯¯¯¯¯¯®®¯¯¯®®¯¯®®®®¯®­®¯¯¯¯®©–I C€¡«±¯®¯¯¯®¯®¯¯®¯®¯®®¯¯®¯®¯®¯®¯®®¯¯®¯®®®®¯®¯¯¯®¯®®¯®¯¯²¡n73o¡°®­¯®¯®¯¯¯®®¯¯®®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®®²„! N„¨°¯®¯¯®®¯®¯¯®®¯¯®®¯¯¯¯¯¯®®®¯®¯®¯¯®¯¯¯®¯®¯®®¯®®¯«–XQ‹£¯°®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®¯­®®®®®®®¯®¯®¯®®®¯®®®¯®¯°±‰< Z˜ª¯®¯¯¯®¯­¯¯¯¯¯®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®±„# R‡¨®®®¯®¯®®®¯®®¯®¯¯¯¯¯¯¯¯¯­¯®¯­®¯¯¯®¯®¯¯®¯®®¯¯¯®®±Z$h¦­¯¯®¯®®¯®¯®®¯¯®®¯®®¯¯¯¯¯®®¯¯¯­®®¯®®¯¯®¯¯®¯®®®¯®¯¯®¯´«\DŒ©®¯®¯¯¯®®¯¯¯¯¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®²„#X©°¯®¯®¯¯®®¯¯®¯®¯®¯¯¯¯¯¯¯­®®¯®®¯¯®®®¯¯®®¯­®®¯¯¯®±«u %>N`fN*B–°®¯®¯®®®®¯®®®¯­¯¯¯®®¯®¯®¯®®¯¯®¯¯¯¯®®®®®¯®¯¯®¯¯¯®¯¯¯¯®2lª®¯®®¯¯®®®®¯¯®®¯®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯°ƒ"XŽ©¯®®®¯®­®¯¯¯®¯®®¯¯¯¯¯¯¯¯®¯®®¯¯®¯¯®®¯¯®¯¯®¯®¯¯¯®®¬“B /gŽ«œsU,m°²¯®®¯®®¯¯¯®®¯¯®¯¯®¯¯®®¯¯¯®®¯¯®®®¯®¯®¯¯¯¯¯¯®¯¯¯¯®¯¯¯«¤[D“³¯®­¯¯¯®¯®®¯®®¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯²€\©¯®®®®¯¯¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®®®®¯®¯®¯¯¯¯¯®¯®¯°­„2!6a›¬²¶£Ša I–³¯¯­®®¯¯®®¯®®¯®¯®¯®®¯®®¯®¯¯¯¯®®¯¯®®¯®¯®¯®®®¯¯®¯®¯®¯­šx5&mª³®®¯®¯®¯®¯¯¯®¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯­¯¯­y`•ª¯®¯¯¯¯®®®¯¯¯®®®¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®¯¯®®¯®¯¯®¯­¯®¯¯–JDt?-u™¯±±§{8 Aƒ©¶±¯³°¯®®®®¯®¯¯¯®¯®®®®®¯­¯¯¯¯®¯¯¯¯®¯¯¯®®®¯®¯¯¯¯¯¯®®°£„ER±¯¯¯¯¯®¯¯¯¯¯®®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®­¤la˜«°®®®¯¯®®¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®¯¯¯®¯¯®¯®®­¯®®°~2%m•z. Aœ¯±­6 ;t’¥™°©µ±¯°¯®¯¯¯®¯®®¯¯®¯®®¯¯¯¯®¯®®¯¯®¯®®¯®®¯¯®¯®¯¯¯¯®°²‘RBz¤²¯®®¯®¯¯®®®®®¯®¯®®¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®«•Zdšª®¯¯®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®®®¯®¯¯­¯®®®­¯®¦v' > ¨^Rƒ§³´+OeTSqyœ¨­²¯¯®¯®¯­®®®­®®®®¯®¯®¯¯¯®¯¯®®®®¯®¯®­®®®®¯¯¯¯®´§o!-u›­¯®®¯®¯¯®®­®®®®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯«‡Jb˜ª°®®®®®¯®®®¯­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®­¯¯¯®¯¯®¯®­¯°ŸaY£±¡K l–¨“S#1P}ަµ¯®®®®­®¯¯®®®¯¯®®¯¯¯®®®®¯®¯¯®¯¯®®­¯¯®®¯¯¯¯®­µ•AZ—ª¯¯®¯¯®®®¯­¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯©u7\’ª°¯¯¯¯¯¯®¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯®®®¯¯®¯®¯¯­®°¢ad¦´«£|0 8ly^&-A}¤ª°¯¯­¯¯¯®¯¯®¯®¯®¯®¯¯®®®¯®¯®®¯®­¯¯®¯¯®®­¯­¯®²ªm-‰°¯¯®®¯¯®¯®®¯®®¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯§d&YŽ©¯®®­®¯­®¯¯¯®¯­¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯¯¯®®¯®®®¯®¯¯¯¯¡^T˜²²¨—k2A* 8y«°¯®®¯¯¯­¯®®®®®¯¯¯®®¯¯¯®¯®®¯®¯¯¯®¯¯®¯®®®¯¯®«ŒC \¥®¯®®®®®®®®¯®¯¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¦UWŒ©°¯¯¯¯¯¯¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®¯¯®¯¯®®¯¯®¯®¯žZQˆ¥µ°«ˆ: ?‚¢¯¯®®¯¯¯®®¯¯®®®¯®¯¯­®¯®®¯®¯¯®¯®®¯®¯®®¯¯¯®¯¯­™^ 9‚³±®®¯¯®¯¯®¯¯®®­¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¤E Q‡©®®¯®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯®®®®¯¯¯®¯¯®®®°¨n 8nŽ«¶—i<  '36RFC: \”­®¯¯¯¯®¯®®¯¯¯®¯®®¯­­¯®®®®®¯®®®¯¯®¯¯¯®¯®®¯¯¯¢q0(a£±®®¯¯®®¯¯®¯®®®¯¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯¯®¡6 K€¨°¯¯¯¯®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯®®®®­¯®®®¯®®®®–1\ˆ¬°¯®®®®®®®®¯®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®«˜. Ex¦°¯®¯®®¯¯­¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯¯¯¯¯¯®®­¯®¯®®¯¯¯­™p#!0v˜¢©³°°µ¬˜uSN𴝝®¯¯¯¯¯®­­¯¯®®®®¯­¯®®­¯®®¯®®¯¯¯¯®¯¯¯®®¯¯±¦bC{¥°¯®®®¯­®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¨*;n¥°¯®®®®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯­¯¯®¯®¯¯¯®®¯®¯¯®¯®°®¥˜U P«°°±®±¯³¯–J |«´¯³¯°±°¯¯­¯®¯¯®¯®¯®®¯®¯¯¯¯®¯¯¯¯®¯¯¯®®®®®¯°°0v ­®¯®®¯­¯¯®¯®®®®¯¯­¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯«™00b¤±®¯¯¯¯®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®®¯¯®®¯®¯®®¯¯®®®¯¯­£E  8i—³°®¯®¯°°ª˜d,Zž¨¯¬¨³¨³¯°¯¯®®®®®®¯¯®¯®¯®¯¯¯®¯¯¯®¯¯¯­¯¯®®®¯¯cC—¯¯¯®®®¯¯®®®®¯®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯® G"S¡±®®®¯®¯¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®®®¯®®¯­®¯®¯¯¯®®¯­­@' M_ABv¤²®¯®¯­¯² w@Gft€wq‚~–¤«°±°¯®®®¯®®®®¯¯®¯¯°±¯²¯²°¯¯¯®­¯¯®¯®¡ƒ2t®±®¯®¯¯®®®®®¯®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯¨k, BŸ±¯¯¯¯¯®¯®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯®®®®¯®¯®¯¯®®¯¯¯±«‰T?"f•k- R†«±¯®®­®±ª‚%"2,**-Lb{¦©°°¯®®®®®¯®¯±¯³­­©°¤¨°©²°°¯¯¯¯¯¯°«…N A—°²¯®¯¯®®®®¯¯®¯¯¯®®­¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¬–_1œ°­¯¯¯®¯¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯¯®®®¯®®¯®¯¯³°t4 SŠ®¨ˆ[*d”¯°¯®¯®®ªz+/oޤ±®®¯¯®®¯¯²ª­¤–rqt}Š•©­°±¯®¯¯°³—c!/u©±®¯¯¯¯®®¯¯¯®¯®¯®®­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®«|# —®®¯®®¯¯®¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®®®¯®¯®®¯®®®®®°°­ŠK 2z¤°²ŸC;s¡²¯®­±³šW)aˆ¨³®®®°°²¯žˆf;6/ $#&:Pv‚§±®¯¯®®¯°~-%\˜­¯¯¯¯®®®¯®¯¯¯¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®±“Y'Ѝ¯¯¯®®®®®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®¯¯®®¯®®¯®¯¯®¯®±©{(f¦°¯±¯”i1N€§²®¯®¡l"'.f®°®°±µ£Šn_5 +B…ª°¯®¯®®·žQ J‹«®¯¯¯­¯¯®®¯¯¯¯®®¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®°¦“LwŸ®¯®®®®®¯®¯®­¯®¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®®®¯¯®¯¯¯®¯¯®®¯®¯®®¯šN 4¯°¯¯²¨‰N#T°±­w0 "DKgzth_/ ?v³²³³jN5*h¤¯¯®¯¯®­°€&*x¨­¯¯¯®¯¯®¯®¯¯¯®®®®¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯­¬l' `“°¯®¯®¯®¯¯­¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯­­¯¯¯®¯®¯®¯¯¯®®®¯®¯¯‘E O—°®¯®¯³ qA*g™±ž„A7_w“®ª­ ¡|._“­·¢uF1 <„¬¯¯¯¯¯®®®›N S™³¯®®®®¯¯¯®®¯¯¯®®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯¯®¯hGˆ±¯®®®®®¯®®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯®®¯¯¯¯®¯¯®¯®®¯¯9d§®¯¯¯®²­”h* :q–BKl¦µ±²°²µ§f<ˆªŽY+Bˆ¯®¯¯¯¯®¯®«p()|®°®®®®¯¯¯¯®¯¯­¯®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯­¯¯®®§–?'}¯¯­¯¯¯®¯®®¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯®®¯®®¯®®¯¯®¯®¯®¯°®2e¦±°®¯¯¯²«„T"DT2 Mr™®²¯¯¯¯°°°)`p?P’­®®¯¯¯®®¯®¯¦ƒ>Z—´¯¯®¯¯®®¯¯­®®¯¯®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯®¯®­®®¯®®¯±«h+m±¯¯®­¯®¯®¯¯¯­­¯¯¯¯¯¯¯¯¯¯¯¯¯­®®¯¯¯®®¯®¯®¯®¯¯¯¯¯­¯®°¯>P”³°®¯¯¯°³¢z<Ex¡²°®¯®®¯¯¯­…5)P”¥­¯®¯¯¯®¯¯®±®‘NA«°¯®®¯®®­¯­¯¯¯¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®¯¯­™cY¥¬°®¯¯¯¯®®®­¯®¯®¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯¯¯®¯¯¯®¯¯®¯®­¯®¯ªˆJ F…¥²°®®®±²¯ŠW=©³¯®¯¯±°±®°«{-D ­¯®®®¯®¯¯®®¯±¨q*xœ­¯¯®®¯®¯®®¯®®®®®¯®¯¯¯®®¯¯¯¯¯¯¯¯¯®®®¯¯¯­®¯¯¯®«†; K’¦°¯¯®¯¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯¯®¯¯¯®¯¯®¯®¯®®¯¯®®¯¯®Œ2 -r•­²¯¯´¬¦›ƒAB‡³°®¯®®³®­®²²§u0y¡¯¯®®®®¯®¯®®¯®°±—@ \”¬®­®¯®®¯®®®¯®®®¯¯®®¯¯®¯®¯¯¯¯¯¯¯¯¯®®¯¯®­¯®¯®¯°p(8rž±¯¯®®®­®®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯¯¯®®®­®®¯¯®¯¯¯®¯°±¡K Gz•³«°¨{c; 4ƒ°®¯­¯±´ª›”ˆ–E-w£´±®®®¯¯®®®®®¯¯®°©s)®­®®®®®¯¯®­®®®®®®®®®®®¯¯¯¯¯¯¯¯¯¯®®®¯¯®¯¯¯®¯®®¬¢OL•±¯¯¯®®­­¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯®­®¯¯®¯®®¯®®®®¯®®®¯®®¯°¦€"Fg„‰†eK9 H‘¯¯¯®±¯ŸsRQ=>K3l˜±®®®¯¯®¯®®¯¯¯®¯®®¬J]¥¯°®®®®¯¯®¯®®®®®®¯®®®®¯¯®¯¯¯¯¯¯¯®®¯­®®­®®¯­¯®¯­K )Н®®¯®¯¯¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®¯¯®®¯¯¯®®®¯®¯®®®®¬¡] 8A,1t«³¯¯«–Z >{¨­®­¯¯®®®¯®¯¯®®®®®®˜k -ˆ±±¯®®¯®¯®¯®¯¯¯¯¯®®®®¯®¯¯¯¯¯¯¯¯¯­®¯¯®¯¯­¯¯¯®®¯¯~!«®®®®¯®¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®­¯®®®®¯¯®¯¯¯®®¯®°¯¤‘H$2 B‹¯¯¯žd i£¯®®¯¯®®¯®¯¯®¯¯®®®¯°¦w= $c¢±°®®¯¯®®¯®®¯®¯¯®®®®®®¯¯¯¯¯¯¯¯¯®¯®®®¯¯¯®®®®¯®®®ŸKPœ«°¯¯®¯¯¯¯¯­®®¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯¯®®¯¯¯¯®¯¯®®¯®¯®¯­ªŒ5#4\zHV—¶¯œGW ®°®®®®¯¯¯¯¯¯®¯¯¯®®®°³ŽV$T‹®°®®¯¯®®¯®®¯¯®®¯¯®®®®®¯¯¯¯¯¯¯¯¯®­¯®¯®®®¯®®¯®®°©yK-|§¯®¯¯®®®¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯®®¯­¯¯®¯­®®¯®®¯°¯¨}9& (D[„«®§A$m¨°^8‹£¯¯¯®¯®®¯­¯¯®¯®®®¯®®¯°ªp$ H§®¯®¯®®¯¯®®¯¯®®¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®¯¯¯®¯®¦|V¤¯®¯®¯¯¯¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯¯®®¯­®­¯®¯®®®®¯®®®¯¯³®xX4Hb€ž¶°±µ¦o0=‚­¤5 b›¯¯®¯¯¯®®¯¯¯®¯¯¯®®¯­¯®°¶˜E &y¢®¯®¯®®¯¯¯®¯¯¯¯¯®®®¯®¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®®¯¯¯­®¯®­–^0œ­®¯¯®®¯®®®¯®®¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯¯­¯®¯®®¯¯¯¯®¯®¯¯®®®±³¥v/ /^w—¬µ¯®¯±³—V!N˜¯Ÿ‡?' Q°±®®®®¯®¯¯¯¯¯¯®¯¯®®¯¯®¯±¯zSœ²®®®¯®®®®¯¯¯¯¯®¯®¯®®¯¯¯¯¯¯¯¯¯®®®¯¯¯®®¯®®®®®¯¯­¯¦ŽC †¥®¯¯¯®¯®®®®¯¯¯®®¯¯¯¯¯¯¯¯¯¯®¯®¯®®­®¯®¯­¯®¯®®¯®®¯®®¯¯°¥j)3bˆ£³°°®®¯±´¬„9a¤³²ŒrY# 2r§®®¯®¯®¯®¯¯¯®¯¯®®¯¯®®®¯®®± K!‚­±¯®¯­®®®¯®¯®®¯¯®®¯¯®¯¯¯¯¯¯¯®¯®®®®¯®¯®®®¯¯®®¯¯®°«l:\¯®®¯®­¯®¯¯¯¯®¯®¯¯¯¯¯¯¯¯®®¯¯®¯¯®®¯®¯®¯¯¯¯®¯¯­®­®®®¯±[!W«³¯¯®®²²¯®¹¦h% *x®´¬ª’d* H–­¯®®®¯®¯¯®®®¯®¯¯®®®¯®¯®®°¬£}(V³°®¯®¯®®¯®¯®®¯®¯®­¯¯¯¯¯¯®®®®¯®®®¯¯®¯®¯®¯­®¯¯®®¯­š{.z­®®®¯®®®¯¯¯¯®®®¯¯¯¯¯¯¯¯®¯¯®®®¯¯®¯¯¯¯¯¯¯­¯®®®®¯®¯®¯§z& C²°¯¯¯®³¯£‹˜¥­—T@´²±³™O+ƒ«¯¯®¯®¯®®¯¯®­®®®¯®¯­®¯­®¯¯¯¥’O?†©±®®¯®®®¯¯¯¯®­®®¯­¯¯¯¯¯¯¯®®¯®®¯¯¯®¯®®®¯¯®¯®®¯¯¯®­œN [©®¯­®®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯®¯®¯®®®®¯®­¯¯®®®­¯®®¯¯¯®®¯¯ _)l­®¯¯®¯±¨YEPo¬†7ZŸ¶±¸žN_𬝝®®¯®¯®®®®¯®®®®¯¯¯®¯®¯®®°¬“m0 =vŸ¯°¯¯®¯¯¯®¯¯®­®®¯­®¯¯¯¯¯®¯¯®®®¯¯¯¯®®®¯®®®¯¯®®¯®¯¯©ˆQ/ލ¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯¯®®¯®¯®¯®¯¯®¯¯¯¯®¯–K <Œª¯¯¯®®¥~:<©¤p# !v­³šp00w©°®¯®­¯®¯¯¯¯®®®¯¯¯®¯®®®¯¯®¯¯°£~E'j¢­¯¯®¯¯®®¯¯¯¯®¯¯®¯¯¯¯¯¯¯®®¯®¯¯®®­®®®®®®®®®®®­¯®¯¯­©0b¡°®®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®®®®®¯¯®¯®®®®¯®¯¯¯®±‚5P™±®¯¯®©ŽH\¤·žP;~…eK^˜³®®¯¯­¯®®¯¯¯®¯®®¯¯®¯¯®¯¯¯®¯®°²‘X$ M™­®¯®¯¯¯®¯¯¯¯®¯¯®¯¯¯¯¯¯®®¯®®®¯®¯®®¯¯¯®®¯¯®®¯®®®®®¯²ši#•®®¯¯®®®®¯¯¯¯®¯¯¯¯¯¯¯¯®®¯¯­¯®¯®®®¯¯¯®®®¯¯®¯®®¯¯¯®ˆ,jž®®®®¯©k&C“¸­…: 0@/2{ª®¯¯¯¯®¯®®®®®®¯¯¯®®¯®¯¯¯®®®¯®®²«x2 $y¯±®¯¯¯¯®®¯¯¯¯¯¯®®®¯¯¯¯®¯¯®¯¯®¯®®¯¯¯®¯¯®¯¯¯¯¯¯¯®¯®®ª˜-y ®¯¯®®®®®¯®®®¯¯¯¯¯¯¯¯¯®¯¯®¯®¯¯¯¯¯®¯®¯®­¯¯®®®¯¯°¦€+[Ÿ±¯°±®’E  =Š­´ªk"  R®®®¯¯®®¯¯®®®®¯®®¯®®¯®®®¯®¯¯®®¯®·œRS›²¯¯¯¯®¯®®®®¯®®®®®¯¯¯®®®®®®¯®¯®¯®®®®®®¯¯®®¯®®¯®®®¯®¥FRƒ¬¯¯¯®¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®¯¯¯¯®®¯®®®¯®®®¯®°©~,)¥¤¶®±|:I‘ª³µ›F 9“¬¯®®®¯¯®®®®¯®¯¯¯®®®®®®®¯®®¯¯®¯¯®±³ƒ, <€ª²®¯¯¯¯¯¯®¯¯¯®®¯®¯¯¯¯¯¯®®¯®¯¯¯®­®¯®®¯®¯®®®­¯®®®¯¯¯ªZ%X§°¯¯¯®­®®®¯®¯¯¯¯¯¯¯¯¯®®¯¯®¯®¯®¯¯¯®¯¯¯¯®¯®®¯®®¯±‹9;p}““[5‹²³®‘J!k™¯¯®¯¯®¯®¯¯®¯®®¯¯¯¯¯®®®®®¯¯®®®®­¯®´¥_-q¡°¯®®¯¯¯¯¯®®¯®®¯¯¯¯®®®®®¯®®¯¯¯¯­®®®®®®®®®®®®¯®¯¯®¯©b.4—¦¯®®®¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯®¯®®®¯®¯¯¯®¯¯®¯¯±›Y '7?\> b¢™…b0 TŒ«¯®®­¯®®¯®¯®¯®¯®¯¯®¯­®¯®®¯¯¯®®®­®®­­Š:_ ­¯®®®¯­¯¯®®¯®®®¯¯¯¯®¯®¯¯®®®®¯®®®¯¯¯®¯®®®¯®¯®¯¯®®°ªX$k“°®¯­®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®­®®®¯®®¯¯¯¯®®¯®¯®¯¢v9 ,YQB/ "X­±¯¯¯®¯®®¯¯®¯¯¯¯¯¯¯®¯®®¯®¯®®®®®¯¯®¯®ªžd7‘­°®¯®¯®®¯¯¯¯®®¯¯¯­¯¯¯¯®¯®®¯®¯¯¯¯®¯¯¯¯®®®¯®®¯¯¯®¯¯£D#s­®®¯®¯¯®­®¯¯¯¯¯¯¯¯¯¯®®®¯¯­¯­®¯®®®¯¯®®­¯®­¯®®¯¬[&   $+Ctš²°¯®¯®®¯®¯®¯®¯®¯®¯¯®¯¯®¯®¯®®®¯®®¯¯®®¯­ ‚F m­±®¯®¯¯®¯®®¯®®¯¯¯¯­®¯¯®¯®®®®¯¯¯¯®®¯®­¯¯®®®¯­¯¯¯°¨&Q›©¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯­®¯¯¯­®¯¯®¯¯­­¯¯¯¯®°¯¥†XBGUQE`oq”©³®¯®¯¯¯®®¯¯¯¯®¯­®¯­¯­¯®®¯®¯®®®¯¯¯¯®®®¯±§”_'N–®¯¯¯¯¯¯¯®®¯®¯­¯¯¯®®¯¯¯®¯®®®¯®¯®®®¯¯¯®®¯¯¯®¯¯¯¯³“R +t£±®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯­¯¯®¯¯®¯®®®¯¯­¯¯®®®¯¯°¡ˆRA{˜š•›¢¡¦¶°°®¯®¯¯¯®®¯®¯¯®¯¯®®­¯®¯¯®¯­­®®¯®¯¯¯¯®¯®°°žuDH…¬¯¯®¯®®®®®¯®¯­¯®®®¯®®¯¯®¯¯®®®¯¯¯¯®¯®¯®®¯¯¯¯¯¯ª”g3­¯®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®¯¯®¯®¯®®¯®®®¯®¯¯¯¯®ª’@ E‘µ´°°¯¯³¯¯¯®®¯®®®¯®®®®®¯¯¯®®®®®¯®¯®®¯®¯®¯¯®®¯¯®¯®²«ŽQ!5‚¬®¯¯®¯®¯¯¯®¯®¯®¯¯­¯®­®®®®¯¯®¯®¯®¯¯®¯®­¯¯¯­®¬¥•U)Y˜®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯¯¯®¯®­®¯®¯®®¯­®®°´°‡<@‚­³¯°¯°®­¯¯®­®®®®®®¯®®¯¯®¯¯¯®®­¯®®¯¯¯¯®®­¯¯­®®®¯®¯´¦l/n§³®¯®®¯®¯®¯¯®¯®®¯¯¯¯®®®®®¯®®®¯¯®®¯®®®®®¯¯±¦[:.t¬®­®®¯®¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯¯®®¯®­¯¯¯®¯¯¯®¯¯µ£s< 1aˆ§´¯®¯®­¯¯®®®¯®®®¯¯®¯¯®¯¯®¯¯¯­¯¯®¯®¯¯­¯¯¯¯­¯®¯®¯®²¯“J C˜³¯¯¯®¯®®¯¯¯¯¯¯¯®®®®¯®®¯®®¯®¯®®®¯¯®®¯®¯¯¬•{N8Ÿª¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®®®®®¯¯¯®®®¯¯®®¯®°±±‘Z* *=ƒŸª¯¯¯¯®¯®®®¯®®­¯¯®¯¯®®®¯®¯¯®¯®­®®¯®®®¯®®­¯®¯®¯¯­³°x1†¨±®®®®¯­®®¯¯®¯¯®®®®¯®®¯­®¯®®®¯¯¯¯¯®®­¯ªœ[1i–±¯¯®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯®®¯®®¯­®®®®®®¯®°²¨„K# 5Y<. ;}¢¬®®¯¯¯®®¯®®¯®¯®¯¯®®®®¯¯®¯®¯¯®¯¯®¯¯¯®¯®®¯®¯®®¯®°µŸS/w °¯®¯®¯¯®¯¯¯®¯®¯¯®®¯®®¯¯­®®®®¯®®®¯®®¯®O +|ª®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯®®®®¯¯®¯®®°®°¡zK!g•…i7S’¬¯¯®®¯¯®¯®®¯¯®®¯®¯®¯¯®¯®®®®®¯¯¯®¯®¯®¯®¯®®¯¯­¯®®±±Š(eª®¯®®®¯®®¯¯¯®¯¯¯¯®®®¯¯®®¯¯¯¯¯­®­®¯®°¤ŠJS–­®®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®®®®®®¯¯®¯®¯­ wQE‹®°ŽL,ˆ­°¯¯¯®®®®¯®®¯¯®¯®¯¯®®¯®¯¯®®¯¯¯®®¯¯®®®®¯®¯¯®®¯¯®¯±œc Fž°°®®®®­®®¯¯®®®¯¯¯®®®¯®¯¯®¯®¯¯¯¯¯¯®±‘J[¨®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯¯®®®¯®®¯®®¯¯®®£ƒT^¥±³T DŠª°®¯¯®®®¯¯®®®®®¯¯­¯¯®¯®®®®¯¯¯¯®®¯®®¯®®¯®®¯¯¯®®®¯®¨ˆ;B†­°®®¯®¯¯®®¯®¯¯¯®¯¯®¯®¯¯¯¯®¯¯®®®®¯®°‘IŠ¡°¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®®®¯®®­­¯®²ªŽN%{«¯®¬p)k¯¯®®®®®®¯®®¯®­®¯®®®¯¯¯®¯®®¯®®¯¯­¯®®¯¯®¯¯¯¯¯¯®®­¯¯­”c;~­®¯®®®¯­¯®®®®¯¯®®¯¯¯®¯®¯®®®®®¯¯¯®¯±—^O…®®®¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®®®®¯­®­®®¯­•N[Ÿ®¯¯¯—; .g³°®®®¯­¯®®¯®¯¯®®¯¯®¯¯®®®¯¯¯¯®¯®¯­®®®¯®®¯¯¯¯®®®®®¯¯¯£x=ƒ«®¯¯¯¯®®®®¯®¯¯¯®®¯¯®®®¯®®¯¯¯®®¯­¯®¯¡+Z©¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®¯®¯¯®®®¯­œ_ <ˆ¥®®¯ª¤20-I€¡´®®­®®¯®®¯®¯®®¯®¯®®­¯¯¯®¯¯®®¯®¯®¯®®¯®¯¯®®¯®®®¯®®®®®°¯ŒS d¡³¯¯®¯®¯®®®®®®¯®®¯­¯®¯®¯®¯¯¯¯¯®®®®¯« B-o—®¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯¯¯®®®®¯¯®®®¬‹5)hœ¯®®®®¬®‰}}—¯±¯¯®®®®¯¯¯¯¯¯®®®®¯®®¯®®®¯¯¯®®¯¯¯¯¯¯¯¯®®¯®®®®¯®¯®¯®¯®°±¥i)Z›¯¯®®®¯¯¯¯¯¯¯¯­®¯®¯®¯®¯®¯®¯®®®¯®®®®¯­`$~«¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯¯¯¯¯¯®¯¢T-i𲝝®®¯®¯¯§©·¯¯¯®®­®¯®®®®¯®¯®®®®¯¯¯®¯®¯¯®¯®®¯®¯®®¯¯®¯®¯¯®®¯®¯®¯¯®¯®°³5_¤¬®®®¯¯¯¯¯¯¯®®¯¯¯¯¯®®®¯¯®¯®¯®¯¯®¯®®¯¯yBX‘¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®¯¯¯¬‰8  %I¢³°®®®¯¯®¯°¯²¯¯¯®®¯­¯®®®®­®®®¯®®¯¯¯®®®®®¯®¯®®¯¯¯®®®®¯¯®¯¯¯¯¯¯¯®´®´¯±²°ŸL [¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®¯®®¯¯¯®¯®¯¯¯Žd $l¦¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®®®°§{ $(;09R^r—­²¯®¯¯®¯¯®­®¯®®®¯®¯®®¯®¯®®®®¯®®­¯¯¯¯®¯®¯®¯¯¯¯®¯®®¯®¯®¯¯¯®¯®®®®¯µŸ£¢²«³O P²®®¯¯¯¯¯¯¯®®®®¯¯®®¯¯®¯¯®¯®­¯®¯®®¯®®¯¡ƒBœ¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®¯¯®®¯¢l &CKMgom€€’§¶¯¯®®¯®®¯¯¯­¯¯®¯®®¯¯®®®®®®®®®®®¯®®®¯®¯®®¯¯¯®¯®®®®®®¯®®®®¯®¯®®­²¥zceam…‰’fYž®¯®®¯¯¯¯¯¯¯¯®®¯¯®®®®¯®®®®¯¯¯­¯¯®®¯¯¯¬•  ¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯¯®®¯®›P162Rng’ŠŸ« ¦±¨²­®°´°¯¯¯®¯®®¯®¯®®®®¯®¯®¯¯®¯¯¯¯®¯®¯¯¯¯¯®®®¯®¯®¯¯®®®¯®¯¯®¯¯¯®®®®¯®¯²W.$ 5M>Vª¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®®¯®¯®®®®¯¯¯¯¯®®¯¯®§W°¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯¯®¯¯¯ŸI #?jtvЧœ¤­²±²±¯³¯±°°¯°¯¯®®¯®®®®¯®¯®¯®®¯®®­¯¯®¯®®¯¯¯®¯¯®®®¯¯®®®¯¯®®®¯®®¯¯®®¯¯®®¯¯®¯°­‚@k£®¯®¯¯¯¯¯¯¯¯®¯®®®®¯®®®®®®¯®®®®¯¯¯®®¯¯—t*v¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®­•U #I^r˜ž¢ª³®®´°°®°¯°®¯­¯¯®®¯¯®¯¯®¯®®®¯¯®®¯®¯¯®®¯®¯¯¯®®¯®®®¯­®®®®®®®¯¯®®¯¯¯®¯¯¯¯¯®¯®®¯®¯¬‰Hy¨¯®¯¯®¯¯¯¯¯¯®¯¯®®®®¯¯¯¯¯¯®®®¯®®®¯¯®¯®q5]¦¬¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯®¯®ŽL JyŒ•ª´¯±¯±¯°®¯®®¯¯®®®®®¯¯®®®¯­¯®¯®¯®¯¯¯®¯®®¯¯¯¯¯¯®®¯¯®¯®¯®¯®¯¯®¯¯®¯®¯®®®¯¯¯®¯®®¯¯®®¯®°œj(/…«¯®®¯®¯¯¯¯¯¯­®¯®¯®¯­¯®®¯­¯¯¯®¯®®®¯°¤‰G3•§°¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®°°œiNIr £©¯´¯¯¯¯¯¯®¯¯¯®¯®®®®¯¯¯¯®®®¯®®¯¯¯¯¯¯®®¯¯®¯¯®¯®®®¯®¯®®¯®¯®¯®®®®®¯®¯®¯®®®®¯®¯¯®®®¯¯¯¯¯®>AŸ¯¯¯®¯¯¯¯¯¯¯¯®¯­¯¯®®¯®®®¯®®­¯®®¯¯°­£†Po °®¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®±²”„š°ª®°²¯¯®¯¯¯¯®®®¯®®¯®¯®®¯®®®®¯®¯¯¯¯¯¯¯¯®®®®¯¯¯¯¯¯®®¯®¯®®®¯®¯®®¯®¯¯®¯¯®®¯¯®¯¯®¯®­®¯¯¯¯®°©|d¡°¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®®¯®¯¯®¯¯¯®®®¯­¥m8 F—°¯¯®¯¯¯¯¯¯¯¯¯¯¯®®¯­¯¯°°­¯´¯¯°®¯®¯®®®®¯¯¯®¯®®¯¯¯®¯¯¯®¯¯®¯®­®®¯®®®®¯¯®®¯®®®¯®®¯¯¯¯¯®¯®®®®®¯¯¯¯®¯¯®¯¯¯®®¯®¯®¯¯®¯®®°«~*9¬¯¯¯¯®¯¯¯¯¯¯¯®®®­¯¯¯¯®¯¯®¯®¯®¯¯¬¨‰f4‰¬¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®­®¯¯®¯¯°¯®¯®¯®¯¯®¯®®®¯®®®¯®¯®®¯­¯¯¯¯¯¯®®®¯¯­®¯®®¯¯¯¯®®®¯­®¯¯¯¯¯®®®¯®­¯¯¯®¯®®®¯®®¯®®¯¯¯¯®¯®¯¯¯¯§‡F ,lœ°¯¯®¯¯¯¯¯¯¯¯¯®¯­®¯¯¯®®¯¯®¯®¯¯®® ŽSs ­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®¯®­®®®®®®®¯¯®®®®®¯¯®¯®®¯¯¯­®¯®®¯¯®¯¯®¯®®®¯¯®¯®¯¯¯®¯®¯®®¯®¯®¯®®¯®®¯®®®®®¯¯®®®¯¯®®¯®®¯®¯¯­ŒY*K©¯¯¯®¯¯¯¯¯¯¯¯®®®¯®®¯®¯¯®®®®®®®­¦|+XŒ«°®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®¯®®®®¯¯®¯¯¯¯®¯®®®¯®¯¯¯¯®®­®¯®¯®¯¯®¯¯¯¯¯®®¯¯¯¯¯®¯¯¯®®®¯¯®¯®®®¯®®®¯®®¯¯¯®®¯¯®®®¯¯¯®¯®®± uUF‡¬¯°¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯¯®®®®®¯¯¯®ª`E) ;q©°®®¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®¯®®¯®®¯®¯¯®®¯®®®®®®®®®®¯®¯®¯¯¯®¯®¯¯¯®®¯¯¯¯®¯¯®¯®¯¯­®¯®¯®®®®®®®¯¯®¯®®¯®®®¯¯®¯¯¯±—v\ )4`–´±°¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®¯®¯®¯®®®®­©£ˆg8V¥°®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯®¯¯¯®®®®¯¯®®¯®®®¯®®®®®®¯¯¯¯¯®®¯®®®¯®®¯®¯®®¯¯®­¯¯­¯®¯®¯®®®­¯¯¯¯®®®®®®®®®®¯®¯¯¯­¯¯¯±®Ÿ—kJ>?6Pgc‚«µ±°®¯¯¯¯¯¯¯¯¯¯¯¯®®­¯®®¯¯¯®¯®¯®®¯¯®¯®­ª£‘a ;›¬¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯¯®¯®®¯®®®¯®¯®®®®¯¯®¯¯®¯®¯®®¯®®¯¯®¯¯¯¯­®¯®®¯®¯­®®®¯¯¯®¯¯®®¯®¯¯¯¯®®¯¯¯®®®­¯¯¯°®­¡”ˆ’™¡žµ±±¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®¯¯®¯¯­®¯¯¯°¯©‚/ #Œ§®®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯®®®®¯¯®®¯¯¯¯®¯®®¯®®¯¯¯®®¯®¯¯®¯¯®®¯®¯®®¯®¯®¯¯®®®®®®®®¯®¯¯®¯®¯¯¯®®®¯¯¯®¯®®¯¯¯¯±²±¯­®²®³¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®®®¯¯¯¯®¯­®®®¯±“Onž°®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯¯®¯®¯®®¯¯®¯¯¯¯®¯®¯¯®¯®¯®¯®®¯®¯¯®¯®¯®¯®®¯®®®®¯®¯®¯¯®®®®®¯®®®¯¯®¯¯¯®¯®¯¯°¯¯±¯°®¯¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®¯­®°—`N“°¯¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®¯®¯¯®®®¯¯¯®¯¯®¯¯®¯¯¯¯¯®®®¯¯¯®®®®¯¯®®¯¯¯¯¯®¯¯®®®®®¯®¯¯®®®¯¯¯¯®¯®®®®®®®®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®®®¯®¯¯®¯®¯¯®¯®®±™b)ˆ°­®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯¯¯®®¯¯¯¯®¯¯¯®®®¯®¯¯®®®¯¯¯®®¯®®¯®¯¯®¯¯¯¯¯¯®¯®®®¯¯®®®®¯®¯®®®®®®¯­¯¯¯¯®¯¯¯¯¯®¯®¯­¯¯¯¯¯¯¯¯¯®®®®®¯®¯®®®¯®¯®¯®¯¯¯®®®°—[{¬®¯®¯®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®¯¯¯¯®®®­¯¯®¯®¯¯¯®­¯¯®¯¯¯¯®®¯¯¯¯®®¯®®¯¯®¯¯­®®®¯®®®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯®®®®¯¯®¯¯®®¯®®¯¯¯¯¯¯®®¯¯®®¯®±‘Bk¢«¯­¯®¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯¯¯®®®¯®¯¯¯®¯®¯¯¯¯¯®®®®®¯®®®®®¯®­®¯®¯®®®¯¯­®¯¯¯¯¯®¯¯®®¯®®¯¯¯¯¯¯¯¯®®¯®¯®®®®¯¯®®¯¯®¯®¯®¯­¯¯®¯¯¯¯¯¯¯®°°®©˜l!\”¨°®®®®¯®®¯­®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®¯¯¯¯¯¯®¯¯¯®®®®®¯®¯®¯¯®¯®®®®¯®¯®¯®¯¯®¯®®¯¯¯®®¯®¯®®®¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®¯®¯®¯­®®¯®¯¯®¯®¯®®¯®¯®¯¯®¯«¦›h8I}¥±¯®¯®®¯®®¯®®­¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯®¯¯®®¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯®¯®®®­®­¯®®¯¯®¯¯¯®¯®¯®®¯®®®®•hC7f ±¯®®¯®¯®¯¯¯®¯¯¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®¯¯¯®¯¯¯®®¯®®¯®¯®®¯®¯®¯¯®¯®¯¬•i-Mœ²¯®®¯®®¯®®¯®¯¯¯­¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®¯¯¯¯¯­®¯®®®¯¯®¯¯®¯¯¯®¯¯®©t5 :—±¯®®¯¯­®®®¯¯®¯¯¯­¯¯¯®¯¯­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­­¯®®®®®­®¯­¯®®¯®¯¯¯®®¯¯®®¯¯®®¯®®°¨j++’®®®¯®¯¯®­®¯¯®¯¯¯®¯®®®¯®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®®¯¯¯®®®¯¯®®¯¯®®®®®¯¯¯¯®®®®¯¯©v8‹«®®¯¯®¯®¯¯­¯¯¯¯®®¯®¯®®¯®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯­¯®®®¯¯®®®¯®®®¯¯®¯¯­®®®¯¯®¯®®®¯«ŒQ¦®¯®®¯¯®¯®¯®¯®®®®®¯¯®®¯¯¯¯®¯¯­¯®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯¯®¯®¯¯®®®®®¯­¯®®¯®®®®®®¯®¯¯¯®¦n_ ®¯¯®®¯¯®®¯®®®¯¯®®¯®®®®®¯¯®¯®¯®®®®®®®¯®¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­®¯®¯®®®¯¯¯®¯¯®®¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯®®}U™­¯®®®¯®¯®®­¯¯®®®¯¯®­¯®¯¯®¯®®®®¯®®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®¯¯­¯®®¯¯®®®®®¯¯¯®¯®¯®®®®¯®®¯²‰/ J­¯¯¯¯®®®®¯®¯¯®¯®®®®¯¯¯®¯®®®¯¯®¯­®®¯¯¯¯¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®¯®¯¯¯®¯®¯®­¯¯®¯®¯®¯®¯®¯®¯®¯­®®²ECˆ¬¯®¯®®®®®®®®®¯¯®¯¯¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯®®®®®¯¯­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯­®®®¯®¯®¯¯®¯®®®¯®¯¯¯®®®¯­¯¯®¯¯¯¯®®¯®®¯¯²‘P#=¬®¯¯¯®®®­®®¯¯¯­®¯¯®¯¯®®¯®®¯®®¯®¯¯®¯¯®®®¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯®¯®¯®¯®®¯¯¯¯¯®®¯®­®®­®¯®®®¯®®®¯®®®¯¯²‘N"6z«°¯¯®¯­®¯¯®®¯®¯¯®¯®®®®¯®¯®®¯¯¯®®¯¯¯¯®®¯®­¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯¯¯®¯®¯®®¯¯®¯¯®®®¯®®¯®®®¯®¯®®¯®®¯®®¯®¯¯®®¯¯¯¯®¯³‰3 1t«¯®¯¯¯¯¯¯®®¯®®¯®®®¯®¯®¯¯¯®®¯®¯¯®¯®®¯¯®¯®®®¯¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯­¯®®®®¯¯¯®®¯®¯¯®¯¯¯¯¯­¯®®®®¯®¯®¯®¯­¯¯®®¯¯­¯­®®¯®¯¯¯®¨x,o«®®®®®¯®¯®®®®®¯¯®®®®¯¯¯®®®¯®¯¯®®¯¯®¯¯¯¯¯®¯®¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯®®¯®­®®¯­¯¯¯®®®®¯®¯®®¯®®®¯®®®®®¯¯®®®¯¯¯®®®¯®¯®­®¬’W)kª¯®¯®¯®®®®®®¯®®®®®®®¯®¯¯¯®¯¯¯®¯¯¯®®®®®®®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯®¯¯®¯®¯¯®®¯®­®¯®®®®¯®®¯®¯¯®®¯¯®¯­¯®¯¯®¯®®­®®­®®®­£\ (iª¯®®¯®¯®®®®¯®®®¯®¯¯¯®®®¯­®¯¯¯¯¯¯¯®¯­®¯®¯®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯®¯®¯¯¯®®®®®¯¯¯­®¯®¯¯¯¯®®¯¯®¯®¯­¯®¯¯®¯®¯®®¯¯¯®¯°Ÿ/(i«®®®®®¯®¯®®®®®®¯®­¯¯¯¯®¯®®®¯®®®®¯¯®¯®®®¯®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®­¯­®¯®®®®®®®¯¯®®®¯¯¯­¯®®¯¯¯¯¯®®¯®®¯®®®®®®¯®¯®®¯®¯¬7'iª°®¯¯®®®®¯®¯®¯­®®¯®®¯¯®®®¯®®¯®®®¯¯®®¯¯®®®®¯®®¯¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®®¯®®¯¯®®¯¯®®¯¯®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯®®°¯¡t> (i«¯®¯¯®¯®¯¯®¯®¯®¯¯®®¯¯®¯¯®®¯¯®¯¯®®®¯¯¯¯®¯®®¯®®®¯®¯¯¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯¯¯¯®®¯¯®¯¯¯®¯¯°¯°¯¯®­­¬¬­®®¯¯°°°°¯°°¯®¯°°¯®«¤–x;(iª°¯¯®®®¯®®¯¯¯®®®¯¯®¯®¯®¯®®®®¯®®®®¯®®¯®®¯­¯®®®®®¯®®®¯¯®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯®®¯®®¯®­¯®¯¯¯­­­«©¥¡ ¡¡¥¦§ªª¬¬­¬­­­­®­­­ª¦™„U+n«°®¯¯®®®®®®¯®®®¯¯®®®¯¯¯¯¯®®®¯®¯­®¯®®®¯®­®®®¯¯®®®¯¯¯®®®¯¯¯¯®¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®®¯®¯¯®¯®®¯®®¯®¨Ž{`UKFCA@BEGHMOTX[cehnprof\PF;).r«¯¯¯¯®®®®¯­®®®¯®¯¯®®¯®¯®®­®¯­®®®¯®¯®®¯¯®¯®¯¯­®¯¯®¯¯¯¯®­®®®®¯¯®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯®®¯¯®¯®¯®®®®¯®©˜€W@$  $)*2653, 7{«°®­®®®¯®¯®®®¯®¯®¯¯¯®®®®®®¯¯¯®®¯®®®®®®®¯®®®®®®®®®¯¯®­®¯®®®®®®¯¯®¯­®¯®®¯®¯®¯¯¯®¯®®¯¯®¯¯¯®¯®¯®®¯¯®®¯¯®¯®®®®®®®¯®¯®®®¯ª•b"J­¯¯®®¯¯®¯¯®¯¯®¯­¯¯¯¯®¯®®®¯¯®¯¯®®®¯¯¯¯­®®®¯®®¯®¯¯®¯®®®¯­®¯®®®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®¯®®®®¯¯®®®¯®®¯®¯¯¯¯¯¯®¯®¯¯¯®®¯®¯¯®®¥Ecž­®®¯®®®®®®®¯¯¯¯®¯­®¯¯®®®¯¯¯¯¯®¯®¯®¯®¯¯®®¯¯­¯®®®¯¯®®®®¯®¯¯¯¯®®®®¯¯¯¯®®®¯®¯¯®®¯¯®¯®¯¯¯¯®®¯¯®®®¯®¯¯¯¯¯®¯®®®®¯®®®¯®®®©Š`Š©®¯®¯®®®®¯¯®®®¯®®®¯¯®®¯®®®­®®®®®®­®®®¯®®®¯®®¯®¯¯¯®®®®¯¯¯®®®¯®®®¯®®¯®®®¯¯¯¯¯®¯®®¯®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®®®®¯¯¯¯®®¯®¯®¯«šO)’¯®¯¯­®®¯¯®¯¯®¯¯®¯®®­¯®®®®­¯¯®¯®¯¯¯®®®¯¯¯­¯­®¯®®®¯¯¯¯®¯®®¯®¯®®¯¯¯®®®¯¯¯¯®¯®®®®®¯¯¯¯¯®¯®¯®¯­®­¯¯¯®¯®®®¯¯¯®¯¯®­®®®®¯š^$ :•¯®¯°¯®¯®®¯¯®®®®¯¯®®®®¯¯®®¯®¯®®¯®®®®¯®®®®®¯®¯¯®®®¯¯¯®®¯¯®®¯¯®®¯¯®¯¯­®®®¯¯®®®®­®®®¯¯¯®¯¯¯®®¯¯®®­¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®¬¥ƒ+ >§©¬®¯®¯®¯®®®¯­¯®®®®¯®®¯®¯­¯®¯®¯¯¯¯®®¯®®®®®¯­¯®®¯®¯®¯¯®®®®®¯¯®®¯¯®®®®¯¯¯®¯¯®®¯®¯®¯®¯¯®¯®¯¯®®¯¯®®®¯®¯®¯®®®¯®®®®¯°©‰] (CTgxŽœª°°°°¯¯®¯¯¯®¯®®¯®¯¯®¯¯®¯®¯®®®®®¯¯¯®®®¯¯®®¯®®¯®¯®¯¯¯®®¯¯¯¯®¯¯¯¯¯¯­¯®®®®®¯®¯¯®¯¯®®®®®¯®®®¯¯®¯¯¯®¯®¯®®®®¯¯¯±£]1$=Wi–¤«®¯¯®¯¯¯¯®¯®¯¯¬««­®°¯¯­¯¯®®®¯¯®®®¯­¯¯®®®¯®¯®¯®®¯®¯®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯¯¯®¯®®®¯®¯¯®®®®®®¯®®®¯¯¯®®­®®¯š:%@i€œ§­®®¯®¯®¯®®®¯¦£¢§«­®®¯®¯¯¯¯®®¯¯®®¯®­¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯®¯¯®®®®¯¯­¯¯¯¯®¯¯¯¯¯¯®­¯®¯®¯¯®¯®®¯®¯®¯§Œ$ "4Qm‰ž«¯°¯®®¯¯®«¢’|nr~–£¬±±¯¯¯¯®®¯®®¯¯®®®®¯¯®®®®®®¯­¯®¯¯¯¯¯¯®®®¯®®®¯®¯¯¯®¯®¯®®®®®¯®®¯¯¯®®®®®¯¯®¯®®®®”r *Rm‡• §­°¯¯¯®§•yc\\jz‹™¡ª­°®®®¯®¯®¯®¯®¯¯®®¯¯®®¯¯¯®®¯¯¯®¯¯®¯¯¯¯­¯®¯¯¯­¯¯¯¯¯®¯¯®®®¯¯®¯­¯¯¯®®¯¯®¯¯¯®~T>n¡­¯®¯®®®«¥‚Z$Pr𥝮®®®®®¯¯®®®®®¯®®¯®®¯­®®¯®®®¯®®¯®®®¯¯®­¯®®¯®¯®®¯®®­®¯®¯®­®®­¯®¯®¯¯®®®®¬b( ,Ll‘£°°¯¯¯­¡”xS.'=[Ÿ¬¯°¯®®®®®®®®®®¯¯®¯®¯®¯¯¯¯®®®¯¯®¯®¯¯¯¯®¯®¯®®¯¯®¯®¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯®¯¬£K'Z~•£ª®®¯°¯¨…Y(Hw£«°®¯®¯®®¯®¯¯®®¯®®­¯¯¯¯¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯®¯®®®®¯®®®¯¯®¯®®®¯®®¯®®°§’4 3z•¨®®¯®®­£}S>x­¯®®®®¯®®®®®¯¯¯®¯¯¯®®®­¯¯®®®®®¯®®¯¯®¯®®®®®¯®¯¯®®¯¯¯¯®¯®¯®®¯¯®®¯±œq">h¥­°®°­¢Žm= -S|¤¬¯¯®®®®¯®¯®¯®®®¯¯®¯¯®®¯¯¯®­¯­®®¯­¯®®¯®¯®¯¯®¯®®¯¯®¯®®¯¯®¯¯¯¯¯®°J '^‰Ÿ©®¯¯±ªŸn.Lˆœª­¯®¯®®®¯¯®®¯®®¯¯®¯®¯¯¯®®®¯®®®¯¯®­¯¯¯®¯¯®®¯®¯®¯®®®¯®®¯¯®®¯¯¯­„-a‰«®¯¯®¬¢†@$^”§±­¯®®®¯¯¯®®®®®®®¯®®®¯¯®®¯®¯¯®¯¯®¯¯¯¯¯®¯¯¯®®®¯®¯¯®¯¯®¯®®®®®¤r;s”¬®°°­¤„V&L}®°®®®®®®¯¯¯®®¯¯®¯¯®®®¯®¯®®¯¯®¯®®¯¯¯®¯®­®¯®®¯¯¯®¯®®¯®®®¯®¬‹U'g—©­®¯®­ŒP!Ey «¯¯¯¯®®®¯®®¯®¯®¯®®­¯¯®®®¯®®¯¯®¯®¯®®®¯¯®®®¯®¯®¯¯¯¯¯¯¯¯®¯ªo7 <Œ£®°®®©›\& +f–°°®®¯®¯¯¯¯¯®¯®®®­®®¯®¯¯®¯¯¯®¯®®¯¯¯¯®¯¯®®®¯®¯®®¯®¯­®¯¯¯¨P @mš§°¯¯¬e(&b‹¨¯¯¯®®¯®®®®®­®¯®®¯¯®¯¯®®¯¯­®¯®®¯¯®®®¯¯¯¯®®¯®®®¯®®®¯®¬¡9 (o“«®®®¯–\0#S”¨®¯¯¯®®¯®®¯®®­®®¯¯®¯¯®¯®­®®®¯®®®¯®¯®®¯®¯¯¯®®¯¯®®¯¯¯¦’( Q©¯­¯ª¢o/ Pzª°®®¯®­¯®®¯®®¯¯­®¯®®¯¯®®­¯­¯¯®®®¯®¯®¯¯­¯®¯®®¯®®¯¯¯œzO‹¢¯¯¯¯—v9 D¡®®¯®¯®®¯¯®®­®¯¯¯¯®¯®®®¯®¯¯¯®®¯®®­¯®¯¯®®¯¯®¯®®®°®Œ^Vˆ©®®¯®¦j-Cƒ£®¯®¯¯¯­®®®®®¯®®®¯®®¯¯¯¯¯®¯®¯¯¯­®¯®¯®­®®®¯¯®¯®¯°~? @‹¦¯¯®­ x" Eq¥°¯®­®¯¯®®®®¯®¯®¯¯®®­¯¯®¯¯®®¯®®¯®®®¯¯®®®®¯¯­¯¯¯oG…¤®¯¯®™k/5}𝝭¯®®¯¯¯®¯®¯¯®¯¯®®®®¯®¯®®¯®®®¯¯®¯¯¯¯¯¯®­®®¬¥`UЍ®¯®¬¡_Bu¨­¯®¯®®¯¯®¯¯¯¯¯®¯®®®¯­®¯¯®¯®¯¯¯¯¯®®®®¯¯¯®®°¦•MF–¦¯¯¯­”q3¦±®®®®®¯¯¯¯¯¯®¯¯¯¯®®®¯®­®®¯®¯®®¯®®®®®®¯¯®°Ÿ};R„©­¯¯¨˜T* >„¡®¯¯¯¯¯®¯­®®¯¯¯¯®¯®¯®®®¯®¯­¯®®®¯¯¯¯¯¯¯®®²˜`*O–¦°¯®«‰_S§®­¯®®¯®¯®¯®®®¯¯®®¯®®¯¯¯®¯¯®¯¯®®¯®¯¯¯®®±ŽC>®¯¯®©ŽM :Œ¢¯¯®®®¯¯®®®®¯®¯®®¯®®®¯¯®®®®¯¯¯¯®®¯®¯®¯°ƒ& S«¯¯°¤‡BIw¤­¯®®®¯¯¯®¯¯®¯¯¯®®¯¯¯®®¯¯®¯¯¯®­®¯¯¯®­¦rY¬¯®®«r@ A‡¢­®¯®¯¯®­®¯®¯®®®®¯®®®¯®®¯¯®®®¯¯¯¯®¯¬˜_f—²¯¯¯¢‰- 2|°¯¯¯®®®¯¯®¯­®®®¯®¯¯­­¯®¯­¯®­¯®¯¯¯ª‚Fnž¬¯®®£m? o¤¬¯­®¯¯­«©£ŒpM% Js«°²±®¯¯¯¦œ‘ƒvdPA.:€’ž¨­¯®¯°¯±²­¡Žl_J<0*($#  3b§®¯®¯®¯®¯®«ªª©§¥¢–Žƒ}tnjh`]]]]]]]]]]\]]\]]]\]\]]]]]\]]]]]\\]\]]\\\\\]]][]]]]]\]\]\]]]\]]]]]]\]]]]^]]\]]\]]\]\]_P Qj…šª°³°°±°¯°°°±°«¨¥¢žšš˜––––––––––—––—•––––•––—––•—––•–––––—•––•—•–——––•––——–––––––––•––—–––––––––––•—––––––˜ƒ-Cy—ž£©­®¯¯¯®¯¯¯¯±¯°°°±±±±²±°±°±±°±°°±±°¯°°°±°±°°±°°±°²°±±°±±±°°°±±°±±°°±°°°±±°±±±°±±±±°±°±±±±°°°°±±±°°±°±±²!?`w¡®¯®¯®¯¯®®®¯®¯®¯®¯®®®®®¯¯®¯®¯®®¯¯¯®®®¯¯®¯¯¯®®®¯®®®®®®¯¯®­¯®®®®®®®¯¯®®®¯®¯¯®¯¯¯®®¯¯¯®®¯®¯¯®®¯®®¯®¯®¯®±› !Nbm|†Ž™Ÿ¥ª®°²´··¸·¸····¹¸¸¸¸¸¸¸¸·¸¹¸¸¸¸·¸¸¸¸¸¸¸·¸¸¸¸·¸¹¸¸¹¸¸¸¸¸¹¸¸¸¹·¸¹¸¸¸¸¸¸·¸¸·¸¸¸¸¸¸·¸¸¸·¸·¸¸¸¸¸º¥" #-6@ELPUXZ\^a``a`_aa`aa```a``_a`````aa_`_````````a``aa`a`_a``a```a```a`a````aa_````a````a`a`````bS openigtlink-3.0.0/Examples/Imager/img/igtlTestImage6.raw000066400000000000000000002000001501024245700231260ustar00rootroot00000000000000 "#%&*())))))*&$#"   !$,7CN[gq{‚‹’˜Ÿ¢£§¬­¬¬¬¬¬­­¨£¡ž˜Šwl^RE4)"  .G]qƒ“ž£¤¦¥§¨©©ª««¬¬­­®­®­­­­®®­­¬¬¬«ª©¨¨¦¥¤ Ž€hP6(?Ufp{ƒŽ•œ¤«¯²±±²°¯°°°°¯¯¯¯¯¯¯®¯¯®¯®®¯¯®°¯¯¯°¯°±²²°®©£™…wkZE(  (@So‚—ª®±±±±¯¯®¯®­¯®¯®®®¯®­¯®®¯®®®¯®®®®®¯¯®®®¯®®¯®¯¯®¯¯°°°°±²ªœ‡gG4 $@e†— ¤§©«­®®®¯­¯¯®¯¯®¯¯®¯®¯®®¯¯®¯®¯®¯®¯¯¯®¯®¯­¯¯®¯¯¯¯®¯®®¯®®¯¯®®­¬©¦£˜‚\1>Xk}Š˜¦­°±°°®®­¯®®®­®®¯¯¯¯¯¯¯®¯¯®®¯®­®®®¯¯®¯®®¯®®®®¯®¯¯®¯¯®¯®®®­®®¯¯®®¯°°­¤”kN0 &A\š­±±°¯¯®¯¯­®®®®®¯®®¯®®®®®¯¯¯¯®®®¯¯®®¯®¯®®¯®®®¯®¯¯®®¯®®¯¯®®®¯¯¯®¯®®¯¯®¯¯¯¯°±°ªpI% Cq‘ž¦©¬®¯¯®®¯­®®¯¯­¯®¯¯®¯­¯¯®¯®¯¯®®®¯®®¯¯¯®¯®¯®®®¯¯¯®¯­®¯¯®®®®¯¯¯¯¯®®¯®¯¯®®®¯¯¯¯¯¯­«§¢k;FcxŠ©¯°°¯®®¯®®®®¯¯¯®¯®¯¯®®®¯¯®®®­®®¯¯®¯®¯®®®­¯®®¯®®¯®®­®¯®®¯®¯®¯®®¯®®¯®®¯®¯¯®®¯¯®®®¯®¯°¯©™„mF$ "?aŠ£°°°®¯®¯¯®®®®¯¯¯¯®­¯­¯®®®®®®¯®­®¯¯®®¯¯®¯­¯¯®¯¯­®®®®®¯®¯®®¯¯¯¯®¯®®¯®®¯¯®¯®®®¯®®®®®®®®¯®¯®®±¯ª†b5 "Lƒ™¥ª¬­¯®®®¯®®¯¯¯¯¯¯®­®¯®¯¯¯¯®¯¯¯®¯®®¯®¯¯¯¯¯¯®®®®¯¯¯®¯®¯®¯¯®¯¯®¯®®¯¯®®¯®¯®­®®®®¯®¯¯¯¯¯¯¯¯¯®¯®¯¯®®©£˜h? C\z¥®²°°®®®®¯¯¯¯®®¯¯¯®®¯­®¯¯®®®®®¯®¯®¯¯®®¯¯¯®¯¯¯¯®¯¯®¯®®¯®®®®®¯¯¯¯¯¯¯¯®®®®¯¯®®®¯¯®¯¯¯®¯®¯®®®®¯®®®¯®°°­™…eF.Q‡¯±¯®¯®®¯¯®®¯®®¯®¯¯®®®®®®®®®®®¯®¯®¯®¯®®®®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯®¯¯¯¯¯¯®®¯®®®¯¯®®¯®­®®®¯®¯¯¯®®®®®¯±®£‹Q)g‰£ª¬¯¯­¯¯®®®¯¯®®®¯®¯®¯¯®¯®®¯¯¯¯¯®¯¯®®®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯­¯¯®®®¯¯®¯®®¯®¯®®®®¯­®®¯®®¯¯¯¯­¯­®­ªŸ['Vw—¦°±°®­¯­¯®¯¯®®®¯®¯®®®®¯®®®®¯¯®®¯®¯®¯¯¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯®®®¯®®¯®®®¯¯®®¯®®¯¯¯¯­¯°°£‘kF!^®°¯®¯®¯¯®®¯®®¯®®®¯¯®®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®¯®®¯­¯¯®®®®®®®®¯¯¯¯¯¯­®°®§}BX{™¥®¯®¯¯®®®¯®¯®®¯¯­¯®¯¯®¯®¯®®®­®®¯¯¯®®®®®¯®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯¯¯®®¯¯¯®¯¯®¯®¯®®¬¡f@6[Ž¥°¯¯¯®¯¯®®¯®®®®®¯®¯¯®®®®®®®¯®®¯®¯¯¯®¯¯¯¯®­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­®¯¯®¯¯®®¯¯®®®¯¯®®®®®®®¯¯®®¯¯°­–zG&D†§­¯¯¯®®¯®®¯®®¯¯®®¯¯®®®®¯®®¯¯¯­®¯®¯¯¯¯¯­¯®®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®¯¯¯®¯¯¯®¯®¯®®®®®¯¯¯¯¯¯¯­¯¯¯©œo*,\ަ­®¯¯®®®®®¯®¯¯¯®¯¯¯®®¯¯¯¯®¯®®®¯®¯¯¯­¯®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯­¯®®¯®®¯¯¯¯®®¯®¯¯®¯®®®®®®¯¯¯®ªŸƒK (l‘¬±¯¯®¯¯®¯®¯®®¯®¯¯­®¯®®¯¯¯®®¯®¯®¯®¯®¯®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®®®¯¯®®¯¯¯®¯¯®®¯¯¯¯®¯®¯¯¯§…[%@|¢¯¯¯¯¯®®¯¯¯¯¯®®¯¯¯¯®®¯¯¯®®¯­®®¯®¯¯¯¯®¯¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®­¯®®®¯®¯¯®¯¯®¯¯®¯¯¯®®®¯®®¯®¯›s6T¡«®®®¯®¯®¯®­¯®®¯¯¯¯¯¯®¯®®®¯¯®®®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯¯¯¯®®®¯¯®¯¯®®®¯®¯®®®®®¯®¯®¯¯ªŸ~XOФ±¯®¯®®¯®®®¯¯®¯®¯¯­®¯®¯®®¯®®®¯®¯®®¯¯­¯­¯¯¯¯®¯¯­®¯¯¯¯¯®®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®®®¯¯¯®®¯¯¯¯®®¯®¯®¯¯®®®¯®¯¯°±¢U#Z‘«¯¯®¯®¯¯®¯®¯¯®¯®®®¯®¯®¯¯¯®¯®®®®¯®¯¯­¯¯®¯¯®¯¯¯®¯®®¯¯¯®¯­®¯¯¯®¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯®®¯¯®®¯®¯¯®®¯®¯¯­¯®®®¯®®¯¯«i$!\‹¨®¯¯¯¯®®¯®¯®¯¯®¯¯®®¯®®®®®¯¯®¯®®®®®¯¯®¯®¯®®¯¯¯®¯­®®®®¯®®®¯¯®¯®®¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯¯¯®®¯¯¯¯¯®®­¯¯®¯¯¯®®­®¯¯®¯¯®ª—}< TŽ¥±®¯­¯®®¯®®¯¯®®¯®¯¯®®®®¯¯¯¯¯¯®¯­®¯¯¯®®®­¯®¯®®®¯­­¯¯®¯®¯­®¯®¯®¯¯®®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®­¯®®­¯¯¯®®­¯¯¯®¯¯¯®¯¯®¯¯­¦r> Y‰®¯®¯­®¯®®¯¯®¯¯®¯®®¯®®¯®®¯®®®¯®®®®®¯®®®¯¯¯®­®¯¯¯®®¯¯®­®¯¯®¯¯®¯®¯®®®¯®®®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯®¯¯¯®­¯¯®¯¯®®¯®¯®¯®¯®®®¯¤Ž6?¤¯®¯­­¯¯®¯¯¯­¯®®®¯®­®¯¯¯®­¯¯®¯®®®®®®®®®¯®¯®¯®®¯®¯®®®¯¯¯¯®¯¯¯®¯®®¯¯®®¯®®®¯®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯¯¯¯¯®¯®®¯®¯¯¯¯¯®®¯®¯®¯®®¯®¬¦…H ;z©¯®®®®®¯¯¯®®¯¯¯¯®®¯®¯¯®¯®®®¯®¯¯®®¯¯®¯®®®¯¯¯¯®¯®­®®®¯®¯¯®¯¯®­®®¯®¯¯®®¯¯®®®®­®®¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯¯¯¯¯®¯®¯­¯®®¯¯®ª{B "tª¯¯®¯¯¯®¯¯®®®®¯®®¯®®¯®¯®®¯®¯¯®¯®®®®¯®¯¯®®¯®¯¯­®®¯¯¯®®¯¯¯®¯¯®­¯¯®¯®¯¯®¯¯¯¯¯®®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯¯®®®®®¯¯®®®¯¯®®®®¯®®®¯®¯¥9 n–®¯¯¯¯¯®¯¯®¯®®¯¯®®¯®¯®®¯®®¯®¯¯¯®®®¯®®¯®¯­®¯®®®®®¯®¯¯®¯®®¯¯¯¯®¯¯®¯®­®¯¯®®¯¯®®¯¯­­¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®®¯¯¯¯¯®®¯®®®¯®®¯­¯®¯®¬¦}QI›¨°¯®­¯¯®¯¯¯¯¯®®¯®®®¯®¯®¯®¯®¯®¯¯¯®®®®®¯¯¯®¯°°°°®®®®¯¯­­¯¯¯¯¯®¯®®¯®¯¯¯¯¯®®¯¯®®¯¯¯®®¯®®®®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯¯®®®®¯¯¯®®®¯®®¯®¯¯°¯¡5 J{¬¯®¯®®¯®¯¯®®®®®­®¯¯®®®¯®®®®¯­¯®®¯®®¯¯®®®¯¯®­®®¯°¯®®¯®¯®¯¯®®®®¯®¯¯®®®¯¯®¯¯®¯®®¯¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®¯¯¯®®¯®¯®¯®¯®¯®¯¯®¯®®¢|5*ž¯¯¯¯¯®®®®®¯¯¯®®®®®¯®®¯¯®¯­®®¯¯®®¯¯®®¯®°²³­¡˜—¡®±®®¯¯¯®®®®¯®®¯®¯¯®®®¯¯¯®¯¯¯¯®¯®®®®®¯¯®®¯¯­­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯­¯®¯¯®¯¯¯®¯¯¯®¯®­®¯®®« f0W›¯®¯®®®®®®¯¯¯®¯¯¯®®¯®¯®¯®®®®¯®¯®®®®¯®¯®¯¬¡ŽydVS\q‘¬¯¯®®®®¯¯®®®®®¯¯®®®¯®¯®¯¯¯¯¯®¯®®¯®¯®®®®®­®®®®­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯¯®®¯¯®¯¯®®®®¯¯¯¯¯®¯¯¯¯¯ŒeH¨°®®¯­®®®¯®¯­¯®¯®¯¯¯¯­®¯®®®®¯¯®¯®®®®­®¯®¡|I# 'e¢­±¯®®¯®®¯¯¯®¯®¯¯®®®®®®¯®¯¯¯®¯¯¯®¯®­®¯®®¯®®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯®¯¯¯®¯®¯®®®¯®®¯¯®¯®¯¯ª›C,m¦¬¯¯®®¯®®®¯¯®®¯®¯¯®¯®¯¯®¯®®¯®®®®®®­®¯®¯¬˜m4$[žµ¯¯¯¯¯¯®¯¯®¯®¯®¯¯¯®¯®­¯¯®¯®¯®¯¯¯®¯¯®¯¯¯®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®®¯¯¯¯®®¯¯®®®®®¯®¯®®¨{J]‹±®®¯®®¯¯®®®¯¯¯®¯®®®¯®¯¯¯®®®®®®¯¯¯®¯®¯¯® h( 3Œ±¯¯®®¯®­®¯®®¯¯®®®¯¯¯¯®¯®®®¯¯¯®¯¯®¯¯®®®®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯¯®¯®¯¯®®®¯®¯®¯®®®¯¯¯°®Ÿu8’¦¯®¯®¯¯®®®®®®®®®¯¯¯¯®®¯®­®­¯®¯¯®¯¯­­¯®­§= u©¯°¯¯¯¯¯¯¯¯®¯¯¯®®¯®¯®¯¯®®¯¯®¯®®¯¯¯¯¯¯¯®®¯¯­¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®®®®¯¯®¯®®®¯®¯¯¯¯¯®¯”D&^¤¬®¯¯®®¯¯®®®®¯®®¯¯¯®¯®®®¯®¯¯¯¯¯¯®®¯¯®¯®­™q _—¯¯¯®®®®®¯®¯¯¯¯®¯¯®®®®¯¯¯®¯®®®®®¯­®¯¯®®¯®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®¯¯®¯¯¯®¯®¯®¯¯®®¯®®¯¯¤~5O€­¯®®®¯®¯®®¯®¯®®®®¯¯®®®¯¯®®¯®¯¯®®®®­®¯¯°®†QY•®¯¯­®¯®¯®®®®®®®¯¯®®¯®¯¯¯®®®¯®¯¯¯®®®®®®¯®®¯¯¯®¯¯®®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®®¯®®®®¯¯¯¯®¯¯®¯®¯®¯­ŸV¢­¯®®¯¯®¯®¯¯®¯¯¯¯¯®¯­®¯®®­¯¯¯®¯­®¯®®®®®¯¯~Baž­¯®¯®®¯®¯­®¯®¯®®¯¯¯®®®®®®¯®¯­¯®®¯¯®®¯®®®®¯¯¯¯¯®®®¯¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®®¯¯¯®¯¯¯¯¯®®®®¯¯¯®®°¬w96”¬¯¯¯¯®®¯¯¯®¯®¯®®¯®®®¯¯¯¯®®¯®¯¯¯®¯®¯®¯¯®¯¯{6p¦­®®¯®­¯¯¯­¯¯®®®®¯®®®¯®®®®®®®¯¯¯®¯¯®®®®¯®®®¯¯®¯®®®¯®®¯¯¯¯®®®®¯¯¯¯¯¯­¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®®®®®¯¯¯¯®­¯¯®¯®®®®¯­–l"b¡°¯¯®®®®®®¯¯®®®¯®®¯®®¯­®®®¯­¯®®®¯®­¯¯®®¯¯±6DŒ±®®¯®¯®®¯¯¯®¯®­¯¯®¯®®®®®®¯®¯¯®¯®®¯¯¯®¯®®®¯¯¯®¯®®¯¯¯®®®®¯¯¯¯®®®¯¯¯¯®®­¯­¯¯®¯®¯®¯¯®¯¯¯¯¯¯®¯®¯¯¯®¯®¯¯¯®®®¯®¯®®¯®¯®®¯ª)D©°¯®¯®¯¯¯®¯¯®­¯®®¯¯®¯¯®¯¯®¯¯¯®¯¯®®¯®®¯¯­®²‚>K†¤®®®­¯®®¯¯¯¯®¯®®¯¯¯¯®¯®¯®®®¯®¯¯®¯®¯®¯¯¯®®¯¯®¯®®¯®¯¯®¯®¯®®®¯®¯¯®­®¯®¯¯®®¯®¯®®¯¯®®¯®¯¯¯¯¯¯¯®¯¯®®¯¯¯®®¯¯­­®®¯¯®¯®¯®®¯°žW-b¤­®®®¯®®®­¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯¯®¯¯¯¯¯®®¯¯¯®³ŒQH{¦°¯®®¯®®¯®®®®¯¯®®®®®¯®®¯®®¯¯®®¯¯®¯¯®¯®¯®®¯®¯¯¯¯®®¯¯¯¯®¯®¯¯¯®®®¯¯®®®®­­®¯¯¯®®®®®¯¯®¯®®®¯¯¯¯¯®®¯®®®®¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯¯¦†S,u­®®®®¯®®®¯®­¯®®®®¯¯¯¯®¯¯¯¯®®®¯¯¯¯¯®®¯¯®¯¯¯²•f)g“¨®¯®¯®®®®®®¯¯®®®®¯®¯®®®¯¯®®¯¯®®®®®®¯®¯¯­¯¯¯¯¯®¯¯¯®®¯®¯®®®®®®®®¯®¯®®®®®¯¯®¯®®®¯¯¯®®®¯®®®®¯®¯¯¯¯®®®¯¯¯¯¯¯¯¯¯®¯¯®¯®®¯¯®¯¬¢l WŒ¯¯¯¯¯¯¯¯¯¯®®®®¯®¯®®®®¯¯®®¯¯®¯¯¯®®¯®®¯®¯®¯¯²Ÿ„;/Œ­°¯®®¯¯¯®®®¯®®¯®®®®®¯¯¯¯¯®¯¯¯¯®¯®®¯¯®®®¯®®®®®®¯¯®¯®¯®®®¯®¯¯®­¯®¯­®¯®¯¯¯®®®¯¯®¯¯®®®®®®®­®¯®®¯¯¯¯¯­¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®®¯¯®°„2}Ÿ¯®®®¯®¯®¯®¯¯¯¯¯®®¯­¯®®®®®®¯¯®®¯¯¯®¯¯®®¯¯¯®¯¨ Q6’°¯¯¯¯¯¯®¯¯®¯®®®¯¯®®®®®¯®¯¯¯®®®®¯¯¯®®¯¯®®¯¯®¯¯¯¯¯¯®¯¯¯®®®®®¯®®¯¯®®¯¯¯®¯®®¯®®®¯®¯¯®®®®®®®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®®®±–d)(˜¬¯®¯®®¯®®®¯®®­¯¯¯®¯¯®¯®®¯¯®®®¯¯¯®¯®®¯¯®®¯¯®¯­®m ^’®³°¯¯¯®¯¯®®­¯­®®®®¯¯¯¯¯®®®¯¯¯¯®®¯¯¯¯¯®¯¯¯®®®­®®®®¯®®®­®¯®®®®®®¯¯®®¯¯¯¯®®¯®¯®®¯¯®¯®®®®¯®¯¯­®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯°£?I¡¯¯®¯¯®­¯®¯¯¯¯®¯®¯®®¯®¯®®®¯®­¯®¯¯®®®¯¯®®¯®¯®¯®±W%V€’ž§­¯°¯¯®®¯¯®®­®¯®®®¯¯¯¯¯®®¯¯¯¯®¯®®¯®¯¯¯®®¯®®¯¯®¯¯®®®®®¯¯¯¯®¯¯®¯¯®®¯¯¯¯®¯®®®®®®¯®®¯¯®¯®®¯®­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯­¯®¯¯®¯¯¯¯¯­¨\8j¦°¯¯®®¯¯®®¯¯¯®¯®®®¯­¯®®¯®¯®®®®®®®¯®®­®¯®®¯®¯¯®°ªL)Ny™§¬¬«­®®°°°°¯¯¯­®®®¯¯®®®®®®®®®¯®®¯¯®®®¯¯®¯®®®¯¯¯®®¯®®®®¯­®¯®®¯®¯¯¯¯¯¯®®¯®®¯®®¯¯®¯¯®¯®¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®­¯®®¯¯®®u/Y‰©¯®®¯®¯¯¯¯®­¯¯¯¯®®®¯¯­¯¯®®®¯®®®®¯¯¯®¯®¯¯¯¯®®®¯¯²«‚L# 8LZhz‰™¤«°±²±±°¯¯®¯®¯¯¯®¯¯®¯¯¯®®®¯¯¯®®¯¯®¯¯¯¯¯®®¯¯®¯®®¯¯®®®®®®¯¯®¯¯®¯®®¯®¯¯­­¯¯®®®¯®¯¯®­®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯¯¯®¯¯¯ŠSv¦¬®®®®¯®¯®®­¯®¯®®®¯¯®®®­¯¯®­®¯¯­®®®¯¯®®®¯¯¯¯¯¯¯¯°®©`" &CZly€„ŠŽ–¦­²µ·µµ³±°¯®®®®®®¯®®¯¯¯¯¯®¯¯¯¯®®¯¯®®®®¯¯¯®®¯¯¯®®®¯®®¯¯®¯®®¯¯¯®®¯¯¯¯®¯¯¯®­­¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®¯¡|„®®¯®¯¯¯¯¯¯¯¯®¯®¯®¯®®¯­¯®®¯¯®®®®®®®¯¯®®¯®®¯®®®®¯¯¯¯³­•sL# %6FWgu‚ˆŽ“•—šŸ¤¨«­¯±°°°¯¯¯®®®­®¯¯®®¯¯®®¯¯¯¯®®®®®®¯¯®®­®¯®®¯¯®®¯®­®¯®¯®®¯¯®¯®¯®®®®¯¯®®®®®¯¯¯¯¯¯¯¯¯®®¯®®¯¯®®®¯®®«-7±®¯¯®¯®¯¯®®®®®¯¯®¯®¯®¯¯®®®¯®®®®®®¯¯®®¯¯¯¯®®¯¯®¯¯¯¯®°°ªeA(!&0>N\l€‘šŸ£¤¤¤§ª®¯±±±±°¯¯¯®®®¯®®®¯®®¯¯®®¯¯®®¯¯®®¯¯¯¯¯­®¯®¯®®¯®®®®¯®®¯¯¯®¯¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯­¯®®¯¯­®®®¯®®¯›H*Z—²®¯®¯®®®¯®®®¯¯®¯¯¯¯®®¯¯®¯¯®¯®¯®¯¯®®®¯¯®®¯¯®®®®®®®¯®¯°¯«£”q> %*/39CO]n€‘ž¤©¬¬¬­­®®¯®®¯¯®¯­­®®¯®®®®®¯¯¯®­®®®¯®®®®¯®¯®®¯¯®¯®¯¯¯®¯¯¯®­¯®¯®®®®­®¯¯¯¯¯¯¯®®¯¯®®¯­®¯¯¯¯¢n1l›³°¯¯®¯¯¯¯¯¯¯®®¯®¯±~ Cx¦¯®®­¯®¯¯¯­­¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯®¯®¯­®¯®®¯¯®®®®­­¯¯¯®¯®®¯¯®¯¯¯¯¯¯¯®¯®¯®®®¯¯­®®¯¯¯¯®¯¯®¯¯®¯®¯®®¯¯¯¯®¯¯®¯®®®®¯®¯®¯®®¯®¯®®¯¯¯®®®¯®®®®¯°±±°±°¬¨£™”‘Œˆƒ}skaVH;,  3bŽª°¯¯¯¯¯¯¯®®®¯¯®®±€ I}§¯®®¯®¯¯¯¯®®­®®®®®¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯®¯¯®®¯¯¯®¯¯®®¯¯®­®¯¯®®¯¯®¯¯®®¯¯®¯®®¯®®¯®¯¯®®¯¯®¯®­¯¯¯®®®¯¯¯¯®®®®®¯®¯®¯¯¯®®¯®¯¯®¯¯®¯¯®¯¯¯¯®®¯¯®¯¯®®¯±°±³´¶¸¸´®¨ š“Œ†€}zzxtrlcYL?+ M©¯°¯¯®¯¯®®¯¯¯®®²„! N„¨°¯®¯¯®®¯®¯¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®¯®®¯¯®®¯®¯¯­­¯®®®­®¯­®¯¯¯¯¯¯®®¯®®®®®®®¯¯®®®¯®®®®¯®®¯¯®®¯¯®®¯¯¯®¯¯®®¯®®¯®®¯®¯®®¯®®¯®®¯¯®®¯®®¯¯®¯¯®¯®¯®®¯®®¯®¯®®­­­¬­®­®¯¯®©£ž•Ž…|s^<F…²°¯¯¯®¯¯¯®®®®®±„# R‡¨®®®¯®¯®®®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯®®¯¯®®®®¯¯¯®®¯®­®¯®®¯®®¯®®®¯¯®®®¯®®¯®®¯®®¯®®¯¯®®¯¯¯¯®¯¯­®¯¯®¯®®®¯¯®¯¯®¯¯¯¯®¯°¯®­¯¯¯¯®®¯®®¯®®¯®®®¯®­®¯®¯¯®®¯®¯¯¯¯°°±°±±¯¯°¯®®­­¯°±³©~8MŒ«±¯¯¯¯¯¯¯®®®®²„#X©°¯®¯®¯¯®®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯®®¯¯®®¯¯®¯¯¯®­®¯®¯®¯¯¯¯®¯¯®®¯®¯®®­®¯®¯®®¯¯®¯®­¯¯®®®®¯¯¯¯®®¯­®¯®¯®®¯¯¯¯¯®®ªž‘Ÿ°¯¯¯¯®¯®¯¯¯¯¯®®®¯®®­¯¯®¯¯®¯®®®®®®®¯®¯®¯®­®¯¯®¯°°°±±žVSŸ²¯¯¯¯¯¯®¯¯®¯°ƒ"XŽ©¯®®®¯®­®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®®®®¯¯®®®®®®®¯¯®®¯­®®®®®®®®¯¯¯¯®¯®®¯¯¯¯®®¯¯¯®®¯®®®®¯®®®¯®¯®¯®®®®®®®¯®¯¯¯¯®®¯°¯l±®­¯¯®®¯¯¯¯­®®¯¯®®®®®¯¯®®®®¯®®®®®¯®®¯¯¯¯®¯¯¯­ªM,g©¯®¯®¯®¯®¯¦UWŒ©°¯¯¯¯¯¯¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®¯¯®¯¯¯¯¯®¯¯¯®®®®¯¯¯¯®®®¯®®¯¯®®¯®®¯®¯®¯®®®¯®¯¯®­¯¯®¯®¯®®®®®¯®®®®­¯®®¯¯Š% {«®®¯®®¯®¯®®®¯®®®¯®¯®®®¯®¯®®¯®®®¯®®®¯®®®¯®®¯®­­RJˆ«¯¯®¯®®¯®¯¤E Q‡©®®¯®¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®­¯®®¯¯®®®®®¯®®­¯®®¯¯®®®®¯®¯¯®®®¯­®®®¯¯¯®®®®®®®¯®®®¯®¯®¯¯¯®¯¯®®®¯®®¯®¯®¯¯¯©dœ¬®®®¯®¯®¯¯®®®®¯¯®®¯­®¯®®­¯¯¯­¯®¯®¯¯®¯®®¯¯¯®®°a b­¯¯¯­¯®¯¯®¡6 K€¨°¯¯¯¯®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯¯­¯®­¯®¯¯®®¯¯®®¯¯¯®®¯®®®®¯®®¯®®®®¯®®®¯­¯®®®®¯®®®®¯®®®®®¯¯¯®¯®®®¯®¯®®®¯®®¯¯Ÿo F}¦¯®®¯¯¯¯¯®®¯®¯®®®¯®¯®®¯¯­¯¯¯®¯¯¯®®¯¯¯¯¯®¯®®¯²u8 0ª¯­®®®®®¯®«˜. Ex¦°¯®¯®®¯¯­¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­¯®¯¯¯®®®®®®¯®¯¯¯®®¯®®¯®¯¯¯¯¯®¯¯¯®®®®¯®®¯®®¯¯®¯®¯®¯®¯®®¯®¯¯¯®¯¯¯®­®­¯­¯®¯®¯¯”` #Oœ°¯¯®®®¯®¯¯¯®®¯¯®¯¯®¯®®¯®¯®¯®®¯¯®®®®®®®¯®¯¯®³‘]_–®®¯¯®®¯¯¯®¨*;n¥°¯®®®®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯®­¯¯¯¯¯¯¯®­¯¯¯¯¯®®¯¯®®®¯®®¯¯®®®¯®®¯®¯®®®®¯®®¯¯¯¯®®®¯®¯®¯¯®®¯¯¯¯®¯¯¯­®¯¯¯®®¯¯°T ,‰«¯®®¯¯®¯®¯¯®®¯¯¯¯¯®¯¯¯¯®¯®®®®®®¯®¯¯®¯¯¯¯®¯¯±¥„6 N‘­¯®¯®¯¯®¯®¯«™00b¤±®¯¯¯¯®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®¯®¯®­¯®¯®®¯®¯¯¯®¯®¯®®®®®®¯¯¯®®®¯­¯®®¯®¯¯¯®®¯¯¯¯®¯®¯­¯®®¯¯¯®®®®®®¯®®®°²†G j®°¯®®¯®¯®®®®¯®®¯¯¯­®¯®¯®­¯¯¯®®­®®¯¯¯®¯¯®®®¯³¤pC,#&0?eЍ°®¯¯¯®¯¯¯®¯® G"S¡±®®®¯®¯¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯­®®¯®®®®¯¯¯®®®®¯®¯®®®¯¯®®®®¯®¯¯®®¯®¯®¯®¯¯­®¯¯¯®®¯®¯®¯®¯®®®®®®¯®¯¯®¯®®¯­¯®®¯°´? Dƒ«²¯¯¯¯¯®®®®¯®®¯®¯¯¯¯­®¯®¯¯¯¯¯¯®®¯¯¯®¯®®¯¯¯®¯­©’wc_m† ­¯®®¯¯®¯®®¯®¯¯¨k, BŸ±¯¯¯¯¯®¯®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®¯¯¯¯®¯¯®®¯¯®®¯®®¯®¯¯®®¯®®®¯®¯®¯®®®¯®®¯®¯®®¯¯¯¯®¯®¯®¯¯¯®®¯¯¯®®®®®®¯¯±µ}4\ ±®®¯®¯¯®¯®®¯®¯®¯®®®®­®¯¯®¯¯¯®¯¯¯®®¯®¯®®®®¯¯¯²©””›¥­°°®¯®®¯¯¯¯®®®¯¬–_1œ°­¯¯¯®¯¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®­®¯¯®¯®­¯¯¯®®®®¯¯¯®®¯®®¯¯­­¯®®®¯¯®®®¯¯¯®¯¯¯¯¯¯¯¯®¯®¯®¯®¯¯®¯®®¯¯¯¯®®¯¯¯®±¶{*9Ь¯®®­­®¯®®®®¯®¯¯®®®®¯®®®®¯®®¯®¯¯®®®®®®®®®¯®®¯±±±³²°¯¯¯®®¯¯®¯®¯®¯¯¯®«|# —®®¯®®¯¯®¯®®®®®®¯¯¯¯¯¯¯¯®¯®®®¯®®¯¯¯®­¯®®¯¯®¯¯¯¯®¯®¯®®¯®¯¯®®¯¯®¯®®¯®¯¯¯®¯¯®®¯¯®®®®®®¯®®®®®®¯¯®¯®®®¯®®®®±¶}' g±¯¯¯®­®®¯¯®¯¯­­®®¯¯®¯¯®®¯¯®®¯®¯®®¯¯¯®¯®®¯®®¯¯®¯°¯¯®¯¯®®®®¯¯¯¯¯¯¯®®±“Y'Ѝ¯¯¯®®®®®®®®¯®¯¯¯¯¯¯¯¯¯®®¯®®®¯¯¯®®¯®®¯¯¯®¯¯¯®®¯¯®®¯¯®¯®¯®®®®¯®¯¯®®®®®¯¯®¯®®¯®¯®¯¯¯¯­­¯®®¯¯¯­®¯®°°°²²²´¸€' 6€¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯¯®¯¯®¯¯®®¯®®¯¯¯®®®¯¯®¯¯¯¯¯¯¯®¯¯®®¯®¯®¯¯¯®®¯®®®¯¯®°¦“LwŸ®¯®®®®®¯®¯®­¯®¯¯¯¯¯¯¯¯¯¯®¯®®¯®®®®®®®®®®®¯¯¯¯®®¯®¯¯®®®¯®®¯®¯¯®®¯¯¯®®¯¯®¯®®¯¯¯®¯®¯¯®¯¯®®¯®¯¯®®¯°¯«§¥¤¤¨²‚+[¢­°®¯¯¯¯®®¯¯®®¯®®¯®¯¯¯¯¯¯®¯®¯®¯®®¯¯¯¯¯®¯¯®¯¯®¯®¯®¯®¯®®®¯®®®®¯®¯®¯®¯­¬l' `“°¯®¯®¯®¯¯­¯®¯®¯¯¯¯¯¯¯¯®®¯®®¯®®¯¯¯¯®®¯¯¯®®®®¯¯®¯®®¯¯®¯¯®¯®®®®®®®®¯¯¯¯¯®®¯®¯®®¯®¯¯®®¯®®¯­®¯®¯®¯®¤’€wtz‰/3~¦´¯¯®®®®®¯®®¯®¯®¯®®®®®®¯¯®®®®®¯®®¯®¯®®®®¯®®¯®®®¯¯®¯®®®¯®¯¯®¯¯®¯¯¯¯®¯hGˆ±¯®®®®®¯®®®¯¯¯®¯¯¯¯¯¯¯¯®®®¯¯®®¯®®®¯®®¯¯¯¯®®¯¯®¯¯®¯¯®®®¯®¯¯®¯­­¯¯®¯¯®¯®¯¯¯¯®¯¯¯¯®®®®¯¯®®¯®¯¯®¦‘wW@957@K=H‘²¯®®¯¯®®®¯¯®®¯®®®®¯¯¯¯®¯®®¯®¯®¯®¯¯¯¯­®¯®®¯¯¯¯®¯¯¯®­¯¯¯¯¯¯®¯®®¯­¯¯®®§–?'}¯¯­¯¯¯®¯®®¯¯¯®­¯¯¯¯¯¯¯®®¯®¯¯¯®®®®®®¯®®®®¯¯¯®®®®®¯®®¯¯¯®®¯®®®¯®®®¯®®¯¯¯¯®¯¯®¯®¯¯®®­¯¯¯¯®®¯¯¯©…Iq¤°¯®®­¯¯®¯®®®¯¯®®¯®®¯¯®¯¯®®¯¯®®®¯¯®¯®¯¯®¯¯®¯®®¯®®®®¯®®¯¯¯®¯®­®®¯®®¯±«h+m±¯¯®­¯®¯®¯¯¯­­¯¯¯¯¯¯¯¯¯®¯®®¯¯¯®¯®­®®®®®¯¯¯¯®®¯®®®¯¯®®¯­®®®¯¯®¯¯¯®¯¯¯®®¯¯¯®®®®®¯®®®®®¯¯¯¯¯¯¡zG Fƒ¯°¯®®­®®¯®®®¯¯®¯®¯¯¯®¯®¯¯¯¯®®®¯®¯®®®®¯®®®®¯¯¯®®¯®¯¯¯¯¯¯¯¯®®®®®®¯®¯¯­™cY¥¬°®¯¯¯¯®®®­¯®¯®¯¯¯¯¯¯®¯®¯¯¯®®¯¯¯®¯®¯®¯¯®¯¯¯®®¯¯®¯¯®®®®¯¯¯®¯®¯®¯®®®®¯®®¯®®®¯®¯®¯®¯¯®®¯®®¯¬Œ;U«¯¯®¯®¯®®®¯¯®®¯®¯®®¯¯¯®®®®¯¯®¯¯¯®¯®¯¯¯®¯®¯¯¯¯¯¯¯®¯¯¯¯¯¯¯®®®¯¯¯­®¯¯¯®«†; K’¦°¯¯®¯¯¯¯­®¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯¯¯®¯®®®®­¯®¯®®¯®¯­®®®¯®­®¯®®®¯®®¯®®®®¯­¯¯¯®¯¯¯®¯®®¯®°®¯¯¯¯°­S 1¥±¯¯¯¯¯¯¯¯®¯¯¯®¯­®®®®¯¯¯®¯¯®¯¯®¯¯®®¯¯®¯®¯®®¯¯®­®®¯¯¯¯¯¯¯®®¯¯®­¯®¯®¯°p(8rž±¯¯®®®­®®®®¯¯®¯¯¯¯¯¯®¯®¯¯®®¯­®®¯®¯®¯¯­®¯®¯®®®¯¯¯¯®®¯¯¯®®¯®®®­®®®¯®®®¯¯®¯®®¯®¯¯¯¯¯®¯¯¯°¨s"8QRE&`•²¯®¯¯®®­®¯¯®¯¯¯®¯­¯®¯®®¯®®®®®®®¯®¯®¯®®®®®®®®¯­®®¯¯¯¯¯¯®®®¯¯®¯¯¯®¯®®¬¢OL•±¯¯¯®®­­¯¯¯®¯®¯¯¯¯¯¯®¯¯®¯¯¯¯­¯¯®¯®®¯¯®®®®¯¯®¯®®¯¯®®¯®®®®®¯®®®®®¯®¯¯®®­®¯®¯°´²ª£ ¤«°³²¬ˆKaª©™p2 8†²¯®®®®®®®­¯®®®¯¯¯®¯®®®®¯®¯®¯®¯¯¯¯­®¯®®®®®¯®®¯¯¯¯¯¯¯¯¯¯®®¯­®®­®®¯­¯®¯­K )Н®®¯®¯¯¯®®®®¯®¯¯¯¯¯¯¯¯¯®¯¯®®®®¯¯®¯®®¯®®®®­¯®®®¯®®®®®¯®®¯®®¯®¯­®®¯®¯®®¯®¯®®«¤—…wrv}‰‘\(LŠ«³²¬t?w°¯¯¯¯®¯®®¯¯¯¯­®¯®®¯¯®¯¯®¯¯®®¯¯¯®¯®¯®¯¯¯¯®®¯®®®®¯¯¯¯¯¯¯­®¯¯®¯¯­¯¯¯®®¯¯~!«®®®®¯®¯®¯®¯¯®¯¯¯¯¯¯¯®¯®®¯®®®¯®¯®®¯®¯®®¯¯¯®¯¯®®¯®®®¯¯¯®®¯¯¯®®®¯¯®®®¯®¯®¯²­—kA*(DX( 3ƒ§²®¯¯±¢mn¬®®¯®®¯¯®®¯®®®®®¯®¯¯¯®¯®®®¯¯®®¯®¯¯®®®¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®®¯¯¯®®®®¯®®®ŸKPœ«°¯¯®¯¯¯¯¯­®®¯¯¯¯¯®¯®¯¯¯®¯®®¯®¯¯®¯¯¯¯¯®¯¯®®¯®®®®®¯®®¯®®¯¯¯¯¯¯®®¯®®®¯­®°¤‡]- O¤­°®¯®¯«z hª¯¯®­®­¯®¯®®¯®¯®®®®¯¯®®®®¯®¯¯¯¯®¯®¯®¯¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯®­¯®¯®®®¯®®¯®®°©yK-|§¯®¯¯®®®¯®®¯¯®¯¯¯¯®®®®¯®®®¯®®®¯¯¯¯®®¯¯®­®¯¯¯¯¯®¯¯¯®®®¯®¯¯®¯°°¯°°¯¯¯®®­¨x=%d­°¯¯¯¯®ŽVl«®®¯¯®®®¯®¯®®¯­®®®¯¯®¯¯®¯¯®¯¯®®®¯®®®¯®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®¯¯¯®¯®¦|V¤¯®¯®¯¯¯¯®¯®®®¯¯¯¯¯¯®¯®¯®®¯®®®¯®¯­¯®¯®¯®®¯­¯®­¯¯®®¯¯®®®®¯®®«¨¦¥¨­®¯°±¥y@;v«°®®¯®¢_#)u­¯¯¯¯®®¯®®¯®¯®¯®®®®®¯¯®®®®®¯®¯®®®®®¯®®¯¯¯¯¯®¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®®¯¯¯­®¯®­–^0œ­®¯¯®®¯®®®¯®®¯¯¯¯­®®®®¯¯®®®¯®®®¯®¯®®¯®®¯®®®®¯¯®¯¯®¯®¯®¯²²³¢”ˆ‰“ ¥¨©ª‘5 ".31+=y«¯®¯°§ˆ:L‰­¯­®®¯¯¯®®®®¯¯®¯¯®®®¯®¯¯®¯¯®¯­¯®¯®®¯¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯®®¯®®®®®¯¯­¯¦ŽC †¥®¯¯¯®¯®®®®¯¯¯®®¯¯®®®®®¯¯¯¯¯¯­®®¯¯¯¯®¯¯¯®­®¯¯®®¯¯¯¯¯®®°¦’u[H< !OvŽ™Ÿ›–vI 8u¨°¯®³C 3‰ª¯¯¯¯®®®¯®®¯®¯®¯®¯®¯¯­¯®®¯®¯¯®®¯¯¯¯®®¯¯¯®­¯¯¯¯¯¯¯¯¯®®®®¯®®®¯¯®¯®¯®¯­®¯¯®®¯­š{.z­®®®¯®®®¯¯¯¯®®®¯®®®­¯¯¯¯¯®®¯®¯®¯®­¯®¯¯¯¯¯¯¯¯¯®®¯®¯­°¨‚R*  R–«®®¯°° q0m£°®¯µ9 "-kŸ®¯®¯®¯¯¯¯®¯­®¯®®®®®®¯®¯¯®®®¯®¯¯­®®®¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯¯®¯®®®¯¯®¯®®¯¯¯®­œN [©®¯­®®¯®®®®¯®¯¯¯¯®®®¯¯®¯¯¯¯®¯®®®®®®®®®¯¯®®­¯¯¯®¯¯¯¯°œQ@ƒª³°¯¯¯¯²•: #_¡±®¯µ¡I,OgoGP”¬®¯°®®¯¯®¯®¯¯¯®®­®®®¯®¯®¯®®­®®®®®¯®¯®®¯¯®®®¯¯¯¯¯¯¯¯¯®¯¯®®®¯¯¯¯®®®¯®®®¯¯®®¯®¯¯©ˆQ/ލ¯¯®®¯¯®¯¯¯¯¯¯¯®®®®®®®¯®®¯¯¯¯¯®®¯¯®®¯¯¯¯®®®®®®®®°µ–^v©°¯¯¯­®¯³¡[N™²­®³¦m) 0k•§¯z0*r¬·´³ª£¤­°¯®®®®¯¯®¯®®¯®®®¯®­¯®®®¯®¯¯®¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®®­®®®®®®®®®®®­¯®¯¯­©0b¡°®®¯¯®¯®¯®¯¯¯¯¯¯®¯®¯¯®®­®¯®®¯®®¯¯®¯¯­®¯¯¯¯¯¯¯¯°®­t'5IJ6 7‰°°®®®®¯­±¦u1 =’²¯®°¬•kLNf‚ž¬±´‘T6w¡­¤š…yz£®°®®®¯®¯®¯®®®®®®¯­®¯¯­­¯¯®®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®¯®®¯¯¯®®¯¯®®¯®®®®®¯²ši#•®®¯¯®®®®¯¯¯¯®¯®®­®®¯¯¯®®¯®®®®®¯®®¯¯¯¯®¯®®¯°±°±±©˜W>l‰‹m: Y™±¯¯¯®®®®°«ŒB'…²¯¯¯¯°¥˜™¤®±°±´“U?h}mF&D§³®­®¯¯®®¯¯¯®¯¯®¯¯®®¯®¯¯®®¯®®¯®®¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®¯®®¯¯¯®¯¯®¯¯¯¯¯¯¯®¯®®ª˜-y ®¯¯®®®®®¯®®®¯®¯¯¯®¯¯®®®®¯®®¯®¯®¯®­­¬ª¨§¬­¥œš™ˆeI#&b’¤©ª®.$u¤°¯¯¯¯¯¯®°®–Lpª±²±³µ±®±´¶µ³²µŽG -B6^Ÿ´®¯­­¯¯®¯¯®¯¯¯¯¯®¯¯®¯­­¯¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯®®®®®®¯®¯®¯®®®®®®¯¯®®¯®®¯®®®¯®¥FRƒ¬¯¯¯®¯¯®¯¯®®¯®®®®®®®¯¯®¯¯¯¯±³´´²¨˜•Ÿ“—gbcFNެ²¯°¶•I'…­²³²²³²±±²¯žV QŒœœ—•“މ‚{wtqS'   9’µ¯¯¯¯®®¯¯®®¯¯¯¯¯¯®¯®®¯¯®¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯¯®­®¯®®¯®¯®®®­¯®®®¯¯¯ªZ%X§°¯¯¯®­®®®¯®¯®¯¯®®®¯¯®®®®®­©¦¤¢˜fbi\JFWZ=,'%+y®°¯­¬±›_ %‚¡›š˜•“Žˆ†r@%GQLE@=;7,#! -‹³°®®¯®®®¯¯¯®®¯¯¯®®®¯¯®¯®®­¯¯®®¯¯¯¯¯¯¯¯¯¯®®®®®¯®®¯¯¯¯­®®®®®®®®®®®®¯®¯¯®¯©b.4—¦¯®®®¯®¯¯¯®¯®®¯¯¯®®®®¯¯®­©“{wqV%  A€¤Ÿ™“‘OYmca_[YVND><3  *ˆ³°¯®®¯®¯®¯®¯®®¯®®®®­¯®¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®®®®¯®®®¯¯¯®¯®®®¯®¯®¯¯®®°ªX$k“°®¯­®¯®®®®¯¯®¯®®¯®¯¯¯®°§ˆ]A?:( Fkytj_[YK-"' ,‹¶¯¯¯¯¯¯¯®¯®¯¯¯®¯®¯¯®®¯®¯®¯®®¯¯¯¯¯¯¯¯¯¯¯­¯¯¯¯®¯®®¯®¯¯¯¯®¯¯¯¯®®®¯®®¯¯¯®¯¯£D#s­®®¯®¯¯®­®¯¯®®¯®¯¯®®¯®¯–L     "S•³¯¯®®¯­®¯¯®®®¯®¯¯®¯¯®¯¯¯®­¯®¯¯¯¯¯¯¯¯¯¯¯¯­®¯¯®¯®®®®¯¯¯¯®®¯®­¯¯®®®¯­¯¯¯°¨&Q›©¯¯¯®¯¯®¯¯¯¯¯¯®¯¯¯®®¯£u%!$'+.42! +ACGIIEDHJNPK39OYZ\\Z]bfgjmoti:DfiC 5}¡±®®¯®®®®¯®¯®­®¯¯¯­®®¯®¯¯®¯¯­¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯®®®¯®¯®®®¯¯¯®®¯¯¯®¯¯¯¯³“R +t£±®®¯¯®®¯¯¯¯¯®®®®¯¯°°žk$ Eky}„‡‹„W$[„†ˆˆ‡…„‡‰‹‚Z9„˜¢¢££¤¥§¨©«««® `%L€Ÿu|Œ¦­¯®®¯¯®¯¯®¯¯¯®¯®¯¯®®®®®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯®®®¯®®¯¯®¯¯®®®¯¯¯¯®¯®¯®®¯¯¯¯¯¯ª”g3­¯®¯®¯¯®¯¯¯®®¯®¯¯®°¯©‹A=r¢¡ ¡¢¤e*n¥¨ªª«­«­®®¯ŸqP¨²¶µ´¶³¤¢²¸µ±±¦p2g›¶±°®¥¥©®®®¯¯®®¯®¯®¯®®¯¯¯¯¯¯¯¯®®¯¯¯®®¯¯¯¯¯¯¯¯¯¯®¯¯­¯®­®®®®¯¯®¯®¯®¯¯®¯®­¯¯¯­®¬¥•U)Y˜®®¯®®¯¯¯¯¯¯®¯®®¯®¯®¯§wJ790# [¨¯°¯°²©e# g¤±²±±±±°°°¯še^±¯¯¯¯©•o^g|£¬±¥_# 9…²°¯¯­®®®¯­¯®®¯®®¯¯®®®¯®¯®¯®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯®®®®®¯®®®¯¯®®¯®®®®®¯¯±¦[:.t¬®­®®¯®¯¯¯®¯®®®®¯¯¯®®¤•‚€q8+.?709SaF?CRD+)m¡¶±°­¡KLŠ­°¯®¯®¯¯®®”Y!f°¯¯¯¯˜a)&J‚¡ªœJ_–¯°¯¯¯¯¯®¯®¯¯¯¯®¯¯®®¯¯¯®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯®®¯®¯®®®¯¯®®¯®¯¯¬•{N8Ÿª¯¯®®¯¯¯¯¯®¯¯¯¯®®®¯®°®¨§£••– ŸŸ¥¬¯¤ž¨lI0% 6f…‘“ˆj+.kª±®¯¯¯¯®¯¯E-m°¯®¯°9 ;R\O!.a£®®®®¯¯¯¯¯®®®¯¯®®¯¯®®®¯®®­¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®®¯®®¯­®¯®®®¯¯¯¯¯®®­¯ªœ[1i–±¯¯®¯¯¯®¯®¯¯¯¯®¯®®­¯¯¯±¯­¬©®¬««®¯«ª¨¬¦Ÿ—‰q(>cjW* FŸ°°¯¯®¯®®±†( 5s®°®®²‰%  +‹¥°¯®®®¯®®¯®¯®®®¯¯®¯®¯¯¯®®¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯®®¯®¯¯®®¯®®¯¯­®®®®¯®®®¯®®¯®O +|ª®¯¯¯¯¯®®¯®¯®¯®¯®¯®®®®°¯®®¯¯®¯¯®¯¯±°¯±³³¬œK !#"yž­¯°¯¯¯­¨t=y¬¯®®²Ž+ d•¯®®¯®®¯®¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®®¯¯®®¯¯¯¯¯­®­®¯®°¤ŠJS–­®®®¯¯®¯­®®¯®¯®®¯®®¯¯­¯¯®­®¯®¯¯®¯¯¯¯®®­¯­w< 3q¤³µ³²³²“WAz«¯¯®±˜M7|¬°¯¯®®®®®¯¯®®®¯¯®®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯®®®¯®¯¯®¯®¯¯¯¯¯¯®±‘J[¨®¯®¯¯¯¯®®®¯®®¯®®¯¯¯®®®¯­®¯®¯®®¯¯¯®®¯®®°°¢> =s™œž˜`/?z«¯®¯°£z+d§°®®¯®®®¯¯®®®®®¯¯®¯®®¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®¯¯®¯®¯¯¯¯®¯¯®®®®¯®°‘IŠ¡°¯¯¯¯¯¯®¯¯¯®®¯­¯¯¯¯¯®¯¯­¯­¯®¯®¯¯¯¯¯¯¯®®°¢yM) ,MYI B`w~nV#:v©°¯®®¬žWU£°®®®®¯®¯¯¯®¯®¯¯®¯¯¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯®®¯¯¯®¯®¯®®®®®¯¯¯®¯±—^O…®®®¯¯¯­¯¯®­¯¯¯­¯®®¯®®®®®®®®¯¯¯®®¯¯®¯¯®®®­©‘k4 #?_‡•€*!+,# -j¥¯¯¯®¯¯ˆQMž°¯¯¯®¯¯¯¯®®¯¯¯¯®®®¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯¯®®®¯®®¯¯¯®®¯­¯®¯¡+Z©¯¯¯¯®®®®®¯®®®®®¯®®®®¯¯¯¯¯®®­¯®¯®¯®®¯­¯¯±«œŒ|rry†” §ª°¢\& TŸ±¯¯¯®°©‡%NŸ±®®¯¯®¯¯®¯­®¯¯®¯®¯®¯®¯­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®¯®®¯­¯®¯®¯®¯¯¯¯¯®®®®¯« B-o—®¯¯¯®®®¯¯®¯¯­®¯¯¯®¯®¯®®¯®®®®¯­®¯¯¯­®­®®¯¯®®§žšž¥¬±²±³­‘f43‰«¯¯®¯±°*V¢³°®¯®®®®®¯¯¯®®¯®®¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯®¯®¯®¯®¯®¯®®®¯®®®®¯­`$~«¯¯¯¯®®®®­®¯­®®¯®®¯¯®¯®®¯®¯¯¯¯®¯¯¯®®®®®¯®¯®®­¬­®®®®®®°³žvG(!?1Z”®±®¯²¢w"&m¥²¯¯¯®¯¯®­®¯®¯®¯®®¯¯¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯®®®¯¯®¯®¯®¯¯®¯®®¯¯yBX‘¯¯¯¯®®®®®®®¯®¯®®®®®¯®®®®®®¯®®¯¯¯®¯®¯®¯®®®¯®¯°®¯¯¯®¯®¯°¯©—m8 +GlZ- 0l™¬±¬žr; @…©±¯®®¯¯®®¯¯®®¯®®¯¯¯¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®¯®®¯¯¯®¯®¯¯¯Žd $l¦¯¯¯¯®¯¯®®¯¯¯¯¯®®¯®¯¯®®®®¯¯®¯¯¯®®¯¯¯¯¯®¯®¯®¯®®¯®®®¯®¯¯±²¬™~lccitŒš¥•i.j–¦œy> ]£­°¯®®¯®¯®®¯®®¯¯¯®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯®®¯¯®¯¯®¯®­¯®¯®®¯®®¯¡ƒBœ¯¯¯¯¯¯®®®®¯¯¯¯®¯®¯¯®®®®¯®¯¯®®®®­®¯®¯¯¯®®¯¯®¯¯®®®¯¯¯®®®¯¯°¯©¢Ÿ ¤ª®²³¨‰? 2NXL0 5€°¯¯®¯®®®¯¯®¯®¯¯®®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®¯®®®®¯¯¯­¯¯®®¯¯¯¬•  ¯¯¯¯¯¯®®¯®®¯¯¯¯®®¯®®¯®¯®¯®®¯®¯¯¯¯®®®®®¯¯®¯¯®¯¯®¯®¯¯®®¯¯°±¯­­­®¯®®¯²¨y9 eœ°¯¯¯¯¯®¯¯®¯¯®¯®®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®®¯®¯®®®®¯¯¯¯¯®®¯¯®§W°¯¯¯¯¯®®®¯®¯®®®®¯¯®®®¯®®¯®®®­®¯®®®¯¯®®®¯®®¯®¯¯¯®®®®¯®­®®®¯®°®¯¯®¯¯°­ w:4ˆ¯¯®¯®¯®®¯¯®­®®¯¯¯®¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®¯®®®®®®¯®®®®¯¯¯®®¯¯—t*v¯®¯¯¯®®¯®¯¯®¯®¯¯®¯®®®¯¯®®®¯¯¯¯¯¯¯¯®¯¯¯®¯¯®®®®®¯®¯¯®®­­®®®®¯¯¯®®®®®®°±Ÿp@`œ´®¯®¯¯¯¯®­®®®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®®¯¯¯¯¯¯®®®¯®®®¯¯®¯®q5]¦¬¯¯¯¯®®¯®¯¯®¯®¯®®¯¯®¯¯¯¯®¯®­­¯®®¯¯­®¯®­¯¯®®¯®¯¯¯®¯¯¯¯¯¯¯®¯®®®¯¯®¯¯¯¯±«_-#127‹§²®®®¯®®­¯®®®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­®¯®¯®¯­¯®®¯­¯¯¯®¯®®®¯°¤‰G3•§°¯¯¯¯¯¯®¯¯®¯®¯®¯¯®®®¯®®®®¯®®®¯¯®®®®®®­¯®¯®¯®¯¯®®¯®¯¯¯®®®¯®¯®¯®­®®®¯¯®¥”n\VYdvˆ}1V¨¯°®¯®®®¯¯¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯¯®®¯®®®¯®®­¯®®¯¯°­£†Po °®¯¯¯®®®¯¯®®¯®®®¯®­¯¯®®¯®®¯¯¯¯¯®®®¯®®¯®¯®®®¯®®¯¯¯®®®®®¯®®¯®¯®®®¯¯¯¯¯®±²°¥™’”›¤®˜;;w±°¯¯®®¯®®®¯¯®®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®®¯®¯¯®¯¯¯®®®¯­¥m8 F—°¯¯®¯¯¯¯¯®®­¯¯®®®¯¯®¯¯®¯¯®¯¯¯®®®¯¯®¯®®®®®¯¯¯¯¯®¯¯®¯®­¯¯¯­®®¯¯­®¯¯¯¯¯¯¯¯°¯¯¯¯¯¯²œ> Y•¯®¯¯®¯¯®®®¯®®®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®­¯¯¯¯®¯¯®¯®¯®¯¯¬¨‰f4‰¬¯¯®¯¯¯¯¯¯¯®®¯¯®¯®®®¯¯¯­¯®¯®¯¯¯¯®¯®¯®¯¯®¯¯¯­¯®¯®®¯¯¯®®¯¯­¯®®®®¯®¯®®¯¯®®®®¯°°°¯²ŸB y®®®®®®¯®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­®¯¯¯®®¯¯®¯®¯¯®® ŽSs ­¯®¯¯¯¯¯¯¯¯¯¯¯®®®¯¯®¯®¯¯¯¯®®®¯¯¯¯®¯®¯¯®¯®®®¯®®¯®®®®®®¯®¯¯®®¯®®¯¯®®®®®®¯®®¯¯¯¯°¢K >‡°¯¯¯®®®¯®¯®®®®®¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯®¯¯®®®®®®®­¦|+XŒ«°®®¯¯¯¯¯¯¯¯¯¯¯­®¯®®®®¯®®®®¯¯¯®¯®®¯¯®¯¯¯¯¯®®¯¯®®¯®¯¯¯¯®®®¯®¯®¯¯®¯®®®¯®­¯¯®¯®®°¥Xk™±¯¯¯¯¯®¯®®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®¯¯®®®®®¯¯¯®ª`E) ;q©°®®¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯®®¯®¯¯¯®®®®®¯®®¯®¯®®¯®­®¯¯®®¯®¯¯¯®­¯®®¯¯¯®®¯¯­¯®¯®®®°ªe)#ަ¯®¯®®®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®®®¯®¯®¯®®®®­©£ˆg8V¥°®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®­¯®­¯¯¯®®®­¯¯®®¯®¯®¯¯®®®­­¯®¯¯¯®¯®¯®¯®¯®®­¯¯¯¯®¯®°­s8=œ­¯®®®¯®®¯¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­¯®®¯¯¯®¯®¯®®¯¯®¯®­ª£‘a ;›¬¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®®®®¯¯®¯®­®¯®®¯®®®®®®¯¯®®®­¯¯®¯¯®®­®®¯¯¯¯®¯¯®¯¯®°¯‚I.^£°¯®¯¯®®®®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®®®¯®®®®¯¯®¯¯­®¯¯¯°¯©‚/ #Œ§®®¯®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®­¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯®¯®®®¯­¯®¯¯®®®®®¯®¯¯®¯®­­¯®®¯®¯¯¯‘_ G¨¯¯¯¯¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯®¯®®®®®¯¯¯¯®¯­®®®¯±“Onž°®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯®¯®¯®¯¯¯®¯®¯®¯®®®®®¯¯¯¯¯®¯¯¯®¯®®®¯®®¯®®¯¯¯qX˜¬®¯¯®®®¯¯¯®¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®¯­®°—`N“°¯¯­¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®®¯¯®®­®¯¯®®¯¯¯­®­¯®¯®¯¯®¯®¯¯®¯¯¯¯®®¯®©†h¦¯¯¯®¯¯¯®®­¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®®®¯®¯¯®¯®¯¯®¯®®±™b)ˆ°­®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®®®¯¯¯¯¯¯®¯¯®¯­®®®­®¯¯®¯®®®®¯¯®®®­®¯¯¯¯®¯±™<&w¬±®¯¯¯®®®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯­¯¯¯¯¯¯¯¯¯®®®®®¯®¯®®®¯®¯®¯®¯¯¯®®®°—[{¬®¯®¯®¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®­®®¯®®®¯¯¯®®¯®¯®¯¯¯®®¯¯¯¯®¯®¯¯®¯®­¯®®®¯¯®³¥_"<‚­±¯®¯®®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯¯®®®®¯¯®¯¯®®¯®®¯¯¯¯¯¯®®¯¯®®¯®±‘Bk¢«¯­¯®¯®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯­®®¯®¯®¯®¯¯¯®®®®®®¯¯¯®®®¯¯¯¯®®®®¯®®¯®±¬I Q®±®¯®®¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®®®®¯¯®®¯¯®¯®¯®¯­¯¯®¯¯¯¯¯¯¯®°°®©˜l!\”¨°®®®®¯®®¯­®¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯®¯®®®¯®®®®®®¯¯®¯¯®®­®®¯®¯®®®¯¯®®®¯¯«m _®°®®­®¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯¯®¯®¯®¯­®®¯®¯¯®¯®¯®®¯®¯®¯¯®¯«¦›h8I}¥±¯®¯®®¯®®¯®®­¯¯¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®¯¯®®®¯®®¯®®¯¯®­¯¯¯¯¯®®¯®®®¯¯­­®®°—hk§®¯¯®®®¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯¯¯®¯®®®­®­¯®®¯¯®¯¯¯®¯®¯®®¯®®®®•hC7f ±¯®®¯®¯®¯¯¯®¯¯¯¯®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®¯®®¯®®¯®®®®®®®¯¯¯®¯®®¯®®¯®¯®®®®¯ª”`+ o¬®°®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯®®¯¯¯®¯¯¯®®¯®®¯®¯®®¯®¯®¯¯®¯®¯¬•i-Mœ²¯®®¯®®¯®®¯®¯¯¯­¯¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯®¯¯®®¯¯¯¯®¯®¯¯®¯¯®¯¯®®®®­­¯¯®¯°¬—a"!w°¯¯®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®®®¯¯¯¯¯­®¯®®®¯¯®¯¯®¯¯¯®¯¯®©t5 :—±¯®®¯¯­®®®¯¯®¯¯¯­¯¯¯®¯¯­¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯®®¯­®¯®®¯®­¯¯¯®¯¯®®®¯¯®®®¯¯¯®®¯ª›U6Mˆ²¯®­®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯­­¯®®®®®­®¯­¯®®¯®¯¯¯®®¯¯®®¯¯®®¯®®°¨j++’®®®¯®¯¯®­®¯¯®¯¯¯®¯®®®¯®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯®¯®®¯¯®­¯¯®®­¯¯®¯¯®®¯®¯®®®®°¯¡hw˜±¯¯­­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯®¯®®¯¯¯®®®¯¯®®¯¯®®®®®¯¯¯¯®®®®¯¯©v8‹«®®¯¯®¯®¯¯­¯¯¯¯®®¯®¯®®¯®¯®®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®¯®®¯®®®¯¯®®¯®®¯¯®®­®¯®¯¯¯®¯®®¯­¬¬¬®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®¯­¯®®®¯¯®®®¯®®®¯¯®¯¯­®®®¯¯®¯®®®¯«ŒQ¦®¯®®¯¯®¯®¯®¯®®®®®¯¯®®¯¯¯¯®¯¯­¯®®®¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯¯¯®¯®®®¯¯®®¯­¯®®¯¯®¯®®¯¯®±±±°¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®¯¯¯®¯®¯¯®®®®®¯­¯®®¯®®®®®®¯®¯¯¯®¦n_ ®¯¯®®¯¯®®¯®®®¯¯®®¯®®®®®¯¯®¯®¯®®®®®®®¯®¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®¯®®®®¯¯®®®®®®®¯®¯¯®¯®®®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®­®¯®¯®®®¯¯¯®¯¯®®¯¯¯®¯®®¯¯¯¯¯¯¯®¯¯®®}U™­¯®®®¯®¯®®­¯¯®®®¯¯®­¯®¯¯®¯®®®®¯®®®¯®¯¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯®®®®¯¯®®¯¯¯®®¯¯®®®®¯¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯¯¯®®¯¯­¯®®¯¯®®®®®¯¯¯®¯®¯®®®®¯®®¯²‰/ J­¯¯¯¯®®®®¯®¯¯®¯®®®®¯¯¯®¯®®®¯¯®¯­®®¯¯¯¯¯¯¯¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯®®¯®¯¯¯¯¯®¯¯¯¯®®¯®®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®®¯®®®¯®¯¯¯®¯®¯®­¯¯®¯®¯®¯®¯®¯®¯®¯­®®²ECˆ¬¯®¯®®®®®®®®®¯¯®¯¯¯¯¯¯¯®¯¯®¯¯¯¯¯¯¯®®®®®¯¯­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®­¯¯®¯®¯¯®¯¯®®¯¯¯®¯­®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯­¯­®®®¯®¯®¯¯®¯®®®¯®¯¯¯®®®¯­¯¯®¯¯¯¯®®¯®®¯¯²‘P#=¬®¯¯¯®®®­®®¯¯¯­®¯¯®¯¯®®¯®®¯®®¯®¯¯®¯¯®®®¯®®®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®®®¯®®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®¯¯¯®¯¯®¯®¯®¯®®¯¯¯¯¯®®¯®­®®­®¯®®®¯®®®¯®®®¯¯²‘N"6z«°¯¯®¯­®¯¯®®¯®¯¯®¯®®®®¯®¯®®¯¯¯®®¯¯¯¯®®¯®­¯¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯®¯®¯®®®¯®¯¯®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯¯¯®®¯¯¯®¯®¯®®¯¯®¯¯®®®¯®®¯®®®¯®¯®®¯®®¯®®¯®¯¯®®¯¯¯¯®¯³‰3 1t«¯®¯¯¯¯¯¯®®¯®®¯®®®¯®¯®¯¯¯®®¯®¯¯®¯®®¯¯®¯®®®¯¯­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯¯­¯®®®®¯¯¯®®¯®¯¯®¯¯¯¯¯­¯®®®®¯®¯®¯®¯­¯¯®®¯¯­¯­®®¯®¯¯¯®¨x,o«®®®®®¯®¯®®®®®¯¯®®®®¯¯¯®®®¯®¯¯®®¯¯®¯¯¯¯¯®¯®¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯®®¯®­®®¯­¯¯¯®®®®¯®¯®®¯®®®¯®®®®®¯¯®®®¯¯¯®®®¯®¯®­®¬’W)kª¯®¯®¯®®®®®®¯®®®®®®®¯®¯¯¯®¯¯¯®¯¯¯®®®®®®®®®¯®®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®®¯®¯¯®¯®¯¯®®¯®­®¯®®®®¯®®¯®¯¯®®¯¯®¯­¯®¯¯®¯®®­®®­®®®­£\ (iª¯®®¯®¯®®®®¯®®®¯®¯¯¯®®®¯­®¯¯¯¯¯¯¯®¯­®¯®¯®¯¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®¯¯¯¯®¯®¯¯¯®®®®®¯¯¯­®¯®¯¯¯¯®®¯¯®¯®¯­¯®¯¯®¯®¯®®¯¯¯®¯°Ÿ/(i«®®®®®¯®¯®®®®®®¯®­¯¯¯¯®¯®®®¯®®®®¯¯®¯®®®¯®®®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®­¯­®¯®®®®®®®¯¯®®®¯¯¯­¯®®¯¯¯¯¯®®¯®®¯®®®®®®¯®¯®®¯®¯¬7'iª°®¯¯®®®®¯®¯®¯­®®¯®®¯¯®®®¯®®¯®®®¯¯®®¯¯®®®®¯®®¯¯®¯¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯¯¯¯¯®®¯®®¯¯®®¯¯®®¯¯®¯¯®¯¯¯®¯¯¯¯¯¯¯¯¯¯®¯®®®¯®¯¯®®°¯¡t> (i«¯®¯¯®¯®¯¯®¯®¯®¯¯®®¯¯®¯¯®®¯¯®¯¯®®®¯¯¯¯®¯®®¯®®®¯®¯¯¯¯¯®­¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®¯®¯®¯®¯¯¯¯®®¯¯®¯¯¯®¯¯°¯°¯¯®­­¬¬­®®¯¯°°°°¯°°¯®¯°°¯®«¤–x;(iª°¯¯®®®¯®®¯¯¯®®®¯¯®¯®¯®¯®®®®¯®®®®¯®®¯®®¯­¯®®®®®¯®®®¯¯®®¯®®®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯¯­­¯¯¯®®¯®®¯®­¯®¯¯¯­­­«©¥¡ ¡¡¥¦§ªª¬¬­¬­­­­®­­­ª¦™„U+n«°®¯¯®®®®®®¯®®®¯¯®®®¯¯¯¯¯®®®¯®¯­®¯®®®¯®­®®®¯¯®®®¯¯¯®®®¯¯¯¯®¯¯¯­®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®¯®®®¯®®¯®¯¯®¯®®¯®®¯®¨Ž{`UKFCA@BEGHMOTX[cehnprof\PF;).r«¯¯¯¯®®®®¯­®®®¯®¯¯®®¯®¯®®­®¯­®®®¯®¯®®¯¯®¯®¯¯­®¯¯®¯¯¯¯®­®®®®¯¯®¯®®¯®¯®¯®¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯®®¯®®¯¯®¯®¯®®®®¯®©˜€W@$  $)*2653, 7{«°®­®®®¯®¯®®®¯®¯®¯¯¯®®®®®®¯¯¯®®¯®®®®®®®¯®®®®®®®®®¯¯®­®¯®®®®®®¯¯®¯­®¯®®¯®¯®¯¯¯®¯®®¯¯®¯¯¯®¯®¯®®¯¯®®¯¯®¯®®®®®®®¯®¯®®®¯ª•b"J­¯¯®®¯¯®¯¯®¯¯®¯­¯¯¯¯®¯®®®¯¯®¯¯®®®¯¯¯¯­®®®¯®®¯®¯¯®¯®®®¯­®¯®®®®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®¯®®®®¯¯®®®¯®®¯®¯¯¯¯¯¯®¯®¯¯¯®®¯®¯¯®®¥Ecž­®®¯®®®®®®®¯¯¯¯®¯­®¯¯®®®¯¯¯¯¯®¯®¯®¯®¯¯®®¯¯­¯®®®¯¯®®®®¯®¯¯¯¯®®®®¯¯¯¯®®®¯®¯¯®®¯¯®¯®¯¯¯¯®®¯¯®®®¯®¯¯¯¯¯®¯®®®®¯®®®¯®®®©Š`Š©®¯®¯®®®®¯¯®®®¯®®®¯¯®®¯®®®­®®®®®®­®®®¯®®®¯®®¯®¯¯¯®®®®¯¯¯®®®¯®®®¯®®¯®®®¯¯¯¯¯®¯®®¯®¯®®¯¯®¯®¯¯¯¯®¯¯¯®®®®®¯¯¯¯®®¯®¯®¯«šO)’¯®¯¯­®®¯¯®¯¯®¯¯®¯®®­¯®®®®­¯¯®¯®¯¯¯®®®¯¯¯­¯­®¯®®®¯¯¯¯®¯®®¯®¯®®¯¯¯®®®¯¯¯¯®¯®®®®®¯¯¯¯¯®¯®¯®¯­®­¯¯¯®¯®®®¯¯¯®¯¯®­®®®®¯š^$ :•¯®¯°¯®¯®®¯¯®®®®¯¯®®®®¯¯®®¯®¯®®¯®®®®¯®®®®®¯®¯¯®®®¯¯¯®®¯¯®®¯¯®®¯¯®¯¯­®®®¯¯®®®®­®®®¯¯¯®¯¯¯®®¯¯®®­¯¯¯¯¯¯¯¯¯¯®¯¯¯®®®¬¥ƒ+ >§©¬®¯®¯®¯®®®¯­¯®®®®¯®®¯®¯­¯®¯®¯¯¯¯®®¯®®®®®¯­¯®®¯®¯®¯¯®®®®®¯¯®®¯¯®®®®¯¯¯®¯¯®®¯®¯®¯®¯¯®¯®¯¯®®¯¯®®®¯®¯®¯®®®¯®®®®¯°©‰] (CTgxŽœª°°°°¯¯®¯¯¯®¯®®¯®¯¯®¯¯®¯®¯®®®®®¯¯¯®®®¯¯®®¯®®¯®¯®¯¯¯®®¯¯¯¯®¯¯¯¯¯¯­¯®®®®®¯®¯¯®¯¯®®®®®¯®®®¯¯®¯¯¯®¯®¯®®®®¯¯¯±£]1$=Wi–¤«®¯¯®¯¯¯¯®¯®¯¯¬««­®°¯¯­¯¯®®®¯¯®®®¯­¯¯®®®¯®¯®¯®®¯®¯®®¯®¯¯¯¯¯¯­¯¯¯¯¯¯¯®¯¯¯®¯®®®¯®¯¯®®®®®®¯®®®¯¯¯®®­®®¯š:%@i€œ§­®®¯®¯®¯®®®¯¦£¢§«­®®¯®¯¯¯¯®®¯¯®®¯®­¯®¯®®¯¯¯¯¯¯¯¯¯¯¯¯®®®®¯¯¯®¯¯®®®®¯¯­¯¯¯¯®¯¯¯¯¯¯®­¯®¯®¯¯®¯®®¯®¯®¯§Œ$ "4Qm‰ž«¯°¯®®¯¯®«¢’|nr~–£¬±±¯¯¯¯®®¯®®¯¯®®®®¯¯®®®®®®¯­¯®¯¯¯¯¯¯®®®¯®®®¯®¯¯¯®¯®¯®®®®®¯®®¯¯¯®®®®®¯¯®¯®®®®”r *Rm‡• §­°¯¯¯®§•yc\\jz‹™¡ª­°®®®¯®¯®¯®¯®¯¯®®¯¯®®¯¯¯®®¯¯¯®¯¯®¯¯¯¯­¯®¯¯¯­¯¯¯¯¯®¯¯®®®¯¯®¯­¯¯¯®®¯¯®¯¯¯®~T>n¡­¯®¯®®®«¥‚Z$Pr𥝮®®®®®¯¯®®®®®¯®®¯®®¯­®®¯®®®¯®®¯®®®¯¯®­¯®®¯®¯®®¯®®­®¯®¯®­®®­¯®¯®¯¯®®®®¬b( ,Ll‘£°°¯¯¯­¡”xS.'=[Ÿ¬¯°¯®®®®®®®®®®¯¯®¯®¯®¯¯¯¯®®®¯¯®¯®¯¯¯¯®¯®¯®®¯¯®¯®¯¯¯¯¯¯¯®¯¯®¯®¯®¯¯®¯¬£K'Z~•£ª®®¯°¯¨…Y(Hw£«°®¯®¯®®¯®¯¯®®¯®®­¯¯¯¯¯®®¯®¯¯®®®¯¯®¯¯¯¯®¯®¯®®®®¯®®®¯¯®¯®®®¯®®¯®®°§’4 3z•¨®®¯®®­£}S>x­¯®®®®¯®®®®®¯¯¯®¯¯¯®®®­¯¯®®®®®¯®®¯¯®¯®®®®®¯®¯¯®®¯¯¯¯®¯®¯®®¯¯®®¯±œq">h¥­°®°­¢Žm= -S|¤¬¯¯®®®®¯®¯®¯®®®¯¯®¯¯®®¯¯¯®­¯­®®¯­¯®®¯®¯®¯¯®¯®®¯¯®¯®®¯¯®¯¯¯¯¯®°J '^‰Ÿ©®¯¯±ªŸn.Lˆœª­¯®¯®®®¯¯®®¯®®¯¯®¯®¯¯¯®®®¯®®®¯¯®­¯¯¯®¯¯®®¯®¯®¯®®®¯®®¯¯®®¯¯¯­„-a‰«®¯¯®¬¢†@$^”§±­¯®®®¯¯¯®®®®®®®¯®®®¯¯®®¯®¯¯®¯¯®¯¯¯¯¯®¯¯¯®®®¯®¯¯®¯¯®¯®®®®®¤r;s”¬®°°­¤„V&L}®°®®®®®®¯¯¯®®¯¯®¯¯®®®¯®¯®®¯¯®¯®®¯¯¯®¯®­®¯®®¯¯¯®¯®®¯®®®¯®¬‹U'g—©­®¯®­ŒP!Ey «¯¯¯¯®®®¯®®¯®¯®¯®®­¯¯®®®¯®®¯¯®¯®¯®®®¯¯®®®¯®¯®¯¯¯¯¯¯¯¯®¯ªo7 <Œ£®°®®©›\& +f–°°®®¯®¯¯¯¯¯®¯®®®­®®¯®¯¯®¯¯¯®¯®®¯¯¯¯®¯¯®®®¯®¯®®¯®¯­®¯¯¯¨P @mš§°¯¯¬e(&b‹¨¯¯¯®®¯®®®®®­®¯®®¯¯®¯¯®®¯¯­®¯®®¯¯®®®¯¯¯¯®®¯®®®¯®®®¯®¬¡9 (o“«®®®¯–\0#S”¨®¯¯¯®®¯®®¯®®­®®¯¯®¯¯®¯®­®®®¯®®®¯®¯®®¯®¯¯¯®®¯¯®®¯¯¯¦’( Q©¯­¯ª¢o/ Pzª°®®¯®­¯®®¯®®¯¯­®¯®®¯¯®®­¯­¯¯®®®¯®¯®¯¯­¯®¯®®¯®®¯¯¯œzO‹¢¯¯¯¯—v9 D¡®®¯®¯®®¯¯®®­®¯¯¯¯®¯®®®¯®¯¯¯®®¯®®­¯®¯¯®®¯¯®¯®®®°®Œ^Vˆ©®®¯®¦j-Cƒ£®¯®¯¯¯­®®®®®¯®®®¯®®¯¯¯¯¯®¯®¯¯¯­®¯®¯®­®®®¯¯®¯®¯°~? @‹¦¯¯®­ x" Eq¥°¯®­®¯¯®®®®¯®¯®¯¯®®­¯¯®¯¯®®¯®®¯®®®¯¯®®®®¯¯­¯¯¯oG…¤®¯¯®™k/5}𝝭¯®®¯¯¯®¯®¯¯®¯¯®®®®¯®¯®®¯®®®¯¯®¯¯¯¯¯¯®­®®¬¥`UЍ®¯®¬¡_Bu¨­¯®¯®®¯¯®¯¯¯¯¯®¯®®®¯­®¯¯®¯®¯¯¯¯¯®®®®¯¯¯®®°¦•MF–¦¯¯¯­”q3¦±®®®®®¯¯¯¯¯¯®¯¯¯¯®®®¯®­®®¯®¯®®¯®®®®®®¯¯®°Ÿ};R„©­¯¯¨˜T* >„¡®¯¯¯¯¯®¯­®®¯¯¯¯®¯®¯®®®¯®¯­¯®®®¯¯¯¯¯¯¯®®²˜`*O–¦°¯®«‰_S§®­¯®®¯®¯®¯®®®¯¯®®¯®®¯¯¯®¯¯®¯¯®®¯®¯¯¯®®±ŽC>®¯¯®©ŽM :Œ¢¯¯®®®¯¯®®®®¯®¯®®¯®®®¯¯®®®®¯¯¯¯®®¯®¯®¯°ƒ& S«¯¯°¤‡BIw¤­¯®®®¯¯¯®¯¯®¯¯¯®®¯¯¯®®¯¯®¯¯¯®­®¯¯¯®­¦rY¬¯®®«r@ A‡¢­®¯®¯¯®­®¯®¯®®®®¯®®®¯®®¯¯®®®¯¯¯¯®¯¬˜_f—²¯¯¯¢‰- 2|°¯¯¯®®®¯¯®¯­®®®¯®¯¯­­¯®¯­¯®­¯®¯¯¯ª‚Fnž¬¯®®£m? o¤¬¯­®¯¯­«©£ŒpM% Js«°²±®¯¯¯¦œ‘ƒvdPA.:€’ž¨­¯®¯°¯±²­¡Žl_J<0*($#  3b§®¯®¯®¯®¯®«ªª©§¥¢–Žƒ}tnjh`]]]]]]]]]]\]]\]]]\]\]]]]]\]]]]]\\]\]]\\\\\]]][]]]]]\]\]\]]]\]]]]]]\]]]]^]]\]]\]]\]\]_P Qj…šª°³°°±°¯°°°±°«¨¥¢žšš˜––––––––––—––—•––––•––—––•—––•–––––—•––•—•–——––•––——–––––––––•––—–––––––––––•—––––––˜ƒ-Cy—ž£©­®¯¯¯®¯¯¯¯±¯°°°±±±±²±°±°±±°±°°±±°¯°°°±°±°°±°°±°²°±±°±±±°°°±±°±±°°±°°°±±°±±±°±±±±°±°±±±±°°°°±±±°°±°±±²!?`w¡®¯®¯®¯¯®®®¯®¯®¯®¯®®®®®¯¯®¯®¯®®¯¯¯®®®¯¯®¯¯¯®®®¯®®®®®®¯¯®­¯®®®®®®®¯¯®®®¯®¯¯®¯¯¯®®¯¯¯®®¯®¯¯®®¯®®¯®¯®¯®±› !Nbm|†Ž™Ÿ¥ª®°²´··¸·¸····¹¸¸¸¸¸¸¸¸·¸¹¸¸¸¸·¸¸¸¸¸¸¸·¸¸¸¸·¸¹¸¸¹¸¸¸¸¸¹¸¸¸¹·¸¹¸¸¸¸¸¸·¸¸·¸¸¸¸¸¸·¸¸¸·¸·¸¸¸¸¸º¥" #-6@ELPUXZ\^a``a`_aa`aa```a``_a`````aa_`_````````a``aa`a`_a``a```a```a`a````aa_````a````a`a`````bS openigtlink-3.0.0/Examples/Point/000077500000000000000000000000001501024245700167045ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Point/CMakeLists.txt000066400000000000000000000012661501024245700214510ustar00rootroot00000000000000PROJECT(Point) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(PointClient PointClient.cxx) TARGET_LINK_LIBRARIES(PointClient OpenIGTLink) ADD_EXECUTABLE(PointServer PointServer.cxx) TARGET_LINK_LIBRARIES(PointServer OpenIGTLink) ADD_EXECUTABLE(PointListServer PointListServer.cxx) TARGET_LINK_LIBRARIES(PointListServer OpenIGTLink) ADD_EXECUTABLE(PointClient3 PointClient3.cxx) TARGET_LINK_LIBRARIES(PointClient3 OpenIGTLink) ADD_EXECUTABLE(PointServer3 PointServer3.cxx) TARGET_LINK_LIBRARIES(PointServer3 OpenIGTLink)openigtlink-3.0.0/Examples/Point/PointClient.cxx000066400000000000000000000062411501024245700216630ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlPointMessage.h" #include "igtlClientSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Transform Message Class igtl::PointMessage::Pointer pointMsg; pointMsg = igtl::PointMessage::New(); pointMsg->SetDeviceName("PointSender"); //--------------------------- // Create 1st point igtl::PointElement::Pointer point0; point0 = igtl::PointElement::New(); point0->SetName("POINT_0"); point0->SetGroupName("GROUP_0"); point0->SetRGBA(0xFF, 0x00, 0x00, 0xFF); point0->SetPosition(10.0, 20.0, 30.0); point0->SetRadius(15.0); point0->SetOwner("IMAGE_0"); //--------------------------- // Create 2nd point igtl::PointElement::Pointer point1; point1 = igtl::PointElement::New(); point1->SetName("POINT_1"); point1->SetGroupName("GROUP_0"); point1->SetRGBA(0x00, 0xFF, 0x00, 0xFF); point1->SetPosition(40.0, 50.0, 60.0); point1->SetRadius(45.0); point1->SetOwner("IMAGE_0"); //--------------------------- // Create 3rd point igtl::PointElement::Pointer point2; point2 = igtl::PointElement::New(); point2->SetName("POINT_2"); point2->SetGroupName("GROUP_0"); point2->SetRGBA(0x00, 0x00, 0xFF, 0xFF); point2->SetPosition(70.0, 80.0, 90.0); point2->SetRadius(75.0); point2->SetOwner("IMAGE_0"); //--------------------------- // Pack into the point message pointMsg->AddPointElement(point0); pointMsg->AddPointElement(point1); pointMsg->AddPointElement(point2); pointMsg->Pack(); //------------------------------------------------------------ // Send socket->Send(pointMsg->GetPackPointer(), pointMsg->GetPackSize()); //------------------------------------------------------------ // Close the socket socket->CloseSocket(); } openigtlink-3.0.0/Examples/Point/PointClient3.cxx000066400000000000000000000125431501024245700217500ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlPointMessage.h" #include "igtlClientSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 5) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; std::cerr << " Version : Version number send to the server" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int version = atoi(argv[4]); int interval = (int) (1000.0 / fps); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (version > IGTL_HEADER_VERSION_2 || version < IGTL_HEADER_VERSION_1) { std::cerr << "Invalid version number" << std::endl; exit(0); } if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Ask the server to start pushing tracking data std::cerr << "Sending GET_POINT message....." << std::endl; igtl::GetPointMessage::Pointer getPointMsg; getPointMsg = igtl::GetPointMessage::New(); getPointMsg->SetDeviceName("PointClient"); getPointMsg->SetHeaderVersion(version); getPointMsg->Pack(); socket->Send(getPointMsg->GetPackPointer(), getPointMsg->GetPackSize()); int loop = 0; while (1) { //------------------------------------------------------------ // Wait for a reply igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { std::cerr << "Connection closed." << std::endl; socket->CloseSocket(); exit(0); } if (rs != headerMsg->GetPackSize()) { std::cerr << "Message size information and actual data size don't match." << std::endl; socket->CloseSocket(); exit(0); } headerMsg->Unpack(); if (headerMsg->GetHeaderVersion() != version) { std::cerr << "Version of the client and server don't match." << std::endl; socket->CloseSocket(); exit(0); } if (strcmp(headerMsg->GetDeviceName(), "PointSender") == 0) { std::cerr << "Receiving Point data type." << std::endl; //------------------------------------------------------------ // Allocate Point Data Message Class igtl::PointMessage::Pointer pointData; pointData = igtl::PointMessage::New(); pointData->SetMessageHeader(headerMsg);//Here the version is also set pointData->AllocatePack(); // Receive body from the socket socket->Receive(pointData->GetPackBodyPointer(), pointData->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = pointData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { if (pointData->GetHeaderVersion() >= IGTL_HEADER_VERSION_2) { #if OpenIGTLink_HEADER_VERSION >= 2 int i = 0; for (std::map >::const_iterator it = pointData->GetMetaData().begin(); it != pointData->GetMetaData().end(); ++it, ++i) { std::cerr<<"The message ID is:"<< " " << pointData->GetMessageID() << std::endl; std::cerr<< it->first << " coding scheme: " << it->second.first << " " << it->second.second << std::endl; } #endif } } igtl::PointElement::Pointer point; for (int i = 0;i < pointData->GetNumberOfPointElement(); i++) { point = igtl::PointElement::New(); pointData->GetPointElement(i, point); igtlFloat32 x,y,z; point->GetPosition(x,y,z); const char * groupName = point->GetGroupName(); const char * ownerName = point->GetOwner(); std::cerr<<"point position: "<GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } openigtlink-3.0.0/Examples/Point/PointListServer.cxx000066400000000000000000000140761501024245700225540ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Image Meta Data Server Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlPointMessage.h" #include "igtlServerSocket.h" using std::ifstream; using std::stringstream; using std::cerr; typedef struct { double x; double y; double z; } Point; typedef std::vector PointList; int SendPointList(igtl::Socket::Pointer& socket, const char *devicename, PointList points); PointList DefaultPointList(); PointList ReadPointList(char* ); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments PointList pointlist; if (argc < 2 || argc > 3) { // If not correct, print usage std::cerr << "Sends OpenIGTLink point list upon POINT_GET request(s)" << std::endl; std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : [optional] file name, wherein each line contains 3 points to send" << std::endl; exit(0); } int port = atoi(argv[1]); if (argc == 2) // check number of arguments pointlist = DefaultPointList(); else if (argc == 3) { char* filename = argv[2]; pointlist = ReadPointList(filename); } igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { socket->CloseSocket(); } if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); std::cerr << "Receiving a message: " << std::endl; std::cerr << " Device Type: \"" << headerMsg->GetDeviceType() << "\"" << std::endl; std::cerr << " Device Name: \"" << headerMsg->GetDeviceName() << "\"" << std::endl; // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "GET_POINT") == 0) { socket->Skip(headerMsg->GetBodySizeToRead(), 0); SendPointList(socket, headerMsg->GetDeviceName(), pointlist); } else { // if the data type is unknown, skip reading. socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } } //------------------------------------------------------------ // Close connection (The example code never reaches to this section ...) socket->CloseSocket(); } int SendPointList(igtl::Socket::Pointer& socket, const char* name, PointList points) { std::cout << "Sending PointList" << std::endl; //------------------------------------------------------------ // Allocate Point Message Class igtl::PointMessage::Pointer pointMsg; pointMsg = igtl::PointMessage::New(); pointMsg->SetDeviceName("PointSender"); //--------------------------- // Create a point message int i = 0; PointList::iterator pt_iter; for (pt_iter = points.begin(); pt_iter != points.end(); ++pt_iter) { igtl::PointElement::Pointer point; point = igtl::PointElement::New(); stringstream pt_name; pt_name << "POINT_" << i; point->SetName(pt_name.str().c_str()); point->SetGroupName("GROUP_0"); point->SetRGBA(0x00, 0x00, 0xFF, 0xFF); point->SetPosition(pt_iter->x, pt_iter->y, pt_iter->z); point->SetRadius(75.0); point->SetOwner("IMAGE_0"); //--------------------------- // Pack into the point message pointMsg->AddPointElement(point); i++; } pointMsg->Pack(); //--------------------------- // Send socket->Send(pointMsg->GetPackPointer(), pointMsg->GetPackSize()); return 1; } //------------------------------------------------------------ // Function to create default point list PointList DefaultPointList() { PointList points; Point pt1 = {10.0, 20.0, 30.0}; Point pt2 = {40.0, 50.0, 60.0}; Point pt3 = {70.0, 80.0, 90.0}; points.push_back(pt1); points.push_back(pt2); points.push_back(pt3); return points; } //------------------------------------------------------------ // Function to read test point data PointList ReadPointList(char* filename) { PointList points; //------------------------------------------------------------ // Load point list from file // file format is x y z\n ifstream f_in(filename); std::string line; if (!f_in.is_open()) { std::cerr << "Error opening file: " << filename << std::endl; exit(0); } Point pt; while ( f_in >> pt.x >> pt.y >> pt.z ) points.push_back(pt); std::cerr << "Read: " << points.size() << " points from file." << std::endl; return points; } openigtlink-3.0.0/Examples/Point/PointServer.cxx000066400000000000000000000066251501024245700217210ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Point Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlPointMessage.h" #include "igtlServerSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //--------------------------- // Create a point message igtl::PointMessage::Pointer pointMsg; pointMsg = igtl::PointMessage::New(); pointMsg->SetDeviceName("PointSender"); //--------------------------- // Create 1st point igtl::PointElement::Pointer point0; point0 = igtl::PointElement::New(); point0->SetName("POINT_0"); point0->SetGroupName("GROUP_0"); point0->SetRGBA(0xFF, 0x00, 0x00, 0xFF); point0->SetPosition(10.0, 20.0, 30.0); point0->SetRadius(15.0); point0->SetOwner("IMAGE_0"); //--------------------------- // Create 2nd point igtl::PointElement::Pointer point1; point1 = igtl::PointElement::New(); point1->SetName("POINT_1"); point1->SetGroupName("GROUP_0"); point1->SetRGBA(0x00, 0xFF, 0x00, 0xFF); point1->SetPosition(40.0, 50.0, 60.0); point1->SetRadius(45.0); point1->SetOwner("IMAGE_0"); //--------------------------- // Create 3rd point igtl::PointElement::Pointer point2; point2 = igtl::PointElement::New(); point2->SetName("POINT_2"); point2->SetGroupName("GROUP_0"); point2->SetRGBA(0x00, 0x00, 0xFF, 0xFF); point2->SetPosition(70.0, 80.0, 90.0); point2->SetRadius(75.0); point2->SetOwner("IMAGE_0"); //--------------------------- // Pack into the point message pointMsg->AddPointElement(point0); pointMsg->AddPointElement(point1); pointMsg->AddPointElement(point2); pointMsg->Pack(); //--------------------------- // Send socket->Send(pointMsg->GetPackPointer(), pointMsg->GetPackSize()); } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) } socket->CloseSocket(); } openigtlink-3.0.0/Examples/Point/PointServer3.cxx000066400000000000000000000120511501024245700217720ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Point Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlPointMessage.h" #include "igtlServerSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == headerMsg->GetPackSize()) { headerMsg->Unpack(); int version = headerMsg->GetHeaderVersion(); if (strcmp(headerMsg->GetDeviceType(), "GET_POINT") == 0) { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { //--------------------------- // Create a point message igtl::PointMessage::Pointer pointMsg; pointMsg = igtl::PointMessage::New(); pointMsg->SetHeaderVersion(version); pointMsg->SetDeviceName("PointSender"); //--------------------------- // Create 1st point igtl::PointElement::Pointer point0; point0 = igtl::PointElement::New(); point0->SetName("POINT_0"); point0->SetGroupName("GROUP_0"); point0->SetRGBA(0xFF, 0x00, 0x00, 0xFF); point0->SetPosition(10.0, 20.0, 30.0); point0->SetRadius(15.0); point0->SetOwner("IMAGE_0"); //--------------------------- // Create 2nd point igtl::PointElement::Pointer point1; point1 = igtl::PointElement::New(); point1->SetName("POINT_1"); point1->SetGroupName("GROUP_0"); point1->SetRGBA(0x00, 0xFF, 0x00, 0xFF); point1->SetPosition(40.0, 50.0, 60.0); point1->SetRadius(45.0); point1->SetOwner("IMAGE_0"); //--------------------------- // Create 3rd point igtl::PointElement::Pointer point2; point2 = igtl::PointElement::New(); point2->SetName("POINT_2"); point2->SetGroupName("GROUP_0"); point2->SetRGBA(0x00, 0x00, 0xFF, 0xFF); point2->SetPosition(70.0, 80.0, 90.0); point2->SetRadius(75.0); point2->SetOwner("IMAGE_0"); //--------------------------- // Pack into the point message pointMsg->AddPointElement(point0); pointMsg->AddPointElement(point1); pointMsg->AddPointElement(point2); pointMsg->SetHeaderVersion(headerMsg->GetHeaderVersion()); #if OpenIGTLink_HEADER_VERSION >= 2 if (headerMsg->GetHeaderVersion() == IGTL_HEADER_VERSION_2) { pointMsg->SetMetaDataElement("First patient age", IANA_TYPE_US_ASCII, "22"); pointMsg->SetMetaDataElement("Second patient age", IANA_TYPE_US_ASCII, "25"); pointMsg->SetMessageID(i); } #endif pointMsg->Pack(); //--------------------------- // Send socket->Send(pointMsg->GetPackPointer(), pointMsg->GetPackSize()); } } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) } socket->CloseSocket(); } openigtlink-3.0.0/Examples/PolyData/000077500000000000000000000000001501024245700173305ustar00rootroot00000000000000openigtlink-3.0.0/Examples/PolyData/CMakeLists.txt000066400000000000000000000007041501024245700220710ustar00rootroot00000000000000PROJECT(PolyData) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ## igtl::PolyDataMessage examples ADD_EXECUTABLE(PolyDataServer PolyDataServer.cxx) TARGET_LINK_LIBRARIES(PolyDataServer OpenIGTLink) ADD_EXECUTABLE(PolyDataClient PolyDataClient.cxx) TARGET_LINK_LIBRARIES(PolyDataClient OpenIGTLink) openigtlink-3.0.0/Examples/PolyData/PolyDataClient.cxx000066400000000000000000000226201501024245700227320ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Image Meta Data Client Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include "igtlOSUtil.h" #include "igtlPolyDataMessage.h" #include "igtlClientSocket.h" int ReceivePolyData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // loop for (int i = 0; i < 10; i ++) { //------------------------------------------------------------ // Send request data igtl::GetPolyDataMessage::Pointer getPolyDataMsg; getPolyDataMsg = igtl::GetPolyDataMessage::New(); getPolyDataMsg->SetDeviceName("Client"); getPolyDataMsg->Pack(); socket->Send(getPolyDataMsg->GetPackPointer(), getPolyDataMsg->GetPackSize()); //------------------------------------------------------------ // Wait for a reply igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { std::cerr << "Connection closed." << std::endl; socket->CloseSocket(); exit(0); } if (rs != headerMsg->GetPackSize()) { std::cerr << "Message size information and actual data size don't match." << std::endl; exit(0); } headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "POLYDATA") == 0) { ReceivePolyData(socket, headerMsg); } else { std::cerr << "Invalid response from the server:" << headerMsg->GetDeviceName() << std::endl; exit(0); } igtl::Sleep(500); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } int ReceivePolyData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving POLYDATA data type." << std::endl; // Create a message buffer to receive transform data igtl::PolyDataMessage::Pointer PolyData; PolyData = igtl::PolyDataMessage::New(); PolyData->SetMessageHeader(header); PolyData->AllocatePack(); // Receive transform data from the socket socket->Receive(PolyData->GetPackBodyPointer(), PolyData->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = PolyData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { igtl::PolyDataPointArray::Pointer pointsArray = PolyData->GetPoints(); igtl::PolyDataCellArray::Pointer verticesArray = PolyData->GetVertices(); igtl::PolyDataCellArray::Pointer linesArray = PolyData->GetLines(); igtl::PolyDataCellArray::Pointer polygonsArray = PolyData->GetPolygons(); igtl::PolyDataCellArray::Pointer triangleStripsArray = PolyData->GetTriangleStrips(); std::cerr << "========== PolyData Contents ==========" << std::endl; if (pointsArray.IsNotNull()) { std::cerr << " ------ Points ------" << std::endl; for (int i = 0; i < pointsArray->GetNumberOfPoints(); i ++) { igtlFloat32 point[3]; pointsArray->GetPoint(i, point); std::cerr << " point[" << i << "] = (" << point[0] << ", " << point[1] << ", " << point[2] << ")" << std::endl; } } if (verticesArray.IsNotNull()) { std::cerr << " ------ Vertices ------" << std::endl; for (unsigned int i = 0; i < verticesArray->GetNumberOfCells(); i ++) { std::list cell; verticesArray->GetCell(i, cell); std::list::iterator iter; iter = cell.begin(); if (iter != cell.end()) { std::cerr << " cell[" << i << "] = (" << *iter; for (; iter != cell.end(); iter ++) { std::cerr << ", " << *iter; } std::cerr << ")" << std::endl; } } } if (linesArray.IsNotNull()) { std::cerr << " ------ Lines ------" << std::endl; for (unsigned int i = 0; i < linesArray->GetNumberOfCells(); i ++) { std::list cell; linesArray->GetCell(i, cell); std::list::iterator iter; iter = cell.begin(); if (iter != cell.end()) { std::cerr << " cell[" << i << "] = (" << *iter; for (; iter != cell.end(); iter ++) { std::cerr << ", " << *iter; } std::cerr << ")" << std::endl; } } } if (polygonsArray.IsNotNull()) { std::cerr << " ------ Polygons ------" << std::endl; for (unsigned int i = 0; i < polygonsArray->GetNumberOfCells(); i ++) { std::list cell; polygonsArray->GetCell(i, cell); std::list::iterator iter; iter = cell.begin(); if (iter != cell.end()) { std::cerr << " cell[" << i << "] = (" << *iter; for (; iter != cell.end(); iter ++) { std::cerr << ", " << *iter; } std::cerr << ")" << std::endl; } } } if (triangleStripsArray.IsNotNull()) { std::cerr << " ------ TriangleStrips ------" << std::endl; for (unsigned int i = 0; i < triangleStripsArray->GetNumberOfCells(); i ++) { std::list cell; triangleStripsArray->GetCell(i, cell); std::list::iterator iter; iter = cell.begin(); if (iter != cell.end()) { std::cerr << " cell[" << i << "] = (" << *iter; for (; iter != cell.end(); iter ++) { std::cerr << ", " << *iter; } std::cerr << ")" << std::endl; } } } unsigned int nAttr = PolyData->GetNumberOfAttributes(); for (unsigned int i = 0; i < nAttr; i ++) { std::cerr << " ------ Attributes #" << i << " ------" << std::endl; igtl::PolyDataAttribute * p = PolyData->GetAttribute(i); if (p) { std::cerr << " Name = " << p->GetName() << std::endl; std::cerr << " Type = "; switch (p->GetType()) { case igtl::PolyDataAttribute::POINT_SCALAR: std::cerr << "POINT_SCALAR" << std::endl; break; case igtl::PolyDataAttribute::POINT_VECTOR: std::cerr << "POINT_VECTOR" << std::endl; break; case igtl::PolyDataAttribute::POINT_NORMAL: std::cerr << "POINT_NORMAL" << std::endl; break; case igtl::PolyDataAttribute::POINT_TENSOR: std::cerr << "POINT_TENSOR" << std::endl; break; case igtl::PolyDataAttribute::POINT_RGBA: std::cerr << "POINT_RGBA" << std::endl; break; case igtl::PolyDataAttribute::CELL_SCALAR: std::cerr << "CELL_SCALAR" << std::endl; break; case igtl::PolyDataAttribute::CELL_VECTOR: std::cerr << "CELL_VECTOR" << std::endl; break; case igtl::PolyDataAttribute::CELL_NORMAL: std::cerr << "CELL_NORMAL" << std::endl; break; case igtl::PolyDataAttribute::CELL_TENSOR: std::cerr << "CELL_TENSOR" << std::endl; break; case igtl::PolyDataAttribute::CELL_RGBA: std::cerr << "CELL_RGBA" << std::endl; break; } unsigned int size = p->GetSize(); unsigned int ncomp = p->GetNumberOfComponents(); igtlFloat32 * data = new igtlFloat32[ncomp]; for (unsigned int j = 0; j < size; j ++) { p->GetNthData(j, data); std::cerr << " data[" << j << "] = (" << data[0]; for (unsigned int k = 1; k < ncomp; k ++) { std::cerr << ", " << data[k]; } std::cerr << ")" << std::endl; } } } std::cerr << "================================" << std::endl; return 1; } return 0; } openigtlink-3.0.0/Examples/PolyData/PolyDataServer.cxx000066400000000000000000000121311501024245700227560ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Image Meta Data Server Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlServerSocket.h" #include "igtlPolyDataMessage.h" int SendPolyData(igtl::Socket::Pointer& socket, const char* name); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { socket->CloseSocket(); } if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "GET_POLYDATA") == 0) { std::cerr << "Received a GET_POLYDATA message." << std::endl; //socket->Skip(headerMsg->GetBodySizeToRead(), 0); SendPolyData(socket, headerMsg->GetDeviceName()); } else { // if the data type is unknown, skip reading. std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } } //------------------------------------------------------------ // Close connection (The example code never reaches to this section ...) socket->CloseSocket(); } int SendPolyData(igtl::Socket::Pointer& socket, const char* name) { //------------------------------------------------------------ // Allocate Status Message Class igtl::PolyDataMessage::Pointer polyDataMsg; polyDataMsg = igtl::PolyDataMessage::New(); // NOTE: the server should send a message with the same device name // as the received query message. polyDataMsg->SetDeviceName(name); // Geometry data static igtlFloat32 pointsData[8][3]={{0,0,0}, {1,0,0}, {1,1,0}, {0,1,0}, {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1}}; static igtlUint32 polyData[6][4]={{0,3,2,1}, {4,5,6,7}, {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7}}; static igtlFloat32 attributeData[8]={0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // Create point array igtl::PolyDataPointArray::Pointer pointArray; pointArray = igtl::PolyDataPointArray::New(); for (unsigned int i = 0; i < 8; i ++) { pointArray->AddPoint(pointsData[i]); } polyDataMsg->SetPoints(pointArray); // Create polygon array igtl::PolyDataCellArray::Pointer polyArray; polyArray = igtl::PolyDataCellArray::New(); for (unsigned int i = 0; i < 6; i ++) { polyArray->AddCell(4, polyData[i]); } polyDataMsg->SetPolygons(polyArray); // Create attribute array igtl::PolyDataAttribute::Pointer attribute; attribute = igtl::PolyDataAttribute::New(); attribute->SetType(igtl::PolyDataAttribute::POINT_SCALAR); attribute->SetName("attr"); attribute->SetSize(8); attribute->SetData(attributeData); polyDataMsg->ClearAttributes(); polyDataMsg->AddAttribute(attribute); polyDataMsg->Pack(); std::cerr << "Size of pack: " << polyDataMsg->GetPackSize() << std::endl; std::cerr << "Name of type: " << polyDataMsg->GetDeviceType() << std::endl; std::cerr << "Sending a POLYDATA message..." << std::endl; socket->Send(polyDataMsg->GetPackPointer(), polyDataMsg->GetPackSize()); return 1; } openigtlink-3.0.0/Examples/QuaternionTrackingData/000077500000000000000000000000001501024245700222155ustar00rootroot00000000000000openigtlink-3.0.0/Examples/QuaternionTrackingData/CMakeLists.txt000066400000000000000000000010051501024245700247510ustar00rootroot00000000000000PROJECT(QuaternionTrackingData) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(QuaternionTrackingDataClient QuaternionTrackingDataClient.cxx) TARGET_LINK_LIBRARIES(QuaternionTrackingDataClient OpenIGTLink) ADD_EXECUTABLE(QuaternionTrackingDataServer QuaternionTrackingDataServer.cxx) TARGET_LINK_LIBRARIES(QuaternionTrackingDataServer OpenIGTLink) openigtlink-3.0.0/Examples/QuaternionTrackingData/QuaternionTrackingDataClient.cxx000066400000000000000000000136501501024245700305070ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Quaternion Tracking Data Client Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlQuaternionTrackingDataMessage.h" #include "igtlClientSocket.h" int ReceiveQuaternionTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 4) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Ask the server to start pushing quaternion tracking data std::cerr << "Sending STT_QTDATA message....." << std::endl; igtl::StartQuaternionTrackingDataMessage::Pointer startQuaternionTrackingMsg; startQuaternionTrackingMsg = igtl::StartQuaternionTrackingDataMessage::New(); startQuaternionTrackingMsg->SetDeviceName("QTDataClient"); startQuaternionTrackingMsg->SetResolution(interval); startQuaternionTrackingMsg->SetCoordinateName("Patient"); startQuaternionTrackingMsg->Pack(); socket->Send(startQuaternionTrackingMsg->GetPackPointer(), startQuaternionTrackingMsg->GetPackSize()); int loop = 0; while (1) { //------------------------------------------------------------ // Wait for a reply igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { std::cerr << "Connection closed." << std::endl; socket->CloseSocket(); exit(0); } if (rs != headerMsg->GetPackSize()) { std::cerr << "Message size information and actual data size don't match." << std::endl; socket->CloseSocket(); exit(0); } headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "QTDATA") == 0) { ReceiveQuaternionTrackingData(socket, headerMsg); } else { std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } if (++loop >= 10) // if received 100 times { //------------------------------------------------------------ // Ask the server to stop pushing quaternion tracking data std::cerr << "Sending STP_QTDATA message....." << std::endl; igtl::StopQuaternionTrackingDataMessage::Pointer stopQuaternionTrackingMsg; stopQuaternionTrackingMsg = igtl::StopQuaternionTrackingDataMessage::New(); stopQuaternionTrackingMsg->SetDeviceName("QTDataClient"); stopQuaternionTrackingMsg->Pack(); socket->Send(stopQuaternionTrackingMsg->GetPackPointer(), stopQuaternionTrackingMsg->GetPackSize()); loop = 0; } } } int ReceiveQuaternionTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving QTDATA data type." << std::endl; //------------------------------------------------------------ // Allocate QuaternionTrackingData Message Class igtl::QuaternionTrackingDataMessage::Pointer quaternionTrackingData; quaternionTrackingData = igtl::QuaternionTrackingDataMessage::New(); quaternionTrackingData->SetMessageHeader(header); quaternionTrackingData->AllocatePack(); // Receive body from the socket socket->Receive(quaternionTrackingData->GetPackBodyPointer(), quaternionTrackingData->GetPackBodySize()); // Deserialize position and quaternion (orientation) data // If you want to skip CRC check, call Unpack() without argument. int c = quaternionTrackingData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = quaternionTrackingData->GetNumberOfQuaternionTrackingDataElements(); for (int i = 0; i < nElements; i ++) { igtl::QuaternionTrackingDataElement::Pointer quaternionTrackingElement; quaternionTrackingData->GetQuaternionTrackingDataElement(i, quaternionTrackingElement); float position[3]; float quaternion[4]; quaternionTrackingElement->GetPosition(position); quaternionTrackingElement->GetQuaternion(quaternion); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << quaternionTrackingElement->GetName() << std::endl; std::cerr << " Type : " << (int) quaternionTrackingElement->GetType() << std::endl; std::cerr << " Position : "; igtl::PrintVector3(position); std::cerr << " Quaternion : "; igtl::PrintVector4(quaternion); std::cerr << "================================" << std::endl; } return 1; } return 0; } openigtlink-3.0.0/Examples/QuaternionTrackingData/QuaternionTrackingDataServer.cxx000066400000000000000000000233461501024245700305420ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Quaternion Tracking Data Server Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlServerSocket.h" #include "igtlQuaternionTrackingDataMessage.h" #include "igtlMultiThreader.h" void* ThreadFunction(void* ptr); int SendQuaternionTrackingData(igtl::Socket::Pointer& socket, igtl::QuaternionTrackingDataMessage::Pointer& quaternionTrackingMsg); void GetRandomTestPositionAndQuaternion(float position[3], float quaternion[4], float phi, float theta); typedef struct { int nloop; igtl::MutexLock::Pointer glock; igtl::Socket::Pointer socket; int interval; int stop; } ThreadData; int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); ThreadData td; while (1) { //------------------------------------------------------------ // Waiting for Connection int threadID = -1; igtl::Socket::Pointer socket; socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // loop for (;;) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { if (threadID >= 0) { td.stop = 1; threader->TerminateThread(threadID); threadID = -1; } std::cerr << "Disconnecting the client." << std::endl; td.socket = NULL; // VERY IMPORTANT. Completely remove the instance. socket->CloseSocket(); break; } if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "STT_QTDATA") == 0) { std::cerr << "Received a STT_QTDATA message." << std::endl; igtl::StartQuaternionTrackingDataMessage::Pointer startQuaternionTracking; startQuaternionTracking = igtl::StartQuaternionTrackingDataMessage::New(); startQuaternionTracking->SetMessageHeader(headerMsg); startQuaternionTracking->AllocatePack(); int r2 = socket->Receive(startQuaternionTracking->GetPackBodyPointer(), startQuaternionTracking->GetPackBodySize()); int c = startQuaternionTracking->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { td.interval = startQuaternionTracking->GetResolution(); td.glock = glock; td.socket = socket; td.stop = 0; threadID = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); } } else if (strcmp(headerMsg->GetDeviceType(), "STP_QTDATA") == 0) { socket->Skip(headerMsg->GetBodySizeToRead(), 0); std::cerr << "Received a STP_QTDATA message." << std::endl; if (threadID >= 0) { td.stop = 1; threader->TerminateThread(threadID); threadID = -1; std::cerr << "Disconnecting the client." << std::endl; td.socket = NULL; // VERY IMPORTANT. Completely remove the instance. socket->CloseSocket(); } break; } else { std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } } //------------------------------------------------------------ // Close connection (The example code never reaches to this section ...) serverSocket->CloseSocket(); } void* ThreadFunction(void* ptr) { //------------------------------------------------------------ // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); //int id = info->ThreadID; //int nThread = info->NumberOfThreads; ThreadData* td = static_cast(info->UserData); //------------------------------------------------------------ // Get user data igtl::MutexLock::Pointer glock = td->glock; long interval = td->interval; std::cerr << "Interval = " << interval << " (ms)" << std::endl; //long interval = 1000; //long interval = (id + 1) * 100; // (ms) igtl::Socket::Pointer& socket = td->socket; //------------------------------------------------------------ // Allocate QuaternionTrackingData Message Class // // NOTE: QuaternionTrackingDataElement class instances are // allocated before the loop starts to avoid // reallocation in each image transfer. igtl::QuaternionTrackingDataMessage::Pointer quaternionTrackingMsg; quaternionTrackingMsg = igtl::QuaternionTrackingDataMessage::New(); igtl::QuaternionTrackingDataElement::Pointer quaternionTrackElement0; quaternionTrackElement0 = igtl::QuaternionTrackingDataElement::New(); quaternionTrackElement0->SetName("Channel 0"); quaternionTrackElement0->SetType(igtl::QuaternionTrackingDataElement::TYPE_TRACKER); igtl::QuaternionTrackingDataElement::Pointer quaternionTrackElement1; quaternionTrackElement1 = igtl::QuaternionTrackingDataElement::New(); quaternionTrackElement1->SetName("Channel 1"); quaternionTrackElement1->SetType(igtl::QuaternionTrackingDataElement::TYPE_6D); igtl::QuaternionTrackingDataElement::Pointer quaternionTrackElement2; quaternionTrackElement2 = igtl::QuaternionTrackingDataElement::New(); quaternionTrackElement2->SetName("Channel 2"); quaternionTrackElement2->SetType(igtl::QuaternionTrackingDataElement::TYPE_5D); quaternionTrackingMsg->AddQuaternionTrackingDataElement(quaternionTrackElement0); quaternionTrackingMsg->AddQuaternionTrackingDataElement(quaternionTrackElement1); quaternionTrackingMsg->AddQuaternionTrackingDataElement(quaternionTrackElement2); //------------------------------------------------------------ // Loop while (!td->stop) { quaternionTrackingMsg->SetDeviceName("Tracker"); glock->Lock(); SendQuaternionTrackingData(socket, quaternionTrackingMsg); glock->Unlock(); igtl::Sleep(interval); } //glock->Lock(); //std::cerr << "Thread #" << id << ": end." << std::endl; //glock->Unlock(); return NULL; } int SendQuaternionTrackingData(igtl::Socket::Pointer& socket, igtl::QuaternionTrackingDataMessage::Pointer& quaternionTrackingMsg) { static float phi0 = 0.0; static float theta0 = 0.0; static float phi1 = 0.0; static float theta1 = 0.0; static float phi2 = 0.0; static float theta2 = 0.0; float position[3]; float quaternion[4]; igtl::QuaternionTrackingDataElement::Pointer ptr; // Channel 0 quaternionTrackingMsg->GetQuaternionTrackingDataElement(0, ptr); GetRandomTestPositionAndQuaternion(position, quaternion, phi0, theta0); ptr->SetPosition(position); ptr->SetQuaternion(quaternion); // Channel 1 quaternionTrackingMsg->GetQuaternionTrackingDataElement(1, ptr); GetRandomTestPositionAndQuaternion(position, quaternion, phi1, theta1); ptr->SetPosition(position); ptr->SetQuaternion(quaternion); // Channel 2 quaternionTrackingMsg->GetQuaternionTrackingDataElement(2, ptr); GetRandomTestPositionAndQuaternion(position, quaternion, phi2, theta2); ptr->SetPosition(position); ptr->SetQuaternion(quaternion); quaternionTrackingMsg->Pack(); socket->Send(quaternionTrackingMsg->GetPackPointer(), quaternionTrackingMsg->GetPackSize()); phi0 += 0.1; phi1 += 0.2; phi2 += 0.3; theta0 += 0.2; theta1 += 0.1; theta2 += 0.05; return 0; } //------------------------------------------------------------ // Function to generate random position and orientation (quaternion). void GetRandomTestPositionAndQuaternion(float position[3], float quaternion[4], float phi, float theta) { // random position position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); phi = phi + 0.2; // random orientation quaternion[0]=0.0; quaternion[1]=0.6666666666*cos(theta); quaternion[2]=0.577350269189626; quaternion[3]=0.6666666666*sin(theta); theta = theta + 0.1; //igtl::PrintVector3(position); //igtl::PrintVector4(quaternion); } openigtlink-3.0.0/Examples/Receiver/000077500000000000000000000000001501024245700173575ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Receiver/CMakeLists.txt000066400000000000000000000006301501024245700221160ustar00rootroot00000000000000PROJECT(Receiver) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(ReceiveServer ReceiveServer.cxx) TARGET_LINK_LIBRARIES(ReceiveServer OpenIGTLink) ADD_EXECUTABLE(ReceiveClient ReceiveClient.cxx) TARGET_LINK_LIBRARIES(ReceiveClient OpenIGTLink) openigtlink-3.0.0/Examples/Receiver/ReceiveClient.cxx000066400000000000000000000474271501024245700226420ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Data Receiving Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlTransformMessage.h" #include "igtlPositionMessage.h" #include "igtlImageMessage.h" #include "igtlClientSocket.h" #include "igtlStatusMessage.h" #if OpenIGTLink_PROTOCOL_VERSION >= 2 #include "igtlPointMessage.h" #include "igtlTrajectoryMessage.h" #include "igtlStringMessage.h" #include "igtlTrackingDataMessage.h" #include "igtlQuaternionTrackingDataMessage.h" #include "igtlCapabilityMessage.h" #endif // OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceiveTransform(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceivePosition(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveImage(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveStatus(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); #if OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceivePoint(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveTrajectory(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveString(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int ReceiveQuaternionTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int ReceiveCapability(igtl::Socket * socket, igtl::MessageHeader * header); #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // Allocate a time stamp igtl::TimeStamp::Pointer ts; ts = igtl::TimeStamp::New(); while (1) { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int r = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (r == 0) { socket->CloseSocket(); exit(0); } if (r != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); // Get time stamp igtlUint32 sec; igtlUint32 nanosec; headerMsg->GetTimeStamp(ts); ts->GetTimeStamp(&sec, &nanosec); std::cerr << "Time stamp: " << sec << "." << std::setw(9) << std::setfill('0') << nanosec << std::endl; // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "TRANSFORM") == 0) { ReceiveTransform(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "POSITION") == 0) { ReceivePosition(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "IMAGE") == 0) { ReceiveImage(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "STATUS") == 0) { ReceiveStatus(socket, headerMsg); } #if OpenIGTLink_PROTOCOL_VERSION >= 2 else if (strcmp(headerMsg->GetDeviceType(), "POINT") == 0) { ReceivePoint(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "TRAJ") == 0) { ReceiveTrajectory(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "STRING") == 0) { ReceiveString(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "TDATA") == 0) { ReceiveTrackingData(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "QTDATA") == 0) { ReceiveQuaternionTrackingData(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "CAPABILITY") == 0) { ReceiveCapability(socket, headerMsg);; } #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 else { std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } //------------------------------------------------------------ // Close connection (The example code never reaches this section ...) socket->CloseSocket(); } int ReceiveTransform(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving TRANSFORM data type." << std::endl; // Create a message buffer to receive transform data igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); transMsg->SetMessageHeader(header); transMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(transMsg->GetPackBodyPointer(), transMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = transMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the transform data igtl::Matrix4x4 matrix; transMsg->GetMatrix(matrix); igtl::PrintMatrix(matrix); std::cerr << std::endl; return 1; } return 0; } int ReceivePosition(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving POSITION data type." << std::endl; // Create a message buffer to receive transform data igtl::PositionMessage::Pointer positionMsg; positionMsg = igtl::PositionMessage::New(); positionMsg->SetMessageHeader(header); positionMsg->AllocatePack(); // Receive position position data from the socket socket->Receive(positionMsg->GetPackBodyPointer(), positionMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = positionMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the transform data float position[3]; float quaternion[4]; positionMsg->GetPosition(position); positionMsg->GetQuaternion(quaternion); std::cerr << "position = (" << position[0] << ", " << position[1] << ", " << position[2] << ")" << std::endl; std::cerr << "quaternion = (" << quaternion[0] << ", " << quaternion[1] << ", " << quaternion[2] << ", " << quaternion[3] << ")" << std::endl << std::endl; return 1; } return 0; } int ReceiveImage(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving IMAGE data type." << std::endl; // Create a message buffer to receive transform data igtl::ImageMessage::Pointer imgMsg; imgMsg = igtl::ImageMessage::New(); imgMsg->SetMessageHeader(header); imgMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(imgMsg->GetPackBodyPointer(), imgMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = imgMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the image data int size[3]; // image dimension float spacing[3]; // spacing (mm/pixel) int svsize[3]; // sub-volume size int svoffset[3]; // sub-volume offset int scalarType; // scalar type int endian; // endian scalarType = imgMsg->GetScalarType(); endian = imgMsg->GetEndian(); imgMsg->GetDimensions(size); imgMsg->GetSpacing(spacing); imgMsg->GetSubVolume(svsize, svoffset); std::cerr << "Device Name : " << imgMsg->GetDeviceName() << std::endl; std::cerr << "Scalar Type : " << scalarType << std::endl; std::cerr << "Endian : " << endian << std::endl; std::cerr << "Dimensions : (" << size[0] << ", " << size[1] << ", " << size[2] << ")" << std::endl; std::cerr << "Spacing : (" << spacing[0] << ", " << spacing[1] << ", " << spacing[2] << ")" << std::endl; std::cerr << "Sub-Volume dimensions : (" << svsize[0] << ", " << svsize[1] << ", " << svsize[2] << ")" << std::endl; std::cerr << "Sub-Volume offset : (" << svoffset[0] << ", " << svoffset[1] << ", " << svoffset[2] << ")" << std::endl << std::endl; return 1; } return 0; } int ReceiveStatus(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving STATUS data type." << std::endl; // Create a message buffer to receive transform data igtl::StatusMessage::Pointer statusMsg; statusMsg = igtl::StatusMessage::New(); statusMsg->SetMessageHeader(header); statusMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(statusMsg->GetPackBodyPointer(), statusMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = statusMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { std::cerr << "========== STATUS ==========" << std::endl; std::cerr << " Code : " << statusMsg->GetCode() << std::endl; std::cerr << " SubCode : " << statusMsg->GetSubCode() << std::endl; std::cerr << " Error Name: " << statusMsg->GetErrorName() << std::endl; std::cerr << " Status : " << statusMsg->GetStatusString() << std::endl; std::cerr << "============================" << std::endl << std::endl; } return 0; } #if OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceivePoint(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving POINT data type." << std::endl; // Create a message buffer to receive transform data igtl::PointMessage::Pointer pointMsg; pointMsg = igtl::PointMessage::New(); pointMsg->SetMessageHeader(header); pointMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(pointMsg->GetPackBodyPointer(), pointMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = pointMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = pointMsg->GetNumberOfPointElement(); for (int i = 0; i < nElements; i ++) { igtl::PointElement::Pointer pointElement; pointMsg->GetPointElement(i, pointElement); igtlUint8 rgba[4]; pointElement->GetRGBA(rgba); igtlFloat32 pos[3]; pointElement->GetPosition(pos); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << pointElement->GetName() << std::endl; std::cerr << " GroupName : " << pointElement->GetGroupName() << std::endl; std::cerr << " RGBA : ( " << (int)rgba[0] << ", " << (int)rgba[1] << ", " << (int)rgba[2] << ", " << (int)rgba[3] << " )" << std::endl; std::cerr << " Position : ( " << std::fixed << pos[0] << ", " << pos[1] << ", " << pos[2] << " )" << std::endl; std::cerr << " Radius : " << std::fixed << pointElement->GetRadius() << std::endl; std::cerr << " Owner : " << pointElement->GetOwner() << std::endl; std::cerr << "================================" << std::endl << std::endl; } } return 1; } int ReceiveTrajectory(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving TRAJECTORY data type." << std::endl; // Create a message buffer to receive transform data igtl::TrajectoryMessage::Pointer trajectoryMsg; trajectoryMsg = igtl::TrajectoryMessage::New(); trajectoryMsg->SetMessageHeader(header); trajectoryMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(trajectoryMsg->GetPackBodyPointer(), trajectoryMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = trajectoryMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = trajectoryMsg->GetNumberOfTrajectoryElement(); for (int i = 0; i < nElements; i ++) { igtl::TrajectoryElement::Pointer trajectoryElement; trajectoryMsg->GetTrajectoryElement(i, trajectoryElement); igtlUint8 rgba[4]; trajectoryElement->GetRGBA(rgba); igtlFloat32 entry[3]; igtlFloat32 target[3]; trajectoryElement->GetEntryPosition(entry); trajectoryElement->GetTargetPosition(target); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << trajectoryElement->GetName() << std::endl; std::cerr << " GroupName : " << trajectoryElement->GetGroupName() << std::endl; std::cerr << " RGBA : ( " << (int)rgba[0] << ", " << (int)rgba[1] << ", " << (int)rgba[2] << ", " << (int)rgba[3] << " )" << std::endl; std::cerr << " Entry Pt : ( " << std::fixed << entry[0] << ", " << entry[1] << ", " << entry[2] << " )" << std::endl; std::cerr << " Target Pt : ( " << std::fixed << target[0] << ", " << target[1] << ", " << target[2] << " )" << std::endl; std::cerr << " Radius : " << std::fixed << trajectoryElement->GetRadius() << std::endl; std::cerr << " Owner : " << trajectoryElement->GetOwner() << std::endl; std::cerr << "================================" << std::endl << std::endl; } } return 1; } int ReceiveString(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving STRING data type." << std::endl; // Create a message buffer to receive transform data igtl::StringMessage::Pointer stringMsg; stringMsg = igtl::StringMessage::New(); stringMsg->SetMessageHeader(header); stringMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(stringMsg->GetPackBodyPointer(), stringMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = stringMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { std::cerr << "Encoding: " << stringMsg->GetEncoding() << "; " << "String: " << stringMsg->GetString() << std::endl << std::endl; } return 1; } int ReceiveTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving TDATA data type." << std::endl; // Create a message buffer to receive transform data igtl::TrackingDataMessage::Pointer trackingData; trackingData = igtl::TrackingDataMessage::New(); trackingData->SetMessageHeader(header); trackingData->AllocatePack(); // Receive body from the socket socket->Receive(trackingData->GetPackBodyPointer(), trackingData->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = trackingData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = trackingData->GetNumberOfTrackingDataElements(); for (int i = 0; i < nElements; i ++) { igtl::TrackingDataElement::Pointer trackingElement; trackingData->GetTrackingDataElement(i, trackingElement); igtl::Matrix4x4 matrix; trackingElement->GetMatrix(matrix); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << trackingElement->GetName() << std::endl; std::cerr << " Type : " << (int) trackingElement->GetType() << std::endl; std::cerr << " Matrix : " << std::endl; igtl::PrintMatrix(matrix); std::cerr << "================================" << std::endl << std::endl; } return 1; } return 0; } int ReceiveQuaternionTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving QTDATA data type." << std::endl; // Create a message buffer to receive transform data igtl::QuaternionTrackingDataMessage::Pointer quaternionTrackingData; quaternionTrackingData = igtl::QuaternionTrackingDataMessage::New(); quaternionTrackingData->SetMessageHeader(header); quaternionTrackingData->AllocatePack(); // Receive body from the socket socket->Receive(quaternionTrackingData->GetPackBodyPointer(), quaternionTrackingData->GetPackBodySize()); // Deserialize position and quaternion (orientation) data // If you want to skip CRC check, call Unpack() without argument. int c = quaternionTrackingData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = quaternionTrackingData->GetNumberOfQuaternionTrackingDataElements(); for (int i = 0; i < nElements; i ++) { igtl::QuaternionTrackingDataElement::Pointer quaternionTrackingElement; quaternionTrackingData->GetQuaternionTrackingDataElement(i, quaternionTrackingElement); float position[3]; float quaternion[4]; quaternionTrackingElement->GetPosition(position); quaternionTrackingElement->GetQuaternion(quaternion); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << quaternionTrackingElement->GetName() << std::endl; std::cerr << " Type : " << (int) quaternionTrackingElement->GetType() << std::endl; std::cerr << " Position : "; igtl::PrintVector3(position); std::cerr << " Quaternion : "; igtl::PrintVector4(quaternion); std::cerr << "================================" << std::endl << std::endl; } return 1; } return 0; } int ReceiveCapability(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving CAPABILITY data type." << std::endl; // Create a message buffer to receive transform data igtl::CapabilityMessage::Pointer capabilMsg; capabilMsg = igtl::CapabilityMessage::New(); capabilMsg->SetMessageHeader(header); capabilMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(capabilMsg->GetPackBodyPointer(), capabilMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = capabilMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nTypes = capabilMsg->GetNumberOfTypes(); for (int i = 0; i < nTypes; i ++) { std::cerr << "Typename #" << i << ": " << capabilMsg->GetType(i) << std::endl; } } return 1; } #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 openigtlink-3.0.0/Examples/Receiver/ReceiveServer.cxx000066400000000000000000000441461501024245700226650ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Data Receiving Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlTransformMessage.h" #include "igtlImageMessage.h" #include "igtlServerSocket.h" #include "igtlStatusMessage.h" #include "igtlPositionMessage.h" #if OpenIGTLink_PROTOCOL_VERSION >= 2 #include "igtlPointMessage.h" #include "igtlTrajectoryMessage.h" #include "igtlStringMessage.h" #include "igtlBindMessage.h" #include "igtlCapabilityMessage.h" #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceiveTransform(igtl::Socket * socket, igtl::MessageHeader * header); int ReceivePosition(igtl::Socket * socket, igtl::MessageHeader * header); int ReceiveImage(igtl::Socket * socket, igtl::MessageHeader * header); int ReceiveStatus(igtl::Socket * socket, igtl::MessageHeader * header); #if OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceivePoint(igtl::Socket * socket, igtl::MessageHeader * header); int ReceiveTrajectory(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveString(igtl::Socket * socket, igtl::MessageHeader * header); int ReceiveBind(igtl::Socket * socket, igtl::MessageHeader * header); int ReceiveCapability(igtl::Socket * socket, igtl::MessageHeader * header); #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // Allocate a time stamp igtl::TimeStamp::Pointer ts; ts = igtl::TimeStamp::New(); //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int r = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (r == 0) { socket->CloseSocket(); } if (r != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); // Get time stamp igtlUint32 sec; igtlUint32 nanosec; headerMsg->GetTimeStamp(ts); ts->GetTimeStamp(&sec, &nanosec); std::cerr << "Time stamp: " << sec << "." << std::setw(9) << std::setfill('0') << nanosec << std::endl; // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "TRANSFORM") == 0) { ReceiveTransform(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "POSITION") == 0) { ReceivePosition(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "IMAGE") == 0) { ReceiveImage(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "STATUS") == 0) { ReceiveStatus(socket, headerMsg); } #if OpenIGTLink_PROTOCOL_VERSION >= 2 else if (strcmp(headerMsg->GetDeviceType(), "POINT") == 0) { ReceivePoint(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "TRAJ") == 0) { ReceiveTrajectory(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "STRING") == 0) { ReceiveString(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "BIND") == 0) { ReceiveBind(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "CAPABILITY") == 0) { ReceiveCapability(socket, headerMsg); } #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 else { // if the data type is unknown, skip reading. std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; std::cerr << "Size : " << headerMsg->GetBodySizeToRead() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } } //------------------------------------------------------------ // Close connection (The example code never reaches to this section ...) socket->CloseSocket(); } int ReceiveTransform(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving TRANSFORM data type." << std::endl; // Create a message buffer to receive transform data igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); transMsg->SetMessageHeader(header); transMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(transMsg->GetPackBodyPointer(), transMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = transMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the transform data igtl::Matrix4x4 matrix; transMsg->GetMatrix(matrix); igtl::PrintMatrix(matrix); return 1; } return 0; } int ReceivePosition(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving POSITION data type." << std::endl; // Create a message buffer to receive transform data igtl::PositionMessage::Pointer positionMsg; positionMsg = igtl::PositionMessage::New(); positionMsg->SetMessageHeader(header); positionMsg->AllocatePack(); // Receive position position data from the socket socket->Receive(positionMsg->GetPackBodyPointer(), positionMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = positionMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the transform data float position[3]; float quaternion[4]; positionMsg->GetPosition(position); positionMsg->GetQuaternion(quaternion); std::cerr << "position = (" << position[0] << ", " << position[1] << ", " << position[2] << ")" << std::endl; std::cerr << "quaternion = (" << quaternion[0] << ", " << quaternion[1] << ", " << quaternion[2] << ", " << quaternion[3] << ")" << std::endl << std::endl; return 1; } return 0; } int ReceiveImage(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving IMAGE data type." << std::endl; // Create a message buffer to receive transform data igtl::ImageMessage::Pointer imgMsg; imgMsg = igtl::ImageMessage::New(); imgMsg->SetMessageHeader(header); imgMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(imgMsg->GetPackBodyPointer(), imgMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = imgMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the image data int size[3]; // image dimension float spacing[3]; // spacing (mm/pixel) int svsize[3]; // sub-volume size int svoffset[3]; // sub-volume offset int scalarType; // scalar type int endian; // endian scalarType = imgMsg->GetScalarType(); endian = imgMsg->GetEndian(); imgMsg->GetDimensions(size); imgMsg->GetSpacing(spacing); imgMsg->GetSubVolume(svsize, svoffset); std::cerr << "Device Name : " << imgMsg->GetDeviceName() << std::endl; std::cerr << "Scalar Type : " << scalarType << std::endl; std::cerr << "Endian : " << endian << std::endl; std::cerr << "Dimensions : (" << size[0] << ", " << size[1] << ", " << size[2] << ")" << std::endl; std::cerr << "Spacing : (" << spacing[0] << ", " << spacing[1] << ", " << spacing[2] << ")" << std::endl; std::cerr << "Sub-Volume dimensions : (" << svsize[0] << ", " << svsize[1] << ", " << svsize[2] << ")" << std::endl; std::cerr << "Sub-Volume offset : (" << svoffset[0] << ", " << svoffset[1] << ", " << svoffset[2] << ")" << std::endl; return 1; } return 0; } int ReceiveStatus(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving STATUS data type." << std::endl; // Create a message buffer to receive transform data igtl::StatusMessage::Pointer statusMsg; statusMsg = igtl::StatusMessage::New(); statusMsg->SetMessageHeader(header); statusMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(statusMsg->GetPackBodyPointer(), statusMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = statusMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { std::cerr << "========== STATUS ==========" << std::endl; std::cerr << " Code : " << statusMsg->GetCode() << std::endl; std::cerr << " SubCode : " << statusMsg->GetSubCode() << std::endl; std::cerr << " Error Name: " << statusMsg->GetErrorName() << std::endl; std::cerr << " Status : " << statusMsg->GetStatusString() << std::endl; std::cerr << "============================" << std::endl; } return 0; } #if OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceivePoint(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving POINT data type." << std::endl; // Create a message buffer to receive transform data igtl::PointMessage::Pointer pointMsg; pointMsg = igtl::PointMessage::New(); pointMsg->SetMessageHeader(header); pointMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(pointMsg->GetPackBodyPointer(), pointMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = pointMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = pointMsg->GetNumberOfPointElement(); for (int i = 0; i < nElements; i ++) { igtl::PointElement::Pointer pointElement; pointMsg->GetPointElement(i, pointElement); igtlUint8 rgba[4]; pointElement->GetRGBA(rgba); igtlFloat32 pos[3]; pointElement->GetPosition(pos); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << pointElement->GetName() << std::endl; std::cerr << " GroupName : " << pointElement->GetGroupName() << std::endl; std::cerr << " RGBA : ( " << (int)rgba[0] << ", " << (int)rgba[1] << ", " << (int)rgba[2] << ", " << (int)rgba[3] << " )" << std::endl; std::cerr << " Position : ( " << std::fixed << pos[0] << ", " << pos[1] << ", " << pos[2] << " )" << std::endl; std::cerr << " Radius : " << std::fixed << pointElement->GetRadius() << std::endl; std::cerr << " Owner : " << pointElement->GetOwner() << std::endl; std::cerr << "================================" << std::endl; } } return 1; } int ReceiveTrajectory(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving TRAJECTORY data type." << std::endl; // Create a message buffer to receive transform data igtl::TrajectoryMessage::Pointer trajectoryMsg; trajectoryMsg = igtl::TrajectoryMessage::New(); trajectoryMsg->SetMessageHeader(header); trajectoryMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(trajectoryMsg->GetPackBodyPointer(), trajectoryMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = trajectoryMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = trajectoryMsg->GetNumberOfTrajectoryElement(); for (int i = 0; i < nElements; i ++) { igtl::TrajectoryElement::Pointer trajectoryElement; trajectoryMsg->GetTrajectoryElement(i, trajectoryElement); igtlUint8 rgba[4]; trajectoryElement->GetRGBA(rgba); igtlFloat32 entry[3]; igtlFloat32 target[3]; trajectoryElement->GetEntryPosition(entry); trajectoryElement->GetTargetPosition(target); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << trajectoryElement->GetName() << std::endl; std::cerr << " GroupName : " << trajectoryElement->GetGroupName() << std::endl; std::cerr << " RGBA : ( " << (int)rgba[0] << ", " << (int)rgba[1] << ", " << (int)rgba[2] << ", " << (int)rgba[3] << " )" << std::endl; std::cerr << " Entry Pt : ( " << std::fixed << entry[0] << ", " << entry[1] << ", " << entry[2] << " )" << std::endl; std::cerr << " Target Pt : ( " << std::fixed << target[0] << ", " << target[1] << ", " << target[2] << " )" << std::endl; std::cerr << " Radius : " << std::fixed << trajectoryElement->GetRadius() << std::endl; std::cerr << " Owner : " << trajectoryElement->GetOwner() << std::endl; std::cerr << "================================" << std::endl << std::endl; } } return 1; } int ReceiveString(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving STRING data type." << std::endl; // Create a message buffer to receive transform data igtl::StringMessage::Pointer stringMsg; stringMsg = igtl::StringMessage::New(); stringMsg->SetMessageHeader(header); stringMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(stringMsg->GetPackBodyPointer(), stringMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = stringMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { std::cerr << "Encoding: " << stringMsg->GetEncoding() << "; " << "String: " << stringMsg->GetString() << std::endl; } return 1; } int ReceiveBind(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving BIND data type." << std::endl; // Create a message buffer to receive transform data igtl::BindMessage::Pointer bindMsg; bindMsg = igtl::BindMessage::New(); bindMsg->SetMessageHeader(header); bindMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(bindMsg->GetPackBodyPointer(), bindMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = bindMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int n = bindMsg->GetNumberOfChildMessages(); for (int i = 0; i < n; i ++) { if (strcmp(bindMsg->GetChildMessageType(i), "STRING") == 0) { igtl::StringMessage::Pointer stringMsg; stringMsg = igtl::StringMessage::New(); bindMsg->GetChildMessage(i, stringMsg); stringMsg->Unpack(0); std::cerr << "Message type: STRING" << std::endl; std::cerr << "Message name: " << stringMsg->GetDeviceName() << std::endl; std::cerr << "Encoding: " << stringMsg->GetEncoding() << "; " << "String: " << stringMsg->GetString() << std::endl; } else if (strcmp(bindMsg->GetChildMessageType(i), "TRANSFORM") == 0) { igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); bindMsg->GetChildMessage(i, transMsg); transMsg->Unpack(0); std::cerr << "Message type: TRANSFORM" << std::endl; std::cerr << "Message name: " << transMsg->GetDeviceName() << std::endl; igtl::Matrix4x4 matrix; transMsg->GetMatrix(matrix); igtl::PrintMatrix(matrix); } } } return 1; } int ReceiveCapability(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving CAPABILITY data type." << std::endl; // Create a message buffer to receive transform data igtl::CapabilityMessage::Pointer capabilMsg; capabilMsg = igtl::CapabilityMessage::New(); capabilMsg->SetMessageHeader(header); capabilMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(capabilMsg->GetPackBodyPointer(), capabilMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = capabilMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nTypes = capabilMsg->GetNumberOfTypes(); for (int i = 0; i < nTypes; i ++) { std::cerr << "Typename #" << i << ": " << capabilMsg->GetType(i) << std::endl; } } return 1; } #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 openigtlink-3.0.0/Examples/SessionManager/000077500000000000000000000000001501024245700205315ustar00rootroot00000000000000openigtlink-3.0.0/Examples/SessionManager/CMakeLists.txt000066400000000000000000000007111501024245700232700ustar00rootroot00000000000000PROJECT(SessionManager) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(SessionManagerServer SessionManagerServer.cxx) TARGET_LINK_LIBRARIES(SessionManagerServer OpenIGTLink) #ADD_EXECUTABLE(SessionManagerClient SessionManagerClient.cxx) #TARGET_LINK_LIBRARIES(SessionManagerClient OpenIGTLink) openigtlink-3.0.0/Examples/SessionManager/SessionManagerServer.cxx000066400000000000000000000144451501024245700253720ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Data Receiving Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlMessageHandler.h" #include "igtlMessageHandlerMacro.h" #include "igtlSessionManager.h" #include "igtlTransformMessage.h" #include "igtlPositionMessage.h" #include "igtlImageMessage.h" //------------------------------------------------------------ // Define a structure type to share data between message // handler classes and main() function. // It can be any types e.g. C++ class, array, etc. // In this example, the shared structure is only used for // passing the message type and the device name from the // handler to main() function. typedef struct { std::string messagetype; std::string devicename; } MyData; //------------------------------------------------------------ // Define message handler classes for TransformMessage, // PositionMessage and ImageMessage. // igtlMessageHandlerClassMacro() defines a child class of // igtl::MessageHandler to handle OpenIGTLink messages for // the message type specified as the first argument. The // second argument will be used for the name of this // message handler class, while the third argument specifies // a type of data that will be shared with the message functions // of this handler class. igtlMessageHandlerClassMacro(igtl::TransformMessage, TransformHandler, MyData); igtlMessageHandlerClassMacro(igtl::PositionMessage, PositionHandler, MyData); igtlMessageHandlerClassMacro(igtl::ImageMessage, ImageHandler, MyData); //------------------------------------------------------------ // You need to describe how the received message is processed // in Process() function of the message handler class. // When Process() is called, pointers to the received message // and the shared data are passed as the arguments. // -- Transform message int TransformHandler::Process(igtl::TransformMessage * transMsg, MyData* data) { // Retrive the transform data igtl::Matrix4x4 matrix; transMsg->GetMatrix(matrix); igtl::PrintMatrix(matrix); data->messagetype = transMsg->GetDeviceType(); data->devicename = transMsg->GetDeviceName(); return 1; } // -- Position message int PositionHandler::Process(igtl::PositionMessage * positionMsg, MyData* data) { // Retrive the transform data float position[3]; float quaternion[4]; positionMsg->GetPosition(position); positionMsg->GetQuaternion(quaternion); std::cerr << "position = (" << position[0] << ", " << position[1] << ", " << position[2] << ")" << std::endl; std::cerr << "quaternion = (" << quaternion[0] << ", " << quaternion[1] << ", " << quaternion[2] << ", " << quaternion[3] << ")" << std::endl << std::endl; data->messagetype = positionMsg->GetDeviceType(); data->devicename = positionMsg->GetDeviceName(); return 1; } // -- Image message int ImageHandler::Process(igtl::ImageMessage * imgMsg, MyData *data) { // Retrive the image data int size[3]; // image dimension float spacing[3]; // spacing (mm/pixel) int svsize[3]; // sub-volume size int svoffset[3]; // sub-volume offset int scalarType; // scalar type int endian; // endian scalarType = imgMsg->GetScalarType(); endian = imgMsg->GetEndian(); imgMsg->GetDimensions(size); imgMsg->GetSpacing(spacing); imgMsg->GetSubVolume(svsize, svoffset); std::cerr << "Device Name : " << imgMsg->GetDeviceName() << std::endl; std::cerr << "Scalar Type : " << scalarType << std::endl; std::cerr << "Endian : " << endian << std::endl; std::cerr << "Dimensions : (" << size[0] << ", " << size[1] << ", " << size[2] << ")" << std::endl; std::cerr << "Spacing : (" << spacing[0] << ", " << spacing[1] << ", " << spacing[2] << ")" << std::endl; std::cerr << "Sub-Volume dimensions : (" << svsize[0] << ", " << svsize[1] << ", " << svsize[2] << ")" << std::endl; std::cerr << "Sub-Volume offset : (" << svoffset[0] << ", " << svoffset[1] << ", " << svoffset[2] << ")" << std::endl; data->messagetype = imgMsg->GetDeviceType(); data->devicename = imgMsg->GetDeviceName(); return 1; } int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); //------------------------------------------------------------ // Create a session manager igtl::SessionManager::Pointer sm; sm = igtl::SessionManager::New(); sm->SetMode(igtl::SessionManager::MODE_SERVER); sm->SetPort(port); //------------------------------------------------------------ // Create message handlers TransformHandler::Pointer tmh = TransformHandler::New(); PositionHandler::Pointer pmh = PositionHandler::New(); ImageHandler::Pointer imh = ImageHandler::New(); MyData mydata; tmh->SetData(&mydata); pmh->SetData(&mydata); imh->SetData(&mydata); //------------------------------------------------------------ // Register the message handlers to the session manager sm->AddMessageHandler(tmh); sm->AddMessageHandler(pmh); sm->AddMessageHandler(imh); //------------------------------------------------------------ // Start session if (sm->Connect()) { while (1) { int r = sm->ProcessMessage(); if (r == 0) // Disconnected { break; } std::cerr << "Message Type: " << tmh->GetData()->messagetype << std::endl; std::cerr << "Device Name: " << tmh->GetData()->devicename << std::endl; } // Stop session sm->Disconnect(); } } openigtlink-3.0.0/Examples/Status/000077500000000000000000000000001501024245700170765ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Status/CMakeLists.txt000066400000000000000000000006211501024245700216350ustar00rootroot00000000000000PROJECT(Status) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(StatusClient StatusClient.cxx) TARGET_LINK_LIBRARIES(StatusClient OpenIGTLink) ADD_EXECUTABLE(StatusServer StatusServer.cxx) TARGET_LINK_LIBRARIES(StatusServer OpenIGTLink) openigtlink-3.0.0/Examples/Status/StatusClient.cxx000066400000000000000000000044761501024245700222570ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Sending Status Messasge Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlStatusMessage.h" #include "igtlClientSocket.h" // // Test comment // int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); int interval = (int) (1000); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Status Message Class igtl::StatusMessage::Pointer statusMsg; statusMsg = igtl::StatusMessage::New(); statusMsg->SetDeviceName("Device"); //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { statusMsg->SetCode(igtl::StatusMessage::STATUS_OK); statusMsg->SetSubCode(128); statusMsg->SetErrorName("OK!"); statusMsg->SetStatusString("This is a test to send status message."); statusMsg->Pack(); socket->Send(statusMsg->GetPackPointer(), statusMsg->GetPackSize()); igtl::Sleep(interval); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } openigtlink-3.0.0/Examples/Status/StatusServer.cxx000066400000000000000000000050001501024245700222670ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlStatusMessage.h" #include "igtlServerSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); int interval = (int) 1000; //------------------------------------------------------------ // Allocate Status Message Class igtl::StatusMessage::Pointer statusMsg; statusMsg = igtl::StatusMessage::New(); statusMsg->SetDeviceName("Device"); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { statusMsg->SetDeviceName("Device"); statusMsg->SetCode(igtl::StatusMessage::STATUS_OK); statusMsg->SetSubCode(128); statusMsg->SetErrorName("OK!"); statusMsg->SetStatusString("This is a test to send status message."); statusMsg->Pack(); socket->Send(statusMsg->GetPackPointer(), statusMsg->GetPackSize()); igtl::Sleep(interval); // wait } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } openigtlink-3.0.0/Examples/String/000077500000000000000000000000001501024245700170615ustar00rootroot00000000000000openigtlink-3.0.0/Examples/String/CMakeLists.txt000066400000000000000000000010021501024245700216120ustar00rootroot00000000000000PROJECT(String) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(StringClient StringClient.cxx) TARGET_LINK_LIBRARIES(StringClient OpenIGTLink) ADD_EXECUTABLE(StringServer StringServer.cxx) TARGET_LINK_LIBRARIES(StringServer OpenIGTLink) ADD_EXECUTABLE(StringEchoServer StringEchoServer.cxx) TARGET_LINK_LIBRARIES(StringEchoServer OpenIGTLink) openigtlink-3.0.0/Examples/String/StringClient.cxx000066400000000000000000000051321501024245700222130ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for String Message Client Program Module: $RCSfile: $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlStringMessage.h" #include "igtlClientSocket.h" #define N_STRINGS 5 const char * testString[N_STRINGS] = { "OpenIGTLink", "Network", "Communication", "Protocol", "Image Guided Therapy", }; int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 4) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send string" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Transform Message Class igtl::StringMessage::Pointer stringMsg; stringMsg = igtl::StringMessage::New(); //------------------------------------------------------------ // loop int i = 0; while (1) { stringMsg->SetDeviceName("StringMessage"); std::cout << "Sending string: " << testString[i] << std::endl; stringMsg->SetString(testString[i]); stringMsg->Pack(); socket->Send(stringMsg->GetPackPointer(), stringMsg->GetPackSize()); igtl::Sleep(interval); // wait i = (i + 1) % N_STRINGS; } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } openigtlink-3.0.0/Examples/String/StringEchoServer.cxx000066400000000000000000000051101501024245700230360ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for String Echo Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlStringMessage.h" #include "igtlServerSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); igtl::MessageHeader::Pointer hdrMsg = igtl::MessageHeader::New(); while (socket.IsNotNull() && socket->GetConnected()) { hdrMsg->InitPack(); int r = socket->Receive(hdrMsg->GetPackPointer(), hdrMsg->GetPackSize()); // check message if (r == 0) { socket->CloseSocket(); continue; } if (r != hdrMsg->GetPackSize()) continue; // get data hdrMsg->Unpack(); igtl::StringMessage::Pointer strMsg(igtl::StringMessage::New()); strMsg->SetMessageHeader(hdrMsg); strMsg->AllocatePack(); socket->Receive(strMsg->GetPackBodyPointer(), strMsg->GetPackBodySize()); int c = strMsg->Unpack(); // echo message back std::cout << "Echoing: " << strMsg->GetString() << std::endl; strMsg->SetDeviceName("StringEchoServer"); strMsg->Pack(); socket->Send(strMsg->GetPackPointer(), strMsg->GetPackSize()); } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } openigtlink-3.0.0/Examples/String/StringServer.cxx000066400000000000000000000051641501024245700222500ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlStringMessage.h" #include "igtlServerSocket.h" #define N_STRINGS 5 const char * testString[N_STRINGS] = { "OpenIGTLink", "Network", "Communication", "Protocol", "Image Guided Therapy", }; int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send string" << std::endl; exit(0); } int port = atoi(argv[1]); double fps = atof(argv[2]); int interval = (int) (1000.0 / fps); igtl::StringMessage::Pointer stringMsg; stringMsg = igtl::StringMessage::New(); stringMsg->SetDeviceName("StringMessage"); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { std::cout << "Sending string: " << testString[i%N_STRINGS] << std::endl; stringMsg->SetDeviceName("StringMessage"); stringMsg->SetString(testString[i%N_STRINGS]); stringMsg->Pack(); socket->Send(stringMsg->GetPackPointer(), stringMsg->GetPackSize()); igtl::Sleep(interval); // wait } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } openigtlink-3.0.0/Examples/Thread/000077500000000000000000000000001501024245700170225ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Thread/CMakeLists.txt000066400000000000000000000010421501024245700215570ustar00rootroot00000000000000PROJECT(Thread) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(SingleMethodExecute SingleMethodExecute.cxx) TARGET_LINK_LIBRARIES(SingleMethodExecute OpenIGTLink) ADD_EXECUTABLE(MultipleMethodExecute MultipleMethodExecute.cxx) TARGET_LINK_LIBRARIES(MultipleMethodExecute OpenIGTLink) ADD_EXECUTABLE(SpawnThread SpawnThread.cxx) TARGET_LINK_LIBRARIES(SpawnThread OpenIGTLink) openigtlink-3.0.0/Examples/Thread/MultipleMethodExecute.cxx000066400000000000000000000070301501024245700240250ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library -- Example for Thread (Multiple Methods) Module: $RCSfile: itkImage.h,v $ Language: C++ Date: $Date: 2008/01/13 19:48:38 $ Version: $Revision: 1.142 $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlMultiThreader.h" #include "igtlOSUtil.h" typedef struct { int nloop; igtl::MutexLock::Pointer glock; } ThreadData; void* ThreadFunction1(void* ptr) { //------------------------------------------------------------ // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); int id = info->ThreadID; int nThread = info->NumberOfThreads; ThreadData* data = static_cast(info->UserData); //------------------------------------------------------------ // Get user data int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; long interval = 100; // (ms) //------------------------------------------------------------ // Loop for (int i = 0; i < nloop; i ++) { glock->Lock(); std::cerr << "Thread #1: counter = " << i << std::endl; glock->Unlock(); igtl::Sleep(interval); } glock->Lock(); std::cerr << "Thread #1: end." << std::endl; glock->Unlock(); return NULL; } void* ThreadFunction2(void* ptr) { //------------------------------------------------------------ // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); int id = info->ThreadID; int nThread = info->NumberOfThreads; ThreadData* data = static_cast(info->UserData); //------------------------------------------------------------ // Set user data int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; long interval = 200; // (ms) //------------------------------------------------------------ // loop for (int i = 0; i < nloop; i ++) { glock->Lock(); std::cerr << "Thread #2: counter = " << i << std::endl; glock->Unlock(); igtl::Sleep(interval); } glock->Lock(); std::cerr << "Thread #2: end." << std::endl; glock->Unlock(); return NULL; } int main(int argc, char * argv [] ) { //------------------------------------------------------------ // Set up thread and mutex cleasses igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); //------------------------------------------------------------ // Set up user data ThreadData td; td.nloop = 20; td.glock = glock; //------------------------------------------------------------ // Set multiple methods as threads threader->SetNumberOfThreads(2); threader->SetMultipleMethod(0, (igtl::ThreadFunctionType) &ThreadFunction1, &td); threader->SetMultipleMethod(1, (igtl::ThreadFunctionType) &ThreadFunction2, &td); //------------------------------------------------------------ // Start threads -- the main thread waits until all threads return. std::cerr << "Starting threads ...." << std::endl; threader->MultipleMethodExecute(); std::cerr << "Theads stopped ...." << std::endl; return 0; } openigtlink-3.0.0/Examples/Thread/SingleMethodExecute.cxx000066400000000000000000000051471501024245700234620ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library -- Example for Thread (Single Method) Module: $RCSfile: itkImage.h,v $ Language: C++ Date: $Date: 2008/01/13 19:48:38 $ Version: $Revision: 1.142 $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlMultiThreader.h" #include "igtlOSUtil.h" typedef struct { int nloop; igtl::MutexLock::Pointer glock; } ThreadData; #define NUM_THREADS 4 void* ThreadFunction(void* ptr) { //------------------------------------------------------------ // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); int id = info->ThreadID; int nThread = info->NumberOfThreads; ThreadData* data = static_cast(info->UserData); //------------------------------------------------------------ // Get user data int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; long interval = (id + 1) * 100; // (ms) //------------------------------------------------------------ // Loop for (int i = 0; i < nloop; i ++) { glock->Lock(); std::cerr << "Thread #" << id << ": counter = " << i << std::endl; glock->Unlock(); igtl::Sleep(interval); } glock->Lock(); std::cerr << "Thread #" << id << ": end." << std::endl; glock->Unlock(); return NULL; } int main(int argc, char * argv [] ) { //------------------------------------------------------------ // Set up thread and mutex cleasses igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); //------------------------------------------------------------ // Set user data ThreadData td; td.nloop = 20; td.glock = glock; //------------------------------------------------------------ // Set multiple methods as threads threader->SetNumberOfThreads(NUM_THREADS); threader->SetSingleMethod((igtl::ThreadFunctionType) &ThreadFunction, &td); //------------------------------------------------------------ // Start threads -- the main thread waits until all threads return. std::cerr << "Starting threads ...." << std::endl; threader->SingleMethodExecute(); std::cerr << "Theads stopped ...." << std::endl; return 0; } openigtlink-3.0.0/Examples/Thread/SpawnThread.cxx000066400000000000000000000064761501024245700220030ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library -- Example for Thread (Spawn Thread) Module: $RCSfile: itkImage.h,v $ Language: C++ Date: $Date: 2008/01/13 19:48:38 $ Version: $Revision: 1.142 $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlMultiThreader.h" #include "igtlOSUtil.h" typedef struct { int nloop; igtl::MutexLock::Pointer glock; } ThreadData; #define NUM_THREADS 4 void* ThreadFunction(void* ptr) { //------------------------------------------------------------ // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); int id = info->ThreadID; int nThread = info->NumberOfThreads; ThreadData* data = static_cast(info->UserData); //------------------------------------------------------------ // Get user data int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; long interval = (id + 1) * 100; // (ms) //------------------------------------------------------------ // Loop for (int i = 0; i < nloop; i ++) { glock->Lock(); std::cerr << "Thread #" << id << ": counter = " << i << std::endl; glock->Unlock(); igtl::Sleep(interval); } glock->Lock(); std::cerr << "Thread #" << id << ": end." << std::endl; glock->Unlock(); return NULL; } int main(int argc, char * argv [] ) { //------------------------------------------------------------ // Set up thread and mutex cleasses igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); //------------------------------------------------------------ // Set up user data ThreadData td; td.nloop = 20; td.glock = glock; //------------------------------------------------------------ // Start threads -- the main thread waits until all threads return. std::cerr << "Starting threads ...." << std::endl; int id1 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); int id2 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); int id3 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); int id4 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); int id5 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); //------------------------------------------------------------ // All threads are detached ... main thread is still active for (int i = 0; i < td.nloop; i ++) { glock->Lock(); std::cerr << "Main Thread: counter = " << i << std::endl; glock->Unlock(); igtl::Sleep(200); } //------------------------------------------------------------ // wait for the threads threader->TerminateThread(id1); threader->TerminateThread(id2); threader->TerminateThread(id3); threader->TerminateThread(id4); threader->TerminateThread(id5); std::cerr << "Theads stopped ...." << std::endl; return 0; } openigtlink-3.0.0/Examples/Tracker/000077500000000000000000000000001501024245700172065ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Tracker/CMakeLists.txt000066400000000000000000000013161501024245700217470ustar00rootroot00000000000000PROJECT(Tracker) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(TrackerClient TrackerClient.cxx) TARGET_LINK_LIBRARIES(TrackerClient OpenIGTLink) ADD_EXECUTABLE(TrackerServer TrackerServer.cxx) TARGET_LINK_LIBRARIES(TrackerServer OpenIGTLink) ADD_EXECUTABLE(TrackerClient2 TrackerClient2.cxx) TARGET_LINK_LIBRARIES(TrackerClient2 OpenIGTLink) ADD_EXECUTABLE(TrackerServer2 TrackerServer2.cxx) TARGET_LINK_LIBRARIES(TrackerServer2 OpenIGTLink) ADD_EXECUTABLE(TrackerClient3 TrackerClient3.cxx) TARGET_LINK_LIBRARIES(TrackerClient3 OpenIGTLink) openigtlink-3.0.0/Examples/Tracker/TrackerClient.cxx000066400000000000000000000065151501024245700224730ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlTransformMessage.h" #include "igtlClientSocket.h" void GetRandomTestMatrix(igtl::Matrix4x4& matrix); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 4) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Transform Message Class igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); transMsg->SetDeviceName("Tracker"); //------------------------------------------------------------ // Allocate TimeStamp class igtl::TimeStamp::Pointer ts; ts = igtl::TimeStamp::New(); //------------------------------------------------------------ // loop while (1) { igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix); ts->GetTime(); transMsg->SetMatrix(matrix); transMsg->SetTimeStamp(ts); transMsg->Pack(); socket->Send(transMsg->GetPackPointer(), transMsg->GetPackSize()); igtl::Sleep(interval); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestMatrix(igtl::Matrix4x4& matrix) { float position[3]; float orientation[4]; // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); phi = phi + 0.2; // random orientation static float theta = 0.0; orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; //igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Tracker/TrackerClient2.cxx000066400000000000000000000066311501024245700225540ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program II (POSITION data type) Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlPositionMessage.h" #include "igtlClientSocket.h" void GetRandomTestVectors(float* position, float* quaternion); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 4) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Transform Message Class igtl::PositionMessage::Pointer positionMsg; positionMsg = igtl::PositionMessage::New(); positionMsg->SetDeviceName("Tracker"); positionMsg->SetPackType(igtl::PositionMessage::ALL); // default //------------------------------------------------------------ // loop while (1) { float position[3]; float quaternion[4]; GetRandomTestVectors(position, quaternion); positionMsg->SetPosition(position); positionMsg->SetQuaternion(quaternion); positionMsg->Pack(); socket->Send(positionMsg->GetPackPointer(), positionMsg->GetPackSize()); igtl::Sleep(interval); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestVectors(float* position, float* quaternion) { // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); phi = phi + 0.2; // random orientation static float theta = 0.0; quaternion[0]=0.0; quaternion[1]=0.6666666666*cos(theta); quaternion[2]=0.577350269189626; quaternion[3]=0.6666666666*sin(theta); theta = theta + 0.1; std::cerr << "position = (" << position[0] << ", " << position[1] << ", " << position[2] << ")" << std::endl; std::cerr << "quaternion = (" << quaternion[0] << ", " << quaternion[1] << ", " << quaternion[2] << ", " << quaternion[3] << ")" << std::endl << std::endl; } openigtlink-3.0.0/Examples/Tracker/TrackerClient3.cxx000066400000000000000000000102201501024245700225420ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlTransformMessage.h" #include "igtlClientSocket.h" #define MAX_DEVICE 4 void GetRandomTestMatrix(igtl::Matrix4x4& matrix, float phi, float theta); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc < 4 || argc > 4 + MAX_DEVICE) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " [ .. ]" << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; std::cerr << " .. : Device names (N < " << MAX_DEVICE << ")" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); int numdev = argc - 4; const char* devicename[4]; if (numdev == 0) { numdev = 1; devicename[0] = "Tracker"; } else { for (int i = 0; i < numdev; i ++) { devicename[i] = argv[i+4]; } } //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Transform Message Class igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); float phi[MAX_DEVICE]; float theta[MAX_DEVICE]; float incr[MAX_DEVICE]; for (int i = 0; i < numdev; i ++) { phi[i] = 0.3*(float)i; theta[i] = 0.2*(float)i; incr[i] = 0.5*(float)(i+1); } //------------------------------------------------------------ // loop igtl::TimeStamp::Pointer ts = igtl::TimeStamp::New(); while (1) { for (int i = 0; i < numdev; i ++) { transMsg->SetDeviceName(devicename[i]); igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix, phi[i], theta[i]); transMsg->SetMatrix(matrix); ts->GetTime(); transMsg->SetTimeStamp(ts); transMsg->Pack(); igtlUint32 sec; igtlUint32 nsec; ts->GetTimeStamp(&sec, &nsec); std::cerr << "Time Stamp: sec = " << sec << ", nsec = " << nsec << std::endl; socket->Send(transMsg->GetPackPointer(), transMsg->GetPackSize()); phi[i] = phi[i] + 0.2*incr[i]; theta[i] = theta[i] + 0.1*incr[i]; } igtl::Sleep(interval); // wait } //------------------------------------------------------------ // Close connection socket->CloseSocket(); } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestMatrix(igtl::Matrix4x4& matrix, float phi, float theta) { float position[3]; float orientation[4]; // random position position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); // random orientation orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); //igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Tracker/TrackerServer.cxx000066400000000000000000000062311501024245700225160ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlTransformMessage.h" #include "igtlServerSocket.h" void GetRandomTestMatrix(igtl::Matrix4x4& matrix); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; exit(0); } int port = atoi(argv[1]); double fps = atof(argv[2]); int interval = (int) (1000.0 / fps); igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); transMsg->SetDeviceName("Tracker"); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { igtl::Matrix4x4 matrix; GetRandomTestMatrix(matrix); transMsg->SetDeviceName("Tracker"); transMsg->SetMatrix(matrix); transMsg->Pack(); socket->Send(transMsg->GetPackPointer(), transMsg->GetPackSize()); igtl::Sleep(interval); // wait } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } void GetRandomTestMatrix(igtl::Matrix4x4& matrix) { float position[3]; float orientation[4]; // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); phi = phi + 0.2; // random orientation static float theta = 0.0; orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; //igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Tracker/TrackerServer2.cxx000066400000000000000000000063001501024245700225750ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Server Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlPositionMessage.h" #include "igtlServerSocket.h" void GetRandomTestVectors(float* position, float* quaternion); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; exit(0); } int port = atoi(argv[1]); double fps = atof(argv[2]); int interval = (int) (1000.0 / fps); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //------------------------------------------------------------ // loop for (int i = 0; i < 100; i ++) { float position[3]; float quaternion[4]; igtl::PositionMessage::Pointer positionMsg; positionMsg = igtl::PositionMessage::New(); positionMsg->SetDeviceName("Tracker"); positionMsg->SetPackType(igtl::PositionMessage::ALL); // default GetRandomTestVectors(position, quaternion); positionMsg->SetPosition(position); positionMsg->SetQuaternion(quaternion); positionMsg->Pack(); socket->Send(positionMsg->GetPackPointer(), positionMsg->GetPackSize()); igtl::Sleep(interval); // wait } } } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) socket->CloseSocket(); } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestVectors(float* position, float* quaternion) { // random position static float phi = 0.0; position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); phi = phi + 0.2; // random orientation static float theta = 0.0; quaternion[0]=0.0; quaternion[1]=0.6666666666*cos(theta); quaternion[2]=0.577350269189626; quaternion[3]=0.6666666666*sin(theta); theta = theta + 0.1; } openigtlink-3.0.0/Examples/TrackingData/000077500000000000000000000000001501024245700201475ustar00rootroot00000000000000openigtlink-3.0.0/Examples/TrackingData/CMakeLists.txt000066400000000000000000000006771501024245700227210ustar00rootroot00000000000000PROJECT(TrackingData) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(TrackingDataClient TrackingDataClient.cxx) TARGET_LINK_LIBRARIES(TrackingDataClient OpenIGTLink) ADD_EXECUTABLE(TrackingDataServer TrackingDataServer.cxx) TARGET_LINK_LIBRARIES(TrackingDataServer OpenIGTLink) openigtlink-3.0.0/Examples/TrackingData/TrackingDataClient.cxx000066400000000000000000000124711501024245700243730ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracker Client Program Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlTrackingDataMessage.h" #include "igtlClientSocket.h" int ReceiveTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 4) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; std::cerr << " : Frequency (fps) to send coordinate" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); double fps = atof(argv[3]); int interval = (int) (1000.0 / fps); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Ask the server to start pushing tracking data std::cerr << "Sending STT_TDATA message....." << std::endl; igtl::StartTrackingDataMessage::Pointer startTrackingMsg; startTrackingMsg = igtl::StartTrackingDataMessage::New(); startTrackingMsg->SetDeviceName("TDataClient"); startTrackingMsg->SetResolution(interval); startTrackingMsg->SetCoordinateName("Patient"); startTrackingMsg->Pack(); socket->Send(startTrackingMsg->GetPackPointer(), startTrackingMsg->GetPackSize()); int loop = 0; while (1) { //------------------------------------------------------------ // Wait for a reply igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { std::cerr << "Connection closed." << std::endl; socket->CloseSocket(); exit(0); } if (rs != headerMsg->GetPackSize()) { std::cerr << "Message size information and actual data size don't match." << std::endl; socket->CloseSocket(); exit(0); } headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "TDATA") == 0) { ReceiveTrackingData(socket, headerMsg); } else { std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } if (++loop >= 10) // if received 100 times { //------------------------------------------------------------ // Ask the server to stop pushing tracking data std::cerr << "Sending STP_TDATA message....." << std::endl; igtl::StopTrackingDataMessage::Pointer stopTrackingMsg; stopTrackingMsg = igtl::StopTrackingDataMessage::New(); stopTrackingMsg->SetDeviceName("TDataClient"); stopTrackingMsg->Pack(); socket->Send(stopTrackingMsg->GetPackPointer(), stopTrackingMsg->GetPackSize()); loop = 0; } } } int ReceiveTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving TDATA data type." << std::endl; //------------------------------------------------------------ // Allocate TrackingData Message Class igtl::TrackingDataMessage::Pointer trackingData; trackingData = igtl::TrackingDataMessage::New(); trackingData->SetMessageHeader(header); trackingData->AllocatePack(); // Receive body from the socket socket->Receive(trackingData->GetPackBodyPointer(), trackingData->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = trackingData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = trackingData->GetNumberOfTrackingDataElements(); for (int i = 0; i < nElements; i ++) { igtl::TrackingDataElement::Pointer trackingElement; trackingData->GetTrackingDataElement(i, trackingElement); igtl::Matrix4x4 matrix; trackingElement->GetMatrix(matrix); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << trackingElement->GetName() << std::endl; std::cerr << " Type : " << (int) trackingElement->GetType() << std::endl; std::cerr << " Matrix : " << std::endl; igtl::PrintMatrix(matrix); std::cerr << "================================" << std::endl; } return 1; } return 0; } openigtlink-3.0.0/Examples/TrackingData/TrackingDataServer.cxx000066400000000000000000000217061501024245700244240ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Tracking Data Server Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlServerSocket.h" #include "igtlTrackingDataMessage.h" #include "igtlMultiThreader.h" void* ThreadFunction(void* ptr); int SendTrackingData(igtl::Socket::Pointer& socket, igtl::TrackingDataMessage::Pointer& trackingMsg); void GetRandomTestMatrix(igtl::Matrix4x4& matrix, float phi, float theta); typedef struct { int nloop; igtl::MutexLock::Pointer glock; igtl::Socket::Pointer socket; int interval; int stop; } ThreadData; int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); ThreadData td; while (1) { //------------------------------------------------------------ // Waiting for Connection int threadID = -1; igtl::Socket::Pointer socket; socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { std::cerr << "A client is connected." << std::endl; // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // loop for (;;) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { if (threadID >= 0) { td.stop = 1; threader->TerminateThread(threadID); threadID = -1; } std::cerr << "Disconnecting the client." << std::endl; td.socket = NULL; // VERY IMPORTANT. Completely remove the instance. socket->CloseSocket(); break; } if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "STT_TDATA") == 0) { std::cerr << "Received a STT_TDATA message." << std::endl; igtl::StartTrackingDataMessage::Pointer startTracking; startTracking = igtl::StartTrackingDataMessage::New(); startTracking->SetMessageHeader(headerMsg); startTracking->AllocatePack(); int r2 = socket->Receive(startTracking->GetPackBodyPointer(), startTracking->GetPackBodySize()); int c = startTracking->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { td.interval = startTracking->GetResolution(); td.glock = glock; td.socket = socket; td.stop = 0; threadID = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); } } else if (strcmp(headerMsg->GetDeviceType(), "STP_TDATA") == 0) { socket->Skip(headerMsg->GetBodySizeToRead(), 0); std::cerr << "Received a STP_TDATA message." << std::endl; if (threadID >= 0) { td.stop = 1; threader->TerminateThread(threadID); threadID = -1; std::cerr << "Disconnecting the client." << std::endl; td.socket = NULL; // VERY IMPORTANT. Completely remove the instance. socket->CloseSocket(); } break; } else { std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } } } } //------------------------------------------------------------ // Close connection (The example code never reaches to this section ...) serverSocket->CloseSocket(); } void* ThreadFunction(void* ptr) { //------------------------------------------------------------ // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); //int id = info->ThreadID; //int nThread = info->NumberOfThreads; ThreadData* td = static_cast(info->UserData); //------------------------------------------------------------ // Get user data igtl::MutexLock::Pointer glock = td->glock; long interval = td->interval; std::cerr << "Interval = " << interval << " (ms)" << std::endl; //long interval = 1000; //long interval = (id + 1) * 100; // (ms) igtl::Socket::Pointer& socket = td->socket; //------------------------------------------------------------ // Allocate TrackingData Message Class // // NOTE: TrackingDataElement class instances are allocated // before the loop starts to avoid reallocation // in each image transfer. igtl::TrackingDataMessage::Pointer trackingMsg; trackingMsg = igtl::TrackingDataMessage::New(); igtl::TrackingDataElement::Pointer trackElement0; trackElement0 = igtl::TrackingDataElement::New(); trackElement0->SetName("Channel 0"); trackElement0->SetType(igtl::TrackingDataElement::TYPE_TRACKER); igtl::TrackingDataElement::Pointer trackElement1; trackElement1 = igtl::TrackingDataElement::New(); trackElement1->SetName("Channel 1"); trackElement1->SetType(igtl::TrackingDataElement::TYPE_6D); igtl::TrackingDataElement::Pointer trackElement2; trackElement2 = igtl::TrackingDataElement::New(); trackElement2->SetName("Channel 2"); trackElement2->SetType(igtl::TrackingDataElement::TYPE_5D); trackingMsg->AddTrackingDataElement(trackElement0); trackingMsg->AddTrackingDataElement(trackElement1); trackingMsg->AddTrackingDataElement(trackElement2); //------------------------------------------------------------ // Loop while (!td->stop) { trackingMsg->SetDeviceName("Tracker"); glock->Lock(); SendTrackingData(socket, trackingMsg); glock->Unlock(); igtl::Sleep(interval); } //glock->Lock(); //std::cerr << "Thread #" << id << ": end." << std::endl; //glock->Unlock(); return NULL; } int SendTrackingData(igtl::Socket::Pointer& socket, igtl::TrackingDataMessage::Pointer& trackingMsg) { static float phi0 = 0.0; static float theta0 = 0.0; static float phi1 = 0.0; static float theta1 = 0.0; static float phi2 = 0.0; static float theta2 = 0.0; igtl::Matrix4x4 matrix; igtl::TrackingDataElement::Pointer ptr; // Channel 0 trackingMsg->GetTrackingDataElement(0, ptr); GetRandomTestMatrix(matrix, phi0, theta0); ptr->SetMatrix(matrix); // Channel 1 trackingMsg->GetTrackingDataElement(1, ptr); GetRandomTestMatrix(matrix, phi1, theta1); ptr->SetMatrix(matrix); // Channel 2 trackingMsg->GetTrackingDataElement(2, ptr); GetRandomTestMatrix(matrix, phi2, theta2); ptr->SetMatrix(matrix); trackingMsg->Pack(); socket->Send(trackingMsg->GetPackPointer(), trackingMsg->GetPackSize()); phi0 += 0.1; phi1 += 0.2; phi2 += 0.3; theta0 += 0.2; theta1 += 0.1; theta2 += 0.05; return 0; } //------------------------------------------------------------ // Function to generate random matrix. void GetRandomTestMatrix(igtl::Matrix4x4& matrix, float phi, float theta) { float position[3]; float orientation[4]; // random position position[0] = 50.0 * cos(phi); position[1] = 50.0 * sin(phi); position[2] = 50.0 * cos(phi); phi = phi + 0.2; // random orientation orientation[0]=0.0; orientation[1]=0.6666666666*cos(theta); orientation[2]=0.577350269189626; orientation[3]=0.6666666666*sin(theta); theta = theta + 0.1; //igtl::Matrix4x4 matrix; igtl::QuaternionToMatrix(orientation, matrix); matrix[0][3] = position[0]; matrix[1][3] = position[1]; matrix[2][3] = position[2]; //igtl::PrintMatrix(matrix); } openigtlink-3.0.0/Examples/Trajectory/000077500000000000000000000000001501024245700177415ustar00rootroot00000000000000openigtlink-3.0.0/Examples/Trajectory/CMakeLists.txt000066400000000000000000000006601501024245700225030ustar00rootroot00000000000000PROJECT(Trajectory) cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) ADD_EXECUTABLE(TrajectoryClient TrajectoryClient.cxx) TARGET_LINK_LIBRARIES(TrajectoryClient OpenIGTLink) ADD_EXECUTABLE(TrajectoryServer TrajectoryServer.cxx) TARGET_LINK_LIBRARIES(TrajectoryServer OpenIGTLink) openigtlink-3.0.0/Examples/Trajectory/TrajectoryClient.cxx000066400000000000000000000071401501024245700237540ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Trajectory message Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlTrajectoryMessage.h" #include "igtlClientSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : IP or host name" << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Allocate Transform Message Class igtl::TrajectoryMessage::Pointer trajectoryMsg; trajectoryMsg = igtl::TrajectoryMessage::New(); trajectoryMsg->SetDeviceName("TrajectorySender"); //--------------------------- // Create 1st trajectory igtl::TrajectoryElement::Pointer trajectory0; trajectory0 = igtl::TrajectoryElement::New(); trajectory0->SetName("TRAJECTORY_0"); trajectory0->SetGroupName("GROUP_0"); trajectory0->SetRGBA(0xFF, 0x00, 0x00, 0xFF); trajectory0->SetEntryPosition(10.0, 20.0, 30.0); trajectory0->SetTargetPosition(20.0, 20.0, 40.0); trajectory0->SetRadius(15.0); trajectory0->SetOwner("IMAGE_0"); //--------------------------- // Create 2nd trajectory igtl::TrajectoryElement::Pointer trajectory1; trajectory1 = igtl::TrajectoryElement::New(); trajectory1->SetName("TRAJECTORY_1"); trajectory1->SetGroupName("GROUP_0"); trajectory1->SetRGBA(0x00, 0xFF, 0x00, 0xFF); trajectory1->SetEntryPosition(40.0, 50.0, 60.0); trajectory1->SetTargetPosition(20.0, 30.0, 10.0); trajectory1->SetRadius(45.0); trajectory1->SetOwner("IMAGE_0"); //--------------------------- // Create 3rd trajectory igtl::TrajectoryElement::Pointer trajectory2; trajectory2 = igtl::TrajectoryElement::New(); trajectory2->SetName("TRAJECTORY_2"); trajectory2->SetGroupName("GROUP_0"); trajectory2->SetRGBA(0x00, 0x00, 0xFF, 0xFF); trajectory2->SetEntryPosition(70.0, 80.0, 90.0); trajectory1->SetTargetPosition(10.0, 40.0, 20.0); trajectory2->SetRadius(75.0); trajectory2->SetOwner("IMAGE_0"); //--------------------------- // Pack into the trajectory message trajectoryMsg->AddTrajectoryElement(trajectory0); trajectoryMsg->AddTrajectoryElement(trajectory1); trajectoryMsg->AddTrajectoryElement(trajectory2); trajectoryMsg->Pack(); //------------------------------------------------------------ // Send socket->Send(trajectoryMsg->GetPackPointer(), trajectoryMsg->GetPackSize()); //------------------------------------------------------------ // Close the socket socket->CloseSocket(); } openigtlink-3.0.0/Examples/Trajectory/TrajectoryServer.cxx000066400000000000000000000075471501024245700240170ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink -- Example for Trajectory message Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "igtlOSUtil.h" #include "igtlTrajectoryMessage.h" #include "igtlServerSocket.h" int main(int argc, char* argv[]) { //------------------------------------------------------------ // Parse Arguments if (argc != 2) // check number of arguments { // If not correct, print usage std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << " : Port # (18944 in Slicer default)" << std::endl; exit(0); } int port = atoi(argv[1]); igtl::ServerSocket::Pointer serverSocket; serverSocket = igtl::ServerSocket::New(); int r = serverSocket->CreateServer(port); if (r < 0) { std::cerr << "Cannot create a server socket." << std::endl; exit(0); } igtl::Socket::Pointer socket; while (1) { //------------------------------------------------------------ // Waiting for Connection socket = serverSocket->WaitForConnection(1000); if (socket.IsNotNull()) // if client connected { //--------------------------- // Create a trajectory message igtl::TrajectoryMessage::Pointer trajectoryMsg; trajectoryMsg = igtl::TrajectoryMessage::New(); trajectoryMsg->SetDeviceName("TrajectorySender"); //--------------------------- // Create 1st trajectory igtl::TrajectoryElement::Pointer trajectory0; trajectory0 = igtl::TrajectoryElement::New(); trajectory0->SetName("TRAJECTORY_0"); trajectory0->SetGroupName("GROUP_0"); trajectory0->SetRGBA(0xFF, 0x00, 0x00, 0xFF); trajectory0->SetEntryPosition(10.0, 20.0, 30.0); trajectory0->SetTargetPosition(20.0, 20.0, 40.0); trajectory0->SetRadius(15.0); trajectory0->SetOwner("IMAGE_0"); //--------------------------- // Create 2nd trajectory igtl::TrajectoryElement::Pointer trajectory1; trajectory1 = igtl::TrajectoryElement::New(); trajectory1->SetName("TRAJECTORY_1"); trajectory1->SetGroupName("GROUP_0"); trajectory1->SetRGBA(0x00, 0xFF, 0x00, 0xFF); trajectory1->SetEntryPosition(40.0, 50.0, 60.0); trajectory1->SetTargetPosition(20.0, 30.0, 10.0); trajectory1->SetRadius(45.0); trajectory1->SetOwner("IMAGE_0"); //--------------------------- // Create 3rd trajectory igtl::TrajectoryElement::Pointer trajectory2; trajectory2 = igtl::TrajectoryElement::New(); trajectory2->SetName("TRAJECTORY_2"); trajectory2->SetGroupName("GROUP_0"); trajectory2->SetRGBA(0x00, 0x00, 0xFF, 0xFF); trajectory2->SetEntryPosition(70.0, 80.0, 90.0); trajectory2->SetTargetPosition(10.0, 40.0, 20.0); trajectory2->SetRadius(75.0); trajectory2->SetOwner("IMAGE_0"); //--------------------------- // Pack into the trajectory message trajectoryMsg->AddTrajectoryElement(trajectory0); trajectoryMsg->AddTrajectoryElement(trajectory1); trajectoryMsg->AddTrajectoryElement(trajectory2); trajectoryMsg->Pack(); //--------------------------- // Send socket->Send(trajectoryMsg->GetPackPointer(), trajectoryMsg->GetPackSize()); } //------------------------------------------------------------ // Close connection (The example code never reachs to this section ...) } socket->CloseSocket(); } openigtlink-3.0.0/FindOpenIGTLink.cmake000066400000000000000000000075511501024245700177330ustar00rootroot00000000000000# - Find an OpenIGTLink installation or build tree. # When OpenIGTLink is found, the OpenIGTLinkConfig.cmake file is sourced to setup the # location and configuration of OpenIGTLink. Please read this file, or # OpenIGTLinkConfig.cmake.in from the OpenIGTLink source tree for the full list of # definitions. Of particular interest is OpenIGTLink_USE_FILE, a CMake source file # that can be included to set the include directories, library directories, # and preprocessor macros. In addition to the variables read from # OpenIGTLinkConfig.cmake, this find module also defines # OpenIGTLink_DIR - The directory containing OpenIGTLinkConfig.cmake. # This is either the root of the build tree, # or the lib/InsightToolkit directory. # This is the only cache entry. # # OpenIGTLink_FOUND - Whether OpenIGTLink was found. If this is true, # OpenIGTLink_DIR is okay. # # USE_OpenIGTLink_FILE - The full path to the UseOpenIGTLink.cmake file. # This is provided for backward # compatability. Use OpenIGTLink_USE_FILE # instead. SET(OpenIGTLink_DIR_STRING "directory containing OpenIGTLinkConfig.cmake. This is either the root of the build tree, or PREFIX/lib/igtl for an installation.") # Search only if the location is not already known. IF(NOT OpenIGTLink_DIR) # Get the system search path as a list. IF(UNIX) STRING(REGEX MATCHALL "[^:]+" OpenIGTLink_DIR_SEARCH1 "$ENV{PATH}") ELSE(UNIX) STRING(REGEX REPLACE "\\\\" "/" OpenIGTLink_DIR_SEARCH1 "$ENV{PATH}") ENDIF(UNIX) STRING(REGEX REPLACE "/;" ";" OpenIGTLink_DIR_SEARCH2 ${OpenIGTLink_DIR_SEARCH1}) # Construct a set of paths relative to the system search path. SET(OpenIGTLink_DIR_SEARCH "") FOREACH(dir ${OpenIGTLink_DIR_SEARCH2}) SET(OpenIGTLink_DIR_SEARCH ${OpenIGTLink_DIR_SEARCH} "${dir}/../lib/igtl") ENDFOREACH(dir) # # Look for an installation or build tree. # FIND_PATH(OpenIGTLink_DIR OpenIGTLinkConfig.cmake # Look for an environment variable OpenIGTLink_DIR. $ENV{OpenIGTLink_DIR} # Look in places relative to the system executable search path. ${OpenIGTLink_DIR_SEARCH} # Look in standard UNIX install locations. /usr/local/lib/igtl /usr/lib/igtl # Read from the CMakeSetup registry entries. It is likely that # OpenIGTLink will have been recently built. [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild1] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild2] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild3] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild4] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild5] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild6] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild7] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild8] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild9] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild10] # Help the user find it if we cannot. DOC "The ${OpenIGTLink_DIR_STRING}" ) ENDIF(NOT OpenIGTLink_DIR) # If OpenIGTLink was found, load the configuration file to get the rest of the # settings. IF(OpenIGTLink_DIR) SET(OpenIGTLink_FOUND 1) INCLUDE(${OpenIGTLink_DIR}/OpenIGTLinkConfig.cmake) # Set USE_OpenIGTLink_FILE for backward-compatability. SET(USE_OpenIGTLink_FILE ${OpenIGTLink_USE_FILE}) ELSE(OpenIGTLink_DIR) SET(OpenIGTLink_FOUND 0) IF(OpenIGTLink_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Please set OpenIGTLink_DIR to the ${OpenIGTLink_DIR_STRING}") ENDIF(OpenIGTLink_FIND_REQUIRED) ENDIF(OpenIGTLink_DIR) openigtlink-3.0.0/GenerateOpenIGTLinkConfig.cmake000066400000000000000000000077741501024245700217420ustar00rootroot00000000000000# Generate the OpenIGTLinkConfig.cmake file in the build tree. Also configure # one for installation. The file tells external projects how to use # OpenIGTLink. #----------------------------------------------------------------------------- # Settings specific to the build tree. # Generate CMake lines that will define the OpenIGTLink_SOURCE_DIR in the OpenIGTLinkConfig.cmake. # We want this to happen only in the OpenIGTLinkConfig.cmake of the build dir, not in the # installed or relocatable one. SET(OpenIGTLink_CONFIG_CODE " # The OpenIGTLink source tree. # For backward compatibility issues we still need to define this variable, although # it is highly probable that it will cause more harm than being useful. # Use OpenIGTLink_INCLUDE_DIRS instead, since OpenIGTLink_SOURCE_DIR may point to non-existent directory IF(NOT OpenIGTLink_LEGACY_REMOVE) SET(OpenIGTLink_SOURCE_DIR \"${OpenIGTLink_SOURCE_DIR}\") ENDIF(NOT OpenIGTLink_LEGACY_REMOVE)" ) # The "use" file. SET(OpenIGTLink_USE_FILE ${OpenIGTLink_BINARY_DIR}/UseOpenIGTLink.cmake) # The build settings file. SET(OpenIGTLink_BUILD_SETTINGS_FILE ${OpenIGTLink_BINARY_DIR}/OpenIGTLinkBuildSettings.cmake) # Library directory. SET(OpenIGTLink_LIBRARY_DIRS_CONFIG ${OpenIGTLink_LIBRARY_PATH}) # Determine the include directories needed. SET(OpenIGTLink_INCLUDE_DIRS_CONFIG ${OpenIGTLink_INCLUDE_DIRS_BUILD_TREE} ${OpenIGTLink_INCLUDE_DIRS_SYSTEM} ) #----------------------------------------------------------------------------- # Configure OpenIGTLinkConfig.cmake for the build tree. CONFIGURE_FILE(${OpenIGTLink_SOURCE_DIR}/OpenIGTLinkConfig.cmake.in ${OpenIGTLink_BINARY_DIR}/OpenIGTLinkConfig.cmake @ONLY IMMEDIATE) #----------------------------------------------------------------------------- # Settings specific to the install tree. # store old OpenIGTLink_LIBRARY_TARGETS_FILE SET(OpenIGTLink_LIBRARY_TARGETS_FILE_BUILDTREE ${OpenIGTLink_LIBRARY_TARGETS_FILE}) # The library dependencies file. SET(OpenIGTLink_LIBRARY_TARGETS_FILE "\${OpenIGTLink_INSTALL_PREFIX}/${OpenIGTLink_INSTALL_PACKAGE_DIR}/OpenIGTLinkTargets.cmake") # The "use" file. SET(OpenIGTLink_USE_FILE \${OpenIGTLink_INSTALL_PREFIX}/${OpenIGTLink_INSTALL_PACKAGE_DIR}/UseOpenIGTLink.cmake) # The build settings file. SET(OpenIGTLink_BUILD_SETTINGS_FILE \${OpenIGTLink_INSTALL_PREFIX}/${OpenIGTLink_INSTALL_PACKAGE_DIR}/OpenIGTLinkBuildSettings.cmake) # Include directories. SET(OpenIGTLink_INCLUDE_DIRS_CONFIG \${OpenIGTLink_INSTALL_PREFIX}/${OpenIGTLink_INSTALL_INCLUDE_DIR}) FOREACH(DIR ${OpenIGTLink_INCLUDE_RELATIVE_DIRS}) LIST(APPEND OpenIGTLink_INCLUDE_DIRS_CONFIG \${OpenIGTLink_INSTALL_PREFIX}/${OpenIGTLink_INSTALL_INCLUDE_DIR}/${DIR}) ENDFOREACH(DIR) IF(OpenIGTLink_INCLUDE_DIRS_SYSTEM) LIST(APPEND OpenIGTLink_INCLUDE_DIRS_CONFIG ${OpenIGTLink_INCLUDE_DIRS_SYSTEM}) ENDIF(OpenIGTLink_INCLUDE_DIRS_SYSTEM) # Link directories. SET(OpenIGTLink_LIBRARY_DIRS_CONFIG "\${OpenIGTLink_INSTALL_PREFIX}/${OpenIGTLink_INSTALL_LIB_DIR}") #----------------------------------------------------------------------------- # Configure OpenIGTLinkConfig.cmake for the install tree. # Construct the proper number of GET_FILENAME_COMPONENT(... PATH) # calls to compute the installation prefix. STRING(REGEX REPLACE "/" ";" OpenIGTLink_INSTALL_PACKAGE_DIR_COUNT "${OpenIGTLink_INSTALL_PACKAGE_DIR}") SET(OpenIGTLink_CONFIG_CODE " # Compute the installation prefix from this OpenIGTLinkConfig.cmake file location. GET_FILENAME_COMPONENT(OpenIGTLink_INSTALL_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)") FOREACH(p ${OpenIGTLink_INSTALL_PACKAGE_DIR_COUNT}) SET(OpenIGTLink_CONFIG_CODE "${OpenIGTLink_CONFIG_CODE}\nGET_FILENAME_COMPONENT(OpenIGTLink_INSTALL_PREFIX \"\${OpenIGTLink_INSTALL_PREFIX}\" PATH)" ) ENDFOREACH(p) CONFIGURE_FILE(${OpenIGTLink_SOURCE_DIR}/OpenIGTLinkConfig.cmake.in ${OpenIGTLink_BINARY_DIR}/Utilities/OpenIGTLinkConfig.cmake @ONLY IMMEDIATE) # restore old OpenIGTLink_LIBRARY_TARGETS_FILE SET(OpenIGTLink_LIBRARY_TARGETS_FILE ${OpenIGTLink_LIBRARY_TARGETS_FILE_BUILDTREE}) openigtlink-3.0.0/LICENSE.txt000066400000000000000000000030001501024245700156510ustar00rootroot00000000000000Copyright (c) 2008, Insight Software Consortium 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. * Neither the name of the Insight Software Consortium 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. openigtlink-3.0.0/OpenIGTLinkConfig.cmake.in000066400000000000000000000041441501024245700206600ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # OpenIGTLinkConfig.cmake - OpenIGTLink CMake configuration file for external projects. # # This file is configured by OpenIGTLink and used by the UseOpenIGTLink.cmake module # to load OpenIGTLink's settings for an external project. @OpenIGTLink_CONFIG_CODE@ # The OpenIGTLink include file directories. SET(OpenIGTLink_INCLUDE_DIRS "@OpenIGTLink_INCLUDE_DIRS_CONFIG@") # The OpenIGTLink library directories. SET(OpenIGTLink_LIBRARY_DIRS "@OpenIGTLink_LIBRARY_DIRS_CONFIG@") # The C and C++ flags added by OpenIGTLink to the cmake-configured flags. SET(OpenIGTLink_REQUIRED_C_FLAGS "@OpenIGTLink_REQUIRED_C_FLAGS@") SET(OpenIGTLink_REQUIRED_CXX_FLAGS "@OpenIGTLink_REQUIRED_CXX_FLAGS@") SET(OpenIGTLink_REQUIRED_LINK_FLAGS "@OpenIGTLink_REQUIRED_LINK_FLAGS@") # The OpenIGTLink Library version number SET(OpenIGTLink_VERSION_MAJOR "@OpenIGTLink_VERSION_MAJOR@") SET(OpenIGTLink_VERSION_MINOR "@OpenIGTLink_VERSION_MINOR@") SET(OpenIGTLink_VERSION_PATCH "@OpenIGTLink_VERSION_PATCH@") # The OpenIGTLink Protocol version number SET(OpenIGTLink_PROTOCOL_VERSION "@OpenIGTLink_PROTOCOL_VERSION@") # The location of the UseOpenIGTLink.cmake file. SET(OpenIGTLink_USE_FILE "@OpenIGTLink_USE_FILE@") # The build settings file. SET(OpenIGTLink_BUILD_SETTINGS_FILE "@OpenIGTLink_BUILD_SETTINGS_FILE@") # Whether OpenIGTLink was built with shared libraries. SET(OpenIGTLink_BUILD_SHARED "@BUILD_SHARED_LIBS@") # Whether OpenIGTLink was built with Tcl wrapping support. SET(OpenIGTLink_CSWIG_TCL "@OpenIGTLink_CSWIG_TCL@") SET(OpenIGTLink_CSWIG_PYTHON "@OpenIGTLink_CSWIG_PYTHON@") SET(OpenIGTLink_CSWIG_JAVA "@OpenIGTLink_CSWIG_JAVA@") # Path to CableSwig configuration used by OpenIGTLink. SET(OpenIGTLink_CableSwig_DIR "@OpenIGTLink_CableSwig_DIR_CONFIG@") # A list of all libraries for OpenIGTLink. Those listed here should # automatically pull in their dependencies. SET(OpenIGTLink_LIBRARIES OpenIGTLink) # The OpenIGTLink library targets. SET(OpenIGTLink_LIBRARY_TARGETS_FILE "@OpenIGTLink_LIBRARY_TARGETS_FILE@") include(${OpenIGTLink_LIBRARY_TARGETS_FILE}) openigtlink-3.0.0/OpenIGTLinkConfigPlatform.cmake000066400000000000000000000072731501024245700217660ustar00rootroot00000000000000#----------------------------------------------------------------------------- # Check platform and generate igtlConfigure.h #----------------------------------------------------------------------------- # # The platform is determined by CMAKE_SYSTEM_NAME variable. # CMake set CMAKE_SYSTEM_NAME based on "uname -s" on unix or just set "Windows" # on windows. # The list of "uname -s" is available in CMake/Modules/CMakeDetermineSystem.cmake # # Thread parameters STRING(FIND ${CMAKE_SYSTEM_NAME} "Windows" _win_string_pos) # Use pthread in default except Windows if(NOT _win_string_pos EQUAL -1) SET(OpenIGTLink_USE_WIN32_THREADS 1) else() SET(OpenIGTLink_USE_PTHREADS 1) endif() # Windows if(NOT _win_string_pos EQUAL -1) SET(OpenIGTLink_PLATFORM_WIN32 1) endif() # Mac OS X if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") SET(OpenIGTLink_PLATFORM_MACOSX 1) endif() # Linux if(CMAKE_SYSTEM_NAME MATCHES "Linux") SET(OpenIGTLink_PLATFORM_LINUX 1) endif() # Sun OS if(CMAKE_SYSTEM_NAME MATCHES "SunOS") # SET(OpenIGTLink_USE_SPROC 1) SET(OpenIGTLink_PLATFORM_SUNOS 1) # Set OpenIGTLink_STD_LINK_LIBRARIES SET(OpenIGTLink_STD_LINK_LIBRARIES ${OpenIGTLink_STD_LINK_LIBRARIES} rt nsl socket ) IF(CMAKE_COMPILER_IS_GNUCXX) SET(OpenIGTLink_STD_LINK_LIBRARIES ${OpenIGTLink_STD_LINK_LIBRARIES} stdc++ ) ELSE(CMAKE_COMPILER_IS_GNUCXX) #FIND_LIBRARY(OpenIGTLink_SUNCC_CSTD_LIBRARY Cstd /opt/SUNWspro/lib) #IF(OpenIGTLink_SUNCC_CSTD_LIBRARY) # SET(OpenIGTLink_STD_LINK_LIBRARIES # ${OpenIGTLink_STD_LINK_LIBRARIES} # Cstd # ) #ENDIF(OpenIGTLink_SUNCC_CSTD_LIBRARY) #FIND_LIBRARY(OpenIGTLink_SUNCC_CRUN_LIBRARY Crun /opt/SUNWspro/lib) #IF(OpenIGTLink_SUNCC_CRUN_LIBRARY) # SET(OpenIGTLink_STD_LINK_LIBRARIES # ${OpenIGTLink_STD_LINK_LIBRARIES} # Crun # ) #ENDIF(OpenIGTLink_SUNCC_CRUN_LIBRARY) ENDIF(CMAKE_COMPILER_IS_GNUCXX) endif(CMAKE_SYSTEM_NAME MATCHES "SunOS") # QNX if(CMAKE_SYSTEM_NAME STREQUAL "QNX") SET(OpenIGTLink_PLATFORM_QNX 1) endif() #----------------------------------------------------------------------------- # Type Check # include(CheckTypeSize) check_type_size(int CMAKE_SIZEOF_INT) check_type_size(long CMAKE_SIZEOF_LONG) check_type_size("void*" CMAKE_SIZEOF_VOID_P) check_type_size(char CMAKE_SIZEOF_CHAR) check_type_size(short CMAKE_SIZEOF_SHORT) check_type_size(float CMAKE_SIZEOF_FLOAT) check_type_size(double CMAKE_SIZEOF_DOUBLE) check_type_size("long long" CMAKE_SIZEOF_LONG_LONG) check_type_size("__int64" CMAKE_SIZEOF___INT64) check_type_size("int64_t" CMAKE_SIZEOF_INT64_T) #ADD_DEFINITIONS(-DIGTL_SIZEOF_CHAR=${CMAKE_SIZEOF_CHAR}) #ADD_DEFINITIONS(-DIGTL_SIZEOF_DOUBLE=${CMAKE_SIZEOF_DOUBLE}) #ADD_DEFINITIONS(-DIGTL_SIZEOF_FLOAT=${CMAKE_SIZEOF_FLOAT}) #ADD_DEFINITIONS(-DIGTL_SIZEOF_INT=${CMAKE_SIZEOF_INT}) #ADD_DEFINITIONS(-DIGTL_SIZEOF_LONG=${CMAKE_SIZEOF_LONG}) #ADD_DEFINITIONS(-DIGTL_SIZEOF_SHORT=${CMAKE_SIZEOF_SHORT}) #ADD_DEFINITIONS(-DIGTL_SIZEOF_FLOAT=${CMAKE_SIZEOF_FLOAT}) #ADD_DEFINITIONS(-DIGTL_SIZEOF_DOUBLE=${CMAKE_SIZEOF_DOUBLE}) #IF(CMAKE_SIZEOF_LONG_LONG) # ADD_DEFINITIONS(-DIGTL_TYPE_USE_LONG_LONG=1) # ADD_DEFINITIONS(-DIGTL_SIZEOF_LONG_LONG=${CMAKE_SIZEOF_LONG_LONG}) #ELSE(CMAKE_SIZEOF_LONG_LONG) # IF(CMAKE_SIZEOF___INT64) # ADD_DEFINITIONS(-DIGTL_TYPE_USE___INT64=1) # ADD_DEFINITIONS(-DIGTL_SIZEOF___INT64=${CMAKE_SIZEOF___INT64}) # ELSE(CMAKE_SIZEOF___INT64) # IF(CMAKE_SIZEOF_INT64_T) # ADD_DEFINITIONS(-DIGTL_TYPE_USE_INT64_T=1) # ADD_DEFINITIONS(-DIGTL_SIZEOF_INT64_T=${CMAKE_SIZEOF_INT64_T}) # ENDIF(CMAKE_SIZEOF_INT64_T) # ENDIF(CMAKE_SIZEOF___INT64) #ENDIF(CMAKE_SIZEOF_LONG_LONG)openigtlink-3.0.0/README.md000066400000000000000000000042241501024245700153160ustar00rootroot00000000000000The OpenIGTLink Library ======================= The OpenIGTLink Library is a C/C++ implementation of [The OpenIGTLink Protocol](Documents/Protocol/index.md). OpenIGTLink is an open-source network communication interface specifically designed for image-guided interventions. It aims to provide a plug-and-play unified real-time communications (URTC) in operating rooms (ORs) for image-guided interventions, where imagers, sensors, surgical robots,and computers from different vendors work cooperatively. This URTC will ensure the seamless data flow among those components and enable a closed-loop process of planning, control, delivery, and feedback. The specification of OpenIGTLink is open, and can be used without any license fee; hence OpenIGTLink is suitable for both industrial and academic developers. The latest information of the protocol is available at [OpenIGTLink Web Page](http://openigtlink.org/). The definition of the protocol used in the current version (one in this git repository) can be found in [Protocol Documentation](Documents/Protocol/index.md) Build Status ------------ * Linux/Mac: [![Build Status](https://travis-ci.org/openigtlink/OpenIGTLink.svg?branch=master)](https://travis-ci.org/openigtlink/OpenIGTLink) * Windows: [![Build status](https://ci.appveyor.com/api/projects/status/beo8cej2nxu55ex0?svg=true)](https://ci.appveyor.com/project/openigtlink/openigtlink) Build Instruction ----------------- Please see [BUILD Instruction](BUILD.md). How to Contribute? ------------------ If you find any issues or have feature request, please feel free to post to [Issues](https://github.com/openigtlink/OpenIGTLink/issues). The OpenIGTLink community is adapted to the collaborative development model on GitHub. [GitHub's instruction"](https://help.github.com/articles/about-collaborative-development-models/) provides a nice overview of collaborative development models and workflows. License ------- The code is distributed as open source under The 3-Clause BSD License. Please refer to the license terms available at [Open Source Initiative Page](https://opensource.org/licenses/BSD-3-Clause) or [LICENSE.txt](LICENSE.txt) included in the source repository. openigtlink-3.0.0/Source/000077500000000000000000000000001501024245700152755ustar00rootroot00000000000000openigtlink-3.0.0/Source/CMakeLists.txt000066400000000000000000000137421501024245700200440ustar00rootroot00000000000000# list of libraries # Note: this part should be moved to OpenIGTLinkConfigPlatform.cmake IF(OpenIGTLink_PLATFORM_WIN32) # for Windows SET(LINK_LIBS ws2_32 wsock32 ) #For debug under win32 system, the run time check mode should be set to /RTCu for multithreading purpose STRING(REPLACE "/RTC1" "/RTCu" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") SET(OpenIGTLink_REQUIRED_CXX_FLAGS ${OpenIGTLink_REQUIRED_CXX_FLAGS}) ELSE() # for POSIX-compatible OSs SET(LINK_LIBS m pthread ) IF(OpenIGTLink_PLATFORM_QNX) LIST(APPEND LINK_LIBS c socket ) ENDIF() IF(OpenIGTLink_PLATFORM_SUNOS) LIST(APPEND LINK_LIBS ${OpenIGTLink_STD_LINK_LIBRARIES} ) ENDIF() ENDIF() ADD_SUBDIRECTORY( igtlutil ) SET(OpenIGTLink_INCLUDE_DIRS ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/igtlutil ${CMAKE_CURRENT_BINARY_DIR}/igtlutil ) SET(OpenIGTLink_SOURCES igtlutil/igtl_header.c igtlutil/igtl_image.c igtlutil/igtl_transform.c igtlutil/igtl_status.c igtlutil/igtl_util.c igtlutil/igtl_position.c igtlutil/igtl_capability.c igtlClientSocket.cxx igtlCapabilityMessage.cxx igtlConditionVariable.cxx igtlFastMutexLock.cxx igtlImageMessage.cxx igtlImageMessage2.cxx igtlLightObject.cxx igtlMath.cxx igtlMessageBase.cxx igtlMessageFactory.cxx igtlMultiThreader.cxx igtlMutexLock.cxx igtlOSUtil.cxx igtlObject.cxx igtlObjectFactoryBase.cxx igtlPositionMessage.cxx igtlServerSocket.cxx igtlSessionManager.cxx igtlSimpleFastMutexLock.cxx igtlSocket.cxx igtlStatusMessage.cxx igtlTimeStamp.cxx igtlTransformMessage.cxx ) SET(OpenIGTLink_INCLUDE_FILES) IF( MSVC OR ${CMAKE_GENERATOR} MATCHES "Xcode" ) LIST(APPEND OpenIGTLink_INCLUDE_FILES igtlutil/igtl_header.h igtlutil/igtl_image.h igtlutil/igtl_position.h igtlutil/igtl_transform.h igtlutil/igtl_types.h igtlutil/igtl_util.h igtlutil/igtl_capability.h igtlutil/igtl_win32header.h igtlMessageHandler.h igtlMessageHandlerMacro.h igtlCapabilityMessage.h igtlClientSocket.h igtlConditionVariable.h igtlCreateObjectFunction.h igtlFastMutexLock.h igtlImageMessage.h igtlImageMessage2.h igtlLightObject.h igtlMacro.h igtlMath.h igtlMessageBase.h igtlMessageFactory.h igtlMessageHeader.h igtlMultiThreader.h igtlMutexLock.h igtlObjectFactory.h igtlOSUtil.h igtlObject.h igtlObjectFactoryBase.h igtlPositionMessage.h igtlServerSocket.h igtlSessionManager.h igtlSimpleFastMutexLock.h igtlSmartPointer.h igtlSocket.h igtlStatusMessage.h igtlTimeStamp.h igtlTransformMessage.h igtlTypes.h igtlWin32Header.h igtlWindows.h igtlCommon.h ) ENDIF() # Add support for OpenIGTLink version 2 IF (${OpenIGTLink_PROTOCOL_VERSION} GREATER "1" ) LIST(APPEND OpenIGTLink_SOURCES igtlutil/igtl_colortable.c igtlutil/igtl_imgmeta.c igtlutil/igtl_lbmeta.c igtlutil/igtl_point.c igtlutil/igtl_tdata.c igtlutil/igtl_qtdata.c igtlutil/igtl_trajectory.c igtlutil/igtl_unit.c igtlutil/igtl_sensor.c igtlutil/igtl_string.c igtlutil/igtl_ndarray.c igtlutil/igtl_bind.c igtlutil/igtl_qtrans.c igtlutil/igtl_polydata.c igtlColorTableMessage.cxx igtlImageMetaMessage.cxx igtlLabelMetaMessage.cxx igtlPointMessage.cxx igtlTrackingDataMessage.cxx igtlPolyDataMessage.cxx igtlQuaternionTrackingDataMessage.cxx igtlTrajectoryMessage.cxx igtlStringMessage.cxx igtlUnit.cxx igtlSensorMessage.cxx igtlBindMessage.cxx igtlNDArrayMessage.cxx ) IF( MSVC OR ${CMAKE_GENERATOR} MATCHES "Xcode" ) LIST(APPEND OpenIGTLink_INCLUDE_FILES igtlutil/igtl_colortable.h igtlutil/igtl_imgmeta.h igtlutil/igtl_lbmeta.h igtlutil/igtl_point.h igtlutil/igtl_tdata.h igtlutil/igtl_qtdata.h igtlutil/igtl_trajectory.h igtlutil/igtl_unit.h igtlutil/igtl_sensor.h igtlutil/igtl_string.h igtlutil/igtl_ndarray.h igtlutil/igtl_bind.h igtlutil/igtl_qtrans.h igtlutil/igtl_polydata.h igtlColorTableMessage.h igtlImageMetaMessage.h igtlLabelMetaMessage.h igtlPointMessage.h igtlTrackingDataMessage.h igtlPolyDataMessage.h igtlQuaternionTrackingDataMessage.h igtlTrajectoryMessage.h igtlStringMessage.h igtlUnit.h igtlSensorMessage.h igtlBindMessage.h igtlNDArrayMessage.h ) ENDIF() ENDIF() # Add support for OpenIGTLink version 3 IF( ${OpenIGTLink_PROTOCOL_VERSION} GREATER "2" ) LIST(APPEND OpenIGTLink_SOURCES igtlCommandMessage.cxx igtlQueryMessage.cxx igtlutil/igtl_command.c igtlutil/igtl_query.c ) IF( MSVC OR ${CMAKE_GENERATOR} MATCHES "Xcode" ) LIST(APPEND OpenIGTLink_INCLUDE_FILES igtlCommandMessage.h igtlQueryMessage.h igtlutil/igtl_command.h igtlutil/igtl_query.h ) ENDIF() ENDIF() ADD_LIBRARY(OpenIGTLink ${OpenIGTLink_SOURCES} ${OpenIGTLink_INCLUDE_FILES}) foreach(p IN LISTS OpenIGTLink_INCLUDE_DIRS) target_include_directories(OpenIGTLink PUBLIC $) endforeach() target_include_directories(OpenIGTLink PUBLIC $) TARGET_LINK_LIBRARIES(OpenIGTLink PUBLIC ${LINK_LIBS}) IF(MSVC) target_compile_options(OpenIGTLink PRIVATE /MP) ENDIF() SET_TARGET_PROPERTIES(OpenIGTLink PROPERTIES VERSION ${OpenIGTLink_VERSION_MAJOR}.${OpenIGTLink_VERSION_MINOR}.${OpenIGTLink_VERSION_PATCH} SOVERSION ${OpenIGTLink_VERSION_MAJOR} ) INSTALL(FILES ${OpenIGTLink_INCLUDE_FILES} DESTINATION ${OpenIGTLink_INSTALL_INCLUDE_DIR} COMPONENT Development) INSTALL(TARGETS OpenIGTLink EXPORT OpenIGTLink RUNTIME DESTINATION ${OpenIGTLink_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries LIBRARY DESTINATION ${OpenIGTLink_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries ARCHIVE DESTINATION ${OpenIGTLink_INSTALL_LIB_DIR} COMPONENT Development)openigtlink-3.0.0/Source/igtlBindMessage.cxx000066400000000000000000000310041501024245700210600ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlBindMessage.h" #include "igtl_header.h" #include "igtl_bind.h" #include namespace igtl { BindMessageBase::BindMessageBase(): MessageBase() { Init(); } BindMessageBase::~BindMessageBase() { } void BindMessageBase::Init() { this->m_ChildMessages.clear(); } int BindMessageBase::SetNumberOfChildMessages(unsigned int n) { this->m_ChildMessages.resize(n); return this->m_ChildMessages.size(); } int BindMessageBase::GetNumberOfChildMessages() { return this->m_ChildMessages.size(); } int BindMessageBase::AppendChildMessage(igtl::MessageBase * child) { if (this->m_ChildMessages.size() < 0xFFFF) { ChildMessageInfo info; #if OpenIGTLink_HEADER_VERSION >= 2 info.type = child->GetMessageType(); #else info.type = child->GetDeviceType(); #endif info.name = child->GetDeviceName(); // If the class instance is BindMessage. if (strncmp(this->m_SendMessageType.c_str(), "BIND", 4) == 0) { info.size = child->GetBufferBodySize(); info.ptr = child->GetBufferBodyPointer(); } this->m_ChildMessages.push_back(info); } return this->m_ChildMessages.size(); } int BindMessageBase::SetChildMessage(unsigned int i, igtl::MessageBase * child) { if (i < this->m_ChildMessages.size()) { #if OpenIGTLink_HEADER_VERSION >= 2 this->m_ChildMessages[i].type = child->GetMessageType(); #else this->m_ChildMessages[i].type = child->GetDeviceType(); #endif this->m_ChildMessages[i].name = child->GetDeviceName(); // If the class instance is BindMessage. if (strncmp(this->m_SendMessageType.c_str(), "BIND", 4) == 0) { this->m_ChildMessages[i].size = child->GetBufferBodySize(); this->m_ChildMessages[i].ptr = child->GetBufferBodyPointer(); } return 1; } else { return 0; } } const char* BindMessageBase::GetChildMessageType(unsigned int i) { if (i < this->m_ChildMessages.size()) { return this->m_ChildMessages[i].type.c_str(); } else { return NULL; } } BindMessage::BindMessage(): BindMessageBase() { this->m_SendMessageType = "BIND"; } BindMessage::~BindMessage() { } int BindMessage::GetChildMessage(unsigned int i, igtl::MessageBase * child) { if (i < this->m_ChildMessages.size()) { child->InitBuffer(); igtl_header * header = (igtl_header *) child->GetBufferPointer(); header->header_version = 1; strncpy( header->name, this->m_ChildMessages[i].type.c_str(), IGTL_HEADER_TYPE_SIZE); strncpy( header->device_name, this->m_ChildMessages[i].name.c_str(), IGTL_HEADER_NAME_SIZE); // Time stamp -- same as the bind message igtl_uint64 ts = m_TimeStampSec & 0xFFFFFFFF; ts = (ts << 32) | (m_TimeStampSecFraction & 0xFFFFFFFF); header->timestamp = ts; header->body_size = this->m_ChildMessages[i].size; header->crc = 0; // Convert to network byte order igtl_header_convert_byte_order(header); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), header, IGTL_HEADER_SIZE); headerMsg->Unpack(); child->SetMessageHeader(headerMsg); child->AllocateBuffer(); // TODO: Is there any way to avoid this memory copy? memcpy(child->GetBufferBodyPointer(), this->m_ChildMessages[i].ptr, this->m_ChildMessages[i].size); child->Unpack(); return 1; } else { return 0; } } int BindMessage::CalculateContentBufferSize() { int size; int nameTableSectionSize = 0; // Size of name table section int dataSectionSize = 0; // Size of data section size = sizeof(igtlUint16) // Number of child messages section + (IGTL_HEADER_TYPE_SIZE + sizeof(igtlUint64)) * this->m_ChildMessages.size() // BIND header + sizeof (igtlUint16); // Size of name table section std::vector::iterator iter; for (iter = this->m_ChildMessages.begin(); iter != this->m_ChildMessages.end(); iter ++) { nameTableSectionSize += (*iter).name.length(); nameTableSectionSize += 1; // NULL separator dataSectionSize += (*iter).size + ((*iter).size%2); // child message body + padding (if applicable) } // Add padding for the whole name table section if (nameTableSectionSize % 2 > 0) { nameTableSectionSize++; } size += nameTableSectionSize; size += dataSectionSize; return size; } int BindMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_bind_info bind_info; igtl_bind_init_info(&bind_info); if (igtl_bind_alloc_info(&bind_info, this->m_ChildMessages.size())) { // TODO: using c library causes additional data copy (C++ member variable to c-structure, // then to pack byte array). Probably, it's good idea to implement PackBody() without // using c APIs. int i = 0; std::vector::iterator iter; for (iter = this->m_ChildMessages.begin(); iter != this->m_ChildMessages.end(); iter ++) { strncpy(bind_info.child_info_array[i].type, (*iter).type.c_str(), IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[i].name, (*iter).name.c_str(), IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[i].size = (*iter).size; bind_info.child_info_array[i].ptr = (*iter).ptr; i ++; } igtl_bind_pack(&bind_info, this->m_Content, IGTL_TYPE_PREFIX_NONE); int nc = this->m_ChildMessages.size(); size_t bind_size = (size_t) igtl_bind_get_size(&bind_info, IGTL_TYPE_PREFIX_NONE); char * ptr = (char *)this->m_Content; ptr = ptr + bind_size; for (int i = 0; i < nc; i ++) { memcpy((void*)ptr, bind_info.child_info_array[i].ptr, bind_info.child_info_array[i].size); ptr += bind_info.child_info_array[i].size; /* Note: a padding byte is added, if the size of the child message body is odd. */ if (bind_info.child_info_array[i].size % 2) { *ptr = '\0'; ptr ++; } } igtl_bind_free_info(&bind_info); // TODO: calling igtl_bind_free_info() after igtl_bind_pack() causes // this causes segmentation fault on Linux... why? return 1; } else { return 0; } } int BindMessage::UnpackContent() { igtl_bind_info bind_info; if (igtl_bind_unpack(IGTL_TYPE_PREFIX_NONE, (void*)this->m_Content, &bind_info, this->GetBufferBodySize()) == 0) { return 0; } int n = bind_info.ncmessages; Init(); for (int i = 0; i < n; i ++) { ChildMessageInfo info; info.type = bind_info.child_info_array[i].type; info.name = bind_info.child_info_array[i].name; info.size = bind_info.child_info_array[i].size; info.ptr = bind_info.child_info_array[i].ptr; this->m_ChildMessages.push_back(info); } return 1; } GetBindMessage::GetBindMessage(): BindMessageBase() { this->m_SendMessageType = "GET_BIND"; } GetBindMessage::~GetBindMessage() { } int GetBindMessage::AppendChildMessage(const char * type, const char * name) { if (strlen(type) < IGTL_HEADER_TYPE_SIZE && strlen(name) < IGTL_HEADER_NAME_SIZE) { BindMessageBase::ChildMessageInfo info; info.type = type; info.name = name; this->m_ChildMessages.push_back(info); } return this->m_ChildMessages.size(); } int GetBindMessage::CalculateContentBufferSize() { int size; size = sizeof(igtlUint16) // Number of child messages section + IGTL_HEADER_TYPE_SIZE * this->m_ChildMessages.size() // BIND header + sizeof (igtlUint16); // Size of name table section std::vector::iterator iter; for (iter = this->m_ChildMessages.begin(); iter != this->m_ChildMessages.end(); iter ++) { size += (*iter).name.length(); size += 1; // NULL separator } return size; } int GetBindMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_bind_info bind_info; igtl_bind_init_info(&bind_info); if (igtl_bind_alloc_info(&bind_info, this->m_ChildMessages.size())) { // TODO: using c library causes additional data copy (C++ member variable to c-structure, // then to pack byte array). Probably, it's good idea to implement PackBody() without // using c APIs. int i = 0; std::vector::iterator iter; for (iter = this->m_ChildMessages.begin(); iter != this->m_ChildMessages.end(); iter ++) { strncpy(bind_info.child_info_array[i].type, (*iter).type.c_str(), IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[i].name, (*iter).name.c_str(), IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[i].size = 0; bind_info.child_info_array[i].ptr = NULL; i ++; } igtl_bind_pack(&bind_info, this->m_Content, IGTL_TYPE_PREFIX_GET); igtl_bind_free_info(&bind_info); return 1; } else { return 0; } } int GetBindMessage::UnpackContent() { igtl_bind_info bind_info; if (igtl_bind_unpack(IGTL_TYPE_PREFIX_NONE, (void*)this->m_Content, &bind_info, this->GetBufferBodySize()) == 0) { return 0; } int n = bind_info.ncmessages; Init(); for (int i = 0; i < n; i ++) { ChildMessageInfo info; info.type = bind_info.child_info_array[i].type; info.name = bind_info.child_info_array[i].name; info.size = 0; info.ptr = NULL; this->m_ChildMessages.push_back(info); } return 1; } StartBindMessage::StartBindMessage(): GetBindMessage() { this->m_SendMessageType = "STT_BIND"; } StartBindMessage::~StartBindMessage() { } void StartBindMessage::SetResolution(igtlUint64 res) { this->m_Resolution = res; } igtlUint64 StartBindMessage::GetResolution() { return this->m_Resolution; } int StartBindMessage::CalculateContentBufferSize() { if (this->m_ChildMessages.size() == 0) { // Only a time stamp field is in the message return sizeof(igtlUint64); } return Superclass::CalculateContentBufferSize() + sizeof(igtlUint64); } int StartBindMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_bind_info bind_info; igtl_bind_init_info(&bind_info); // If there is no child message information in the class instance, // the message request any available messages if (this->m_ChildMessages.size() == 0) { bind_info.request_all = 1; } if (igtl_bind_alloc_info(&bind_info, this->m_ChildMessages.size())) { // TODO: using c library causes additional data copy (C++ member variable to c-structure, // then to pack byte array). Probably, it's good idea to implement PackBody() without // using c APIs. int i = 0; std::vector::iterator iter; for (iter = this->m_ChildMessages.begin(); iter != this->m_ChildMessages.end(); iter ++) { strncpy(bind_info.child_info_array[i].type, (*iter).type.c_str(), IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[i].name, (*iter).name.c_str(), IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[i].size = 0; bind_info.child_info_array[i].ptr = NULL; i ++; } bind_info.resol = this->m_Resolution; igtl_bind_pack(&bind_info, this->m_Content, IGTL_TYPE_PREFIX_STT); igtl_bind_free_info(&bind_info); return 1; } else { return 0; } } int StartBindMessage::UnpackContent() { igtl_bind_info bind_info; if (igtl_bind_unpack(IGTL_TYPE_PREFIX_NONE, (void*)this->m_Content, &bind_info, this->GetBufferBodySize()) == 0) { return 0; } int n = bind_info.ncmessages; this->m_Resolution = bind_info.resol; Init(); for (int i = 0; i < n; i ++) { ChildMessageInfo info; info.type = bind_info.child_info_array[i].type; info.name = bind_info.child_info_array[i].name; info.size = 0; info.ptr = NULL; this->m_ChildMessages.push_back(info); } return 1; } int RTSBindMessage::CalculateContentBufferSize() { return sizeof (igtlUint8); } int RTSBindMessage::PackContent() { AllocateBuffer(); * (igtlUint8 * )this->m_Content = this->m_Status; return 1; } int RTSBindMessage::UnpackContent() { this->m_Status = * (igtlUint8 * )this->m_Content; return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlBindMessage.h000066400000000000000000000202321501024245700205060ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlBindMessage_h #define __igtlBindMessage_h #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" namespace igtl { /// The BindMessageBase class is a base class for the BindMessage, GetBindMessage and /// StartBindMessage classes. The class is used to manage a list of child messages that /// will be bundled into a BIND message. class IGTLCommon_EXPORT BindMessageBase: public MessageBase { public: typedef BindMessageBase Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::BindMessageBase, igtl::MessageBase); igtlNewMacro(igtl::BindMessageBase); public: /// Initializes the BindMessageBase class. void Init(); /// Sets the number of child messages bundled in the message and returns the total number of /// child messages. The returned value should be same as 'n', if the number is updated successfully. int SetNumberOfChildMessages(unsigned int n); /// Gets the number of child messages bundled in the message. int GetNumberOfChildMessages(); /// Appends a new child message to the end of the list of child messages. /// The AppendChildMessage() function will increment the number of child messages. /// Returns the number of child messages after appending the specified child message. int AppendChildMessage(igtl::MessageBase * child); /// Sets or replaces a child message specified by the index 'i'. The SetChildMessage() does not /// increment the number of child messages. Returns non-zero value, if success. int SetChildMessage(unsigned int i, igtl::MessageBase * child); /// Gets the name of a child message specified by the index 'i'. const char* GetChildMessageType(unsigned int i); protected: BindMessageBase(); ~BindMessageBase(); protected: /// A structure to manage properties of a child message, including message type, message name, /// size and pointer to the class instance of the child message. A ChildMessageInfo structure is /// allocated per child message and managed by a vector m_ChildMessages. typedef struct { std::string type; std::string name; igtlUint64 size; void * ptr; } ChildMessageInfo; /// A vector to manage a list of ChildMessageInfo structures. std::vector m_ChildMessages; }; /// A class for the BIND message type class IGTLCommon_EXPORT BindMessage: public BindMessageBase { public: typedef BindMessage Self; typedef BindMessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::BindMessage, igtl::BindMessageBase); igtlNewMacro(igtl::BindMessage); public: /// Gets a child message specified by the index 'i'. A pointer to the instance of /// the specified child message is substituted to the message base specified by 'child'. /// Returns non-zero value if success. int GetChildMessage(unsigned int i, igtl::MessageBase * child); protected: BindMessage(); ~BindMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); }; /// A class for the GET_BIND message type. The GET_BIND message contains a list of child messages /// to request for specific messages. If no child message is specified, the receiver must return /// the all available messages. class IGTLCommon_EXPORT GetBindMessage: public BindMessageBase { public: typedef GetBindMessage Self; typedef BindMessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetBindMessage, igtl::BindMessageBase); igtlNewMacro(igtl::GetBindMessage); public: /// Appends the type and name of a new child message to the end of the list of child messages. /// The AppendChildMessage() function will increment the number of child messages. /// Returns the number of child messages. int AppendChildMessage(const char * type, const char * name); protected: GetBindMessage(); ~GetBindMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); }; /// A class for the STT_BIND message type. Like the GET_BIND message type, it contains a list of /// child messages to request for specific messages. If no child message is specified, /// the receiver must return the all available messages. class IGTLCommon_EXPORT StartBindMessage: public GetBindMessage { public: typedef StartBindMessage Self; typedef GetBindMessage Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StartBindMessage, igtl::GetBindMessage); igtlNewMacro(igtl::StartBindMessage); public: /// Sets time resolution. The time resolution is specified /// as a 64-bit fixed-point used in OpenIGTLink time stamp. void SetResolution(igtlUint64 res); /// Gets time resolution. The time resolution is specified /// as a 64-bit fixed-point used in OpenIGTLink time stamp. igtlUint64 GetResolution(); protected: StartBindMessage(); ~StartBindMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); igtlUint64 m_Resolution; }; /// A class for the STP_BIND message type. The STP_BIND message is sent to the sender /// of BIND message stream to stop it. class IGTLCommon_EXPORT StopBindMessage: public MessageBase { public: typedef StopBindMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StopBindMessage, igtl::MessageBase); igtlNewMacro(igtl::StopBindMessage); protected: StopBindMessage() : MessageBase() { this->m_SendMessageType = "STP_BIND"; }; ~StopBindMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// A class for the RTS_BIND message type. The RTS_BIND message has to be returned /// to acknowledge STT_BIND and STP_BIND. class IGTLCommon_EXPORT RTSBindMessage: public MessageBase { public: typedef RTSBindMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; // Status type enum { STATUS_SUCCESS = 0, STATUS_ERROR = 1 }; igtlTypeMacro(igtl::RTSBindMessage, igtl::MessageBase); igtlNewMacro(igtl::RTSBindMessage); /// Sets the status for the start/stop request. 'status' must be either RTSBindMessage::STATUS_SUCCESS or RTSBindMessage::STATUS_ERROR. void SetStatus(igtlUint8 status){ this->m_Status = status; } /// Gets the status for the start/stop request. 'status' must be either RTSBindMessage::STATUS_SUCCESS or RTSBindMessage::STATUS_ERROR. igtlUint8 GetStatus() { return this->m_Status; }; protected: RTSBindMessage() : MessageBase(), m_Status(0) { this->m_SendMessageType = "RTS_BIND"; }; ~RTSBindMessage() {}; /// Stores the status for the start/stop request. igtlUint8 m_Status; protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); }; } // namespace igtl #endif // _igtlBindMessage_hopenigtlink-3.0.0/Source/igtlCapabilityMessage.cxx000077500000000000000000000061331501024245700222750ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Module: Language: C++ Date: Version: Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlCapabilityMessage.h" #include #include #include #include #include #include // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include namespace igtl { CapabilityMessage::CapabilityMessage(): MessageBase() { this->m_SendMessageType = "CAPABILITY"; this->m_TypeNames.clear(); /// CapabilityMessage stay the same as previous versions, set m_Version = 1 /// to make the pack and unpack procedures the same as OpenIGTLink_PROTOCOL_VERSION 1 #if OpenIGTLink_HEADER_VERSION >= 2 m_HeaderVersion = IGTL_HEADER_VERSION_1; #endif } CapabilityMessage::~CapabilityMessage() { this->m_TypeNames.clear(); } void CapabilityMessage::SetTypes(std::vector types) { this->m_TypeNames.clear(); this->m_TypeNames = types; } int CapabilityMessage::SetType(int id, const char* type) { if (id < (int)this->m_TypeNames.size() && strlen(type) < IGTL_HEADER_TYPE_SIZE) { this->m_TypeNames[id] = type; return 1; } else { return 0; } } const char* CapabilityMessage::GetType(int id) { if (id < (int)this->m_TypeNames.size()) { return this->m_TypeNames[id].c_str(); } else { return ""; } } int CapabilityMessage::CalculateContentBufferSize() { return (sizeof(char) * IGTL_HEADER_TYPE_SIZE * this->m_TypeNames.size()); } int CapabilityMessage::PackContent() { AllocateBuffer(); if (this->m_TypeNames.size() == 0) { return 0; } igtl_capability_info info; int nTypes = this->m_TypeNames.size(); igtl_capability_init_info(&info); info.ntypes = nTypes; igtl_capability_alloc_info(&info, nTypes); for(int i = 0; i < nTypes; i++ ) { memcpy(info.typenames[i], this->m_TypeNames[i].c_str(), IGTL_HEADER_TYPE_SIZE); } igtl_capability_pack(&info, this->m_Content); return 1; } int CapabilityMessage::UnpackContent() { igtl_capability_info info; igtl_capability_init_info(&info); igtl_capability_unpack(this->m_Content, &info, this->CalculateReceiveContentSize()); int ntypes = info.ntypes; if(ntypes == 0) { return 0; } this->m_TypeNames.clear(); for(int i = 0; i < ntypes; i++) { std::string buf; if (igtl::Strnlen((const char*)info.typenames[i], IGTL_HEADER_TYPE_SIZE) < IGTL_HEADER_TYPE_SIZE) { buf.append((const char*)info.typenames[i]); } else { buf.append((const char*)info.typenames[i], IGTL_HEADER_TYPE_SIZE); } this->m_TypeNames.push_back(buf); } return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlCapabilityMessage.h000077500000000000000000000033401501024245700217170ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlCapabilityMessage_h #define __igtlCapabilityMessage_h #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #include #include namespace igtl { class IGTLCommon_EXPORT CapabilityMessage: public MessageBase { public: typedef CapabilityMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::CapabilityMessage, igtl::MessageBase); igtlNewMacro(igtl::CapabilityMessage); public: void SetTypes(std::vector types); int SetType(int id, const char* name); const char* GetType(int id); void SetNumberOfTypes(int n) { m_TypeNames.resize(n); } int GetNumberOfTypes() { return m_TypeNames.size(); } std::vector GetTypes() { return m_TypeNames; } protected: CapabilityMessage(); ~CapabilityMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); std::vector m_TypeNames; }; } // namespace igtl #endif // __igtlCapabilityMessage_hopenigtlink-3.0.0/Source/igtlClientSocket.cxx000066400000000000000000000047021501024245700212730ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkClientSocket.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "igtlClientSocket.h" namespace igtl { //----------------------------------------------------------------------------- ClientSocket::ClientSocket() { } //----------------------------------------------------------------------------- ClientSocket::~ClientSocket() { } //----------------------------------------------------------------------------- int ClientSocket::ConnectToServer(const char* hostName, int port, bool logErrorIfServerConnectionFailed /*= true*/) { if (this->m_SocketDescriptor != -1) { igtlWarningMacro("Client connection already exists. Closing it."); this->CloseSocket(this->m_SocketDescriptor); this->m_SocketDescriptor = -1; } this->m_SocketDescriptor = this->CreateSocket(); if (!this->m_SocketDescriptor) { igtlErrorMacro("Failed to create socket."); return -1; } if (this->Connect(this->m_SocketDescriptor, hostName, port) == -1) { this->CloseSocket(this->m_SocketDescriptor); this->m_SocketDescriptor = -1; if( logErrorIfServerConnectionFailed ) { igtlErrorMacro("Failed to connect to server " << hostName << ":" << port); } return -1; } return 0; } //----------------------------------------------------------------------------- void ClientSocket::PrintSelf(std::ostream& os) const { this->Superclass::PrintSelf(os); } } // end of igtl namespace openigtlink-3.0.0/Source/igtlClientSocket.h000066400000000000000000000040501501024245700207140ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkClientSocket.h,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // .NAME igtlClientSocket - Encapsulates a client socket. #ifndef __igtlClientSocket_h #define __igtlClientSocket_h #include "igtlSocket.h" #include "igtlWin32Header.h" namespace igtl { class ServerSocket; class IGTLCommon_EXPORT ClientSocket : public Socket { public: typedef ClientSocket Self; typedef Socket Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::ClientSocket, igtl::Socket) igtlNewMacro(igtl::ClientSocket); /// Connects to host. Returns 0 on success, -1 on error. int ConnectToServer(const char* hostname, int port, bool logErrorIfServerConnectionFailed = true); protected: ClientSocket(); ~ClientSocket(); void PrintSelf(std::ostream& os) const; friend class ServerSocket; private: ClientSocket(const ClientSocket&); // Not implemented. void operator=(const ClientSocket&); // Not implemented. }; } #endif openigtlink-3.0.0/Source/igtlColorTableMessage.cxx000066400000000000000000000051511501024245700222360ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlColorTableMessage.h" #include "igtl_header.h" #include "igtl_colortable.h" namespace igtl { ColorTableMessage::ColorTableMessage(): MessageBase() { indexType = INDEX_UINT8; mapType = MAP_UINT8; m_ColorTableHeader = NULL; m_ColorTable = NULL; m_SendMessageType = "COLORT"; /// ColorTableMessage stay the same as previous versions, set m_Version = 1 /// to make the pack and unpack procedures the same as OpenIGTLink_PROTOCOL_VERSION 1 #if OpenIGTLink_HEADER_VERSION >= 2 m_HeaderVersion = IGTL_HEADER_VERSION_1; #endif } ColorTableMessage::~ColorTableMessage() { } void ColorTableMessage::AllocateTable() { // Memory area to store image scalar is allocated with // message and image header, by using AllocatePack() implemented // in the parent class. AllocateBuffer(); m_ColorTableHeader = m_Content; m_ColorTable = &m_ColorTableHeader[IGTL_COLORTABLE_HEADER_SIZE]; } void* ColorTableMessage::GetTablePointer() { return (void*)m_ColorTable; } int ColorTableMessage::GetColorTableSize() { igtl_colortable_header header; header.indexType = this->indexType; header.mapType = this->mapType; return (int) igtl_colortable_get_table_size(&header); } int ColorTableMessage::CalculateContentBufferSize() { return GetColorTableSize() + IGTL_COLORTABLE_HEADER_SIZE; } int ColorTableMessage::PackContent() { igtl_colortable_header* colortable_header = (igtl_colortable_header*)m_ColorTableHeader; colortable_header->indexType = this->indexType; colortable_header->mapType = this->mapType; igtl_colortable_convert_byte_order(colortable_header, (void*)m_ColorTable); return 1; } int ColorTableMessage::UnpackContent() { this->m_ColorTableHeader = this->m_Content; this->m_ColorTable = &(this->m_Content[IGTL_COLORTABLE_HEADER_SIZE]); igtl_colortable_header* colortable_header = (igtl_colortable_header*)this->m_ColorTableHeader; igtl_colortable_convert_byte_order(colortable_header, (void*)this->m_ColorTable); this->indexType = colortable_header->indexType; this->mapType = colortable_header->mapType; return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlColorTableMessage.h000066400000000000000000000074121501024245700216650ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlColorTableMessage_h #define __igtlColorTableMessage_h #include "igtlObject.h" #include "igtlMacro.h" #include "igtlMath.h" #include "igtlMessageBase.h" namespace igtl { /// A class for the GET_COLORT message type. class IGTLCommon_EXPORT GetColorTableMessage: public MessageBase { public: typedef GetColorTableMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetColorTableMessage, igtl::MessageBase); igtlNewMacro(igtl::GetColorTableMessage); protected: GetColorTableMessage() : MessageBase() { this->m_SendMessageType = "GET_COLORT"; }; ~GetColorTableMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// A class for the COLORT message type. class IGTLCommon_EXPORT ColorTableMessage: public MessageBase { public: typedef ColorTableMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::ColorTableMessage, igtl::MessageBase) igtlNewMacro(igtl::ColorTableMessage); public: /// Index value types (UINT8 or UINT16) and map types (UINT8, UINT16 and RGB(UINT8x3)) enum { INDEX_UINT8 = 3, INDEX_UINT16 = 5, MAP_UINT8 = 3, MAP_UINT16 = 5, MAP_RGB = 19, }; public: /// Sets the index type for the color type void SetIndexType(int t) { indexType = t; }; /// Sets the index type for the color type to 8-bit unsigned integer. void SetIndexTypeToUint8() { indexType = INDEX_UINT8; }; /// Sets the index type for the color type to 16-bit unsigned integer. void SetIndexTypeToUint16() { indexType = INDEX_UINT16; }; /// Gets the index type. Returns either INDEX_UINT8 or INDEX_UINT16. int GetIndexType() { return indexType; }; /// Sets the scalar type of the map. void SetMapType(int t) { mapType = t; }; /// Sets the scalar type of the map to 8-bit unsigned integer. void SetMapTypeToUint8() { mapType = MAP_UINT8; }; /// Sets the scalar type of the map to 16-bit unsigned integer. void SetMapTypeToUint16() { mapType = MAP_UINT16; }; /// Gets the type of the map. int GetMapType() { return mapType; }; /// Gets the size of the color table. int GetColorTableSize(); /// Allocates a memory area for the color table. void AllocateTable(); /// Returns a pointer to the color table. void* GetTablePointer(); protected: ColorTableMessage(); ~ColorTableMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// A variable to store the index type. Either INDEX_UINT8 or INDEX_UINT16. int indexType; /// A variable to store the type of the map. Either MAP_UINT8, MAP_UINT16 or MAP_RGB. int mapType; /// A pointer to the header for the color table. unsigned char* m_ColorTableHeader; /// A pointer to the color table data. unsigned char* m_ColorTable; }; } // namespace igtl #endif // _igtlColorTableMessage_hopenigtlink-3.0.0/Source/igtlCommandMessage.cxx000066400000000000000000000151601501024245700215670ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlCommandMessage.h" #include "igtl_header.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include #define NUM_ENCODINGS 257 namespace { bool isEncodingValid(int encoding) { for( int i = 0; i < NUM_ENCODINGS-1; ++i ) { if( encoding == igtl::CommandMessage::validEncodings[i] ) { return true; } } return false; } } namespace igtl { const int CommandMessage::validEncodings[NUM_ENCODINGS] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,109,110,111,112,113,114,115,116,117,118,119,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2011,2044,2045,2010,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2250,2251,2252,2253,2254,2255,2256,2257,2258,2259,2260}; CommandMessage::CommandMessage() : MessageBase() , m_CommandId(0) , m_Encoding(3) { memset(m_CommandName, 0, IGTL_COMMAND_NAME_SIZE); this->m_HeaderVersion = IGTL_HEADER_VERSION_2; this->m_SendMessageType = "COMMAND"; this->m_Command.clear(); } CommandMessage::~CommandMessage() { } int CommandMessage::SetCommandId(igtlUint32 aId) { this->m_CommandId = aId; return 1; } int CommandMessage::SetCommandName(const char* aCommandName) { if (strlen(aCommandName) > IGTL_COMMAND_NAME_SIZE) /* If the length is beyond the range specified by the spec */ { return 0; } strcpy((char*)m_CommandName, aCommandName); return 1; } int CommandMessage::SetCommandName(const std::string& aCommandName) { return this->SetCommandName(aCommandName.c_str()); } int CommandMessage::SetCommandContent(const char* string) { if (strlen(string) > 0xFFFF) /* If the length is beyond the range of unsigned short */ { return 0; } this->m_Command = string; return (int) this->m_Command.length(); } int CommandMessage::SetCommandContent(const std::string & string) { if (string.length() > 0xFFFF) /* If the length is beyond the range of unsigned short */ { return 0; } this->m_Command = string; return (int) this->m_Command.length(); } int CommandMessage::SetContentEncoding(igtlUint16 enc) { if( !isEncodingValid(enc) ) { return 0; } this->m_Encoding = enc; return 1; } igtlUint32 CommandMessage::GetCommandId() const { return this->m_CommandId; } std::string CommandMessage::GetCommandName() const { return std::string((char*)this->m_CommandName); } std::string CommandMessage::GetCommandContent() const { return this->m_Command; } igtlUint32 CommandMessage::GetCommandContentLength() const { return this->m_Command.length(); } igtlUint16 CommandMessage::GetContentEncoding() const { return this->m_Encoding; } int CommandMessage::CalculateContentBufferSize() { // Body pack size is the sum of ENCODING, LENGTH and STRING fields return sizeof(igtl_command_header) + this->m_Command.length(); } int CommandMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_command_header * command_header; char * command; // Set pointers #if OpenIGTLink_HEADER_VERSION >= 2 command_header = (igtl_command_header*) this->m_Content; command = (char *) this->m_Content + sizeof(igtl_command_header); #else command_header = (igtl_command_header*) this->m_Body; command = (char *) this->m_Body + sizeof(igtl_command_header); #endif // Copy data command_header->encoding = static_cast(this->m_Encoding); command_header->length = static_cast(this->m_Command.length()); command_header->commandId = this->m_CommandId; memcpy(command_header->commandName, this->m_CommandName, IGTL_COMMAND_NAME_SIZE); strncpy(command, this->m_Command.c_str(), command_header->length); // Convert byte order from host to network igtl_command_convert_byte_order(command_header); return 1; } int CommandMessage::UnpackContent() { igtl_command_header * command_header; char * command; #if OpenIGTLink_HEADER_VERSION >= 2 command_header = (igtl_command_header*) this->m_Content; command = (char *) this->m_Content + sizeof(igtl_command_header); #else command_header = (igtl_command_header*) this->m_Body; command = (char *) this->m_Body + sizeof(igtl_command_header); #endif // Convert byte order from network to host igtl_command_convert_byte_order(command_header); // Copy data this->m_CommandId = command_header->commandId; memcpy(m_CommandName, command_header->commandName, IGTL_COMMAND_NAME_SIZE); this->m_Encoding = command_header->encoding; this->m_Command.clear(); this->m_Command.append(command, command_header->length); return 1; } int RTSCommandMessage::SetCommandErrorString(const char* anErrorString) { if (strlen(anErrorString) > IGTL_COMMAND_NAME_SIZE) /* If the length is beyond the range specified by the spec */ { return 0; } strcpy((char*)m_CommandName, anErrorString); return 1; } int RTSCommandMessage::SetCommandErrorString(const std::string& anErrorString) { if( anErrorString.length() > IGTL_COMMAND_NAME_SIZE ) { return 0; } strcpy((char*)m_CommandName, anErrorString.c_str()); return 1; } std::string RTSCommandMessage::GetCommandErrorString() const { return std::string((char*)this->m_CommandName); } RTSCommandMessage::RTSCommandMessage() : CommandMessage() { this->m_SendMessageType = std::string("RTS_COMMAND"); } RTSCommandMessage::~RTSCommandMessage() { } } // namespace igtl openigtlink-3.0.0/Source/igtlCommandMessage.h000066400000000000000000000071461501024245700212210ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlCommandMessage_h #define __igtlCommandMessage_h #include "igtlObject.h" #include "igtlMacro.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtl_command.h" namespace igtl { class IGTLCommon_EXPORT CommandMessage : public MessageBase { public: static const int validEncodings[257]; public: typedef CommandMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::CommandMessage, igtl::MessageBase) igtlNewMacro(igtl::CommandMessage); public: /// Sets the command ID int SetCommandId(igtlUint32 aId); /// Sets the command name int SetCommandName(const char* aCommandName); /// Sets the command name by std::string int SetCommandName(const std::string& aCommandName); /// Sets the string by character array. int SetCommandContent(const char* string); /// Sets the string by std::string. int SetCommandContent(const std::string & string); /// Sets the encoding of the string. For character encoding, please refer IANA Character Sets /// (http://www.iana.org/assignments/character-sets). /// US-ASCII (ANSI-X3.4-1968; MIBenum = 3) is strongly recommended. int SetContentEncoding(igtlUint16 enc); /// Gets the command ID igtlUint32 GetCommandId() const; /// Get the command name std::string GetCommandName() const; /// Gets the string. std::string GetCommandContent() const; /// Gets the length of the command content igtlUint32 GetCommandContentLength() const; /// Gets the encoding of the string. The returned value is defined in /// IANA Character Sets (http://www.iana.org/assignments/character-sets). igtlUint16 GetContentEncoding() const; protected: CommandMessage(); ~CommandMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// The unique ID of the command igtlUint32 m_CommandId; /// The name of the command igtlUint8 m_CommandName[IGTL_COMMAND_NAME_SIZE]; /// The encoding of the command string. /// The value is defined in IANA Character Sets (http://www.iana.org/assignments/character-sets). igtlUint16 m_Encoding; /// The command stored as an XML encoded string. std::string m_Command; }; class IGTLCommon_EXPORT RTSCommandMessage : public CommandMessage { public: typedef RTSCommandMessage Self; typedef CommandMessage Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::RTSCommandMessage, igtl::CommandMessage) igtlNewMacro(igtl::RTSCommandMessage); public: /// Sets the error string int SetCommandErrorString(const char* aCommandName); /// Sets the error string by std::string int SetCommandErrorString(const std::string& aCommandName); /// Get the error string std::string GetCommandErrorString() const; protected: RTSCommandMessage(); ~RTSCommandMessage(); }; } // namespace igtl #endif // _igtlCommandMessage_hopenigtlink-3.0.0/Source/igtlCommon.h000066400000000000000000000037001501024245700175560ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Open Image Guided Therapy Link Network Layer Module: $RCSfile: igtlCommon.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlCommon_h #define __igtlCommon_h #include #include namespace igtl { /// This function contains the extrinsic knowledge of the protocol version history /// so that programmers don't need to know which protocol version uses which header version static int IGTLProtocolToHeaderLookup(int igtlProtocolVersion) { if( igtlProtocolVersion == OpenIGTLink_PROTOCOL_VERSION_1 || igtlProtocolVersion == OpenIGTLink_PROTOCOL_VERSION_2 ) { return IGTL_HEADER_VERSION_1; } else if( igtlProtocolVersion == OpenIGTLink_PROTOCOL_VERSION_3) { return IGTL_HEADER_VERSION_2; } else { // TODO : which error mechanism to use for error reporting return IGTL_HEADER_VERSION_1; } } } #endif openigtlink-3.0.0/Source/igtlConditionVariable.cxx000066400000000000000000000125271501024245700223040ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkConditionVariable.cxx,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlConditionVariable.h" namespace igtl { ConditionVariable::ConditionVariable() { #ifdef OpenIGTLink_USE_PTHREADS pthread_mutex_init(&m_Mutex, NULL); pthread_cond_init(&m_ConditionVariable, NULL); #else #ifdef WIN32 m_NumberOfWaiters = 0; m_WasBroadcast = 0; m_Semaphore = CreateSemaphore(NULL, // no security 0, // initial value 0x7fffffff, // max count NULL); // unnamed InitializeCriticalSection( &m_NumberOfWaitersLock ); m_WaitersAreDone = CreateEvent( NULL, // no security FALSE, // auto-reset FALSE, // non-signaled initially NULL ); // unnamed #endif #endif } ConditionVariable::~ConditionVariable() { #ifdef OpenIGTLink_USE_PTHREADS pthread_mutex_destroy(&m_Mutex); pthread_cond_destroy(&m_ConditionVariable); #else #ifdef WIN32 CloseHandle( m_Semaphore ); CloseHandle( m_WaitersAreDone ); DeleteCriticalSection( &m_NumberOfWaitersLock ); #endif #endif } void ConditionVariable::Signal() { #ifdef OpenIGTLink_USE_PTHREADS pthread_cond_signal(&m_ConditionVariable); #else #ifdef WIN32 EnterCriticalSection( &m_NumberOfWaitersLock ); int haveWaiters = m_NumberOfWaiters > 0; LeaveCriticalSection( &m_NumberOfWaitersLock ); // if there were not any waiters, then this is a no-op if (haveWaiters) { ReleaseSemaphore(m_Semaphore, 1, 0); } #endif #endif } void ConditionVariable::Broadcast() { #ifdef OpenIGTLink_USE_PTHREADS pthread_cond_broadcast(&m_ConditionVariable); #else #ifdef WIN32 // This is needed to ensure that m_NumberOfWaiters and m_WasBroadcast are // consistent EnterCriticalSection( &m_NumberOfWaitersLock ); int haveWaiters = 0; if (m_NumberOfWaiters > 0) { // We are broadcasting, even if there is just one waiter... // Record that we are broadcasting, which helps optimize Wait() // for the non-broadcast case m_WasBroadcast = 1; haveWaiters = 1; } if (haveWaiters) { // Wake up all waiters atomically ReleaseSemaphore(m_Semaphore, m_NumberOfWaiters, 0); LeaveCriticalSection( &m_NumberOfWaitersLock ); // Wait for all the awakened threads to acquire the counting // semaphore WaitForSingleObject( m_WaitersAreDone, INFINITE ); // This assignment is ok, even without the m_NumberOfWaitersLock held // because no other waiter threads can wake up to access it. m_WasBroadcast = 0; } else { LeaveCriticalSection( &m_NumberOfWaitersLock ); } #endif #endif } void ConditionVariable::Wait(SimpleMutexLock *mutex) { #ifdef OpenIGTLink_USE_PTHREADS pthread_cond_wait(&m_ConditionVariable, &mutex->GetMutexLock() ); #else #ifdef WIN32 // Avoid race conditions EnterCriticalSection( &m_NumberOfWaitersLock ); m_NumberOfWaiters++; LeaveCriticalSection( &m_NumberOfWaitersLock ); // This call atomically releases the mutex and waits on the // semaphore until signaled SignalObjectAndWait( mutex->GetMutexLock(), m_Semaphore, INFINITE, FALSE ); // Reacquire lock to avoid race conditions EnterCriticalSection( &m_NumberOfWaitersLock ); // We're no longer waiting.... m_NumberOfWaiters--; // Check to see if we're the last waiter after the broadcast int lastWaiter = m_WasBroadcast && m_NumberOfWaiters == 0; LeaveCriticalSection( &m_NumberOfWaitersLock ); // If we're the last waiter thread during this particular broadcast // then let the other threads proceed if (lastWaiter) { // This call atomically signals the m_WaitersAreDone event and waits // until it can acquire the external mutex. This is required to // ensure fairness SignalObjectAndWait( m_WaitersAreDone, mutex->GetMutexLock(), INFINITE, FALSE); } else { // Always regain the external mutex since that's the guarentee we // give to our callers WaitForSingleObject( mutex->GetMutexLock(), INFINITE ); } #endif #endif } }//end of namespace igtl openigtlink-3.0.0/Source/igtlConditionVariable.h000066400000000000000000000122441501024245700217250ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkConditionVariable.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlConditionVariable_h #define __igtlConditionVariable_h #include "igtlConfigure.h" // This implementation uses a routine called SignalObjectAndWait() // which is only defined on WinNT 4.0 or greater systems. We need to // define this symbol in order to get the prototype for the // routine. This needs to be done before we load any system headers. #ifdef OpenIGTLink_USE_WIN32_THREADS #undef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #include "igtlWindows.h" #endif #include "igtlMutexLock.h" #include "igtlLightObject.h" namespace igtl { /** \class ConditionVariable * \brief A thread synchronization object used to suspend execution until some * condition on shared data is met. * * A thread calls Wait() to suspend its execution until the condition is * met. Each call to Signal() from an executing thread will then cause a single * waiting thread to be released. A call to Signal() means, "signal * that the condition is true." Broadcast() releases all threads waiting on * the condition variable. * * The IGTL ConditionVariable implementation is consistent with the standard * definition and use of condition variables in pthreads and other common * thread libraries. * * IMPORTANT: A condition variable always requires an associated SimpleMutexLock * object. The mutex object is used to avoid a dangerous race condition when * Wait() and Signal() are called simultaneously from two different * threads. * * On systems using pthreads, this implementation abstract the * standard calls to the pthread condition variable. On Win32 * systems, there is no system provided condition variable. This * class implements a condition variable using a critical section, a * semphore, an event and a number of counters. The implementation is * almost an extract translation of the implementation presented by * Douglas C Schmidt and Irfan Pyarali in "Strategies for Implementing * POSIX Condition Variables on Win32". This article can be found at * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html * */ class IGTLCommon_EXPORT ConditionVariable : public LightObject { public: /** Standard class typedefs. */ typedef ConditionVariable Self; typedef LightObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ igtlNewMacro(Self); /** Run-time type information (and related methods). */ igtlTypeMacro(ConditionVariable, LightObject); /** Suspend execution of this thread until the condition is signaled. The * argument is a SimpleMutex object that must be locked prior to calling * this method. */ void Wait(SimpleMutexLock * mutex); /** Signal that the condition is true and release one waiting thread */ void Signal(); /** Signal that the condition is true and release all waiting threads */ void Broadcast(); protected: ConditionVariable(); ~ConditionVariable(); private: ConditionVariable(const Self & other); const Self & operator=( const Self & ); #ifdef OpenIGTLink_USE_PTHREADS pthread_cond_t m_ConditionVariable; MutexType m_Mutex; #else int m_NumberOfWaiters; // number of waiting threads #ifdef WIN32 CRITICAL_SECTION m_NumberOfWaitersLock; // Serialize access to // m_NumberOfWaiters HANDLE m_Semaphore; // Semaphore to queue threads HANDLE m_WaitersAreDone; // Auto-reset event used by the // broadcast/signal thread to // wait for all the waiting // threads to wake up and // release the semaphore size_t m_WasBroadcast; // Keeps track of whether we // were broadcasting or signaling #endif #endif }; } // end namespace igtl #endif openigtlink-3.0.0/Source/igtlCreateObjectFunction.h000066400000000000000000000055711501024245700223760ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkCreateObjectFunction.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlCreateObjectFunction_h #define __igtlCreateObjectFunction_h #include "igtlObject.h" namespace igtl { /** \class CreateObjectFunctionBase * \brief Define API for object creation callback functions. * * \ingroup IGTLSystemObjects */ class CreateObjectFunctionBase: public Object { public: /** Standard typedefs. */ typedef CreateObjectFunctionBase Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Create an object and return a pointer to it as an * igtl::LightObject. */ virtual SmartPointer CreateObject() = 0; protected: CreateObjectFunctionBase() {} ~CreateObjectFunctionBase() {} private: CreateObjectFunctionBase(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; /** \class CreateObjectFunction * \brief CreateObjectFunction is used to create callback functions that * create IGTL Objects for use with the igtl::ObjectFactory. * * \ingroup IGTLSystemObjects */ template class CreateObjectFunction : public CreateObjectFunctionBase { public: /** Standard class typedefs. */ typedef CreateObjectFunction Self; typedef SmartPointer Pointer; /** Methods from igtl:LightObject. */ igtlFactorylessNewMacro(Self); LightObject::Pointer CreateObject() { return T::New().GetPointer(); } protected: CreateObjectFunction() {} ~CreateObjectFunction() {} private: CreateObjectFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace igtl #endif openigtlink-3.0.0/Source/igtlFastMutexLock.cxx000066400000000000000000000030141501024245700214300ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFastMutexLock.cxx,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlFastMutexLock.h" namespace igtl { void FastMutexLock::PrintSelf(std::ostream& os) const { Superclass::PrintSelf(os); } }//end namespace igtl openigtlink-3.0.0/Source/igtlFastMutexLock.h000066400000000000000000000070501501024245700210610ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFastMutexLock.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlFastMutexLock_h #define __igtlFastMutexLock_h #include "igtlObject.h" #include "igtlSimpleFastMutexLock.h" #include "igtlObjectFactory.h" namespace igtl { /** \class FastMutexLock * \brief Critical section locking class. * * FastMutexLock allows the locking of variables which are accessed * through different threads. This header file also defines * SimpleFastMutexLock which is not a subclass of Object. * The API is identical to that of MutexLock, and the behavior is * identical as well, except on Windows 9x/NT platforms. The only difference * on these platforms is that MutexLock is more flexible, in that * it works across processes as well as across threads, but also costs * more, in that it evokes a 600-cycle x86 ring transition. The * FastMutexLock provides a higher-performance equivalent (on * Windows) but won't work across processes. Since it is unclear how, * in igtl, an object at the igtl level can be shared across processes * in the first place, one should use FastMutexLock unless one has * a very good reason to use MutexLock. If higher-performance equivalents * for non-Windows platforms (Irix, SunOS, etc) are discovered, they * should replace the implementations in this class * * \ingroup OSSystemObjects */ class IGTLCommon_EXPORT FastMutexLock : public Object { public: /** Standard class typedefs. */ typedef FastMutexLock Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation. */ igtlNewMacro(Self); /** Run-time type information. */ igtlTypeMacro(FastMutexLock,Object); /** Lock the igtlFastMutexLock. */ void Lock(); /** Unlock the FastMutexLock. */ void Unlock(); protected: FastMutexLock() {} ~FastMutexLock() {} SimpleFastMutexLock m_SimpleFastMutexLock; void PrintSelf(std::ostream& os) const; private: FastMutexLock(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; inline void FastMutexLock::Lock( void ) { m_SimpleFastMutexLock.Lock(); } inline void FastMutexLock::Unlock( void ) { m_SimpleFastMutexLock.Unlock(); } }//end igtl namespace #endif openigtlink-3.0.0/Source/igtlImageMessage.cxx000066400000000000000000000260161501024245700212350ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlImageMessage.h" #include "igtl_header.h" #include "igtl_image.h" namespace igtl { ImageMessage::ImageMessage(): MessageBase() { for (int i = 0; i < 3; i ++) { dimensions[i] = 0; spacing[i] = 0.0; subDimensions[i] = 0; subOffset[i] = 0; } for (int i = 0; i < 4; i ++) { for (int j = 0; j < 4; j ++) { matrix[i][j] = (i == j ? 1.0 : 0.0); } } endian = ENDIAN_BIG; coordinate = COORDINATE_RAS; scalarType = TYPE_UINT8; m_ImageHeader = NULL; m_Image = NULL; numComponents = 1; m_SendMessageType = "IMAGE"; ScalarSizeTable[0] = 0; ScalarSizeTable[1] = 0; ScalarSizeTable[2] = sizeof(igtlInt8); // TYPE_INT8 ScalarSizeTable[3] = sizeof(igtlUint8); // TYPE_UINT8 ScalarSizeTable[4] = sizeof(igtlInt16); // TYPE_INT16 ScalarSizeTable[5] = sizeof(igtlUint16); // TYPE_UINT16 ScalarSizeTable[6] = sizeof(igtlInt32); // TYPE_INT32 ScalarSizeTable[7] = sizeof(igtlUint32); // TYPE_UINT32 ScalarSizeTable[8] = 0; // not defined ScalarSizeTable[9] = 0; // not defined ScalarSizeTable[10]= sizeof(igtlFloat32); // TYPE_FLOAT32 ScalarSizeTable[11]= sizeof(igtlFloat64); // TYPE_FLOAT64 } ImageMessage::~ImageMessage() { } void ImageMessage::SetDimensions(int s[3]) { dimensions[0] = s[0]; dimensions[1] = s[1]; dimensions[2] = s[2]; // initialize sub-volume subDimensions[0] = dimensions[0]; subDimensions[1] = dimensions[1]; subDimensions[2] = dimensions[2]; subOffset[0] = 0; subOffset[1] = 0; subOffset[2] = 0; } void ImageMessage::SetDimensions(int i, int j, int k) { dimensions[0] = i; dimensions[1] = j; dimensions[2] = k; // initialize sub-volume subDimensions[0] = dimensions[0]; subDimensions[1] = dimensions[1]; subDimensions[2] = dimensions[2]; subOffset[0] = 0; subOffset[1] = 0; subOffset[2] = 0; } void ImageMessage::GetDimensions(int s[3]) { s[0] = dimensions[0]; s[1] = dimensions[1]; s[2] = dimensions[2]; } void ImageMessage::GetDimensions(int &i, int &j, int &k) { i = dimensions[0]; j = dimensions[1]; k = dimensions[2]; } int ImageMessage::SetSubVolume(int dim[3], int off[3]) { // make sure that sub-volume fits in the dimensions if (off[0] + dim[0] <= dimensions[0] && off[1] + dim[1] <= dimensions[1] && off[2] + dim[2] <= dimensions[2]) { subDimensions[0] = dim[0]; subDimensions[1] = dim[1]; subDimensions[2] = dim[2]; subOffset[0] = off[0]; subOffset[1] = off[1]; subOffset[2] = off[2]; return 1; } else { return 0; } } int ImageMessage::SetSubVolume(int dimi, int dimj, int dimk, int offi, int offj, int offk) { // make sure that sub-volume fits in the dimensions if (offi + dimi <= dimensions[0] && offj + dimj <= dimensions[1] && offk + dimk <= dimensions[2]) { subDimensions[0] = dimi; subDimensions[1] = dimj; subDimensions[2] = dimk; subOffset[0] = offi; subOffset[1] = offj; subOffset[2] = offk; return 1; } else { return 0; } } void ImageMessage::GetSubVolume(int dim[3], int off[3]) { dim[0] = subDimensions[0]; dim[1] = subDimensions[1]; dim[2] = subDimensions[2]; off[0] = subOffset[0]; off[1] = subOffset[1]; off[2] = subOffset[2]; } void ImageMessage::GetSubVolume(int &dimi, int &dimj, int &dimk, int &offi, int &offj, int &offk) { dimi = subDimensions[0]; dimj = subDimensions[1]; dimk = subDimensions[2]; offi = subOffset[0]; offj = subOffset[1]; offk = subOffset[2]; } void ImageMessage::SetSpacing(float s[3]) { spacing[0] = s[0]; spacing[1] = s[1]; spacing[2] = s[2]; } void ImageMessage::SetSpacing(float si, float sj, float sk) { spacing[0] = si; spacing[1] = sj; spacing[2] = sk; } void ImageMessage::GetSpacing(float s[3]) { s[0] = spacing[0]; s[1] = spacing[1]; s[2] = spacing[2]; } void ImageMessage::GetSpacing(float &si, float &sj, float &sk) { si = spacing[0]; sj = spacing[1]; sk = spacing[2]; } void ImageMessage::SetOrigin(float p[3]) { matrix[0][3] = p[0]; matrix[1][3] = p[1]; matrix[2][3] = p[2]; } void ImageMessage::SetOrigin(float px, float py, float pz) { matrix[0][3] = px; matrix[1][3] = py; matrix[2][3] = pz; } void ImageMessage::GetOrigin(float p[3]) { p[0] = matrix[0][3]; p[1] = matrix[1][3]; p[2] = matrix[2][3]; } void ImageMessage::GetOrigin(float &px, float &py, float &pz) { px = matrix[0][3]; py = matrix[1][3]; pz = matrix[2][3]; } void ImageMessage::SetNormals(float o[3][3]) { matrix[0][0] = o[0][0]; matrix[0][1] = o[0][1]; matrix[0][2] = o[0][2]; matrix[1][0] = o[1][0]; matrix[1][1] = o[1][1]; matrix[1][2] = o[1][2]; matrix[2][0] = o[2][0]; matrix[2][1] = o[2][1]; matrix[2][2] = o[2][2]; } void ImageMessage::SetNormals(float t[3], float s[3], float n[3]) { matrix[0][0] = t[0]; matrix[1][0] = t[1]; matrix[2][0] = t[2]; matrix[0][1] = s[0]; matrix[1][1] = s[1]; matrix[2][1] = s[2]; matrix[0][2] = n[0]; matrix[1][2] = n[1]; matrix[2][2] = n[2]; } void ImageMessage::GetNormals(float o[3][3]) { o[0][0] = matrix[0][0]; o[0][1] = matrix[0][1]; o[0][2] = matrix[0][2]; o[1][0] = matrix[1][0]; o[1][1] = matrix[1][1]; o[1][2] = matrix[1][2]; o[2][0] = matrix[2][0]; o[2][1] = matrix[2][1]; o[2][2] = matrix[2][2]; } void ImageMessage::GetNormals(float t[3], float s[3], float n[3]) { t[0] = matrix[0][0]; t[1] = matrix[1][0]; t[2] = matrix[2][0]; s[0] = matrix[0][1]; s[1] = matrix[1][1]; s[2] = matrix[2][1]; n[0] = matrix[0][2]; n[1] = matrix[1][2]; n[2] = matrix[2][2]; } void ImageMessage::SetMatrix(Matrix4x4& mat) { matrix[0][0] = mat[0][0]; matrix[1][0] = mat[1][0]; matrix[2][0] = mat[2][0]; matrix[3][0] = mat[3][0]; matrix[0][1] = mat[0][1]; matrix[1][1] = mat[1][1]; matrix[2][1] = mat[2][1]; matrix[3][1] = mat[3][1]; matrix[0][2] = mat[0][2]; matrix[1][2] = mat[1][2]; matrix[2][2] = mat[2][2]; matrix[3][2] = mat[3][2]; matrix[0][3] = mat[0][3]; matrix[1][3] = mat[1][3]; matrix[2][3] = mat[2][3]; matrix[3][3] = mat[3][3]; } void ImageMessage::GetMatrix(Matrix4x4& mat) { mat[0][0] = matrix[0][0]; mat[1][0] = matrix[1][0]; mat[2][0] = matrix[2][0]; mat[3][0] = matrix[3][0]; mat[0][1] = matrix[0][1]; mat[1][1] = matrix[1][1]; mat[2][1] = matrix[2][1]; mat[3][1] = matrix[3][1]; mat[0][2] = matrix[0][2]; mat[1][2] = matrix[1][2]; mat[2][2] = matrix[2][2]; mat[3][2] = matrix[3][2]; mat[0][3] = matrix[0][3]; mat[1][3] = matrix[1][3]; mat[2][3] = matrix[2][3]; mat[3][3] = matrix[3][3]; } void ImageMessage::AllocateScalars() { // Memory area to store image scalar is allocated with // message and image header, by using AllocatePack() implemented // in the parent class. AllocateBuffer(); #if OpenIGTLink_HEADER_VERSION >= 2 m_ImageHeader = m_Content; m_Image = &m_ImageHeader[IGTL_IMAGE_HEADER_SIZE]; #else m_ImageHeader = m_Body; m_Image = &m_ImageHeader[IGTL_IMAGE_HEADER_SIZE]; #endif } void* ImageMessage::GetScalarPointer() { return (void*)m_Image; } int ImageMessage::CalculateContentBufferSize() { return GetSubVolumeImageSize() + IGTL_IMAGE_HEADER_SIZE; } int ImageMessage::PackContent() { AllocateBuffer(); igtl_image_header* image_header = (igtl_image_header*)m_ImageHeader; image_header->header_version = IGTL_IMAGE_HEADER_VERSION; image_header->num_components = this->numComponents; image_header->scalar_type = this->scalarType; image_header->endian = this->endian; image_header->coord = this->coordinate; image_header->size[0] = this->dimensions[0]; image_header->size[1] = this->dimensions[1]; image_header->size[2] = this->dimensions[2]; image_header->subvol_offset[0] = this->subOffset[0]; image_header->subvol_offset[1] = this->subOffset[1]; image_header->subvol_offset[2] = this->subOffset[2]; image_header->subvol_size[0] = this->subDimensions[0]; image_header->subvol_size[1] = this->subDimensions[1]; image_header->subvol_size[2] = this->subDimensions[2]; float origin[3]; float norm_i[3]; float norm_j[3]; float norm_k[3]; for (int i = 0; i < 3; i ++) { norm_i[i] = matrix[i][0]; norm_j[i] = matrix[i][1]; norm_k[i] = matrix[i][2]; origin[i] = matrix[i][3]; } igtl_image_set_matrix(this->spacing, origin, norm_i, norm_j, norm_k, image_header); igtl_image_convert_byte_order(image_header); return 1; } int ImageMessage::UnpackContent() { #if OpenIGTLink_HEADER_VERSION >= 2 m_ImageHeader = m_Content; #elif OpenIGTLink_PROTOCOL_VERSION <=2 m_ImageHeader = m_Body; #endif igtl_image_header* image_header = (igtl_image_header*)m_ImageHeader; igtl_image_convert_byte_order(image_header); if (image_header->header_version == IGTL_IMAGE_HEADER_VERSION) { // Image format version 1 this->scalarType = image_header->scalar_type; this->numComponents = image_header->num_components; this->endian = image_header->endian; this->coordinate = image_header->coord; this->dimensions[0] = image_header->size[0]; this->dimensions[1] = image_header->size[1]; this->dimensions[2] = image_header->size[2]; this->subOffset[0] = image_header->subvol_offset[0]; this->subOffset[1] = image_header->subvol_offset[1]; this->subOffset[2] = image_header->subvol_offset[2]; this->subDimensions[0] = image_header->subvol_size[0]; this->subDimensions[1] = image_header->subvol_size[1]; this->subDimensions[2] = image_header->subvol_size[2]; // Set image orientation float rspacing[3]; float origin[3]; float norm_i[3]; float norm_j[3]; float norm_k[3]; igtl_image_get_matrix(rspacing, origin, norm_i, norm_j, norm_k, image_header); for (int i = 0; i < 3; i ++) { this->spacing[i] = rspacing[i]; matrix[i][0] = norm_i[i]; matrix[i][1] = norm_j[i]; matrix[i][2] = norm_k[i]; matrix[i][3] = origin[i]; } matrix[3][0] = 0.0; matrix[3][1] = 0.0; matrix[3][2] = 0.0; matrix[3][3] = 1.0; m_Image = &m_ImageHeader[IGTL_IMAGE_HEADER_SIZE]; return 1; } else { // Incompatible version. return 0; } } void ImageMessage::SetNumComponents(int num) { if (num > 0 && num < 255) { numComponents = num; } } int ImageMessage::GetNumComponents() { return numComponents; } } // namespace igtl openigtlink-3.0.0/Source/igtlImageMessage.h000066400000000000000000000273071501024245700206660ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlImageMessage_h #define __igtlImageMessage_h #include "igtlObject.h" #include "igtlMacro.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtl_header.h" namespace igtl { // A class for the GEt_IMAGE message type. class IGTLCommon_EXPORT GetImageMessage: public HeaderOnlyMessageBase { public: typedef GetImageMessage Self; typedef HeaderOnlyMessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetImageMessage, igtl::HeaderOnlyMessageBase); igtlNewMacro(igtl::GetImageMessage); protected: GetImageMessage() : HeaderOnlyMessageBase() { this->m_SendMessageType = "GET_IMAGE";}; ~GetImageMessage() {}; }; // A class for the STP_IMAGE message type. class IGTLCommon_EXPORT StopImageMessage: public HeaderOnlyMessageBase { public: typedef StopImageMessage Self; typedef HeaderOnlyMessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StopImageMessage, igtl::HeaderOnlyMessageBase); igtlNewMacro(igtl::StopImageMessage); protected: StopImageMessage() : HeaderOnlyMessageBase() { this->m_SendMessageType = "STP_IMAGE";}; ~StopImageMessage() {}; }; /// A class for the IMAGE message type. /// The IMAGE format supports 2D or 3D images with metric information including /// image matrix size, voxel size, coordinate system type, position, and orientation. /// The body section of the IMAGE data consists of two parts: image header to transfer /// the metric information and image body to transfer the array of pixel or voxel values. /// The data type of pixel or voxel can be either scalar or vector, and numerical values /// can be 8-, 16-, 32-bit integer, or 32- or 64-bit floating point. The pixel values /// can be either big-endian or little-endian, since the sender software can specify /// the byte order in the image header. The format also supports "partial image transfer", /// in which a region of the image is transferred instead of the whole image. This mechanism /// is suitable for real-time applications, in which images are updated region-by-region. /// The sub-volume must be box-shaped and defined by 6 parameters consisting of the indices /// for the corner voxel of the sub-volume and matrix size of the sub-volume. class IGTLCommon_EXPORT ImageMessage: public MessageBase { public: typedef ImageMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::ImageMessage, igtl::MessageBase) igtlNewMacro(igtl::ImageMessage); public: /// Coordinate sysmtem. Either left-posterior-superior (LPS) or right-anterior-superior (RAS). enum { COORDINATE_RAS=1, COORDINATE_LPS=2 }; /// Endian used in the bite array for the image data. enum { ENDIAN_BIG=1, ENDIAN_LITTLE=2 }; /// Pixel data type either scalar or vector. enum { DTYPE_SCALAR = 1, DTYPE_VECTOR = 3 }; /// Pixel data type. enum { TYPE_INT8 = 2, TYPE_UINT8 = 3, TYPE_INT16 = 4, TYPE_UINT16 = 5, TYPE_INT32 = 6, TYPE_UINT32 = 7, TYPE_FLOAT32 = 10, TYPE_FLOAT64 = 11 }; public: /// Sets image dimensions by an array of the numbers of pixels in i, j and k directions. /// SetDimensions() should be called prior to SetSubVolume(), since SetDimensions() /// sets subvolume parameters automatically assuming that subvolume = entire volume. void SetDimensions(int s[3]); /// Sets image dimensions by the numbers of pixels in i, j and k directions. /// SetDimensions() should be called prior to SetSubVolume(), since SetDimensions() /// sets subvolume parameters automatically assuming that subvolume = entire volume. void SetDimensions(int i, int j, int k); /// Gets image dimensions as an array of the numbers of pixels in i, j and k directions. void GetDimensions(int s[3]); /// Gets image dimensions as the numbers of pixels in i, j and k directions. void GetDimensions(int &i, int &j, int &k); /// Sets sub-volume dimensions and offset by arrays of the dimensions and the offset. /// SetSubVolume() should be called after calling SetDiemensions(), since SetDimensions() /// reset the subvolume parameters automatically. Returns non-zero value if the subvolume /// is successfully specified. Returns zero, if invalid subvolume is specified. int SetSubVolume(int dim[3], int off[3]); /// Sets sub-volume dimensions and offset by the dimensions and the offset in i, j and k /// directions. SetSubVolume() should be called after calling SetDiemensions(), /// since SetDimensions() reset the subvolume parameters automatically. /// Returns non-zero value if the subvolume is successfully specified. /// Returns zero, if invalid subvolume is specified. int SetSubVolume(int dimi, int dimj, int dimk, int offi, int offj, int offk); /// Gets sub-volume dimensions and offset using arrays of the dimensions and the offset. void GetSubVolume(int dim[3], int off[3]); /// Gets sub-volume dimensions and offset by the dimensions and the offset in i, j and k /// directions. void GetSubVolume(int &dimi, int &dimj, int &dimk, int &offi, int &offj, int &offk); /// Sets spacings by an array of spacing values in i, j and k directions. void SetSpacing(float s[3]); /// Sets spacings by spacing values in i, j and k directions. void SetSpacing(float si, float sj, float sk); /// Gets spacings using an array of spacing values in i, j and k directions. void GetSpacing(float s[3]); /// Gets spacings using spacing values in i, j and k directions. void GetSpacing(float &si, float &sj, float &sk); /// Sets the coordinates of the origin by an array of positions along the first (R or L), /// second (A or P) and the third (S) axes. void SetOrigin(float p[3]); /// Sets the coordinates of the origin by positions along the first (R or L), second (A or P) /// and the third (S) axes. void SetOrigin(float px, float py, float pz); /// Gets the coordinates of the origin using an array of positions along the first (R or L), /// second (A or P) and the third (S) axes. void GetOrigin(float p[3]); /// Gets the coordinates of the origin by positions along the first (R or L), second (A or P) /// and the third (S) axes. void GetOrigin(float &px, float &py, float &pz); /// Sets the orientation of the image by an array of the normal vectors for the i, j /// and k indeces. void SetNormals(float o[3][3]); /// Sets the orientation of the image by the normal vectors for the i, j and k indeces. void SetNormals(float t[3], float s[3], float n[3]); /// Gets the orientation of the image using an array of the normal vectors for the i, j /// and k indeces. void GetNormals(float o[3][3]); /// Gets the orientation of the image using the normal vectors for the i, j and k indeces. void GetNormals(float t[3], float s[3], float n[3]); /// Sets the number of components for each voxel. void SetNumComponents(int num); /// Gets the number of components for each voxel. int GetNumComponents(); /// Sets the origin/orientation matrix. void SetMatrix(Matrix4x4& mat); /// Gets the origin/orientation matrix. void GetMatrix(Matrix4x4& mat); /// Sets the image scalar type. void SetScalarType(int t) { scalarType = t; }; /// Sets the image scalar type to 8-bit integer. void SetScalarTypeToInt8() { scalarType = TYPE_INT8; }; /// Sets the image scalar type to unsigned 8-bit integer. void SetScalarTypeToUint8() { scalarType = TYPE_UINT8; }; /// Sets the image scalar type to 16-bit integer. void SetScalarTypeToInt16() { scalarType = TYPE_INT16; }; /// Sets the image scalar type to unsigned 16-bit integer. void SetScalarTypeToUint16() { scalarType = TYPE_UINT16; }; /// Sets the image scalar type to 32-bit integer. void SetScalarTypeToInt32() { scalarType = TYPE_INT32; }; /// Sets the image scalar type to unsigned 32-bit integer. void SetScalarTypeToUint32() { scalarType = TYPE_UINT32; }; /// Gets the image scalar type. int GetScalarType() { return scalarType; }; /// Gets the size of the scalar type used in the current image data. /// (e.g. 1 byte for 8-bit integer) int GetScalarSize() { return ScalarSizeTable[scalarType]; }; /// Gets the size of the specified scalar type. (e.g. 1 byte for 8-bit integer) int GetScalarSize(int type) { return ScalarSizeTable[type]; }; /// Sets the Endianess of the image scalars. (default is ENDIAN_BIG) void SetEndian(int e) { endian = e; }; /// Gets the Endianess of the image scalars. int GetEndian() { return endian; }; /// Gets the size (length) of the byte array for the image data. /// The size is defined by dimensions[0]*dimensions[1]*dimensions[2]*scalarSize*numComponents. /// TODO: Should returned value be 64-bit integer? int GetImageSize() { return dimensions[0]*dimensions[1]*dimensions[2]*GetScalarSize()*numComponents; }; /// Returns coordinate system (COORDINATE_RAS or COORDINATE_LPS) int GetCoordinateSystem() { return coordinate;}; /// Sets coordinate system (COORDINATE_RAS or COORDINATE_LPS) void SetCoordinateSystem(int c) {coordinate = c;}; /// Gets the size (length) of the byte array for the subvolume image data. /// The size is defined by subDimensions[0]*subDimensions[1]*subDimensions[2]* /// scalarSize*numComponents. int GetSubVolumeImageSize() { return subDimensions[0]*subDimensions[1]*subDimensions[2]*GetScalarSize()*numComponents; }; /// Allocates a memory area for the scalar data based on the dimensions of the subvolume, /// the number of components, and the scalar type. void AllocateScalars(); /// Gets a pointer to the scalar data. void* GetScalarPointer(); protected: ImageMessage(); ~ImageMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// A vector containing the numbers of voxels in i, j and k directions. int dimensions[3]; /// A vector containing the spacings of the voxels in i, j and k directions. float spacing[3]; /// A vector containing the numbers of voxels of the subvolume in i, j and k directions. int subDimensions[3]; /// A vector containing the offset (number of voxels) of the first voxel of /// the subvolume from the first voxel of the original image. int subOffset[3]; /// A matrix representing the origin and the orientation of the image. /// The matrix is set to identity by default Matrix4x4 matrix; /// A variable for the Endian of the scalar values in the image. int endian; /// A variable for the number of components. int numComponents; /// A variable for the scalar type of the voxels. int scalarType; /// A variable for the scalar type of the voxels. int coordinate; /// A pointer to the serialized image header. unsigned char* m_ImageHeader; /// A pointer to the serialized image data. unsigned char* m_Image; /// A table to look up the size of a given scalar type. int ScalarSizeTable[12]; }; } // namespace igtl #endif // _igtlImageMessage_hopenigtlink-3.0.0/Source/igtlImageMessage2.cxx000066400000000000000000000413171501024245700213200ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlImageMessage2.h" #include #include "igtl_header.h" #include "igtl_image.h" namespace igtl { ImageMessage2::ImageMessage2(): MessageBase() { for (int i = 0; i < 3; i ++) { dimensions[i] = 0; spacing[i] = 0.0; subDimensions[i] = 0; subOffset[i] = 0; } for (int i = 0; i < 4; i ++) { for (int j = 0; j < 4; j ++) { matrix[i][j] = (i == j ? 1.0 : 0.0); } } endian = ENDIAN_BIG; coordinate = COORDINATE_RAS; scalarType = TYPE_UINT8; m_ImageHeader = NULL; m_Image = NULL; numComponents = 1; m_SendMessageType = "IMAGE"; ScalarSizeTable[0] = 0; ScalarSizeTable[1] = 0; ScalarSizeTable[2] = sizeof(igtlInt8); // TYPE_INT8 ScalarSizeTable[3] = sizeof(igtlUint8); // TYPE_UINT8 ScalarSizeTable[4] = sizeof(igtlInt16); // TYPE_INT16 ScalarSizeTable[5] = sizeof(igtlUint16); // TYPE_UINT16 ScalarSizeTable[6] = sizeof(igtlInt32); // TYPE_INT32 ScalarSizeTable[7] = sizeof(igtlUint32); // TYPE_UINT32 ScalarSizeTable[8] = 0; // not defined ScalarSizeTable[9] = 0; // not defined ScalarSizeTable[10]= sizeof(igtlFloat32); // TYPE_FLOAT32 ScalarSizeTable[11]= sizeof(igtlFloat64); // TYPE_FLOAT64 #ifdef FRAGMENTED_PACK this->m_Header = new unsigned char [IGTL_HEADER_SIZE]; this->m_Content = NULL; this->m_SelfAllocatedImageHeader = 0; this->m_ImageSize = 0; this->m_SelfAllocatedImage = 0; this->m_SinglePack = NULL; this->m_SinglePackSize = 0; // Size of the pack. Only header can be used after initialization this->m_MessageSize = IGTL_HEADER_SIZE; #endif } ImageMessage2::~ImageMessage2() { #ifdef FRAGMENTED_PACK //if (this->m_Header) // { // delete [] this->m_Header; // } if (this->m_ImageHeader && this->m_ImageHeader!= this->m_Content && this->m_SelfAllocatedImageHeader) { delete [] this->m_ImageHeader; } if (this->m_Image && this->m_SelfAllocatedImage) { delete [] this->m_Image; this->m_SelfAllocatedImage = 0; } #endif } void ImageMessage2::SetDimensions(int s[3]) { dimensions[0] = s[0]; dimensions[1] = s[1]; dimensions[2] = s[2]; // initialize sub-volume subDimensions[0] = dimensions[0]; subDimensions[1] = dimensions[1]; subDimensions[2] = dimensions[2]; subOffset[0] = 0; subOffset[1] = 0; subOffset[2] = 0; } void ImageMessage2::SetDimensions(int i, int j, int k) { dimensions[0] = i; dimensions[1] = j; dimensions[2] = k; // initialize sub-volume subDimensions[0] = dimensions[0]; subDimensions[1] = dimensions[1]; subDimensions[2] = dimensions[2]; subOffset[0] = 0; subOffset[1] = 0; subOffset[2] = 0; } void ImageMessage2::GetDimensions(int s[3]) { s[0] = dimensions[0]; s[1] = dimensions[1]; s[2] = dimensions[2]; } void ImageMessage2::GetDimensions(int &i, int &j, int &k) { i = dimensions[0]; j = dimensions[1]; k = dimensions[2]; } int ImageMessage2::SetSubVolume(int dim[3], int off[3]) { // make sure that sub-volume fits in the dimensions if (off[0] + dim[0] <= dimensions[0] && off[1] + dim[1] <= dimensions[1] && off[2] + dim[2] <= dimensions[2]) { subDimensions[0] = dim[0]; subDimensions[1] = dim[1]; subDimensions[2] = dim[2]; subOffset[0] = off[0]; subOffset[1] = off[1]; subOffset[2] = off[2]; return 1; } else { return 0; } } int ImageMessage2::SetSubVolume(int dimi, int dimj, int dimk, int offi, int offj, int offk) { // make sure that sub-volume fits in the dimensions if (offi + dimi <= dimensions[0] && offj + dimj <= dimensions[1] && offk + dimk <= dimensions[2]) { subDimensions[0] = dimi; subDimensions[1] = dimj; subDimensions[2] = dimk; subOffset[0] = offi; subOffset[1] = offj; subOffset[2] = offk; return 1; } else { return 0; } } void ImageMessage2::GetSubVolume(int dim[3], int off[3]) { dim[0] = subDimensions[0]; dim[1] = subDimensions[1]; dim[2] = subDimensions[2]; off[0] = subOffset[0]; off[1] = subOffset[1]; off[2] = subOffset[2]; } void ImageMessage2::GetSubVolume(int &dimi, int &dimj, int &dimk, int &offi, int &offj, int &offk) { dimi = subDimensions[0]; dimj = subDimensions[1]; dimk = subDimensions[2]; offi = subOffset[0]; offj = subOffset[1]; offk = subOffset[2]; } void ImageMessage2::SetSpacing(float s[3]) { spacing[0] = s[0]; spacing[1] = s[1]; spacing[2] = s[2]; } void ImageMessage2::SetSpacing(float si, float sj, float sk) { spacing[0] = si; spacing[1] = sj; spacing[2] = sk; } void ImageMessage2::GetSpacing(float s[3]) { s[0] = spacing[0]; s[1] = spacing[1]; s[2] = spacing[2]; } void ImageMessage2::GetSpacing(float &si, float &sj, float &sk) { si = spacing[0]; sj = spacing[1]; sk = spacing[2]; } void ImageMessage2::SetOrigin(float p[3]) { matrix[0][3] = p[0]; matrix[1][3] = p[1]; matrix[2][3] = p[2]; } void ImageMessage2::SetOrigin(float px, float py, float pz) { matrix[0][3] = px; matrix[1][3] = py; matrix[2][3] = pz; } void ImageMessage2::GetOrigin(float p[3]) { p[0] = matrix[0][3]; p[1] = matrix[1][3]; p[2] = matrix[2][3]; } void ImageMessage2::GetOrigin(float &px, float &py, float &pz) { px = matrix[0][3]; py = matrix[1][3]; pz = matrix[2][3]; } void ImageMessage2::SetNormals(float o[3][3]) { matrix[0][0] = o[0][0]; matrix[0][1] = o[0][1]; matrix[0][2] = o[0][2]; matrix[1][0] = o[1][0]; matrix[1][1] = o[1][1]; matrix[1][2] = o[1][2]; matrix[2][0] = o[2][0]; matrix[2][1] = o[2][1]; matrix[2][2] = o[2][2]; } void ImageMessage2::SetNormals(float t[3], float s[3], float n[3]) { matrix[0][0] = t[0]; matrix[1][0] = t[1]; matrix[2][0] = t[2]; matrix[0][1] = s[0]; matrix[1][1] = s[1]; matrix[2][1] = s[2]; matrix[0][2] = n[0]; matrix[1][2] = n[1]; matrix[2][2] = n[2]; } void ImageMessage2::GetNormals(float o[3][3]) { o[0][0] = matrix[0][0]; o[0][1] = matrix[0][1]; o[0][2] = matrix[0][2]; o[1][0] = matrix[1][0]; o[1][1] = matrix[1][1]; o[1][2] = matrix[1][2]; o[2][0] = matrix[2][0]; o[2][1] = matrix[2][1]; o[2][2] = matrix[2][2]; } void ImageMessage2::GetNormals(float t[3], float s[3], float n[3]) { t[0] = matrix[0][0]; t[1] = matrix[1][0]; t[2] = matrix[2][0]; s[0] = matrix[0][1]; s[1] = matrix[1][1]; s[2] = matrix[2][1]; n[0] = matrix[0][2]; n[1] = matrix[1][2]; n[2] = matrix[2][2]; } void ImageMessage2::SetMatrix(Matrix4x4& mat) { matrix[0][0] = mat[0][0]; matrix[1][0] = mat[1][0]; matrix[2][0] = mat[2][0]; matrix[3][0] = mat[3][0]; matrix[0][1] = mat[0][1]; matrix[1][1] = mat[1][1]; matrix[2][1] = mat[2][1]; matrix[3][1] = mat[3][1]; matrix[0][2] = mat[0][2]; matrix[1][2] = mat[1][2]; matrix[2][2] = mat[2][2]; matrix[3][2] = mat[3][2]; matrix[0][3] = mat[0][3]; matrix[1][3] = mat[1][3]; matrix[2][3] = mat[2][3]; matrix[3][3] = mat[3][3]; } void ImageMessage2::GetMatrix(Matrix4x4& mat) { mat[0][0] = matrix[0][0]; mat[1][0] = matrix[1][0]; mat[2][0] = matrix[2][0]; mat[3][0] = matrix[3][0]; mat[0][1] = matrix[0][1]; mat[1][1] = matrix[1][1]; mat[2][1] = matrix[2][1]; mat[3][1] = matrix[3][1]; mat[0][2] = matrix[0][2]; mat[1][2] = matrix[1][2]; mat[2][2] = matrix[2][2]; mat[3][2] = matrix[3][2]; mat[0][3] = matrix[0][3]; mat[1][3] = matrix[1][3]; mat[2][3] = matrix[2][3]; mat[3][3] = matrix[3][3]; } void ImageMessage2::AllocateScalars() { // Memory area to store image scalar is allocated with // message and image header, by using AllocatePack() implemented // in the parent class. #ifdef FRAGMENTED_PACK MessageBase::AllocateBuffer(); if (!this->m_ImageHeader) { this->m_ImageHeader = new unsigned char [IGTL_IMAGE_HEADER_SIZE]; this->m_SelfAllocatedImageHeader = 1; } int s = GetSubVolumeImageSize(); if (this->m_SelfAllocatedImage && this->m_Image) { delete [] this->m_Image; } this->m_Image = new unsigned char [s]; this->m_SelfAllocatedImage = 1; this->m_ImageSize = s; this->m_MessageSize = IGTL_HEADER_SIZE + IGTL_IMAGE_HEADER_SIZE + s; #else AllocateBuffer(); this->m_ImageHeader = m_Content; this->m_Image = &m_ImageHeader[IGTL_IMAGE_HEADER_SIZE]; #endif } void* ImageMessage2::GetScalarPointer() { return (void*)m_Image; } #ifdef FRAGMENTED_PACK void ImageMessage2::SetScalarPointer(void * p) { if (this->m_SelfAllocatedImage && this->m_Image) { this->m_SelfAllocatedImage = 0; this->m_ImageSize = 0; delete [] this->m_Image; } this->m_Image = (unsigned char *) p; for (int i = 0;im_Content[i] = m_ImageHeader[i]; } for (int i = 0;im_Content[i+IGTL_IMAGE_HEADER_SIZE] = m_Image[i]; } } void* ImageMessage2::GetBufferPointer() { // This function is re-implemented for backward compatibility. // If fragmented pack is supported, this function may cause // memory copy that may considerably slows the program. // When the pack only contains header if (this->m_MessageSize == IGTL_HEADER_SIZE) { return this->m_Header; } // int vs = this->GetSubVolumeImageSize(); if (this->m_SinglePackSize < IGTL_HEADER_SIZE + IGTL_IMAGE_HEADER_SIZE + vs) { if (this->m_SinglePack) { delete [] this->m_SinglePack; } this->m_SinglePack = new unsigned char [IGTL_HEADER_SIZE + IGTL_IMAGE_HEADER_SIZE + vs]; this->m_SinglePackSize = IGTL_HEADER_SIZE + IGTL_IMAGE_HEADER_SIZE + vs; } if (this->m_SinglePack == NULL) { return NULL; } unsigned char * ptr = this->m_SinglePack; memcpy(ptr, this->m_Header, IGTL_HEADER_SIZE); ptr += IGTL_HEADER_SIZE; memcpy(ptr, this->m_ImageHeader, IGTL_IMAGE_HEADER_SIZE); ptr += IGTL_IMAGE_HEADER_SIZE; memcpy(ptr, this->m_Image, vs); return (void*) this->m_SinglePack; } void* ImageMessage2::GetPackFragmentPointer(int id) { if (id == 0) { return this->m_Header; } else if (id == 1) { return this->m_ImageHeader; } else if (id == 2) { return this->m_Image; } return NULL; } int ImageMessage2::GetPackFragmentSize(int id) { if (id == 0) { return IGTL_HEADER_SIZE; } else if (id == 1) { return IGTL_IMAGE_HEADER_SIZE; } else if (id == 2) { return GetSubVolumeImageSize(); } return 0; } #endif // FRAGMENTED_PACK int ImageMessage2::CalculateContentBufferSize() { // This function is called by: // MessageBase::Pack() // MessageBase::AllocatePack() return GetSubVolumeImageSize() + IGTL_IMAGE_HEADER_SIZE; } #ifdef FRAGMENTED_PACK int ImageMessage2::Pack() { PackContent(); m_IsBodyUnpacked = false; // pack header igtl_header* h = (igtl_header*) m_Header; igtl_uint64 crc = crc64(0, 0, 0LL); // initial crc h->header_version = IGTL_HEADER_VERSION_1; igtl_uint64 ts = m_TimeStampSec & 0xFFFFFFFF; ts = (ts << 32) | (m_TimeStampSecFraction & 0xFFFFFFFF); h->timestamp = ts; h->body_size = CalculateContentBufferSize(); // Note pack fragment #0 is the OpenIGTLink general header. for (int i = 1; i < this->GetNumberOfPackFragments(); i ++) { crc = crc64((unsigned char*)this->GetPackFragmentPointer(i), this->GetPackFragmentSize(i), crc); } h->crc = crc; strncpy(h->name, m_SendMessageType.c_str(), 12); strncpy(h->device_name, m_DeviceName.c_str(), 20); igtl_header_convert_byte_order(h); m_IsHeaderUnpacked = false; return 1; } #endif // FRAGMENTED_PACK int ImageMessage2::PackContent() { igtl_image_header* image_header = (igtl_image_header*)this->m_ImageHeader; image_header->header_version = IGTL_IMAGE_HEADER_VERSION; image_header->num_components = this->numComponents; image_header->scalar_type = this->scalarType; image_header->endian = this->endian; image_header->coord = this->coordinate; image_header->size[0] = this->dimensions[0]; image_header->size[1] = this->dimensions[1]; image_header->size[2] = this->dimensions[2]; image_header->subvol_offset[0] = this->subOffset[0]; image_header->subvol_offset[1] = this->subOffset[1]; image_header->subvol_offset[2] = this->subOffset[2]; image_header->subvol_size[0] = this->subDimensions[0]; image_header->subvol_size[1] = this->subDimensions[1]; image_header->subvol_size[2] = this->subDimensions[2]; float origin[3]; float norm_i[3]; float norm_j[3]; float norm_k[3]; for (int i = 0; i < 3; i ++) { norm_i[i] = matrix[i][0]; norm_j[i] = matrix[i][1]; norm_k[i] = matrix[i][2]; origin[i] = matrix[i][3]; } igtl_image_set_matrix(this->spacing, origin, norm_i, norm_j, norm_k, image_header); igtl_image_convert_byte_order(image_header); return 1; } int ImageMessage2::UnpackContent() { if (this->m_ImageHeader && this->m_SelfAllocatedImageHeader) { delete [] this->m_ImageHeader; this->m_SelfAllocatedImageHeader = 0; } if (this->m_Image && this->m_SelfAllocatedImage) { delete [] this->m_Image; this->m_SelfAllocatedImage = 0; } this->m_ImageHeader = this->m_Content; igtl_image_header* image_header = (igtl_image_header*)m_ImageHeader; igtl_image_convert_byte_order(image_header); if (image_header->header_version == IGTL_IMAGE_HEADER_VERSION) { // Image format version 1 this->scalarType = image_header->scalar_type; this->numComponents = image_header->num_components; this->endian = image_header->endian; this->coordinate = image_header->coord; this->dimensions[0] = image_header->size[0]; this->dimensions[1] = image_header->size[1]; this->dimensions[2] = image_header->size[2]; this->subOffset[0] = image_header->subvol_offset[0]; this->subOffset[1] = image_header->subvol_offset[1]; this->subOffset[2] = image_header->subvol_offset[2]; this->subDimensions[0] = image_header->subvol_size[0]; this->subDimensions[1] = image_header->subvol_size[1]; this->subDimensions[2] = image_header->subvol_size[2]; // Set image orientation float rspacing[3]; float origin[3]; float norm_i[3]; float norm_j[3]; float norm_k[3]; igtl_image_get_matrix(rspacing, origin, norm_i, norm_j, norm_k, image_header); for (int i = 0; i < 3; i ++) { this->spacing[i] = rspacing[i]; matrix[i][0] = norm_i[i]; matrix[i][1] = norm_j[i]; matrix[i][2] = norm_k[i]; matrix[i][3] = origin[i]; } matrix[3][0] = 0.0; matrix[3][1] = 0.0; matrix[3][2] = 0.0; matrix[3][3] = 1.0; this->m_Image = this->m_ImageHeader; this->m_Image += IGTL_IMAGE_HEADER_SIZE; return 1; } else { // Incompatible version. return 0; } } #ifdef FRAGMENTED_PACK void ImageMessage2::AllocateBuffer(int contentSize) { MessageBase::AllocateBuffer(contentSize); if (contentSize <= 0) { contentSize = 0; this->m_IsBodyUnpacked = false; } int s = IGTL_HEADER_SIZE + contentSize; m_IsHeaderUnpacked = false; m_IsBodyUnpacked = false; if (contentSize > 0) { if (this->m_ImageHeader && this->m_SelfAllocatedImageHeader) { delete [] this->m_ImageHeader; this->m_ImageHeader = NULL; this->m_SelfAllocatedImageHeader = 0; } if (this->m_Image && this->m_SelfAllocatedImage) { delete [] this->m_Image; this->m_Image = NULL; this->m_SelfAllocatedImage = 0; } if (this->m_Body) { if (this->m_MessageSize != s) { // If the pack area exists but needs to be reallocated // m_IsHeaderUnpacked status is not changed in this case. unsigned char * old = this->m_Body; this->m_Body = new unsigned char [contentSize]; memcpy(this->m_Body, old, contentSize); delete [] old; } } else { this->m_Body = new unsigned char [contentSize]; } this->m_MessageSize = s; } } #endif // FRAGMENTED_PACK void ImageMessage2::SetNumComponents(int num) { if (num > 0 && num < 255) { numComponents = num; } } int ImageMessage2::GetNumComponents() { return numComponents; } } // namespace igtl openigtlink-3.0.0/Source/igtlImageMessage2.h000066400000000000000000000344521501024245700207470ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlImageMessage2_h #define __igtlImageMessage2_h #include "igtlObject.h" //#include "igtlMacros.h" #include "igtlMacro.h" #include "igtlMath.h" #include "igtlMessageBase.h" #define FRAGMENTED_PACK namespace igtl { /// A class for the GET_IMAGE message type. The difference between the ImageMessage and /// ImageMessage2 classes is that the ImageMessage2 class supports fragmented pack. /// Fragmeted pack allows allocating memory for each segment independently. /// The version 1 library assumes that the memory area for entire message pack /// is allocated at once, causing extra memory copies in some applications. /// (For example, copying image from source into the pack memory) class IGTLCommon_EXPORT GetImageMessage2: public MessageBase { public: typedef GetImageMessage2 Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetImageMessage2, igtl::MessageBase); igtlNewMacro(igtl::GetImageMessage2); protected: GetImageMessage2() : MessageBase() { this->m_SendMessageType = "GET_IMAGE"; }; ~GetImageMessage2() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// A class for the IMAGE message type with support for fragmented packing. /// The IMAGE format supports 2D or 3D images with metric information including /// image matrix size, voxel size, coordinate system type, position, and orientation. /// The body section of the IMAGE data consists of two parts: image header to transfer /// the metric information and image body to transfer the array of pixel or voxel values. /// The data type of pixel or voxel can be either scalar or vector, and numerical values /// can be 8-, 16-, 32-bit integer, or 32- or 64-bit floating point. The pixel values /// can be either big-endian or little-endian, since the sender software can specify /// the byte order in the image header. The format also supports "partial image transfer", /// in which a region of the image is transferred instead of the whole image. This mechanism /// is suitable for real-time applications, in which images are updated region-by-region. /// The sub-volume must be box-shaped and defined by 6 parameters consisting of the indices /// for the corner voxel of the sub-volume and matrix size of the sub-volume. /// /// The difference between the ImageMessage and /// ImageMessage2 classes is that the ImageMessage2 class supports fragmented pack. /// Fragmeted pack allows allocating memory for each segment independently. /// The version 1 library assumes that the memory area for entire message pack /// is allocated at once, causing extra memory copies in some applications. /// (For example, copying image from source into the pack memory) class IGTLCommon_EXPORT ImageMessage2: public MessageBase { public: typedef ImageMessage2 Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::ImageMessage2, igtl::MessageBase) igtlNewMacro(igtl::ImageMessage2); public: /// Coordinate system. Either left-posterior-superior (LPS) or right-anterior-superior (RAS). enum { COORDINATE_RAS=1, COORDINATE_LPS=2 }; /// Endian used in the bite array for the image data. enum { ENDIAN_BIG=1, ENDIAN_LITTLE=2 }; /// Pixel data type either scalar or vector. enum { DTYPE_SCALAR = 1, DTYPE_VECTOR = 3 }; /// Pixel data type. enum { TYPE_INT8 = 2, TYPE_UINT8 = 3, TYPE_INT16 = 4, TYPE_UINT16 = 5, TYPE_INT32 = 6, TYPE_UINT32 = 7, TYPE_FLOAT32 = 10, TYPE_FLOAT64 = 11 }; public: /// Sets image dimensions by an array of the numbers of pixels in i, j and k directions. /// SetDimensions() should be called prior to SetSubVolume(), since SetDimensions() /// sets subvolume parameters automatically assuming that subvolume = entire volume. void SetDimensions(int s[3]); /// Sets image dimensions by the numbers of pixels in i, j and k directions. /// SetDimensions() should be called prior to SetSubVolume(), since SetDimensions() /// sets subvolume parameters automatically assuming that subvolume = entire volume. void SetDimensions(int i, int j, int k); /// Gets image dimensions as an array of the numbers of pixels in i, j and k directions. void GetDimensions(int s[3]); /// Gets image dimensions as the numbers of pixels in i, j and k directions. void GetDimensions(int &i, int &j, int &k); /// Sets sub-volume dimensions and offset by arrays of the dimensions and the offset. /// SetSubVolume() should be called after calling SetDiemensions(), since SetDimensions() /// reset the subvolume parameters automatically. Returns non-zero value if the subvolume /// is successfully specified. Returns zero, if invalid subvolume is specified. int SetSubVolume(int dim[3], int off[3]); /// Sets sub-volume dimensions and offset by the dimensions and the offset in i, j and k /// directions. SetSubVolume() should be called after calling SetDiemensions(), /// since SetDimensions() reset the subvolume parameters automatically. /// Returns non-zero value if the subvolume is successfully specified. /// Returns zero, if invalid subvolume is specified. int SetSubVolume(int dimi, int dimj, int dimk, int offi, int offj, int offk); /// Gets sub-volume dimensions and offset using arrays of the dimensions and the offset. void GetSubVolume(int dim[3], int off[3]); /// Gets sub-volume dimensions and offset by the dimensions and the offset in i, j and k /// directions. void GetSubVolume(int &dimi, int &dimj, int &dimk, int &offi, int &offj, int &offk); /// Sets spacings by an array of spacing values in i, j and k directions. void SetSpacing(float s[3]); /// Sets spacings by spacing values in i, j and k directions. void SetSpacing(float si, float sj, float sk); /// Gets spacings using an array of spacing values in i, j and k directions. void GetSpacing(float s[3]); /// Gets spacings using spacing values in i, j and k directions. void GetSpacing(float &si, float &sj, float &sk); /// Sets the coordinates of the origin by an array of positions along the first (R or L), /// second (A or P) and the third (S) axes. void SetOrigin(float p[3]); /// Sets the coordinates of the origin by positions along the first (R or L), second (A or P) /// and the third (S) axes. void SetOrigin(float px, float py, float pz); /// Gets the coordinates of the origin using an array of positions along the first (R or L), /// second (A or P) and the third (S) axes. void GetOrigin(float p[3]); /// Gets the coordinates of the origin by positions along the first (R or L), second (A or P) /// and the third (S) axes. void GetOrigin(float &px, float &py, float &pz); /// Sets the orientation of the image by an array of the normal vectors for the i, j /// and k indeces. void SetNormals(float o[3][3]); /// Sets the orientation of the image by the normal vectors for the i, j and k indeces. void SetNormals(float t[3], float s[3], float n[3]); /// Gets the orientation of the image using an array of the normal vectors for the i, j /// and k indeces. void GetNormals(float o[3][3]); /// Gets the orientation of the image using the normal vectors for the i, j and k indeces. void GetNormals(float t[3], float s[3], float n[3]); /// Sets the number of components for each voxel. void SetNumComponents(int num); /// Gets the number of components for each voxel. int GetNumComponents(); /// Sets the origin/orientation matrix. void SetMatrix(Matrix4x4& mat); /// Gets the origin/orientation matrix. void GetMatrix(Matrix4x4& mat); /// Sets the image scalar type. void SetScalarType(int t) { scalarType = t; }; /// Sets the image scalar type to 8-bit integer. void SetScalarTypeToInt8() { scalarType = TYPE_INT8; }; /// Sets the image scalar type to unsigned 8-bit integer. void SetScalarTypeToUint8() { scalarType = TYPE_UINT8; }; /// Sets the image scalar type to 16-bit integer. void SetScalarTypeToInt16() { scalarType = TYPE_INT16; }; /// Sets the image scalar type to unsigned 16-bit integer. void SetScalarTypeToUint16() { scalarType = TYPE_UINT16; }; /// Sets the image scalar type to 32-bit integer. void SetScalarTypeToInt32() { scalarType = TYPE_INT32; }; /// Sets the image scalar type to unsigned 32-bit integer. void SetScalarTypeToUint32() { scalarType = TYPE_UINT32; }; /// Gets the image scalar type. int GetScalarType() { return scalarType; }; /// Gets the size of the scalar type used in the current image data. /// (e.g. 1 byte for 8-bit integer) int GetScalarSize() { return ScalarSizeTable[scalarType]; }; /// Gets the size of the specified scalar type. (e.g. 1 byte for 8-bit integer) int GetScalarSize(int type) { return ScalarSizeTable[type]; }; /// Sets the Endianess of the image scalars. (default is ENDIAN_BIG) void SetEndian(int e) { endian = e; }; /// Gets the Endianess of the image scalars. int GetEndian() { return endian; }; /// Gets the size (length) of the byte array for the image data. /// The size is defined by dimensions[0]*dimensions[1]*dimensions[2]*scalarSize*numComponents. // TODO: Should returned value be 64-bit integer? int GetImageSize() { return dimensions[0]*dimensions[1]*dimensions[2]*GetScalarSize()*numComponents; }; /// Returns coordinate system (COORDINATE_RAS or COORDINATE_LPS) int GetCoordinateSystem() { return coordinate;}; /// Sets coordinate system (COORDINATE_RAS or COORDINATE_LPS) void SetCoordinateSystem(int c) {coordinate = c;}; /// Gets the size (length) of the byte array for the subvolume image data. /// The size is defined by subDimensions[0]*subDimensions[1]*subDimensions[2]* /// scalarSize*numComponents. int GetSubVolumeImageSize() { return subDimensions[0]*subDimensions[1]*subDimensions[2]*GetScalarSize()*numComponents; }; /// Allocates a memory area for the scalar data based on the dimensions of the subvolume, /// the number of components, and the scalar type. /// Note: If FragmentedPack is active, GetScalarPointer() causes extra memory allocation to /// create a single pack memroy degrading the performance. virtual void AllocateScalars(); /// Gets a pointer to the scalar data. virtual void* GetScalarPointer(); #ifdef FRAGMENTED_PACK /// Sets the pointer to the scalar data (for fragmented pack support). virtual void SetScalarPointer(void * p); /// Gets a pointer to the scalar data (for fragmented pack support). void* GetBufferPointer(); /// Gets the number of fragments for the packed (serialized) data. Returns 3 /// consisting of header, image header and image body. (for fragmented pack support) int GetNumberOfPackFragments() { return 3; /* header, image header and image body */ } /// Gets a pointer to the specified fragment of the packed data. (for fragmented pack support) void* GetPackFragmentPointer(int id); /// Gets the size of the specified fragment. (for fragmented pack support) int GetPackFragmentSize(int id); #endif // FRAGMENTED_PACK protected: ImageMessage2(); ~ImageMessage2(); protected: virtual int CalculateContentBufferSize(); #ifdef FRAGMENTED_PACK public: /// Pack() serializes the header and body based on the member variables. /// PackBody() must be implemented in the child class. (for fragmented pack support) virtual int Pack(); public: #endif //FRAGMENTED_PACK virtual int PackContent(); virtual int UnpackContent(); #ifdef FRAGMENTED_PACK /// Allocate memory specifying the body size /// (used when create a brank package to receive data) (for fragmented pack support) virtual void AllocateBuffer(int contentSize); #endif //FRAGMENTED_PACK /// A vector containing the numbers of voxels in i, j and k directions. int dimensions[3]; /// A vector containing the spacings of the voxels in i, j and k directions. float spacing[3]; /// A vector containing the numbers of voxels of the subvolume in i, j and k directions. int subDimensions[3]; /// A vector containing the offset (number of voxels) of the first voxel of /// the subvolume from the first voxel of the original image. int subOffset[3]; /// A matrix representing the origin and the orientation of the image. /// The matrix is set to identity by default Matrix4x4 matrix; /// A variable for the Endian of the scalar values in the image. int endian; /// A variable for the number of components. int numComponents; /// A variable for the scalar type of the voxels. int scalarType; /// A variable for the scalar type of the voxels. int coordinate; /// A pointer to the serialized image header. unsigned char* m_ImageHeader; /// A pointer to the serialized image data. unsigned char* m_Image; #ifdef FRAGMENTED_PACK /// A pointer to the serialized data (for backward compatibility with the conventional packing) unsigned char* m_SinglePack; /// A variable for the memory size of this->m_SinglePack (for backward compatibility with the /// conventional packing) int m_SinglePackSize; /// A variable for the memory size of this->m_Image (for backward compatibility with the /// conventional packing) int m_ImageSize; /// A flag for the fragmented image pack (allocated by this class). int m_SelfAllocatedImage; /// A flag for the fragmented image pack (allocated by this class). int m_SelfAllocatedImageHeader; #endif /// A table to look up the size of a given scalar type. int ScalarSizeTable[12]; }; } // namespace igtl #endif // _igtlImageMessage2_hopenigtlink-3.0.0/Source/igtlImageMetaMessage.cxx000066400000000000000000000166521501024245700220510ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlImageMetaMessage.h" #include "igtl_header.h" #include "igtl_imgmeta.h" #include "igtl_image.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include #include namespace igtl { //---------------------------------------------------------------------- // igtl::ImageMetaElement class ImageMetaElement::ImageMetaElement() : Object() { this->m_TimeStamp = 0; this->m_Size[0] = 0; this->m_Size[1] = 0; this->m_Size[2] = 0; this->m_ScalarType = 0; } ImageMetaElement::~ImageMetaElement() { } int ImageMetaElement::SetName(const char* name) { if (strlen(name) <= IGTL_IMGMETA_LEN_NAME) { this->m_Name = name; return 1; } else { return 0; } } int ImageMetaElement::SetDeviceName(const char* devname) { if (strlen(devname) <= IGTL_IMGMETA_LEN_DEVICE_NAME) { this->m_DeviceName = devname; return 1; } else { return 0; } } int ImageMetaElement::SetModality(const char* modality) { if (strlen(modality) <= IGTL_IMGMETA_LEN_MODALITY) { this->m_Modality = modality; return 1; } else { return 0; } } int ImageMetaElement::SetPatientName(const char* patname) { if (strlen(patname) <= IGTL_IMGMETA_LEN_PATIENT_NAME) { this->m_PatientName = patname; return 1; } else { return 0; } } int ImageMetaElement::SetPatientID(const char* patid) { if (strlen(patid) <= IGTL_IMGMETA_LEN_PATIENT_ID) { this->m_PatientID = patid; return 1; } else { return 0; } } void ImageMetaElement::SetTimeStamp(igtl::TimeStamp::Pointer& time) { this->m_TimeStamp = time; } void ImageMetaElement::GetTimeStamp(igtl::TimeStamp::Pointer& time) { time = this->m_TimeStamp; } void ImageMetaElement::SetSize(igtlUint16 size[3]) { this->m_Size[0] = size[0]; this->m_Size[1] = size[1]; this->m_Size[2] = size[2]; } void ImageMetaElement::SetSize(igtlUint16 si, igtlUint16 sj, igtlUint16 sk) { this->m_Size[0] = si; this->m_Size[1] = sj; this->m_Size[2] = sk; } void ImageMetaElement::GetSize(igtlUint16* size) { size[0] = this->m_Size[0]; size[1] = this->m_Size[1]; size[2] = this->m_Size[2]; } void ImageMetaElement::GetSize(igtlUint16& si, igtlUint16& sj, igtlUint16& sk) { si = this->m_Size[0]; sj = this->m_Size[1]; sk = this->m_Size[2]; } void ImageMetaElement::SetScalarType(igtlUint8 type) { if (type == IGTL_IMAGE_STYPE_TYPE_INT8 || type == IGTL_IMAGE_STYPE_TYPE_UINT8 || type == IGTL_IMAGE_STYPE_TYPE_INT16 || type == IGTL_IMAGE_STYPE_TYPE_UINT16 || type == IGTL_IMAGE_STYPE_TYPE_INT32 || type == IGTL_IMAGE_STYPE_TYPE_UINT32 || type == IGTL_IMAGE_STYPE_TYPE_FLOAT32 || type == IGTL_IMAGE_STYPE_TYPE_FLOAT64) { this->m_ScalarType = type; } else { this->m_ScalarType = 0; } } igtlUint8 ImageMetaElement::GetScalarType() { return this->m_ScalarType; } //---------------------------------------------------------------------- // igtl::ImageMetaMessage class ImageMetaMessage::ImageMetaMessage() { this->m_SendMessageType = "IMGMETA"; this->m_ImageMetaList.clear(); } ImageMetaMessage::~ImageMetaMessage() { } int ImageMetaMessage::AddImageMetaElement(ImageMetaElement::Pointer& elem) { this->m_ImageMetaList.push_back(elem); return this->m_ImageMetaList.size(); } void ImageMetaMessage::ClearImageMetaElement() { this->m_ImageMetaList.clear(); } int ImageMetaMessage::GetNumberOfImageMetaElement() { return this->m_ImageMetaList.size(); } void ImageMetaMessage::GetImageMetaElement(int index, ImageMetaElement::Pointer& elem) { if (index >= 0 && index < (int) this->m_ImageMetaList.size()) { elem = this->m_ImageMetaList[index]; } } int ImageMetaMessage::CalculateContentBufferSize() { // The body size sum of the header size and status message size. return IGTL_IMGMETA_ELEMENT_SIZE * this->m_ImageMetaList.size(); } int ImageMetaMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_imgmeta_element* element = (igtl_imgmeta_element*)this->m_Content; std::vector::iterator iter; for (iter = this->m_ImageMetaList.begin(); iter != this->m_ImageMetaList.end(); iter ++) { strncpy((char*)element->name, (*iter)->GetName(), IGTL_IMGMETA_LEN_NAME); strncpy((char*)element->device_name, (*iter)->GetDeviceName(), IGTL_IMGMETA_LEN_DEVICE_NAME); strncpy((char*)element->modality, (*iter)->GetModality(), IGTL_IMGMETA_LEN_MODALITY); strncpy((char*)element->patient_name, (*iter)->GetPatientName(), IGTL_IMGMETA_LEN_PATIENT_NAME); strncpy((char*)element->patient_id, (*iter)->GetPatientID(), IGTL_IMGMETA_LEN_PATIENT_ID); igtl::TimeStamp::Pointer ts; (*iter)->GetTimeStamp(ts); if (ts.IsNotNull()) { element->timestamp = ts->GetTimeStampUint64(); } else { element->timestamp = 0; } igtlUint16 size[3]; (*iter)->GetSize(size); element->size[0] = size[0]; element->size[1] = size[1]; element->size[2] = size[2]; element->scalar_type = (*iter)->GetScalarType(); element->reserved = 0; element ++; } igtl_imgmeta_convert_byte_order((igtl_imgmeta_element*)this->m_Content, this->m_ImageMetaList.size()); return 1; } int ImageMetaMessage::UnpackContent() { this->m_ImageMetaList.clear(); igtl_imgmeta_element* element = (igtl_imgmeta_element*) this->m_Content; int nElement = igtl_imgmeta_get_data_n(this->m_BodySizeToRead); igtl_imgmeta_convert_byte_order(element, nElement); char strbuf[128]; for (int i = 0; i < nElement; i ++) { ImageMetaElement::Pointer elemClass = ImageMetaElement::New(); // Add '\n' at the end of each string // (necessary for a case, where a string reaches the maximum length.) strbuf[IGTL_IMGMETA_LEN_NAME] = '\n'; strncpy(strbuf, (char*)element->name, IGTL_IMGMETA_LEN_NAME); elemClass->SetName((const char*)strbuf); strbuf[IGTL_IMGMETA_LEN_DEVICE_NAME] = '\n'; strncpy(strbuf, (char*)element->device_name, IGTL_IMGMETA_LEN_DEVICE_NAME); elemClass->SetDeviceName(strbuf); strbuf[IGTL_IMGMETA_LEN_MODALITY] = '\n'; strncpy(strbuf, (char*)element->modality, IGTL_IMGMETA_LEN_MODALITY); elemClass->SetModality(strbuf); strbuf[IGTL_IMGMETA_LEN_PATIENT_NAME] = '\n'; strncpy(strbuf, (char*)element->patient_name, IGTL_IMGMETA_LEN_PATIENT_NAME); elemClass->SetPatientName(strbuf); strbuf[IGTL_IMGMETA_LEN_PATIENT_ID] = '\n'; strncpy(strbuf, (char*)element->patient_id, IGTL_IMGMETA_LEN_PATIENT_ID); elemClass->SetPatientID(strbuf); TimeStamp::Pointer ts = TimeStamp::New(); ts->SetTime(element->timestamp); elemClass->SetTimeStamp(ts); elemClass->SetSize(element->size); elemClass->SetScalarType(element->scalar_type); this->m_ImageMetaList.push_back(elemClass); element ++; } return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlImageMetaMessage.h000066400000000000000000000146521501024245700214740ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlImageMetaMessage_h #define __igtlImageMetaMessage_h #include #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #include "igtlImageMessage.h" namespace igtl { /// A class to manage meta data of images. class IGTLCommon_EXPORT ImageMetaElement: public Object { public: typedef ImageMetaElement Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::ImageMetaElement, igtl::Object); igtlNewMacro(igtl::ImageMetaElement); public: /// Sets the image name/description. The string 'name' must not exceed 64 characters. int SetName(const char* name); /// Gets the image name/description. const char* GetName() { return this->m_Name.c_str(); }; /// Sets the device name (message name). The string 'devname' must not exceed 20 /// characters. int SetDeviceName(const char* devname); /// Gets the device name (message name). const char* GetDeviceName() { return this->m_DeviceName.c_str(); }; /// Sets the name of the image modality (e.g. CT, MRI). The string 'modality' must not /// exceed 32 characters. int SetModality(const char* modality); /// Gets the name of the image modality. const char* GetModality() { return this->m_Modality.c_str(); }; /// Sets the patient name. The string 'patname' must not exceed 64 characters. int SetPatientName(const char* patname); /// Gets the patient name. const char* GetPatientName() { return this->m_PatientName.c_str(); }; /// Sets the patient ID. The string 'patid' must not exceed 64 characters. int SetPatientID(const char* patid); /// Gets the patient ID. const char* GetPatientID() { return this->m_PatientID.c_str(); } /// Sets the scan time for the image. void SetTimeStamp(igtl::TimeStamp::Pointer& time); /// Gets the scan time for the image. void GetTimeStamp(igtl::TimeStamp::Pointer& time); /// Sets the size of the image by an array containing the numbers of voxels in i, j, and k /// directions. void SetSize(igtlUint16 size[3]); /// Sets the size of the image by the numbers of voxels in i, j, and k directions. void SetSize(igtlUint16 si, igtlUint16 sj, igtlUint16 sk); /// Gets the size of the image using an array containing the numbers of voxels in i, j, and k /// directions. void GetSize(igtlUint16* size); /// Gets the size of the image by the numbers of voxels in i, j, and k directions. void GetSize(igtlUint16& si, igtlUint16& sj, igtlUint16& sk); /// Sets the scalar type of the image void SetScalarType(igtlUint8 type); /// Gets the scalar type of the image. igtlUint8 GetScalarType(); protected: ImageMetaElement(); ~ImageMetaElement(); protected: /// name / description (<= 64 bytes) std::string m_Name; /// device name to query the IMAGE and COLORT std::string m_DeviceName; /// modality name (<= 32 bytes) std::string m_Modality; /// patient name (<= 64 bytes) std::string m_PatientName; /// patient ID (MRN etc.) (<= 64 bytes) std::string m_PatientID; /// scan time TimeStamp::Pointer m_TimeStamp; /// entire image volume size igtlUint16 m_Size[3]; /// scalar type. see scalar_type in IMAGE message igtlUint8 m_ScalarType; }; /// A class for the GET_IMGMETA message type. class IGTLCommon_EXPORT GetImageMetaMessage: public MessageBase { public: typedef GetImageMetaMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetImageMetaMessage, igtl::MessageBase); igtlNewMacro(igtl::GetImageMetaMessage); protected: GetImageMetaMessage() : MessageBase() { this->m_SendMessageType = "GET_IMGMETA"; }; ~GetImageMetaMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// The IMGMETA message is used to transfer image meta information which are not /// available in the IMAGE message type, such as patient name, medical record number, /// modality etc. An IMGMETA message can contain meta data for multiple images. /// This message type may be used to obtain a list of images available in /// the remote system, such as image database or commercial image-guided surgery (IGS) system. class IGTLCommon_EXPORT ImageMetaMessage: public MessageBase { public: typedef ImageMetaMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::ImageMetaMessage, igtl::MessageBase); igtlNewMacro(igtl::ImageMetaMessage); public: /// Adds an image meta element to the list. Returns the number of elements after /// adding the image meta element. int AddImageMetaElement(ImageMetaElement::Pointer& elem); /// Clears the all image meta elements in the list. void ClearImageMetaElement(); /// Gets the number of the image meta elements in the list. int GetNumberOfImageMetaElement(); /// Gets the image meta data specified by the index. void GetImageMetaElement(int index, ImageMetaElement::Pointer& elem); protected: ImageMetaMessage(); ~ImageMetaMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// A list of pointers to image meta data. std::vector m_ImageMetaList; }; } // namespace igtl #endif // _igtlImageMetaMessage_hopenigtlink-3.0.0/Source/igtlLabelMetaMessage.cxx000066400000000000000000000146231501024245700220420ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlLabelMetaMessage.h" #include "igtl_header.h" #include "igtl_imgmeta.h" #include "igtl_lbmeta.h" #include "igtl_image.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include #include namespace igtl { //---------------------------------------------------------------------- // igtl::LabelMetaElement class LabelMetaElement::LabelMetaElement() : Object() { this->m_Name = ""; this->m_DeviceName = ""; this->m_Label = 0; this->m_RGBA[0] = 0; this->m_RGBA[1] = 0; this->m_RGBA[2] = 0; this->m_RGBA[3] = 0; this->m_Size[0] = 0; this->m_Size[1] = 0; this->m_Size[2] = 0; this->m_Owner = ""; } LabelMetaElement::~LabelMetaElement() { } int LabelMetaElement::SetName(const char* name) { if (strlen(name) <= IGTL_LBMETA_LEN_NAME) { this->m_Name = name; return 1; } else { return 0; } } int LabelMetaElement::SetDeviceName(const char* devname) { if (strlen(devname) <= IGTL_LBMETA_LEN_DEVICE_NAME) { this->m_DeviceName = devname; return 1; } else { return 0; } } void LabelMetaElement::SetRGBA(igtlUint8 rgba[4]) { this->m_RGBA[0] = rgba[0]; this->m_RGBA[1] = rgba[1]; this->m_RGBA[2] = rgba[2]; this->m_RGBA[3] = rgba[3]; } void LabelMetaElement::SetRGBA(igtlUint8 r, igtlUint8 g, igtlUint8 b, igtlUint8 a) { this->m_RGBA[0] = r; this->m_RGBA[1] = g; this->m_RGBA[2] = b; this->m_RGBA[3] = a; } void LabelMetaElement::GetRGBA(igtlUint8* rgba) { rgba[0] = this->m_RGBA[0]; rgba[1] = this->m_RGBA[1]; rgba[2] = this->m_RGBA[2]; rgba[3] = this->m_RGBA[3]; } void LabelMetaElement::GetRGBA(igtlUint8& r, igtlUint8& g, igtlUint8& b, igtlUint8& a) { r = this->m_RGBA[0]; g = this->m_RGBA[1]; b = this->m_RGBA[2]; a = this->m_RGBA[3]; } void LabelMetaElement::SetSize(igtlUint16 size[3]) { this->m_Size[0] = size[0]; this->m_Size[1] = size[1]; this->m_Size[2] = size[2]; } void LabelMetaElement::SetSize(igtlUint16 si, igtlUint16 sj, igtlUint16 sk) { this->m_Size[0] = si; this->m_Size[1] = sj; this->m_Size[2] = sk; } void LabelMetaElement::GetSize(igtlUint16* size) { size[0] = this->m_Size[0]; size[1] = this->m_Size[1]; size[2] = this->m_Size[2]; } void LabelMetaElement::GetSize(igtlUint16& si, igtlUint16& sj, igtlUint16& sk) { si = this->m_Size[0]; sj = this->m_Size[1]; sk = this->m_Size[2]; } int LabelMetaElement::SetOwner(const char* owner) { if (strlen(owner) <= IGTL_LBMETA_LEN_OWNER) { this->m_Owner = owner; return 1; } else { return 0; } } //---------------------------------------------------------------------- // igtl::LabelMetaMessage class LabelMetaMessage::LabelMetaMessage() { this->m_SendMessageType = "LBMETA"; this->m_LabelMetaList.clear(); } LabelMetaMessage::~LabelMetaMessage() { } int LabelMetaMessage::AddLabelMetaElement(LabelMetaElement::Pointer& elem) { this->m_LabelMetaList.push_back(elem); return this->m_LabelMetaList.size(); } void LabelMetaMessage::ClearLabelMetaElement() { this->m_LabelMetaList.clear(); } int LabelMetaMessage::GetNumberOfLabelMetaElement() { return this->m_LabelMetaList.size(); } void LabelMetaMessage::GetLabelMetaElement(int index, LabelMetaElement::Pointer& elem) { if (index >= 0 && index < (int)this->m_LabelMetaList.size()) { elem = this->m_LabelMetaList[index]; } } int LabelMetaMessage::CalculateContentBufferSize() { // The body size sum of the header size and status message size. return IGTL_LBMETA_ELEMENT_SIZE * this->m_LabelMetaList.size(); } int LabelMetaMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_lbmeta_element* element; element = (igtl_lbmeta_element*)this->m_Content; std::vector::iterator iter; for (iter = this->m_LabelMetaList.begin(); iter != this->m_LabelMetaList.end(); iter ++) { strncpy((char*)element->name, (*iter)->GetName(), IGTL_LBMETA_LEN_NAME); strncpy((char*)element->device_name, (*iter)->GetDeviceName(), IGTL_LBMETA_LEN_DEVICE_NAME); element->label = (*iter)->GetLabel(); element->reserved = 0; igtlUint8 rgba[4]; (*iter)->GetRGBA(rgba); element->rgba[0] = rgba[0]; element->rgba[1] = rgba[1]; element->rgba[2] = rgba[2]; element->rgba[3] = rgba[3]; igtlUint16 size[3]; (*iter)->GetSize(size); element->size[0] = size[0]; element->size[1] = size[1]; element->size[2] = size[2]; strncpy((char*)element->owner, (*iter)->GetOwner(), IGTL_LBMETA_LEN_OWNER); element ++; } igtl_lbmeta_convert_byte_order((igtl_lbmeta_element*)this->m_Content, this->m_LabelMetaList.size()); return 1; } int LabelMetaMessage::UnpackContent() { this->m_LabelMetaList.clear(); igtl_lbmeta_element* element = (igtl_lbmeta_element*) this->m_Content; int nElement = igtl_lbmeta_get_data_n(this->m_BodySizeToRead); igtl_lbmeta_convert_byte_order(element, nElement); char strbuf[128]; for (int i = 0; i < nElement; i ++) { LabelMetaElement::Pointer elemClass = LabelMetaElement::New(); // Add '\n' at the end of each string // (neccesary for a case, where a string reaches the maximum length.) strbuf[IGTL_LBMETA_LEN_NAME] = '\n'; strncpy(strbuf, (char*)element->name, IGTL_LBMETA_LEN_NAME); elemClass->SetName((const char*)strbuf); strbuf[IGTL_LBMETA_LEN_DEVICE_NAME] = '\n'; strncpy(strbuf, (char*)element->device_name, IGTL_LBMETA_LEN_DEVICE_NAME); elemClass->SetDeviceName(strbuf); elemClass->SetLabel(element->label); elemClass->SetRGBA(element->rgba); elemClass->SetSize(element->size); strbuf[IGTL_LBMETA_LEN_OWNER] = '\n'; strncpy(strbuf, (char*)element->owner, IGTL_LBMETA_LEN_OWNER); elemClass->SetOwner(strbuf); this->m_LabelMetaList.push_back(elemClass); element ++; } return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlLabelMetaMessage.h000066400000000000000000000135501501024245700214650ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlLabelMetaMessage_h #define __igtlLabelMetaMessage_h #include #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #include "igtlImageMessage.h" namespace igtl { class IGTLCommon_EXPORT LabelMetaElement: public Object { public: typedef LabelMetaElement Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::LabelMetaElement, igtl::Object); igtlNewMacro(igtl::LabelMetaElement); public: /// Sets the image name/description. The string 'name' must not exceed 64 characters. int SetName(const char* name); /// Gets the image name/description. const char* GetName() { return this->m_Name.c_str(); }; /// Sets the device name (message name). The string 'devname' must not exceed 20 /// characters. int SetDeviceName(const char* devname); /// Gets the device name (message name). const char* GetDeviceName() { return this->m_DeviceName.c_str(); }; /// Sets the label of the structure. void SetLabel(igtlUint8 label) { this->m_Label = label; }; /// Gets the label of the structure. igtlUint8 GetLabel() { return this->m_Label; }; /// Sets the color of the structure by an array representing RGBA. void SetRGBA(igtlUint8 rgba[4]); /// Sets the color of the structure by R, G, B, and A values. void SetRGBA(igtlUint8 r, igtlUint8 g, igtlUint8 b, igtlUint8 a); /// Gets the color of the structure by an array representing RGBA. void GetRGBA(igtlUint8* rgba); /// Gets the color of the structure by R, G, B, and A values. void GetRGBA(igtlUint8& r, igtlUint8& g, igtlUint8& b, igtlUint8& a); /// Sets the size of the image by an array containing the numbers of voxels in i, j, and k /// directions. void SetSize(igtlUint16 size[3]); /// Sets the size of the image by the numbers of voxels in i, j, and k directions. void SetSize(igtlUint16 si, igtlUint16 sj, igtlUint16 sk); /// Gets the size of the image using an array containing the numbers of voxels in i, j, and k /// directions. void GetSize(igtlUint16* size); /// Gets the size of the image by the numbers of voxels in i, j, and k directions. void GetSize(igtlUint16& si, igtlUint16& sj, igtlUint16& sk); /// Sets the name of the image that owns this label map. int SetOwner(const char* owner); /// Gets the name of the image that owns this label map. const char* GetOwner() { return this->m_Owner.c_str(); }; protected: LabelMetaElement(); ~LabelMetaElement(); protected: /// Name / description (<= 64 bytes) std::string m_Name; /// Device name to query the IMAGE and COLORT std::string m_DeviceName; /// Label igtlUint8 m_Label; /// Color in RGBA. default: (0, 0, 0, 0) igtlUint8 m_RGBA[4]; /// entire image volume size igtlUint16 m_Size[3]; /// device name of the owner image. (can be empty) std::string m_Owner; }; /// A class for the GET_LBMETA message type. class IGTLCommon_EXPORT GetLabelMetaMessage: public MessageBase { public: typedef GetLabelMetaMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetLabelMetaMessage, igtl::MessageBase); igtlNewMacro(igtl::GetLabelMetaMessage); protected: GetLabelMetaMessage() : MessageBase() { this->m_SendMessageType = "GET_LBMETA"; }; ~GetLabelMetaMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// The LBMETA is used to transfer meta information for label maps, which are not available /// in the IMAGE message type. To retrieve voxel objects or a label map, GET_IMAGE / IMAGE /// can be used. But the client should be able to get a list of available structures. class IGTLCommon_EXPORT LabelMetaMessage: public MessageBase { public: typedef LabelMetaMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::LabelMetaMessage, igtl::MessageBase); igtlNewMacro(igtl::LabelMetaMessage); public: /// Adds an label meta element to the list. int AddLabelMetaElement(LabelMetaElement::Pointer& elem); /// Clears the all label meta elements in the list. void ClearLabelMetaElement(); /// Gets the number of the label meta elements in the list. int GetNumberOfLabelMetaElement(); /// Gets the label meta element specified by the index. void GetLabelMetaElement(int index, LabelMetaElement::Pointer& elem); protected: LabelMetaMessage(); ~LabelMetaMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); // A list of pointers to label meta data. std::vector m_LabelMetaList; }; } // namespace igtl #endif // _igtlLabelMetaMessage_hopenigtlink-3.0.0/Source/igtlLightObject.cxx000066400000000000000000000144111501024245700211000ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkLightObject.cxx,v $ Language: C++ Date: $Date: 2009-11-12 23:48:21 -0500 (Thu, 12 Nov 2009) $ Version: $Revision: 5332 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlLightObject.h" #include "igtlObjectFactory.h" #include "igtlFastMutexLock.h" #include #include #include // Better name demanging for gcc #if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) #define GCC_USEDEMANGLE #endif #ifdef GCC_USEDEMANGLE #include #include #endif namespace igtl { LightObject::Pointer LightObject::New() { Pointer smartPtr; LightObject *rawPtr = ::igtl::ObjectFactory::Create(); if(rawPtr == NULL) { rawPtr = new LightObject; } smartPtr = rawPtr; rawPtr->UnRegister(); return smartPtr; } LightObject::Pointer LightObject::CreateAnother() const { return LightObject::New(); } /** * Delete a igtl object. This method should always be used to delete an object * when the new operator was used to create it. Using the C++ delete method * will not work with reference counting. */ void LightObject ::Delete() { this->UnRegister(); } /** * Avoid DLL boundary problems. */ #ifdef _WIN32 void* LightObject ::operator new(size_t n) { return new char[n]; } void* LightObject ::operator new[](size_t n) { return new char[n]; } void LightObject ::operator delete(void* m) { delete [] (char*)m; } void LightObject ::operator delete[](void* m, size_t) { delete [] (char*)m; } #endif /** * This function will be common to all igtl objects. It just calls the * header/self/trailer virtual print methods, which can be overriden by * subclasses (any igtl object). */ void LightObject ::Print(std::ostream& os) const { this->PrintHeader(os); this->PrintSelf(os); this->PrintTrailer(os); } /** * This method is called when igtlExceptionMacro executes. It allows * the debugger to break on error. */ void LightObject ::BreakOnError() { ; } /** * Increase the reference count (mark as used by another object). */ void LightObject ::Register() const { m_ReferenceCountLock.Lock(); m_ReferenceCount++; m_ReferenceCountLock.Unlock(); } /** * Decrease the reference count (release by another object). */ void LightObject ::UnRegister() const { m_ReferenceCountLock.Lock(); int tmpReferenceCount = --m_ReferenceCount; m_ReferenceCountLock.Unlock(); // ReferenceCount in now unlocked. We may have a race condition // to delete the object. if ( tmpReferenceCount <= 0) { delete this; } } /** * Sets the reference count (use with care) */ void LightObject ::SetReferenceCount(int ref) { m_ReferenceCountLock.Lock(); m_ReferenceCount = ref; m_ReferenceCountLock.Unlock(); if ( ref <= 0) { delete this; } } LightObject ::~LightObject() { /** * warn user if reference counting is on and the object is being referenced * by another object. * a call to uncaught_exception is necessary here to avoid throwing an * exception if one has been thrown already. This is likely to * happen when a subclass constructor (say B) is throwing an exception: at * that point, the stack unwinds by calling all superclass destructors back * to this method (~LightObject): since the ref count is still 1, an * exception would be thrown again, causing the system to abort()! */ if(m_ReferenceCount > 0 && !std::uncaught_exception()) { // A general exception safety rule is that destructors should // never throw. Something is wrong with a program that reaches // this point anyway. Also this is the least-derived class so the // whole object has been destroyed by this point anyway. Just // issue a warning. // igtlExceptionMacro(<< "Trying to delete object with non-zero reference count."); igtlWarningMacro("Trying to delete object with non-zero reference count."); } } /** * Chaining method to print an object's instance variables, as well as * its superclasses. */ void LightObject ::PrintSelf(std::ostream& os) const { #ifdef GCC_USEDEMANGLE char const * mangledName = typeid(*this).name(); int status; char* unmangled = abi::__cxa_demangle(mangledName, 0, 0, &status); const char* indent = " "; os << indent << "RTTI typeinfo: "; if(status == 0) { os << unmangled; free(unmangled); } else { os << mangledName; } os << std::endl; #else char* indent = " "; os << indent << "RTTI typeinfo: " << typeid( *this ).name() << std::endl; #endif os << indent << "Reference Count: " << m_ReferenceCount << std::endl; } /** * Define a default print header for all objects. */ void LightObject ::PrintHeader(std::ostream& os) const { os << " " << this->GetNameOfClass() << " (" << this << ")\n"; } /** * Define a default print trailer for all objects. */ void LightObject ::PrintTrailer(std::ostream& igtlNotUsed(os)) const { } /** * This operator allows all subclasses of LightObject to be printed via <<. * It in turn invokes the Print method, which in turn will invoke the * PrintSelf method that all objects should define, if they have anything * interesting to print out. */ std::ostream& operator<<(std::ostream& os, const LightObject& o) { o.Print(os); return os; } } // end namespace igtl openigtlink-3.0.0/Source/igtlLightObject.h000066400000000000000000000115341501024245700205300ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkLightObject.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlLightObject_h #define __igtlLightObject_h #include "igtlSmartPointer.h" #include "igtlSimpleFastMutexLock.h" #include "igtlMacro.h" #include #include namespace igtl { /** \class LightObject * \brief Light weight base class for most igtl classes. * * LightObject is the highest level base class for most igtl objects. It * implements reference counting and the API for object printing. * It can be used as a lightweight base class in preference to Object. * (LightObject does not support callbacks or modified time as Object * does.) All IGTL objects should be a subclass of LightObject or Object * with few exceptions (due to performance concerns). * * \sa Object * \ingroup IGTLSystemObjects * \ingroup DataRepresentation */ class IGTLCommon_EXPORT LightObject { public: /** Standard clas typedefs. */ typedef LightObject Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ static Pointer New(); /** Create an object from an instance, potentially deferring to a * factory. This method allows you to create an instance of an * object that is exactly the same type as the referring object. * This is useful in cases where an object has been cast back to a * base class. */ virtual Pointer CreateAnother() const; /** Delete an igtl object. This method should always be used to delete an * object when the new operator was used to create it. Using the C * delete method will not work with reference counting. */ virtual void Delete(); /** Return the name of this class as a string. Used by the object factory * (implemented in New()) to instantiate objects of a named type. Also * used for debugging and other output information. */ virtual const char *GetNameOfClass() const {return "LightObject";} #ifdef _WIN32 /** Used to avoid dll boundary problems. */ void* operator new(size_t); void* operator new[](size_t); void operator delete(void*); void operator delete[](void*, size_t); #endif /** Cause the object to print itself out. */ void Print(std::ostream& os) const; /** This method is called when igtlExceptionMacro executes. It allows * the debugger to break on error. */ static void BreakOnError(); /** Increase the reference count (mark as used by another object). */ virtual void Register() const; /** Decrease the reference count (release by another object). */ virtual void UnRegister() const; /** Gets the reference count on this object. */ virtual int GetReferenceCount() const {return m_ReferenceCount;} /** Sets the reference count on this object. This is a dangerous * method, use it with care. */ virtual void SetReferenceCount(int); protected: LightObject():m_ReferenceCount(1) {} virtual ~LightObject(); /** Methods invoked by Print() to print information about the object * including superclasses. Typically not called by the user (use Print() * instead) but used in the hierarchical print process to combine the * output of several classes. */ virtual void PrintSelf(std::ostream& os) const; virtual void PrintHeader(std::ostream& os) const; virtual void PrintTrailer(std::ostream& os) const; /** Number of uses of this object by other objects. */ mutable volatile int m_ReferenceCount; /** Mutex lock to protect modification to the reference count */ mutable SimpleFastMutexLock m_ReferenceCountLock; private: LightObject(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace igtl #endif openigtlink-3.0.0/Source/igtlMacro.h000066400000000000000000001102321501024245700173660ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMacro.h,v $ Language: C++ Date: $Date: 2009-05-22 15:29:17 -0400 (Fri, 22 May 2009) $ Version: $Revision: 4248 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /** * igtlMacro.h defines standard system-wide macros, constants, and other * parameters. One of its most important functions is to define macros used * to interface to instance variables in a standard fashion. For example, * these macros manage modified time, debugging information, and provide a * standard interface to set and get instance variables. Macros are * available for built-in types; for string classe; vector arrays; * object pointers; and debug, warning, and error printout information. */ #ifndef __igtlMacro_h #define __igtlMacro_h #include "igtlWin32Header.h" //#include "igtlConfigure.h" #include // Determine type of string stream to use. #if !defined(CMAKE_NO_ANSI_STRING_STREAM) # include #elif !defined(CMAKE_NO_ANSI_STREAM_HEADERS) # include # define IGTL_NO_ANSI_STRING_STREAM #else # include # define IGTL_NO_ANSI_STRING_STREAM #endif /** \namespace igtl * \brief The "igtl" namespace contains all OpenIGTLink classes. There are several nested namespaces * within the igtl:: namespace. */ namespace igtl { } // end namespace igtl - this is here for documentation purposes /** A convenience macro marks variables as not being used by a method, * avoiding compile-time warnings. */ #define igtlNotUsed(x) /** Macro to initialize static constants. This is used frequently to replace * the use of enum's within a class. Some compilers do not allow an enum of * one class to be passed as template argument to another class. Other * uses of this macro as possible. * * This is based (verbatim) on the BOOST_STATIC_CONSTANT macro. The original * Boost documentation is below. * * BOOST_STATIC_CONSTANT workaround --------------------------------------- // * On compilers which don't allow in-class initialization of static integral * constant members, we must use enums as a workaround if we want the constants * to be available at compile-time. This macro gives us a convenient way to * declare such constants. */ #if defined(_MSC_VER) && (_MSC_VER <= 1300) # define IGTL_NO_INCLASS_MEMBER_INITIALIZATION #endif #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x540) # define IGTL_NO_INCLASS_MEMBER_INITIALIZATION #endif #if defined(__SVR4) && !defined(__SUNPRO_CC) # define IGTL_NO_INCLASS_MEMBER_INITIALIZATION #endif // A class template like this will not instantiate on GCC 2.95: // template struct A // { // static const int N = 1; // enum { S = sizeof(A::N) }; // }; // We need to use enum for static constants instead. #if defined(__GNUC__) # define IGTL_NO_SIZEOF_CONSTANT_LOOKUP #endif #if defined(_MSC_VER) && (_MSC_VER <= 1300) #define IGTL_NO_SELF_AS_TRAIT_IN_TEMPLATE_ARGUMENTS #endif #if defined(IGTL_NO_INCLASS_MEMBER_INITIALIZATION) || \ defined(IGTL_NO_SIZEOF_CONSTANT_LOOKUP) # define igtlStaticConstMacro(name,type,value) enum { name = value } #else # define igtlStaticConstMacro(name,type,value) static const type name = value #endif #ifdef IGTL_NO_SELF_AS_TRAIT_IN_TEMPLATE_ARGUMENTS # define igtlGetStaticConstMacro(name) name #else # define igtlGetStaticConstMacro(name) (Self::name) #endif /** Set an input. This defines the Set"name"Input() method */ #define igtlSetInputMacro(name, type, number) \ virtual void Set##name##Input(const type *_arg) \ { \ igtlDebugMacro("setting input " #name " to " << _arg); \ if (_arg != static_cast(this->ProcessObject::GetInput( number ))) \ { \ this->ProcessObject::SetNthInput( number, const_cast(_arg) ); \ } \ } \ virtual void SetInput##number(const type *_arg) \ { \ igtlDebugMacro("setting input " #number " to " << _arg); \ if (_arg != static_cast(this->ProcessObject::GetInput( number ))) \ { \ this->ProcessObject::SetNthInput( number, const_cast(_arg) ); \ } \ } /** Macro used to redefine a type from the superclass. */ #define igtlSuperclassTraitMacro(traitnameType) \ typedef typename Superclass::traitnameType traitnameType; /** Get an input. This defines the Get"name"Input() method */ #define igtlGetInputMacro(name, type, number) \ virtual const type * Get##name##Input() const \ { \ igtlDebugMacro("returning input " << #name " of " << static_cast(this->ProcessObject::GetInput( number )) ); \ return static_cast(this->ProcessObject::GetInput( number )); \ } \ virtual const type * GetInput##number() const \ { \ igtlDebugMacro("returning input " << #number " of " << static_cast(this->ProcessObject::GetInput( number )) ); \ return static_cast(this->ProcessObject::GetInput( number )); \ } /** Set a decorated input. This defines the Set"name"() method. * It invokes SetInputMacro() and GetInputMacro() for the decorated object */ #define igtlSetDecoratedInputMacro(name, type, number) \ igtlSetInputMacro(name, SimpleDataObjectDecorator, number); \ igtlGetInputMacro(name, SimpleDataObjectDecorator, number); \ virtual void Set##name(const type &_arg) \ { \ typedef SimpleDataObjectDecorator< type > DecoratorType; \ igtlDebugMacro("setting input " #name " to " << _arg); \ const DecoratorType * oldInput = \ static_cast< const DecoratorType * >( \ this->ProcessObject::GetInput(number) ); \ if( oldInput && oldInput->Get() == _arg ) \ { \ return; \ } \ typename DecoratorType::Pointer newInput = DecoratorType::New(); \ newInput->Set( _arg ); \ this->Set##name##Input( newInput ); \ } /** Set a decorated input that derives from igtl::Object, but not from * igtl::DataObject. This defines the Set"name"() method. It invokes * SetInputMacro() and GetInputMacro() for the decorated object */ #define igtlSetDecoratedObjectInputMacro(name, type, number) \ igtlSetInputMacro(name, DataObjectDecorator, number); \ igtlGetInputMacro(name, DataObjectDecorator, number); \ virtual void Set##name(const type *_arg) \ { \ typedef DataObjectDecorator< type > DecoratorType; \ igtlDebugMacro("setting input " #name " to " << _arg); \ const DecoratorType * oldInput = \ static_cast< const DecoratorType * >( \ this->ProcessObject::GetInput(number) ); \ if( oldInput && oldInput->Get() == _arg ) \ { \ return; \ } \ typename DecoratorType::Pointer newInput = DecoratorType::New(); \ newInput->Set( _arg ); \ this->Set##name##Input( newInput ); \ } /** Set built-in type. Creates member Set"name"() (e.g., SetVisibility()); */ #define igtlSetMacro(name,type) \ virtual void Set##name (const type _arg) \ { \ igtlDebugMacro("setting " #name " to " << _arg); \ if (this->m_##name != _arg) \ { \ this->m_##name = _arg; \ } \ } /** Get built-in type. Creates member Get"name"() (e.g., GetVisibility()); */ #define igtlGetMacro(name,type) \ virtual type Get##name () \ { \ igtlDebugMacro("returning " << #name " of " << this->m_##name ); \ return this->m_##name; \ } /** Get built-in type. Creates member Get"name"() (e.g., GetVisibility()); * This is the "const" form of the igtlGetMacro. It should be used unless * the member can be changed through the "Get" access routine. */ #define igtlGetConstMacro(name,type) \ virtual type Get##name () const \ { \ igtlDebugMacro("returning " << #name " of " << this->m_##name ); \ return this->m_##name; \ } /** Get built-in type. Creates member Get"name"() (e.g., GetVisibility()); * This is the "const" form of the igtlGetMacro. It should be used unless * the member can be changed through the "Get" access routine. * This versions returns a const reference to the variable. */ #define igtlGetConstReferenceMacro(name,type) \ virtual const type & Get##name () const \ { \ igtlDebugMacro("returning " << #name " of " << this->m_##name ); \ return this->m_##name; \ } /** Set built-in type. Creates member Set"name"() (e.g., SetVisibility()); * This should be use when the type is an enum. It is use to avoid warnings on * some compilers with non specified enum types passed to igtlDebugMacro.*/ #define igtlSetEnumMacro(name,type) \ virtual void Set##name (const type _arg) \ { \ igtlDebugMacro("setting " #name " to " << static_cast(_arg)); \ if (this->m_##name != _arg) \ { \ this->m_##name = _arg; \ } \ } /** Get built-in type. Creates member Get"name"() (e.g., GetVisibility()); * This should be use when the type is an enum. It is use to avoid warnings on * some compilers with non specified enum types passed to igtlDebugMacro.*/ #define igtlGetEnumMacro(name,type) \ virtual type Get##name () const \ { \ igtlDebugMacro("returning " << #name " of " << static_cast(this->m_##name) ); \ return this->m_##name; \ } /** Set character string. Creates member Set"name"() * (e.g., SetFilename(char *)). The macro assumes that * the class member (name) is declared a type std::string. */ #define igtlSetStringMacro(name) \ virtual void Set##name (const char* _arg) \ { \ if ( _arg && (_arg == this->m_##name) ) { return;} \ if (_arg) \ { \ this->m_##name = _arg;\ } \ else \ { \ this->m_##name = ""; \ } \ } \ virtual void Set##name (const std::string & _arg) \ { \ this->Set##name( _arg.c_str() ); \ } \ /** Get character string. Creates member Get"name"() * (e.g., SetFilename(char *)). The macro assumes that * the class member (name) is declared as a type std::string. */ #define igtlGetStringMacro(name) \ virtual const char* Get##name () const \ { \ return this->m_##name.c_str(); \ } /** Set built-in type where value is constrained between min/max limits. * Create member Set"name"() (e.q., SetRadius()). #defines are * convienience for clamping open-ended values. */ #define igtlSetClampMacro(name,type,min,max) \ virtual void Set##name (type _arg) \ { \ igtlDebugMacro("setting " << #name " to " << _arg ); \ if (this->m_##name != (_argmax?max:_arg))) \ { \ this->m_##name = (_argmax?max:_arg)); \ } \ } /** Set pointer to object; uses Object reference counting methodology. * Creates method Set"name"() (e.g., SetPoints()). Note that using * smart pointers requires using real pointers when setting input, * but returning smart pointers on output. */ #define igtlSetObjectMacro(name,type) \ virtual void Set##name (type* _arg) \ { \ igtlDebugMacro("setting " << #name " to " << _arg ); \ if (this->m_##name != _arg) \ { \ this->m_##name = _arg; \ } \ } /** Get a smart pointer to an object. Creates the member * Get"name"() (e.g., GetPoints()). */ #define igtlGetObjectMacro(name,type) \ virtual type * Get##name () \ { \ igtlDebugMacro("returning " #name " address " << this->m_##name ); \ return this->m_##name.GetPointer(); \ } /** Set const pointer to object; uses Object reference counting methodology. * Creates method Set"name"() (e.g., SetPoints()). Note that using * smart pointers requires using real pointers when setting input, * but returning smart pointers on output. */ #define igtlSetConstObjectMacro(name,type) \ virtual void Set##name (const type* _arg) \ { \ igtlDebugMacro("setting " << #name " to " << _arg ); \ if (this->m_##name != _arg) \ { \ this->m_##name = _arg; \ } \ } /** Get a smart const pointer to an object. Creates the member * Get"name"() (e.g., GetPoints()). */ #define igtlGetConstObjectMacro(name,type) \ virtual const type * Get##name () const \ { \ igtlDebugMacro("returning " #name " address " << this->m_##name ); \ return this->m_##name.GetPointer(); \ } /** Get a const reference to a smart pointer to an object. * Creates the member Get"name"() (e.g., GetPoints()). */ #define igtlGetConstReferenceObjectMacro(name,type) \ virtual const typename type::Pointer & Get##name () const \ { \ igtlDebugMacro("returning " #name " address " << this->m_##name ); \ return this->m_##name; \ } /** Create members "name"On() and "name"Off() (e.g., DebugOn() DebugOff()). * Set method must be defined to use this macro. */ #define igtlBooleanMacro(name) \ virtual void name##On () { this->Set##name(true);} \ virtual void name##Off () { this->Set##name(false);} /** General set vector macro creates a single method that copies specified * number of values into object. * Examples: void SetColor(c,3) */ #define igtlSetVectorMacro(name,type,count) \ virtual void Set##name(type data[]) \ { \ unsigned int i; \ for (i=0; im_##name[i] ) { break; }} \ if ( i < count ) \ { \ for (i=0; im_##name[i] = data[i]; }\ } \ } /** Get vector macro. Returns pointer to type (i.e., array of type). * This is for efficiency. */ #define igtlGetVectorMacro(name,type,count) \ virtual type *Get##name () const \ { \ return this->m_##name; \ } /** Define two object creation methods. The first method, New(), * creates an object from a class, potentially deferring to a factory. * The second method, CreateAnother(), creates an object from an * instance, potentially deferring to a factory. This second method * allows you to create an instance of an object that is exactly the * same type as the referring object. This is useful in cases where * an object has been cast back to a base class. * * These creation methods first try asking the object factory to create * an instance, and then default to the standard "new" operator if the * factory fails. * * These routines assigns the raw pointer to a smart pointer and then call * UnRegister() on the rawPtr to compensate for LightObject's constructor * initializing an object's reference count to 1 (needed for proper * initialization of process objects and data objects cycles). */ #define igtlNewMacro(x) \ static Pointer New(void) \ { \ Pointer smartPtr = ::igtl::ObjectFactory::Create(); \ if(smartPtr.GetPointer() == NULL) \ { \ smartPtr = new x; \ } \ smartPtr->UnRegister(); \ return smartPtr; \ } \ virtual ::igtl::LightObject::Pointer CreateAnother(void) const \ { \ return x::New().GetPointer(); \ } \ /** Define two object creation methods. The first method, New(), * creates an object from a class but does not defer to a factory. * The second method, CreateAnother(), creates an object from an * instance, again without deferring to a factory. This second method * allows you to create an instance of an object that is exactly the * same type as the referring object. This is useful in cases where * an object has been cast back to a base class. * * These creation methods first try asking the object factory to create * an instance, and then default to the standard "new" operator if the * factory fails. * * These routines assigns the raw pointer to a smart pointer and then call * UnRegister() on the rawPtr to compensate for LightObject's constructor * initializing an object's reference count to 1 (needed for proper * initialization of process objects and data objects cycles). */ #define igtlFactorylessNewMacro(x) \ static Pointer New(void) \ { \ Pointer smartPtr; \ x *rawPtr = new x; \ smartPtr = rawPtr; \ rawPtr->UnRegister(); \ return smartPtr; \ } \ virtual ::igtl::LightObject::Pointer CreateAnother(void) const \ { \ ::igtl::LightObject::Pointer smartPtr; \ smartPtr = x::New().GetPointer(); \ return smartPtr; \ } /** Macro used to add standard methods to all classes, mainly type * information. */ #define igtlTypeMacro(thisClass,superclass) \ virtual const char *GetNameOfClass() const \ {return #thisClass;} //namespace igtl //{ ///** // * The following is used to output debug, warning, and error messages. // * Use a global function which actually calls: // * OutputWindow::GetInstance()->DisplayText(); // * This is to avoid Object #include of OutputWindow // * while OutputWindow #includes Object. */ //extern IGTLCommon_EXPORT void OutputWindowDisplayText(const char*); //extern IGTLCommon_EXPORT void OutputWindowDisplayErrorText(const char*); //extern IGTLCommon_EXPORT void OutputWindowDisplayWarningText(const char*); //extern IGTLCommon_EXPORT void OutputWindowDisplayGenericOutputText(const char*); //extern IGTLCommon_EXPORT void OutputWindowDisplayDebugText(const char*); //} // end namespace igtl /** This macro is used to print debug (or other information). They are * also used to catch errors, etc. Example usage looks like: * igtlDebugMacro(<< "this is debug info" << this->SomeVariable); */ #if defined(IGTL_LEAN_AND_MEAN) || defined(__BORLANDC__) #define igtlDebugMacro(x) #else #define igtlDebugMacro(x) \ { if (this->GetDebug() /*&& ::igtl::Object::GetGlobalWarningDisplay()*/) \ { ::igtl::OStringStream igtlmsg; \ igtlmsg << "Debug: In " __FILE__ ", line " << __LINE__ << "\n" \ << this->GetNameOfClass() << " (" << this << "): " x \ << "\n\n"; \ std::cerr << igtlmsg.str(); /*::igtl::OutputWindowDisplayDebugText(igtlmsg.str().c_str());*/} \ } #endif /** This macro is used to print warning information (i.e., unusual circumstance * but not necessarily fatal.) Example usage looks like: * igtlWarningMacro(<< "this is warning info" << this->SomeVariable); */ #ifdef IGTL_LEAN_AND_MEAN #define igtlWarningMacro(x) #else #define igtlWarningMacro(x) \ { if ( 1/*::igtl::Object::GetGlobalWarningDisplay()*/) \ { ::igtl::OStringStream igtlmsg; \ igtlmsg << "WARNING: In " __FILE__ ", line " << __LINE__ << "\n" \ << this->GetNameOfClass() << " (" << this << "): " x \ << "\n\n"; \ std::cerr << igtlmsg.str(); /*::igtl::OutputWindowDisplayWarningText(igtlmsg.str().c_str());*/} \ } #endif namespace igtl { /** * igtl::OStringStream wrapper to hide differences between * std::ostringstream and the old ostrstream. Necessary for * portability. */ #if !defined(IGTL_NO_ANSI_STRING_STREAM) class OStringStream: public std::ostringstream { public: OStringStream() {} private: OStringStream(const OStringStream&); void operator=(const OStringStream&); }; #else namespace OStringStreamDetail { class Cleanup { public: Cleanup(std::ostrstream& ostr): m_OStrStream(ostr) {} ~Cleanup() { m_OStrStream.rdbuf()->freeze(0); } static void IgnoreUnusedVariable(const Cleanup&) {} protected: std::ostrstream& m_OStrStream; }; }//namespace OStringStreamDetail class OStringStream: public std::ostrstream { public: typedef std::ostrstream Superclass; OStringStream() {} std::string str() { OStringStreamDetail::Cleanup cleanup(*this); OStringStreamDetail::Cleanup::IgnoreUnusedVariable(cleanup); int pcount = this->pcount(); const char* ptr = this->Superclass::str(); return std::string(ptr?ptr:"", pcount); } private: OStringStream(const OStringStream&); void operator=(const OStringStream&); }; #endif }//namespace igtl #if defined(IGTL_CPP_FUNCTION) #if defined(__BORLANDC__) #define IGTL_LOCATION __FUNC__ #elif defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(CABLE_CONFIGURATION) && !defined(CSWIG) #define IGTL_LOCATION __FUNCSIG__ #elif defined(__GNUC__) #define IGTL_LOCATION __PRETTY_FUNCTION__ #else #define IGTL_LOCATION __FUNCTION__ #endif #else #define IGTL_LOCATION "unknown" #endif #define igtlExceptionMacro(x) \ { \ ::igtl::OStringStream igtlmsg; \ igtlmsg << "Debug: In " __FILE__ ", line " << __LINE__ << "\n" \ << this->GetNameOfClass() << " (" << this << "): " x \ << "\n\n"; \ std::cerr << igtlmsg.str(); /*::igtl::OutputWindowDisplayDebugText(igtlmsg.str().c_str());*/ \ } #define igtlErrorMacro(x) \ { \ ::igtl::OStringStream igtlmsg; \ igtlmsg << "Debug: In " __FILE__ ", line " << __LINE__ << "\n" \ << this->GetNameOfClass() << " (" << this << "): " x \ << "\n\n"; \ std::cerr << igtlmsg.str(); /*::igtl::OutputWindowDisplayDebugText(igtlmsg.str().c_str());*/ \ } #ifdef IGTL_LEAN_AND_MEAN #define igtlGenericOutputMacro(x) #else #define igtlGenericOutputMacro(x) \ { if (1/*::igtl::Object::GetGlobalWarningDisplay()*/) \ { ::igtl::OStringStream igtlmsg; \ igtlmsg << "WARNING: In " __FILE__ ", line " << __LINE__ << "\n" \ x << "\n\n"; \ std::cerr << igtlmsg.str();/*::igtl::OutputWindowDisplayGenericOutputText(igtlmsg.str().c_str());*/} \ } #endif //---------------------------------------------------------------------------- // Macros for simplifying the use of logging // #define igtlLogMacro( x, y) \ { \ if (this->GetLogger() ) \ { \ this->GetLogger()->Write(::igtl::LoggerBase::x, y); \ } \ } #define igtlLogMacroStatic( obj, x, y) \ { \ if (obj->GetLogger() ) \ { \ obj->GetLogger()->Write(::igtl::LoggerBase::x, y); \ } \ } //---------------------------------------------------------------------------- // Setup legacy code policy. // // CMake options IGTL_LEGACY_REMOVE and IGTL_LEGACY_SILENT are converted // to definitions (or non-defs) in igtlConfigure.h and tested below. // They may be used to completely remove legacy code or silence the // warnings. The default is to warn about their use. // // Source files that test the legacy code may define IGTL_LEGACY_TEST // like this: // // #define IGTL_LEGACY_TEST // #include "igtlClassWithDeprecatedMethod.h" // // in order to silence the warnings for calling deprecated methods. // No other source files in IGTL should call the methods since they are // provided only for compatibility with older user code. // Define igtlLegacyMacro to mark legacy methods where they are // declared in their class. Example usage: // // // @deprecated Replaced by MyOtherMethod() as of IGTL 2.0. // igtlLegacyMacro(void MyMethod()); #if defined(IGTL_LEGACY_REMOVE) // Remove legacy methods completely. Put a bogus declaration in // place to avoid stray semicolons because this is an error for some // compilers. Using a class forward declaration allows any number // of repeats in any context without generating unique names. # define igtlLegacyMacro(method) class igtlLegacyMethodRemoved /* no ';' */ #elif defined(IGTL_LEGACY_SILENT) || defined(IGTL_LEGACY_TEST) || defined(CSWIG) // Provide legacy methods with no warnings. # define igtlLegacyMacro(method) method #else // Setup compile-time warnings for uses of deprecated methods if // possible on this compiler. # if defined(__GNUC__) && !defined(__INTEL_COMPILER) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) # define igtlLegacyMacro(method) method __attribute__((deprecated)) # elif defined(_MSC_VER) && _MSC_VER >= 1300 # define igtlLegacyMacro(method) __declspec(deprecated) method # else # define igtlLegacyMacro(method) method # endif #endif // Macros to create runtime deprecation warning messages in function // bodies. Example usage: // // void igtlMyClass::MyOldMethod() // { // igtlLegacyBodyMacro(igtlMyClass::MyOldMethod, 2.0); // } // // void igtlMyClass::MyMethod() // { // igtlLegacyReplaceBodyMacro(igtlMyClass::MyMethod, 2.0, // igtlMyClass::MyOtherMethod); // } #if defined(IGTL_LEGACY_REMOVE) || defined(IGTL_LEGACY_SILENT) # define igtlLegacyBodyMacro(method, version) # define igtlLegacyReplaceBodyMacro(method, version, replace) #else # define igtlLegacyBodyMacro(method, version) \ igtlWarningMacro(#method " was deprecated for IGTL " #version " and will be removed in a future version.") # define igtlLegacyReplaceBodyMacro(method, version, replace) \ igtlWarningMacro(#method " was deprecated for IGTL " #version " and will be removed in a future version. Use " #replace " instead.") #endif #if defined(__INTEL_COMPILER) # pragma warning (disable: 193) /* #if testing undefined identifier */ #endif //============================================================================= /* Choose a way to prevent template instantiation on this platform. - IGTL_TEMPLATE_DO_NOT_INSTANTIATE = use #pragma do_not_instantiate to prevent instantiation - IGTL_TEMPLATE_EXTERN = use extern template to prevent instantiation Note that VS 6 supports extern template instantiation but it is hard to block the resulting warning because its stream headers re-enable it. Therefore we just disable support for now. */ #if defined(__sgi) && defined(_COMPILER_VERSION) # define IGTL_TEMPLATE_DO_NOT_INSTANTIATE 1 #elif defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 700 # define IGTL_TEMPLATE_EXTERN 1 #elif defined(__GNUC__) && __GNUC__ >= 3 # define IGTL_TEMPLATE_EXTERN 1 #elif defined(_MSC_VER) && _MSC_VER >= 1300 # define IGTL_TEMPLATE_EXTERN 1 #endif #if !defined(IGTL_TEMPLATE_DO_NOT_INSTANTIATE) # define IGTL_TEMPLATE_DO_NOT_INSTANTIATE 0 #endif #if !defined(IGTL_TEMPLATE_EXTERN) # define IGTL_TEMPLATE_EXTERN 0 #endif /* Define a macro to explicitly instantiate a template. - IGTL_TEMPLATE_EXPORT(X) = Explicitly instantiate X, where X is of the form N(a1[,a2...,aN]). examples: IGTL_TEMPLATE_EXPORT(1(class Foo)) IGTL_TEMPLATE_EXPORT(2(class Bar)) Use one level of expansion delay to allow user code to have a macro determining the number of arguments. */ #define IGTL_TEMPLATE_EXPORT(x) IGTL_TEMPLATE_EXPORT_DELAY(x) #define IGTL_TEMPLATE_EXPORT_DELAY(x) template IGTL_TEMPLATE_##x; /* Define a macro to prevent template instantiations. - IGTL_TEMPLATE_IMPORT(X) = Prevent instantiation of X, where X is of the form N(a1[,a2...,aN]). examples: IGTL_TEMPLATE_IMPORT(1(class Foo)) IGTL_TEMPLATE_IMPORT(2(class Bar)) Use one level of expansion delay to allow user code to have a macro determining the number of arguments. */ #if IGTL_TEMPLATE_EXTERN # define IGTL_TEMPLATE_IMPORT_DELAY(x) extern template IGTL_TEMPLATE_##x; # if defined(_MSC_VER) # pragma warning (disable: 4231) /* extern template extension */ # endif #elif IGTL_TEMPLATE_DO_NOT_INSTANTIATE # define IGTL_TEMPLATE_IMPORT_DELAY(x) \ IGTL_TEMPLATE_IMPORT_IMPL(do_not_instantiate IGTL_TEMPLATE_##x) # define IGTL_TEMPLATE_IMPORT_IMPL(x) _Pragma(#x) #endif #if defined(IGTL_TEMPLATE_IMPORT_DELAY) # define IGTL_TEMPLATE_IMPORT(x) IGTL_TEMPLATE_IMPORT_DELAY(x) # define IGTL_TEMPLATE_IMPORT_WORKS 1 #else # define IGTL_TEMPLATE_IMPORT(x) # define IGTL_TEMPLATE_IMPORT_WORKS 0 #endif /* Define macros to export and import template instantiations. These depend on each class providing a macro defining the instantiations given template arguments in X. The argument X is of the form N(a1[,a2...,aN]). The argument Y is a valid preprocessing token unique to the template arguments given in X. Typical usage is IGTL_EXPORT_TEMPLATE(igtlfoo_EXPORT, Foo, (int), I) IGTL_EXPORT_TEMPLATE(igtlfoo_EXPORT, Bar, (int, char), IC) The IGTL_TEMPLATE_ macro should be defined in igtl.h and is of the following form: #define IGTL_TEMPLATE_(_, EXPORT, x, y) namespace igtl { \ _((class EXPORT < IGTL_TEMPLATE_ x >)) \ namespace Templates { typedef < IGTL_TEMPLATE_ x > ##y; }\ } The argument "_" will be replaced by another macro such as IGTL_TEMPLATE_EXPORT or IGTL_TEMPLATE_IMPORT, so it should be used as if calling one of these macros. The argument "EXPORT" will be replaced by a dllexport/dllimport macro such as IGTLCommon_EXPORT. The argument "x" is a paren-enclosed list of template arguments. The argument "y" is a preprocessing token corresponding to the given template arguments and should be used to construct typedef names for the instantiations. Note the use of IGTL_TEMPLATE_, where is the number of template arguments for the class template. Note also that the number of template arguments is usually the length of the list nested within the inner parentheses, so the instantiation is listed with the form (...). Example definitions: #define IGTL_TEMPLATE_Foo(_, EXPORT, x, y) namespace igtl { \ _(1(class EXPORT Foo< IGTL_TEMPLATE_1 x >)) \ _(1(EXPORT std::ostream& operator<<(std::ostream&, \ const Foo< IGTL_TEMPLATE_1 x >&))) \ namespace Templates { typedef Foo< IGTL_TEMPLATE_1 x > Foo##y; }\ } #define IGTL_TEMPLATE_Bar(_, EXPORT, x, y) namespace igtl { \ _(2(class EXPORT Bar< IGTL_TEMPLATE_2 x >)) \ _(1(EXPORT std::ostream& operator<<(std::ostream&, \ const Bar< IGTL_TEMPLATE_2 x >&))) \ namespace Templates { typedef Bar< IGTL_TEMPLATE_2 x > Bar##y; }\ } Note that in the stream operator for template Bar there is a "1" at the beginning even though two arguments are taken. This is because the expression "IGTL_TEMPLATE_2 x" is contained inside the parentheses of the function signature which protects the resulting comma from separating macro arguments. Therefore the nested parentheses contain a list of only one macro argument. The IGTL_EMPTY macro used in these definitions is a hack to work around a VS 6.0 preprocessor bug when EXPORT is empty. */ #define IGTL_EXPORT_TEMPLATE(EXPORT, c, x, y) \ IGTL_TEMPLATE_##c(IGTL_TEMPLATE_EXPORT, EXPORT IGTL_EMPTY, x, y) #define IGTL_IMPORT_TEMPLATE(EXPORT, c, x, y) \ IGTL_TEMPLATE_##c(IGTL_TEMPLATE_IMPORT, EXPORT IGTL_EMPTY, x, y) #define IGTL_EMPTY /* Define macros to support passing a variable number of arguments throug other macros. This is used by IGTL_TEMPLATE_EXPORT, IGTL_TEMPLATE_IMPORT, and by each template's instantiation macro. */ #define IGTL_TEMPLATE_1(x1) x1 #define IGTL_TEMPLATE_2(x1,x2) x1,x2 #define IGTL_TEMPLATE_3(x1,x2,x3) x1,x2,x3 #define IGTL_TEMPLATE_4(x1,x2,x3,x4) x1,x2,x3,x4 #define IGTL_TEMPLATE_5(x1,x2,x3,x4,x5) x1,x2,x3,x4,x5 #define IGTL_TEMPLATE_6(x1,x2,x3,x4,x5,x6) x1,x2,x3,x4,x5,x6 #define IGTL_TEMPLATE_7(x1,x2,x3,x4,x5,x6,x7) x1,x2,x3,x4,x5,x6,x7 #define IGTL_TEMPLATE_8(x1,x2,x3,x4,x5,x6,x7,x8) x1,x2,x3,x4,x5,x6,x7,x8 #define IGTL_TEMPLATE_9(x1,x2,x3,x4,x5,x6,x7,x8,x9) x1,x2,x3,x4,x5,x6,x7,x8,x9 /* In order to support both implicit and explicit instantation a .h file needs to know whether it should include its .txx file containing the template definitions. Define a macro to tell it. Typical usage in igtlFoo.h: #if IGTL_TEMPLATE_TXX # include "igtlFoo.txx" #endif */ #if defined(IGTL_MANUAL_INSTANTIATION) # define IGTL_TEMPLATE_TXX 0 #else # define IGTL_TEMPLATE_TXX !(IGTL_TEMPLATE_CXX || IGTL_TEMPLATE_TYPE) #endif /* All explicit instantiation source files define IGTL_TEMPLATE_CXX. Define IGTL_MANUAL_INSTANTIATION to tell .h files that have not been converted to this explicit instantiation scheme to not include their .txx files. Also disable warnings that commonly occur in these files but are not useful. */ #if IGTL_TEMPLATE_CXX # undef IGTL_MANUAL_INSTANTIATION # define IGTL_MANUAL_INSTANTIATION # if defined(_MSC_VER) # pragma warning (disable: 4275) /* non dll-interface base */ # pragma warning (disable: 4661) /* no definition available */ # endif #endif //============================================================================= /* Define macros to export and import template instantiations for each library in IGTL. */ #define IGTL_EXPORT_IGTLCommon(c, x, n) \ IGTL_EXPORT_TEMPLATE(IGTLCommon_EXPORT, c, x, n) #define IGTL_IMPORT_IGTLCommon(c, x, n) \ IGTL_IMPORT_TEMPLATE(IGTLCommon_EXPORT, c, x, n) /* Define a macro to decide whether to block instantiation of IGTL templates. They should be blocked only if the platform supports blocking template instantiation and the explicit instantiations are available. - IGTL_TEMPLATE_EXPLICIT = Whether to include "XXX+-.h" from "XXX.h" to prevent implicit instantiations of templates explicitly instantiated elsewhere. Typical usage in igtlFoo.h: #if IGTL_TEMPLATE_EXPLICIT # include "igtlFoo+-.h" #endif */ #if IGTL_TEMPLATE_IMPORT_WORKS && defined(IGTL_EXPLICIT_INSTANTIATION) # define IGTL_TEMPLATE_EXPLICIT !IGTL_TEMPLATE_CXX #else # define IGTL_TEMPLATE_EXPLICIT 0 #endif //---------------------------------------------------------------------------- // Macro to declare that a function does not return. __attribute__((noreturn)) // On some compiler, functions that do not return (ex: exit(0)) must // have the noreturn attribute. Otherwise, a warning is raised. Use // that macro to avoid those warnings. GCC defines the attribute // noreturn for versions 2.5 and higher. #if defined(__GNUC__) # if (((__GNUC__ == 2) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ >= 3)) # define IGTL_NO_RETURN \ __attribute__ ((noreturn)) # endif #else # define IGTL_NO_RETURN #endif #ifdef IGTL_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING //-------------------------------------------------------------------------------- // Helper macros for Template Meta-Programming techniques of for-loops unrolling //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- // Macro that generates an unrolled for loop for assigning elements of one array // to elements of another array The array are assumed to be of same length // (dimension), and this is also assumed to be the value of NumberOfIterations. // No verification of size is performed. Casting is perfomed as part of the // assignment, by using the DestinationElementType as the casting type. // Source and destination array types must have defined opearator[] in their API. #define igtlFoorLoopAssignmentMacro(DestinationType,SourceType,DestinationElementType,DestinationArray,SourceArray,NumberOfIterations) \ for(unsigned int i=0;i < NumberOfIterations; ++i) \ { \ DestinationArray[i] = static_cast< DestinationElementType >( SourceArray[i] ); \ } //-------------------------------------------------------------------------------- // Macro that generates an unrolled for loop for rounding and assigning // elements of one array to elements of another array The array are assumed to // be of same length (dimension), and this is also assumed to be the value of // NumberOfIterations. No verification of size is performed. Casting is // perfomed as part of the assignment, by using the DestinationElementType as // the casting type. // Source and destination array types must have defined opearator[] in their API. #define igtlFoorLoopRoundingAndAssignmentMacro(DestinationType,SourceType,DestinationElementType,DestinationArray,SourceArray,NumberOfIterations) \ for(unsigned int i=0;i < NumberOfIterations; ++i) \ { \ DestinationArray[i] = static_cast< DestinationElementType >( vnl_math_rnd( SourceArray[i] ) ); \ } #endif // end of Template Meta Programming helper macros #endif //end of igtlMacro.h openigtlink-3.0.0/Source/igtlMath.cxx000066400000000000000000000105241501024245700175740ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtlWin32Header.h" #include "igtlMath.h" namespace igtl { void IGTLCommon_EXPORT PrintMatrix(igtl::Matrix4x4 &matrix) { std::cout << "=============" << std::endl; std::cout << matrix[0][0] << ", " << matrix[0][1] << ", " << matrix[0][2] << ", " << matrix[0][3] << std::endl; std::cout << matrix[1][0] << ", " << matrix[1][1] << ", " << matrix[1][2] << ", " << matrix[1][3] << std::endl; std::cout << matrix[2][0] << ", " << matrix[2][1] << ", " << matrix[2][2] << ", " << matrix[2][3] << std::endl; std::cout << matrix[3][0] << ", " << matrix[3][1] << ", " << matrix[3][2] << ", " << matrix[3][3] << std::endl; std::cout << "=============" << std::endl; } void IGTLCommon_EXPORT PrintVector3(float v[3]) { std::cout << v[0] << ", " << v[1] << ", " << v[2] << std::endl; } void IGTLCommon_EXPORT PrintVector3(float x, float y, float z) { std::cout << x << ", " << y << ", " << z << std::endl; } void IGTLCommon_EXPORT PrintVector4(float v[4]) { std::cout << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << std::endl; } void IGTLCommon_EXPORT PrintVector4(float x, float y, float z, float w) { std::cout << x << ", " << y << ", " << z << ", " << w << std::endl; } void IGTLCommon_EXPORT QuaternionToMatrix(float* q, Matrix4x4& m) { // normalize float mod = sqrt(q[0]*q[0]+q[1]*q[1]+q[2]*q[2]+q[3]*q[3]); // convert to the matrix const float x = q[0] / mod; const float y = q[1] / mod; const float z = q[2] / mod; const float w = q[3] / mod; const float xx = x * x * 2.0; const float xy = x * y * 2.0; const float xz = x * z * 2.0; const float xw = x * w * 2.0; const float yy = y * y * 2.0; const float yz = y * z * 2.0; const float yw = y * w * 2.0; const float zz = z * z * 2.0; const float zw = z * w * 2.0; m[0][0] = 1.0 - (yy + zz); m[1][0] = xy + zw; m[2][0] = xz - yw; m[0][1] = xy - zw; m[1][1] = 1.0 - (xx + zz); m[2][1] = yz + xw; m[0][2] = xz + yw; m[1][2] = yz - xw; m[2][2] = 1.0 - (xx + yy); m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0; m[0][3] = 0.0; m[1][3] = 0.0; m[2][3] = 0.0; } void IGTLCommon_EXPORT MatrixToQuaternion(Matrix4x4& m, float* q) { float trace = m[0][0] + m[1][1] + m[2][2]; if ( trace > 0.0 ) { float s = 0.5f / sqrt(trace + 1.0f); q[3] = 0.25f / s; q[0] = ( m[2][1] - m[1][2] ) * s; q[1] = ( m[0][2] - m[2][0] ) * s; q[2] = ( m[1][0] - m[0][1] ) * s; } else { if ( m[0][0] > m[1][1] && m[0][0] > m[2][2] ) { float s = 2.0f * sqrt( 1.0f + m[0][0] - m[1][1] - m[2][2]); q[3] = (m[2][1] - m[1][2] ) / s; q[0] = 0.25f * s; q[1] = (m[0][1] + m[1][0] ) / s; q[2] = (m[0][2] + m[2][0] ) / s; } else if (m[1][1] > m[2][2]) { float s = 2.0f * sqrt( 1.0f + m[1][1] - m[0][0] - m[2][2]); q[3] = (m[0][2] - m[2][0] ) / s; q[0] = (m[0][1] + m[1][0] ) / s; q[1] = 0.25f * s; q[2] = (m[1][2] + m[2][1] ) / s; } else { float s = 2.0f * sqrt( 1.0f + m[2][2] - m[0][0] - m[1][1] ); q[3] = (m[1][0] - m[0][1] ) / s; q[0] = (m[0][2] + m[2][0] ) / s; q[1] = (m[1][2] + m[2][1] ) / s; q[2] = 0.25f * s; } } } void IGTLCommon_EXPORT Cross(float *a, float *b, float *c) { a[0] = b[1]*c[2] - c[1]*b[2]; a[1] = c[0]*b[2] - b[0]*c[2]; a[2] = b[0]*c[1] - c[0]*b[1]; } void IGTLCommon_EXPORT IdentityMatrix(igtl::Matrix4x4 &matrix) { matrix[0][0] = 1.0; matrix[1][0] = 0.0; matrix[2][0] = 0.0; matrix[3][0] = 0.0; matrix[0][1] = 0.0; matrix[1][1] = 1.0; matrix[2][1] = 0.0; matrix[3][1] = 0.0; matrix[0][2] = 0.0; matrix[1][2] = 0.0; matrix[2][2] = 1.0; matrix[3][2] = 0.0; matrix[0][3] = 0.0; matrix[1][3] = 0.0; matrix[2][3] = 0.0; matrix[3][3] = 1.0; } } // namespace igtl openigtlink-3.0.0/Source/igtlMath.h000066400000000000000000000036361501024245700172270ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlMath_h #define __igtlMath_h #include "igtlWin32Header.h" namespace igtl { typedef float Matrix4x4[4][4]; /// Prints out a 4-by-4 matrix on the standard output. void IGTLCommon_EXPORT PrintMatrix(igtl::Matrix4x4 &matrix); /// Prints out a 3-element vector on the standard output. void IGTLCommon_EXPORT PrintVector3(float v[3]); /// Prints out a 3-element vector on the standard output. void IGTLCommon_EXPORT PrintVector3(float x, float y, float z); /// Prints out a 4-element vector on the standard output. void IGTLCommon_EXPORT PrintVector4(float v[4]); /// Prints out a 4-element vector on the standard output. void IGTLCommon_EXPORT PrintVector4(float x, float y, float z, float w); /// Converts a quaternion to a 3-by-3 rotation matrix. Only the 3-by-3 rotation matrix part /// in the 4-by-4 matrix is used. void IGTLCommon_EXPORT QuaternionToMatrix(float* q, Matrix4x4& m); /// Converts a 3-by-3 rotation matrix a quaternion. Only the 3-by-3 rotation matrix part /// in the 4-by-4 matrix is used. void IGTLCommon_EXPORT MatrixToQuaternion(Matrix4x4& m, float* q); /// Calculates the cross products of 3-element vectors 'b' and 'c'. The result is substituted into /// a 3-element vector a. void IGTLCommon_EXPORT Cross(float *a, float *b, float *c); /// Initialize a 4-by-4 matrix as an identity matrix. void IGTLCommon_EXPORT IdentityMatrix(igtl::Matrix4x4 &matrix); } #endif // __igtlMath_h openigtlink-3.0.0/Source/igtlMessageBase.cxx000066400000000000000000000616041501024245700210670ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlMessageBase.h" #include "igtlMessageFactory.h" #include "igtl_header.h" #include "igtl_util.h" #include #include #include #include namespace { static const int META_DATA_INDEX_COUNT_SIZE = sizeof(igtlUint16); } namespace igtl { MessageBase::MessageBase() : Object() , m_MessageSize(0) , m_Header(NULL) , m_Body(NULL) , m_Content(NULL) , m_BodySizeToRead(0) , m_SendMessageType("") , m_ReceiveMessageType("") , m_HeaderVersion(IGTL_HEADER_VERSION_1) , m_DeviceName("") , m_TimeStampSec(0) , m_TimeStampSecFraction(0) , m_IsHeaderUnpacked(false) , m_IsBodyUnpacked(false) , m_IsBodyPacked(false) #if OpenIGTLink_HEADER_VERSION >= 2 , m_ExtendedHeader(NULL) , m_IsExtendedHeaderUnpacked(false) , m_MetaData(NULL) , m_MessageId(0) , m_MetaDataMap(MetaDataMap()) #endif { } MessageBase::~MessageBase() { if (this->m_MessageSize > 0 && this->m_Header != NULL) { delete [] m_Header; m_MessageSize = 0; m_Header = NULL; m_Body = NULL; m_Content = NULL; #if OpenIGTLink_HEADER_VERSION >= 2 m_ExtendedHeader = NULL; m_MetaDataHeader = NULL; m_MetaData = NULL; #endif } } int MessageBase::CalculateContentBufferSize() { return 0; } igtl::MessageBase::Pointer MessageBase::Clone() { igtl::MessageBase::Pointer clone; { igtl::MessageFactory::Pointer factory = igtl::MessageFactory::New(); clone = factory->CreateSendMessage(this->GetMessageType(), this->GetHeaderVersion()); } int bodySize = this->m_MessageSize - IGTL_HEADER_SIZE; clone->InitBuffer(); clone->CopyHeader(this); clone->AllocateBuffer(bodySize); if (bodySize > 0) { clone->CopyBody(this); } #if OpenIGTLink_HEADER_VERSION >= 2 clone->m_MetaDataHeader = this->m_MetaDataHeader; clone->m_MetaDataMap = this->m_MetaDataMap; clone->m_IsExtendedHeaderUnpacked = this->m_IsExtendedHeaderUnpacked; #endif return clone; } void MessageBase::SetHeaderVersion(unsigned short version) { m_HeaderVersion = version; m_IsBodyPacked = false; } unsigned short MessageBase::GetHeaderVersion() const { return m_HeaderVersion; } void MessageBase::SetDeviceName(const char* name) { if (name == NULL) { return; } SetDeviceName(std::string(name)); } void MessageBase::SetDeviceName(const std::string& name) { m_DeviceName = name; m_IsBodyPacked = false; } void MessageBase::SetDeviceType(const std::string& type) { this->m_ReceiveMessageType = type; m_IsBodyPacked = false; } std::string MessageBase::GetDeviceName() const { return m_DeviceName; } const char* MessageBase::GetDeviceName() { return m_DeviceName.c_str(); } const char* MessageBase::GetDeviceType() { if (m_SendMessageType.length() > 0) { return m_SendMessageType.c_str(); } else { return m_ReceiveMessageType.c_str(); } } std::string MessageBase::GetMessageType() const { if (m_SendMessageType.length() > 0) { return m_SendMessageType; } else { return m_ReceiveMessageType; } } #if OpenIGTLink_HEADER_VERSION >= 2 igtlUint32 MessageBase::GetMetaDataSize() { if( m_HeaderVersion >= IGTL_HEADER_VERSION_2 ) { igtlUint32 metaDataSize(0); for (MetaDataMap::const_iterator it = m_MetaDataMap.begin(); it != m_MetaDataMap.end(); ++it) { metaDataSize += it->first.length() + it->second.second.length(); } return metaDataSize; } else { return 0; } } igtlUint16 MessageBase::GetMetaDataHeaderSize() { if( m_HeaderVersion >= IGTL_HEADER_VERSION_2 ) { return (m_MetaDataMap.size()*sizeof(igtl_metadata_header_entry)) + sizeof(igtlUint16); // index_count is at beginning of header } else { return 0; } } igtlUint32 MessageBase::GetMessageID() { return m_MessageId; } void MessageBase::SetMessageID(igtlUint32 idValue) { m_MessageId = idValue; m_IsBodyPacked = false; } bool MessageBase::SetMetaDataElement(const std::string& key, IANA_ENCODING_TYPE encodingScheme, std::string value) { igtl_metadata_header_entry entry; if (key.length() > std::numeric_limits::max()) { return false; } entry.key_size = static_cast(key.length()); entry.value_encoding = static_cast(encodingScheme); entry.value_size = value.length(); m_MetaDataMap[key] = std::pair(encodingScheme, value); m_IsBodyPacked = false; return true; } bool MessageBase::SetMetaDataElement(const std::string& key, igtl_uint8 value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, igtl_int8 value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, igtl_uint16 value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, igtl_int16 value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, igtl_uint32 value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, igtl_int32 value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, igtl_uint64 value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, igtl_int64 value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, float value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::SetMetaDataElement(const std::string& key, double value) { std::stringstream ss; ss << value; return SetMetaDataElement(key, IANA_TYPE_US_ASCII, ss.str()); } bool MessageBase::GetMetaDataElement(const std::string& key, std::string& value) const { IANA_ENCODING_TYPE type; return GetMetaDataElement(key, type, value); } bool MessageBase::GetMetaDataElement(const std::string& key, IANA_ENCODING_TYPE& encoding, std::string& value) const { if (m_MetaDataMap.find(key) != m_MetaDataMap.end()) { encoding = m_MetaDataMap.find(key)->second.first; value = m_MetaDataMap.find(key)->second.second; return true; } return false; } const MessageBase::MetaDataMap& MessageBase::GetMetaData() const { return this->m_MetaDataMap; } bool MessageBase::PackExtendedHeader() { if( m_HeaderVersion == IGTL_HEADER_VERSION_2 ) { int aSize = m_MessageSize - IGTL_HEADER_SIZE - sizeof(igtl_extended_header); if( aSize < 0 ) { // Ensure we have enough space to write the header AllocateBuffer(0); } igtl_extended_header* extended_header = (igtl_extended_header*) m_ExtendedHeader; extended_header->extended_header_size = sizeof(igtl_extended_header); extended_header->meta_data_header_size = this->GetMetaDataHeaderSize(); extended_header->meta_data_size = this->GetMetaDataSize(); extended_header->message_id = this->GetMessageID(); igtl_extended_header_convert_byte_order(extended_header); return true; } return false; } bool MessageBase::PackMetaData() { if( m_HeaderVersion == IGTL_HEADER_VERSION_2 ) { if (m_MetaDataMap.size() > std::numeric_limits::max()) { return false; } igtl_uint16 index_count = static_cast(m_MetaDataMap.size()); // first two byte are the total number of meta data if(igtl_is_little_endian()) { index_count = BYTE_SWAP_INT16(index_count); } // Pack meta data header key/encoding/value trios memcpy(m_MetaDataHeader, &index_count, META_DATA_INDEX_COUNT_SIZE); if (m_MetaDataMap.size() > 0) { unsigned char* entryPointer = &m_MetaDataHeader[META_DATA_INDEX_COUNT_SIZE]; for (MetaDataMap::const_iterator it = m_MetaDataMap.begin(); it != m_MetaDataMap.end();++it) { igtl_metadata_header_entry entry; entry.key_size = it->first.length(); entry.value_encoding = it->second.first; entry.value_size = it->second.second.length(); if(igtl_is_little_endian()) { entry.key_size = BYTE_SWAP_INT16(entry.key_size); entry.value_encoding = BYTE_SWAP_INT16(entry.value_encoding); entry.value_size = BYTE_SWAP_INT32(entry.value_size); } memcpy(&entryPointer[0], &entry.key_size, sizeof(igtlUint16)); memcpy(&entryPointer[2], &entry.value_encoding, sizeof(igtlUint16)); memcpy(&entryPointer[4], &entry.value_size, sizeof(igtlUint32)); entryPointer += sizeof(igtl_metadata_header_entry); } // Pack meta data key/value pairs std::string key(""); std::string value(""); unsigned char* metaDataPointer = m_MetaData; int i(0); for (MetaDataMap::iterator it = m_MetaDataMap.begin(); it != m_MetaDataMap.end(); ++it, ++i) { memcpy(metaDataPointer, it->first.c_str(), it->first.length()); metaDataPointer += it->first.length(); memcpy(metaDataPointer, it->second.second.c_str(), it->second.second.length()); metaDataPointer += it->second.second.length(); } return true; } else { return true; } } return false; } bool MessageBase::UnpackExtendedHeader() { if (m_HeaderVersion == IGTL_HEADER_VERSION_2) { igtl_extended_header* extended_header = (igtl_extended_header*)m_ExtendedHeader; igtl_extended_header_convert_byte_order(extended_header); if( extended_header->extended_header_size != sizeof(igtl_extended_header) ) { // any extra data will be dropped, if the order of variables is changed, this will be seriously broken // TODO : add error reporting? } this->m_MessageId = extended_header->message_id; m_Content = &m_Body[extended_header->extended_header_size]; m_MetaDataHeader = &m_Body[m_BodySizeToRead - extended_header->meta_data_header_size - extended_header->meta_data_size]; m_MetaData = &m_Body[m_BodySizeToRead - extended_header->meta_data_size]; m_IsExtendedHeaderUnpacked = true; return true; } return false; } bool MessageBase::UnpackMetaData() { if (m_HeaderVersion == IGTL_HEADER_VERSION_2) { // Parse the header igtl_uint16 index_count = 0; // first two byte are the total number of meta data memcpy(&index_count, m_MetaDataHeader, META_DATA_INDEX_COUNT_SIZE); if(igtl_is_little_endian()) { index_count = BYTE_SWAP_INT16(index_count); } if( index_count == 0 ) { return true; } std::vector metaDataEntries; igtl_metadata_header_entry entry; unsigned char* entryPointer = &m_MetaDataHeader[META_DATA_INDEX_COUNT_SIZE]; for (int i = 0; i < index_count; i++) { memcpy(&entry.key_size, &entryPointer[0], sizeof(igtlUint16)); memcpy(&entry.value_encoding, &entryPointer[2], sizeof(igtlUint16)); memcpy(&entry.value_size, &entryPointer[4], sizeof(igtlUint32)); if(igtl_is_little_endian()) { entry.key_size = BYTE_SWAP_INT16(entry.key_size); entry.value_encoding = BYTE_SWAP_INT16(entry.value_encoding); entry.value_size = BYTE_SWAP_INT32(entry.value_size); } metaDataEntries.push_back(entry); entryPointer += sizeof(igtl_metadata_header_entry); } // Parse the meta data m_MetaDataMap.clear(); unsigned char* metaDataPointer = m_MetaData; for (int i = 0; i < index_count; i++) { std::string key; key.assign(metaDataPointer, metaDataPointer + metaDataEntries[i].key_size); metaDataPointer += metaDataEntries[i].key_size; std::string value; value.assign(metaDataPointer, metaDataPointer + metaDataEntries[i].value_size); metaDataPointer += metaDataEntries[i].value_size; m_MetaDataMap[key] = std::pair((IANA_ENCODING_TYPE)metaDataEntries[i].value_encoding, value); } return true; } return false; } #endif int MessageBase::SetTimeStamp(unsigned int sec, unsigned int frac) { m_TimeStampSec = sec; m_TimeStampSecFraction = frac; return 1; } int MessageBase::GetTimeStamp(unsigned int* sec, unsigned int* frac) { *sec = m_TimeStampSec; *frac = m_TimeStampSecFraction; return 1; } void MessageBase::SetTimeStamp(igtl::TimeStamp::Pointer& ts) { m_TimeStampSec = ts->GetSecond(); m_TimeStampSecFraction = igtl_nanosec_to_frac(ts->GetNanosecond()); } void MessageBase::GetTimeStamp(igtl::TimeStamp::Pointer& ts) { ts->SetTime(m_TimeStampSec, igtl_frac_to_nanosec(m_TimeStampSecFraction)); } int MessageBase::Pack() { if (m_IsBodyPacked) { // Allow for multiple packs return 1; } if( m_SendMessageType.empty() ) { // We do not allow sending of base class messages, aka igtl::MessageBase // TODO : error reporting? return 0; } #if OpenIGTLink_HEADER_VERSION >= 2 PackExtendedHeader(); #endif // Derived classes will re-call allocate pack with their required content size PackContent(); #if OpenIGTLink_HEADER_VERSION >= 2 PackMetaData(); #endif m_IsBodyPacked = true; // pack header igtl_header* h = (igtl_header*) m_Header; igtl_uint64 crc = crc64(0, 0, 0LL); // initial crc h->header_version = m_HeaderVersion; igtl_uint64 ts = m_TimeStampSec & 0xFFFFFFFF; ts = (ts << 32) | (m_TimeStampSecFraction & 0xFFFFFFFF); h->timestamp = ts; h->body_size = GetBufferBodySize(); h->crc = crc64((unsigned char*)m_Body, h->body_size, crc); strncpy(h->name, m_SendMessageType.c_str(), 12); strncpy(h->device_name, m_DeviceName.c_str(), 20); igtl_header_convert_byte_order(h); return 1; } int MessageBase::Unpack(int crccheck) { int r = UNPACK_UNDEF; // Check if the pack exists and if it has not been unpacked. if (m_Header != NULL && m_MessageSize >= IGTL_HEADER_SIZE && !m_IsHeaderUnpacked ) { InitBuffer(); UnpackHeader(r); } #if OpenIGTLink_HEADER_VERSION >= 2 // Check if the body exists and it has not been unpacked // The extended header is technically located inside the body, so we have to check to see if the remaining body size // is > 0, or if full body size > sizeof(igtl_extended_header) if( m_HeaderVersion >= IGTL_HEADER_VERSION_2 ) { if (GetBufferBodySize() > static_cast(sizeof(igtl_extended_header)) + META_DATA_INDEX_COUNT_SIZE && !m_IsBodyUnpacked) { UnpackBody(crccheck, r); } } else { #endif if(GetBufferBodySize() > 0 && !m_IsBodyUnpacked) { UnpackBody(crccheck, r); } #if OpenIGTLink_HEADER_VERSION >= 2 } #endif return r; } void* MessageBase::GetBufferPointer() { return (void*) m_Header; } void* MessageBase::GetBufferBodyPointer() { return (void*) m_Body; } int MessageBase::GetBufferSize() { return m_MessageSize; } int MessageBase::GetBufferBodySize() { return GetBufferSize() - IGTL_HEADER_SIZE; } int MessageBase::CalculateReceiveContentSize() { #if OpenIGTLink_HEADER_VERSION >= 2 if( m_HeaderVersion >= IGTL_HEADER_VERSION_2 ) { if( !m_IsExtendedHeaderUnpacked ) { // TODO : would like to throw an error, which method to do to report errors? return -1; } igtl_extended_header* header = (igtl_extended_header*)m_ExtendedHeader; return GetBufferSize() - IGTL_HEADER_SIZE - header->extended_header_size - header->meta_data_header_size - header->meta_data_size; } else { #endif return m_BodySizeToRead; #if OpenIGTLink_HEADER_VERSION >= 2 } #endif } const char* MessageBase::GetBodyType() { return this->m_ReceiveMessageType.c_str(); } int MessageBase::PackContent() { return 0; } int MessageBase::UnpackContent() { return 0; } void MessageBase::AllocateBuffer() { if( m_BodySizeToRead > 0 ) { // called after receiving general header AllocateUnpack(m_BodySizeToRead); } else { // called for creating pack to send AllocateBuffer(CalculateContentBufferSize()); } } void MessageBase::InitBuffer() { m_IsHeaderUnpacked = false; m_IsBodyPacked = false; m_IsBodyUnpacked = false; m_BodySizeToRead = 0; m_DeviceName = ""; m_ReceiveMessageType = ""; // Re-allocate header area int message_size = IGTL_HEADER_SIZE; if (m_Header == NULL) { // For the first time m_Header = new unsigned char [message_size]; m_IsHeaderUnpacked = false; m_IsBodyUnpacked = false; } else if (m_MessageSize != message_size) { // If the pack area exists but needs to be reallocated // m_IsHeaderUnpacked status is not changed in this case. unsigned char* old = m_Header; m_Header = new unsigned char [message_size]; memcpy(m_Header, old, std::min(m_MessageSize, message_size)); delete [] old; m_IsBodyUnpacked = false; } m_Body = &m_Header[IGTL_HEADER_SIZE]; #if OpenIGTLink_HEADER_VERSION >= 2 if (m_HeaderVersion == IGTL_HEADER_VERSION_2) { m_ExtendedHeader = m_Body; // Other members can't be populated until the message is unpacked } else { m_Content = m_Body; } #else m_Content = m_Body; #endif m_MessageSize = message_size; } void MessageBase::AllocateBuffer(int contentSize) { #if OpenIGTLink_HEADER_VERSION >= 2 int message_size(-1); if (m_HeaderVersion == IGTL_HEADER_VERSION_2) { message_size = IGTL_HEADER_SIZE + contentSize + sizeof(igtl_extended_header) + GetMetaDataHeaderSize() + GetMetaDataSize(); } else { message_size = IGTL_HEADER_SIZE + contentSize; } #else int message_size = IGTL_HEADER_SIZE + contentSize; #endif if (m_Header == NULL) { // For the first time m_Header = new unsigned char [message_size]; m_IsHeaderUnpacked = false; m_IsBodyUnpacked = false; m_IsBodyPacked = false; } else if (m_MessageSize != message_size) { // If the pack area exists but needs to be reallocated // m_IsHeaderUnpacked status is not changed in this case. unsigned char* old = m_Header; m_Header = new unsigned char [message_size]; memcpy(m_Header, old, std::min(m_MessageSize, message_size)); delete [] old; m_IsBodyUnpacked = false; } m_Body = &m_Header[IGTL_HEADER_SIZE]; #if OpenIGTLink_HEADER_VERSION >= 2 if (m_HeaderVersion == IGTL_HEADER_VERSION_2) { m_ExtendedHeader = m_Body; m_Content = &m_Body[sizeof(igtl_extended_header)]; m_MetaDataHeader = &m_Body[sizeof(igtl_extended_header)+contentSize]; m_MetaData = &m_Body[sizeof(igtl_extended_header)+contentSize+GetMetaDataHeaderSize()]; } else { #endif m_Content = m_Body; #if OpenIGTLink_HEADER_VERSION >= 2 } #endif m_MessageSize = message_size; } int MessageBase::CopyHeader(const MessageBase* mb) { if (m_Header != NULL && mb->m_Header != NULL) { memcpy(m_Header, mb->m_Header, IGTL_HEADER_SIZE); m_Body = &m_Header[IGTL_HEADER_SIZE]; if (mb->m_HeaderVersion < IGTL_HEADER_VERSION_2) { m_Content = m_Body; } } m_MessageSize = mb->m_MessageSize; m_ReceiveMessageType = mb->m_ReceiveMessageType; m_DeviceName = mb->m_DeviceName; m_TimeStampSec = mb->m_TimeStampSec; m_TimeStampSecFraction = mb->m_TimeStampSecFraction; m_IsHeaderUnpacked = mb->m_IsHeaderUnpacked; m_IsBodyUnpacked = mb->m_IsBodyUnpacked; m_IsBodyPacked = mb->m_IsBodyPacked; m_BodySizeToRead = mb->m_BodySizeToRead; m_HeaderVersion = mb->m_HeaderVersion; return 1; } int MessageBase::CopyBody(const MessageBase *mb) { int bodySize = m_MessageSize - IGTL_HEADER_SIZE; if (m_Body != NULL && mb->m_Body != NULL && bodySize > 0) { memcpy(m_Body, mb->m_Body, bodySize); #if OpenIGTLink_HEADER_VERSION >= 2 if( m_HeaderVersion == IGTL_HEADER_VERSION_2 ) { igtl_extended_header* other_ext_header = (igtl_extended_header*)(mb->m_ExtendedHeader); if( other_ext_header->extended_header_size != sizeof(igtl_extended_header) ) { return 0; } m_ExtendedHeader = m_Body; m_Content = &m_Body[other_ext_header->extended_header_size]; m_MetaDataHeader = &m_Body[bodySize - other_ext_header->meta_data_header_size - other_ext_header->meta_data_size]; m_MetaData = &m_Body[bodySize - other_ext_header->meta_data_size]; } else { #endif m_Content = m_Body; #if OpenIGTLink_HEADER_VERSION >= 2 } #endif return 1; } return 0; } void MessageBase::UnpackHeader(int& r) { // Unpack (deserialize) the header igtl_header* h = (igtl_header*) m_Header; igtl_header_convert_byte_order(h); m_TimeStampSecFraction = h->timestamp & 0xFFFFFFFF; m_TimeStampSec = (h->timestamp >> 32 ) & 0xFFFFFFFF; m_HeaderVersion = h->header_version; m_BodySizeToRead = h->body_size; char bodyType[IGTL_HEADER_TYPE_SIZE+1]; char deviceName[IGTL_HEADER_NAME_SIZE+1]; bodyType[IGTL_HEADER_TYPE_SIZE] = '\0'; deviceName[IGTL_HEADER_NAME_SIZE] = '\0'; strncpy(bodyType, h->name, IGTL_HEADER_TYPE_SIZE); strncpy(deviceName, h->device_name, IGTL_HEADER_NAME_SIZE); m_ReceiveMessageType = bodyType; if( m_ReceiveMessageType.empty() ) { // MessageBase class has been sent, this can't be good // TODO : how to report an error } m_DeviceName = deviceName; // Mark as unpacked. m_IsHeaderUnpacked = true; r |= UNPACK_HEADER; } void MessageBase::UnpackBody(int crccheck, int& r) { igtl_header* h = (igtl_header*) m_Header; igtl_uint64 crc = crc64(0, 0, 0LL); // initial crc if (crccheck) { // Calculate CRC of the body crc = crc64((unsigned char*)m_Body, m_BodySizeToRead, crc); } else { crc = h->crc; } if (crc == h->crc) { // Unpack (deserialize) the Body #if OpenIGTLink_HEADER_VERSION >= 2 UnpackExtendedHeader(); #endif UnpackContent(); #if OpenIGTLink_HEADER_VERSION >= 2 UnpackMetaData(); #endif m_IsBodyUnpacked = true; r |= UNPACK_BODY; } else { m_IsBodyUnpacked = false; } } void MessageBase::AllocateUnpack(int bodySizeToRead) { if (bodySizeToRead <= 0) { bodySizeToRead = 0; m_IsBodyUnpacked = false; } int message_size = IGTL_HEADER_SIZE + bodySizeToRead; if (m_Header == NULL) { // For the first time m_Header = new unsigned char [message_size]; m_IsHeaderUnpacked = false; m_IsBodyUnpacked = false; m_IsBodyPacked = false; } else if (m_MessageSize != message_size) { // If the pack area exists but needs to be reallocated // m_IsHeaderUnpacked status is not changed in this case. unsigned char* old = m_Header; m_Header = new unsigned char [message_size]; memcpy(m_Header, old, std::min(m_MessageSize, message_size)); delete [] old; m_IsBodyUnpacked = false; } m_Body = &m_Header[IGTL_HEADER_SIZE]; #if OpenIGTLink_HEADER_VERSION >= 2 if (m_HeaderVersion >= IGTL_HEADER_VERSION_2) { m_ExtendedHeader = m_Body; // Other members can't be populated until the message is unpacked } else { #endif m_Content = m_Body; #if OpenIGTLink_HEADER_VERSION >= 2 } #endif m_MessageSize = message_size; } int MessageBase::Copy(const MessageBase* mb) { if (this == mb) { return 0; } // Check if the destination (this class) is MessageBase or // the source and destination class are the same type. // The pack size is also checked if it is larger than the header size. if ((m_SendMessageType.length() == 0 || m_SendMessageType == mb->m_ReceiveMessageType) && mb->m_MessageSize >= IGTL_HEADER_SIZE) { // Set the header version before calling any functions, as it determines later behavior m_HeaderVersion = mb->m_HeaderVersion; int bodySize = mb->m_MessageSize - IGTL_HEADER_SIZE; AllocateBuffer(bodySize); CopyHeader(mb); if (bodySize > 0) { CopyBody(mb); } return 1; } else { return 0; } } int MessageBase::SetMessageHeader(const MessageHeader* mb) { return Copy(mb); } int MessageBase::GetBodySizeToRead() { return m_BodySizeToRead; } } openigtlink-3.0.0/Source/igtlMessageBase.h000066400000000000000000000371061501024245700205140ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlMessageBase_h #define __igtlMessageBase_h #include "igtlMacro.h" #include "igtlMath.h" #include "igtlMessageHeader.h" #include "igtlObject.h" #include "igtlObjectFactory.h" #include "igtlTimeStamp.h" #include "igtl_header.h" #include "igtl_types.h" #include #include #include namespace igtl { /// The MessageBase class is the base class of all message type classes /// used in the OpenIGTLink Library. The message classes can be used /// both for serializing (packing) OpenIGTLink message byte streams. /// The class can also deserializing (unpacking) OpenIGTLink. /// For the deserialization example, please refer igtlMessageHeader.h. /// /// The typical packing procedures using sub-classes of /// MessageBase look like the followings /// /// // Create instance and set Device Name /// igtl::TransformMessage::Pointer transMsg; /// transMsg = igtl::TransformMessage::New(); /// transMsg->SetDeviceName("Tracker"); /// /// // Create matrix and substitute values /// igtl::Matrix4x4 matrix; /// GetRandomTestMatrix(matrix); /// /// // Set matrix data, serialize, and send it. /// transMsg->SetMatrix(matrix); /// transMsg->AllocatePack(); // optional /// transMsg->Pack(); /// socket->Send(transMsg->GetBufferPointer(), transMsg->GetBufferSize()); /// /// V1/V2 message structure: /// GetBodySize() /// /-------------------------/\----------------------------------------------------------\ /// GetPackContentSize() (subclassed) /// /-------------------------------------/\----------------------------------------------\ /// |____________|_____________________________________________________________________________________| /// m_Header m_Body /// /// /// V3 message structure: /// GetBodySize() /// /-------------------------/\------------------------------------------------------------\ /// GetPackContentSize() (subclassed) /// /\ (sending after setters are called, receiving after extended header has been parsed) /// /--------/ \-----------\ /// |____________|___________________|________________________|___________________|_______________________| /// m_Header m_ExtendedHeader m_Content (old m_Body) m_MetaDataHeader m_MetaData /// m_Body /// class IGTLCommon_EXPORT MessageBase: public Object { public: typedef MessageBase Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; #if OpenIGTLink_HEADER_VERSION >= 2 // Types for managing meta data typedef std::map > MetaDataMap; #endif igtlTypeMacro(igtl::MessageBase, igtl::Object) igtlNewMacro(igtl::MessageBase); /// Unpack status. They are returned by the Unpack() function. enum { UNPACK_UNDEF = 0x0000, UNPACK_HEADER = 0x0001, UNPACK_BODY = 0x0002 }; public: /// Create a clone of this message, new memory but all internals are preserved virtual igtl::MessageBase::Pointer Clone(); /// Sets the message version number void SetHeaderVersion(unsigned short headerVersion); /// Gets the message version number unsigned short GetHeaderVersion() const; /// Sets the device name. void SetDeviceName(const char* name); /// Sets the device name. void SetDeviceName(const std::string& name); /// Sets the device (message) type. void SetDeviceType(const std::string& type); /// Gets the device name. const char* GetDeviceName(); /// Gets the device name. std::string GetDeviceName() const; /// Gets the device (message) type. const char* GetDeviceType(); #if OpenIGTLink_HEADER_VERSION >= 2 /// Gets the size (length) of the byte array for the meta data. /// The size is defined by the length of each meta data elements and the total number of /// the meta data element. igtlUint32 GetMetaDataSize(); /// Gets the size (length) of the byte array for the meta data header. igtlUint16 GetMetaDataHeaderSize(); /// Gets the message ID igtlUint32 GetMessageID(); /// Sets the message ID void SetMessageID(igtlUint32 idValue); /// Add Meta data element bool SetMetaDataElement(const std::string& key, IANA_ENCODING_TYPE encodingScheme, std::string value); bool SetMetaDataElement(const std::string& key, igtl_uint8); bool SetMetaDataElement(const std::string& key, igtl_int8); bool SetMetaDataElement(const std::string& key, igtl_uint16); bool SetMetaDataElement(const std::string& key, igtl_int16); bool SetMetaDataElement(const std::string& key, igtl_uint32); bool SetMetaDataElement(const std::string& key, igtl_int32); bool SetMetaDataElement(const std::string& key, igtl_uint64); bool SetMetaDataElement(const std::string& key, igtl_int64); bool SetMetaDataElement(const std::string& key, float); bool SetMetaDataElement(const std::string& key, double); /// Get meta data element bool GetMetaDataElement(const std::string& key, std::string& value) const; bool GetMetaDataElement(const std::string& key, IANA_ENCODING_TYPE& encoding, std::string& value) const; /// Get meta data map const MetaDataMap& GetMetaData() const; /// Pack the extended header bool PackExtendedHeader(); /// Pack the meta data bool PackMetaData(); /// Unpack Extended header /// When receiving a message, after the base header is unpacked, the extended header is read /// Once read, the m_MetaDataHeader and m_MetaData members are populated as we now know the message structure bool UnpackExtendedHeader(); /// Unpack Extended header and the meta data bool UnpackMetaData(); #endif /// Sets time of message creation. 'sec' and 'frac' are seconds and fractions of a second respectively. int SetTimeStamp(unsigned int sec, unsigned int frac); /// Gets time of message creation. 'sec' and 'frac' are seconds and fractions of a second respectively. int GetTimeStamp(unsigned int* sec, unsigned int* frac); /// Sets time of message creation. void SetTimeStamp(igtl::TimeStamp::Pointer& ts); /// Gets time of message creation. void GetTimeStamp(igtl::TimeStamp::Pointer& ts); /// Pack() serializes the header and body based on the member variables. /// PackContent() must be implemented in the child class. virtual int Pack(); /// Unpack() deserializes the header and/or body, extracting data from /// the byte stream. If the header has already been deserilized, Unpack() /// deserializes only the body part. UnpackBody() must be implemented to /// deserialize the body part. Unpack() performs 64-bit CRC check, /// when crccheck = 1. It returns: /// /// UNPACK_UNDEF : Nothing deserialized /// UNPACK_HEADER : The header has been deserialized. /// UNPACK_BODY : The body has been deserialized. /// If CRC check fails, Unpack() doesn't /// deserialize the body, thus it doesn't /// return UNPACK_BODY flag. /// UNPACK_HEADER|UNPACK_BODY: Both the header and body have been /// deserialized int Unpack(int crccheck = 0); /// Gets a pointer to the raw byte array for the serialized data including the header and the body. void* GetBufferPointer(); void* GetPackPointer() { return GetBufferPointer(); } /// Gets a pointer to the raw byte array for the serialized body data. void* GetBufferBodyPointer(); void* GetPackBodyPointer() { return GetBufferBodyPointer(); } /// Gets the size of the serialized message data. int GetBufferSize(); int GetPackSize() { return GetBufferSize(); } /// Gets the size of the serialized body data. int GetBufferBodySize(); int GetPackBodySize() { return GetBufferBodySize(); } /// Calculate the size of the received content data /// Returns -1 if the extended header has not been properly initialized (meta data size, meta data header size, etc...) /// Used when receiving data, not sending int CalculateReceiveContentSize(); /// Gets the type of the body. const char* GetBodyType(); /// Gets the message type. std::string GetMessageType() const; /// AllocatePack() allocates memory for underlying buffer /// If m_BodySizeToRead > 0, we are allocating for receiving a message void AllocateBuffer(); void AllocatePack() { AllocateBuffer(); } /// Call InitPack() before receive header. /// This function simply resets the Unpacked flag for both /// the header and body pack /// Only allocate the original 58 byte header void InitBuffer(); void InitPack() { InitBuffer(); } /// Copy() copies contents from the specified Massage class. /// If the type of the specified class is the same as this class, /// general header and body are copied. int Copy(const MessageBase* mb); /// Sets the message header. virtual int SetMessageHeader(const MessageHeader* mb); /// GetBodySizeToRead() returns the size of the body to be read. This function must be called /// after the message header is set. int GetBodySizeToRead(); protected: MessageBase(); ~MessageBase(); protected: /// Gets the size of the serialized content. virtual int CalculateContentBufferSize(); /// Packs (serialize) the content. Must be implemented in all child classes. virtual int PackContent(); /// Unpacks (deserialize) the content. Must be implemented in all child classes. virtual int UnpackContent(); /// Allocates memory specifying the content size. /// Implicitly allocates extended header, metadata header and metadata in addition to content virtual void AllocateBuffer(int contentSize); /// Allocates memory specifying the unpack content size /// Size of body to allocate is determined from v1 message header field 'body_size' virtual void AllocateUnpack(int bodySizeToRead); /// Copies the serialized body data int CopyBody(const MessageBase* mb); /// Copies a header from given message int CopyHeader(const MessageBase* mb); /// Unpack the first 58 bytes void UnpackHeader(int& r); /// Unpack the body /// If it's a v3 message, body is ext header + content + metadataheader + metadata void UnpackBody(int crccheck, int& r); protected: int m_MessageSize; /// A pointer to the byte array for the serialized header. To prevent large /// copy of the byte array in the Pack() function, header byte array is /// concatenated to the byte array for the body. unsigned char* m_Header; /// A pointer to the byte array for the serialized body. To prevent large /// copy of the byte array in the Pack() function, header byte array is /// concatenated to the byte array for the header. unsigned char* m_Body; /// A pointer to the underlying content of a message unsigned char* m_Content; /// The size of the body to be read. This function must be called /// after the message header is set. int m_BodySizeToRead; /// A character string for the send device type (message type). std::string m_SendMessageType; /// A character string for the device type (message type). This will be used when the header /// is deserialized from a byte stream received from the network. std::string m_ReceiveMessageType; /// An unsigned short for the message format version unsigned short m_HeaderVersion; /// A character string for the device name (message name). std::string m_DeviceName; /// A time stamp (second) for message creation. It consists of fields for seconds /// (m_TimeStampSec)and fractions of a second (m_TimeStampSecFraction). unsigned int m_TimeStampSec; /// A time stamp (second) for message creation. It consists of fields for seconds /// (m_TimeStampSec)and fractions of a second (m_TimeStampSecFraction). unsigned int m_TimeStampSecFraction; /// Unpacking (deserialization) status for the header bool m_IsHeaderUnpacked; /// Unpacking (deserialization) status for the body bool m_IsBodyUnpacked; /// Packing (serialization) status for the body bool m_IsBodyPacked; #if OpenIGTLink_HEADER_VERSION >= 2 protected: /// A pointer to the serialized extended header. unsigned char* m_ExtendedHeader; /// A flag to record the unpacked state of the extended header bool m_IsExtendedHeaderUnpacked; /// A pointer to the meta data. unsigned char* m_MetaData; /// A pointer to the meta data header. unsigned char* m_MetaDataHeader; /// Message ID igtlUint32 m_MessageId; /// Map storing the key value pairs MetaDataMap m_MetaDataMap; #endif // if OpenIGTLink_HEADER_VERSION >= 2 }; /// A class for header-only message types, which are used for querying. class IGTLCommon_EXPORT HeaderOnlyMessageBase: public MessageBase { public: typedef HeaderOnlyMessageBase Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::HeaderOnlyMessageBase, igtl::MessageBase); igtlNewMacro(igtl::HeaderOnlyMessageBase); protected: HeaderOnlyMessageBase() { this->m_SendMessageType = ""; }; ~HeaderOnlyMessageBase() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// A macro to help defining a class for query message types /// that do not have message bodies. // TODO: Need test. #define igtlCreateDefaultQueryMessageClass(name, msgtype) \ class IGTLCommon_EXPORT name : public HeaderOnlyMessageBase\ { \ public: \ typedef name Self; \ typedef HeaderOnlyMessageBase Superclass; \ typedef SmartPointer Pointer; \ typedef SmartPointer ConstPointer; \ \ igtlTypeMacro(igtl::name, igtl::HeaderOnlyMessageBase); \ igtlNewMacro(igtl::name); \ \ protected: \ name() : HeaderOnlyMessageBase() { this->m_SendMessageType = msgtype; }; \ ~name() {}; \ }; } // namespace igtl #endif // _igtlMessageBase_h openigtlink-3.0.0/Source/igtlMessageDebugFunction.h000066400000000000000000000034051501024245700223710ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igltMessageDebugFunction_h #define __igltMessageDebugFunction_h #define ABS_ERROR 1e-6 void TestDebugCharArrayCmp(void* inputPointer, unsigned char* inputArray, int size) { for (int i = 0 ; i< size;++i) { std::cerr< +0.0f ? tol:-tol; for(int i=0;i < 4; i++) { for(int j=0;j < 4; j++) { if((outMatrix[i][j] - inMatrix[i][j]) > tol || (outMatrix[i][j] - inMatrix[i][j]) < -tol) { equal = false; } } } return equal; } bool ArrayFloatComparison(float returnArray[], float inArray[], int size, float tol) { bool equal = true; tol = tol > +0.0f ? tol:-tol; for(int j=0;j < size; j++) { if((returnArray[j] - inArray[j]) > tol || (returnArray[j] - inArray[j]) < -tol) { equal = false; } } return equal; } #endif // __igltOSUtil_h openigtlink-3.0.0/Source/igtlMessageFactory.cxx000066400000000000000000000244701501024245700216240ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlMessageFactory.h" #include "igtlTransformMessage.h" #include "igtlPositionMessage.h" #include "igtlImageMessage.h" #include "igtlClientSocket.h" #include "igtlStatusMessage.h" #include "igtlCapabilityMessage.h" #if OpenIGTLink_PROTOCOL_VERSION >= 2 #include "igtlPointMessage.h" #include "igtlTrajectoryMessage.h" #include "igtlStringMessage.h" #include "igtlTrackingDataMessage.h" #include "igtlQuaternionTrackingDataMessage.h" #endif // OpenIGTLink_PROTOCOL_VERSION >= 2 #if OpenIGTLink_HEADER_VERSION >= 2 #include "igtlCommandMessage.h" #endif // OpenIGTLink_PROTOCOL_VERSION >= 3 #include "igtl_header.h" #include #include #include #include #include namespace igtl { //----------------------------------------------------------------------------- MessageFactory::MessageFactory() { this->AddMessageType("TRANSFORM", (PointerToMessageBaseNew)&igtl::TransformMessage::New); this->AddMessageType("GET_TRANS", (PointerToMessageBaseNew)&igtl::GetTransformMessage::New); this->AddMessageType("POSITION", (PointerToMessageBaseNew)&igtl::PositionMessage::New); this->AddMessageType("IMAGE", (PointerToMessageBaseNew)&igtl::ImageMessage::New); this->AddMessageType("GET_IMAGE", (PointerToMessageBaseNew)&igtl::GetImageMessage::New); this->AddMessageType("STATUS", (PointerToMessageBaseNew)&igtl::StatusMessage::New); this->AddMessageType("GET_STATUS", (PointerToMessageBaseNew)&igtl::GetStatusMessage::New); this->AddMessageType("CAPABILITY", (PointerToMessageBaseNew)&igtl::CapabilityMessage::New); #if OpenIGTLink_PROTOCOL_VERSION >= 2 this->AddMessageType("POINT", (PointerToMessageBaseNew)&igtl::PointMessage::New); this->AddMessageType("GET_POINT", (PointerToMessageBaseNew)&igtl::GetPointMessage::New); this->AddMessageType("TRAJ", (PointerToMessageBaseNew)&igtl::TrajectoryMessage::New); this->AddMessageType("GET_TRAJ", (PointerToMessageBaseNew)&igtl::GetTrajectoryMessage::New); this->AddMessageType("STRING", (PointerToMessageBaseNew)&igtl::StringMessage::New); this->AddMessageType("TDATA", (PointerToMessageBaseNew)&igtl::TrackingDataMessage::New); this->AddMessageType("RTS_TDATA", (PointerToMessageBaseNew)&igtl::RTSTrackingDataMessage::New); this->AddMessageType("STT_TDATA", (PointerToMessageBaseNew)&igtl::StartTrackingDataMessage::New); this->AddMessageType("STP_TDATA", (PointerToMessageBaseNew)&igtl::StopTrackingDataMessage::New); this->AddMessageType("QTDATA", (PointerToMessageBaseNew)&igtl::QuaternionTrackingDataMessage::New); this->AddMessageType("RTS_QTDATA", (PointerToMessageBaseNew)&igtl::RTSQuaternionTrackingDataMessage::New); this->AddMessageType("STT_QTDATA", (PointerToMessageBaseNew)&igtl::StartQuaternionTrackingDataMessage::New); this->AddMessageType("STP_QTDATA", (PointerToMessageBaseNew)&igtl::StopQuaternionTrackingDataMessage::New); #endif #if OpenIGTLink_PROTOCOL_VERSION >= 3 this->AddMessageType("COMMAND", (PointerToMessageBaseNew)&igtl::CommandMessage::New); this->AddMessageType("RTS_COMMAND", (PointerToMessageBaseNew)&igtl::RTSCommandMessage::New); #endif } //----------------------------------------------------------------------------- MessageFactory::~MessageFactory() { } //----------------------------------------------------------------------------- void MessageFactory::AddMessageType(const std::string& messageTypeName, MessageFactory::PointerToMessageBaseNew messageTypeNewPointer ) { this->IgtlMessageTypes[messageTypeName] = messageTypeNewPointer; } //---------------------------------------------------------------------------- MessageFactory::PointerToMessageBaseNew MessageFactory::GetMessageTypeNewPointer(const std::string& messageTypeName) const { if ( this->IgtlMessageTypes.find(messageTypeName) != this->IgtlMessageTypes.end() ) { return this->IgtlMessageTypes.find(messageTypeName)->second; } std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", unknown message type constructor requested." << std::endl; throw std::invalid_argument(oss.str()); return NULL; } //----------------------------------------------------------------------------- bool MessageFactory::IsValid(igtl::MessageHeader::Pointer headerMsg) { bool result = false; #if OpenIGTLink_HEADER_VERSION >= 2 if (headerMsg.IsNotNull() && IgtlMessageTypes.find(headerMsg->GetMessageType()) != IgtlMessageTypes.end() ) #else if (headerMsg.IsNotNull() && IgtlMessageTypes.find(headerMsg->GetDeviceType()) != IgtlMessageTypes.end()) #endif { result = true; } return result; } //---------------------------------------------------------------------------- bool MessageFactory::IsValid(igtl::MessageHeader::Pointer headerMsg) const { bool result = false; #if OpenIGTLink_HEADER_VERSION >= 2 if (headerMsg.IsNotNull() && IgtlMessageTypes.find(headerMsg->GetMessageType()) != IgtlMessageTypes.end() ) #else if (headerMsg.IsNotNull() && IgtlMessageTypes.find(headerMsg->GetDeviceType()) != IgtlMessageTypes.end()) #endif { result = true; } return result; } //----------------------------------------------------------------------------- igtl::MessageBase::Pointer MessageFactory::GetMessage(igtl::MessageHeader::Pointer headerMsg) { if (headerMsg.IsNull()) { std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", header is NULL." << std::endl; throw std::invalid_argument(oss.str()); } #if OpenIGTLink_HEADER_VERSION >= 2 std::string messageType(headerMsg->GetMessageType()); #else std::string messageType(headerMsg->GetDeviceType()); #endif if (!this->IsValid(headerMsg)) { std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", receiving message of type:" << messageType << std::endl; throw std::invalid_argument(oss.str()); } std::string messageTypeUpper(messageType); std::transform(messageTypeUpper.begin(), messageTypeUpper.end(), messageTypeUpper.begin(), ::toupper); igtl::MessageBase::Pointer result = NULL; if( GetMessageTypeNewPointer(messageTypeUpper) == NULL ) { std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", unable to create message of type:" << messageTypeUpper << std::endl; throw std::invalid_argument(oss.str()); } result = GetMessageTypeNewPointer(messageTypeUpper)(); // Must have a valid message at this point, otherwise its a programming bug. assert(result.IsNotNull()); result->SetMessageHeader(headerMsg); result->InitBuffer(); return result; } //---------------------------------------------------------------------------- igtl::MessageHeader::Pointer MessageFactory::CreateHeaderMessage(int headerVersion) const { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->SetHeaderVersion(headerVersion); headerMsg->InitBuffer(); return headerMsg; } //---------------------------------------------------------------------------- igtl::MessageBase::Pointer MessageFactory::CreateReceiveMessage(igtl::MessageHeader::Pointer headerMsg) const { if (headerMsg.IsNull()) { std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", header is NULL." << std::endl; throw std::invalid_argument(oss.str()); } #if OpenIGTLink_HEADER_VERSION >= 2 std::string messageType(headerMsg->GetMessageType()); #else std::string messageType(headerMsg->GetDeviceType()); #endif std::string messageTypeUpper(messageType); std::transform(messageTypeUpper.begin(), messageTypeUpper.end(), messageTypeUpper.begin(), ::toupper); if (!this->IsValid(headerMsg)) { std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", receiving message of type:" << messageTypeUpper << std::endl; throw std::invalid_argument(oss.str()); } igtl::MessageBase::Pointer result = NULL; if( GetMessageTypeNewPointer(messageTypeUpper) == NULL ) { std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", unable to create message of type:" << messageTypeUpper << std::endl; throw std::invalid_argument(oss.str()); } result = GetMessageTypeNewPointer(messageTypeUpper)(); // Must have a valid message at this point, otherwise its a programming bug. assert(result.IsNotNull()); result->SetMessageHeader(headerMsg); result->AllocateBuffer(); return result; } //---------------------------------------------------------------------------- igtl::MessageBase::Pointer MessageFactory::CreateSendMessage(const std::string& messageType, int headerVersion) const { if (messageType.empty()) { std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", message type is undefined." << std::endl; throw std::invalid_argument(oss.str()); } std::string messageTypeUpper(messageType); std::transform(messageTypeUpper.begin(), messageTypeUpper.end(), messageTypeUpper.begin(), ::toupper); igtl::MessageBase::Pointer result = NULL; if( GetMessageTypeNewPointer(messageTypeUpper) == NULL ) { std::ostringstream oss; oss << "Error: In " __FILE__ ", line " << __LINE__ << ", unable to create message of type:" << messageTypeUpper << std::endl; throw std::invalid_argument(oss.str()); } result = GetMessageTypeNewPointer(messageTypeUpper)(); // Must have a valid message at this point, otherwise its a programming bug. assert(result.IsNotNull()); result->SetDeviceType(messageTypeUpper); result->SetHeaderVersion(headerVersion); result->InitBuffer(); return result; } //---------------------------------------------------------------------------- void MessageFactory::GetAvailableMessageTypes(std::vector& types) const { types.clear(); for( std::map::const_iterator it = IgtlMessageTypes.begin(); it != IgtlMessageTypes.end(); ++it ) { types.push_back(it->first); } return; } } // end namespace openigtlink-3.0.0/Source/igtlMessageFactory.h000066400000000000000000000102531501024245700212430ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlMessageFactory_h #define __igtlMessageFactory_h #include "igtlMacro.h" #include "igtlMessageBase.h" #include "igtlMessageHeader.h" #include "igtlObject.h" #include "igtl_header.h" #include namespace igtl { class IGTLCommon_EXPORT MessageFactory: public Object { public: typedef MessageFactory Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(MessageFactory, Object) igtlNewMacro(MessageFactory); /*! Function pointer for storing New() static methods of igtl::MessageBase classes */ typedef igtl::MessageBase::Pointer (*PointerToMessageBaseNew)(); /// Add message type name and pointer to IGTL message new function /// Usage: AddMessageType( "IMAGE", (PointerToMessageBaseNew)&igtl::ImageMessage::New ); /// \param messageTypeName The name of the message type /// \param messageTypeNewPointer Function pointer to the message type new function (e.g. (PointerToMessageBaseNew)&igtl::ImageMessage::New ) virtual void AddMessageType(const std::string& messageTypeName, MessageFactory::PointerToMessageBaseNew messageTypeNewPointer); /// Get pointer to message type new function, or NULL if the message type not registered /// Usage: igtl::MessageBase::Pointer message = GetMessageTypeNewPointer("IMAGE")(); /// Throws invalid_argument if message type is not found virtual MessageFactory::PointerToMessageBaseNew GetMessageTypeNewPointer(const std::string& messageTypeName) const; /// Checks that headerMsg is not null and the headerMsg->GetDeviceType() refers to a valid type, returning true if valid, and false otherwise. bool IsValid(igtl::MessageHeader::Pointer headerMsg); /// Checks that headerMsg is not null and the headerMsg->GetDeviceType() refers to a valid type, returning true if valid, and false otherwise. bool IsValid(igtl::MessageHeader::Pointer headerMsg) const; /// LEGACY method, use CreateReceiveMessage instead /// Constructs a message from the given header. /// Throws invalid_argument if headerMsg is NULL. /// Throws invalid_argument if this->IsValid(headerMsg) returns false. /// Creates message, sets header onto message and calls AllocateBuffer() on the message. igtl::MessageBase::Pointer GetMessage(igtl::MessageHeader::Pointer headerMsg); /// Constructs a message header. /// Throws invalid_argument if headerMsg is NULL. /// Throws invalid_argument if this->IsValid(headerMsg) returns false. /// Creates message, calls InitBuffer() igtl::MessageHeader::Pointer CreateHeaderMessage(int headerVersion) const; /// Constructs a message from the given populated header. /// Throws invalid_argument if headerMsg is NULL. /// Throws invalid_argument if this->IsValid(headerMsg) returns false. /// Creates message, sets header onto message and calls AllocatePack() on the message. igtl::MessageBase::Pointer CreateReceiveMessage(igtl::MessageHeader::Pointer headerMsg) const; /// Constructs an empty message from the given message type. /// Throws invalid_argument if messageType is empty. /// Creates message, sets header onto message and calls AllocatePack() on the message. igtl::MessageBase::Pointer CreateSendMessage(const std::string& messageType, int headerVersion) const; /// Return the list of known message types void GetAvailableMessageTypes(std::vector& types) const; protected: MessageFactory(); ~MessageFactory(); private: /*! Map igt message types and the New() static methods of igtl::MessageBase classes */ std::map IgtlMessageTypes; }; // end class } // end namespace #endif // __igtlMessageFactory_h openigtlink-3.0.0/Source/igtlMessageHandler.h000066400000000000000000000030771501024245700212170ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: git@github.com:openigtlink/OpenIGTLink.git Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlMessageHandler_h #define __igtlMessageHandler_h #include "igtlObject.h" #include "igtlMacro.h" #include "igtlSocket.h" #include "igtlMessageBase.h" namespace igtl { class IGTLCommon_EXPORT MessageHandler: public Object { public: typedef MessageHandler Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::MessageHandler, igtl::Object) igtlNewMacro(igtl::MessageHandler); public: virtual const char* GetMessageType() { return ""; } #if OpenIGTLink_HEADER_VERSION >= 2 virtual std::string GetMessageType() const { return std::string(""); } #endif virtual int ReceiveMessage(Socket*, MessageBase*, int) { return 0; }; void SetMessageBuffer(MessageBase* buffer) { this->m_Buffer = buffer; } MessageBase * GetMessageBuffer() { return this->m_Buffer; } protected: MessageHandler() {} ~MessageHandler() {} protected: MessageBase * m_Buffer; }; } // namespace igtl #endif // _igtlMessageHandler_h openigtlink-3.0.0/Source/igtlMessageHandlerMacro.h000066400000000000000000000305031501024245700221730ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: git@github.com:openigtlink/OpenIGTLink.git Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlMessageHandlerMacro_h #define __igtlMessageHandlerMacro_h #include "igtlMessageHandler.h" // Description: // The igtlMessageHandlerClassMacro() macro is to help developers to // define message handler class. It generates a child class of igtl::MessageHandler. // The developer only needs to implement ProcessMessage() after calling this macro. // The following code shows how to define a handler that processes IMAGE message: // // igtlMessageHandlerClassMacro(igtl::ImageMessage, TestImageMessageHandler); // void TestImageMessageHandler::Process(igtl::ImageMessage * message) // { // // do something // } #if OpenIGTLink_PROTOCOL_VERSION >= 3 #define igtlMessageHandlerClassMacro(messagetype, classname, datatype) \ class classname : public ::igtl::MessageHandler \ { \ public: \ typedef classname Self; \ typedef ::igtl::MessageHandler Superclass; \ typedef igtl::SmartPointer Pointer; \ typedef igtl::SmartPointer ConstPointer; \ igtlTypeMacro(classname, ::igtl::MessageHandler); \ igtlNewMacro(classname); \ public: \ virtual const char* GetMessageType() \ { \ return this->m_Message->GetDeviceType(); \ } \ virtual int Process(messagetype*, datatype*); \ int ReceiveMessage(::igtl::Socket* socket, ::igtl::MessageBase* header, int pos) \ { \ if (pos == 0) /* New body */ \ { \ this->m_Message->SetMessageHeader(header); \ this->m_Message->InitBuffer(); \ } \ int s = socket->Receive((void*)((char*)this->m_Message->GetBufferBodyPointer()+pos), \ this->m_Message->GetBufferBodySize()-pos); \ if (s < 0) /* Time out */ \ { \ return pos; \ } \ if (s+pos >= this->m_Message->GetBufferBodySize()) \ { \ int r = this->m_Message->Unpack(this->m_CheckCRC); \ if (r) \ { \ Process(this->m_Message, this->m_Data); \ } \ else \ { \ return -1; \ } \ } \ return s + pos; /* return current position in the body */ \ } \ virtual void CheckCRC(int i) \ { \ if (i == 0) \ { \ this->m_CheckCRC = 0; \ } \ else \ { \ this->m_CheckCRC = 1; \ } \ } \ void SetData(datatype* p) \ { \ this->m_Data = p; \ } \ datatype* GetData() \ { \ return this->m_Data; \ } \ protected: \ classname() \ { \ this->m_Message = messagetype::New(); \ this->m_CheckCRC = 1; \ this->m_Data = NULL; \ } \ ~classname() {} \ protected: \ int m_CheckCRC; \ messagetype::Pointer m_Message; \ datatype* m_Data; \ }; #else #define igtlMessageHandlerClassMacro(messagetype, classname, datatype) \ class classname : public ::igtl::MessageHandler \ { \ public: \ typedef classname Self; \ typedef ::igtl::MessageHandler Superclass; \ typedef igtl::SmartPointer Pointer; \ typedef igtl::SmartPointer ConstPointer; \ igtlTypeMacro(classname, ::igtl::MessageHandler); \ igtlNewMacro(classname); \ public: \ virtual std::string GetMessageType() const \ { \ return this->m_Message->GetMessageType(); \ } \ virtual const char* GetMessageType() \ { \ return this->m_Message->GetType(); \ } \ virtual const char* GetMessageType() \ { \ return this->m_Message->GetDeviceType(); \ } \ virtual int Process(messagetype*, datatype*); \ int ReceiveMessage(::igtl::Socket* socket, ::igtl::MessageBase* header, int pos) \ { \ if (pos == 0) /* New body */ \ { \ this->m_Message->SetMessageHeader(header); \ this->m_Message->AllocateBuffer(); \ } \ int s = socket->Receive((void*)((char*)this->m_Message->GetBufferBodyPointer()+pos), \ this->m_Message->GetBufferBodySize()-pos); \ if (s < 0) /* Time out */ \ { \ return pos; \ } \ if (s+pos >= this->m_Message->GetBufferBodySize()) \ { \ int r = this->m_Message->Unpack(this->m_CheckCRC); \ if (r) \ { \ Process(this->m_Message, this->m_Data); \ } \ else \ { \ return -1; \ } \ } \ return s + pos; /* return current position in the body */ \ } \ virtual void CheckCRC(int i) \ { \ if (i == 0) \ { \ this->m_CheckCRC = 0; \ } \ else \ { \ this->m_CheckCRC = 1; \ } \ } \ void SetData(datatype* p) \ { \ this->m_Data = p; \ } \ datatype* GetData() \ { \ return this->m_Data; \ } \ protected: \ classname() \ { \ this->m_Message = messagetype::New(); \ this->m_CheckCRC = 1; \ this->m_Data = NULL; \ } \ ~classname() {} \ protected: \ int m_CheckCRC; \ messagetype::Pointer m_Message; \ datatype* m_Data; \ }; #endif #endif // __igtlMessageHandlerMacro_h openigtlink-3.0.0/Source/igtlMessageHeader.h000066400000000000000000000051551501024245700210310ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlMessageHeader_h #define __igtlMessageHeader_h namespace igtl { /// The MessageHeader class is used to receive and parse general headers /// to prepare for receiving body data. The class is currently just the alias /// of MessageBase class. Please refer igtlMessageBase.h for more details and /// the implementation of the class. /// /// The following is the typical unpacking (deserialization) procedures /// using igtl::MessssageHeader class: /// /// // Create instance and set Device Name /// igtl::MessageBase::Pointer headerMsg; /// headerMsg = igtl::MessageBase::New(); /// /// // Initialize receive buffer /// // Set up memory area to and receive the general header and unpack /// headerMsg->InitPack(); /// /// socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); /// headerMsg->Unpack(); /// /// // Check data type string /// if (strcmp(headerMsg->GetDeviceType(), "TRANSFORM")) /// { /// igtl::TransformMessage::Pointer transMsg; /// transMsg = igtl::TransformMessage::New(); /// transMsg->SetMessageHeader(headerMsg); /// transMsg->AllocatePack(); /// /// // Receive transform data from the socket// /// socket->Receive(transMsg->GetPackBodyPointer(), transMsg->GetPackBodySize()); /// /// // Deserialize the transform data /// transMsg->Unpack(); /// /// // Retrive the transform data /// igtl::Matrix4x4 matrix; /// transMsg->GetMatrix(matrix); /// /// .... /// /// } /// else if (strcmp(headerMsg->GetDeviceType(), "IMAGE")) /// { /// igtl::ImageMessage::Pointer imageMsg; /// imageMsg = igtl::ImageMessage::New(); /// transMsg->SetMessageHeader(headerMsg); /// imageMsg->AllocatePack(); /// socket->Receive(imageMsg->GetPackBodyPointer(), imageMsg->GetPackBodySize()); /// imageMsg->Unpack(); /// } /// else if (...) /// { /// ... /// } class MessageBase; typedef class MessageBase MessageHeader; }; #include "igtlMessageBase.h" #endif //__igtlMessageHeader_h openigtlink-3.0.0/Source/igtlMultiThreader.cxx000066400000000000000000000634201501024245700214570ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkMultiThreader.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #ifdef _WIN32 #pragma warning ( disable : 4786 ) #include "igtlWindows.h" #include #endif #include "igtlMultiThreader.h" #include "igtlMutexLock.h" #include "igtlObjectFactory.h" // These are the includes necessary for multithreaded rendering on an SGI // using the sproc() call #ifdef OpenIGTLink_USE_SPROC #include #include #include #include #endif #ifdef OpenIGTLink_USE_PTHREADS #include #endif // Need to define "igtlExternCThreadFunctionType" to avoid warning on some // platforms about passing function pointer to an argument expecting an // extern "C" function. Placing the typedef of the function pointer type // inside an extern "C" block solves this problem. #if defined(OpenIGTLink_USE_PTHREADS) || defined(OpenIGTLink_HP_PTHREADS) #include extern "C" { typedef void *(*igtlExternCThreadFunctionType)(void *); } #else //typedef igtlThreadFunctionType igtlExternCThreadFunctionType; #endif #ifdef __APPLE__ #include #include #endif namespace igtl { // Initialize static member that controls global maximum number of threads static int MultiThreaderGlobalMaximumNumberOfThreads = 0; void MultiThreader::SetGlobalMaximumNumberOfThreads(int val) { if (val == MultiThreaderGlobalMaximumNumberOfThreads) { return; } MultiThreaderGlobalMaximumNumberOfThreads = val; } int MultiThreader::GetGlobalMaximumNumberOfThreads() { return MultiThreaderGlobalMaximumNumberOfThreads; } // 0 => Not initialized. static int MultiThreaderGlobalDefaultNumberOfThreads = 0; void MultiThreader::SetGlobalDefaultNumberOfThreads(int val) { if (val == MultiThreaderGlobalDefaultNumberOfThreads) { return; } MultiThreaderGlobalDefaultNumberOfThreads = val; } int MultiThreader::GetGlobalDefaultNumberOfThreads() { if (MultiThreaderGlobalDefaultNumberOfThreads == 0) { int num = 1; // default is 1 #ifdef OpenIGTLink_USE_SPROC // Default the number of threads to be the number of available // processors if we are using sproc() num = prctl( PR_MAXPPROCS ); #endif #ifdef OpenIGTLink_USE_PTHREADS // Default the number of threads to be the number of available // processors if we are using pthreads() #ifdef _SC_NPROCESSORS_ONLN num = sysconf( _SC_NPROCESSORS_ONLN ); #elif defined(_SC_NPROC_ONLN) num = sysconf( _SC_NPROC_ONLN ); #endif #if defined(__SVR4) && defined(sun) && defined(PTHREAD_MUTEX_NORMAL) pthread_setconcurrency(num); #endif #endif #ifdef __APPLE__ // Use sysctl() to determine the number of CPUs. This is prefered // over MPProcessors() because it doesn't require CoreServices // (which is only available in 32bit on Mac OS X 10.4) int mib[2] = {CTL_HW, HW_NCPU}; size_t dataLen = sizeof(int); // 'num' is an 'int' int result = sysctl(mib, 2, &num, &dataLen, NULL, 0); if (result == -1) { num = 1; } #endif #ifdef _WIN32 { SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); num = sysInfo.dwNumberOfProcessors; } #endif #ifndef OpenIGTLink_USE_WIN32_THREADS #ifndef OpenIGTLink_USE_SPROC #ifndef OpenIGTLink_USE_PTHREADS // If we are not multithreading, the number of threads should // always be 1 num = 1; #endif #endif #endif // Lets limit the number of threads to IGTL_MAX_THREADS if (num > IGTL_MAX_THREADS) { num = IGTL_MAX_THREADS; } MultiThreaderGlobalDefaultNumberOfThreads = num; } return MultiThreaderGlobalDefaultNumberOfThreads; } // Constructor. Default all the methods to NULL. Since the // ThreadInfoArray is static, the ThreadIDs can be initialized here // and will not change. MultiThreader::MultiThreader() { int i; for ( i = 0; i < IGTL_MAX_THREADS; i++ ) { this->m_ThreadInfoArray[i].ThreadID = i; this->m_ThreadInfoArray[i].ActiveFlag = NULL; this->m_ThreadInfoArray[i].ActiveFlagLock = NULL; this->m_MultipleMethod[i] = NULL; this->m_SpawnedThreadActiveFlag[i] = 0; this->m_SpawnedThreadActiveFlagLock[i] = NULL; this->m_SpawnedThreadInfoArray[i].ThreadID = i; } this->m_SingleMethod = NULL; this->m_NumberOfThreads = MultiThreader::GetGlobalDefaultNumberOfThreads(); } // Destructor. Nothing allocated so nothing needs to be done here. MultiThreader::~MultiThreader() { } //---------------------------------------------------------------------------- int MultiThreader::GetNumberOfThreads() { int num = this->m_NumberOfThreads; if(MultiThreaderGlobalMaximumNumberOfThreads > 0 && num > MultiThreaderGlobalMaximumNumberOfThreads) { num = MultiThreaderGlobalMaximumNumberOfThreads; } return num; } // Set the user defined method that will be run on NumberOfThreads threads // when m_SingleMethodExecute is called. void MultiThreader::SetSingleMethod( ThreadFunctionType f, void *data ) { this->m_SingleMethod = f; this->m_SingleData = data; } // Set one of the user defined methods that will be run on NumberOfThreads // threads when m_MultipleMethodExecute is called. This method should be // called with index = 0, 1, .., NumberOfThreads-1 to set up all the // required user defined methods void MultiThreader::SetMultipleMethod( int index, ThreadFunctionType f, void *data ) { // You can only set the method for 0 through NumberOfThreads-1 if ( index >= this->m_NumberOfThreads ) { igtlErrorMacro( << "Can't set method " << index << " with a thread count of " << this->m_NumberOfThreads ); } else { this->m_MultipleMethod[index] = f; this->m_MultipleData[index] = data; } } // Execute the method set as the SingleMethod on NumberOfThreads threads. void MultiThreader::SingleMethodExecute() { int thread_loop = 0; #ifdef OpenIGTLink_USE_WIN32_THREADS DWORD threadId; HANDLE process_id[IGTL_MAX_THREADS]; #endif #ifdef OpenIGTLink_USE_SPROC siginfo_t info_ptr; int process_id[IGTL_MAX_THREADS]; #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_t process_id[IGTL_MAX_THREADS]; #endif if ( !this->m_SingleMethod ) { igtlErrorMacro( << "No single method set!" ); return; } // obey the global maximum number of threads limit if (MultiThreaderGlobalMaximumNumberOfThreads && this->m_NumberOfThreads > MultiThreaderGlobalMaximumNumberOfThreads) { this->m_NumberOfThreads = MultiThreaderGlobalMaximumNumberOfThreads; } // We are using sproc (on SGIs), pthreads(on Suns), or a single thread // (the default) #ifdef OpenIGTLink_USE_WIN32_THREADS // Using CreateThread on a PC // // We want to use CreateThread to start this->m_NumberOfThreads - 1 // additional threads which will be used to call this->SingleMethod(). // The parent thread will also call this routine. When it is done, // it will wait for all the children to finish. // // First, start up the this->m_NumberOfThreads-1 processes. Keep track // of their process ids for use later in the waitid call for (thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { this->m_ThreadInfoArray[thread_loop].UserData = this->m_SingleData; this->m_ThreadInfoArray[thread_loop].NumberOfThreads = this->m_NumberOfThreads; process_id[thread_loop] = CreateThread(NULL, 0, this->m_SingleMethod, ((void *)(&this->m_ThreadInfoArray[thread_loop])), 0, &threadId); if (process_id[thread_loop] == NULL) { igtlErrorMacro("Error in thread creation !!!"); } } // Now, the parent thread calls this->SingleMethod() itself this->m_ThreadInfoArray[0].UserData = this->m_SingleData; this->m_ThreadInfoArray[0].NumberOfThreads = this->m_NumberOfThreads; this->m_SingleMethod((void *)(&this->m_ThreadInfoArray[0])); // The parent thread has finished this->SingleMethod() - so now it // waits for each of the other processes to exit for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { WaitForSingleObject(process_id[thread_loop], INFINITE); } // close the threads for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { CloseHandle(process_id[thread_loop]); } #endif #ifdef OpenIGTLink_USE_SPROC // Using sproc() on an SGI // // We want to use sproc to start this->m_NumberOfThreads - 1 additional // threads which will be used to call this->SingleMethod(). The // parent thread will also call this routine. When it is done, // it will wait for all the children to finish. // // First, start up the this->m_NumberOfThreads-1 processes. Keep track // of their process ids for use later in the waitid call for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { this->m_ThreadInfoArray[thread_loop].UserData = this->m_SingleData; this->m_ThreadInfoArray[thread_loop].NumberOfThreads = this->m_NumberOfThreads; process_id[thread_loop] = sproc( this->m_SingleMethod, PR_SADDR, ( (void *)(&this->m_ThreadInfoArray[thread_loop]) ) ); if ( process_id[thread_loop] == -1) { igtlErrorMacro("sproc call failed. Code: " << errno << endl); } } // Now, the parent thread calls this->m_SingleMethod() itself this->m_ThreadInfoArray[0].UserData = this->m_SingleData; this->m_ThreadInfoArray[0].NumberOfThreads = this->m_NumberOfThreads; this->m_SingleMethod((void *)(&this->m_ThreadInfoArray[0]) ); // The parent thread has finished this->m_SingleMethod() - so now it // waits for each of the other processes to exit for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { waitid( P_PID, (id_t) process_id[thread_loop], &info_ptr, WEXITED ); } #endif #ifdef OpenIGTLink_USE_PTHREADS // Using POSIX threads // // We want to use pthread_create to start this->m_NumberOfThreads-1 additional // threads which will be used to call this->m_SingleMethod(). The // parent thread will also call this routine. When it is done, // it will wait for all the children to finish. // // First, start up the this->m_NumberOfThreads-1 processes. Keep track // of their process ids for use later in the pthread_join call pthread_attr_t attr; #ifdef OpenIGTLink_HP_PTHREADS pthread_attr_create( &attr ); #else pthread_attr_init(&attr); #if !defined(__CYGWIN__) pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); #endif #endif for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { this->m_ThreadInfoArray[thread_loop].UserData = this->m_SingleData; this->m_ThreadInfoArray[thread_loop].NumberOfThreads = this->m_NumberOfThreads; #ifdef OpenIGTLink_HP_PTHREADS pthread_create( &(process_id[thread_loop]), attr, this->m_SingleMethod, ( (void *)(&this->m_ThreadInfoArray[thread_loop]) ) ); #else int threadError; threadError = pthread_create( &(process_id[thread_loop]), &attr, reinterpret_cast( this->m_SingleMethod), ( (void *)(&this->m_ThreadInfoArray[thread_loop]) ) ); if (threadError != 0) { igtlErrorMacro(<< "Unable to create a thread. pthread_create() returned " << threadError); } #endif } // Now, the parent thread calls this->m_SingleMethod() itself this->m_ThreadInfoArray[0].UserData = this->m_SingleData; this->m_ThreadInfoArray[0].NumberOfThreads = this->m_NumberOfThreads; this->m_SingleMethod((void *)(&this->m_ThreadInfoArray[0]) ); // The parent thread has finished this->m_SingleMethod() - so now it // waits for each of the other processes to exit for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { pthread_join( process_id[thread_loop], NULL ); } #endif #ifndef OpenIGTLink_USE_WIN32_THREADS #ifndef OpenIGTLink_USE_SPROC #ifndef OpenIGTLink_USE_PTHREADS // There is no multi threading, so there is only one thread. this->m_ThreadInfoArray[0].UserData = this->m_SingleData; this->m_ThreadInfoArray[0].NumberOfThreads = this->m_NumberOfThreads; this->m_SingleMethod( (void *)(&this->m_ThreadInfoArray[0]) ); #endif #endif #endif } void MultiThreader::MultipleMethodExecute() { int thread_loop; #ifdef OpenIGTLink_USE_WIN32_THREADS DWORD threadId; HANDLE process_id[IGTL_MAX_THREADS]; #endif #ifdef OpenIGTLink_USE_SPROC siginfo_t info_ptr; int process_id[IGTL_MAX_THREADS]; #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_t process_id[IGTL_MAX_THREADS]; #endif // obey the global maximum number of threads limit if (MultiThreaderGlobalMaximumNumberOfThreads && this->m_NumberOfThreads > MultiThreaderGlobalMaximumNumberOfThreads) { this->m_NumberOfThreads = MultiThreaderGlobalMaximumNumberOfThreads; } for ( thread_loop = 0; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { if ( this->m_MultipleMethod[thread_loop] == (ThreadFunctionType)NULL) { igtlErrorMacro( << "No multiple method set for: " << thread_loop ); return; } } // We are using sproc (on SGIs), pthreads(on Suns), CreateThread // on a PC or a single thread (the default) #ifdef OpenIGTLink_USE_WIN32_THREADS // Using CreateThread on a PC // // We want to use CreateThread to start this->m_NumberOfThreads - 1 // additional threads which will be used to call the m_NumberOfThreads-1 // methods defined in this->m_MultipleMethods[](). The parent thread // will call this->m_MultipleMethods[m_NumberOfThreads-1](). When it is done, // it will wait for all the children to finish. // // First, start up the this->m_NumberOfThreads-1 processes. Keep track // of their process ids for use later in the waitid call for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { this->m_ThreadInfoArray[thread_loop].UserData = this->m_MultipleData[thread_loop]; this->m_ThreadInfoArray[thread_loop].NumberOfThreads = this->m_NumberOfThreads; process_id[thread_loop] = CreateThread(NULL, 0, this->m_MultipleMethod[thread_loop], ((void *)(&this->m_ThreadInfoArray[thread_loop])), 0, &threadId); if (process_id[thread_loop] == NULL) { igtlErrorMacro("Error in thread creation !!!"); } } // Now, the parent thread calls the last method itself this->m_ThreadInfoArray[0].UserData = this->m_MultipleData[0]; this->m_ThreadInfoArray[0].NumberOfThreads = this->m_NumberOfThreads; (this->m_MultipleMethod[0])((void *)(&this->m_ThreadInfoArray[0]) ); // The parent thread has finished its method - so now it // waits for each of the other processes (created with sproc) to // exit for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { WaitForSingleObject(process_id[thread_loop], INFINITE); } // close the threads for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { CloseHandle(process_id[thread_loop]); } #endif #ifdef OpenIGTLink_USE_SPROC // Using sproc() on an SGI // // We want to use sproc to start this->m_NumberOfThreads - 1 additional // threads which will be used to call the m_NumberOfThreads-1 methods // defined in this->m_MultipleMethods[](). The parent thread // will call this->m_MultipleMethods[m_NumberOfThreads-1](). When it is done, // it will wait for all the children to finish. // // First, start up the this->m_NumberOfThreads-1 processes. Keep track // of their process ids for use later in the waitid call for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { this->m_ThreadInfoArray[thread_loop].UserData = this->m_MultipleData[thread_loop]; this->m_ThreadInfoArray[thread_loop].NumberOfThreads = this->m_NumberOfThreads; process_id[thread_loop] = sproc( this->m_MultipleMethod[thread_loop], PR_SADDR, ( (void *)(&this->m_ThreadInfoArray[thread_loop]) ) ); } // Now, the parent thread calls the last method itself this->m_ThreadInfoArray[0].UserData = this->m_MultipleData[0]; this->m_ThreadInfoArray[0].NumberOfThreads = this->m_NumberOfThreads; (this->m_MultipleMethod[0])((void *)(&this->m_ThreadInfoArray[0]) ); // The parent thread has finished its method - so now it // waits for each of the other processes (created with sproc) to // exit for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { waitid( P_PID, (id_t) process_id[thread_loop], &info_ptr, WEXITED ); } #endif #ifdef OpenIGTLink_USE_PTHREADS // Using POSIX threads // // We want to use pthread_create to start this->m_NumberOfThreads - 1 // additional // threads which will be used to call the NumberOfThreads-1 methods // defined in this->m_MultipleMethods[](). The parent thread // will call this->m_MultipleMethods[NumberOfThreads-1](). When it is done, // it will wait for all the children to finish. // // First, start up the this->m_NumberOfThreads-1 processes. Keep track // of their process ids for use later in the pthread_join call pthread_attr_t attr; #ifdef OpenIGTLink_HP_PTHREADS pthread_attr_create( &attr ); #else pthread_attr_init(&attr); #ifndef __CYGWIN__ pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); #endif #endif for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { this->m_ThreadInfoArray[thread_loop].UserData = this->m_MultipleData[thread_loop]; this->m_ThreadInfoArray[thread_loop].NumberOfThreads = this->m_NumberOfThreads; #ifdef OpenIGTLink_HP_PTHREADS pthread_create( &(process_id[thread_loop]), attr, this->m_MultipleMethod[thread_loop], ( (void *)(&this->m_ThreadInfoArray[thread_loop]) ) ); #else pthread_create( &(process_id[thread_loop]), &attr, reinterpret_cast( this->m_MultipleMethod[thread_loop]), ( (void *)(&this->m_ThreadInfoArray[thread_loop]) ) ); #endif } // Now, the parent thread calls the last method itself this->m_ThreadInfoArray[0].UserData = this->m_MultipleData[0]; this->m_ThreadInfoArray[0].NumberOfThreads = this->m_NumberOfThreads; (this->m_MultipleMethod[0])((void *)(&this->m_ThreadInfoArray[0]) ); // The parent thread has finished its method - so now it // waits for each of the other processes to exit for ( thread_loop = 1; thread_loop < this->m_NumberOfThreads; thread_loop++ ) { pthread_join( process_id[thread_loop], NULL ); } #endif #ifndef OpenIGTLink_USE_WIN32_THREADS #ifndef OpenIGTLink_USE_SPROC #ifndef OpenIGTLink_USE_PTHREADS // There is no multi threading, so there is only one thread. this->m_ThreadInfoArray[0].UserData = this->m_MultipleData[0]; this->m_ThreadInfoArray[0].NumberOfThreads = this->m_NumberOfThreads; (this->m_MultipleMethod[0])( (void *)(&this->m_ThreadInfoArray[0]) ); #endif #endif #endif } int MultiThreader::SpawnThread( ThreadFunctionType f, void *userdata ) { int id = 0; #ifdef OpenIGTLink_USE_WIN32_THREADS DWORD threadId; #endif for ( id = 0; id < IGTL_MAX_THREADS; id++ ) { if ( ! this->m_SpawnedThreadActiveFlagLock[id] ) { this->m_SpawnedThreadActiveFlagLock[id] = MutexLock::New(); } this->m_SpawnedThreadActiveFlagLock[id]->Lock(); if (this->m_SpawnedThreadActiveFlag[id] == 0) { // We've got a useable thread id, so grab it this->m_SpawnedThreadActiveFlag[id] = 1; this->m_SpawnedThreadActiveFlagLock[id]->Unlock(); break; } this->m_SpawnedThreadActiveFlagLock[id]->Unlock(); } if ( id >= IGTL_MAX_THREADS ) { igtlErrorMacro( << "You have too many active threads!" ); return -1; } this->m_SpawnedThreadInfoArray[id].UserData = userdata; this->m_SpawnedThreadInfoArray[id].NumberOfThreads = 1; this->m_SpawnedThreadInfoArray[id].ActiveFlag = &this->m_SpawnedThreadActiveFlag[id]; this->m_SpawnedThreadInfoArray[id].ActiveFlagLock = this->m_SpawnedThreadActiveFlagLock[id]; // We are using sproc (on SGIs), pthreads(on Suns or HPs), // CreateThread (on win32), or generating an error #ifdef OpenIGTLink_USE_WIN32_THREADS // Using CreateThread on a PC // this->m_SpawnedThreadProcessID[id] = CreateThread(NULL, 0, f, ((void *)(&this->m_SpawnedThreadInfoArray[id])), 0, &threadId); if (this->m_SpawnedThreadProcessID[id] == NULL) { igtlErrorMacro("Error in thread creation !!!"); } #endif #ifdef OpenIGTLink_USE_SPROC // Using sproc() on an SGI // this->m_SpawnedThreadProcessID[id] = sproc( f, PR_SADDR, ( (void *)(&this->m_SpawnedThreadInfoArray[id]) ) ); #endif #ifdef OpenIGTLink_USE_PTHREADS // Using POSIX threads // pthread_attr_t attr; #ifdef OpenIGTLink_HP_PTHREADS pthread_attr_create( &attr ); #else pthread_attr_init(&attr); #ifndef __CYGWIN__ pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); #endif #endif #ifdef OpenIGTLink_HP_PTHREADS pthread_create( &(this->m_SpawnedThreadProcessID[id]), attr, f, ( (void *)(&this->m_SpawnedThreadInfoArray[id]) ) ); #else pthread_create( &(this->m_SpawnedThreadProcessID[id]), &attr, reinterpret_cast(f), ( (void *)(&this->m_SpawnedThreadInfoArray[id]) ) ); #endif #endif #ifndef OpenIGTLink_USE_WIN32_THREADS #ifndef OpenIGTLink_USE_SPROC #ifndef OpenIGTLink_USE_PTHREADS // There is no multi threading, so there is only one thread. // This won't work - so give an error message. igtlErrorMacro( << "Cannot spawn thread in a single threaded environment!" ); this->m_SpawnedThreadActiveFlagLock[id] = 0; id = -1; #endif #endif #endif return id; } void MultiThreader::TerminateThread( int threadID ) { if ( !this->m_SpawnedThreadActiveFlag[threadID] ) { return; } this->m_SpawnedThreadActiveFlagLock[threadID]->Lock(); this->m_SpawnedThreadActiveFlag[threadID] = 0; this->m_SpawnedThreadActiveFlagLock[threadID]->Unlock(); #ifdef OpenIGTLink_USE_WIN32_THREADS WaitForSingleObject(this->m_SpawnedThreadProcessID[threadID], INFINITE); CloseHandle(this->m_SpawnedThreadProcessID[threadID]); #endif #ifdef OpenIGTLink_USE_SPROC siginfo_t info_ptr; waitid( P_PID, (id_t) this->m_SpawnedThreadProcessID[threadID], &info_ptr, WEXITED ); #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_join( this->m_SpawnedThreadProcessID[threadID], NULL ); #endif #ifndef OpenIGTLink_USE_WIN32_THREADS #ifndef OpenIGTLink_USE_SPROC #ifndef OpenIGTLink_USE_PTHREADS // There is no multi threading, so there is only one thread. // This won't work - so give an error message. igtlErrorMacro(<< "Cannot terminate thread in single threaded environment!"); #endif #endif #endif this->m_SpawnedThreadActiveFlagLock[threadID] = 0; this->m_SpawnedThreadActiveFlagLock[threadID] = NULL; } //---------------------------------------------------------------------------- MultiThreaderIDType MultiThreader::GetCurrentThreadID() { #if defined(OpenIGTLink_USE_PTHREADS) return pthread_self(); #elif defined(OpenIGTLink_USE_WIN32_THREADS) return GetCurrentThreadId(); #elif defined(OpenIGTLink_USE_SPROC) return getpid(); #else // No threading implementation. Assume all callers are in the same // thread. return 0; #endif } //---------------------------------------------------------------------------- int MultiThreader::ThreadsEqual(MultiThreaderIDType t1, MultiThreaderIDType t2) { #if defined(OpenIGTLink_USE_PTHREADS) return pthread_equal(t1, t2) != 0; #elif defined(OpenIGTLink_USE_WIN32_THREADS) return t1 == t2; #elif defined(OpenIGTLink_USE_SPROC) return t1 == t2; #else // No threading implementation. Assume all callers are in the same // thread. return 1; #endif } // Print method for the multithreader void MultiThreader::PrintSelf(std::ostream& os) const { this->Superclass::PrintSelf(os); const char* indent = " "; os << indent << "Thread Count: " << this->m_NumberOfThreads << "\n"; os << indent << "Global Maximum Number Of Threads: " << MultiThreaderGlobalMaximumNumberOfThreads << std::endl; os << "Thread system used: " << #ifdef OpenIGTLink_USE_PTHREADS "PTHREADS" #elif defined OpenIGTLink_USE_SPROC "SPROC" #elif defined OpenIGTLink_USE_WIN32_THREADS "WIN32 Threads" #elif defined OpenIGTLink_HP_PTHREADS "HP PThreads" #else "NO THREADS SUPPORT" #endif << std::endl; } } // namespace igtl openigtlink-3.0.0/Source/igtlMultiThreader.h000066400000000000000000000224031501024245700211000ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkMultiThreader.h,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // .NAME igtlMultiThreader - A class for performing multithreaded execution // .SECTION Description // igtlMultithreader is a class that provides support for multithreaded // execution using sproc() on an SGI, or pthread_create on any platform // supporting POSIX threads. This class can be used to execute a single // method on multiple threads, or to specify a method per thread. #ifndef __igtlMultiThreader_h #define __igtlMultiThreader_h #include "igtlObject.h" #include "igtlObjectFactory.h" #include "igtlMacro.h" #include "igtlMutexLock.h" #ifdef OpenIGTLink_USE_SPROC #include // Needed for unix implementation of sproc #include // Needed for unix implementation of sproc #endif #if defined(OpenIGTLink_USE_PTHREAD) || defined(OpenIGTLink_HP_PTHREAD) #include // Needed for PTHREAD implementation of mutex #include // Needed for unix implementation of pthreads #include // Needed for unix implementation of pthreads #endif namespace igtl { // If OpenIGTLink_USE_SPROC is defined, then sproc() will be used to create // multiple threads on an SGI. If OpenIGTLink_USE_PTHREAD is defined, then // pthread_create() will be used to create multiple threads (on // a sun, for example) // Defined in igtlSystemIncludes.h: // IGTL_MAX_THREADS // If OpenIGTLink_USE_PTHREADS is defined, then the multithreaded // function is of type void *, and returns NULL // Otherwise the type is void which is correct for WIN32 // and SPROC //BTX // The maximum number of threads allowed #ifdef OpenIGTLink_USE_SPROC #define IGTL_MAX_THREADS 128 #endif #ifdef OpenIGTLink_USE_PTHREADS #define IGTL_MAX_THREADS 128 #endif #ifdef OpenIGTLink_USE_WIN32_THREADS #define IGTL_MAX_THREADS 128 #endif // cygwin threads are unreliable #ifdef __CYGWIN__ #undef IGTL_MAX_THREADS #define IGTL_MAX_THREADS 128 #endif // mingw threads cause crashes so limit to 1 #if defined(__MINGW32__) #undef IGTL_MAX_THREADS #define IGTL_MAX_THREADS 1 #endif // On some sgi machines, threads and stl don't mix so limit to 1 #if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 #undef IGTL_MAX_THREADS #define IGTL_MAX_THREADS 1 #endif #ifndef IGTL_MAX_THREADS #define IGTL_MAX_THREADS 1 #endif #ifdef OpenIGTLink_USE_SPROC typedef int ThreadProcessIDType; typedef int MultiThreaderIDType; #endif #ifdef OpenIGTLink_USE_PTHREADS typedef void *(*ThreadFunctionType)(void *); typedef pthread_t ThreadProcessIDType; typedef pthread_t MultiThreaderIDType; #endif #ifdef OpenIGTLink_USE_WIN32_THREADS typedef igtlWindowsLPTHREAD_START_ROUTINE ThreadFunctionType; typedef igtlWindowsHANDLE ThreadProcessIDType; typedef igtlWindowsDWORD MultiThreaderIDType; #endif #if !defined(OpenIGTLink_USE_PTHREADS) && !defined(OpenIGTLink_USE_WIN32_THREADS) typedef void (*ThreadFunctionType)(void *); typedef int ThreadProcessIDType; typedef int MultiThreaderIDType; #endif //ETX class IGTLCommon_EXPORT MultiThreader : public Object { public: /** Standard class typedefs. */ typedef MultiThreader Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlNewMacro(Self); igtlTypeMacro(MultiThreader, Object); // Description: // This is the structure that is passed to the thread that is // created from the SingleMethodExecute, MultipleMethodExecute or // the SpawnThread method. It is passed in as a void *, and it is // up to the method to cast correctly and extract the information. // The ThreadID is a number between 0 and NumberOfThreads-1 that indicates // the id of this thread. The NumberOfThreads is this->NumberOfThreads for // threads created from SingleMethodExecute or MultipleMethodExecute, // and it is 1 for threads created from SpawnThread. // The UserData is the (void *)arg passed into the SetSingleMethod, // SetMultipleMethod, or SpawnThread method. //BTX #define ThreadInfoStruct MultiThreader::ThreadInfo class ThreadInfo { public: int ThreadID; int NumberOfThreads; int *ActiveFlag; MutexLock::Pointer ActiveFlagLock; void *UserData; }; //ETX // Description: // Get/Set the number of threads to create. It will be clamped to the range // 1 - IGTL_MAX_THREADS, so the caller of this method should check that the // requested number of threads was accepted. igtlSetClampMacro( NumberOfThreads, int, 1, IGTL_MAX_THREADS ); virtual int GetNumberOfThreads(); // Description: // Set/Get the maximum number of threads to use when multithreading. // This limits and overrides any other settings for multithreading. // A value of zero indicates no limit. static void SetGlobalMaximumNumberOfThreads(int val); static int GetGlobalMaximumNumberOfThreads(); // Description: // Set/Get the value which is used to initialize the NumberOfThreads // in the constructor. Initially this default is set to the number of // processors or IGTL_MAX_THREADS (which ever is less). static void SetGlobalDefaultNumberOfThreads(int val); static int GetGlobalDefaultNumberOfThreads(); // These methods are excluded from Tcl wrapping 1) because the // wrapper gives up on them and 2) because they really shouldn't be // called from a script anyway. //BTX // Description: // Execute the SingleMethod (as define by SetSingleMethod) using // this->NumberOfThreads threads. void SingleMethodExecute(); // Description: // Execute the MultipleMethods (as define by calling SetMultipleMethod // for each of the required this->NumberOfThreads methods) using // this->NumberOfThreads threads. void MultipleMethodExecute(); // Description: // Set the SingleMethod to f() and the UserData field of the // ThreadInfo that is passed to it will be data. // This method (and all the methods passed to SetMultipleMethod) // must be of type ThreadFunctionType and must take a single argument of // type void *. void SetSingleMethod(ThreadFunctionType, void *data ); // Description: // Set the MultipleMethod at the given index to f() and the UserData // field of the ThreadInfo that is passed to it will be data. void SetMultipleMethod( int index, ThreadFunctionType, void *data ); // Description: // Create a new thread for the given function. Return a thread id // which is a number between 0 and IGTL_MAX_THREADS - 1. This id should // be used to kill the thread at a later time. int SpawnThread( ThreadFunctionType, void *data ); // Description: // Terminate the thread that was created with a SpawnThreadExecute() void TerminateThread( int thread_id ); // Description: // Get the thread identifier of the calling thread. static MultiThreaderIDType GetCurrentThreadID(); // Description: // Check whether two thread identifiers refer to the same thread. static int ThreadsEqual(MultiThreaderIDType t1, MultiThreaderIDType t2); protected: MultiThreader(); ~MultiThreader(); void PrintSelf(std::ostream& os) const; // The number of threads to use int m_NumberOfThreads; // An array of thread info containing a thread id // (0, 1, 2, .. IGTL_MAX_THREADS-1), the thread count, and a pointer // to void so that user data can be passed to each thread ThreadInfo m_ThreadInfoArray[IGTL_MAX_THREADS]; // The methods ThreadFunctionType m_SingleMethod; ThreadFunctionType m_MultipleMethod[IGTL_MAX_THREADS]; // Storage of MutexFunctions and ints used to control spawned // threads and the spawned thread ids int m_SpawnedThreadActiveFlag[IGTL_MAX_THREADS]; MutexLock::Pointer m_SpawnedThreadActiveFlagLock[IGTL_MAX_THREADS]; ThreadProcessIDType m_SpawnedThreadProcessID[IGTL_MAX_THREADS]; ThreadInfo m_SpawnedThreadInfoArray[IGTL_MAX_THREADS]; //ETX // Internal storage of the data void *m_SingleData; void *m_MultipleData[IGTL_MAX_THREADS]; private: MultiThreader(const MultiThreader&); // Not implemented. void operator=(const MultiThreader&); // Not implemented. }; } // namespace igtl #endif openigtlink-3.0.0/Source/igtlMutexLock.cxx000066400000000000000000000054511501024245700206210ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMutexLock.cxx,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlMutexLock.h" namespace igtl { // New for the SimpleMutex SimpleMutexLock *SimpleMutexLock::New() { return new SimpleMutexLock; } // Construct a new MutexLock SimpleMutexLock::SimpleMutexLock() { #ifdef OpenIGTLink_USE_SPROC init_lock( &m_MutexLock ); #endif #ifdef OpenIGTLink_USE_WIN32_THREADS m_MutexLock = CreateMutex( NULL, FALSE, NULL ); #endif #ifdef OpenIGTLink_USE_PTHREADS #ifdef OpenIGTLink_HP_PTHREADS pthread_mutex_init(&m_MutexLock, pthread_mutexattr_default); #else pthread_mutex_init(&m_MutexLock, NULL); #endif #endif } // Destruct the MutexVariable SimpleMutexLock::~SimpleMutexLock() { #ifdef OpenIGTLink_USE_WIN32_THREADS CloseHandle(m_MutexLock); #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_mutex_destroy( &m_MutexLock); #endif } // Lock the MutexLock void SimpleMutexLock::Lock() { #ifdef OpenIGTLink_USE_SPROC spin_lock( &m_MutexLock ); #endif #ifdef OpenIGTLink_USE_WIN32_THREADS WaitForSingleObject( m_MutexLock, INFINITE ); #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_mutex_lock( &m_MutexLock); #endif } // Unlock the MutexLock void SimpleMutexLock::Unlock() { #ifdef OpenIGTLink_USE_SPROC release_lock( &m_MutexLock ); #endif #ifdef OpenIGTLink_USE_WIN32_THREADS ReleaseMutex( m_MutexLock ); #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_mutex_unlock( &m_MutexLock); #endif } void MutexLock::PrintSelf(std::ostream& os) const { Superclass::PrintSelf(os); } }//end namespace igtl openigtlink-3.0.0/Source/igtlMutexLock.h000066400000000000000000000105141501024245700202420ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMutexLock.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlMutexLock_h #define __igtlMutexLock_h #include "igtlObject.h" #include "igtlObjectFactory.h" #ifdef OpenIGTLink_USE_SPROC #include #endif #ifdef OpenIGTLink_USE_PTHREADS #include #endif #ifdef OpenIGTLink_USE_WIN32_THREADS #include "igtlWindows.h" #endif namespace igtl { #ifdef OpenIGTLink_USE_SPROC typedef abilock_t MutexType; #endif #ifdef OpenIGTLink_USE_PTHREADS typedef pthread_mutex_t MutexType; #endif #ifdef OpenIGTLink_USE_WIN32_THREADS typedef HANDLE MutexType; #endif #ifndef OpenIGTLink_USE_SPROC #ifndef OpenIGTLink_USE_PTHREADS #ifndef OpenIGTLink_USE_WIN32_THREADS typedef int MutexType; #endif #endif #endif /** \class SimpleMutexLock * \brief Simple mutual exclusion locking class. * SimpleMutexLock allows the locking of variables which are accessed * through different threads. This header file also defines * SimpleMutexLock which is not a subclass of Object. * * \ingroup OSSystemObjects */ class IGTLCommon_EXPORT SimpleMutexLock { public: /** Standard class typedefs. */ typedef SimpleMutexLock Self; /** Constructor and destructor left public purposely. */ SimpleMutexLock(); virtual ~SimpleMutexLock(); /** Methods for creation and destruction through the object factory. */ static SimpleMutexLock *New(); //void Delete() {delete this;} /** Used for debugging and other run-time purposes. */ virtual const char *GetNameOfClass() {return "igtlSimpleMutexLock";}; /** Lock the MutexLock. */ void Lock( void ); /** Unlock the MutexLock. */ void Unlock( void ); /** Access the MutexType member variable from outside this class */ MutexType& GetMutexLock() { return m_MutexLock; } const MutexType GetMutexLock() const { return m_MutexLock; } protected: MutexType m_MutexLock; }; /** \class MutexLock * \brief Mutual exclusion locking class. * * MutexLock allows the locking of variables which are accessed * through different threads. This header file also defines * SimpleMutexLock which is not a subclass of igtlObject. * * \ingroup OSSystemObjects */ class IGTLCommon_EXPORT MutexLock : public Object { public: /** Standard class typedefs. */ typedef MutexLock Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation. */ igtlNewMacro(Self); /** Run-time information. */ igtlTypeMacro(MutexLock,Object); /** Lock the igtlMutexLock. */ void Lock( void ); /** Unlock the MutexLock. */ void Unlock( void ); protected: MutexLock() {} ~MutexLock() {} SimpleMutexLock m_SimpleMutexLock; void PrintSelf(std::ostream& os) const; private: MutexLock(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; inline void MutexLock::Lock( void ) { m_SimpleMutexLock.Lock(); } inline void MutexLock::Unlock( void ) { m_SimpleMutexLock.Unlock(); } }//end igtl namespace #endif openigtlink-3.0.0/Source/igtlNDArrayMessage.cxx000066400000000000000000000125551501024245700215160ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlNDArrayMessage.h" #include "igtlTypes.h" #include "igtl_header.h" #include "igtl_ndarray.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include namespace igtl { ArrayBase::ArrayBase() { this->m_ByteArray = NULL; this->m_Size.clear(); } ArrayBase::~ArrayBase() { if (this->m_ByteArray) { delete (igtlUint8 *) this->m_ByteArray; } } int ArrayBase::SetSize(IndexType size) { if (this->m_Size == size) { // If the size of the array is same as specified, // do nothing return 1; } if (this->m_ByteArray != NULL) { delete (igtlUint8 *) this->m_ByteArray; } this->m_Size = size; this->m_ByteArray = (void *) new igtlUint8[GetRawArraySize()]; if (this->m_ByteArray) { return 1; } else { this->m_Size.clear(); return 0; } } int ArrayBase::SetArray(void * array) { if (this->m_ByteArray) { memcpy(this->m_ByteArray, array, GetRawArraySize()); return 1; } else { return 0; } }; igtlUint64 ArrayBase::GetRawArraySize() { return (igtlUint64) GetNumberOfElements() * (igtlUint64) GetElementSize(); } igtlUint32 ArrayBase::GetNumberOfElements() { igtlUint32 len = 1; IndexType::iterator iter; for (iter = this->m_Size.begin(); iter != this->m_Size.end(); iter ++) { len *= *iter; } return len; } igtlUint32 ArrayBase::Get1DIndex(IndexType index) { igtlUint32 p; igtlUint32 step; igtlUint16 dim = this->m_Size.size(); if (this->m_Size.size() != index.size()) { // TODO: how to pass the error to the caller? return 0; } p = 0; step = 1; IndexType::iterator iter; for (int i = dim-1; i >= 0; i --) { p += index[i] * step; step *= this->m_Size[i]; } igtlUint32 m = GetNumberOfElements(); if (p <= m) { return p; } else { // TODO: how to pass the error to the caller? return m; } } NDArrayMessage::NDArrayMessage(): MessageBase() { this->m_SendMessageType = "NDARRAY"; this->m_Array = NULL; this->m_Type = 0; } NDArrayMessage::~NDArrayMessage() { } int NDArrayMessage::SetArray(int type, ArrayBase * a) { // Check if type is valid if (type < 2 || type > 13 || type == 8 || type == 9 || type == 12) { return 0; } this->m_Type = type; if (a) { this->m_Array = a; return 1; } else { return 0; } } int NDArrayMessage::CalculateContentBufferSize() { int dataSize; int dim; if (this->m_Array == NULL) { return 0; } dim = this->m_Array->GetDimension(); dataSize = sizeof(igtlUint8) * 2 + sizeof(igtlUint16) * (igtl_uint64) dim + this->m_Array->GetRawArraySize(); return dataSize; } int NDArrayMessage::PackContent() { // Allocate buffer AllocateBuffer(); if (this->m_Array == NULL) { return 0; } igtl_ndarray_info info; igtl_ndarray_init_info(&info); info.dim = this->m_Array->GetDimension(); info.type = this->m_Type; ArrayBase::IndexType size = this->m_Array->GetSize(); igtl_uint16 * s = new igtl_uint16[info.dim]; for (int i = 0; i < info.dim; i ++) { s[i] = size[i]; } int r = igtl_ndarray_alloc_info(&info, s); delete [] s; if (r == 0) { return 0; } // size.data() doesn't work for some environtments (MacOS X 10.5 and Win32, as far as I know) // if (igtl_ndarray_alloc_info(&info, size.data()) == 0) // { // return 0; // } memcpy(info.array, this->m_Array->GetRawArray(), this->m_Array->GetRawArraySize()); igtl_ndarray_pack(&info, this->m_Content, IGTL_TYPE_PREFIX_NONE); return 1; } int NDArrayMessage::UnpackContent() { igtl_ndarray_info info; igtl_ndarray_unpack(IGTL_TYPE_PREFIX_NONE, this->m_Content, &info, this->CalculateReceiveContentSize()); this->m_Type = info.type; ArrayBase::IndexType size; size.resize(info.dim); for (int i = 0; i < info.dim; i ++) { size[i] = info.size[i]; } switch (this->m_Type) { case TYPE_INT8: this->m_Array = new Array; break; case TYPE_UINT8: this->m_Array = new Array; break; case TYPE_INT16: this->m_Array = new Array; break; case TYPE_UINT16: this->m_Array = new Array; break; case TYPE_INT32: this->m_Array = new Array; break; case TYPE_UINT32: this->m_Array = new Array; break; case TYPE_FLOAT32: this->m_Array = new Array; break; case TYPE_FLOAT64: this->m_Array = new Array; break; case TYPE_COMPLEX: this->m_Array = new Array; break; default: return 0; break; } this->m_Array->SetSize(size); memcpy(this->m_Array->GetRawArray(), info.array, this->m_Array->GetRawArraySize()); return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlNDArrayMessage.h000066400000000000000000000107211501024245700211340ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlNDArrayMessage_h #define __igtlNDArrayMessage_h #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #define IGTL_STRING_MESSAGE_DEFAULT_ENCODING 3 /* Default encoding -- ANSI-X3.5-1968 */ namespace igtl { class IGTLCommon_EXPORT ArrayBase { public: /// Vector type for an index of N-D array typedef std::vector IndexType; protected: ArrayBase(); ~ArrayBase(); public: /// Sets the size of the N-D array. Returns non-zero value, if success. int SetSize(IndexType size); /// Gets the size of the N-D array. IndexType GetSize() { return this->m_Size; }; /// Gets the dimension of the N-D array. int GetDimension() { return this->m_Size.size(); }; /// Sets an array from a byte array. Size and dimension must be specified prior to /// calling the SetArray() function. int SetArray(void * array); /// Gets the size of the raw byte array stored in the class. igtlUint64 GetRawArraySize(); /// Gets the raw byte array stored in the class. void * GetRawArray() { return this->m_ByteArray; }; protected: /// Gets the size of a element of the array. virtual int GetElementSize() = 0; /// Gets the number of elements in the array. igtlUint32 GetNumberOfElements(); /// Returns the 1-D index of the element specified by 'index'. /// This function is used to calculate the index of the element in /// the raw array. igtlUint32 Get1DIndex(IndexType index); private: /// A vector representing the size of the N-D array. IndexType m_Size; /// A pointer to the byte array data. void * m_ByteArray; }; template class IGTLCommon_EXPORT Array : public ArrayBase { public: /// Sets a value of the element specified by 'index' int SetValue(IndexType index, T value) { if (Get1DIndex(index) <= GetNumberOfElements()) { T* ByteArray = (T*)GetRawArray(); ByteArray[Get1DIndex(index) * sizeof(T)] = value; return 1; } else { return 0; } } /// Gets a value of the element specified by 'index' int GetValue(IndexType index, T & value) { if (Get1DIndex(index) <= GetNumberOfElements()) { T* ByteArray = (T*)GetRawArray(); value = ByteArray[Get1DIndex(index) * sizeof(T)]; return 1; } else { return 0; } } protected: /// Gets the size of elements (e.g. 1 byte in case of 8-bit integer) virtual int GetElementSize() { return sizeof(T); }; }; class IGTLCommon_EXPORT NDArrayMessage: public MessageBase { public: /// Types of elements enum { TYPE_INT8 = 2, TYPE_UINT8 = 3, TYPE_INT16 = 4, TYPE_UINT16 = 5, TYPE_INT32 = 6, TYPE_UINT32 = 7, TYPE_FLOAT32 = 10, TYPE_FLOAT64 = 11, TYPE_COMPLEX = 13, }; public: typedef NDArrayMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::NDArrayMessage, igtl::MessageBase); igtlNewMacro(igtl::NDArrayMessage); public: /// Sets an array with an element type. int SetArray(int type, ArrayBase * a); /// Gets a pointer to the array. ArrayBase * GetArray() { return this->m_Array; }; /// Gets the type of elements of the array. (e.g. TYPE_INT8) int GetType() { return this->m_Type; } ; protected: NDArrayMessage(); ~NDArrayMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// A pointer to the N-D array. ArrayBase * m_Array; /// A variable for the type of the N-D array. int m_Type; }; } // namespace igtl #endif // _igtlNDArrayMessage_h openigtlink-3.0.0/Source/igtlOSUtil.cxx000066400000000000000000000024331501024245700200620ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlOSUtil.h" #if defined(_WIN32) && !defined(__CYGWIN__) #include #else #include #include #endif #include namespace igtl { void Sleep(int milliseconds) { #if defined(_WIN32) && !defined(__CYGWIN__) // Call Windows Native Sleep() function ::Sleep(milliseconds); #else struct timespec req; req.tv_sec = (int) milliseconds / 1000; req.tv_nsec = (milliseconds % 1000) * 1000000; while ((nanosleep(&req, &req) == -1) && (errno == EINTR)) { continue; } #endif } // strnlen(), if not defined #ifndef OpenIGTLink_HAVE_STRNLEN size_t Strnlen(const char* s, size_t maxlen) { size_t i; for(i = 0; i < maxlen; i++) { if(s[i] == '\0') return i; } return maxlen; } #endif } openigtlink-3.0.0/Source/igtlOSUtil.h000066400000000000000000000021241501024245700175040ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igltOSUtil_h #define __igltOSUtil_h #include #include "igtlWin32Header.h" namespace igtl { /** Stop the program for the duration specified in millisecond * The maximum dulation is * */ void IGTLCommon_EXPORT Sleep(int millisecond); /** Just in case strnlen() is not defined (e.g. Mac OS X Snow Leopard) */ #ifndef OpenIGTLink_HAVE_STRNLEN size_t IGTLCommon_EXPORT Strnlen(const char* s, size_t maxlen); #else inline size_t IGTLCommon_EXPORT Strnlen(const char* s, size_t maxlen) { return strnlen(s, maxlen); } #endif } #endif // __igltOSUtil_h openigtlink-3.0.0/Source/igtlObject.cxx000066400000000000000000000273441501024245700201210ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkObject.cxx,v $ Language: C++ Date: $Date: 2009-11-12 23:48:21 -0500 (Thu, 12 Nov 2009) $ Version: $Revision: 5332 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlObject.h" #include "igtlObjectFactory.h" #include "igtlMacro.h" namespace igtl { /** * Initialize static member that controls warning display. */ bool Object::m_GlobalWarningDisplay = true; //class Observer //{ //public: // Observer(Command* c, // const EventObject * event, // unsigned long tag) :m_Command(c), // m_Event(event), // m_Tag(tag) // { } // virtual ~Observer() // { delete m_Event; } // Command::Pointer m_Command; // const EventObject * m_Event; // unsigned long m_Tag; //}; //class SubjectImplementation //{ //public: // SubjectImplementation() {m_Count = 0;} // ~SubjectImplementation(); //// unsigned long AddObserver(const EventObject & event, Command* cmd); //// unsigned long AddObserver(const EventObject & event, Command* cmd) const; //// void RemoveObserver(unsigned long tag); //// void RemoveAllObservers(); //// void InvokeEvent( const EventObject & event, Object* self); //// void InvokeEvent( const EventObject & event, const Object* self); //// Command *GetCommand(unsigned long tag); // // bool HasObserver(const EventObject & event) const; // // bool PrintObservers(std::ostream& os) const; //private: // //std::list m_Observers; // unsigned long m_Count; //}; //SubjectImplementation:: //~SubjectImplementation() //{ //// for(std::list::iterator i = m_Observers.begin(); //// i != m_Observers.end(); ++i) //// { //// delete (*i); //// } //} //unsigned long //SubjectImplementation:: //AddObserver(const EventObject & event, // Command* cmd) //{ // Observer* ptr = new Observer(cmd, event.MakeObject(), m_Count); // m_Observers.push_back(ptr); // m_Count++; // return ptr->m_Tag; //} //unsigned long //SubjectImplementation:: //AddObserver(const EventObject & event, // Command* cmd) const //{ // Observer* ptr = new Observer(cmd, event.MakeObject(), m_Count); // SubjectImplementation * me = const_cast( this ); // me->m_Observers.push_back(ptr); // me->m_Count++; // return ptr->m_Tag; //} //void //SubjectImplementation:: //RemoveObserver(unsigned long tag) //{ // for(std::list::iterator i = m_Observers.begin(); // i != m_Observers.end(); ++i) // { // if((*i)->m_Tag == tag) // { // delete (*i); // m_Observers.erase(i); // return; // } // } //} //void //SubjectImplementation:: //RemoveAllObservers() //{ // for(std::list::iterator i = m_Observers.begin(); // i != m_Observers.end(); ++i) // { // delete (*i); // } // m_Observers.clear(); //} // // //void //SubjectImplementation:: //InvokeEvent( const EventObject & event, // Object* self) //{ // for(std::list::iterator i = m_Observers.begin(); // i != m_Observers.end(); ++i) // { // const EventObject * e = (*i)->m_Event; // if(e->CheckEvent(&event)) // { // (*i)->m_Command->Execute(self, event); // } // } //} // //void //SubjectImplementation:: //InvokeEvent( const EventObject & event, // const Object* self) //{ // for(std::list::iterator i = m_Observers.begin(); // i != m_Observers.end(); ++i) // { // const EventObject * e = (*i)->m_Event; // if(e->CheckEvent(&event)) // { // (*i)->m_Command->Execute(self, event); // } // } //} //Command* //SubjectImplementation:: //GetCommand(unsigned long tag) //{ // for(std::list::iterator i = m_Observers.begin(); // i != m_Observers.end(); ++i) // { // if ( (*i)->m_Tag == tag) // { // return (*i)->m_Command; // } // } // return 0; //} //bool //SubjectImplementation:: //HasObserver(const EventObject & event) const //{ // for(std::list::const_iterator i = m_Observers.begin(); // i != m_Observers.end(); ++i) // { // const EventObject * e = (*i)->m_Event; // if(e->CheckEvent(&event)) // { // return true; // } // } // return false; //} //bool //SubjectImplementation:: //PrintObservers(std::ostream& os) const //{ // if(m_Observers.empty()) // { // return false; // } // // for(std::list::const_iterator i = m_Observers.begin(); // i != m_Observers.end(); ++i) // { // const EventObject * e = (*i)->m_Event; // const Command* c = (*i)->m_Command; // os << " " << e->GetEventName() << "(" << c->GetNameOfClass() << ")\n"; // } // return true; //} Object::Pointer Object::New() { Pointer smartPtr; Object *rawPtr = ::igtl::ObjectFactory::Create(); if(rawPtr == NULL) { rawPtr = new Object; } smartPtr = rawPtr; rawPtr->UnRegister(); return smartPtr; } LightObject::Pointer Object::CreateAnother() const { return Object::New().GetPointer(); } /** * Turn debugging output on. */ void Object ::DebugOn() const { m_Debug = true; } /** * Turn debugging output off. */ void Object ::DebugOff() const { m_Debug = false; } /** * Get the value of the debug flag. */ bool Object ::GetDebug() const { return m_Debug; } /** * Set the value of the debug flag. A non-zero value turns debugging on. */ void Object ::SetDebug(bool debugFlag) const { m_Debug = debugFlag; } ///** // * Return the modification for this object. // */ //unsigned long //Object //::GetMTime() const //{ // return m_MTime.GetMTime(); //} ///** // * Make sure this object's modified time is greater than all others. // */ //void //Object //::Modified() const //{ // m_MTime.Modified(); // //InvokeEvent( ModifiedEvent() ); //} /** * Increase the reference count (mark as used by another object). */ void Object ::Register() const { igtlDebugMacro(<< "Registered, " << "ReferenceCount = " << (m_ReferenceCount+1)); // call the parent Superclass::Register(); } /** * Decrease the reference count (release by another object). */ void Object ::UnRegister() const { // call the parent igtlDebugMacro(<< "UnRegistered, " << "ReferenceCount = " << (m_ReferenceCount-1)); if ( (m_ReferenceCount-1) <= 0) { /** * If there is a delete method, invoke it. */ //this->InvokeEvent(DeleteEvent()); } Superclass::UnRegister(); } /** * Sets the reference count (use with care) */ void Object ::SetReferenceCount(int ref) { igtlDebugMacro(<< "Reference Count set to " << ref); // ReferenceCount in now unlocked. We may have a race condition to // to delete the object. if( ref <= 0 ) { /** * If there is a delete method, invoke it. */ //this->InvokeEvent(DeleteEvent()); } Superclass::SetReferenceCount(ref); } /** * Set the value of the global debug output control flag. */ void Object ::SetGlobalWarningDisplay(bool val) { m_GlobalWarningDisplay = val; } /** * Get the value of the global debug output control flag. */ bool Object ::GetGlobalWarningDisplay() { return m_GlobalWarningDisplay; } //unsigned long //Object //::AddObserver(const EventObject & event, Command *cmd) //{ // if (!this->m_SubjectImplementation) // { // this->m_SubjectImplementation = new SubjectImplementation; // } // return this->m_SubjectImplementation->AddObserver(event,cmd); //} //unsigned long //Object //::AddObserver(const EventObject & event, Command *cmd) const //{ // if (!this->m_SubjectImplementation) // { // Self * me = const_cast( this ); // me->m_SubjectImplementation = new SubjectImplementation; // } // return this->m_SubjectImplementation->AddObserver(event,cmd); //} //Command* //Object //::GetCommand(unsigned long tag) //{ // if (this->m_SubjectImplementation) // { // return this->m_SubjectImplementation->GetCommand(tag); // } // return NULL; //} //void //Object //::RemoveObserver(unsigned long tag) //{ // if (this->m_SubjectImplementation) // { // this->m_SubjectImplementation->RemoveObserver(tag); // } //} //void //Object //::RemoveAllObservers() //{ // if (this->m_SubjectImplementation) // { // this->m_SubjectImplementation->RemoveAllObservers(); // } //} //void //Object //::InvokeEvent( const EventObject & event ) //{ // if (this->m_SubjectImplementation) // { // this->m_SubjectImplementation->InvokeEvent(event,this); // } //} //void //Object //::InvokeEvent( const EventObject & event ) const //{ // if (this->m_SubjectImplementation) // { // this->m_SubjectImplementation->InvokeEvent(event,this); // } //} // // // // //bool //Object //::HasObserver( const EventObject & event ) const //{ // if (this->m_SubjectImplementation) // { // return this->m_SubjectImplementation->HasObserver(event); // } // return false; //} // // // //bool //Object //::PrintObservers(std::ostream& os) const //{ // if (this->m_SubjectImplementation) // { // return this->m_SubjectImplementation->PrintObservers(os); // } // return false; //} /** * Create an object with Debug turned off and modified time initialized * to the most recently modified object. */ Object ::Object(): LightObject(), m_Debug(false)/*, m_SubjectImplementation(NULL), m_MetaDataDictionary(NULL) */ { // this->Modified(); } Object ::~Object() { igtlDebugMacro(<< "Destructing!"); //delete m_SubjectImplementation; //delete m_MetaDataDictionary;//Deleting a NULL pointer does nothing. } /** * Chaining method to print an object's instance variables, as well as * its superclasses. */ void Object ::PrintSelf(std::ostream& os) const { Superclass::PrintSelf(os); const char* indent = " "; // os << indent << "Modified Time: " << this->GetMTime() << std::endl; os << indent << "Debug: " << (m_Debug ? "On\n" : "Off\n"); os << indent << "Observers: \n"; /* if(!this->PrintObservers(os)) { os << " " << "none\n"; } */ } //MetaDataDictionary & //Object //::GetMetaDataDictionary(void) //{ // if(m_MetaDataDictionary==NULL) // { // m_MetaDataDictionary=new MetaDataDictionary; // } // return *m_MetaDataDictionary; //} //const MetaDataDictionary & //Object //::GetMetaDataDictionary(void) const //{ // if(m_MetaDataDictionary==NULL) // { // m_MetaDataDictionary=new MetaDataDictionary; // } // return *m_MetaDataDictionary; //} //void //Object //::SetMetaDataDictionary(const MetaDataDictionary & rhs) //{ // if(m_MetaDataDictionary==NULL) // { // m_MetaDataDictionary=new MetaDataDictionary; // } // *m_MetaDataDictionary=rhs; //} } // end namespace igtl openigtlink-3.0.0/Source/igtlObject.h000066400000000000000000000163711501024245700175440ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkObject.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlObject_h #define __igtlObject_h #include "igtlLightObject.h" //#include "igtlTimeStamp.h" //#include "igtlEventObject.h" //#include "igtlMetaDataDictionary.h" #include "igtlConfigure.h" namespace igtl { //class SubjectImplementation; //class Command; /** \class Object * \brief Base class for most igtl classes. * * Object is the second-highest level base class for most igtl objects. * It extends the base object functionality of LightObject by * implementing callbacks (via object/observer), debug flags/methods, * and modification time tracking. Most IGTL classes should be a subclas * of Object due to the need to keep track of modified time. * * \ingroup IGTLSystemObjects * \ingroup DataRepresentation */ class IGTLCommon_EXPORT Object: public LightObject { public: /** Smart pointer typedef support. */ typedef Object Self; typedef LightObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ static Pointer New(); /** Create an object from an instance, potentially deferring to a * factory. This method allows you to create an instance of an * object that is exactly the same type as the referring object. * This is useful in cases where an object has been cast back to a * base class. */ virtual LightObject::Pointer CreateAnother() const; /** Standard part of all igtl objects. */ igtlTypeMacro(Object, LightObject); /** Turn debugging output on. */ virtual void DebugOn() const; /** Turn debugging output off. */ virtual void DebugOff() const; /** Get the value of the debug flag. */ bool GetDebug() const; /** Set the value of the debug flag. A non-zero value turns debugging on. */ void SetDebug(bool debugFlag) const; /** Return this objects modified time. */ // virtual unsigned long GetMTime() const; /** Update the modification time for this object. Many filters rely on the * modification time to determine if they need to recompute their data. */ // virtual void Modified() const; /** Increase the reference count (mark as used by another object). */ virtual void Register() const; /** Decrease the reference count (release by another object). */ virtual void UnRegister() const; /** Sets the reference count (use with care) */ virtual void SetReferenceCount(int); /** This is a global flag that controls whether any debug, warning * or error messages are displayed. */ static void SetGlobalWarningDisplay(bool flag); static bool GetGlobalWarningDisplay(); static void GlobalWarningDisplayOn() { Object::SetGlobalWarningDisplay(true); } static void GlobalWarningDisplayOff() { Object::SetGlobalWarningDisplay(false); } /** Allow people to add/remove/invoke observers (callbacks) to any IGTL * object. This is an implementation of the subject/observer design * pattern. An observer is added by specifying an event to respond to * and an igtl::Command to execute. It returns an unsigned long tag * which can be used later to remove the event or retrieve the * command. The memory for the Command becomes the responsibility of * this object, so don't pass the same instance of a command to two * different objects */ // unsigned long AddObserver(const EventObject & event, Command *); // unsigned long AddObserver(const EventObject & event, Command *) const; /** Get the command associated with the given tag. NOTE: This returns * a pointer to a Command, but it is safe to asign this to a * Command::Pointer. Since Command inherits from LightObject, at this * point in the code, only a pointer or a reference to the Command can * be used. */ //Command* GetCommand(unsigned long tag); /** Call Execute on all the Commands observing this event id. */ //void InvokeEvent( const EventObject & ); /** Call Execute on all the Commands observing this event id. * The actions triggered by this call doesn't modify this object. */ //void InvokeEvent( const EventObject & ) const; /** Remove the observer with this tag value. */ //void RemoveObserver(unsigned long tag); /** Remove all observers . */ //void RemoveAllObservers(); /** Return true if an observer is registered for this event. */ //bool HasObserver( const EventObject & event ) const; /** * \return A reference to this objects MetaDataDictionary. * \warning This reference may be changed. */ //MetaDataDictionary & GetMetaDataDictionary(void); /** * \return A constant reference to this objects MetaDataDictionary. */ //const MetaDataDictionary & GetMetaDataDictionary(void) const; /** * \return Set the MetaDataDictionary */ //void SetMetaDataDictionary(const MetaDataDictionary & rhs); protected: Object(); virtual ~Object(); /** Methods invoked by Print() to print information about the object * including superclasses. Typically not called by the user (use Print() * instead) but used in the hierarchical print process to combine the * output of several classes. */ virtual void PrintSelf(std::ostream& os) const; //bool PrintObservers(std::ostream& os) const; private: Object(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented /** Enable/Disable debug messages. */ mutable bool m_Debug; /** Keep track of modification time. */ // mutable TimeStamp m_MTime; /** Global object debug flag. */ static bool m_GlobalWarningDisplay; /** Implementation class for Subject/Observer Pattern. * This is only allocated if used. */ //SubjectImplementation* m_SubjectImplementation; /** * Implementation for holding Object MetaData * @see igtl::MetaDataDictionary * @see igtl::MetaDataObjectBase * @see igtl::MetaDataObject * This is only allocated if used. */ //mutable MetaDataDictionary * m_MetaDataDictionary; }; } // end namespace igtl #endif openigtlink-3.0.0/Source/igtlObjectFactory.h000066400000000000000000000047341501024245700210740ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkObjectFactory.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlObjectFactory_h #define __igtlObjectFactory_h #include "igtlObjectFactoryBase.h" namespace igtl { /** \class ObjectFactory * \brief Create instances of a class. * * ObjectFactory is a helper class used to created instances of a * class. Object factories are used for instantiation because they allow * run-time replacement of a class with a user-supplied version. For * example, if you wished to replace an algorithm with your own custom * version, or with a hardware-accelerated version, ObjectFactory * can be used to do this. * * This implementation of the object factory is templated and uses RTTI * (Run-Time Type Information) to create the name of the class it is to * instantiate. (The name may include template type parameters, depending * on the class definition.) * * \ingroup IGTLSystemObjects */ template class ObjectFactory : public ObjectFactoryBase { public: static typename T::Pointer Create() { LightObject::Pointer ret = ObjectFactory::CreateInstance(typeid(T).name()); return dynamic_cast(ret.GetPointer()); } }; } // end namespace igtl #endif openigtlink-3.0.0/Source/igtlObjectFactoryBase.cxx000066400000000000000000000426211501024245700222370ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkObjectFactoryBase.cxx,v $ Language: C++ Date: $Date: 2010-06-09 16:16:36 -0400 (Wed, 09 Jun 2010) $ Version: $Revision: 6525 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif #include "igtlObjectFactoryBase.h" //#include "igtlDynamicLoader.h" //#include "igtlDirectory.h" //#include "igtlVersion.h" #include #include #include #include namespace { class CleanUpObjectFactory { public: inline void Use() { } ~CleanUpObjectFactory() { igtl::ObjectFactoryBase::UnRegisterAllFactories(); } }; static CleanUpObjectFactory CleanUpObjectFactoryGlobal; } namespace igtl { /** * Add this for the SGI compiler which does not seem * to provide a default implementation as it should. */ bool operator==(const ObjectFactoryBase::OverrideInformation& rhs, const ObjectFactoryBase::OverrideInformation& lhs) { return (rhs.m_Description == lhs.m_Description && rhs.m_OverrideWithName == lhs.m_OverrideWithName); } /** * Add this for the SGI compiler which does not seem * to provide a default implementation as it should. */ bool operator<(const ObjectFactoryBase::OverrideInformation& rhs, const ObjectFactoryBase::OverrideInformation& lhs) { return (rhs.m_Description < lhs.m_Description && rhs.m_OverrideWithName < lhs.m_OverrideWithName); } /** \class StringOverMap * \brief Internal implementation class for ObjectFactorBase. * * Create a sub class to shrink the size of the symbols * Also, so a forward reference can be put in ObjectFactoryBase.h * and a pointer member can be used. This avoids other * classes including and getting long symbol warnings. */ typedef std::multimap StringOverMapType; /** \class OverRideMap * \brief Internal implementation class for ObjectFactorBase. */ class OverRideMap : public StringOverMapType { public: }; /** * Initialize static list of factories. */ std::list* ObjectFactoryBase::m_RegisteredFactories = 0; /** * Create an instance of a named igtl object using the loaded * factories */ LightObject::Pointer ObjectFactoryBase ::CreateInstance(const char* igtlclassname) { if ( !ObjectFactoryBase::m_RegisteredFactories ) { ObjectFactoryBase::Initialize(); } for ( std::list::iterator i = m_RegisteredFactories->begin(); i != m_RegisteredFactories->end(); ++i ) { LightObject::Pointer newobject = (*i)->CreateObject(igtlclassname); if(newobject) { newobject->Register(); return newobject; } } return 0; } std::list ObjectFactoryBase ::CreateAllInstance(const char* igtlclassname) { if ( !ObjectFactoryBase::m_RegisteredFactories ) { ObjectFactoryBase::Initialize(); } std::list created; for ( std::list::iterator i = m_RegisteredFactories->begin(); i != m_RegisteredFactories->end(); ++i ) { LightObject::Pointer newobject = (*i)->CreateObject(igtlclassname); if(newobject) { created.push_back(newobject); } } return created; } /** * A one time initialization method. */ void ObjectFactoryBase ::Initialize() { CleanUpObjectFactoryGlobal.Use(); /** * Don't do anything if we are already initialized */ if ( ObjectFactoryBase::m_RegisteredFactories ) { return; } ObjectFactoryBase::m_RegisteredFactories = new std::list; ObjectFactoryBase::RegisterDefaults(); // ObjectFactoryBase::LoadDynamicFactories(); } /** * Register any factories that are always present in IGTL like * the OpenGL factory, currently this is not done. */ void ObjectFactoryBase ::RegisterDefaults() { } ///** // * Load all libraries in IGTL_AUTOLOAD_PATH // */ //void //ObjectFactoryBase //::LoadDynamicFactories() //{ // /** // * follow PATH conventions // */ //#ifdef _WIN32 // char PathSeparator = ';'; //#else // char PathSeparator = ':'; //#endif // // std::string LoadPath; // if (getenv("IGTL_AUTOLOAD_PATH")) // { // LoadPath = getenv("IGTL_AUTOLOAD_PATH"); // } // else // { // return; // } // // if(LoadPath.size() == 0) // { // return; // } // std::string::size_type EndSeparatorPosition = 0; // std::string::size_type StartSeparatorPosition = 0; // // while ( StartSeparatorPosition != std::string::npos ) // { // StartSeparatorPosition = EndSeparatorPosition; // // /** // * find PathSeparator in LoadPath // */ // EndSeparatorPosition = LoadPath.find(PathSeparator, // StartSeparatorPosition); // if(EndSeparatorPosition == std::string::npos) // { // EndSeparatorPosition = LoadPath.size() + 1; // Add 1 to simulate // // having a separator // } // std::string CurrentPath = // LoadPath.substr(StartSeparatorPosition, // EndSeparatorPosition - StartSeparatorPosition); // // ObjectFactoryBase::LoadLibrariesInPath(CurrentPath.c_str()); // // /** // * Move past separator // */ // if(EndSeparatorPosition > LoadPath.size()) // { // StartSeparatorPosition = std::string::npos; // } // else // { // EndSeparatorPosition++; // Skip the separator // } // } //} /** * A file scope helper function to concat path and file into * a full path */ //static std::string //CreateFullPath(const char* path, const char* file) //{ // std::string ret; //#ifdef _WIN32 // const char sep = '\\'; //#else // const char sep = '/'; //#endif // /** // * make sure the end of path is a separator // */ // ret = path; // if ( !ret.empty() && ret[ret.size()-1] != sep ) // { // ret += sep; // } // ret += file; // return ret; //} /** * A file scope typedef to make the cast code to the load * function cleaner to read. */ typedef ObjectFactoryBase* (* IGTL_LOAD_FUNCTION)(); ///** // * A file scoped function to determine if a file has // * the shared library extension in its name, this converts name to lower // * case before the compare, DynamicLoader always uses // * lower case for LibExtension values. // */ //inline bool //NameIsSharedLibrary(const char* name) //{ // std::string extension = igtlsys::DynamicLoader::LibExtension(); // //#ifdef __APPLE__ // // possible bug: CMake generated build file on the Mac makes // // libraries with a .dylib extension. kwsys guesses the extension // // should be ".so" // extension = ".dylib"; //#endif // // std::string sname = name; // if ( sname.rfind(extension) == sname.size() - extension.size() ) // { // return true; // } // return false; //} ///** // * // */ //void //ObjectFactoryBase //::LoadLibrariesInPath(const char* path) //{ // Directory::Pointer dir = Directory::New(); // if ( !dir->Load(path) ) // { // return; // } // // /** // * Attempt to load each file in the directory as a shared library // */ // for ( unsigned int i = 0; i < dir->GetNumberOfFiles(); i++ ) // { // const char* file = dir->GetFile(i); // /** // * try to make sure the file has at least the extension // * for a shared library in it. // */ // if ( NameIsSharedLibrary(file) ) // { // std::string fullpath = CreateFullPath(path, file); // LibHandle lib = DynamicLoader::OpenLibrary(fullpath.c_str()); // if ( lib ) // { // /** // * Look for the symbol igtlLoad in the library // */ // IGTL_LOAD_FUNCTION loadfunction // = (IGTL_LOAD_FUNCTION)DynamicLoader::GetSymbolAddress(lib, "igtlLoad"); // /** // * if the symbol is found call it to create the factory // * from the library // */ // if ( loadfunction ) // { // ObjectFactoryBase* newfactory = (*loadfunction)(); // // /** // * initialize class members if load worked // */ // newfactory->m_LibraryHandle = (void*)lib; // newfactory->m_LibraryPath = fullpath; // newfactory->m_LibraryDate = 0; // unused for now... // ObjectFactoryBase::RegisterFactory(newfactory); // } // else // { // // We would really like to close the lib if it does not // // contain the igtlLoad symbol. Unfortuantely, it seems that // // some systems crash on the call // // DynamicLoader::CloseLibrary(lib) if the lib has symbols // // that the current executable is using. // } // } // } // } //} /** * Recheck the IGTL_AUTOLOAD_PATH for new libraries */ void ObjectFactoryBase ::ReHash() { ObjectFactoryBase::UnRegisterAllFactories(); ObjectFactoryBase::Initialize(); } /** * initialize class members */ ObjectFactoryBase::ObjectFactoryBase() { m_LibraryHandle = 0; m_LibraryDate = 0; m_OverrideMap = new OverRideMap; } /** * Unload the library and free the path string */ ObjectFactoryBase ::~ObjectFactoryBase() { m_OverrideMap->erase(m_OverrideMap->begin(), m_OverrideMap->end()); delete m_OverrideMap; } /** * Add a factory to the registered list */ void ObjectFactoryBase ::RegisterFactory(ObjectFactoryBase* factory) { if ( factory->m_LibraryHandle == 0 ) { const char nonDynamicName[] = "Non-Dynamicaly loaded factory"; factory->m_LibraryPath = nonDynamicName; } // if ( strcmp(factory->GetIGTLSourceVersion(), // Version::GetIGTLSourceVersion()) != 0 ) // { // igtlGenericOutputMacro(<< "Possible incompatible factory load:" // << "\nRunning igtl version :\n" << Version::GetIGTLSourceVersion() // << "\nLoaded factory version:\n" << factory->GetIGTLSourceVersion() // << "\nLoading factory:\n" << factory->m_LibraryPath << "\n"); // } ObjectFactoryBase::Initialize(); ObjectFactoryBase::m_RegisteredFactories->push_back(factory); factory->Register(); } /** * */ void ObjectFactoryBase ::PrintSelf(std::ostream& os) const { Superclass::PrintSelf(os); const char* indent = " "; os << indent << "Factory DLL path: " << m_LibraryPath.c_str() << "\n"; os << indent << "Factory description: " << this->GetDescription() << std::endl; int num = static_cast( m_OverrideMap->size() ); os << indent << "Factory overides " << num << " classes:" << std::endl; //indent = indent.GetNextIndent(); for(OverRideMap::iterator i = m_OverrideMap->begin(); i != m_OverrideMap->end(); ++i) { os << indent << "Class : " << (*i).first.c_str() << "\n"; os << indent << "Overridden with: " << (*i).second.m_OverrideWithName.c_str() << std::endl; os << indent << "Enable flag: " << (*i).second.m_EnabledFlag << std::endl; os << indent << "Create object: " << (*i).second.m_CreateObject << std::endl; os << std::endl; } } /** * */ void ObjectFactoryBase ::UnRegisterFactory(ObjectFactoryBase* factory) { for ( std::list::iterator i = m_RegisteredFactories->begin(); i != m_RegisteredFactories->end(); ++i ) { if ( factory == *i ) { factory->UnRegister(); m_RegisteredFactories->remove(factory); return; } } } /** * unregister all factories and delete the RegisteredFactories list */ void ObjectFactoryBase ::UnRegisterAllFactories() { if ( ObjectFactoryBase::m_RegisteredFactories ) { // Collect up all the library handles so they can be closed // AFTER the factory has been deleted. std::list libs; for ( std::list::iterator i = m_RegisteredFactories->begin(); i != m_RegisteredFactories->end(); ++i ) { libs.push_back(static_cast((*i)->m_LibraryHandle)); } // Unregister each factory for ( std::list::iterator f = m_RegisteredFactories->begin(); f != m_RegisteredFactories->end(); ++f ) { (*f)->UnRegister(); } // // And delete the library handles all at once // for ( std::list::iterator lib = libs.begin(); // lib != libs.end(); // ++lib) // { // if((*lib)) // { // DynamicLoader::CloseLibrary(static_cast(*lib)); // } // } delete ObjectFactoryBase::m_RegisteredFactories; ObjectFactoryBase::m_RegisteredFactories = 0; } } /** * */ void ObjectFactoryBase ::RegisterOverride(const char* classOverride, const char* subclass, const char* description, bool enableFlag, CreateObjectFunctionBase* createFunction) { ObjectFactoryBase::OverrideInformation info; info.m_Description = description; info.m_OverrideWithName = subclass; info.m_EnabledFlag = enableFlag; info.m_CreateObject = createFunction; m_OverrideMap->insert(OverRideMap::value_type(classOverride, info)); } LightObject::Pointer ObjectFactoryBase ::CreateObject(const char* igtlclassname) { OverRideMap::iterator start = m_OverrideMap->lower_bound(igtlclassname); OverRideMap::iterator end = m_OverrideMap->upper_bound(igtlclassname); for ( OverRideMap::iterator i = start; i != end; ++i ) { if ( i != m_OverrideMap->end() && (*i).second.m_EnabledFlag) { return (*i).second.m_CreateObject->CreateObject(); } } return 0; } /** * */ void ObjectFactoryBase ::SetEnableFlag(bool flag, const char* className, const char* subclassName) { OverRideMap::iterator start = m_OverrideMap->lower_bound(className); OverRideMap::iterator end = m_OverrideMap->upper_bound(className); for ( OverRideMap::iterator i = start; i != end; ++i ) { if ( (*i).second.m_OverrideWithName == subclassName ) { (*i).second.m_EnabledFlag = flag; } } } /** * */ bool ObjectFactoryBase ::GetEnableFlag(const char* className, const char* subclassName) { OverRideMap::iterator start = m_OverrideMap->lower_bound(className); OverRideMap::iterator end = m_OverrideMap->upper_bound(className); for ( OverRideMap::iterator i = start; i != end; ++i ) { if ( (*i).second.m_OverrideWithName == subclassName ) { return (*i).second.m_EnabledFlag; } } return 0; } /** * */ void ObjectFactoryBase ::Disable(const char* className) { OverRideMap::iterator start = m_OverrideMap->lower_bound(className); OverRideMap::iterator end = m_OverrideMap->upper_bound(className); for ( OverRideMap::iterator i = start; i != end; ++i ) { (*i).second.m_EnabledFlag = 0; } } /** * */ std::list ObjectFactoryBase ::GetRegisteredFactories() { return *ObjectFactoryBase::m_RegisteredFactories; } /** * Return a list of classes that this factory overrides. */ std::list ObjectFactoryBase ::GetClassOverrideNames() { std::list ret; for ( OverRideMap::iterator i = m_OverrideMap->begin(); i != m_OverrideMap->end(); ++i ) { ret.push_back((*i).first); } return ret; } /** * Return a list of the names of classes that override classes. */ std::list ObjectFactoryBase ::GetClassOverrideWithNames() { std::list ret; for ( OverRideMap::iterator i = m_OverrideMap->begin(); i != m_OverrideMap->end(); ++i ) { ret.push_back((*i).second.m_OverrideWithName); } return ret; } /** * Retrun a list of descriptions for class overrides */ std::list ObjectFactoryBase ::GetClassOverrideDescriptions() { std::list ret; for ( OverRideMap::iterator i = m_OverrideMap->begin(); i != m_OverrideMap->end(); ++i ) { ret.push_back((*i).second.m_Description); } return ret; } /** * Return a list of enable flags */ std::list ObjectFactoryBase ::GetEnableFlags() { std::list ret; for( OverRideMap::iterator i = m_OverrideMap->begin(); i != m_OverrideMap->end(); ++i) { ret.push_back((*i).second.m_EnabledFlag); } return ret; } /** * Return the path to a dynamically loaded factory. */ const char * ObjectFactoryBase ::GetLibraryPath() { return m_LibraryPath.c_str(); } } // end namespace igtl openigtlink-3.0.0/Source/igtlObjectFactoryBase.h000066400000000000000000000170421501024245700216630ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkObjectFactoryBase.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlObjectFactoryBase_h #define __igtlObjectFactoryBase_h #include "igtlObject.h" #include "igtlCreateObjectFunction.h" #include #include namespace igtl { /** \class ObjectFactoryBase * \brief Create instances of classes using an object factory. * * ObjectFactoryBase is used to create igtl objects. The base class * ObjectFactoryBase contains a static method CreateInstance() that is * used to create igtl objects from the list of registerd ObjectFactoryBase * sub-classes. The first time CreateInstance() is called, all dll's or * shared libraries in the environment variable IGTL_AUTOLOAD_PATH are loaded * into the current process. The C function igtlLoad is called on each dll. * igtlLoad should return an instance of the factory sub-class implemented in * the shared library. IGTL_AUTOLOAD_PATH is an environment variable * containing a colon separated (semi-colon on win32) list of paths. * * This can be use to overide the creation of any object in IGTL. * * \ingroup IGTLSystemObjects */ class OverRideMap; class IGTLCommon_EXPORT ObjectFactoryBase : public Object { public: /** Standard class typedefs. */ typedef ObjectFactoryBase Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ igtlTypeMacro(ObjectFactoryBase, Object); /** Create and return an instance of the named igtl object. * Each loaded ObjectFactoryBase will be asked in the order * the factory was in the IGTL_AUTOLOAD_PATH. After the * first factory returns the object no other factories are asked. */ static LightObject::Pointer CreateInstance(const char* igtlclassname); /** Create and return all possible instances of the named igtl object. * Each loaded ObjectFactoryBase will be asked in the order * the factory was in the IGTL_AUTOLOAD_PATH. All created objects * will be returned in the list. */ static std::list CreateAllInstance(const char* igtlclassname); /** Re-check the IGTL_AUTOLOAD_PATH for new factory libraries. * This calls UnRegisterAll before re-loading. */ static void ReHash(); /** Register a factory so it can be used to create igtl objects. */ static void RegisterFactory(ObjectFactoryBase* ); /** Remove a factory from the list of registered factories. */ static void UnRegisterFactory(ObjectFactoryBase*); /** Unregister all factories. */ static void UnRegisterAllFactories(); /** Return the list of all registered factories. This is NOT a copy, * do not remove items from this list! */ static std::list GetRegisteredFactories(); /** All sub-classes of ObjectFactoryBase should must return the version of * IGTL they were built with. This should be implemented with the macro * IGTL_SOURCE_VERSION and NOT a call to Version::GetIGTLSourceVersion. * As the version needs to be compiled into the file as a string constant. * This is critical to determine possible incompatible dynamic factory loads. */ virtual const char* GetIGTLSourceVersion(void) const = 0; /** Return a descriptive string describing the factory. */ virtual const char* GetDescription(void) const = 0; /** Return a list of classes that this factory overrides. */ virtual std::list GetClassOverrideNames(); /** Return a list of the names of classes that override classes. */ virtual std::list GetClassOverrideWithNames(); /** Return a list of descriptions for class overrides. */ virtual std::list GetClassOverrideDescriptions(); /** Return a list of enable flags. */ virtual std::list GetEnableFlags(); /** Set the Enable flag for the specific override of className. */ virtual void SetEnableFlag(bool flag, const char* className, const char* subclassName); /** Get the Enable flag for the specific override of className. */ virtual bool GetEnableFlag(const char* className, const char* subclassName); /** Set all enable flags for the given class to 0. This will * mean that the factory will stop producing class with the given * name. */ virtual void Disable(const char* className); /** This returns the path to a dynamically loaded factory. */ const char* GetLibraryPath(); /** \class OverrideInformation * \brief Internal implementation class for ObjectFactorBase. */ struct OverrideInformation { std::string m_Description; std::string m_OverrideWithName; bool m_EnabledFlag; CreateObjectFunctionBase::Pointer m_CreateObject; }; protected: virtual void PrintSelf(std::ostream& os) const; /** Register object creation information with the factory. */ void RegisterOverride(const char* classOverride, const char* overrideClassName, const char* description, bool enableFlag, CreateObjectFunctionBase* createFunction); /** This method is provided by sub-classes of ObjectFactoryBase. * It should create the named igtl object or return 0 if that object * is not supported by the factory implementation. */ virtual LightObject::Pointer CreateObject(const char* igtlclassname ); ObjectFactoryBase(); virtual ~ObjectFactoryBase(); private: OverRideMap* m_OverrideMap; ObjectFactoryBase(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented /** Initialize the static members of ObjectFactoryBase. RegisterDefaults * is called here. */ static void Initialize(); /** Register default factories which are not loaded at run time. */ static void RegisterDefaults(); // /** Load dynamic factories from the IGTL_AUTOLOAD_PATH */ // static void LoadDynamicFactories(); // // /** Load all dynamic libraries in the given path */ // static void LoadLibrariesInPath( const char*); // /** list of registered factories */ static std::list* m_RegisteredFactories; /** Member variables for a factory set by the base class * at load or register time */ void* m_LibraryHandle; unsigned long m_LibraryDate; std::string m_LibraryPath; }; } // end namespace igtl #endif openigtlink-3.0.0/Source/igtlPointMessage.cxx000066400000000000000000000147761501024245700213160ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlPointMessage.h" #include "igtl_header.h" #include "igtl_point.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include #include namespace igtl { //---------------------------------------------------------------------- // igtl::PointElement class PointElement::PointElement() : Object() { this->m_Name = ""; this->m_GroupName = ""; this->m_RGBA[0] = 0; this->m_RGBA[1] = 0; this->m_RGBA[2] = 0; this->m_RGBA[3] = 0; this->m_Position[0] = 0.0; this->m_Position[1] = 0.0; this->m_Position[2] = 0.0; this->m_Radius = 0.0; this->m_Owner = ""; } PointElement::~PointElement() { } int PointElement::SetName(const char* name) { if (strlen(name) <= IGTL_POINT_LEN_NAME) { this->m_Name = name; return 1; } else { return 0; } } int PointElement::SetGroupName(const char* grpname) { if (strlen(grpname) <= IGTL_POINT_LEN_GROUP_NAME) { this->m_GroupName = grpname; return 1; } else { return 0; } } void PointElement::SetRGBA(igtlUint8 rgba[4]) { this->m_RGBA[0] = rgba[0]; this->m_RGBA[1] = rgba[1]; this->m_RGBA[2] = rgba[2]; this->m_RGBA[3] = rgba[3]; } void PointElement::SetRGBA(igtlUint8 r, igtlUint8 g, igtlUint8 b, igtlUint8 a) { this->m_RGBA[0] = r; this->m_RGBA[1] = g; this->m_RGBA[2] = b; this->m_RGBA[3] = a; } void PointElement::GetRGBA(igtlUint8* rgba) { rgba[0] = this->m_RGBA[0]; rgba[1] = this->m_RGBA[1]; rgba[2] = this->m_RGBA[2]; rgba[3] = this->m_RGBA[3]; } void PointElement::GetRGBA(igtlUint8& r, igtlUint8& g, igtlUint8& b, igtlUint8& a) { r = this->m_RGBA[0]; g = this->m_RGBA[1]; b = this->m_RGBA[2]; a = this->m_RGBA[3]; } void PointElement::SetPosition(igtlFloat32 position[3]) { this->m_Position[0] = position[0]; this->m_Position[1] = position[1]; this->m_Position[2] = position[2]; } void PointElement::SetPosition(igtlFloat32 x, igtlFloat32 y, igtlFloat32 z) { this->m_Position[0] = x; this->m_Position[1] = y; this->m_Position[2] = z; } void PointElement::GetPosition(igtlFloat32* position) { position[0] = this->m_Position[0]; position[1] = this->m_Position[1]; position[2] = this->m_Position[2]; } void PointElement::GetPosition(igtlFloat32& x, igtlFloat32& y, igtlFloat32& z) { x = this->m_Position[0]; y = this->m_Position[1]; z = this->m_Position[2]; } int PointElement::SetOwner(const char* owner) { if (strlen(owner) <= IGTL_POINT_LEN_OWNER) { this->m_Owner = owner; return 1; } else { return 0; } } //---------------------------------------------------------------------- // igtl::PointMessage class PointMessage::PointMessage() { this->m_SendMessageType = "POINT"; this->m_PointList.clear(); } PointMessage::~PointMessage() { } int PointMessage::AddPointElement(PointElement::Pointer& elem) { this->m_PointList.push_back(elem); return this->m_PointList.size(); } void PointMessage::ClearPointElement() { this->m_PointList.clear(); } int PointMessage::GetNumberOfPointElement() { return this->m_PointList.size(); } void PointMessage::GetPointElement(int index, PointElement::Pointer& elem) { if (index >= 0 && index < (int)this->m_PointList.size()) { elem = this->m_PointList[index]; } } int PointMessage::CalculateContentBufferSize() { // The content size is the sum of the header size and status message size. return IGTL_POINT_ELEMENT_SIZE * this->m_PointList.size(); } int PointMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_point_element* element; element = (igtl_point_element*)(this->m_Content); igtl_point_element* elementHolder = element; std::vector::iterator iter; for (iter = this->m_PointList.begin(); iter != this->m_PointList.end(); iter ++) { strncpy((char*)element->name, (*iter)->GetName(), IGTL_POINT_LEN_NAME); strncpy((char*)element->group_name, (*iter)->GetGroupName(), IGTL_POINT_LEN_GROUP_NAME); igtlUint8 rgba[4]; (*iter)->GetRGBA(rgba); element->rgba[0] = rgba[0]; element->rgba[1] = rgba[1]; element->rgba[2] = rgba[2]; element->rgba[3] = rgba[3]; igtlFloat32 position[3]; (*iter)->GetPosition(position); element->position[0] = position[0]; element->position[1] = position[1]; element->position[2] = position[2]; element->radius = (*iter)->GetRadius(); strncpy((char*)element->owner, (*iter)->GetOwner(), IGTL_POINT_LEN_OWNER); element ++; } igtl_point_convert_byte_order(elementHolder, this->m_PointList.size()); return 1; } int PointMessage::UnpackContent() { this->m_PointList.clear(); igtl_point_element* element = NULL; int nElement = 0; #if OpenIGTLink_HEADER_VERSION >= 2 element = (igtl_point_element*) (this->m_Content); nElement = igtl_point_get_data_n(CalculateReceiveContentSize()); #elif OpenIGTLink_PROTOCOL_VERSION <=2 element = (igtl_point_element*) this->m_Body; nElement = igtl_point_get_data_n(this->m_BodySizeToRead); #endif igtl_point_convert_byte_order(element, nElement); char strbuf[128]; for (int i = 0; i < nElement; i ++) { PointElement::Pointer elemClass = PointElement::New(); // Add '\n' at the end of each string // (necessary for a case, where a string reaches the maximum length.) strbuf[IGTL_POINT_LEN_NAME] = '\n'; strncpy(strbuf, (char*)element->name, IGTL_POINT_LEN_NAME); elemClass->SetName((const char*)strbuf); strbuf[IGTL_POINT_LEN_GROUP_NAME] = '\n'; strncpy(strbuf, (char*)element->group_name, IGTL_POINT_LEN_GROUP_NAME); elemClass->SetGroupName(strbuf); elemClass->SetRGBA(element->rgba); elemClass->SetPosition(element->position); elemClass->SetRadius(element->radius); strbuf[IGTL_POINT_LEN_OWNER] = '\n'; strncpy(strbuf, (char*)element->owner, IGTL_POINT_LEN_OWNER); elemClass->SetOwner(strbuf); this->m_PointList.push_back(elemClass); element ++; } return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlPointMessage.h000066400000000000000000000131771501024245700207350ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlPointMessage_h #define __igtlPointMessage_h #include #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #include "igtlImageMessage.h" namespace igtl { /// A class to manage point information. class IGTLCommon_EXPORT PointElement: public Object { public: typedef PointElement Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::PointElement, igtl::Object); igtlNewMacro(igtl::PointElement); public: /// Sets the name/description of the point. The string 'name' must not exceed 64 characters. int SetName(const char* name); /// Gets the name/description of the point. const char* GetName() { return this->m_Name.c_str(); }; /// Sets the group name e.g. "Labeled Point", "Landmark", "Fiducial", etc. int SetGroupName(const char* grpname); /// Gets the group name const char* GetGroupName() { return this->m_GroupName.c_str(); }; /// Sets the color of the point specified by an array of R, G, B and A. void SetRGBA(igtlUint8 rgba[4]); /// Sets the color of the point specified by values of R, G, B and A. void SetRGBA(igtlUint8 r, igtlUint8 g, igtlUint8 b, igtlUint8 a); /// Gets the color of the point using an array of R, G, B and A. void GetRGBA(igtlUint8* rgba); /// Gets the color of the point using values of R, G, B and A. void GetRGBA(igtlUint8& r, igtlUint8& g, igtlUint8& b, igtlUint8& a); /// Sets the position of the point by an array of x, y and z coordinates. void SetPosition(igtlFloat32 position[3]); /// Sets the position of the point by x, y and z coordinates. void SetPosition(igtlFloat32 x, igtlFloat32 y, igtlFloat32 z); /// Gets the position of the point using an array of x, y and z coordinates. void GetPosition(igtlFloat32* position); /// Gets the position of the point using x, y and z coordinates. void GetPosition(igtlFloat32& x, igtlFloat32& y, igtlFloat32& z); /// Sets the radius of the point. void SetRadius(igtlFloat32 radius) { this->m_Radius = radius; }; /// Gets the radius of the point. igtlFloat32 GetRadius() { return this->m_Radius; }; /// Sets the name of the image that owns this label map. int SetOwner(const char* owner); /// Gets the name of the image that owns this label map. const char* GetOwner() { return this->m_Owner.c_str(); }; protected: PointElement(); ~PointElement(); protected: /// name / description (< 64 bytes) std::string m_Name; /// Can be "Labeled Point", "Landmark", Fiducial", ... std::string m_GroupName; /// Color in R/G/B/A igtlUint8 m_RGBA[4]; /// Position igtlFloat32 m_Position[3]; /// Radius of the point. Can be 0. igtlFloat32 m_Radius; /// Device name of the ower image std::string m_Owner; }; /// A class for the GET_POINT message type. class IGTLCommon_EXPORT GetPointMessage: public MessageBase { public: typedef GetPointMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetPointMessage, igtl::MessageBase); igtlNewMacro(igtl::GetPointMessage); protected: GetPointMessage() : MessageBase() { this->m_SendMessageType = "GET_POINT"; }; ~GetPointMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// A class for the POINT message type. /// The POINT message type is designed to transfer information about fiducials, which are often used in surgical planning and navigation in the image-guided therapy. class IGTLCommon_EXPORT PointMessage: public MessageBase { public: typedef PointMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::PointMessage, igtl::MessageBase); igtlNewMacro(igtl::PointMessage); public: /// Adds a point to the list. It returns the number of points in the list after /// adding the point. int AddPointElement(PointElement::Pointer& elem); /// Clears the points in the list. void ClearPointElement(); /// Gets the number of points in the list. int GetNumberOfPointElement(); /// Gets a pointer to the point specified by 'index'. void GetPointElement(int index, PointElement::Pointer& elem); protected: PointMessage(); ~PointMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// A list of pointers to the points. std::vector m_PointList; }; } // namespace igtl #endif // _igtlPointMessage_hopenigtlink-3.0.0/Source/igtlPolyDataMessage.cxx000066400000000000000000000454011501024245700217270ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlPolyDataMessage.h" #include "igtlTypes.h" #include "igtl_header.h" #include "igtl_polydata.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include #include namespace igtl { // Description: // PolyDataPointArray class PolyDataPointArray::PolyDataPointArray() : Object() { Clear(); } PolyDataPointArray::~PolyDataPointArray() { } void PolyDataPointArray::Clear() { this->m_Data.clear(); } void PolyDataPointArray::SetNumberOfPoints(int n) { this->m_Data.resize(n); std::vector< Point >::iterator iter; for (iter = this->m_Data.begin(); iter != this->m_Data.end(); iter ++) { iter->resize(3); } } int PolyDataPointArray::GetNumberOfPoints() { return this->m_Data.size(); } int PolyDataPointArray::SetPoint(unsigned int id, igtlFloat32 * point) { if (id >= this->m_Data.size()) { return 0; } Point & dst = this->m_Data[id]; dst[0] = point[0]; dst[1] = point[1]; dst[2] = point[2]; return 1; } int PolyDataPointArray::SetPoint(unsigned int id, igtlFloat32 x, igtlFloat32 y, igtlFloat32 z) { if (id >= this->m_Data.size()) { return 0; } Point & dst = this->m_Data[id]; dst[0] = x; dst[1] = y; dst[2] = z; return 1; } int PolyDataPointArray::AddPoint(igtlFloat32 * point) { Point newPoint; newPoint.resize(3); newPoint[0] = point[0]; newPoint[1] = point[1]; newPoint[2] = point[2]; this->m_Data.push_back(newPoint); return 1; } int PolyDataPointArray::AddPoint(igtlFloat32 x, igtlFloat32 y, igtlFloat32 z) { Point newPoint; newPoint.resize(3); newPoint[0] = x; newPoint[1] = y; newPoint[2] = z; this->m_Data.push_back(newPoint); return 1; } int PolyDataPointArray::GetPoint(unsigned int id, igtlFloat32 & x, igtlFloat32 & y, igtlFloat32 & z) { if (id >= this->m_Data.size()) { return 0; } Point & dst = this->m_Data[id]; x = dst[0]; y = dst[1]; z = dst[2]; return 1; } int PolyDataPointArray::GetPoint(unsigned int id, igtlFloat32 * point) { if (id >= this->m_Data.size()) { return 0; } Point & dst = this->m_Data[id]; point[0] = dst[0]; point[1] = dst[1]; point[2] = dst[2]; return 1; } // Description: // PolyDataCellArray class to pass vertices, lines, polygons, and triangle strips PolyDataCellArray::PolyDataCellArray() : Object() { Clear(); } PolyDataCellArray::~PolyDataCellArray() {} void PolyDataCellArray::Clear() { this->m_Data.clear(); } igtlUint32 PolyDataCellArray::GetNumberOfCells() { return this->m_Data.size(); } void PolyDataCellArray::AddCell(int n, igtlUint32 * cell) { std::list newCell; for (int i = 0; i < n; i ++) { newCell.push_back(cell[i]); } if (n > 0) { this->m_Data.push_back(newCell); } } void PolyDataCellArray::AddCell(std::list cell) { this->m_Data.push_back(cell); } igtlUint32 PolyDataCellArray::GetCellSize(unsigned int id) { if (id >= this->m_Data.size()) { return 0; } return this->m_Data[id].size(); } igtlUint32 PolyDataCellArray::GetTotalSize() { igtlUint32 size; size = 0; std::vector< std::list >::iterator iter; for (iter = this->m_Data.begin(); iter != this->m_Data.end(); iter ++) { size += ((*iter).size() + 1); } return size * sizeof(igtlUint32); } int PolyDataCellArray::GetCell(unsigned int id, igtlUint32 * cell) { if (id >= this->m_Data.size()) { return 0; } std::list & src = this->m_Data[id]; std::list::iterator iter; for (iter = src.begin(); iter != src.end(); iter ++) { *cell = *iter; cell ++; } return 1; } int PolyDataCellArray::GetCell(unsigned int id, std::list& cell) { if (id >= this->m_Data.size()) { return 0; } std::list & src = this->m_Data[id]; cell.resize(src.size()); std::list::iterator srcIter; std::list::iterator dstIter = cell.begin(); for (srcIter = src.begin(); srcIter != src.end(); srcIter ++) { *dstIter = *srcIter; dstIter ++; } return 1; } // Description: // Attribute class used for passing attribute data PolyDataAttribute::PolyDataAttribute() : Object() { Clear(); } PolyDataAttribute::~PolyDataAttribute() { } void PolyDataAttribute::Clear() { this->m_Type = POINT_SCALAR; this->m_NComponents = 1; this->m_Name = ""; this->m_Data.clear(); this->m_Size = 0; } int PolyDataAttribute::SetType(int t, int n) { int valid = 0; switch(t) { case POINT_SCALAR: case CELL_SCALAR: if (n > 0 && n < 128) { valid = 1; this->m_NComponents = n; } break; case POINT_VECTOR: case CELL_VECTOR: valid = 1; this->m_NComponents = 3; break; case POINT_NORMAL: case CELL_NORMAL: valid = 1; this->m_NComponents = 3; break; case POINT_TENSOR: case CELL_TENSOR: valid = 1; this->m_NComponents = 9; break; case POINT_RGBA: case CELL_RGBA: valid = 1; this->m_NComponents = 4; break; default: break; } if (valid) { this->m_Type = t; unsigned int n = this->m_Size * this->m_NComponents; if (n != this->m_Data.size()) { // TODO: this may cause unnecesasry memory allocation, // unless m_Size == 0. // Memory should be reallocate just before use. this->m_Data.resize(n); } return t; } else { return -1; } } igtlUint32 PolyDataAttribute::GetNumberOfComponents() { return this->m_NComponents; } igtlUint32 PolyDataAttribute::SetSize(igtlUint32 size) { this->m_Size = size; unsigned int n = this->m_Size * this->m_NComponents; if (n != this->m_Data.size()) { // TODO: this may cause unnecesasry memory allocation. // Memory should be reallocate just before use. this->m_Data.resize(n); } this->m_Data.resize(size*this->m_NComponents); return this->m_Size; } igtlUint32 PolyDataAttribute::GetSize() { return this->m_Size; } void PolyDataAttribute::SetName(const char * name) { this->m_Name = name; } int PolyDataAttribute::SetData(igtlFloat32 * data) { if (!data) { return 0; } std::vector::iterator iter; for (iter = this->m_Data.begin(); iter != this->m_Data.end(); iter ++) { *iter = *data; data ++; } return 1; } int PolyDataAttribute::GetData(igtlFloat32 * data) { if (!data) { return 0; } std::vector::iterator iter; for (iter = this->m_Data.begin(); iter != this->m_Data.end(); iter ++) { *data = *iter; data ++; } return 1; } int PolyDataAttribute::SetNthData(unsigned int n, igtlFloat32 * data) { if (n >= this->m_Size) { return 0; } std::vector::iterator iter; iter = this->m_Data.begin() + n*this->m_NComponents; for (unsigned int i = 0; i < this->m_NComponents; i ++) { *iter = *data; iter ++; data ++; } return 1; } int PolyDataAttribute::GetNthData(unsigned int n, igtlFloat32 * data) { if (n >= this->m_Size) { return 0; } std::vector::iterator iter; iter = this->m_Data.begin() + n*this->m_NComponents; for (unsigned int i = 0; i < this->m_NComponents; i ++) { *data = *iter; iter ++; data ++; } return 1; } // Description: // PolyDataMessage class implementation PolyDataMessage::PolyDataMessage() { this->m_SendMessageType = "POLYDATA"; Clear(); } PolyDataMessage::~PolyDataMessage() { } void IGTLCommon_EXPORT SetPolyDataInfo(igtl_polydata_info * info, PolyDataMessage * pdm) { igtl_polydata_init_info(info); if (pdm->GetPoints()) { info->header.npoints = pdm->GetPoints()->GetNumberOfPoints(); } else { info->header.npoints = 0; } if (pdm->GetVertices()) { info->header.nvertices = pdm->GetVertices()->GetNumberOfCells(); info->header.size_vertices = pdm->GetVertices()->GetTotalSize(); } else { info->header.nvertices = 0; info->header.size_vertices = 0; } if (pdm->GetLines()) { info->header.nlines = pdm->GetLines()->GetNumberOfCells(); info->header.size_lines = pdm->GetLines()->GetTotalSize(); } else { info->header.nlines = 0; info->header.size_lines = 0; } if (pdm->GetPolygons()) { info->header.npolygons = pdm->GetPolygons()->GetNumberOfCells(); info->header.size_polygons = pdm->GetPolygons()->GetTotalSize(); } else { info->header.npolygons = 0; info->header.size_polygons = 0; } if (pdm->GetTriangleStrips()) { info->header.ntriangle_strips = pdm->GetTriangleStrips()->GetNumberOfCells(); info->header.size_triangle_strips = pdm->GetTriangleStrips()->GetTotalSize(); } else { info->header.ntriangle_strips = 0; info->header.size_triangle_strips = 0; } info->header.nattributes = pdm->GetNumberOfAttributes(); } void IGTLCommon_EXPORT SetPolyDataInfoAttribute(igtl_polydata_info * info, PolyDataMessage * pdm) { igtl_polydata_attribute * attr = info->attributes; for (unsigned int i = 0; i < info->header.nattributes; i ++) { PolyDataAttribute * src = pdm->GetAttribute(i); if (src) { attr->type = src->GetType(); attr->ncomponents = src->GetNumberOfComponents(); attr->n = src->GetSize(); //attr->name = const_cast(src->GetName()); // TODO: aloways allocating memory isn't a good approach... if (attr->name) { free(attr->name); } attr->name = (char *) malloc(strlen(src->GetName())+1); if (attr->name) { strcpy(attr->name, src->GetName()); } if (attr->data) { free(attr->data); } igtlUint32 size = attr->ncomponents * attr->n; attr->data = (igtlFloat32*)malloc((size_t)size*sizeof(igtlFloat32)); if (attr->data) { src->GetData(attr->data); } attr ++; } } } void IGTLCommon_EXPORT UnSetPolyDataInfoAttribute(igtl_polydata_info * info) { igtl_polydata_attribute * attr = info->attributes; for (unsigned int i = 0; i < info->header.nattributes; i ++) { attr->type = 0; attr->ncomponents = 0; attr->n = 0; if (attr->name) { free(attr->name); attr->name = NULL; } if (attr->data) { free(attr->data); attr->data = NULL; } attr ++; } } int PolyDataMessage::CalculateContentBufferSize() { // TODO: The current implementation of GetBodyPackSize() allocates // igtl_polydata_info and the array of igtl_polydata_attribute to calculate // the size of pack. However, this approach is not efficient because // it causes unnecessary memory allocation. int dataSize; igtl_polydata_info info; SetPolyDataInfo(&info, this); // Instead of calling igtl_polydata_alloc_info(), we only allocate // memory for the attribute array, since igtl_polydata_alloc_info() // allocates also allocates the memory area for actual points and // cell data, which is not necessary to calculate polydata size. info.attributes = new igtl_polydata_attribute[info.header.nattributes]; if (!info.attributes) { //ERROR return 0; } // init attributes igtl_polydata_attribute * attr = info.attributes; for (unsigned int i = 0; i < info.header.nattributes; i ++) { attr->type = 0; attr->ncomponents = 0; attr->n = 0; attr->name = NULL; attr->data = NULL; attr ++; } SetPolyDataInfoAttribute(&info, this); dataSize = igtl_polydata_get_size(&info, IGTL_TYPE_PREFIX_NONE); UnSetPolyDataInfoAttribute(&info); //delete [] (info.attributes); delete [] info.attributes; return dataSize; } int PolyDataMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_polydata_info info; SetPolyDataInfo(&info, this); if (igtl_polydata_alloc_info(&info) == 0) { return 0; } //SetPolyDataInfoAttribute(&info, this); // Points if (info.points) { igtlFloat32 * ptr_f = info.points; for (int i = 0; i < this->m_Points->GetNumberOfPoints(); i ++) { igtlFloat32 points[3]; this->m_Points->GetPoint(i, points); *(ptr_f++) = points[0]; *(ptr_f++) = points[1]; *(ptr_f++) = points[2]; } } //Vertices if (info.vertices) { igtlUint32 * ptr_i = info.vertices; for (unsigned int i = 0; i < this->m_Vertices->GetNumberOfCells(); i ++) { *ptr_i = this->m_Vertices->GetCellSize(i); ptr_i ++; this->m_Vertices->GetCell(i, ptr_i); ptr_i += this->m_Vertices->GetCellSize(i); } } //Lines if (info.lines) { igtlUint32 * ptr_i = info.lines; for (unsigned int i = 0; i < this->m_Lines->GetNumberOfCells(); i ++) { *ptr_i = this->m_Lines->GetCellSize(i); ptr_i ++; this->m_Lines->GetCell(i, ptr_i); ptr_i += this->m_Lines->GetCellSize(i); } } //Polygons if (info.polygons) { igtlUint32 * ptr_i = info.polygons; for (unsigned int i = 0; i < this->m_Polygons->GetNumberOfCells(); i ++) { *ptr_i = this->m_Polygons->GetCellSize(i); ptr_i ++; this->m_Polygons->GetCell(i, ptr_i); ptr_i += this->m_Polygons->GetCellSize(i); } } //TriangleStrips if (info.triangle_strips) { igtlUint32 * ptr_i = info.triangle_strips; for (unsigned int i = 0; i < this->m_TriangleStrips->GetNumberOfCells(); i ++) { *ptr_i = this->m_TriangleStrips->GetCellSize(i); ptr_i ++; this->m_TriangleStrips->GetCell(i, ptr_i); ptr_i += this->m_TriangleStrips->GetCellSize(i); } } SetPolyDataInfoAttribute(&info, this); igtl_polydata_pack(&info, this->m_Content, IGTL_TYPE_PREFIX_NONE); igtl_polydata_free_info(&info); return 1; } int PolyDataMessage::UnpackContent() { igtl_polydata_info info; igtl_polydata_init_info(&info); int r = 0; r = igtl_polydata_unpack(IGTL_TYPE_PREFIX_NONE, (void*)this->m_Content, &info, this->CalculateReceiveContentSize()); if ( r == 0) { return 0; } // Points if (this->m_Points.IsNull()) { this->m_Points = igtl::PolyDataPointArray::New(); } this->m_Points->Clear(); if (info.header.npoints > 0) { this->m_Points->SetNumberOfPoints(info.header.npoints); for (unsigned int i = 0; i < info.header.npoints; i ++) { this->m_Points->SetPoint(i, &(info.points[i*3])); } } igtlUint32 * ptr; // Vertices if (this->m_Vertices.IsNull()) { this->m_Vertices = igtl::PolyDataCellArray::New(); } this->m_Vertices->Clear(); ptr = info.vertices; for (unsigned int i = 0; i < info.header.nvertices; i ++) { unsigned int n = *ptr; ptr ++; this->m_Vertices->AddCell(n, ptr); ptr += n; } // Lines if (this->m_Lines.IsNull()) { this->m_Lines = igtl::PolyDataCellArray::New(); } this->m_Lines->Clear(); ptr = info.lines; for (unsigned int i = 0; i < info.header.nlines; i ++) { unsigned int n = *ptr; ptr ++; this->m_Lines->AddCell(n, ptr); ptr += n; } // Polygons if (this->m_Polygons.IsNull()) { this->m_Polygons = igtl::PolyDataCellArray::New(); } this->m_Polygons->Clear(); ptr = info.polygons; for (unsigned int i = 0; i < info.header.npolygons; i ++) { unsigned int n = *ptr; ptr ++; this->m_Polygons->AddCell(n, ptr); ptr += n; } // TriangleStrips if (this->m_TriangleStrips.IsNull()) { this->m_TriangleStrips = igtl::PolyDataCellArray::New(); } this->m_TriangleStrips->Clear(); ptr = info.triangle_strips; for (unsigned int i = 0; i < info.header.ntriangle_strips; i ++) { unsigned int n = *ptr; ptr ++; this->m_TriangleStrips->AddCell(n, ptr); ptr += n; } // Attributes this->m_Attributes.clear(); igtl_polydata_attribute * attr = info.attributes; for (unsigned int i = 0; i < info.header.nattributes; i ++) { PolyDataAttribute::Pointer pda = PolyDataAttribute::New(); if (pda.IsNotNull()) { pda->Clear(); pda->SetType(attr->type, attr->ncomponents); pda->SetSize(attr->n); pda->SetName(attr->name); pda->SetData(attr->data); attr ++; this->m_Attributes.push_back(pda); } } return 1; } void PolyDataMessage::Clear() { if (this->m_Points.IsNotNull()) { //this->m_Points->Delete(); this->m_Points = NULL; } if (this->m_Vertices.IsNotNull()) { //this->m_Vertices->Delete(); this->m_Vertices = NULL; } if(this->m_Lines.IsNotNull()) { //this->m_Lines->Delete(); this->m_Lines = NULL; } if (this->m_Polygons.IsNotNull()) { //this->m_Polygons->Delete(); this->m_Polygons = NULL; } if (this->m_TriangleStrips.IsNotNull()) { //this->m_TriangleStrips->Delete(); this->m_TriangleStrips = NULL; } // TODO: is this OK? this->m_Attributes.clear(); } void PolyDataMessage::ClearAttributes() { std::vector::iterator iter; for (iter = this->m_Attributes.begin(); iter != this->m_Attributes.end(); iter ++) { *iter = NULL; } this->m_Attributes.clear(); } void PolyDataMessage::AddAttribute(PolyDataAttribute * att) { this->m_Attributes.push_back(att); } int PolyDataMessage::GetNumberOfAttributes() { return this->m_Attributes.size(); } PolyDataAttribute * PolyDataMessage::GetAttribute(unsigned int id) { if (id >= this->m_Attributes.size()) { return NULL; } return this->m_Attributes[id]; } GetPolyDataMessage::GetPolyDataMessage() { this->m_SendMessageType = "GET_POLYDATA"; } bool RTSPolyDataMessage::GetStatus() const { return m_Status == 1; } void RTSPolyDataMessage::SetStatus(bool status) { m_Status = status ? 1 : 0; } int RTSPolyDataMessage::CalculateContentBufferSize() { return sizeof(igtl_uint8); } int RTSPolyDataMessage::PackContent() { AllocateBuffer(); igtl_uint8* content; // Copy data #if OpenIGTLink_HEADER_VERSION >= 2 content = this->m_Content; #else content = this->m_Body; #endif *content = m_Status; return 1; } int RTSPolyDataMessage::UnpackContent() { igtl_uint8* content; #if OpenIGTLink_HEADER_VERSION >= 2 content = this->m_Content; #else content = this->m_Body; #endif this->m_Status = *content; return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlPolyDataMessage.h000066400000000000000000000310621501024245700213520ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlPolyDataMessage_h #define __igtlPolyDataMessage_h #include #include "igtlObject.h" #include "igtlMacro.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" namespace igtl { /// A class for the GET_POLYDATA message type. class IGTLCommon_EXPORT GetPolyDataMessage: public MessageBase { public: typedef GetPolyDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetPolyDataMessage, igtl::MessageBase); igtlNewMacro(igtl::GetPolyDataMessage); protected: GetPolyDataMessage(); ~GetPolyDataMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// A class for the RTS_POLYDATA message type. class IGTLCommon_EXPORT RTSPolyDataMessage : public MessageBase { public: typedef RTSPolyDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::RTSPolyDataMessage, igtl::MessageBase); igtlNewMacro(igtl::RTSPolyDataMessage); bool GetStatus() const; void SetStatus(bool status); protected: RTSPolyDataMessage() : MessageBase() { this->m_SendMessageType = "RTS_POLYDATA"; }; ~RTSPolyDataMessage() {}; protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); protected: /// Result of the previous GET_POLYDATA/POLYDATA message igtl_uint8 m_Status; }; /// A class for the STP_POLYDATA message type. class IGTLCommon_EXPORT StopPolyDataMessage: public MessageBase { public: typedef StopPolyDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StopPolyDataMessage, igtl::MessageBase); igtlNewMacro(igtl::StopPolyDataMessage); protected: StopPolyDataMessage() : MessageBase() { this->m_SendMessageType = "STP_POLYDATA"; }; ~StopPolyDataMessage() {}; protected: virtual int GetBodyPackSize() { return 0; }; virtual int PackBody() { AllocatePack(); return 1; }; virtual int UnpackBody() { return 1; }; }; /// A class for the STT_POLYDATA message type. class IGTLCommon_EXPORT StartPolyDataMessage : public MessageBase { public: typedef StartPolyDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StartPolyDataMessage, igtl::MessageBase); igtlNewMacro(igtl::StartPolyDataMessage); protected: StartPolyDataMessage() : MessageBase() { this->m_SendMessageType = "STT_POLYDATA"; }; ~StartPolyDataMessage() {}; protected: virtual int GetBodyPackSize() { return 0; }; virtual int PackBody() { AllocatePack(); return 1; }; virtual int UnpackBody() { return 1; }; }; // A class to manage a point array. class IGTLCommon_EXPORT PolyDataPointArray : public Object { public: /// A vector to represent coordinates of a point. typedef std::vector Point; public: typedef PolyDataPointArray Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::PolyDataPointArray, igtl::Object); igtlNewMacro(igtl::PolyDataPointArray); protected: PolyDataPointArray(); ~PolyDataPointArray(); public: /// Clears the all points in the list. void Clear(); /// Sets the number of points. This function will change the size of the list. void SetNumberOfPoints(int n); /// Gets the number of points in the list. int GetNumberOfPoints(); /// Substitutes the point specified by 'id' with a point specified by 'point'. /// The 'point' contains the x, y, and z coordinates of the point. int SetPoint(unsigned int id, igtlFloat32 * point); /// Substitutes the point specified by 'id' with a point specified by 'x', 'y' and 'z'. int SetPoint(unsigned int id, igtlFloat32 x, igtlFloat32 y, igtlFloat32 z); /// Adds a point specified by 'point' to the list. /// The 'point' contains the x, y, and z coordinates of the point. int AddPoint(igtlFloat32 * point); /// Adds a point 'point' specified by 'x', 'y' and 'z'. int AddPoint(igtlFloat32 x, igtlFloat32 y, igtlFloat32 z); /// Gets the coordinates of the point specified by 'id' int GetPoint(unsigned int id, igtlFloat32 & x, igtlFloat32 & y, igtlFloat32 & z); /// Gets the coordinates of the point specified by 'id' int GetPoint(unsigned int id, igtlFloat32 * point); private: /// A list of the points. std::vector< Point > m_Data; }; // The PolyDataCellArray class is used to pass vertices, lines, polygons, and triangle strips class IGTLCommon_EXPORT PolyDataCellArray : public Object { public: enum { NULL_POINT = 0xFFFFFFFF, }; public: typedef PolyDataCellArray Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::PolyDataCellArray, igtl::Object); igtlNewMacro(igtl::PolyDataCellArray); protected: PolyDataCellArray(); ~PolyDataCellArray(); public: /// Clears the cell array. void Clear(); /// Gets the number of cells in the array. igtlUint32 GetNumberOfCells(); /// Adds an array of cells stored in 'cell'. The number of cells is specified by 'n'. void AddCell(int n, igtlUint32 * cell); /// Adds an array of cells stored in 'cell'. void AddCell(std::list cell); /// GetTotalSize() returns the total memory size of the cell data array in /// POLYDATA message. Cell data array is array of cell data, consisting of /// and array of . Both /// and are unsigned 32-bit integer. /// Consequently, the total size can be calculated by: /// sizeof(igtlUint32) * (number of points for 0th cell + 1) + (number of points for 1th cell + 1) /// ... + (number of points for (N-1)th cell + 1). Note that this includes the first igtlUint32 value /// that specifies the number of points in each cell. igtlUint32 GetTotalSize(); /// Gets the size of the cell specified by 'id'. igtlUint32 GetCellSize(unsigned int id); /// Gets the cell specified by the 'id'. A list of points in the cell will be stored in the /// 'cell'. A memory area sufficient to store the points in the cell must be allocated /// before calling GetCell() function, and specified as 'cell'. int GetCell(unsigned int id, igtlUint32 * cell); /// Gets the cell specified by the 'id'. A list of points in the cell will be stored in the 'cell'. int GetCell(unsigned int id, std::list& cell); private: /// A lists of the cells. Each cell consists of multiple points. std::vector< std::list > m_Data; }; /// Attribute class used for passing attribute data. class IGTLCommon_EXPORT PolyDataAttribute : public Object { public: /// Point and cell types. enum { POINT_SCALAR = 0x00, POINT_VECTOR = 0x01, POINT_NORMAL = 0x02, POINT_TENSOR = 0x03, POINT_RGBA = 0x04, CELL_SCALAR = 0x10, CELL_VECTOR = 0x11, CELL_NORMAL = 0x12, CELL_TENSOR = 0x13, CELL_RGBA = 0x14, }; public: typedef PolyDataAttribute Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::PolyDataAttribute, igtl::Object); igtlNewMacro(igtl::PolyDataAttribute); protected: PolyDataAttribute(); ~PolyDataAttribute(); public: /// Clears the attributes void Clear(); /// SetType() is used to set the attribute type. If the attribute is set properly, /// the function returns the type value (POINT_* or CELL_*). Otherwise /// the function returns negative value. The second argument will be ignored /// if 't' is neither POINT_SCALAR nor CELL_SCALAR. /// If the POINT_SCALAR and CELL_SCALAR is specified as 't', the number of /// components can be specified as the second argument. The number of /// components must be 0 < n < 128. int SetType(int t, int n=1); /// Gets the attribute type. igtlUint8 GetType() { return this->m_Type; }; /// Gets the number of components. The number depends on the type of the points/cells e.g. /// 3 in case of POINT_VECTOR. igtlUint32 GetNumberOfComponents(); /// Sets the size of the attribute. igtlUint32 SetSize(igtlUint32 size); /// Gets the size of the attribute. igtlUint32 GetSize(); /// Sets the name of the attribute. void SetName(const char * name); /// Gets the name of the attribute. const char* GetName() { return this->m_Name.c_str(); }; /// Sets the attribute by byte array. int SetData(igtlFloat32 * data); /// Gets the attribute as a byte array. int GetData(igtlFloat32 * data); /// Sets the Nth data. int SetNthData(unsigned int n, igtlFloat32 * data); /// Gets the Nth data. int GetNthData(unsigned int n, igtlFloat32 * data); private: /// The attribute type. igtlUint8 m_Type; /// The number of components. igtlUint8 m_NComponents; /// The size of the attribute. igtlUint32 m_Size; /// The name of the attribute. std::string m_Name; /// The list of attributes. std::vector m_Data; }; /// A class for the POLYDATA message type. class IGTLCommon_EXPORT PolyDataMessage: public MessageBase { public: typedef PolyDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::PolyDataMessage, igtl::MessageBase); igtlNewMacro(igtl::PolyDataMessage); public: /// Clears the polydata. void Clear(); /// Sets an array of points. igtlSetObjectMacro(Points, PolyDataPointArray); /// Gets an array of points. igtlGetObjectMacro(Points, PolyDataPointArray); /// Sets an array of vertices. igtlSetObjectMacro(Vertices, PolyDataCellArray); /// Gets an array of vertices. igtlGetObjectMacro(Vertices, PolyDataCellArray); /// Sets an array of lines. igtlSetObjectMacro(Lines, PolyDataCellArray); /// Gets an array of lines. igtlGetObjectMacro(Lines, PolyDataCellArray); /// Sets an array of polygons. igtlSetObjectMacro(Polygons, PolyDataCellArray); /// Gets an array of polygons. igtlGetObjectMacro(Polygons, PolyDataCellArray); /// Sets an array of triangle strips. igtlSetObjectMacro(TriangleStrips, PolyDataCellArray); /// Gets an array of triangle strips. igtlGetObjectMacro(TriangleStrips, PolyDataCellArray); /// Clears the attributes. void ClearAttributes(); /// Adds an attribute. void AddAttribute(PolyDataAttribute * att); /// Gets the number of attributes. int GetNumberOfAttributes(); /// Gets an attribute specified by 'id'. PolyDataAttribute * GetAttribute(unsigned int id); protected: PolyDataMessage(); ~PolyDataMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// A pointer to the array of points. PolyDataPointArray::Pointer m_Points; /// A pointer to the array of vertices. PolyDataCellArray::Pointer m_Vertices; /// A pointer to the array of lines. PolyDataCellArray::Pointer m_Lines; /// A pointer to the array of polygons. PolyDataCellArray::Pointer m_Polygons; /// A pointer to the array of triangle strips. PolyDataCellArray::Pointer m_TriangleStrips; /// A list of pointers to the attributes. std::vector m_Attributes; }; } // namespace igtl #endif // _igtlPolyDataMessage_hopenigtlink-3.0.0/Source/igtlPositionMessage.cxx000066400000000000000000000147241501024245700220220ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlPositionMessage.h" #include "igtl_header.h" #include "igtl_position.h" #include #include namespace igtl { PositionMessage::PositionMessage(): MessageBase() { Init(); m_SendMessageType = "POSITION"; } PositionMessage::~PositionMessage() { } void PositionMessage::Init() { this->m_PackType = ALL; this->m_Position[0] = 0.0; this->m_Position[1] = 0.0; this->m_Position[2] = 0.0; this->m_Quaternion[0] = 0.0; this->m_Quaternion[1] = 0.0; this->m_Quaternion[2] = 0.0; this->m_Quaternion[3] = 1.0; } void PositionMessage::SetPackType(int t) { if (t >= POSITION_ONLY && t <= ALL) { this->m_PackType = t; } } int PositionMessage::SetPackTypeByContentSize(int s) { if (s == IGTL_POSITION_MESSAGE_POSITON_ONLY_SIZE) { this->m_PackType = POSITION_ONLY; } else if (s == IGTL_POSITION_MESSAGE_WITH_QUATERNION3_SIZE) { this->m_PackType = WITH_QUATERNION3; } else if (s == IGTL_POSITION_MESSAGE_DEFAULT_SIZE) { this->m_PackType = ALL; } else { // Do any error handling? this->m_PackType = ALL; return 0; } return this->m_PackType; } void PositionMessage::SetPosition(const float* pos) { this->m_Position[0] = pos[0]; this->m_Position[1] = pos[1]; this->m_Position[2] = pos[2]; } void PositionMessage::SetPosition(float x, float y, float z) { this->m_Position[0] = x; this->m_Position[1] = y; this->m_Position[2] = z; } void PositionMessage::SetQuaternion(const float* quat) { this->m_Quaternion[0] = quat[0]; this->m_Quaternion[1] = quat[1]; this->m_Quaternion[2] = quat[2]; this->m_Quaternion[3] = quat[3]; } void PositionMessage::SetQuaternion(float ox, float oy, float oz, float w) { this->m_Quaternion[0] = ox; this->m_Quaternion[1] = oy; this->m_Quaternion[2] = oz; this->m_Quaternion[3] = w; } void PositionMessage::GetPosition(float* pos) { pos[0] = this->m_Position[0]; pos[1] = this->m_Position[1]; pos[2] = this->m_Position[2]; } void PositionMessage::GetPosition(float* x, float* y, float* z) { *x = this->m_Position[0]; *y = this->m_Position[1]; *z = this->m_Position[2]; } void PositionMessage::GetQuaternion(float* quat) { quat[0] = this->m_Quaternion[0]; quat[1] = this->m_Quaternion[1]; quat[2] = this->m_Quaternion[2]; quat[3] = this->m_Quaternion[3]; } void PositionMessage::GetQuaternion(float* ox, float* oy, float* oz, float* w) { *ox = this->m_Quaternion[0]; *oy = this->m_Quaternion[1]; *oz = this->m_Quaternion[2]; *w = this->m_Quaternion[3]; } int PositionMessage::SetMessageHeader(const MessageHeader* mb) { int rc = Copy(mb); int rt = SetPackTypeByContentSize(this->CalculateContentBufferSize()); return (rc && rt); } int PositionMessage::CalculateContentBufferSize() { int ret; switch (this->m_PackType) { case POSITION_ONLY: ret = IGTL_POSITION_MESSAGE_POSITON_ONLY_SIZE; break; case WITH_QUATERNION3: ret = IGTL_POSITION_MESSAGE_WITH_QUATERNION3_SIZE; break; default: ret = IGTL_POSITION_MESSAGE_DEFAULT_SIZE; break; } return ret; } int PositionMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_position* p = NULL; #if OpenIGTLink_HEADER_VERSION >= 2 p = (igtl_position*)(this->m_Content); #elif OpenIGTLink_PROTOCOL_VERSION <=2 p = (igtl_position*)(this->m_Body); #endif p->position[0] = this->m_Position[0]; p->position[1] = this->m_Position[1]; p->position[2] = this->m_Position[2]; if (this->m_PackType == WITH_QUATERNION3) { p->quaternion[0] = this->m_Quaternion[0]; p->quaternion[1] = this->m_Quaternion[1]; p->quaternion[2] = this->m_Quaternion[2]; } else if (this->m_PackType == ALL) { p->quaternion[0] = this->m_Quaternion[0]; p->quaternion[1] = this->m_Quaternion[1]; p->quaternion[2] = this->m_Quaternion[2]; p->quaternion[3] = this->m_Quaternion[3]; } igtl_position_convert_byte_order(p); return 1; } int PositionMessage::UnpackContent() { igtl_position* p = NULL; #if OpenIGTLink_HEADER_VERSION >= 2 p = (igtl_position*)(this->m_Content); #elif OpenIGTLink_PROTOCOL_VERSION <=2 p = (igtl_position*)(this->m_Body); #endif int contentSize = CalculateReceiveContentSize(); if( contentSize == -1 ) { return 0; } switch (contentSize) { case IGTL_POSITION_MESSAGE_POSITON_ONLY_SIZE: this->m_PackType = POSITION_ONLY; igtl_position_convert_byte_order_position_only(p); break; case IGTL_POSITION_MESSAGE_WITH_QUATERNION3_SIZE: this->m_PackType = WITH_QUATERNION3; igtl_position_convert_byte_order_quaternion3(p); break; default: //IGTL_POSITION_MESSAGE_DEFAULT_SIZE this->m_PackType = ALL; igtl_position_convert_byte_order(p); break; } this->m_Position[0] = p->position[0]; this->m_Position[1] = p->position[1]; this->m_Position[2] = p->position[2]; if (this->m_PackType == POSITION_ONLY) { this->m_Quaternion[0] = 0.0; this->m_Quaternion[1] = 0.0; this->m_Quaternion[2] = 0.0; this->m_Quaternion[3] = 1.0; } if (this->m_PackType == WITH_QUATERNION3) { float ox = p->quaternion[0]; float oy = p->quaternion[1]; float oz = p->quaternion[2]; float sq = 1.0 - (ox*ox + oy*oy + oz*oz); if (sq < 0.0) { // TODO: what should we do with invalid quaternion? // Tentatively we set (0, 0, 0, 1); this->m_Quaternion[0] = 0.0; this->m_Quaternion[1] = 0.0; this->m_Quaternion[2] = 0.0; this->m_Quaternion[3] = 1.0; } else { float w = sqrt(sq); this->m_Quaternion[0] = ox; this->m_Quaternion[1] = oy; this->m_Quaternion[2] = oz; this->m_Quaternion[3] = w; } } else if (this->m_PackType == ALL) { this->m_Quaternion[0] = p->quaternion[0]; this->m_Quaternion[1] = p->quaternion[1]; this->m_Quaternion[2] = p->quaternion[2]; this->m_Quaternion[3] = p->quaternion[3]; } return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlPositionMessage.h000066400000000000000000000102241501024245700214360ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlPositionMessage_h #define __igtlPositionMessage_h #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" namespace igtl { /// The POSITION data type is used to transfer position and orientation information. /// The data are a combination of 3-dimensional vector for the position and quaternion /// for the orientation. Although equivalent position and orientation can be described /// with the TRANSFORM data type, the POSITION data type has the advantage of smaller /// data size (19%). It is therefore more suitable for pushing high frame-rate data /// from tracking devices. class IGTLCommon_EXPORT PositionMessage: public MessageBase { public: /// Types of message formats. The format of the POSITION message type can contain /// only a 3-element position vector (POSITION_ONLY), a combination of 3-element /// position vector and 3-element quaternion (WITH_QUATERNION3), or a combination /// of 3-element position vector and 4-element quaternion (ALL). enum { POSITION_ONLY = 1, WITH_QUATERNION3, ALL, }; public: typedef PositionMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::PositionMessage, igtl::MessageBase); igtlNewMacro(igtl::PositionMessage); public: /// Initializes the class. void Init(); /// Sets the type of the pack. 't' must be either POSITION_ONLY, WITH_QUATERNION3, or ALL. void SetPackType(int t); /* POSITION_ONLY / WITH_QUATERNION3 / ALL */ /// Gets the type of the pack. The returned value must be either POSITION_ONLY, WITH_QUATERNION3, or ALL. int GetPackType() { return m_PackType; }; /// Specifies the pack type by body size (in most case obtained from general header). int SetPackTypeByContentSize(int s); /// Sets the position by 3-element array of x, y, and z coordinates. void SetPosition(const float* pos); /// Sets the position by x, y, and z coordinates. void SetPosition(float x, float y, float z); /// Sets the quaternion by 4-element array. void SetQuaternion(const float* quat); /// Sets the quaternion by elements of the quaternion (ox, oy, oz and w). void SetQuaternion(float ox, float oy, float oz, float w); /// Gets the position. The function substitutes 3-element array of x, y and z coordinates in 'pos'. void GetPosition(float* pos); /// Gets the position. The function substitutes the coordinates in 'x', 'y', and 'z'. void GetPosition(float* x, float* y, float* z); /// Gets the quaternion. The function substitutes the array of elements of the quaternion in 'quat'. void GetQuaternion(float* quat); /// Gets the quaternion. The function substitutes the elements of the quaternion in 'ox', 'oy', 'oz' and 'w'. void GetQuaternion(float* ox, float* oy, float* oz, float* w); /// Sets the message header. // TODO: Is this needed or integrated in igtlMessageBase? virtual int SetMessageHeader(const MessageHeader* mb); protected: PositionMessage(); ~PositionMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// The type of message formats (either POSITION_ONLY, WITH_QUATERNION3, or ALL). igtlInt32 m_PackType; /// An array of x, y, and z coordinates for the position. igtlFloat32 m_Position[3]; /// An array of ox, oy, oz, and w elements for the quaternion. igtlFloat32 m_Quaternion[4]; }; } // namespace igtl #endif // _igtlPositionMessage_h openigtlink-3.0.0/Source/igtlQuaternionTrackingDataMessage.cxx000066400000000000000000000222511501024245700246120ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlQuaternionTrackingDataMessage.h" #include "igtlMath.h" #include "igtl_header.h" #include "igtl_qtdata.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include #include namespace igtl { //---------------------------------------------------------------------- // igtl::QuaternionTrackingDataElement class QuaternionTrackingDataElement::QuaternionTrackingDataElement() : Object() { this->m_Name = ""; this->m_Type = TYPE_TRACKER; this->m_position[0] = 0; this->m_position[1] = 0; this->m_position[2] = 0; this->m_quaternion[0] = 0; this->m_quaternion[1] = 0; this->m_quaternion[2] = 0; this->m_quaternion[3] = 1; } QuaternionTrackingDataElement::~QuaternionTrackingDataElement() { } int QuaternionTrackingDataElement::SetName(const char* name) { if (strlen(name) <= IGTL_QTDATA_LEN_NAME) { this->m_Name = name; return 1; } else { return 0; } } int QuaternionTrackingDataElement::SetType(igtlUint8 type) { if(type == TYPE_TRACKER || type == TYPE_6D || type == TYPE_3D || type == TYPE_5D) { this->m_Type = type; return type; } else { return 0; } } void QuaternionTrackingDataElement::SetPosition(float p[3]) { this->m_position[0] = p[0]; this->m_position[1] = p[1]; this->m_position[2] = p[2]; } void QuaternionTrackingDataElement::GetPosition(float p[3]) { p[0] = this->m_position[0]; p[1] = this->m_position[1]; p[2] = this->m_position[2]; } void QuaternionTrackingDataElement::SetPosition(float px, float py, float pz) { this->m_position[0] = px; this->m_position[1] = py; this->m_position[2] = pz; } void QuaternionTrackingDataElement::GetPosition(float* px, float* py, float* pz) { *px = this->m_position[0]; *py = this->m_position[1]; *pz = this->m_position[2]; } void QuaternionTrackingDataElement::SetQuaternion(float q[4]) { this->m_quaternion[0] = q[0]; this->m_quaternion[1] = q[1]; this->m_quaternion[2] = q[2]; this->m_quaternion[3] = q[3]; } void QuaternionTrackingDataElement::GetQuaternion(float q[4]) { q[0] = this->m_quaternion[0]; q[1] = this->m_quaternion[1]; q[2] = this->m_quaternion[2]; q[3] = this->m_quaternion[3]; } void QuaternionTrackingDataElement::SetQuaternion(float qx, float qy, float qz, float w) { this->m_quaternion[0] = qx; this->m_quaternion[1] = qy; this->m_quaternion[2] = qz; this->m_quaternion[3] = w; } void QuaternionTrackingDataElement::GetQuaternion(float* qx, float* qy, float* qz, float* w) { *qx = this->m_quaternion[0]; *qy = this->m_quaternion[1]; *qz = this->m_quaternion[2]; *w = this->m_quaternion[3]; } //---------------------------------------------------------------------- // igtl::StartQuaternionTrackingDataMessage class StartQuaternionTrackingDataMessage::StartQuaternionTrackingDataMessage() { this->m_SendMessageType = "STT_QTDATA"; this->m_Resolution = 0; this->m_CoordinateName = ""; } StartQuaternionTrackingDataMessage::~StartQuaternionTrackingDataMessage() { } int StartQuaternionTrackingDataMessage::SetCoordinateName(const char* name) { if (strlen(name) <= IGTL_STT_QTDATA_LEN_COORDNAME) { this->m_CoordinateName = name; return 1; } else { return 0; } } int StartQuaternionTrackingDataMessage::CalculateContentBufferSize() { return IGTL_STT_QTDATA_SIZE; } int StartQuaternionTrackingDataMessage::PackContent() { AllocateBuffer(); igtl_stt_qtdata* stt_qtdata = (igtl_stt_qtdata*)this->m_Content; stt_qtdata->resolution = this->m_Resolution; strncpy(stt_qtdata->coord_name, this->m_CoordinateName.c_str(), IGTL_STT_QTDATA_LEN_COORDNAME); igtl_stt_qtdata_convert_byte_order(stt_qtdata); return 1; } int StartQuaternionTrackingDataMessage::UnpackContent() { igtl_stt_qtdata* stt_qtdata = (igtl_stt_qtdata*)this->m_Content; igtl_stt_qtdata_convert_byte_order(stt_qtdata); this->m_Resolution = stt_qtdata->resolution; char strbuf[IGTL_STT_QTDATA_LEN_COORDNAME+1]; strbuf[IGTL_STT_QTDATA_LEN_COORDNAME] = '\n'; strncpy(strbuf, stt_qtdata->coord_name, IGTL_STT_QTDATA_LEN_COORDNAME); this->SetCoordinateName(strbuf); return 1; } RTSQuaternionTrackingDataMessage::RTSQuaternionTrackingDataMessage() : m_Status(0) { this->m_SendMessageType = "RTS_QTDATA"; } //---------------------------------------------------------------------- // igtl::RTSQuaternionTrackingDataMessage class int RTSQuaternionTrackingDataMessage::CalculateContentBufferSize() { return IGTL_RTS_QTDATA_SIZE; } int RTSQuaternionTrackingDataMessage::PackContent() { AllocateBuffer(); igtl_rts_qtdata* rts_qtdata = (igtl_rts_qtdata*)this->m_Content; rts_qtdata->status = this->m_Status; igtl_rts_qtdata_convert_byte_order(rts_qtdata); return 1; } int RTSQuaternionTrackingDataMessage::UnpackContent() { igtl_rts_qtdata* rts_qtdata = (igtl_rts_qtdata*)this->m_Content; igtl_rts_qtdata_convert_byte_order(rts_qtdata); this->m_Status= rts_qtdata->status; return 1; } //---------------------------------------------------------------------- // igtl::QuaternionTrackingDataMessage class QuaternionTrackingDataMessage::QuaternionTrackingDataMessage() { this->m_SendMessageType = "QTDATA"; this->m_QuaternionTrackingDataList.clear(); } QuaternionTrackingDataMessage::~QuaternionTrackingDataMessage() { } int QuaternionTrackingDataMessage::AddQuaternionTrackingDataElement(QuaternionTrackingDataElement::Pointer& elem) { this->m_QuaternionTrackingDataList.push_back(elem); return this->m_QuaternionTrackingDataList.size(); } void QuaternionTrackingDataMessage::ClearQuaternionTrackingDataElements() { this->m_QuaternionTrackingDataList.clear(); } int QuaternionTrackingDataMessage::GetNumberOfQuaternionTrackingDataElements() { return this->m_QuaternionTrackingDataList.size(); } void QuaternionTrackingDataMessage::GetQuaternionTrackingDataElement(int index, QuaternionTrackingDataElement::Pointer& elem) { if (index >= 0 && index < (int)this->m_QuaternionTrackingDataList.size()) { elem = this->m_QuaternionTrackingDataList[index]; } } int QuaternionTrackingDataMessage::CalculateContentBufferSize() { return IGTL_QTDATA_ELEMENT_SIZE * this->m_QuaternionTrackingDataList.size(); } int QuaternionTrackingDataMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_qtdata_element* element = NULL; element = (igtl_qtdata_element*)(this->m_Content); igtl_qtdata_element * elementHolder = element; std::vector::iterator iter; for (iter = this->m_QuaternionTrackingDataList.begin(); iter != this->m_QuaternionTrackingDataList.end(); iter ++) { strncpy((char*)element->name, (*iter)->GetName(), IGTL_QTDATA_LEN_NAME); element->type = (*iter)->GetType(); element->reserved = 0; float p[3]; (*iter)->GetPosition(p); float q[4]; (*iter)->GetQuaternion(q); for (int i = 0; i < 3; i ++) { element->position[i] = p[i]; } for (int j = 0; j < 4; j ++) { element->quaternion[j] = q[j]; } element ++; } igtl_qtdata_convert_byte_order(elementHolder, this->m_QuaternionTrackingDataList.size()); return 1; } int QuaternionTrackingDataMessage::UnpackContent() { this->m_QuaternionTrackingDataList.clear(); igtl_qtdata_element* element = NULL; int nElement = 0; #if OpenIGTLink_HEADER_VERSION >= 2 element = (igtl_qtdata_element*) (this->m_Content); nElement = igtl_qtdata_get_data_n(CalculateReceiveContentSize()); #elif OpenIGTLink_PROTOCOL_VERSION <=2 element = (igtl_qtdata_element*) this->m_Body; nElement = igtl_qtdata_get_data_n(this->m_BodySizeToRead); #endif igtl_qtdata_convert_byte_order(element, nElement); char strbuf[128]; for (int i = 0; i < nElement; i ++) { QuaternionTrackingDataElement::Pointer elemClass = QuaternionTrackingDataElement::New(); // Add '\n' at the end of each string // (necessary for a case, where a string reaches the maximum length.) strbuf[IGTL_QTDATA_LEN_NAME] = '\n'; strncpy(strbuf, (char*)element->name, IGTL_QTDATA_LEN_NAME); elemClass->SetName((const char*)strbuf); elemClass->SetType(element->type); float p[3] = {0, 0, 0}; float q[4] = {0, 0, 0, 1}; for (int i = 0; i < 3; i ++) { p[i] = element->position[i]; } for (int j = 0; j < 4; j ++) { q[j] = element->quaternion[j]; } elemClass->SetPosition(p); elemClass->SetQuaternion(q); this->m_QuaternionTrackingDataList.push_back(elemClass); element ++; } return 1; } StopQuaternionTrackingDataMessage::StopQuaternionTrackingDataMessage() { this->m_SendMessageType = "STP_QTDATA"; } } // namespace igtlopenigtlink-3.0.0/Source/igtlQuaternionTrackingDataMessage.h000066400000000000000000000205131501024245700242360ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlQuaternionTrackingDataMessage_h #define __igtlQuaternionTrackingDataMessage_h #include #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" namespace igtl { /// A class to manage tracking data as a quaternion used in the QTDATA message type. /// A QuaternionTrackingDataElement class instance holds tracking data for 1 tracking device. class IGTLCommon_EXPORT QuaternionTrackingDataElement: public Object { public: typedef QuaternionTrackingDataElement Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::QuaternionTrackingDataElement, igtl::Object); igtlNewMacro(igtl::QuaternionTrackingDataElement); /// Tracking data type. /// TYPE_TRACKER: Tracker /// TYPE_6D: 6D instrument: (regular instrument) /// TYPE_3D: 3D instrument (only tip of the instrument defined) /// TYPE_5D: 5D instrument (tip and handle are defined, but not the normal vector) enum { TYPE_TRACKER = 1, TYPE_6D = 2, TYPE_3D = 3, TYPE_5D = 4, }; public: /// Sets the name of the instrument/tracker. int SetName(const char* name); /// Gets the name of the instrument/tracker. const char* GetName() { return this->m_Name.c_str(); }; /// Sets the type of the instrument/tracker. int SetType(igtlUint8 type); /// Gets the type of the instrument/tracker. igtlUint8 GetType() { return this->m_Type; }; /// Sets the position by 3-element array of x, y, and z coordinates. void SetPosition(float p[3]); /// Gets the position. The function substitutes 3-element array of x, y and z coordinates in 'p'. void GetPosition(float p[3]); /// Sets the position by x, y, and z coordinates. void SetPosition(float px, float py, float pz); /// Gets the position. The function substitutes the xyz coordinates in 'px', 'py', and 'pz'. void GetPosition(float* px, float* py, float* pz); /// Sets the quaternion by 4-element array. void SetQuaternion(float q[4]); /// Gets the quaternion. The function substitutes the array of elements of the quaternion in 'q'. void GetQuaternion(float q[4]); /// Sets the quaternion by elements of the quaternion (x, y, z and w). void SetQuaternion(float qx, float qy, float qz, float w); /// Gets the quaternion. The function substitutes the elements of the quaternion in 'qx', 'qy', 'qz' and 'qw'. void GetQuaternion(float* qx, float* qy, float* qz, float* w); protected: QuaternionTrackingDataElement(); ~QuaternionTrackingDataElement(); protected: /// Name / description (< 20 bytes) std::string m_Name; /// Tracking data type (TYPE_TRACKER, TYPE_6D, TYPE_3D, TYPE_5D) igtlUint8 m_Type; /// position (x, y, z) igtlFloat32 m_position[3]; /// orientation as quaternion (qx, qy, qz, w) igtlFloat32 m_quaternion[4]; }; /// A class for the STT_QTDATA message type. class IGTLCommon_EXPORT StartQuaternionTrackingDataMessage: public MessageBase { public: typedef StartQuaternionTrackingDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StartQuaternionTrackingDataMessage, igtl::MessageBase); igtlNewMacro(igtl::StartQuaternionTrackingDataMessage); public: /// Sets the time resolution for streaming of QTDATA messages void SetResolution(igtlInt32 res) { this->m_Resolution = res; }; // ms /// Gets the time resolution for streaming of QTDATA messages igtlInt32 GetResolution() { return this->m_Resolution; }; /// Sets the name of the coordinate system. The name must be defined by the user. int SetCoordinateName(const char* name); /// Gets the name of the coordinate system. const char* GetCoordinateName() { return this->m_CoordinateName.c_str(); }; protected: StartQuaternionTrackingDataMessage(); ~StartQuaternionTrackingDataMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); protected: /// Minimum time between two frames (ms). Use 0 for as fast as possible. igtlInt32 m_Resolution; /// Name of the coordinate system std::string m_CoordinateName; }; class IGTLCommon_EXPORT StopQuaternionTrackingDataMessage: public MessageBase { public: typedef StopQuaternionTrackingDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StopQuaternionTrackingDataMessage, igtl::MessageBase); igtlNewMacro(igtl::StopQuaternionTrackingDataMessage); protected: StopQuaternionTrackingDataMessage(); ~StopQuaternionTrackingDataMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// A class for the RTS_QTDATA message type. class IGTLCommon_EXPORT RTSQuaternionTrackingDataMessage: public MessageBase { public: typedef RTSQuaternionTrackingDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /// Status types enum { STATUS_SUCCESS = 0, STATUS_ERROR = 1 }; igtlTypeMacro(igtl::RTSQuaternionTrackingDataMessage, igtl::MessageBase); igtlNewMacro(igtl::RTSQuaternionTrackingDataMessage); /// Sets the status. 'status' must be either STATUS_SUCCESS or STATUS_ERROR. void SetStatus(igtlUint8 status){ this->m_Status = status; } /// Gets the status. The function returns either STATUS_SUCCESS or STATUS_ERROR. igtlUint8 GetStatus() { return this->m_Status; }; protected: RTSQuaternionTrackingDataMessage(); ~RTSQuaternionTrackingDataMessage() {}; /// A variable to store the status. igtlUint8 m_Status; protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); }; /// The QTDATA message type is intended for transferring 3D positions of surgical tools, /// markers etc. Its role is almost identical to TDATA, except that QTDATA describes /// orientation by using quaternion. class IGTLCommon_EXPORT QuaternionTrackingDataMessage: public MessageBase { public: typedef QuaternionTrackingDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::QuaternionTrackingDataMessage, igtl::MessageBase); igtlNewMacro(igtl::QuaternionTrackingDataMessage); public: /// Adds tracking data element. int AddQuaternionTrackingDataElement(QuaternionTrackingDataElement::Pointer& elem); /// Clears the all tracking data element in the list. void ClearQuaternionTrackingDataElements(); /// Gets the number of tracking data elements in the list. int GetNumberOfQuaternionTrackingDataElements(); /// Gets the tracking data element specified by 'index'. void GetQuaternionTrackingDataElement(int index, QuaternionTrackingDataElement::Pointer& elem); protected: QuaternionTrackingDataMessage(); ~QuaternionTrackingDataMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// The list of tracking data elements. std::vector m_QuaternionTrackingDataList; }; } // namespace igtl #endif // _igtlQuaternionTrackingDataMessage_hopenigtlink-3.0.0/Source/igtlQueryMessage.cxx000066400000000000000000000070001501024245700213100ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlQueryMessage.h" #include "igtl_header.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include namespace igtl { QueryMessage::QueryMessage() { this->m_SendMessageType = "QUERY"; } QueryMessage::~QueryMessage() { } int QueryMessage::SetDeviceUID(const char* string) { if (strlen(string) > 0xFFFF) /* If the length is beyond the range of unsigned short */ { return 0; } m_DeviceUID = string; return (int) this->m_DeviceUID.length(); } int QueryMessage::SetDeviceUID(const std::string & string) { if (string.length() > 0xFFFF) /* If the length is beyond the range of unsigned short */ { return 0; } this->m_DeviceUID = string; return (int) this->m_DeviceUID.length(); } std::string QueryMessage::GetDeviceUID() { return this->m_DeviceUID; } int QueryMessage::SetDataType(const char* dataType) { if (strlen(dataType) > IGTL_QUERY_DATE_TYPE_SIZE) /* If the length is beyond the range specified by the spec */ { return 0; } strcpy((char*)m_DataType, dataType); return 1; } int QueryMessage::SetDataType(const std::string& dataType) { return this->SetDataType(dataType.c_str()); } int QueryMessage::CalculateContentBufferSize() { // Body pack size is the sum of DeviceUID and data type fields return IGTL_QUERY_HEADER_SIZE + this->m_DeviceUID.length(); } int QueryMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_query_header * query_header; char * deviceName; // Set pointers #if OpenIGTLink_HEADER_VERSION >= 2 query_header = (igtl_query_header*) this->m_Content; deviceName = (char *) this->m_Content + sizeof(igtl_query_header); #else query_header = (igtl_query_header*) this->m_Body; deviceName = (char *) this->m_Body + sizeof(igtl_query_header); #endif // Copy data query_header->deviceUIDLength = static_cast(this->m_DeviceUID.length()); query_header->queryID = this->m_QueryID; memcpy(query_header->queryDataType, this->m_DataType, IGTL_QUERY_DATE_TYPE_SIZE); strncpy(deviceName, this->m_DeviceUID.c_str(), query_header->deviceUIDLength); // Convert byte order from host to network igtl_query_convert_byte_order(query_header); return 1; } int QueryMessage::UnpackContent() { igtl_query_header * query_header; char * deviceName; #if OpenIGTLink_HEADER_VERSION >= 2 query_header = (igtl_query_header*) this->m_Content; deviceName = (char *) this->m_Content + sizeof(igtl_query_header); #else query_header = (igtl_query_header*) this->m_Body; deviceName = (char *) this->m_Body + sizeof(igtl_query_header); #endif // Convert byte order from network to host igtl_query_convert_byte_order(query_header); // Copy data this->m_QueryID = query_header->queryID; memcpy(m_DataType, query_header->queryDataType, IGTL_QUERY_DATE_TYPE_SIZE); this->m_DeviceUID.clear(); this->m_DeviceUID.append(deviceName, query_header->deviceUIDLength); return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlQueryMessage.h000066400000000000000000000040641501024245700207440ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlQueryMessage_h #define __igtlQueryMessage_h #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #include "igtl_query.h" namespace igtl { /// THe STRING message type is used for transferring a character string. It supports character strings up to 65535 bytes. class IGTLCommon_EXPORT QueryMessage: public MessageBase { public: typedef QueryMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::QueryMessage, igtl::MessageBase); igtlNewMacro(igtl::QueryMessage); public: /// Sets the string by character array. int SetDeviceUID(const char* string); /// Sets the string by std::string. int SetDeviceUID(const std::string & string); /// Sets the string by character array. int SetDataType(const char* string); /// Sets the string by std::string. int SetDataType(const std::string & string); /// Gets the device uid. std::string GetDeviceUID(); /// Gets the data type. std::string GetDataType(); protected: QueryMessage(); ~QueryMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// The string. std::string m_DeviceUID; igtlUint32 m_QueryID; /// Query Data Type igtlUint8 m_DataType[IGTL_QUERY_DATE_TYPE_SIZE ]; }; } // namespace igtl #endif // _igtlQueryMessage_h openigtlink-3.0.0/Source/igtlSensorMessage.cxx000066400000000000000000000066761501024245700214760ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlSensorMessage.h" #include "igtl_header.h" #include "igtl_sensor.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include namespace igtl { SensorMessage::SensorMessage(): MessageBase() { m_SendMessageType = "SENSOR"; this->m_Length = 0; this->m_Status = 0; this->m_Unit = 0; this->m_Array.clear(); } SensorMessage::~SensorMessage() { } int SensorMessage::SetLength(unsigned int n) { if (n <= 256) { this->m_Length = n; this->m_Array.resize(n); } return (int) this->m_Length; } unsigned int SensorMessage::GetLength() { return this->m_Length; } int SensorMessage::SetUnit(igtlUnit unit) { this->m_Unit = unit; return 1; } int SensorMessage::SetUnit(igtl::Unit * unit) { this->m_Unit = unit->Pack(); return 1; } igtlUnit SensorMessage::GetUnit() { return this->m_Unit; } int SensorMessage::GetUnit(igtl::Unit * unit) { return unit->Unpack(this->m_Unit); } int SensorMessage::SetValue(igtlFloat64 * data) { for (int i = 0; i < this->m_Length; i ++) { this->m_Array[i] = data[i]; } return 1; } int SensorMessage::SetValue(unsigned int i, igtlFloat64 value) { if (i < this->m_Length) { this->m_Array[i] = value; return 1; } return 0; } igtlFloat64 SensorMessage::GetValue(unsigned int i) { if (i < this->m_Length) { return this->m_Array[i]; } else { return 0.0; } } int SensorMessage::CalculateContentBufferSize() { // Body pack size is the sum of LARRAY, STATUS, UNIT and DATA return sizeof(igtlUint8)*2 + sizeof(igtlUnit) + sizeof(igtlFloat64)*this->m_Length; } int SensorMessage::PackContent() { // Allocate buffer AllocateBuffer(); // Set pointers igtl_sensor_header * sensor_header; igtl_float64 * data; sensor_header = (igtl_sensor_header *) (this->m_Content); data = (igtl_float64 *) (this->m_Content + sizeof(igtl_sensor_header)); // Copy data sensor_header->larray = this->m_Length; sensor_header->status = this->m_Status; sensor_header->unit = this->m_Unit; for (int i = 0; i < this->m_Length; i ++) { data[i] = this->m_Array[i]; } // Convert byte order from local to network igtl_sensor_convert_byte_order(sensor_header, data); return 1; } int SensorMessage::UnpackContent() { // Set pointers igtl_sensor_header * sensor_header; igtl_float64 * data; sensor_header = (igtl_sensor_header *) (this->m_Content); data = (igtl_float64 *) (this->m_Content + sizeof(igtl_sensor_header)); // Convert byte order from local to network igtl_sensor_convert_byte_order(sensor_header, data); // Copy data this->m_Length = sensor_header->larray; this->m_Status = sensor_header->status; this->m_Unit = sensor_header->unit; this->m_Array.resize(this->m_Length); for (int i = 0; i < this->m_Length; i ++) { this->m_Array[i] = data[i]; } return 1; } } // namespace igtl openigtlink-3.0.0/Source/igtlSensorMessage.h000066400000000000000000000053061501024245700211100ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlSensorMessage_h #define __igtlSensorMessage_h #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #include "igtlUnit.h" namespace igtl { /// SENSOR is a message type, which is used to transfer sensor reading, /// 3-axis position, velocity, acceleration, angle, angle velocity and angle acceleration. /// The message format is intended for manipulator control and various types of sensors. class IGTLCommon_EXPORT SensorMessage: public MessageBase { public: typedef SensorMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::SensorMessage, igtl::MessageBase); igtlNewMacro(igtl::SensorMessage); public: /// Sets the length of the array. Returns the resulted length. int SetLength(unsigned int n); /// Gets the length of the array. unsigned int GetLength(); /// Sets the unit for the sensor values. Returns 1 if success. int SetUnit(igtlUnit unit); /// Sets the unit for the sensor values Returns 1 if success. int SetUnit(igtl::Unit * unit); /// Gets the unit as 64-bit unit field defined in igtlUnit.h. igtlUnit GetUnit(); /// Gets the unit as igtl::Unit class. int GetUnit(igtl::Unit * unit); /// Sets sensor values from an array of 64-bit floating data. Returns 1 if success. int SetValue(igtlFloat64 * data); /// Sets the value for the i-th sensor. Returns 1 if success. int SetValue(unsigned int i, igtlFloat64 value); /// Gets the value of the i-th sensor. igtlFloat64 GetValue(unsigned int i); protected: SensorMessage(); ~SensorMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// Length of sensor array. igtlUint8 m_Length; /// Sensor status (Reserved). igtlUint8 m_Status; /// Unit (generated by igtl::Unit::Pack()). igtlUnit m_Unit; /// The array of sensor values. std::vector m_Array; }; } // namespace igtl #endif // _igtlSensorMessage_h openigtlink-3.0.0/Source/igtlServerSocket.cxx000066400000000000000000000066261501024245700213320ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkServerSocket.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "igtlServerSocket.h" #include "igtlClientSocket.h" namespace igtl { //----------------------------------------------------------------------------- ServerSocket::ServerSocket() { } //----------------------------------------------------------------------------- ServerSocket::~ServerSocket() { } //----------------------------------------------------------------------------- int ServerSocket::GetServerPort() { if (!this->GetConnected()) { return 0; } return this->GetPort(this->m_SocketDescriptor); } //----------------------------------------------------------------------------- int ServerSocket::CreateServer(int port) { if (this->m_SocketDescriptor != -1) { igtlWarningMacro("Server Socket already exists. Closing old socket."); this->CloseSocket(this->m_SocketDescriptor); this->m_SocketDescriptor = -1; } this->m_SocketDescriptor = this->CreateSocket(); if (this->m_SocketDescriptor < 0) { return -1; } if ( this->BindSocket(this->m_SocketDescriptor, port) != 0|| this->Listen(this->m_SocketDescriptor) != 0) { // failed to bind or listen. this->CloseSocket(this->m_SocketDescriptor); this->m_SocketDescriptor = -1; return -1; } // Success. return 0; } //----------------------------------------------------------------------------- //ClientSocket* ServerSocket::WaitForConnection(unsigned long msec /*=0*/) ClientSocket::Pointer ServerSocket::WaitForConnection(unsigned long msec /*=0*/) { if (this->m_SocketDescriptor < 0) { igtlErrorMacro("Server Socket not created yet!"); return NULL; } int ret = this->SelectSocket(this->m_SocketDescriptor, msec); if (ret == 0) { // Timed out. return NULL; } if (ret == -1) { igtlErrorMacro("Error selecting socket."); return NULL; } int clientsock = this->Accept(this->m_SocketDescriptor); if (clientsock == -1) { igtlErrorMacro("Failed to accept the socket."); return NULL; } // Create a new ClientSocket and return it. ClientSocket::Pointer cs = ClientSocket::New(); cs->m_SocketDescriptor = clientsock; return cs; } //----------------------------------------------------------------------------- void ServerSocket::PrintSelf(std::ostream& os) const { this->Superclass::PrintSelf(os); } } // end of igtl namespace openigtlink-3.0.0/Source/igtlServerSocket.h000066400000000000000000000046741501024245700207600ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkServerSocket.h,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // .NAME igtlServerSocket - Encapsulate a socket that accepts connections. // .SECTION Description // #ifndef __igtlServerSocket_h #define __igtlServerSocket_h #include "igtlSocket.h" #include "igtlClientSocket.h" #include "igtlWin32Header.h" namespace igtl { class IGTLCommon_EXPORT ServerSocket : public Socket { public: typedef ServerSocket Self; typedef Socket Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::ServerSocket, igtl::Socket); igtlNewMacro(igtl::ServerSocket); // Description: // Creates a server socket at a given port and binds to it. // Returns -1 on error. 0 on success. int CreateServer(int port); // Description: // Waits for a connection. When a connection is received // a new ClientSocket object is created and returned. // Returns NULL on timeout. //ClientSocket* WaitForConnection(unsigned long msec=0); ClientSocket::Pointer WaitForConnection(unsigned long msec=0); // Description: // Returns the port on which the server is running. int GetServerPort(); protected: ServerSocket(); ~ServerSocket(); void PrintSelf(std::ostream& os) const; private: ServerSocket(const ServerSocket&); // Not implemented. void operator=(const ServerSocket&); // Not implemented. }; } // end of igtl namespace #endif openigtlink-3.0.0/Source/igtlSessionManager.cxx000066400000000000000000000176761501024245700216400ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: git@github.com:openigtlink/OpenIGTLink.git Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include "igtlSessionManager.h" #include "igtlMessageHandler.h" #include "igtlClientSocket.h" #include "igtlServerSocket.h" #include "igtl_header.h" namespace igtl { SessionManager::SessionManager() { this->m_MessageHandlerList.clear(); this->m_Mode = MODE_SERVER; this->m_Header = igtl::MessageHeader::New(); this->m_TimeStamp = igtl::TimeStamp::New(); this->m_CurrentReadIndex = 0; this->m_HeaderDeserialized = 0; } SessionManager::~SessionManager() { } int SessionManager::AddMessageHandler(MessageHandler* handler) { // Check if there is any handler for the same message type std::vector< MessageHandler* >::iterator iter; for (iter = this->m_MessageHandlerList.begin(); iter != this->m_MessageHandlerList.end(); iter ++) { if ( (*iter)->GetMessageType() == handler->GetMessageType() ) { return 0; } } // If not, add the handler to the list. this->m_MessageHandlerList.push_back(handler); return 1; } int SessionManager::RemoveMessageHandler(MessageHandler* handler) { // Check if there is any handler for the same message type std::vector< MessageHandler* >::iterator iter; for (iter = this->m_MessageHandlerList.begin(); iter != this->m_MessageHandlerList.end(); iter ++) { if (*iter == handler) { this->m_MessageHandlerList.erase(iter); return 1; } } return 0; } int SessionManager::Connect() { this->m_Socket = NULL; if (this->m_Mode == MODE_CLIENT) { ClientSocket::Pointer clientSocket; clientSocket = ClientSocket::New(); //this->DebugOff(); if (this->m_Hostname.length() == 0) { return 0; } //this->m_Socket->SetConnectTimeout(1000); int r = clientSocket->ConnectToServer(this->m_Hostname.c_str(), this->m_Port); if (r == 0) // if connected to server { //clientSocket->SetReceiveTimeout(0); this->m_Socket = clientSocket; } } else { ServerSocket::Pointer serverSocket; serverSocket = ServerSocket::New(); int r = serverSocket->CreateServer(this->m_Port); if (r < 0) { return 0; } if (serverSocket.IsNotNull()) { //this->ServerSocket->CreateServer(this->m_Port); this->m_Socket = serverSocket->WaitForConnection(10000); } if (this->m_Socket.IsNotNull() && this->m_Socket->GetConnected()) // if client connected { this->m_Socket->DebugOff(); } else { return 0; } } this->m_Socket->SetReceiveBlocking(0); // Psuedo non-blocking this->m_CurrentReadIndex = 0; this->m_HeaderDeserialized = 0; return 1; } int SessionManager::Disconnect() { if (this->m_Socket.IsNotNull()) { this->m_Socket->CloseSocket(); } return 0; } int SessionManager::ProcessMessage() { // The workflow of this function is as follows: // // HEADER: // IF the message is (a) a new message: // start reading the header; // ELSE IF the message is a message in progress: // if the process is reading the header: // continue to read the header; // ELSE: // GOTO BODY; // // IF the header has not been received: // GOTO BODY; // ELSE // RETURN; // // BODY: // IF the process has not started reading the body: // check the body type; // find an appropriate handler; // start reading the body // ELSE: // continue to read the body // //-------------------------------------------------- // Header if (this->m_CurrentReadIndex == 0) { // Initialize receive buffer this->m_Header->InitBuffer(); // Receive generic header from the socket int r = this->m_Socket->Receive(this->m_Header->GetBufferPointer(), this->m_Header->GetBufferSize(), 0); if (r == 0) { this->m_CurrentReadIndex = 0; this->m_HeaderDeserialized = 0; return 0; // Disconnected } if (r != this->m_Header->GetBufferSize()) { // Only a part of header has arrived. if (r < 0) // timeout { this->m_CurrentReadIndex = 0; } else { this->m_CurrentReadIndex = r; } return -1; } // The header has been received. this->m_CurrentReadIndex = IGTL_HEADER_SIZE; } else if (this->m_CurrentReadIndex < IGTL_HEADER_SIZE) { // Message transfer was interrupted in the header int r = this->m_Socket->Receive((void*)((char*)this->m_Header->GetBufferPointer()+this->m_CurrentReadIndex), this->m_Header->GetBufferSize()-this->m_CurrentReadIndex, 0); if (r == 0) { this->m_CurrentReadIndex = 0; this->m_HeaderDeserialized = 0; return 0; // Disconnected } if (r != this->m_Header->GetBufferSize()-this->m_CurrentReadIndex) { // Only a part of header has arrived. if (r > 0) // exclude a case of timeout { this->m_CurrentReadIndex += r; } return -1; } // The header has been received. this->m_CurrentReadIndex = IGTL_HEADER_SIZE; } //-------------------------------------------------- // Body if (this->m_HeaderDeserialized == 0) { // Deserialize the header this->m_Header->Unpack(); // Get time stamp igtlUint32 sec; igtlUint32 nanosec; this->m_Header->GetTimeStamp(this->m_TimeStamp); this->m_TimeStamp->GetTimeStamp(&sec, &nanosec); //std::cerr << "Time stamp: " // << sec << "." << std::setw(9) << std::setfill('0') // << nanosec << std::endl; // Look for a message handler that matches to the message type. int found = 0; std::vector< MessageHandler* >::iterator iter; for (iter = this->m_MessageHandlerList.begin(); iter != this->m_MessageHandlerList.end(); iter ++) { #if OpenIGTLink_HEADER_VERSION >= 2 if ( this->m_Header->GetMessageType() == (*iter)->GetMessageType() ) #else if (strcmp(this->m_Header->GetDeviceType(), (*iter)->GetMessageType()) == 0) #endif { this->m_CurrentMessageHandler = *iter; found = 1; break; } } // If there is no message handler, skip the message if (!found) { #if OpenIGTLink_HEADER_VERSION >= 2 std::cerr << "Receiving: " << this->m_Header->GetMessageType() << std::endl; #else std::cerr << "Receiving: " << this->m_Header->GetDeviceType() << std::endl; #endif this->m_Socket->Skip(this->m_Header->GetBodySizeToRead(), 0); // Reset the index counter to be ready for the next message this->m_CurrentReadIndex = 0; this->m_HeaderDeserialized = 0; return 1; } this->m_HeaderDeserialized = 1; } int r = this->m_CurrentMessageHandler->ReceiveMessage(this->m_Socket, this->m_Header, this->m_CurrentReadIndex-IGTL_HEADER_SIZE); if (r == this->m_Header->GetBodySizeToRead()) { this->m_CurrentReadIndex = 0; this->m_HeaderDeserialized = 0; } else { this->m_CurrentReadIndex += IGTL_HEADER_SIZE + r; } return 1; } int SessionManager::PushMessage(MessageBase* message) { if (message && this->m_Socket.IsNotNull() && this->m_Socket->GetConnected()) // if client connected { return this->m_Socket->Send(message->GetBufferPointer(), message->GetBufferSize()); } else { return 0; } } } openigtlink-3.0.0/Source/igtlSessionManager.h000066400000000000000000000052451501024245700212520ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: git@github.com:openigtlink/OpenIGTLink.git Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlSessionManager_h #define __igtlSessionManager_h #include "igtlObject.h" #include "igtlMacro.h" #include "igtlMessageHandler.h" #include namespace igtl { class IGTLCommon_EXPORT SessionManager: public Object { public: typedef SessionManager Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(SessionManager, Object) igtlNewMacro(SessionManager); public: enum { MODE_SERVER, MODE_CLIENT }; void SetHostname(const char * str) {this->m_Hostname = str; this->m_ConfigurationUpdated = true; } const char * GetHostname() { return this->m_Hostname.c_str(); } void SetPort(int p) { this->m_Port = p; this->m_ConfigurationUpdated = true; } int GetPort() { return this->m_Port; } // Description: // Set the role of session manager. Either MODE_SERVER or MODE_CLIENT void SetMode(int m) {this->m_Mode = m; this->m_ConfigurationUpdated = true; } int GetMode() {return this->m_Mode; } // Description: // Register / Unregister a message handler int AddMessageHandler(MessageHandler*); int RemoveMessageHandler(MessageHandler*); // Description: // Functions to manage the session int Connect(); int Disconnect(); int ProcessMessage(); int PushMessage(MessageBase*); protected: SessionManager(); ~SessionManager(); protected: bool m_ConfigurationUpdated; std::string m_Hostname; int m_Port; int m_Mode; // Description: // m_CurrentReadIndex is used to save the current position of the message. // The index becomes >0 when message transfer is interrupted and only a part // of message has arrived. int m_CurrentReadIndex; int m_HeaderDeserialized; MessageHandler* m_CurrentMessageHandler; std::vector< MessageHandler* > m_MessageHandlerList; Socket::Pointer m_Socket; igtl::MessageHeader::Pointer m_Header; igtl::TimeStamp::Pointer m_TimeStamp; }; } #endif // __igtlSessionManager_h openigtlink-3.0.0/Source/igtlSimpleFastMutexLock.cxx000066400000000000000000000057661501024245700226220ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkSimpleFastMutexLock.cxx,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlSimpleFastMutexLock.h" namespace igtl { // Construct a new SimpleMutexLock SimpleFastMutexLock::SimpleFastMutexLock() { #ifdef OpenIGTLink_USE_SPROC init_lock( &m_FastMutexLock ); #endif #if defined(_WIN32) && !defined(OpenIGTLink_USE_PTHREADS) //this->MutexLock = CreateMutex( NULL, FALSE, NULL ); InitializeCriticalSection(&m_FastMutexLock); #endif #ifdef OpenIGTLink_USE_PTHREADS #ifdef OpenIGTLink_HP_PTHREADS pthread_mutex_init(&(m_FastMutexLock), pthread_mutexattr_default); #else pthread_mutex_init(&(m_FastMutexLock), NULL); #endif #endif } // Destruct the SimpleMutexVariable SimpleFastMutexLock::~SimpleFastMutexLock() { #if defined(_WIN32) && !defined(OpenIGTLink_USE_PTHREADS) //CloseHandle(this->MutexLock); DeleteCriticalSection(&m_FastMutexLock); #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_mutex_destroy( &m_FastMutexLock); #endif } // Lock the FastMutexLock void SimpleFastMutexLock::Lock() const { #ifdef OpenIGTLink_USE_SPROC spin_lock( &m_FastMutexLock ); #endif #if defined(_WIN32) && !defined(OpenIGTLink_USE_PTHREADS) //WaitForSingleObject( this->MutexLock, INFINITE ); EnterCriticalSection(&m_FastMutexLock); #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_mutex_lock( &m_FastMutexLock); #endif } // Unlock the FastMutexLock void SimpleFastMutexLock::Unlock() const { #ifdef OpenIGTLink_USE_SPROC release_lock( &m_FastMutexLock ); #endif #if defined(_WIN32) && !defined(OpenIGTLink_USE_PTHREADS) //ReleaseMutex( this->MutexLock ); LeaveCriticalSection(&m_FastMutexLock); #endif #ifdef OpenIGTLink_USE_PTHREADS pthread_mutex_unlock( &m_FastMutexLock); #endif } }//end namespace igtl openigtlink-3.0.0/Source/igtlSimpleFastMutexLock.h000066400000000000000000000056661501024245700222460ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkSimpleFastMutexLock.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlSimpleFastMutexLock_h #define __igtlSimpleFastMutexLock_h #include "igtlMacro.h" #ifdef OpenIGTLink_USE_SPROC #include #endif #ifdef OpenIGTLink_USE_PTHREADS #include #endif #if defined(_WIN32) && !defined(OpenIGTLink_USE_PTHREADS) #include "igtlWindows.h" #endif namespace igtl { #ifdef OpenIGTLink_USE_SPROC #include typedef abilock_t FastMutexType; #endif #ifdef OpenIGTLink_USE_PTHREADS #include typedef pthread_mutex_t FastMutexType; #endif #if defined(_WIN32) && !defined(OpenIGTLink_USE_PTHREADS) #include typedef CRITICAL_SECTION FastMutexType; #endif #ifndef OpenIGTLink_USE_SPROC #ifndef OpenIGTLink_USE_PTHREADS #ifndef _WIN32 typedef int FastMutexType; #endif #endif #endif /** \class SimpleFastMutexLock * \brief Critical section locking class that can be allocated on the stack. * * SimpleFastMutexLock is used by FastMutexLock to perform mutex locking. * SimpleFastMutexLock is not a subclass of Object and is designed to be * allocated on the stack. * * \ingroup OSSystemObjects */ // Critical Section object that is not a igtlObject. class IGTLCommon_EXPORT SimpleFastMutexLock { public: /** Standard class typedefs. */ typedef SimpleFastMutexLock Self; /** Constructor and destructor left public purposely because of stack allocation. */ SimpleFastMutexLock(); ~SimpleFastMutexLock(); /** Lock access. */ void Lock() const; /** Unlock access. */ void Unlock() const; protected: mutable FastMutexType m_FastMutexLock; }; }//end igtl namespace #endif openigtlink-3.0.0/Source/igtlSmartPointer.h000066400000000000000000000117451501024245700207650ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkSmartPointer.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlSmartPointer_h #define __igtlSmartPointer_h #include "igtlMacro.h" #include namespace igtl { /** \class SmartPointer * \brief Implements transparent reference counting. * * SmartPointer implements reference counting by overloading * operator -> (and *) among others. This allows natural interface * to the class referred to by the pointer without having to invoke * special Register()/UnRegister() methods directly. * * To compile / test this class * Windows: cl SmartPointerTest.cxx; .\SmartPointerTest.exe * linux: c++ SmartPointerTest.cxx ./a.out * other: CCcompiler SmartPointerTest.cxx ./a.out * * \ingroup IGTLSystemObjects * \ingroup DataAccess */ template class IGTL_EXPORT SmartPointer { public: typedef TObjectType ObjectType; /** Constructor */ SmartPointer () { m_Pointer = 0; } /** Copy constructor */ SmartPointer (const SmartPointer &p): m_Pointer(p.m_Pointer) { this->Register(); } /** Constructor to pointer p */ SmartPointer (ObjectType *p): m_Pointer(p) { this->Register(); } /** Destructor */ ~SmartPointer () { this->UnRegister(); m_Pointer = 0; } /** Overload operator -> */ ObjectType *operator -> () const { return m_Pointer; } /** Return pointer to object. */ operator ObjectType * () const { return m_Pointer; } /** Test if the pointer has been initialized */ bool IsNotNull() const { return m_Pointer != 0; } bool IsNull() const { return m_Pointer == 0; } /** Template comparison operators. */ template bool operator == ( R r ) const { return (m_Pointer == static_cast(r) ); } template bool operator != ( R r ) const { return (m_Pointer != static_cast(r) ); } /** Access function to pointer. */ ObjectType *GetPointer () const { return m_Pointer; } /** Comparison of pointers. Less than comparison. */ bool operator < (const SmartPointer &r) const { return (void*)m_Pointer < (void*) r.m_Pointer; } /** Comparison of pointers. Greater than comparison. */ bool operator > (const SmartPointer &r) const { return (void*)m_Pointer > (void*) r.m_Pointer; } /** Comparison of pointers. Less than or equal to comparison. */ bool operator <= (const SmartPointer &r) const { return (void*)m_Pointer <= (void*) r.m_Pointer; } /** Comparison of pointers. Greater than or equal to comparison. */ bool operator >= (const SmartPointer &r) const { return (void*)m_Pointer >= (void*) r.m_Pointer; } /** Overload operator assignment. */ SmartPointer &operator = (const SmartPointer &r) { return this->operator = (r.GetPointer()); } /** Overload operator assignment. */ SmartPointer &operator = (ObjectType *r) { if (m_Pointer != r) { ObjectType* tmp = m_Pointer; //avoid recursive unregisters by retaining temporarily m_Pointer = r; this->Register(); if ( tmp ) { tmp->UnRegister(); } } return *this; } /** Function to print object pointed to */ ObjectType *Print (std::ostream& os) const { // This prints the object pointed to by the pointer (*m_Pointer).Print(os); return m_Pointer; } private: /** The pointer to the object referrred to by this smart pointer. */ ObjectType* m_Pointer; void Register() { if(m_Pointer) { m_Pointer->Register(); } } void UnRegister() { if(m_Pointer) { m_Pointer->UnRegister(); } } }; template std::ostream& operator<< (std::ostream& os, SmartPointer p) { p.Print(os); return os; } } // end namespace igtl #endif openigtlink-3.0.0/Source/igtlSocket.cxx000066400000000000000000000402631501024245700201360ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: igtlSocket.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "igtlSocket.h" #if defined(_WIN32) && !defined(__CYGWIN__) #include #include #else #include #include #include #include #include #include #include #include #endif #include #if defined(_WIN32) && !defined(__CYGWIN__) #define WSA_VERSION MAKEWORD(1,1) #define igtlCloseSocketMacro(sock) (closesocket(sock)) #else #define igtlCloseSocketMacro(sock) \ { \ shutdown(sock, 2); \ close(sock); \ } #endif namespace igtl { //----------------------------------------------------------------------------- Socket::Socket() { this->m_SocketDescriptor = -1; this->m_SendTimeoutFlag = 0; this->m_ReceiveTimeoutFlag = 0; } //----------------------------------------------------------------------------- Socket::~Socket() { if (this->m_SocketDescriptor != -1) { this->CloseSocket(this->m_SocketDescriptor); this->m_SocketDescriptor = -1; } } //----------------------------------------------------------------------------- int Socket::CreateSocket() { #if defined(_WIN32) && !defined(__CYGWIN__) // Declare variables WSADATA wsaData; //SOCKET ListenSocket; //sockaddr_in service; //--------------------------------------- // Initialize Winsock int iResult = WSAStartup( MAKEWORD(2,2), &wsaData ); if( iResult != NO_ERROR ) { std::cerr << "Error at WSAStartup" << std::endl; return -1; } #endif int sock = socket(AF_INET, SOCK_STREAM, 0); // Elimate windows 0.2 second delay sending (buffering) data. int on = 1; if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on))) { return -1; } return sock; } //----------------------------------------------------------------------------- int Socket::BindSocket(int socketdescriptor, int port) { struct sockaddr_in server; server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(port); // Allow the socket to be bound to an address that is already in use #ifdef _WIN32 int opt=1; setsockopt(socketdescriptor, SOL_SOCKET, SO_REUSEADDR, (char*) &opt, sizeof(int)); #elif defined(VTK_HAVE_SO_REUSEADDR) int opt=1; setsockopt(socketdescriptor, SOL_SOCKET, SO_REUSEADDR, (void *) &opt, sizeof(int)); #endif if ( bind(socketdescriptor, reinterpret_cast(&server), sizeof(server)) ) { return -1; } return 0; } //----------------------------------------------------------------------------- int Socket::Accept(int socketdescriptor) { if (socketdescriptor < 0) { return -1; } return accept(socketdescriptor, 0, 0); } //----------------------------------------------------------------------------- int Socket::Listen(int socketdescriptor) { if (socketdescriptor < 0) { return -1; } return listen(socketdescriptor, 1); } //----------------------------------------------------------------------------- int Socket::SelectSocket(int socketdescriptor, unsigned long msec) { if (socketdescriptor < 0 ) { // invalid socket descriptor. return -1; } fd_set rset; struct timeval tval; struct timeval* tvalptr = 0; if ( msec > 0 ) { tval.tv_sec = msec / 1000; tval.tv_usec = (msec % 1000)*1000; tvalptr = &tval; } FD_ZERO(&rset); FD_SET(socketdescriptor, &rset); int res = select(socketdescriptor + 1, &rset, 0, 0, tvalptr); if(res == 0) { return 0;//for time limit expire } if ( res < 0 || !(FD_ISSET(socketdescriptor, &rset)) ) { // Some error. return -1; } // The indicated socket has some activity on it. return 1; } //----------------------------------------------------------------------------- int Socket::SelectSockets(const int* sockets_to_select, int size, unsigned long msec, int* selected_index) { int i; int max_fd = -1; *selected_index = -1; if (size < 0) { return -1; } fd_set rset; struct timeval tval; struct timeval* tvalptr = 0; if ( msec > 0 ) { tval.tv_sec = msec / 1000; tval.tv_usec = msec % 1000; tvalptr = &tval; } FD_ZERO(&rset); for (i=0; i max_fd)? sockets_to_select[i] : max_fd; } int res = select(max_fd + 1, &rset, 0, 0, tvalptr); if (res == 0) { return 0; //Timeout } if (res < 0) { // SelectSocket error. return -1; } //check which socket has some activity. for (i=0; ih_addr, hp->h_length); name.sin_port = htons(port); int r = connect(socketdescriptor, reinterpret_cast(&name), sizeof(name)); return r; } //----------------------------------------------------------------------------- int Socket::GetPort(int sock) { struct sockaddr_in sockinfo; memset(&sockinfo, 0, sizeof(sockinfo)); #if defined(OpenIGTLink_HAVE_GETSOCKNAME_WITH_SOCKLEN_T) socklen_t sizebuf = sizeof(sockinfo); #else int sizebuf = sizeof(sockinfo); #endif // FIXME: Setup configuration for VTK_HAVE_GETSOCKNAME_WITH_SOCKLEN_T so we can uncomment these lines if(getsockname(sock, reinterpret_cast(&sockinfo), &sizebuf) != 0) { return 0; } return ntohs(sockinfo.sin_port); } //----------------------------------------------------------------------------- void Socket::CloseSocket(int socketdescriptor) { if (socketdescriptor < 0) { return; } igtlCloseSocketMacro(socketdescriptor); } //----------------------------------------------------------------------------- int Socket::Send(const void* data, int length) { if (!this->GetConnected()) { return 0; } if (length == 0) { // nothing to send. return 1; } const char* buffer = reinterpret_cast(data); int total = 0; do { int flags; #if defined(_WIN32) && !defined(__CYGWIN__) flags = 0; #else // On unix boxes if the client disconnects and the server attempts // to send data through the socket then the application crashes // due to SIGPIPE signal. Disable the signal to prevent crash. //#ifndef __sun // flags = MSG_NOSIGNAL; //#else // // Signal is not present on SUN systems, the signal has // // to be managed at application level. // flags = 0; //#endif #if defined(MSG_NOSIGNAL) // For Linux > 2.2 flags = MSG_NOSIGNAL; #else #if defined(SO_NOSIGPIPE) // Mac OS X int set = 1; setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); #endif flags = 0; #endif #endif int n = send(this->m_SocketDescriptor, buffer+total, length-total, flags); if(n < 0) { // FIXME : Use exceptions ? igtlErrorMacro("Socket Error: Send failed."); return 0; } total += n; } while(total < length); return 1; } //----------------------------------------------------------------------------- int Socket::Receive(void* data, int length, int readFully/*=1*/) { if (!this->GetConnected()) { return 0; } char* buffer = reinterpret_cast(data); int total = 0; do { #if defined(_WIN32) && !defined(__CYGWIN__) int trys = 0; #endif int n = recv(this->m_SocketDescriptor, buffer+total, length-total, 0); #if defined(_WIN32) && !defined(__CYGWIN__) if(n == 0) { // On long messages, Windows recv sometimes fails with WSAENOBUFS, but // will work if you try again. int error = WSAGetLastError(); if ((error == WSAENOBUFS) && (trys++ < 1000)) { Sleep(1); continue; } // FIXME : Use exceptions ? igtlErrorMacro("Socket Error: Receive failed."); return 0; } else if (n < 0) { // TODO: Need to check if this means timeout. return -1; } #else if(n == 0) // Disconnected { // FIXME : Use exceptions ? igtlErrorMacro("Socket Error: Receive failed."); return 0; } else if (n < 0) // Error (including time out) { // TODO: If it is time-out, errno == EAGAIN return -1; } #endif total += n; } while(readFully && total < length); return total; } //----------------------------------------------------------------------------- int Socket::SetTimeout(int timeout) { if (SetReceiveTimeout(timeout) && SetSendTimeout(timeout)) { return 1; } else { return 0; } } //----------------------------------------------------------------------------- int Socket::SetReceiveTimeout(int timeout) { if (!this->GetConnected()) { return 0; } #if defined(_WIN32) && !defined(__CYGWIN__) this->m_ReceiveTimeout = timeout; int len; #else this->m_ReceiveTimeout.tv_sec = timeout/1000; /* second */ this->m_ReceiveTimeout.tv_usec = (timeout%1000) * 1000; /* microsecond */ socklen_t len; #endif if ( timeout > 0 ) { getsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_RCVTIMEO, (char*)&(this->m_OrigReceiveTimeout), &len); setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_RCVTIMEO, (char*)&(this->m_ReceiveTimeout), sizeof(this->m_ReceiveTimeout)); this->m_ReceiveTimeoutFlag = 1; } else if (this->m_ReceiveTimeoutFlag) { setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_RCVTIMEO, (char*)&(this->m_OrigReceiveTimeout), sizeof(this->m_OrigReceiveTimeout)); this->m_ReceiveTimeoutFlag = 0; } return timeout; } //----------------------------------------------------------------------------- int Socket::SetSendTimeout(int timeout) { if (!this->GetConnected()) { return 0; } #if defined(_WIN32) && !defined(__CYGWIN__) this->m_SendTimeout = timeout; int len; #else this->m_SendTimeout.tv_sec = timeout/1000; /* second */ this->m_SendTimeout.tv_usec = (timeout%1000) * 1000; /* microsecond */ socklen_t len; #endif if ( timeout > 0 ) { getsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_SNDTIMEO, (char*)&(this->m_OrigSendTimeout), &len); setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_SNDTIMEO, (char*)&(this->m_SendTimeout), sizeof(this->m_SendTimeout)); this->m_SendTimeoutFlag = 1; } else if (this->m_SendTimeoutFlag) { setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_SNDTIMEO, (char*)&(this->m_OrigSendTimeout), sizeof(this->m_OrigSendTimeout)); this->m_SendTimeoutFlag = 0; } return timeout; } //----------------------------------------------------------------------------- int Socket::SetReceiveBlocking(int sw) { if (!this->GetConnected()) { return 0; } // If sw == 1, timeout is set to 0 (wait until it receives message) #if defined(_WIN32) && !defined(__CYGWIN__) if (sw==0) { this->m_ReceiveTimeout = 1; } else { this->m_ReceiveTimeout = 0; } int len; #else if (sw==0) { this->m_ReceiveTimeout.tv_sec = 0; /* second */ this->m_ReceiveTimeout.tv_usec = 1; /* nanosecond */ } else { this->m_ReceiveTimeout.tv_sec = 0; /* second */ this->m_ReceiveTimeout.tv_usec = 0; /* nanosecond */ } socklen_t len; #endif if (sw==0) { getsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_RCVTIMEO, (char*)&(this->m_OrigReceiveTimeout), &len); setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_RCVTIMEO, (char*)&(this->m_ReceiveTimeout), sizeof(this->m_ReceiveTimeout)); this->m_ReceiveTimeoutFlag = 1; } else if (this->m_ReceiveTimeoutFlag) { setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_RCVTIMEO, (char*)&(this->m_OrigReceiveTimeout), sizeof(this->m_OrigReceiveTimeout)); this->m_ReceiveTimeoutFlag = 0; } return sw; } //----------------------------------------------------------------------------- int Socket::SetSendBlocking(int sw) { if (!this->GetConnected()) { return 0; } // If sw == 1, timeout is set to 0 (wait until it receives message) #if defined(_WIN32) && !defined(__CYGWIN__) if (sw==0) { this->m_SendTimeout = 1; } else { this->m_SendTimeout = 0; } int len; #else if (sw==0) { this->m_SendTimeout.tv_sec = 0; /* second */ this->m_SendTimeout.tv_usec = 1; /* nanosecond */ } else { this->m_SendTimeout.tv_sec = 0; /* second */ this->m_SendTimeout.tv_usec = 0; /* nanosecond */ } socklen_t len; #endif if (sw==0) { getsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_SNDTIMEO, (char*)&(this->m_OrigSendTimeout), &len); setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_SNDTIMEO, (char*)&(this->m_SendTimeout), sizeof(this->m_SendTimeout)); this->m_SendTimeoutFlag = 1; } else if (this->m_SendTimeoutFlag) { setsockopt(this->m_SocketDescriptor, SOL_SOCKET, SO_SNDTIMEO, (char*)&(this->m_OrigSendTimeout), sizeof(this->m_OrigSendTimeout)); this->m_SendTimeoutFlag = 0; } return sw; } //----------------------------------------------------------------------------- int Socket::GetSocketAddressAndPort(std::string& address, int& port) { struct sockaddr_in sockinfo; memset(&sockinfo, 0, sizeof(sockinfo)); #if defined(OpenIGTLink_HAVE_GETSOCKNAME_WITH_SOCKLEN_T) socklen_t sizebuf = sizeof(sockinfo); #else int sizebuf = sizeof(sockinfo); #endif if( getsockname(this->m_SocketDescriptor, reinterpret_cast(&sockinfo), &sizebuf) != 0) { return 0; } const char* a = inet_ntoa(sockinfo.sin_addr); if ( a == NULL ) { return 0; } address = a; port = ntohs(sockinfo.sin_port); return 1; } //----------------------------------------------------------------------------- int Socket::Skip(int length, int skipFully/*=1*/) { if (length == 0) { return 0; } unsigned char dummy[256]; int block = 256; int n = 0; int remain = length; do { if (remain < block) { block = remain; } n = this->Receive(dummy, block, skipFully); if (!skipFully && n <= 0) { break; } remain -= n; } while (remain > 0 || (skipFully && n < block)); return (length - remain); } //----------------------------------------------------------------------------- void Socket::PrintSelf(std::ostream& os) const { this->Superclass::PrintSelf(os); } } // end of igtl namespace openigtlink-3.0.0/Source/igtlSocket.h000066400000000000000000000141761501024245700175670ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: igtlSocket.h,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** \class Socket * \brief BSD socket encapsulation. * * This abstract class encapsulates a BSD socket. * It provides an API for basic socket operations. * * This class was largely based on the igtlSocket class * from the Visualization Toolkit VTK. * */ #ifndef __igtlSocket_h #define __igtlSocket_h #include "igtlObject.h" #include "igtlObjectFactory.h" #include "igtlMacro.h" #include "igtlWin32Header.h" #if defined(_WIN32) && !defined(__CYGWIN__) #else #include #endif namespace igtl { class SocketCollection; /// class IGTL_EXPORT Socket class IGTLCommon_EXPORT Socket : public Object { public: typedef Socket Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::Socket, igtl::Object) igtlNewMacro(igtl::Socket); public: /// Check is the socket is alive. bool GetConnected() { return (this->m_SocketDescriptor >=0); } /// Close the socket. void CloseSocket() { this->CloseSocket(this->m_SocketDescriptor); this->m_SocketDescriptor = -1; } /// These methods send data over the socket. /// Returns 1 on success, 0 on error and raises vtkCommand::ErrorEvent. /// SIGPIPE or other signal may be raised on systems (e.g., Sun Solaris) where /// MSG_NOSIGNAL flag is not supported for the socket send method. int Send(const void* data, int length); /// Receive data from the socket. /// This call blocks until some data is read from the socket, unless timeout is set /// by SetTimeout() or SetReceiveTimeout(). /// When the readFully flag is set, this call will block until all the requested data is /// read from the socket. The readFully flag will be ignored if the timeout is active. /// 0 on error, -1 on timeout, else number of bytes read is returned. int Receive(void* data, int length, int readFully=1); /// Set sending/receiving timeout for the existing socket in millisecond. /// This function should be called after opening the socket. int SetTimeout(int timeout); /// Set reciving timeout for the existing socket in millisecond. /// This function should be called after opening the socket. int SetReceiveTimeout(int timeout); /// Set sending timeout for the existing socket in millisecond. /// This function should be called after opening the socket. int SetSendTimeout(int timeout); /// Set (psuedo) non-blocking mode for recv(). When sw=1, the time out is set to /// minimum value (1 microsecond in UNIX, 1 millisecond in Windows) for receiving. int SetReceiveBlocking(int sw); /// Set (psuedo) non-blocking mode for recv(). When sw=1, the time out is set to /// minimum value (1 microsecond in UNIX, 1 millisecond in Windows) for sending. int SetSendBlocking(int sw); /// Get socket address int GetSocketAddressAndPort(std::string& address, int & port); /// Skip reading data from the socket. /// The Skip() call has been newly introduced to the igtlSocket, /// after the class is imported from VTK, thus the call is /// not available in vtkSocket class. int Skip(int length, int skipFully=1); protected: Socket(); ~Socket(); void PrintSelf(std::ostream& os) const; int m_SocketDescriptor; igtlGetMacro(SocketDescriptor, int); //BTX friend class vtkSocketCollection; //ETX /// Creates an endpoint for communication and returns the descriptor. /// -1 indicates error. int CreateSocket(); /// Close the socket. void CloseSocket(int socketdescriptor); /// Binds socket to a particular port. /// Returns 0 on success other -1 is returned. int BindSocket(int socketdescriptor, int port); /// Selects a socket ie. waits for it to change status. /// Returns 1 on success; 0 on timeout; -1 on error. msec=0 implies /// no timeout. int SelectSocket(int socketdescriptor, unsigned long msec); /// Accept a connection on a socket. Returns -1 on error. Otherwise /// the descriptor of the accepted socket. int Accept(int socketdescriptor); /// Listen for connections on a socket. Returns 0 on success. -1 on error. int Listen(int socketdescriptor); /// Connect to a server socket. Returns 0 on success, -1 on error. int Connect(int socketdescriptor, const char* hostname, int port); /// Returns the port to which the socket is connected. /// 0 on error. int GetPort(int socketdescriptor); /// Selects set of sockets. Returns 0 on timeout, -1 on error. /// 1 on success. Selected socket's index is returned thru /// selected_index static int SelectSockets(const int* sockets_to_select, int size, unsigned long msec, int* selected_index); private: Socket(const Socket&); // Not implemented. void operator=(const Socket&); // Not implemented. #if defined(_WIN32) && !defined(__CYGWIN__) DWORD m_SendTimeout; DWORD m_ReceiveTimeout; DWORD m_OrigSendTimeout; DWORD m_OrigReceiveTimeout; #else struct timeval m_SendTimeout; struct timeval m_ReceiveTimeout; struct timeval m_OrigSendTimeout; struct timeval m_OrigReceiveTimeout; #endif int m_SendTimeoutFlag; int m_ReceiveTimeoutFlag; }; } #endif openigtlink-3.0.0/Source/igtlStatusMessage.cxx000066400000000000000000000066551501024245700215050ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlStatusMessage.h" #include "igtl_header.h" #include "igtl_status.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include namespace igtl { StatusMessage::StatusMessage(): MessageBase() { m_StatusHeader = NULL; m_StatusMessage = NULL; m_ErrorName[0] = '\n'; m_SendMessageType = "STATUS"; m_StatusMessageString = ""; } StatusMessage::~StatusMessage() { } void StatusMessage::SetCode(int code) { if (code >= 0 && code < STATUS_NUM_TYPES) { this->m_Code = code; } else { this->m_Code = 0; } } int StatusMessage::GetCode() { return this->m_Code; } void StatusMessage::SetSubCode(igtlInt64 subcode) { this->m_SubCode = subcode; } igtlInt64 StatusMessage::GetSubCode() { return this->m_SubCode; } void StatusMessage::SetErrorName(const char* name) { this->m_ErrorName[IGTL_STATUS_ERROR_NAME_LENGTH-1] = '\0'; strncpy(this->m_ErrorName, name, IGTL_STATUS_ERROR_NAME_LENGTH); } const char* StatusMessage::GetErrorName() { return this->m_ErrorName; } void StatusMessage::SetStatusString(const char* str) { this->m_StatusMessageString = str; } const char* StatusMessage::GetStatusString() { return this->m_StatusMessageString.c_str(); } int StatusMessage::CalculateContentBufferSize() { // The body size sum of the header size and status message size. // Note that the status message ends with '\0' return IGTL_STATUS_HEADER_SIZE + m_StatusMessageString.size() + 1; } int StatusMessage::PackContent() { // Allocate buffer AllocateBuffer(); m_StatusHeader = this->m_Content; m_StatusMessage = (char*)&m_StatusHeader[IGTL_STATUS_HEADER_SIZE]; igtl_status_header* status_header = (igtl_status_header*)this->m_StatusHeader; status_header->code = static_cast(this->m_Code); status_header->subcode = this->m_SubCode; strncpy(status_header->error_name, this->m_ErrorName, IGTL_STATUS_ERROR_NAME_LENGTH); strcpy(this->m_StatusMessage, this->m_StatusMessageString.c_str()); igtl_status_convert_byte_order(status_header); return 1; } int StatusMessage::UnpackContent() { m_StatusHeader = this->m_Content; m_StatusMessage = (char*)&m_StatusHeader[IGTL_STATUS_HEADER_SIZE]; igtl_status_header* status_header = (igtl_status_header*)this->m_StatusHeader; igtl_status_convert_byte_order(status_header); this->m_Code = status_header->code; this->m_SubCode = status_header->subcode; this->m_ErrorName[IGTL_STATUS_ERROR_NAME_LENGTH-1] = '\0'; strncpy(this->m_ErrorName, status_header->error_name, IGTL_STATUS_ERROR_NAME_LENGTH); // make sure that the status message in the pack ends with '\0' if (m_StatusMessage[this->m_BodySizeToRead-IGTL_STATUS_HEADER_SIZE-1] == '\0') { this->m_StatusMessageString = m_StatusMessage; } else { //std::cerr << "status message in the pack does not end with '\0'" << std::endl; } return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlStatusMessage.h000066400000000000000000000113441501024245700211210ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLinkLibrary Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlStatusMessage_h #define __igtlStatusMessage_h #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" namespace igtl { /// A class for the GET_STATUS message type. class IGTLCommon_EXPORT GetStatusMessage: public HeaderOnlyMessageBase { public: typedef GetStatusMessage Self; typedef HeaderOnlyMessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetStatusMessage, igtl::HeaderOnlyMessageBase); igtlNewMacro(igtl::GetStatusMessage); protected: GetStatusMessage() : HeaderOnlyMessageBase() { this->m_SendMessageType = "GET_STATUS"; }; ~GetStatusMessage() {}; }; /// The STATUS data type is used to notify the receiver about the current status of the sender. /// The data consist of status code in a 16-bit unsigned integer, sub code in a 64-bit integer, /// error name in a 20-byte-length character string, and a status message. The length of /// the status message is determined by the size information in the general header. /// The status code is defined as a part of the OpenIGTLink protocol specification listed /// bellow. The sub code is device specific and is defined by developers. In addition, /// developers can build their own error name/code into the status message and additional /// optional description in the following data field. class IGTLCommon_EXPORT StatusMessage: public MessageBase { public: typedef StatusMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StatusMessage, igtl::MessageBase); igtlNewMacro(igtl::StatusMessage); public: /// Status codes -- see igtl_status.h enum { STATUS_INVALID = 0, STATUS_OK = 1, STATUS_UNKNOWN_ERROR = 2, STATUS_PANICK_MODE = 3, /* emergency */ STATUS_NOT_FOUND = 4, /* file, configuration, device etc */ STATUS_ACCESS_DENIED = 5, STATUS_BUSY = 6, STATUS_TIME_OUT = 7, /* Time out / Connection lost */ STATUS_OVERFLOW = 8, /* Overflow / Can't be reached */ STATUS_CHECKSUM_ERROR = 9, /* Checksum error */ STATUS_CONFIG_ERROR = 10, /* Configuration error */ STATUS_RESOURCE_ERROR = 11, /* Not enough resource (memory, storage etc) */ STATUS_UNKNOWN_INSTRUCTION = 12, /* Illegal/Unknown instruction */ STATUS_NOT_READY = 13, /* Device not ready (starting up)*/ STATUS_MANUAL_MODE = 14, /* Manual mode (device does not accept commands) */ STATUS_DISABLED = 15, /* Device disabled */ STATUS_NOT_PRESENT = 16, /* Device not present */ STATUS_UNKNOWN_VERSION = 17, /* Device version not known */ STATUS_HARDWARE_FAILURE = 18, /* Hardware failure */ STATUS_SHUT_DOWN = 19, /* Exiting / shut down in progress */ STATUS_NUM_TYPES = 20 }; public: /// Sets the status code. void SetCode(int code); /// Gets the status code. int GetCode(); /// Sets the sub code. void SetSubCode(igtlInt64 subcode); /// Gets the sub code. igtlInt64 GetSubCode(); /// Sets the error name. The error name can be defined by a developer. void SetErrorName(const char* name); /// Gets the error name. const char* GetErrorName(); /// Sets the status string. void SetStatusString(const char* str); /// Gets the status string. const char* GetStatusString(); protected: StatusMessage(); ~StatusMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// The error code. igtlUint16 m_Code; /// The sub code. igtlInt64 m_SubCode; /// The error name. char m_ErrorName[20]; /// The status message string. std::string m_StatusMessageString; /// A pointer to the byte array of the status header. unsigned char* m_StatusHeader; /// A pointer to the byte array of the status message. char* m_StatusMessage; }; } // namespace igtl #endif // _igtlStatusMessage_hopenigtlink-3.0.0/Source/igtlStringMessage.cxx000066400000000000000000000065261501024245700214650ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlStringMessage.h" #include "igtl_header.h" #include "igtl_string.h" #include // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS namespace igtl { StringMessage::StringMessage() { this->m_SendMessageType = "STRING"; this->m_Encoding = IGTL_STRING_MESSAGE_DEFAULT_ENCODING; this->m_String.clear(); } StringMessage::~StringMessage() { } int StringMessage::SetString(const char* string) { if (strlen(string) > 0xFFFF) /* If the length is beyond the range of unsigned short */ { return 0; } this->m_String = string; return (int) this->m_String.length(); } int StringMessage::SetString(const std::string & string) { if (string.length() > 0xFFFF) /* If the length is beyond the range of unsigned short */ { return 0; } this->m_String = string; return (int) this->m_String.length(); } int StringMessage::SetEncoding(igtlUint16 enc) { // TODO: the argument should be validated before it is substituted this->m_Encoding = enc; return 1; } const char* StringMessage::GetString() { return this->m_String.c_str(); } igtlUint16 StringMessage::GetEncoding() { return this->m_Encoding; } int StringMessage::CalculateContentBufferSize() { // Body pack size is the sum of ENCODING, LENGTH and STRING fields return sizeof(igtlUint16)*2 + this->m_String.length(); } int StringMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_string_header * string_header; char * string; // Set pointers #if OpenIGTLink_HEADER_VERSION >= 2 string_header = (igtl_string_header*) this->m_Content; string = (char *) this->m_Content + sizeof(igtlUint16)*2; #elif OpenIGTLink_PROTOCOL_VERSION <=2 string_header = (igtl_string_header*) this->m_Body; string = (char *) this->m_Body + sizeof(igtlUint16)*2; #endif // Copy data string_header->encoding = static_cast(this->m_Encoding); string_header->length = static_cast(this->m_String.length()); strncpy(string, this->m_String.c_str(), string_header->length); // Convert byte order from host to network igtl_string_convert_byte_order(string_header); return 1; } int StringMessage::UnpackContent() { igtl_string_header * string_header; char * string; #if OpenIGTLink_HEADER_VERSION >= 2 string_header = (igtl_string_header*) (this->m_Content); string = (char *) this->m_Content + sizeof(igtlUint16)*2; #elif OpenIGTLink_PROTOCOL_VERSION <=2 string_header = (igtl_string_header*) this->m_Body; string = (char *) this->m_Body + sizeof(igtlUint16)*2; #endif // Convert byte order from network to host igtl_string_convert_byte_order(string_header); // Copy data this->m_Encoding = string_header->encoding; this->m_String.clear(); this->m_String.append(string, string_header->length); return 1; } } // namespace igtlopenigtlink-3.0.0/Source/igtlStringMessage.h000066400000000000000000000045571501024245700211140ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlStringMessage_h #define __igtlStringMessage_h #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #define IGTL_STRING_MESSAGE_DEFAULT_ENCODING 3 /* Default encoding -- ANSI-X3.5-1968 */ namespace igtl { /// THe STRING message type is used for transferring a character string. It supports character strings up to 65535 bytes. class IGTLCommon_EXPORT StringMessage: public MessageBase { public: typedef StringMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StringMessage, igtl::MessageBase); igtlNewMacro(igtl::StringMessage); public: /// Sets the string by character array. int SetString(const char* string); /// Sets the string by std::string. int SetString(const std::string & string); /// Sets the encoding of the string. For character encoding, please refer IANA Character Sets /// (http://www.iana.org/assignments/character-sets). /// US-ASCII (ANSI-X3.4-1968; MIBenum = 3) is strongly recommended. int SetEncoding(igtlUint16 enc); /// Gets the string. const char* GetString(); /// Gets the encoding of the string. The returned value is defined in /// IANA Character Sets (http://www.iana.org/assignments/character-sets). igtlUint16 GetEncoding(); protected: StringMessage(); ~StringMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// The encoding of the string. /// The value is defined in IANA Character Sets (http://www.iana.org/assignments/character-sets). igtlUint16 m_Encoding; /// The string. std::string m_String; }; } // namespace igtl #endif // _igtlStringMessage_h openigtlink-3.0.0/Source/igtlTimeStamp.cxx000066400000000000000000000145121501024245700206070ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Part of the code is copied from itk::RealTimeClock class in Insight Segmentation & Registration Toolkit: Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkRealTimeClock.cxx,v $ Language: C++ Date: $Date: 2011-03-24 00:08:23 -0400 (Thu, 24 Mar 2011) $ Version: $Revision: 7354 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlTimeStamp.h" #include #if defined(WIN32) || defined(_WIN32) #include #else #include #endif // defined(WIN32) || defined(_WIN32) #include #include "igtl_util.h" namespace igtl { TimeStamp::TimeStamp(): Object() { #if defined(WIN32) || defined(_WIN32) //LARGE_INTEGER frequency; //::QueryPerformanceFrequency(&frequency); // //this->m_WinFrequency = // static_cast< FrequencyType >( (__int64)frequency.QuadPart ); // //SYSTEMTIME st1; //SYSTEMTIME st2; //FILETIME ft1; //FILETIME ft2; // //::memset( &st1, 0, sizeof( st1 ) ); //::memset( &st2, 0, sizeof( st2 ) ); // //st1.wYear = 1601; //st1.wMonth = 1; //st1.wDay = 1; // //st2.wYear = 1970; //st2.wMonth = 1; //st2.wDay = 1; // //::SystemTimeToFileTime(&st1, &ft1); //::SystemTimeToFileTime(&st2, &ft2); // //LARGE_INTEGER ui1; //LARGE_INTEGER ui2; // //memcpy( &ui1, &ft1, sizeof( ui1 ) ); //memcpy( &ui2, &ft2, sizeof( ui2 ) ); // //this->m_WinDifference = // static_cast< TimeStampType >( ui2.QuadPart - ui1.QuadPart) / // static_cast< TimeStampType >( 1e7 ); // //FILETIME currentTime; //LARGE_INTEGER intTime; //LARGE_INTEGER tick; // //::GetSystemTimeAsFileTime( ¤tTime ); //::QueryPerformanceCounter( &tick ); // //memcpy( &intTime, ¤tTime, sizeof( intTime ) ); // //this->m_WinOrigin = // static_cast< TimeStampType >( intTime.QuadPart ) / // static_cast< TimeStampType >( 1e7 ); // //this->m_WinOrigin -= // static_cast< TimeStampType >( (__int64)tick.QuadPart ) / // this->m_WinFrequency; // //this->m_WinOrigin += this->m_WinDifference; // //this->m_Frequency = static_cast( m_WinFrequency ); this->m_WinTimeOrigin = time( NULL ); this->m_WinClockOrigin = clock(); this->m_Frequency = 1000000; #else this->m_Frequency = 1000000; #endif // defined(WIN32) || defined(_WIN32) } TimeStamp::~TimeStamp() { } void TimeStamp::GetTime() { #if defined(WIN32) || defined(_WIN32) //LARGE_INTEGER tick; // //::QueryPerformanceCounter( &tick ); // //TimeStampType value = // static_cast< TimeStampType >( (__int64)tick.QuadPart ) / // this->m_WinFrequency; // //value += this->m_WinOrigin; // //double second = floor(value); clock_t c1 = clock(); this->m_Second = this->m_WinTimeOrigin + ( c1 - this->m_WinClockOrigin ) / CLOCKS_PER_SEC; this->m_Nanosecond = (c1 - this->m_WinClockOrigin ) % CLOCKS_PER_SEC * ( 1e9 / CLOCKS_PER_SEC ); #else struct timeval tval; ::gettimeofday( &tval, 0 ); this->m_Second = tval.tv_sec; this->m_Nanosecond = tval.tv_usec * 1000; /* convert from micro to nano */ #endif // defined(WIN32) || defined(_WIN32) } void TimeStamp::SetTime(double tm) { double second = floor(tm); this->m_Second = static_cast(second); this->m_Nanosecond = static_cast((tm - second)*1e9); } void TimeStamp::SetTime(igtlUint32 second, igtlUint32 nanosecond) { if (nanosecond < 1e9) { this->m_Second = second; this->m_Nanosecond = nanosecond; } } void TimeStamp::SetTime(igtlUint64 tm) { // Export from 64-bit fixed-point expression used in OpenIGTLink igtlInt32 sec = static_cast((tm >> 32 ) & 0xFFFFFFFF); igtlInt32 fraction = static_cast(tm & 0xFFFFFFFF); this->m_Second = sec; this->m_Nanosecond = igtl_frac_to_nanosec(static_cast(fraction)); } //----------------------------------------------------------------------------- void TimeStamp::SetTimeInNanoseconds(igtlUint64 tm) { igtlUint64 sec = tm / 1e9; // integer rounding igtlUint64 nano = sec * 1e9; // round it back up to get whole number of seconds expressed in nanoseconds. this->m_Second = static_cast(sec); this->m_Nanosecond = static_cast(tm - nano); } double TimeStamp::GetTimeStamp() { double tm; tm = static_cast(this->m_Second) + static_cast(this->m_Nanosecond) / 1e9; return tm; } void TimeStamp::GetTimeStamp(igtlUint32* second, igtlUint32* nanosecond) { *second = this->m_Second; *nanosecond = this->m_Nanosecond; } igtlUint64 TimeStamp::GetTimeStampUint64() { // Export as 64-bit fixed-point expression used in OpenIGTLink igtlInt32 sec = this->m_Second; igtlInt32 fraction = igtl_nanosec_to_frac(this->m_Nanosecond); igtlUint64 ts = sec & 0xFFFFFFFF; ts = (ts << 32) | (fraction & 0xFFFFFFFF); return ts; } //----------------------------------------------------------------------------- igtlUint64 TimeStamp::GetTimeStampInNanoseconds() const { igtlUint64 tmp = this->m_Second * 1e9; tmp += this->m_Nanosecond; return tmp; } void TimeStamp::PrintSelf( std::ostream& os) const { Superclass::PrintSelf(os); std::string indent = " "; os << indent << "Frequency of the clock: " << this->m_Frequency << std::endl; os << indent << "Second : " << this->m_Second << std::endl; os << indent << "Nanosecond : " << this->m_Nanosecond << std::endl; } } openigtlink-3.0.0/Source/igtlTimeStamp.h000066400000000000000000000064171501024245700202410ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlTimeStamp_h #define __igtlTimeStamp_h #include "igtlMacro.h" #include "igtlObject.h" #include "igtlObjectFactory.h" #include "igtlTypes.h" #if defined(WIN32) || defined(_WIN32) #include #endif namespace igtl { class IGTLCommon_EXPORT TimeStamp : public Object { public: typedef TimeStamp Self; typedef Object Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; igtlTypeMacro(TimeStamp, Object); igtlNewMacro(Self); /// Gets the frequency of a clock. igtlGetConstMacro(Frequency, igtlUint32); /// Gets the second part of the time stamp. igtlGetConstMacro(Second, igtlUint32); /// Gets the fraction of second part of the time stamp. igtlGetConstMacro(Nanosecond, igtlUint32); /// Gets the current time from the system's clock and save it as a time stamp. void GetTime(); /// Sets the time by double floating-point value. void SetTime(double tm); /// Sets the time by second and nanosecond void SetTime(igtlUint32 second, igtlUint32 nanosecond); /// Sets the time by using 64-bit fixed-point expression used in OpenIGTLink. void SetTime(igtlUint64 tm); /// Sets the time using the total number of nano-seconds since the start of time (Unix Epoch = 1 Jan 1970). /// Note: This is deliberately different to SetTime(); void SetTimeInNanoseconds(igtlUint64 tm); /// Gets the time stamp. Returns a double floating-point value. double GetTimeStamp(); /// Gets the time stamp. The second and nanosecond parts are stored in 'second' and 'nanosecond' void GetTimeStamp(igtlUint32* second, igtlUint32* nanosecond); /// Gets the time stamp. Returns a 64-bit fixed-point expression used in OpenIGTLink. igtlUint64 GetTimeStampUint64(); /// Gets the time in nano-seconds since the start of time (Unix Epoch = 1 Jan 1970). /// Note: This is deliberately different to GetTimeStampUint64(); igtlUint64 GetTimeStampInNanoseconds() const; protected: /** constructor */ TimeStamp(); /** destructor */ virtual ~TimeStamp(); /** Print the object information in a stream. */ virtual void PrintSelf( std::ostream& os) const; private: /// Clock frequency (Hz) igtlInt32 m_Frequency; /// Second part of the time relative to 00:00:00 January 1, 1970 UTC igtlInt32 m_Second; /// Nano-second part of the time stamp igtlInt32 m_Nanosecond; #if defined(WIN32) || defined(_WIN32) //typedef double TimeStampType; //typedef double FrequencyType; // //FrequencyType m_WinFrequency; //TimeStampType m_WinDifference; //TimeStampType m_WinOrigin; time_t m_WinTimeOrigin; clock_t m_WinClockOrigin; #endif }; } // end of namespace igtl #endif // __igtlTimeStamp_h openigtlink-3.0.0/Source/igtlTrackingDataMessage.cxx000066400000000000000000000211651501024245700225470ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlTrackingDataMessage.h" #include "igtlMath.h" #include "igtl_header.h" #include "igtl_tdata.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include #include namespace igtl { //---------------------------------------------------------------------- // igtl::TrackingDataElement class TrackingDataElement::TrackingDataElement() : Object() { this->m_Name = ""; this->m_Type = TYPE_TRACKER; IdentityMatrix(this->m_Matrix); } TrackingDataElement::~TrackingDataElement() { } int TrackingDataElement::SetName(const char* name) { if (strlen(name) <= IGTL_TDATA_LEN_NAME) { this->m_Name = name; return 1; } else { return 0; } } int TrackingDataElement::SetType(igtlUint8 type) { if(type == TYPE_TRACKER || type == TYPE_6D || type == TYPE_3D || type == TYPE_5D) { this->m_Type = type; return type; } else { return 0; } } void TrackingDataElement::SetPosition(float p[3]) { this->m_Matrix[0][3] = p[0]; this->m_Matrix[1][3] = p[1]; this->m_Matrix[2][3] = p[2]; } void TrackingDataElement::GetPosition(float p[3]) { p[0] = this->m_Matrix[0][3]; p[1] = this->m_Matrix[1][3]; p[2] = this->m_Matrix[2][3]; } void TrackingDataElement::SetPosition(float px, float py, float pz) { this->m_Matrix[0][3] = px; this->m_Matrix[1][3] = py; this->m_Matrix[2][3] = pz; } void TrackingDataElement::GetPosition(float* px, float* py, float* pz) { *px = this->m_Matrix[0][3]; *py = this->m_Matrix[1][3]; *pz = this->m_Matrix[2][3]; } void TrackingDataElement::SetMatrix(Matrix4x4& mat) { m_Matrix[0][0] = mat[0][0]; m_Matrix[1][0] = mat[1][0]; m_Matrix[2][0] = mat[2][0]; m_Matrix[3][0] = mat[3][0]; m_Matrix[0][1] = mat[0][1]; m_Matrix[1][1] = mat[1][1]; m_Matrix[2][1] = mat[2][1]; m_Matrix[3][1] = mat[3][1]; m_Matrix[0][2] = mat[0][2]; m_Matrix[1][2] = mat[1][2]; m_Matrix[2][2] = mat[2][2]; m_Matrix[3][2] = mat[3][2]; m_Matrix[0][3] = mat[0][3]; m_Matrix[1][3] = mat[1][3]; m_Matrix[2][3] = mat[2][3]; m_Matrix[3][3] = mat[3][3]; } void TrackingDataElement::GetMatrix(Matrix4x4& mat) { mat[0][0] = m_Matrix[0][0]; mat[1][0] = m_Matrix[1][0]; mat[2][0] = m_Matrix[2][0]; mat[3][0] = m_Matrix[3][0]; mat[0][1] = m_Matrix[0][1]; mat[1][1] = m_Matrix[1][1]; mat[2][1] = m_Matrix[2][1]; mat[3][1] = m_Matrix[3][1]; mat[0][2] = m_Matrix[0][2]; mat[1][2] = m_Matrix[1][2]; mat[2][2] = m_Matrix[2][2]; mat[3][2] = m_Matrix[3][2]; mat[0][3] = m_Matrix[0][3]; mat[1][3] = m_Matrix[1][3]; mat[2][3] = m_Matrix[2][3]; mat[3][3] = m_Matrix[3][3]; } //---------------------------------------------------------------------- // igtl::StartTrackingDataMessage class StartTrackingDataMessage::StartTrackingDataMessage() { this->m_SendMessageType = "STT_TDATA"; this->m_Resolution = 0; this->m_CoordinateName = ""; } StartTrackingDataMessage::~StartTrackingDataMessage() { } int StartTrackingDataMessage::SetCoordinateName(const char* name) { if (strlen(name) <= IGTL_STT_TDATA_LEN_COORDNAME) { this->m_CoordinateName = name; return 1; } else { return 0; } } int StartTrackingDataMessage::CalculateContentBufferSize() { return IGTL_STT_TDATA_SIZE; } int StartTrackingDataMessage::PackContent() { AllocateBuffer(); igtl_stt_tdata* stt_tdata = NULL; stt_tdata = (igtl_stt_tdata*)(this->m_Content); stt_tdata->resolution = this->m_Resolution; strncpy(stt_tdata->coord_name, this->m_CoordinateName.c_str(), IGTL_STT_TDATA_LEN_COORDNAME); igtl_stt_tdata_convert_byte_order(stt_tdata); return 1; } int StartTrackingDataMessage::UnpackContent() { igtl_stt_tdata* stt_tdata = NULL; stt_tdata = (igtl_stt_tdata*)(this->m_Content); igtl_stt_tdata_convert_byte_order(stt_tdata); this->m_Resolution = stt_tdata->resolution; char strbuf[IGTL_STT_TDATA_LEN_COORDNAME+1]; strbuf[IGTL_STT_TDATA_LEN_COORDNAME] = '\n'; strncpy(strbuf, stt_tdata->coord_name, IGTL_STT_TDATA_LEN_COORDNAME); this->SetCoordinateName(strbuf); return 1; } //---------------------------------------------------------------------- // igtl::RTSTrackingDataMessage class int RTSTrackingDataMessage::CalculateContentBufferSize() { return IGTL_RTS_TDATA_SIZE; } int RTSTrackingDataMessage::PackContent() { AllocateBuffer(); igtl_rts_tdata* rts_tdata = NULL; rts_tdata = (igtl_rts_tdata*)this->m_Content; rts_tdata->status = this->m_Status; igtl_rts_tdata_convert_byte_order(rts_tdata); return 1; } int RTSTrackingDataMessage::UnpackContent() { igtl_rts_tdata* rts_tdata = NULL; rts_tdata = (igtl_rts_tdata*)this->m_Content; igtl_rts_tdata_convert_byte_order(rts_tdata); this->m_Status= rts_tdata->status; return 1; } //---------------------------------------------------------------------- // igtl::TrackingDataMessage class TrackingDataMessage::TrackingDataMessage() { this->m_SendMessageType = "TDATA"; this->m_TrackingDataList.clear(); } TrackingDataMessage::~TrackingDataMessage() { } int TrackingDataMessage::AddTrackingDataElement(TrackingDataElement::Pointer& elem) { this->m_TrackingDataList.push_back(elem); return this->m_TrackingDataList.size(); } void TrackingDataMessage::ClearTrackingDataElements() { this->m_TrackingDataList.clear(); } int TrackingDataMessage::GetNumberOfTrackingDataElements() { return this->m_TrackingDataList.size(); } void TrackingDataMessage::GetTrackingDataElement(int index, TrackingDataElement::Pointer& elem) { if (index >= 0 && index < (int)this->m_TrackingDataList.size()) { elem = this->m_TrackingDataList[index]; } } int TrackingDataMessage::CalculateContentBufferSize() { // The body size sum of the header size and status message size. return IGTL_TDATA_ELEMENT_SIZE * this->m_TrackingDataList.size(); } int TrackingDataMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_tdata_element* element = NULL; element = (igtl_tdata_element*)(this->m_Content); igtl_tdata_element * elementHolder = element; std::vector::iterator iter; for (iter = this->m_TrackingDataList.begin(); iter != this->m_TrackingDataList.end(); iter ++) { strncpy((char*)element->name, (*iter)->GetName(), IGTL_TDATA_LEN_NAME); element->type = (*iter)->GetType(); element->reserved = 0; Matrix4x4 matrix; (*iter)->GetMatrix(matrix); for (int i = 0; i < 3; i ++) { element->transform[i] = matrix[i][0]; element->transform[i+3] = matrix[i][1]; element->transform[i+6] = matrix[i][2]; element->transform[i+9] = matrix[i][3]; } element ++; } igtl_tdata_convert_byte_order(elementHolder, this->m_TrackingDataList.size()); return 1; } int TrackingDataMessage::UnpackContent() { this->m_TrackingDataList.clear(); igtl_tdata_element* element = NULL; int nElement = 0; element = (igtl_tdata_element*)(this->m_Content); nElement = igtl_tdata_get_data_n(CalculateReceiveContentSize()); igtl_tdata_convert_byte_order(element, nElement); char strbuf[128]; for (int i = 0; i < nElement; i ++) { TrackingDataElement::Pointer elemClass = TrackingDataElement::New(); // Add '\n' at the end of each string // (neccesary for a case, where a string reaches the maximum length.) strbuf[IGTL_TDATA_LEN_NAME] = '\n'; strncpy(strbuf, (char*)element->name, IGTL_TDATA_LEN_NAME); elemClass->SetName((const char*)strbuf); elemClass->SetType(element->type); Matrix4x4 matrix; IdentityMatrix(matrix); for (int j = 0; j < 3; j ++) { matrix[j][0] = element->transform[j]; matrix[j][1] = element->transform[j+3]; matrix[j][2] = element->transform[j+6]; matrix[j][3] = element->transform[j+9]; } elemClass->SetMatrix(matrix); this->m_TrackingDataList.push_back(elemClass); element ++; } return 1; } } // namespace igtl openigtlink-3.0.0/Source/igtlTrackingDataMessage.h000066400000000000000000000174701501024245700222000ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlTrackingDataMessage_h #define __igtlTrackingDataMessage_h #include #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" namespace igtl { class IGTLCommon_EXPORT TrackingDataElement: public Object { public: typedef TrackingDataElement Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::TrackingDataElement, igtl::Object); igtlNewMacro(igtl::TrackingDataElement); /// Tracking data type. /// TYPE_TRACKER: Tracker /// TYPE_6D: 6D instrument: (regular instrument) /// TYPE_3D: 3D instrument (only tip of the instrument defined) /// TYPE_5D: 5D instrument (tip and handle are defined, but not the normal vector) enum { TYPE_TRACKER = 1, TYPE_6D = 2, TYPE_3D = 3, TYPE_5D = 4, }; public: /// Sets the name of the instrument/tracker. int SetName(const char* name); /// Gets the name of the instrument/tracker. const char* GetName() { return this->m_Name.c_str(); }; /// Sets the type of the instrument/tracker. int SetType(igtlUint8 type); /// Gets the type of the instrument/tracker. igtlUint8 GetType() { return this->m_Type; }; /// Sets the position by 3-element array of x, y, and z coordinates. void SetPosition(float p[3]); /// Gets the position. The function substitutes 3-element array of x, y and z coordinates in 'p'. void GetPosition(float p[3]); /// Sets the position by x, y, and z coordinates. void SetPosition(float px, float py, float pz); /// Gets the position. The function substitutes the xyz coordinates in 'px', 'py', and 'pz'. void GetPosition(float* px, float* py, float* pz); /// Sets the 4-by-4 transformation matrix. void SetMatrix(Matrix4x4& mat); /// Gets the 4-by-4 transformation matrix. void GetMatrix(Matrix4x4& mat); protected: TrackingDataElement(); ~TrackingDataElement(); protected: /// Name / description (< 20 bytes std::string m_Name; /// Tracking data type (TYPE_TRACKER, TYPE_6D, TYPE_3D, TYPE_5D) igtlUint8 m_Type; /// Transform matrix Matrix4x4 m_Matrix; }; /// A class for the STT_TDATA message type. class IGTLCommon_EXPORT StartTrackingDataMessage: public MessageBase { public: typedef StartTrackingDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StartTrackingDataMessage, igtl::MessageBase); igtlNewMacro(igtl::StartTrackingDataMessage); public: /// Sets the time resolution for streaming of QTDATA messages void SetResolution(igtlInt32 res) { this->m_Resolution = res; }; // ms /// Gets the time resolution for streaming of QTDATA messages igtlInt32 GetResolution() { return this->m_Resolution; }; /// Sets the name of the coordinate system. The name must be defined by the user. int SetCoordinateName(const char* name); /// Gets the name of the coordinate system. const char* GetCoordinateName() { return this->m_CoordinateName.c_str(); }; protected: StartTrackingDataMessage(); ~StartTrackingDataMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); protected: /// Minimum time between two frames (ms). Use 0 for as fast as possible. igtlInt32 m_Resolution; /// Name of the coordinate system. std::string m_CoordinateName; }; /// A class for the STP_TDATA message type. class IGTLCommon_EXPORT StopTrackingDataMessage: public MessageBase { public: typedef StopTrackingDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::StopTrackingDataMessage, igtl::MessageBase); igtlNewMacro(igtl::StopTrackingDataMessage); protected: StopTrackingDataMessage() : MessageBase() { this->m_SendMessageType = "STP_TDATA"; }; ~StopTrackingDataMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// A class for the RTS_TDATA message type. class IGTLCommon_EXPORT RTSTrackingDataMessage: public MessageBase { public: typedef RTSTrackingDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /// Status type enum { STATUS_SUCCESS = 0, STATUS_ERROR = 1 }; igtlTypeMacro(igtl::RTSTrackingDataMessage, igtl::MessageBase); igtlNewMacro(igtl::RTSTrackingDataMessage); /// Sets the status. 'status' must be either STATUS_SUCCESS or STATUS_ERROR. void SetStatus(igtlUint8 status){ this->m_Status = status; } /// Gets the status. The function returns either STATUS_SUCCESS or STATUS_ERROR. igtlUint8 GetStatus() { return this->m_Status; }; protected: RTSTrackingDataMessage() : MessageBase(), m_Status(0) { this->m_SendMessageType = "RTS_TDATA"; }; ~RTSTrackingDataMessage() {}; /// A variable to store the status. igtlUint8 m_Status; protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); }; /// The TDATA message type is intended for transferring 3D positions of surgical tools, /// markers etc. Those positions are often measured by optical, electromagnetic or other /// type of 3D position sensor continuously and transferred as series of messages. /// Since it is important for software that receives TDATA to control data flow, /// STT_TDATA query data type has interval field to control the frame rate of consecutive messages. class IGTLCommon_EXPORT TrackingDataMessage: public MessageBase { public: typedef TrackingDataMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::TrackingDataMessage, igtl::MessageBase); igtlNewMacro(igtl::TrackingDataMessage); public: /// Adds tracking data element. int AddTrackingDataElement(TrackingDataElement::Pointer& elem); /// Clears the all tracking data element in the list. void ClearTrackingDataElements(); /// Gets the number of tracking data elements in the list. int GetNumberOfTrackingDataElements(); inline int GetNumberOfTrackingDataElement() { return GetNumberOfTrackingDataElements(); }; // will be removed. /// Gets the tracking data element specified by 'index'. void GetTrackingDataElement(int index, TrackingDataElement::Pointer& elem); protected: TrackingDataMessage(); ~TrackingDataMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// The list of tracking data elements. std::vector m_TrackingDataList; }; } // namespace igtl #endif // _igtlTrackingDataMessage_hopenigtlink-3.0.0/Source/igtlTrajectoryMessage.cxx000066400000000000000000000212361501024245700223400ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlTrajectoryMessage.h" #include "igtl_header.h" #include "igtl_trajectory.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS #include #include namespace igtl { //---------------------------------------------------------------------- // igtl::TrajectoryElement class TrajectoryElement::TrajectoryElement() : Object() { this->m_Name = ""; this->m_GroupName = ""; this->m_Type = TYPE_TARGET_ONLY; this->m_RGBA[0] = 0; this->m_RGBA[1] = 0; this->m_RGBA[2] = 0; this->m_RGBA[3] = 0; this->m_EntryPosition[0] = 0.0; this->m_EntryPosition[1] = 0.0; this->m_EntryPosition[2] = 0.0; this->m_TargetPosition[0] = 0.0; this->m_TargetPosition[1] = 0.0; this->m_TargetPosition[2] = 0.0; this->m_Radius = 0.0; this->m_Owner = ""; } TrajectoryElement::~TrajectoryElement() { } int TrajectoryElement::SetName(const char* name) { if (strlen(name) <= IGTL_TRAJECTORY_LEN_NAME) { this->m_Name = name; return 1; } else { return 0; } } int TrajectoryElement::SetGroupName(const char* grpname) { if (strlen(grpname) <= IGTL_TRAJECTORY_LEN_GROUP_NAME) { this->m_GroupName = grpname; return 1; } else { return 0; } } int TrajectoryElement::SetType(igtlUint8 type) { if (type == TYPE_ENTRY_ONLY|| type == TYPE_TARGET_ONLY|| TYPE_ENTRY_TARGET) { this->m_Type = type; return 1; } else { return 0; } } void TrajectoryElement::SetRGBA(igtlUint8 rgba[4]) { this->m_RGBA[0] = rgba[0]; this->m_RGBA[1] = rgba[1]; this->m_RGBA[2] = rgba[2]; this->m_RGBA[3] = rgba[3]; } void TrajectoryElement::SetRGBA(igtlUint8 r, igtlUint8 g, igtlUint8 b, igtlUint8 a) { this->m_RGBA[0] = r; this->m_RGBA[1] = g; this->m_RGBA[2] = b; this->m_RGBA[3] = a; } void TrajectoryElement::GetRGBA(igtlUint8* rgba) { rgba[0] = this->m_RGBA[0]; rgba[1] = this->m_RGBA[1]; rgba[2] = this->m_RGBA[2]; rgba[3] = this->m_RGBA[3]; } void TrajectoryElement::GetRGBA(igtlUint8& r, igtlUint8& g, igtlUint8& b, igtlUint8& a) { r = this->m_RGBA[0]; g = this->m_RGBA[1]; b = this->m_RGBA[2]; a = this->m_RGBA[3]; } void TrajectoryElement::SetEntryPosition(igtlFloat32 position[3]) { this->m_EntryPosition[0] = position[0]; this->m_EntryPosition[1] = position[1]; this->m_EntryPosition[2] = position[2]; } void TrajectoryElement::SetEntryPosition(igtlFloat32 x, igtlFloat32 y, igtlFloat32 z) { this->m_EntryPosition[0] = x; this->m_EntryPosition[1] = y; this->m_EntryPosition[2] = z; } void TrajectoryElement::GetEntryPosition(igtlFloat32* position) { position[0] = this->m_EntryPosition[0]; position[1] = this->m_EntryPosition[1]; position[2] = this->m_EntryPosition[2]; } void TrajectoryElement::GetEntryPosition(igtlFloat32& x, igtlFloat32& y, igtlFloat32& z) { x = this->m_EntryPosition[0]; y = this->m_EntryPosition[1]; z = this->m_EntryPosition[2]; } void TrajectoryElement::SetTargetPosition(igtlFloat32 position[3]) { this->m_TargetPosition[0] = position[0]; this->m_TargetPosition[1] = position[1]; this->m_TargetPosition[2] = position[2]; } void TrajectoryElement::SetTargetPosition(igtlFloat32 x, igtlFloat32 y, igtlFloat32 z) { this->m_TargetPosition[0] = x; this->m_TargetPosition[1] = y; this->m_TargetPosition[2] = z; } void TrajectoryElement::GetTargetPosition(igtlFloat32* position) { position[0] = this->m_TargetPosition[0]; position[1] = this->m_TargetPosition[1]; position[2] = this->m_TargetPosition[2]; } void TrajectoryElement::GetTargetPosition(igtlFloat32& x, igtlFloat32& y, igtlFloat32& z) { x = this->m_TargetPosition[0]; y = this->m_TargetPosition[1]; z = this->m_TargetPosition[2]; } int TrajectoryElement::SetOwner(const char* owner) { if (strlen(owner) <= IGTL_TRAJECTORY_LEN_OWNER) { this->m_Owner = owner; return 1; } else { return 0; } } //---------------------------------------------------------------------- // igtl::TrajectoryMessage class TrajectoryMessage::TrajectoryMessage() { this->m_SendMessageType = "TRAJ"; this->m_TrajectoryList.clear(); } TrajectoryMessage::~TrajectoryMessage() { } int TrajectoryMessage::AddTrajectoryElement(TrajectoryElement::Pointer& elem) { this->m_TrajectoryList.push_back(elem); return this->m_TrajectoryList.size(); } void TrajectoryMessage::ClearTrajectoryElement(TrajectoryElement::Pointer& elem) { igtlLegacyReplaceBodyMacro(TrajectoryMessage::ClearTrajectoryElement, 3.0, TrajectoryMessage::ClearAllTrajectoryElements); (void)(elem); // Unused variable this->m_TrajectoryList.clear(); } void TrajectoryMessage::ClearAllTrajectoryElements() { this->m_TrajectoryList.clear(); } int TrajectoryMessage::GetNumberOfTrajectoryElement() { return this->m_TrajectoryList.size(); } void TrajectoryMessage::GetTrajectoryElement(int index, TrajectoryElement::Pointer& elem) { if (index >= 0 && index < (int)this->m_TrajectoryList.size()) { elem = this->m_TrajectoryList[index]; } } int TrajectoryMessage::CalculateContentBufferSize() { return IGTL_TRAJECTORY_ELEMENT_SIZE * this->m_TrajectoryList.size(); } int TrajectoryMessage::PackContent() { // Allocate buffer AllocateBuffer(); igtl_trajectory_element* element = NULL; element = (igtl_trajectory_element*)(this->m_Content); igtl_trajectory_element * elementHolder = element; std::vector::iterator iter; for (iter = this->m_TrajectoryList.begin(); iter != this->m_TrajectoryList.end(); iter ++) { strncpy((char*)element->name, (*iter)->GetName(), IGTL_TRAJECTORY_LEN_NAME); strncpy((char*)element->group_name, (*iter)->GetGroupName(), IGTL_TRAJECTORY_LEN_GROUP_NAME); element->type = (*iter)->GetType(); element->reserved = 0; igtlUint8 rgba[4]; (*iter)->GetRGBA(rgba); element->rgba[0] = rgba[0]; element->rgba[1] = rgba[1]; element->rgba[2] = rgba[2]; element->rgba[3] = rgba[3]; igtlFloat32 position[3]; (*iter)->GetEntryPosition(position); element->entry_pos[0] = position[0]; element->entry_pos[1] = position[1]; element->entry_pos[2] = position[2]; (*iter)->GetTargetPosition(position); element->target_pos[0] = position[0]; element->target_pos[1] = position[1]; element->target_pos[2] = position[2]; element->radius = (*iter)->GetRadius(); strncpy((char*)element->owner_name, (*iter)->GetOwner(), IGTL_TRAJECTORY_LEN_OWNER); element ++; } igtl_trajectory_convert_byte_order(elementHolder, this->m_TrajectoryList.size()); return 1; } int TrajectoryMessage::UnpackContent() { this->m_TrajectoryList.clear(); igtl_trajectory_element* element = NULL; int nElement = 0; #if OpenIGTLink_HEADER_VERSION >= 2 element = (igtl_trajectory_element*)(this->m_Content); nElement = igtl_trajectory_get_data_n(CalculateReceiveContentSize()); #elif OpenIGTLink_PROTOCOL_VERSION <=2 element = (igtl_trajectory_element*)this->m_Body; nElement = igtl_trajectory_get_data_n(this->m_BodySizeToRead); #endif igtl_trajectory_convert_byte_order(element, nElement); char strbuf[128]; for (int i = 0; i < nElement; i ++) { TrajectoryElement::Pointer elemClass = TrajectoryElement::New(); // Add '\n' at the end of each string // (neccesary for a case, where a string reaches the maximum length.) strbuf[IGTL_TRAJECTORY_LEN_NAME] = '\n'; strncpy(strbuf, (char*)element->name, IGTL_TRAJECTORY_LEN_NAME); elemClass->SetName((const char*)strbuf); strbuf[IGTL_TRAJECTORY_LEN_GROUP_NAME] = '\n'; strncpy(strbuf, (char*)element->group_name, IGTL_TRAJECTORY_LEN_GROUP_NAME); elemClass->SetGroupName(strbuf); elemClass->SetType(element->type); elemClass->SetRGBA(element->rgba); elemClass->SetEntryPosition(element->entry_pos); elemClass->SetTargetPosition(element->target_pos); elemClass->SetRadius(element->radius); strbuf[IGTL_TRAJECTORY_LEN_OWNER] = '\n'; strncpy(strbuf, (char*)element->owner_name, IGTL_TRAJECTORY_LEN_OWNER); elemClass->SetOwner(strbuf); this->m_TrajectoryList.push_back(elemClass); element ++; } return 1; } } // namespace igtl openigtlink-3.0.0/Source/igtlTrajectoryMessage.h000066400000000000000000000156171501024245700217730ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlTrajectoryMessage_h #define __igtlTrajectoryMessage_h #include #include #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" #include "igtlTypes.h" #include "igtlImageMessage.h" namespace igtl { /// TrajectoryElement class is used to manage a trajectory in TrajectoryMessage class. class IGTLCommon_EXPORT TrajectoryElement: public Object { public: typedef TrajectoryElement Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::TrajectoryElement, igtl::Object); igtlNewMacro(igtl::TrajectoryElement); /// Types of trajectory. enum { TYPE_ENTRY_ONLY = 1, /* Trajectory with only entry point */ TYPE_TARGET_ONLY = 2, /* Trajectory with only target point */ TYPE_ENTRY_TARGET = 3, /* Trajectory with entry and target point */ }; public: /// Sets the name of the trajectory. int SetName(const char* name); /// Gets the name of the trajectory. const char* GetName() { return this->m_Name.c_str(); }; /// Sets the group name e.g. "Trajectory" int SetGroupName(const char* grpname); /// Gets the group name. const char* GetGroupName() { return this->m_GroupName.c_str(); }; /// Sets the trajectory type. 'type' must be either TYPE_ENTRY_ONLY, TYPE_TARGET_ONLY, or TYPE_ENTRY_TARGET. int SetType(igtlUint8 type); /// Gets the trajectory type. The returned value is either TYPE_ENTRY_ONLY, TYPE_TARGET_ONLY, or TYPE_ENTRY_TARGET. igtlUint8 GetType() { return this->m_Type; }; /// Sets the color of the trajectory using an array of r, g, b and alpha. void SetRGBA(igtlUint8 rgba[4]); /// Sets the color of the trajectory by r, g, b and alpha. void SetRGBA(igtlUint8 r, igtlUint8 g, igtlUint8 b, igtlUint8 a); /// Gets the color of the trajectory. An array of r, g, b and alpha is stored in 'rgba' void GetRGBA(igtlUint8* rgba); /// Gets the color of the trajectory. void GetRGBA(igtlUint8& r, igtlUint8& g, igtlUint8& b, igtlUint8& a); /// Sets the entry position using an array. void SetEntryPosition(igtlFloat32 position[3]); /// Sets the entry position. void SetEntryPosition(igtlFloat32 x, igtlFloat32 y, igtlFloat32 z); /// Sets the entry position using an array of x, y, and z coordinates. void GetEntryPosition(igtlFloat32* position); /// Gets the entry position. void GetEntryPosition(igtlFloat32& x, igtlFloat32& y, igtlFloat32& z); /// Sets the target position using an array of x, y, and z coordinates. void SetTargetPosition(igtlFloat32 position[3]); /// Sets the target position. void SetTargetPosition(igtlFloat32 x, igtlFloat32 y, igtlFloat32 z); /// Gets the target position. Stores an array of x, y, and z coordinates in 'position' void GetTargetPosition(igtlFloat32* position); /// Gets the target position. void GetTargetPosition(igtlFloat32& x, igtlFloat32& y, igtlFloat32& z); /// Sets the radius. void SetRadius(igtlFloat32 radius) { this->m_Radius = radius; }; /// Gets the radius. igtlFloat32 GetRadius() { return this->m_Radius; }; /// Sets the owner of the trajectory. 'owner' must be a name of image. int SetOwner(const char* owner); /// Gets the owner of the trajectory. const char* GetOwner() { return this->m_Owner.c_str(); }; protected: TrajectoryElement(); ~TrajectoryElement(); protected: /// name / description (< 64 bytes) std::string m_Name; /// Can be "Labeled Trajectory", "Landmark", Fiducial", ... std::string m_GroupName; /// Trajectory type (see TYPE_* constants) igtlUint8 m_Type; /// Color in R/G/B/A igtlUint8 m_RGBA[4]; /// Coordinate of the entry point igtlFloat32 m_EntryPosition[3]; /// Coordinate of the target point igtlFloat32 m_TargetPosition[3]; /// Radius of the trajectory. Can be 0. igtlFloat32 m_Radius; /// Device name of the ower image. std::string m_Owner; }; /// A class for the GET_TRAJ message type. class IGTLCommon_EXPORT GetTrajectoryMessage: public MessageBase { public: typedef GetTrajectoryMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetTrajectoryMessage, igtl::MessageBase); igtlNewMacro(igtl::GetTrajectoryMessage); protected: GetTrajectoryMessage() : MessageBase() { this->m_SendMessageType = "GET_TRAJ"; }; ~GetTrajectoryMessage() {}; protected: virtual int CalculateContentBufferSize() { return 0; }; virtual int PackContent() { AllocateBuffer(); return 1; }; virtual int UnpackContent() { return 1; }; }; /// The TRAJECTORY message type support to transfer information about 3D trajectory, /// which is often used in surgical planning and guidance in image-guided therapy. class IGTLCommon_EXPORT TrajectoryMessage: public MessageBase { public: typedef TrajectoryMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::TrajectoryMessage, igtl::MessageBase); igtlNewMacro(igtl::TrajectoryMessage); public: /// Adds a trajectory to the list. int AddTrajectoryElement(TrajectoryElement::Pointer& elem); /// Clears the all trajectory from the list. igtlLegacyMacro( void ClearTrajectoryElement(TrajectoryElement::Pointer& elem)); /// Clears all trajectory elements from the list. void ClearAllTrajectoryElements(); /// Gets the number of trajectory in the list. int GetNumberOfTrajectoryElement(); /// Gets the trajectory specified by 'index'. void GetTrajectoryElement(int index, TrajectoryElement::Pointer& elem); protected: TrajectoryMessage(); ~TrajectoryMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// A list of pointers to the trajectories. std::vector m_TrajectoryList; }; } // namespace igtl #endif // _igtlTrajectoryMessage_hopenigtlink-3.0.0/Source/igtlTransformMessage.cxx000066400000000000000000000136611501024245700221700ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlTransformMessage.h" #include "igtl_header.h" #include "igtl_transform.h" #include namespace igtl { TransformMessage::TransformMessage() : MessageBase() { m_Transform = m_Content; matrix[0][0] = 1.0; matrix[1][0] = 0.0; matrix[2][0] = 0.0; matrix[3][0] = 0.0; matrix[0][1] = 0.0; matrix[1][1] = 1.0; matrix[2][1] = 0.0; matrix[3][1] = 0.0; matrix[0][2] = 0.0; matrix[1][2] = 0.0; matrix[2][2] = 1.0; matrix[3][2] = 0.0; matrix[0][3] = 0.0; matrix[1][3] = 0.0; matrix[2][3] = 0.0; matrix[3][3] = 1.0; m_SendMessageType = "TRANSFORM"; } TransformMessage::~TransformMessage() { } void TransformMessage::SetPosition(float p[3]) { matrix[0][3] = p[0]; matrix[1][3] = p[1]; matrix[2][3] = p[2]; } void TransformMessage::GetPosition(float p[3]) { p[0] = matrix[0][3]; p[1] = matrix[1][3]; p[2] = matrix[2][3]; } void TransformMessage::SetPosition(float px, float py, float pz) { matrix[0][3] = px; matrix[1][3] = py; matrix[2][3] = pz; } void TransformMessage::GetPosition(float* px, float* py, float* pz) { *px = matrix[0][3]; *py = matrix[1][3]; *pz = matrix[2][3]; } void TransformMessage::SetNormals(float o[3][3]) { matrix[0][0] = o[0][0]; matrix[0][1] = o[0][1]; matrix[0][2] = o[0][2]; matrix[1][0] = o[1][0]; matrix[1][1] = o[1][1]; matrix[1][2] = o[1][2]; matrix[2][0] = o[2][0]; matrix[2][1] = o[2][1]; matrix[2][2] = o[2][2]; } void TransformMessage::GetNormals(float o[3][3]) { o[0][0] = matrix[0][0]; o[0][1] = matrix[0][1]; o[0][2] = matrix[0][2]; o[1][0] = matrix[1][0]; o[1][1] = matrix[1][1]; o[1][2] = matrix[1][2]; o[2][0] = matrix[2][0]; o[2][1] = matrix[2][1]; o[2][2] = matrix[2][2]; } void TransformMessage::SetNormals(float t[3], float s[3], float n[3]) { matrix[0][0] = t[0]; matrix[1][0] = t[1]; matrix[2][0] = t[2]; matrix[0][1] = s[0]; matrix[1][1] = s[1]; matrix[2][1] = s[2]; matrix[0][2] = n[0]; matrix[1][2] = n[1]; matrix[2][2] = n[2]; } void TransformMessage::GetNormals(float t[3], float s[3], float n[3]) { t[0] = matrix[0][0]; t[1] = matrix[1][0]; t[2] = matrix[2][0]; s[0] = matrix[0][1]; s[1] = matrix[1][1]; s[2] = matrix[2][1]; n[0] = matrix[0][2]; n[1] = matrix[1][2]; n[2] = matrix[2][2]; } void TransformMessage::SetMatrix(Matrix4x4& mat) { matrix[0][0] = mat[0][0]; matrix[1][0] = mat[1][0]; matrix[2][0] = mat[2][0]; matrix[3][0] = mat[3][0]; matrix[0][1] = mat[0][1]; matrix[1][1] = mat[1][1]; matrix[2][1] = mat[2][1]; matrix[3][1] = mat[3][1]; matrix[0][2] = mat[0][2]; matrix[1][2] = mat[1][2]; matrix[2][2] = mat[2][2]; matrix[3][2] = mat[3][2]; matrix[0][3] = mat[0][3]; matrix[1][3] = mat[1][3]; matrix[2][3] = mat[2][3]; matrix[3][3] = mat[3][3]; } void TransformMessage::GetMatrix(Matrix4x4& mat) { mat[0][0] = matrix[0][0]; mat[1][0] = matrix[1][0]; mat[2][0] = matrix[2][0]; mat[3][0] = matrix[3][0]; mat[0][1] = matrix[0][1]; mat[1][1] = matrix[1][1]; mat[2][1] = matrix[2][1]; mat[3][1] = matrix[3][1]; mat[0][2] = matrix[0][2]; mat[1][2] = matrix[1][2]; mat[2][2] = matrix[2][2]; mat[3][2] = matrix[3][2]; mat[0][3] = matrix[0][3]; mat[1][3] = matrix[1][3]; mat[2][3] = matrix[2][3]; mat[3][3] = matrix[3][3]; } int TransformMessage::CalculateContentBufferSize() { return IGTL_TRANSFORM_SIZE; } int TransformMessage::PackContent() { AllocateBuffer(); // The m_Transform is not aligned with m_Body, when allocatePack() is called. // This is to realign the two pointers. #if OpenIGTLink_HEADER_VERSION >= 2 this->m_Transform = this->m_Content; #else this->m_Transform = m_Body; #endif //igtl_float32* transform = (igtl_float32*)this->m_Transform; // doesn't work on Solaris igtl_float32 transform[12]; for (int i = 0; i < 3; i ++) { transform[i] = matrix[i][0]; transform[i+3] = matrix[i][1]; transform[i+6] = matrix[i][2]; transform[i+9] = matrix[i][3]; } igtl_transform_convert_byte_order(transform); #if OpenIGTLink_HEADER_VERSION >= 2 if (m_HeaderVersion == IGTL_HEADER_VERSION_2) { memcpy((void*)(this->m_Transform), (void*)transform, sizeof(igtl_float32)*12); } else { memcpy((void*)this->m_Transform, (void*)transform, sizeof(igtl_float32)*12); } #elif OpenIGTLink_PROTOCOL_VERSION <= 2 memcpy((void*)this->m_Transform, (void*)transform, sizeof(igtl_float32)*12); #endif return 1; } int TransformMessage::UnpackContent() { this->m_Transform = this->m_Content; //igtl_float32* transform = (igtl_float32*)this->m_Transform; // doesn't work on Solaris igtl_float32 transform[12]; #if OpenIGTLink_HEADER_VERSION >= 2 if (m_HeaderVersion == IGTL_HEADER_VERSION_2) { memcpy((void*)transform, (void*)(this->m_Transform), sizeof(igtl_float32)*12); } else { memcpy((void*)transform, (void*)this->m_Transform, sizeof(igtl_float32)*12); } #elif OpenIGTLink_PROTOCOL_VERSION <= 2 memcpy((void*)transform, (void*)this->m_Transform, sizeof(igtl_float32)*12); #endif igtl_transform_convert_byte_order(transform); for (int i = 0; i < 3; i ++) { matrix[i][0] = transform[i] ; matrix[i][1] = transform[i+3]; matrix[i][2] = transform[i+6]; matrix[i][3] = transform[i+9]; } matrix[3][0] = 0.0; matrix[3][1] = 0.0; matrix[3][2] = 0.0; matrix[3][3] = 1.0; return 1; } } // namespace igtl openigtlink-3.0.0/Source/igtlTransformMessage.h000066400000000000000000000071031501024245700216070ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlTransformMessage_h #define __igtlTransformMessage_h #include "igtlObject.h" #include "igtlMath.h" #include "igtlMessageBase.h" namespace igtl { /// A class for the GET_TRANS message type. class IGTLCommon_EXPORT GetTransformMessage: public HeaderOnlyMessageBase { public: typedef GetTransformMessage Self; typedef HeaderOnlyMessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::GetTransformMessage, igtl::HeaderOnlyMessageBase); igtlNewMacro(igtl::GetTransformMessage); protected: GetTransformMessage() : HeaderOnlyMessageBase() { this->m_SendMessageType = "GET_TRANS"; }; ~GetTransformMessage() {}; }; /// The TRANSFORM data type is used to transfer a homogeneous linear transformation /// in 4-by-4 matrix form. One such matrix was shown earlier in equation (1). /// Note that if a device is sending only translation and rotation, then TRANSFORM /// is equivalent to POSITION. But TRANSFORM can also be used to transfer affine /// transformations or simple scaling. Like IMAGE and POSITION, TRANSFORM carries /// information about the coordinate system used. class IGTLCommon_EXPORT TransformMessage: public MessageBase { public: typedef TransformMessage Self; typedef MessageBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; igtlTypeMacro(igtl::TransformMessage, igtl::MessageBase); igtlNewMacro(igtl::TransformMessage); public: /// Sets a position (or a translation vector) in the RAS coordinate system. void SetPosition(float p[3]); /// Gets a position (or a translation vector) in the RAS coordinate system. void GetPosition(float p[3]); /// Sets a position (or a translation vector) in the RAS coordinate system. void SetPosition(float px, float py, float pz); /// Gets a position (or a translation vector) in the RAS coordinate system. void GetPosition(float* px, float* py, float* pz); /// Sets normal vectors (or a rotation matrix) in the RAS coordinate system. void SetNormals(float o[3][3]); /// Gets normal vectors (or a rotation matrix) in the RAS coordinate system. void GetNormals(float o[3][3]); /// Sets normal vectors (or a rotation matrix) in the RAS coordinate system. void SetNormals(float t[3], float s[3], float n[3]); /// Gets normal vectors (or a rotation matrix) in the RAS coordinate system. void GetNormals(float t[3], float s[3], float n[3]); /// Sets rotation matrix using igtl::Matrix4x4. void SetMatrix(Matrix4x4& mat); /// Sets rotation matrix using igtl::Matrix4x4. void GetMatrix(Matrix4x4& mat); protected: TransformMessage(); ~TransformMessage(); protected: virtual int CalculateContentBufferSize(); virtual int PackContent(); virtual int UnpackContent(); /// The transformation matrix. Matrix4x4 matrix; /// The byte array for the serialized transform data. unsigned char* m_Transform; }; } // namespace igtl #endif // _igtlTransformMessage_h openigtlink-3.0.0/Source/igtlTypes.h000066400000000000000000000051001501024245700174260ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlTypes_H #define __igtlTypes_H #include "igtlTypeConfig.h" /* 8-bit integer type */ #if IGTL_SIZEOF_CHAR == 1 typedef unsigned char igtlUint8; typedef char igtlInt8; #else # error "No native data type can represent an 8-bit integer." #endif /* 16-bit integer type */ #if IGTL_SIZEOF_SHORT == 2 typedef unsigned short igtlUint16; typedef signed short igtlInt16; #elif IGTL_SIZEOF_INT == 2 typedef unsigned int igtlUint16; typedef signed int igtlInt16; #else # error "No native data type can represent a 16-bit integer." #endif /* 32-bit integer type */ #if IGTL_SIZEOF_INT == 4 typedef unsigned int igtlUint32; typedef signed int igtlInt32; #elif IGTL_SIZEOF_LONG == 4 typedef unsigned long igtlUint32; typedef signed long igtlInt32; #else # error "No native data type can represent a 32-bit integer." #endif /* 64-bit integer type */ #if defined(IGTL_TYPE_USE_LONG_LONG) && IGTL_SIZEOF_LONG_LONG == 8 typedef unsigned long long igtlUint64; typedef signed long long igtlInt64; #elif IGTL_SIZEOF_INT == 8 typedef unsigned int igtlUint64; typedef signed int igtlInt64; #elif IGTL_SIZEOF_LONG == 8 typedef unsigned long igtlUint64; typedef signed long igtlInt64; #elif defined(IGTL_TYPE_USE___INT64) && IGTL_SIZEOF___INT64 == 8 typedef unsigned __int64 igtlUint64; typedef signed __int64 igtlInt64; #elif defined(IGTL_TYPE_USE_INT64_T) && IGTL_SIZEOF_INT64_T == 8 typedef unsigned int64_t igtlUint64; typedef signed int64_t igtlInt64; #else # error "No native data type can represent a 64-bit integer." #endif /* 32-bit floating point type */ #if IGTL_SIZEOF_FLOAT == 4 typedef float igtlFloat32; #else # error "No native data type can represent a 32-bit floating point value." #endif /* 64-bit floating point type */ #if IGTL_SIZEOF_DOUBLE == 8 typedef double igtlFloat64; #else # error "No native data type can represent a 64-bit floating point value." #endif /* 128-bit complex type */ typedef double igtlComplex[2]; #endif /* __igtlTypes_H */ openigtlink-3.0.0/Source/igtlUnit.cxx000066400000000000000000000041611501024245700176220ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlUnit.h" #include "igtl_unit.h" // Disable warning C4996 (strncpy() may be unsafe) in Windows. #define _CRT_SECURE_NO_WARNINGS namespace igtl { Unit::Unit(): Object() { Init(); } Unit::~Unit() { } void Unit::Init() { this->m_Prefix = SI_PREFIX_NONE; this->m_NUnits = 0; for (int i = 0; i < 6; i ++) { this->m_Unit[i] = SI_BASE_NONE; this->m_Exp[i] = 0; } } int Unit::SetPrefix(int prefix) { if (prefix >= SI_PREFIX_NONE && prefix <= SI_PREFIX_FEMTO) { this->m_Prefix = prefix; return 1; } else { return 0; } } int Unit::Append(int unit, int exp) { // Check number of units already appended if (this->m_NUnits >= 6) { return 0; } // Check range if (unit < SI_BASE_NONE || unit >= SI_NUM_UNIT_TYPES) { return 0; } if (exp < -7 || exp > 7) { return 0; } // Append this->m_Unit[this->m_NUnits] = (igtlUint8)unit; this->m_Exp[this->m_NUnits] = (igtlInt8)exp; this->m_NUnits++; return 1; } igtlUnit Unit::Pack() { igtl_unit_data data; igtl_unit_init(&data); data.prefix = this->m_Prefix; for (int i = 0; i < 6; i ++) { data.unit[i] = this->m_Unit[i]; data.exp[i] = this->m_Exp[i]; } return (igtlUnit) igtl_unit_pack(&data); } int Unit::Unpack(igtlUnit unit) { igtl_unit_data data; if (igtl_unit_unpack((igtl_unit)unit, &data) == 0) { return 0; } Init(); this->m_Prefix = data.prefix; for (int i = 0; i < 6; i ++) { this->m_Unit[i] = data.unit[i]; this->m_Exp[i] = data.exp[i]; } return 1; } } // namespace igtl openigtlink-3.0.0/Source/igtlUnit.h000066400000000000000000000122701501024245700172470ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlUnit_h #define __igtlUnit_h #include "igtlWin32Header.h" #include "igtlMacro.h" #include "igtlObject.h" #include "igtlObjectFactory.h" #include "igtlTypes.h" namespace igtl { typedef igtlUint64 igtlUnit; /// The Unit class provides a general way to describe unites defined in International System of Unites (SI) /// in its 8-byte (or 64-bit) field. The field is designed to specifiy a unit consisting of SI-prefix /// (e.g. milli, micro, kilo etc...) and combination of SI-base and/or SI-derived unites. /// The bites in the field are assigned as follows: /// /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... /// |PREFIX | UNIT0 | EXP0 | UNIT1 | EXP1 | UNIT2 | EXP2 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... /// 0 1 2 3 4 /// /// ...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /// EXP2 | UNIT3 | EXP3 | UNIT4 | EXP4 | UNIT5 | EXP5 | /// ...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /// 4 5 6 7 class IGTLCommon_EXPORT Unit : public Object { public: /// SI Prefix enum { SI_PREFIX_NONE = 0x0, /* None */ SI_PREFIX_DEKA = 0x1, /* deka (deca) (1e1) */ SI_PREFIX_HECTO = 0x2, /* hecto (1e2) */ SI_PREFIX_KILO = 0x3, /* kilo (1e3) */ SI_PREFIX_MEGA = 0x4, /* mega (1e6) */ SI_PREFIX_GIGA = 0x5, /* giga (1e9) */ SI_PREFIX_TERA = 0x6, /* tera (1e12) */ SI_PREFIX_PETA = 0x7, /* peta (1e15) */ SI_PREFIX_DECI = 0x9, /* deci (1e-1) */ SI_PREFIX_CENTI = 0xA, /* centi (1e-2) */ SI_PREFIX_MILLI = 0xB, /* milli (1e-3) */ SI_PREFIX_MICRO = 0xC, /* micro (1e-6) */ SI_PREFIX_NANO = 0xD, /* nano (1e-9) */ SI_PREFIX_PICO = 0xE, /* pico (1e-12) */ SI_PREFIX_FEMTO = 0xF, /* femto (1e-15) */ }; /// SI Units enum { // SI Base Units SI_BASE_NONE = 0x00, SI_BASE_METER = 0x01, /* meter */ SI_BASE_GRAM = 0x02, /* gram */ SI_BASE_SECOND = 0x03, /* second */ SI_BASE_AMPERE = 0x04, /* ampere */ SI_BASE_KELVIN = 0x05, /* kelvin */ SI_BASE_MOLE = 0x06, /* mole */ SI_BASE_CANDELA = 0x07, /* candela */ // SI Derived Units SI_DERIVED_RADIAN = 0x08, /* radian meter/meter */ SI_DERIVED_STERADIAN = 0x09, /* steradian meter^2/meter^2 */ SI_DERIVED_HERTZ = 0x0A, /* hertz /second */ SI_DERIVED_NEWTON = 0x0B, /* newton meter-kilogram/second^2 */ SI_DERIVED_PASCAL = 0x0C, /* pascal kilogram/meter-second^2 */ SI_DERIVED_JOULE = 0x0D, /* joule meter^2-kilogram/second^2 */ SI_DERIVED_WATT = 0x0E, /* watt meter^2-kilogram/second^3 */ SI_DERIVED_COULOMB = 0x0F, /* coulomb second-ampere */ SI_DERIVED_VOLT = 0x10, /* volt meter^2-kilogram/second^3-ampere */ SI_DERIVED_FARAD = 0x11, /* farad second^4-ampere^2/meter^2-kilogram */ SI_DERIVED_OHM = 0x12, /* ohm meter^2-kilogram/second^3-ampere^2 */ SI_DERIVED_SIEMENS = 0x13, /* siemens second^3-ampere^2/meter^2-kilogram */ SI_DERIVED_WEBER = 0x14, /* weber meter^2-kilogram/second^2-ampere */ SI_DERIVED_TESLA = 0x15, /* tesla kilogram/second^2-ampere */ SI_DERIVED_HENRY = 0x16, /* henry meter^2-kilogram/second^2-ampere^2 */ SI_DERIVED_LUMEN = 0x17, /* lumen candela-steradian */ SI_DERIVED_LUX = 0x18, /* lux candela-steradian/meter^2 */ SI_DERIVED_BECQUEREL = 0x19, /* becquerel /second */ SI_DERIVED_GRAY = 0x1A, /* gray meter^2/second^2 */ SI_DERIVED_SIEVERT = 0x1B, /* sievert meter^2/second^2 */ SI_NUM_UNIT_TYPES = 0x1C, }; public: typedef Unit Self; typedef Object Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; igtlTypeMacro(Unit, Object); igtlNewMacro(Self); /// Initializes the class. void Init(); /// Sets the SI prefix. int SetPrefix(int prefix); /// Appends a unit with exponential int Append(int unit, int exp); /// Packs (or serializes) the unit into a 64-bit value. igtlUnit Pack(); /// Unpacks the unit from a 64-bit value. int Unpack(igtlUnit unit); protected: /// constructor Unit(); /// destructor virtual ~Unit(); private: /// Prefix. igtlUint8 m_Prefix; /// Either SI-Base or SI-Derived. igtlUint8 m_Unit[6]; /// Must be within [-7, 7]. igtlInt8 m_Exp[6]; /// Number of units appended. igtlInt32 m_NUnits; }; } #endif // __igtlUnit_h openigtlink-3.0.0/Source/igtlWin32Header.h000066400000000000000000000133711501024245700203460ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkWin32Header.h,v $ Language: C++ Date: $Date: 2010-01-17 13:38:05 -0500 (Sun, 17 Jan 2010) $ Version: $Revision: 5577 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. Portions of this code are covered under the VTK copyright. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igtlWin32Header_h #define __igtlWin32Header_h #include "igtlConfigure.h" // add in the Windows variants #if defined(__CYGWIN__) #ifndef WIN32 #define WIN32 1 #endif #ifndef _WIN32 #define _WIN32 1 #endif #endif #if defined(_WIN32) // Include the windows header here only if requested by user code. # if defined(IGTL_INCLUDE_WINDOWS_H) # include // Define types from the windows header file. typedef DWORD igtlWindowsDWORD; typedef PVOID igtlWindowsPVOID; typedef LPVOID igtlWindowsLPVOID; typedef HANDLE igtlWindowsHANDLE; typedef LPTHREAD_START_ROUTINE igtlWindowsLPTHREAD_START_ROUTINE; # else // Define types from the windows header file. typedef unsigned long igtlWindowsDWORD; typedef void* igtlWindowsPVOID; typedef igtlWindowsPVOID igtlWindowsLPVOID; typedef igtlWindowsPVOID igtlWindowsHANDLE; typedef igtlWindowsDWORD (__stdcall *igtlWindowsLPTHREAD_START_ROUTINE)(igtlWindowsLPVOID); # endif #if ( _MSC_VER >= 1300 ) // Visual studio .NET #pragma warning ( disable : 4311 ) #pragma warning ( disable : 4312 ) # define igtlGetWindowLong GetWindowLongPtr # define igtlSetWindowLong SetWindowLongPtr # define igtlLONG LONG_PTR # define igtlGWL_WNDPROC GWLP_WNDPROC # define igtlGWL_HINSTANCE GWLP_HINSTANCE # define igtlGWL_USERDATA GWLP_USERDATA #else // older or non-Visual studio # define igtlGetWindowLong GetWindowLong # define igtlSetWindowLong SetWindowLong # define igtlLONG LONG # define igtlGWL_WNDPROC GWL_WNDPROC # define igtlGWL_HINSTANCE GWL_HINSTANCE # define igtlGWL_USERDATA GWL_USERDATA #endif // #endif #if defined(_MSC_VER) // Enable MSVC compiler warning messages that are useful but off by default. # pragma warning ( default : 4263 ) /* no override, call convention differs */ // Disable MSVC compiler warning messages that often occur in valid code. # if !defined(IGTL_DISPLAY_WIN32_WARNINGS) # pragma warning ( disable : 4003 ) /* not enough actual parameters for macro */ # pragma warning ( disable : 4097 ) /* typedef is synonym for class */ # pragma warning ( disable : 4127 ) /* conditional expression is constant */ # pragma warning ( disable : 4244 ) /* possible loss in conversion */ # pragma warning ( disable : 4251 ) /* missing DLL-interface */ # pragma warning ( disable : 4305 ) /* truncation from type1 to type2 */ # pragma warning ( disable : 4309 ) /* truncation of constant value */ # pragma warning ( disable : 4514 ) /* unreferenced inline function */ # pragma warning ( disable : 4706 ) /* assignment in conditional expression */ # pragma warning ( disable : 4710 ) /* function not inlined */ # pragma warning ( disable : 4786 ) /* identifier truncated in debug info */ # pragma warning ( disable : 4996 ) /* 'strncpy': This function or variable may be unsafe. */ # endif // typename keyword in default template arguments is not accepted by // MSVC. This macro should only be used in such places. # if !defined(CABLE_CONFIGURATION) && (_MSC_VER < 1310) # define IGTL_TYPENAME # else # define IGTL_TYPENAME typename # endif #else # define IGTL_TYPENAME typename #endif // MSVC 6.0 in release mode will warn about code it produces with its // optimizer. Disable the warnings specifically for this // configuration. Real warnings will be revealed by a debug build or // by other compilers. #if defined(_MSC_VER) && (_MSC_VER < 1300) && defined(NDEBUG) # pragma warning ( disable : 4701 ) /* Variable may be used uninitialized. */ # pragma warning ( disable : 4702 ) /* Unreachable code. */ #endif #if defined(__BORLANDC__) // Disable Borland compiler warning messages that often occur in valid code. # if !defined(IGTL_DISPLAY_WIN32_WARNINGS) # pragma warn -8004 /* assigned a value that is never used */ # pragma warn -8008 /* condition is always false */ # pragma warn -8026 /* funcs w/class-by-value args not expanded inline */ # pragma warn -8027 /* functions w/ do/for/while not expanded inline */ # pragma warn -8060 /* possibly incorrect assignment */ # pragma warn -8066 /* unreachable code */ # pragma warn -8072 /* suspicious pointer arithmetic */ # endif #endif // IGTL_EXPORT can not be used #define IGTL_EXPORT #if (defined(_WIN32) || defined(WIN32)) && !defined(IGTLSTATIC) # ifdef IGTLCommon_EXPORTS # define IGTLCommon_EXPORT __declspec(dllexport) # else # define IGTLCommon_EXPORT __declspec(dllimport) # endif /* IGTLCommon_EXPORT */ #else /* unix needs nothing */ #define IGTLCommon_EXPORT #endif #endif openigtlink-3.0.0/Source/igtlWindows.h000066400000000000000000000030771501024245700177670ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkWindows.h,v $ Language: C++ Date: $Date: 2008-12-22 19:05:42 -0500 (Mon, 22 Dec 2008) $ Version: $Revision: 3460 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /** This file is used to create the smallest windows.h possible. * Also it removes a few annoying #define's in windows.h. */ #ifndef __igtlWindows_h #define __igtlWindows_h #ifndef NOMINMAX #define NOMINMAX #endif #ifdef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN #endif #define WIN32_LEAN_AND_MEAN #include #include #endif openigtlink-3.0.0/Source/igtlutil/000077500000000000000000000000001501024245700171325ustar00rootroot00000000000000openigtlink-3.0.0/Source/igtlutil/CMakeLists.txt000066400000000000000000000041141501024245700216720ustar00rootroot00000000000000#SET(IGTL_UTIL_PROTOCOL_VERSION "1") #SET(IGTL_UTIL_PROTOCOL_VERSION ${OpenIGTLink_PROTOCOL_VERSION}) if(OpenIGTLink_BUILD_SHARED_LIBS) set(igtlutil_BUILD_SHARED_LIBS ${OpenIGTLink_BUILD_SHARED_LIBS}) endif(OpenIGTLink_BUILD_SHARED_LIBS) if(OpenIGTLink_BUILD_GENERATE_PIC) set(igtlutil_BUILD_GENERATE_PIC ${OpenIGTLink_BUILD_GENERATE_PIC}) set(IGTLSTATIC 1) endif(OpenIGTLink_BUILD_GENERATE_PIC) SET(igtlutil_HEADS igtl_header.h igtl_image.h igtl_position.h igtl_transform.h igtl_types.h igtl_util.h igtl_capability.h ) SET(igtlutil_SOURCES igtl_header.c igtl_image.c igtl_position.c igtl_transform.c igtl_util.c igtl_capability.c ) if (${OpenIGTLink_PROTOCOL_VERSION} GREATER "1") SET(igtlutil_HEADS ${igtlutil_HEADS} igtl_colortable.h igtl_imgmeta.h igtl_lbmeta.h igtl_point.h igtl_tdata.h igtl_qtdata.h igtl_trajectory.h igtl_unit.h igtl_sensor.h igtl_string.h igtl_ndarray.h igtl_bind.h igtl_qtrans.h igtl_polydata.h ) SET(igtlutil_SOURCES ${igtlutil_SOURCES} igtl_colortable.c igtl_imgmeta.c igtl_lbmeta.c igtl_point.c igtl_tdata.c igtl_qtdata.c igtl_trajectory.c igtl_unit.c igtl_sensor.c igtl_string.c igtl_ndarray.c igtl_bind.c igtl_qtrans.c igtl_polydata.c ) endif (${OpenIGTLink_PROTOCOL_VERSION} GREATER "1") if (${OpenIGTLink_PROTOCOL_VERSION} GREATER "2") SET(igtlutil_HEADS ${igtlutil_HEADS} igtl_command.h ) SET(igtlutil_SOURCES ${igtlutil_SOURCES} igtl_command.c ) endif (${OpenIGTLink_PROTOCOL_VERSION} GREATER "2") IF( MSVC OR ${CMAKE_GENERATOR} MATCHES "Xcode") ADD_LIBRARY(igtlutil ${igtlutil_SOURCES} ${igtlutil_HEADS} ) ELSE() ADD_LIBRARY(igtlutil ${igtlutil_SOURCES} ) ENDIF() IF(MSVC) target_compile_options(igtlutil PRIVATE /MP) ENDIF() SET_TARGET_PROPERTIES(igtlutil PROPERTIES VERSION ${OpenIGTLink_VERSION_MAJOR}.${OpenIGTLink_VERSION_MINOR}.${OpenIGTLink_VERSION_PATCH} SOVERSION ${OpenIGTLink_VERSION_MAJOR} ) #TARGET_LINK_LIBRARIES(igtlutil # ${LIBS} # ) openigtlink-3.0.0/Source/igtlutil/igtl_bind.c000066400000000000000000000367751501024245700212530ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_bind.h" #include "igtl_util.h" void igtl_export igtl_bind_init_info(igtl_bind_info * bind_info) { if (bind_info) { bind_info->ncmessages = 0; bind_info->child_info_array = NULL; bind_info->resol = 0; bind_info->request_all = 0; bind_info->status = 0; } } int igtl_export igtl_bind_alloc_info(igtl_bind_info * bind_info, igtl_uint16 ncmessages) { size_t size; if (bind_info == NULL) { return 0; } size = (size_t) ncmessages * sizeof(igtl_bind_child_info); bind_info->child_info_array = malloc(size); if (bind_info->child_info_array != NULL) { bind_info->ncmessages = ncmessages; memset(bind_info->child_info_array, 0, size); return 1; } else { bind_info->ncmessages = 0; return 0; } } int igtl_export igtl_bind_free_info(igtl_bind_info * bind_info) { if (bind_info == NULL) { return 0; } if (bind_info->ncmessages == 0 || bind_info->child_info_array == NULL) { bind_info->ncmessages = 0; return 1; } free(bind_info->child_info_array); return 1; } /* * Function to unpack BIND message */ int igtl_bind_unpack_normal(void * byte_array, igtl_bind_info * info) { igtl_uint16 i; igtl_uint16 ncmessages; igtl_uint16 nametable_size; size_t namelen; char * ptr; char * ptr2; igtl_uint64 tmp64; if (byte_array == NULL || info == NULL) { return 0; } /* Number of child messages */ ptr = (char *) byte_array; if (igtl_is_little_endian()) { ncmessages = BYTE_SWAP_INT16(*((igtl_uint16*)ptr)); } else { ncmessages = *((igtl_uint16*)ptr); } /* Allocate an array of bind_info, if neccessary */ if (ncmessages != info->ncmessages) { if (igtl_bind_alloc_info(info, ncmessages) == 0) { return 0; } } /* Pointer to the first element in the BIND header section */ ptr += sizeof(igtl_uint16); /* Extract types and body sizes from the BIND header section */ for (i = 0; i < ncmessages; i ++) { /* Type of child message */ strncpy(info->child_info_array[i].type, (char*)ptr, IGTL_HEADER_TYPE_SIZE); info->child_info_array[i].type[IGTL_HEADER_TYPE_SIZE] = '\0'; /* Body size of child message */ ptr += IGTL_HEADER_TYPE_SIZE; if (igtl_is_little_endian()) { memcpy(&tmp64, ptr, sizeof(igtl_uint64)); info->child_info_array[i].size = BYTE_SWAP_INT64(tmp64); } else { memcpy(&(info->child_info_array[i].size), ptr, sizeof(igtl_uint64)); } ptr += sizeof(igtl_uint64); } /* Name table size */ if (igtl_is_little_endian()) { nametable_size = BYTE_SWAP_INT16(*((igtl_uint16 *) ptr)); } else { nametable_size = *((igtl_uint16 *) ptr); } /* * Check if the name table field is aligned to WORD (The length of * the field must be even. */ if (nametable_size % 2 != 0) { return 0; } ptr += sizeof(igtl_uint16); ptr2 = ptr; /* Extract device names from the name table section */ if (nametable_size > 0) { for (i = 0; i < ncmessages; i ++) { strncpy(info->child_info_array[i].name, ptr, IGTL_HEADER_NAME_SIZE); info->child_info_array[i].name[IGTL_HEADER_NAME_SIZE] = '\0'; namelen = strlen(info->child_info_array[i].name); ptr += namelen + 1; } } ptr = ptr2 + nametable_size; /* Set pointers to the child message bodies */ for (i = 0; i < ncmessages; i ++) { info->child_info_array[i].ptr = ptr; /* Note: a padding byte is added, if the size of the child message body is odd. */ ptr += info->child_info_array[i].size + (info->child_info_array[i].size % 2); } /** TODO: check the total size of the message? **/ return 1; } /* * Function to unpack GET_BIND and STT_BIND messages */ int igtl_bind_unpack_request(void * byte_array, igtl_bind_info * info, igtl_uint64 size) { igtl_uint16 i; igtl_uint16 ncmessages; igtl_uint16 nametable_size; size_t namelen; char * ptr; char * ptr2; if (size == 0) { info->request_all = 1; return 1; } info->request_all = 0; if (byte_array == NULL || info == NULL) { return 0; } /* Number of child messages */ ptr = (char *) byte_array; if (igtl_is_little_endian()) { ncmessages = BYTE_SWAP_INT16(*((igtl_uint16*)ptr)); } else { ncmessages = *((igtl_uint16*)ptr); } /* Allocate an array of bind_info, if neccessary */ if (ncmessages != info->ncmessages) { if (igtl_bind_alloc_info(info, ncmessages) == 0) { return 0; } } /* Pointer to the first element in the BIND header section */ ptr += sizeof(igtl_uint16); /* Extract types and body sizes from the BIND header section */ for (i = 0; i < ncmessages; i ++) { /* Type of child message */ strncpy(info->child_info_array[i].type, (char*)ptr, IGTL_HEADER_TYPE_SIZE); info->child_info_array[i].type[IGTL_HEADER_TYPE_SIZE] = '\0'; ptr += IGTL_HEADER_TYPE_SIZE; } /* Name table size */ if (igtl_is_little_endian()) { nametable_size = BYTE_SWAP_INT16(*((igtl_uint16 *) ptr)); } else { nametable_size = *((igtl_uint16 *) ptr); } /* * Check if the name table field is aligned to WORD (The length of * the field must be even. */ if (nametable_size % 2 != 0) { return 0; } ptr += sizeof(igtl_uint16); ptr2 = ptr; /* Extract device names from the name table section */ if (nametable_size > 0) { for (i = 0; i < ncmessages; i ++) { strncpy(info->child_info_array[i].name, ptr, IGTL_HEADER_NAME_SIZE); info->child_info_array[i].name[IGTL_HEADER_NAME_SIZE] = '\0'; namelen = strlen(info->child_info_array[i].name); ptr += namelen + 1; } } /** TODO: check the total size of the message? **/ return 1; } int igtl_export igtl_bind_unpack(int type, void * byte_array, igtl_bind_info * info, igtl_uint64 size) { char * ptr; switch (type) { case IGTL_TYPE_PREFIX_NONE: return igtl_bind_unpack_normal(byte_array, info); break; case IGTL_TYPE_PREFIX_GET: return igtl_bind_unpack_request(byte_array, info, size); break; case IGTL_TYPE_PREFIX_STT: /* * STT_BIND message has the same format as GET_BIND, except that it * has the time resolution field. */ /* Obtain time resolution */ ptr = byte_array; if (igtl_is_little_endian()) { memcpy(&(info->resol), ptr, sizeof(igtl_uint64)); info->resol = BYTE_SWAP_INT64(info->resol); } else { memcpy(&(info->resol), ptr, sizeof(igtl_uint64)); } /* Unpack rest of the message */ ptr += sizeof(igtl_uint64); return igtl_bind_unpack_request(ptr, info, size-sizeof(igtl_uint64)); break; case IGTL_TYPE_PREFIX_STP: return 1; break; case IGTL_TYPE_PREFIX_RTS: info->status = * (igtl_uint8 *) byte_array; return 1; break; default: return 0; break; } } /* * Function to unpack BIND message */ int igtl_bind_pack_normal(igtl_bind_info * info, void * byte_array) { char * ptr; igtl_uint32 i; igtl_uint32 nc; igtl_uint16 * nts; size_t wb; size_t len; igtl_uint16 tmp16; igtl_uint64 tmp64; ptr = (char *) byte_array; nc = info->ncmessages; /* Validate info */ if (info->ncmessages == 0 || info->child_info_array == NULL) { return 0; } /* Number of child messages */ if (igtl_is_little_endian()) { /* *((igtl_uint16*) ptr) = BYTE_SWAP_INT16(info->ncmessages); */ tmp16 = BYTE_SWAP_INT16(info->ncmessages); memcpy(ptr, &tmp16, sizeof(igtl_uint16)); } else { /* *((igtl_uint16*) ptr) = info->ncmessages; */ memcpy(ptr, &(info->ncmessages), sizeof(igtl_uint16)); } ptr += sizeof(igtl_uint16); /* BIND header section */ for (i = 0; i < nc; i ++) { /* Fill with 0 */ memset(ptr, 0, IGTL_HEADER_TYPE_SIZE); strncpy((char*)ptr, info->child_info_array[i].type, IGTL_HEADER_TYPE_SIZE); ptr += IGTL_HEADER_TYPE_SIZE; /* 2011-04-29 * Since ptr is not alined to double-word order at this point, * "* ((igtl_uint64 *) ptr) = " may fail in some archtecture. * In the following section, memcpy() is called instaed of using * ((igtl_uint64 *) ptr) * expression. */ if (igtl_is_little_endian()) { tmp64 = BYTE_SWAP_INT64(info->child_info_array[i].size); memcpy(ptr, &tmp64, sizeof(igtl_uint64)); } else { memcpy(ptr, &(info->child_info_array[i].size), sizeof(igtl_uint64)); } ptr += sizeof(igtl_uint64); } /* Name table section */ nts = (igtl_uint16 *) ptr; /* save address for name table size field */ ptr += sizeof(igtl_uint16); wb = 0; for (i = 0; i < nc; i ++) { len = strlen(info->child_info_array[i].name); if (len > IGTL_HEADER_NAME_SIZE) { return 0; } /* copy string + NULL-terminator */ strncpy(ptr, info->child_info_array[i].name, len+1); ptr += (len + 1); wb += len + 1; } /* Add padding if the size of the name table section is not even */ if (wb % 2 > 0) { *((igtl_uint8*)ptr) = 0; ptr ++; wb ++; } /* Substitute name table size */ *nts = (igtl_uint16) wb; if (igtl_is_little_endian()) { *nts = BYTE_SWAP_INT16(*nts); } return 1; } /* * Function to unpack STT_BIND and GET_BIND messages */ int igtl_bind_pack_request(igtl_bind_info * info, void * byte_array) { char * ptr; igtl_uint32 i; igtl_uint32 nc; igtl_uint16 * nts; size_t wb; size_t len; igtl_uint16 tmp16; ptr = (char *) byte_array; nc = info->ncmessages; /* If requesting all available, no body is generated. */ if (info->request_all == 1) { return 1; } /* Validate info */ if (info->ncmessages == 0 || info->child_info_array == NULL) { return 0; } /* Number of child messages */ if (igtl_is_little_endian()) { /* *((igtl_uint16*) ptr) = BYTE_SWAP_INT16(info->ncmessages); */ tmp16 = BYTE_SWAP_INT16(info->ncmessages); memcpy(ptr, &tmp16, sizeof(igtl_uint16)); } else { /* *((igtl_uint16*) ptr) = info->ncmessages; */ memcpy(ptr, &(info->ncmessages), sizeof(igtl_uint16)); } ptr += sizeof(igtl_uint16); /* BIND header section */ for (i = 0; i < nc; i ++) { /*memset(ptr, 0, IGTL_HEADER_TYPE_SIZE); */ /* Fill with 0 */ strncpy((char*)ptr, info->child_info_array[i].type, IGTL_HEADER_TYPE_SIZE); ptr += IGTL_HEADER_TYPE_SIZE; } /* Name table section */ nts = (igtl_uint16 *) ptr; /* save address for name table size field */ ptr += sizeof(igtl_uint16); wb = 0; for (i = 0; i < nc; i ++) { len = strlen(info->child_info_array[i].name); if (len > IGTL_HEADER_NAME_SIZE) { return 0; } /* copy string + NULL-terminator */ strncpy(ptr, info->child_info_array[i].name, len+1); ptr += (len + 1); wb += len + 1; } /* Substitute name table size */ *nts = (igtl_uint16) wb; if (igtl_is_little_endian()) { *nts = BYTE_SWAP_INT16(*nts); } return 1; } int igtl_export igtl_bind_pack(igtl_bind_info * info, void * byte_array, int type) { char * ptr; igtl_uint64 tmp64; switch (type) { case IGTL_TYPE_PREFIX_NONE: return igtl_bind_pack_normal(info, byte_array); break; case IGTL_TYPE_PREFIX_GET: return igtl_bind_pack_request(info, byte_array); break; case IGTL_TYPE_PREFIX_STT: /* * STT_BIND message has the same format as GET_BIND, except that it * has the time resolution field. */ ptr = (char *) byte_array; /* Get time resolution */ if (igtl_is_little_endian()) { memcpy(&tmp64, ptr, sizeof(igtl_uint64)); info->resol = BYTE_SWAP_INT64(tmp64); } else { memcpy(&(info->resol), ptr, sizeof(igtl_uint64)); } ptr += sizeof(igtl_uint64); /* Generate rest of the message */ return igtl_bind_pack_request(info, ptr); break; case IGTL_TYPE_PREFIX_STP: return 1; break; case IGTL_TYPE_PREFIX_RTS: * (igtl_uint8 * ) byte_array = info->status; return 1; break; default: return 0; break; } } /* * Function to calculate size of BIND message header */ igtl_uint64 igtl_bind_get_size_normal(igtl_bind_info * info) { igtl_uint64 size; igtl_uint32 ntable_size; igtl_uint16 i; igtl_uint16 nc; nc = info->ncmessages; /* Size of NCMESSAGES section */ size = sizeof(igtl_uint16); /* Add size of BIND header section */ size += (IGTL_HEADER_TYPE_SIZE+sizeof(igtl_uint64)) * nc; /* Add size of table size field*/ size += sizeof(igtl_uint16); /* Calculate size of name table */ ntable_size = 0; for (i = 0; i < nc; i ++) { /* string length + NULL separator */ ntable_size += strlen(info->child_info_array[i].name) + 1; } if (ntable_size %2 > 0) { ntable_size += 1; } size += ntable_size; return size; } /* * Function to calculate size of GET_BIND/STT_BIND messages */ igtl_uint64 igtl_bind_get_size_request(igtl_bind_info * info) { igtl_uint64 size; igtl_uint32 ntable_size; igtl_uint16 i; igtl_uint16 nc; nc = info->ncmessages; /* Size of NCMESSAGES section */ size = sizeof(igtl_uint16); /* Add size of BIND header section */ size += (IGTL_HEADER_TYPE_SIZE+sizeof(igtl_uint64)) * nc; /* Add size of table size field*/ size += sizeof(igtl_uint16); /* Calculate size of name table */ ntable_size = 0; for (i = 0; i < nc; i ++) { /* string length + NULL separator */ ntable_size += strlen(info->child_info_array[i].name) + 1; } return size; } igtl_uint64 igtl_export igtl_bind_get_size(igtl_bind_info * info, int type) { switch (type) { case IGTL_TYPE_PREFIX_NONE: return igtl_bind_get_size_normal(info); break; case IGTL_TYPE_PREFIX_GET: return igtl_bind_get_size_request(info); break; case IGTL_TYPE_PREFIX_STT: /* * STT_BIND message has the same format as GET_BIND, except that it * has the time resolution field. */ return igtl_bind_get_size_request(info) + sizeof(igtl_uint64); break; case IGTL_TYPE_PREFIX_STP: return 0; break; case IGTL_TYPE_PREFIX_RTS: return sizeof(igtl_uint8); break; default: return 0; break; } } igtl_uint64 igtl_export igtl_bind_get_crc(igtl_bind_info * info, int type, void* bind_message) { igtl_uint64 crc; igtl_uint64 bind_length; igtl_uint16 i; igtl_uint16 nc; bind_length = (igtl_uint64)igtl_bind_get_size(info, type); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) bind_message, (int)bind_length, crc); if (type == IGTL_TYPE_PREFIX_NONE) { nc = info->ncmessages; for (i = 0; i < nc; i ++) { crc = crc64((unsigned char*) info->child_info_array[i].ptr, (int)info->child_info_array[i].size, crc); } } return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_bind.h000066400000000000000000000076041501024245700212450ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_BIND_H #define __IGTL_BIND_H #include "igtl_win32header.h" #include "igtl_header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_win32header.h" #ifdef __cplusplus extern "C" { #endif /** The igtl_bind_info structure holds information about a child message in an OpenIGTLink * BIND message. The structure is used for functions defined in igtl_bind.h */ typedef struct { char type[IGTL_HEADER_TYPE_SIZE+1]; /* Data type (OpenIGTLink Device Type string) */ char name[IGTL_HEADER_NAME_SIZE+1]; /* Device name */ igtl_uint64 size; /* Data size */ void* ptr; /* Pointer to the child message */ } igtl_bind_child_info; typedef struct { igtl_uint16 ncmessages; /* Number of child message */ igtl_bind_child_info * child_info_array; /* Array of igtl_bind_child_info */ igtl_uint64 resol; /* Time resolution (used for STT_BIND) */ igtl_uint8 request_all; /* Flag to request all available data (used for GET_BIND and STT_BIND) */ igtl_uint8 status; /* Status for RTS message */ } igtl_bind_info; /** Initializes igtl_bind_info */ void igtl_export igtl_bind_init_info(igtl_bind_info * bind_info); /** Allocates an array of igtl_bind_child_info in bind_info with length of 'ncmessages.' * Returns 1 if the array is successfully allocated/freed */ int igtl_export igtl_bind_alloc_info(igtl_bind_info * bind_info, igtl_uint16 ncmessages); /** Frees an array of igtl_bind_child_info in bind_info with length of 'ncmessages.' * Returns 1 if the array is successfully allocated/freed */ int igtl_export igtl_bind_free_info(igtl_bind_info * bind_info); /** Unpacks BIND message. Extracts information about child messages in a byte array of * BIND messages and store it in a igtl_bind_info structure. * 'type' argument specifies a message type prefix * (none, GET_, STT_, STP_ or RTS_) by IGTL_TYPE_PREFIX_* macro. * Returns 1 if success, otherwise 0. */ int igtl_export igtl_bind_unpack(int type, void * byte_array, igtl_bind_info * info, igtl_uint64 size); /** Packs BIND message. Converts an igtl_bind_info structure to a byte array. * 'byte_array' should be allocated prior to calling igtl_bind_pack() with memory size * calculated by igtl_bind_get_size(). 'type' argument specifies a message type prefix * (none, GET_, STT_, STP_ or RTS_) by IGTL_TYPE_PREFIX_* macro. * Returns 1 if success, otherwise 0. */ int igtl_export igtl_bind_pack(igtl_bind_info * info, void * byte_array, int type); /** igtl_bind_get_size() calculates the size of bind header, consisting of * BIND hearder section (including number of child messages) and * name table section based on a igtl_bind_header. * The size returned from this function does not include size of child message data. * 'type' argument specifies a message type prefix * (none, GET_, STT_, STP_ or RTS_) by IGTL_TYPE_PREFIX_* macro. */ igtl_uint64 igtl_export igtl_bind_get_size(igtl_bind_info * info, int type); /** Calculates CRC of BIND message. Note that 'info' is used only for * getting size of the message. */ igtl_uint64 igtl_export igtl_bind_get_crc(igtl_bind_info * info, int type, void* bind_message); #ifdef __cplusplus } #endif #endif /* __IGTL_BIND_H */ openigtlink-3.0.0/Source/igtlutil/igtl_capability.c000066400000000000000000000066451501024245700224510ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_capability.h" #include "igtl_util.h" #include "igtl_header.h" void igtl_export igtl_capability_init_info(igtl_capability_info * info) { if (info) { info->ntypes = 0; info->typenames = NULL; } } int igtl_export igtl_capability_alloc_info(igtl_capability_info * info, int ntypes) { unsigned int i; unsigned char * ptr; if (info == NULL) { return 0; } info->ntypes = ntypes; info->typenames = malloc(sizeof(unsigned char*) * info->ntypes); if (info->typenames == NULL) { /* failed to allocate memory */ return 0; } ptr = malloc(sizeof(unsigned char) * (IGTL_HEADER_TYPE_SIZE+1) * info->ntypes); if (ptr == NULL) { free(info->typenames); info->ntypes = 0; return 0; } for (i = 0; i < info->ntypes; i ++) { info->typenames[i] = ptr; ptr += sizeof(unsigned char) * (IGTL_HEADER_TYPE_SIZE+1); } return 1; } int igtl_export igtl_capability_free_info(igtl_capability_info * info) { if (info == NULL) { return 0; } if (info->typenames == NULL) { return 0; } free(info->typenames[0]); free(info->typenames); info->ntypes = 0; return 1; } igtl_uint32 igtl_export igtl_capability_get_length(igtl_capability_info * info) { if (info == NULL) { return 0; } return (info->ntypes * IGTL_HEADER_TYPE_SIZE); } int igtl_export igtl_capability_unpack(void * byte_array, igtl_capability_info * info, igtl_uint64 pack_size) { int ntypes; int i; unsigned char * ptr; if (pack_size % IGTL_HEADER_TYPE_SIZE > 0) { /* In valid body size */ return 0; } if (info == NULL) { return 0; } ntypes = (int)((int)pack_size / IGTL_HEADER_TYPE_SIZE); /* Adjust the size of info->typenames */ if (info->ntypes != ntypes) { igtl_capability_free_info(info); igtl_capability_alloc_info(info, ntypes); } ptr = byte_array; for (i = 0; i < ntypes; i ++) { strncpy((char*)info->typenames[i], (char*)ptr, IGTL_HEADER_TYPE_SIZE); info->typenames[i][IGTL_HEADER_TYPE_SIZE] = '\0'; ptr += IGTL_HEADER_TYPE_SIZE; } return 1; } int igtl_export igtl_capability_pack(igtl_capability_info * info, void * byte_array) { unsigned int i; unsigned char * ptr; if (info == NULL) { return 0; } if (byte_array == NULL) { return 0; } ptr = byte_array; for (i = 0; i < info->ntypes; i ++) { strncpy((char*)ptr, (char*)info->typenames[i], IGTL_HEADER_TYPE_SIZE); ptr += IGTL_HEADER_TYPE_SIZE; } return 1; } igtl_uint64 igtl_export igtl_capability_get_crc(igtl_capability_info * info, void* capability) { igtl_uint64 crc; igtl_uint64 message_length; message_length = (igtl_uint32)igtl_capability_get_length(info); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) capability, (int)message_length, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_capability.h000066400000000000000000000051631501024245700224500ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_CAPABILITY_H #define __IGTL_CAPABILITY_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_win32header.h" #define IGTL_CAPABILITY_HEADER_SIZE 4 #ifdef __cplusplus extern "C" { #endif typedef struct { igtl_uint32 ntypes; unsigned char ** typenames; } igtl_capability_info; /** Initializes igtl_ndarray_info */ void igtl_export igtl_capability_init_info(igtl_capability_info * info); /** Allocates ndarray info. Allocate size array and ND-array pointed from igtl_ndarray_info. * 'type' and 'dim' in igtl_ndarray_info must be specified before * calling igtl_ndarray_alloc_info(). */ int igtl_export igtl_capability_alloc_info(igtl_capability_info * info, int ntypes); /** Frees ndarray info. */ int igtl_export igtl_capability_free_info(igtl_capability_info * info); /** Calculates capability data size of the pixel array, which will be * transferred with the specified header. */ igtl_uint32 igtl_export igtl_capability_get_length(igtl_capability_info * info); /** Unpacks CAPABILITY message. Extracts information in a byte array of CAPABILITY * messages and store it in a igtl_capability_info structure. 'type' argument specifies * a message type prefix (none, GET_, STT_, STP_ or RTS_) by IGTL_TYPE_PREFIX_* macro. * Returns 1 if success, otherwise 0. */ int igtl_export igtl_capability_unpack(void * byte_array, igtl_capability_info * info, igtl_uint64 pack_size); /** Packs CAPABILITY message. Converts an igtl_capability_info structure to a byte array. * 'byte_array' should be allocated prior to calling igtl_capability_pack() with memory size * calculated by igtl_capability_get_size(). 'type' argument specifies a message type prefix * (none, or GET_) by IGTL_TYPE_PREFIX_* macro. Returns 1 if success, otherwise 0. */ int igtl_export igtl_capability_pack(igtl_capability_info * info, void * byte_array); /** Calculates CRC of image data body including header * and array of pixel data. */ igtl_uint64 igtl_export igtl_capability_get_crc(igtl_capability_info* info, void* capability); #ifdef __cplusplus } #endif #endif /* __IGTL_CAPABILITY_H */ openigtlink-3.0.0/Source/igtlutil/igtl_colortable.c000066400000000000000000000041521501024245700224450ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_util.h" #include "igtl_colortable.h" igtl_uint64 igtl_export igtl_colortable_get_table_size(igtl_colortable_header* header) { igtl_int32 n; igtl_int32 s; if (header->indexType == IGTL_COLORTABLE_INDEX_UINT8) { n = 256; } else /* IGTL_COLORTABLE_INDEX_UINT64 */ { n = 256*256; } if (header->mapType == IGTL_COLORTABLE_MAP_UINT8) { s = 1; } else if (header->mapType == IGTL_COLORTABLE_MAP_UINT16) { s = 2; } else /* IGTL_COLORTABLE_MAP_RGB */ { s = 3; } return (igtl_uint64) n*s; } void igtl_export igtl_colortable_convert_byte_order(igtl_colortable_header* header, void* table) { int i; int n; igtl_uint16* tmp; if (igtl_is_little_endian()) { if (header->mapType == IGTL_COLORTABLE_MAP_UINT16) { n = (header->indexType == IGTL_COLORTABLE_INDEX_UINT16)? 256*256 : 256; tmp = (igtl_uint16*) table; for (i = 0; i < n; i ++) { tmp[i] = BYTE_SWAP_INT16(tmp[i]); } } } } igtl_uint64 igtl_export igtl_colortable_get_crc(igtl_colortable_header* header, void* table) { igtl_uint64 crc; igtl_uint64 data_size; /* calculate header size using igtl_colortable_get_table_size(). * This funciton can be called after byte order conversion, since * both index and map type field are uint8 and not affected by byte conversion. */ data_size = igtl_colortable_get_table_size(header); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) header, IGTL_COLORTABLE_HEADER_SIZE, crc); crc = crc64((unsigned char*) table, (int)data_size, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_colortable.h000066400000000000000000000042611501024245700224530ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_COLORTABLE_H #define __IGTL_COLORTABLE_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #define IGTL_COLORTABLE_HEADER_SIZE 2 #define IGTL_COLORTABLE_INDEX_UINT8 3 #define IGTL_COLORTABLE_INDEX_UINT16 5 #define IGTL_COLORTABLE_MAP_UINT8 3 #define IGTL_COLORTABLE_MAP_UINT16 5 #define IGTL_COLORTABLE_MAP_RGB 19 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Status data header for OpenIGTLinik protocol */ typedef struct { igtl_int8 indexType; /* Index Type: 3:uint8 5:uint16 */ igtl_int8 mapType; /* 3: uint8 5:uint16 19:RGB color */ } igtl_colortable_header; #pragma pack() /** igtl_colortable_get_data_size(n) calculates the size of body based on the index * and map types. The size of body is used in the message header. * igtl_colortable_get_data_n(size) calculates the number of images in the body, based on * the body size. This function may be used when a client program parses a COLORTABLE message. */ igtl_uint64 igtl_export igtl_colortable_get_table_size(igtl_colortable_header* header); /** Converts endianness of each element in an array of * igtl_igtl_colortable_header and color table from host byte order to network byte order, * or vice versa (if necessary). The function automatically determins the endian type of the host. */ void igtl_export igtl_colortable_convert_byte_order(igtl_colortable_header* header, void* table); /** Calculates CRC of color table message */ igtl_uint64 igtl_export igtl_colortable_get_crc(igtl_colortable_header* header, void* table); #ifdef __cplusplus } #endif #endif /* __IGTL_COLORTABLE_H */ openigtlink-3.0.0/Source/igtlutil/igtl_command.c000066400000000000000000000026101501024245700217320ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_command.h" #include "igtl_util.h" void igtl_export igtl_command_convert_byte_order(igtl_command_header* header) { if (igtl_is_little_endian()) { header->commandId = BYTE_SWAP_INT32(header->commandId); header->encoding = BYTE_SWAP_INT16(header->encoding); header->length = BYTE_SWAP_INT32(header->length); } } igtl_uint64 igtl_export igtl_command_get_crc(igtl_command_header * header, void* command) { igtl_uint64 crc; igtl_uint32 command_length; /* convert byte order to get command length */ igtl_command_convert_byte_order(header); command_length = (igtl_uint32)(header->length); igtl_command_convert_byte_order(header); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) header, IGTL_COMMAND_HEADER_SIZE, crc); crc = crc64((unsigned char*) command, command_length, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_command.h000066400000000000000000000035231501024245700217430ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_COMMAND_H #define __IGTL_COMMAND_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_win32header.h" #define IGTL_COMMAND_HEADER_SIZE 138 #define IGTL_COMMAND_NAME_SIZE 128 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memory */ typedef struct { igtl_uint32 commandId; /* The unique ID of this command */ igtl_uint8 commandName[IGTL_COMMAND_NAME_SIZE]; /* The name of this command */ igtl_uint16 encoding; /* Character encoding type as MIBenum value (defined by IANA). Default=3 */ /* Please refer http://www.iana.org/assignments/character-sets for detail */ igtl_uint32 length; /* Length of command */ } igtl_command_header; #pragma pack() /** Converts endian-ness from host byte order to network byte order, * or vice versa. NOTE: It is developer's responsibility to have the command body with BOM * (byte order mark) or in big endian order. */ void igtl_export igtl_command_convert_byte_order(igtl_command_header * header); /** Calculates CRC of image data body including header * and array of pixel data. */ igtl_uint64 igtl_export igtl_command_get_crc(igtl_command_header * header, void* command); #ifdef __cplusplus } #endif #endif /* __IGTL_COMMAND_H */openigtlink-3.0.0/Source/igtlutil/igtl_header.c000066400000000000000000000027451501024245700215550ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_util.h" #include "igtl_header.h" void igtl_export igtl_header_convert_byte_order(igtl_header * header) { if (igtl_is_little_endian()) { header->header_version = BYTE_SWAP_INT16(header->header_version); header->timestamp = BYTE_SWAP_INT64(header->timestamp); header->body_size = BYTE_SWAP_INT64(header->body_size); header->crc = BYTE_SWAP_INT64(header->crc); } } #if OpenIGTLink_HEADER_VERSION >= 2 void igtl_export igtl_extended_header_convert_byte_order(igtl_extended_header * extended_header) { if (igtl_is_little_endian()) { extended_header->extended_header_size = BYTE_SWAP_INT16(extended_header->extended_header_size); extended_header->meta_data_header_size = BYTE_SWAP_INT16(extended_header->meta_data_header_size); extended_header->meta_data_size = BYTE_SWAP_INT32(extended_header->meta_data_size); extended_header->message_id = BYTE_SWAP_INT32(extended_header->message_id); } } #endif openigtlink-3.0.0/Source/igtlutil/igtl_header.h000066400000000000000000000067641501024245700215670ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_HEADER_H #define __IGTL_HEADER_H #define IGTL_HEADER_VERSION_1 1 #define IGTL_HEADER_VERSION_2 2 #define IGTL_HEADER_SIZE 58 #define IGTL_HEADER_TYPE_SIZE 12 #define IGTL_HEADER_NAME_SIZE 20 /* Following macros will be obsolete. Included for old programs*/ #define IGTL_HEADER_TYPESIZE IGTL_HEADER_TYPE_SIZE #define IGTL_HEADER_NAMESIZE IGTL_HEADER_NAME_SIZE #define IGTL_HEADER_DEVSIZE IGTL_HEADER_NAME_SIZE /* Device name prefix macro */ #define IGTL_TYPE_PREFIX_NONE 0 #define IGTL_TYPE_PREFIX_GET 1 #define IGTL_TYPE_PREFIX_STT 2 #define IGTL_TYPE_PREFIX_STP 3 #define IGTL_TYPE_PREFIX_RTS 4 #define IGTL_NUM_TYPE_PREFIX 5 #include "igtl_types.h" #include "igtl_win32header.h" #include "igtlConfigure.h" #ifdef __cplusplus extern "C" { #endif #pragma pack(2) /* For 2-byte boundary in memory */ /** Message header of OpenIGTLink message. * igtl_header is an overall data header for OpenIGTLink protocol. * It is transfered at beginning of every OpenIGTLink message to give * type and size of following data body to a receiver. * These parameters allow the receiver to parse or skip the data body. */ typedef struct { igtl_uint16 header_version; /* header version number */ char name[IGTL_HEADER_TYPE_SIZE]; /* data type name */ char device_name[IGTL_HEADER_NAME_SIZE]; /* device name */ igtl_uint64 timestamp; /* time stamp message */ igtl_uint64 body_size; /* size of the body */ igtl_uint64 crc; /* CRC */ } igtl_header; #if OpenIGTLink_HEADER_VERSION >= 2 /** Message extended header of OpenIGTLink message. * igtl_extended_header is an overall data extended header for OpenIGTLink protocol. * It is transfered with the data body to define the * size of extended header and the meta data size */ typedef struct { igtl_uint16 extended_header_size; /* size of extended header */ igtl_uint16 meta_data_header_size; /* size of the meta data header*/ igtl_uint32 meta_data_size; /* size of meta data */ igtl_uint32 message_id; /* message id */ } igtl_extended_header; typedef struct { igtl_uint16 key_size; igtl_uint16 value_encoding; igtl_uint32 value_size; } igtl_metadata_header_entry; #endif #pragma pack() /** igtl_header_convert_byte_order() convers endianness of each * member variable in igtl_header structure from host byte order * to network byte order, or vice versa. */ void igtl_export igtl_header_convert_byte_order(igtl_header * header); #if OpenIGTLink_HEADER_VERSION >= 2 /** igtl_extended_header_convert_byte_order() convers endianness of each * member variable in igtl_header structure from host byte order * to network byte order, or vice versa. */ void igtl_export igtl_extended_header_convert_byte_order(igtl_extended_header * extended_header); #endif #ifdef __cplusplus } #endif #endif /* __IGTL_HEADER_H */ openigtlink-3.0.0/Source/igtlutil/igtl_image.c000066400000000000000000000160731501024245700214060ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_image.h" #include "igtl_util.h" igtl_uint64 igtl_export igtl_image_get_data_size(igtl_image_header * header) { igtl_uint64 si; igtl_uint64 sj; igtl_uint64 sk; igtl_uint64 sp; igtl_uint64 data_size; si = header->subvol_size[0]; sj = header->subvol_size[1]; sk = header->subvol_size[2]; switch (header->scalar_type) { case IGTL_IMAGE_STYPE_TYPE_INT8: case IGTL_IMAGE_STYPE_TYPE_UINT8: sp = 1; break; case IGTL_IMAGE_STYPE_TYPE_INT16: case IGTL_IMAGE_STYPE_TYPE_UINT16: sp = 2; break; case IGTL_IMAGE_STYPE_TYPE_INT32: case IGTL_IMAGE_STYPE_TYPE_UINT32: sp = 4; break; default: sp = 0; break; } data_size = si*sj*sk*sp; return data_size; } void igtl_export igtl_image_set_matrix(float spacing[3], float origin[3], float norm_i[3], float norm_j[3], float norm_k[3], igtl_image_header * header) { header->matrix[0] = (igtl_float32) (norm_i[0] * spacing[0]); header->matrix[1] = (igtl_float32) (norm_i[1] * spacing[0]); header->matrix[2] = (igtl_float32) (norm_i[2] * spacing[0]); header->matrix[3] = (igtl_float32) (norm_j[0] * spacing[1]); header->matrix[4] = (igtl_float32) (norm_j[1] * spacing[1]); header->matrix[5] = (igtl_float32) (norm_j[2] * spacing[1]); header->matrix[6] = (igtl_float32) (norm_k[0] * spacing[2]); header->matrix[7] = (igtl_float32) (norm_k[1] * spacing[2]); header->matrix[8] = (igtl_float32) (norm_k[2] * spacing[2]); header->matrix[9] = (igtl_float32) (origin[0]); header->matrix[10] = (igtl_float32) (origin[1]); header->matrix[11] = (igtl_float32) (origin[2]); } void igtl_export igtl_image_set_matrix_4x4(float _matrix [4][4], igtl_image_header * header) { header->matrix[0] = _matrix[0][0]; header->matrix[1] = _matrix[0][1]; header->matrix[2] = _matrix[0][2]; header->matrix[3] = _matrix[1][0]; header->matrix[4] = _matrix[1][1]; header->matrix[5] = _matrix[1][2]; header->matrix[6] = _matrix[2][0]; header->matrix[7] = _matrix[2][1]; header->matrix[8] = _matrix[2][2]; header->matrix[9] = _matrix[0][3]; header->matrix[10] = _matrix[1][3]; header->matrix[11] = _matrix[2][3]; } void igtl_export igtl_image_get_matrix(float spacing[3], float origin[3], float norm_i[3], float norm_j[3], float norm_k[3], igtl_image_header * header) { float tx; float ty; float tz; float sx; float sy; float sz; float nx; float ny; float nz; float px; float py; float pz; tx = (float) header->matrix[0]; ty = (float) header->matrix[1]; tz = (float) header->matrix[2]; sx = (float) header->matrix[3]; sy = (float) header->matrix[4]; sz = (float) header->matrix[5]; nx = (float) header->matrix[6]; ny = (float) header->matrix[7]; nz = (float) header->matrix[8]; px = (float) header->matrix[9]; py = (float) header->matrix[10]; pz = (float) header->matrix[11]; spacing[0] = sqrtf(tx*tx + ty*ty + tz*tz); spacing[1] = sqrtf(sx*sx + sy*sy + sz*sz); spacing[2] = sqrtf(nx*nx + ny*ny + nz*nz); if (spacing[0] != 0) { norm_i[0] = header->matrix[0] / spacing[0]; norm_i[1] = header->matrix[1] / spacing[0]; norm_i[2] = header->matrix[2] / spacing[0]; } if (spacing[1] != 0) { norm_j[0] = header->matrix[3] / spacing[1]; norm_j[1] = header->matrix[4] / spacing[1]; norm_j[2] = header->matrix[5] / spacing[1]; } if (spacing[2] != 0) { norm_k[0] = header->matrix[6] / spacing[2]; norm_k[1] = header->matrix[7] / spacing[2]; norm_k[2] = header->matrix[8] / spacing[2]; } origin[0] = header->matrix[9]; origin[1] = header->matrix[10]; origin[2] = header->matrix[11]; } void igtl_export igtl_image_get_matrix_4x4(float _matrix[4][4], igtl_image_header * header) { _matrix[0][0] = header->matrix[0]; _matrix[0][1] = header->matrix[1]; _matrix[0][2] = header->matrix[2]; _matrix[1][0] = header->matrix[3]; _matrix[1][1] = header->matrix[4]; _matrix[1][2] = header->matrix[5]; _matrix[2][0] = header->matrix[6]; _matrix[2][1] = header->matrix[7]; _matrix[2][2] = header->matrix[8]; _matrix[0][3] = header->matrix[9]; _matrix[1][3] = header->matrix[10]; _matrix[2][3] = header->matrix[11]; _matrix[3][0] = 0; _matrix[3][1] = 0; _matrix[3][2] = 0; _matrix[3][3] = 1; } void igtl_export igtl_image_convert_byte_order(igtl_image_header * header) { int i; igtl_uint32 tmp[12]; if (igtl_is_little_endian()) { header->header_version = BYTE_SWAP_INT16(header->header_version); for (i = 0; i < 3; i ++) { header->size[i] = BYTE_SWAP_INT16(header->size[i]); header->subvol_size[i] = BYTE_SWAP_INT16(header->subvol_size[i]); header->subvol_offset[i] = BYTE_SWAP_INT16(header->subvol_offset[i]); } memcpy(tmp, header->matrix, sizeof(igtl_uint32)*12); /* * TODO: The following loop may cause segmentation fault, when it is compiled * with '-ftree-vectorize' optimization option on 64-bit Linux. * ('-ftree-vectorize' becomes active, when '-O3' optimization is specified.) * -- code has been updated on June 24 -- needs test */ for (i = 0; i < 12; i ++) { tmp[i] = BYTE_SWAP_INT32(tmp[i]); } memcpy(header->matrix, tmp, sizeof(igtl_uint32)*12); } } igtl_uint64 igtl_export igtl_image_get_crc(igtl_image_header * header, void* image) { igtl_uint64 crc; igtl_uint64 img_size; /* calculate image size (we do not call igtl_image_get_data_size() * because header has already been serialized. */ igtl_uint64 si; igtl_uint64 sj; igtl_uint64 sk; igtl_uint64 sp; if (igtl_is_little_endian()) { si = BYTE_SWAP_INT16(header->subvol_size[0]); sj = BYTE_SWAP_INT16(header->subvol_size[1]); sk = BYTE_SWAP_INT16(header->subvol_size[2]); } else { si = header->subvol_size[0]; sj = header->subvol_size[1]; sk = header->subvol_size[2]; } switch (header->scalar_type) { case IGTL_IMAGE_STYPE_TYPE_INT8: case IGTL_IMAGE_STYPE_TYPE_UINT8: sp = 1; break; case IGTL_IMAGE_STYPE_TYPE_INT16: case IGTL_IMAGE_STYPE_TYPE_UINT16: sp = 2; break; case IGTL_IMAGE_STYPE_TYPE_INT32: case IGTL_IMAGE_STYPE_TYPE_UINT32: sp = 4; break; default: sp = 0; break; } img_size = si*sj*sk*sp; crc = crc64(0, 0, 0); crc = crc64((unsigned char*) header, IGTL_IMAGE_HEADER_SIZE, crc); crc = crc64((unsigned char*) image, (int)img_size, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_image.h000066400000000000000000000115341501024245700214100ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_IMAGE_H #define __IGTL_IMAGE_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_win32header.h" #define IGTL_IMAGE_HEADER_VERSION 1 #define IGTL_IMAGE_HEADER_SIZE 72 /* Data type */ #define IGTL_IMAGE_DTYPE_SCALAR 1 #define IGTL_IMAGE_DTYPE_VECTOR 3 /* Scalar type */ #define IGTL_IMAGE_STYPE_TYPE_INT8 2 #define IGTL_IMAGE_STYPE_TYPE_UINT8 3 #define IGTL_IMAGE_STYPE_TYPE_INT16 4 #define IGTL_IMAGE_STYPE_TYPE_UINT16 5 #define IGTL_IMAGE_STYPE_TYPE_INT32 6 #define IGTL_IMAGE_STYPE_TYPE_UINT32 7 #define IGTL_IMAGE_STYPE_TYPE_FLOAT32 10 #define IGTL_IMAGE_STYPE_TYPE_FLOAT64 11 /* Endian */ #define IGTL_IMAGE_ENDIAN_BIG 1 #define IGTL_IMAGE_ENDIAN_LITTLE 2 /* Image coordinate system */ #define IGTL_IMAGE_COORD_RAS 1 #define IGTL_IMAGE_COORD_LPS 2 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Image data consists of image data header, which is defined in this * structure, folowed by array of image pixel data. * igtl_image_header helps a receiver to load array of image pixel data. * The header supports "partial volume update", where a fraction of volume * image is transferred from a sender to receiver. This fraction called * "sub-volume" in this protocol, and its size and starting index is * specified in 'subvol_size' and 'subvol_offset'. * In case of transferring entire image in one message, 'size' and * 'subvol_size' should be same, and 'subvol_offset' equals (0, 0, 0). */ typedef struct { igtl_uint16 header_version; /* data format version number(1) */ igtl_uint8 num_components; /* number of components per element*/ igtl_uint8 scalar_type; /* scalar type */ /*2:int8 3:uint8 4:int16 5:uint16 6:int32 7:uint32 10:float32 11:float64) */ igtl_uint8 endian; /* endian type of image data */ /* (1:big, 2:little) */ igtl_uint8 coord; /* coordinate system (1:RAS 2:LPS) */ igtl_uint16 size[3]; /* entire image volume size */ igtl_float32 matrix[12]; /* orientation / origin of image */ /* - matrix[0-2]: norm_i * pix_i */ /* - matrix[3-5]: norm_j * pix_j */ /* - matrix[6-8]: norm_k * pix_k */ /* - matrix[9-11]:origin */ /* where norm_* are normal vectors */ /* along each index, and pix_* are */ /* pixel size in each direction */ igtl_uint16 subvol_offset[3]; /* sub volume offset */ igtl_uint16 subvol_size[3]; /* sub volume size */ } igtl_image_header; #pragma pack() /** Calculates size of the pixel array, which will be transferred with the specified header. */ igtl_uint64 igtl_export igtl_image_get_data_size(igtl_image_header * header); /** Generates image orientation/origin matrix from spacing, origin and normal vectors. */ void igtl_export igtl_image_set_matrix(float spacing[3], float origin[3], float norm_i[3], float norm_j[3], float norm_k[3], igtl_image_header * header); void igtl_export igtl_image_get_matrix(float spacing[3], float origin[3], float norm_i[3], float norm_j[3], float norm_k[3], igtl_image_header * header); /** Sets the image orientation/origin matrix in 4x4 format */ void igtl_export igtl_image_set_matrix_4x4(float _matrix[4][4],igtl_image_header * header); /** Gets the image orientation/origin matrix in 4x4 format */ void igtl_export igtl_image_get_matrix_4x4(float _matrix[4][4],igtl_image_header * header); /** Converts endianness of each member variable in igtl_image_header from host * byte order to network byte order, or vice versa. */ void igtl_export igtl_image_convert_byte_order(igtl_image_header * header); /** Calculates CRC of image data body including header and array of pixel data. */ igtl_uint64 igtl_export igtl_image_get_crc(igtl_image_header * header, void* image); #ifdef __cplusplus } #endif #endif /* __IGTL_IMAGE_H */ openigtlink-3.0.0/Source/igtlutil/igtl_imgmeta.c000066400000000000000000000026141501024245700217430ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_imgmeta.h" #include "igtl_util.h" void igtl_export igtl_imgmeta_convert_byte_order(igtl_imgmeta_element* metalist, int nitem) { igtl_imgmeta_element* elem; int i; for (i = 0; i < nitem; i ++) { elem = &(metalist[i]); if (igtl_is_little_endian()) { elem->timestamp = BYTE_SWAP_INT64(elem->timestamp); elem->size[0] = BYTE_SWAP_INT16(elem->size[0]); elem->size[1] = BYTE_SWAP_INT16(elem->size[1]); elem->size[2] = BYTE_SWAP_INT16(elem->size[2]); } } } igtl_uint64 igtl_export igtl_imgmeta_get_crc(igtl_imgmeta_element* metalist, int nitem) { igtl_imgmeta_element* elem; int i; igtl_uint64 crc; crc = crc64(0, 0, 0); for (i = 0; i < nitem; i ++) { elem = &(metalist[i]); crc = crc64((unsigned char*) elem, IGTL_IMGMETA_ELEMENT_SIZE, crc); } return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_imgmeta.h000066400000000000000000000064721501024245700217560ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_IMGMETA_H #define __IGTL_IMGMETA_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_image.h" #define IGTL_IMGMETA_ELEMENT_SIZE 260 /* Scalar type */ /* Use the same numbers as IMAGE */ /* #define IGTL_IMGMETA_STYPE_TYPE_INT8 2 #define IGTL_IMGMETA_STYPE_TYPE_UINT8 3 #define IGTL_IMGMETA_STYPE_TYPE_INT16 4 #define IGTL_IMGMETA_STYPE_TYPE_UINT16 5 #define IGTL_IMGMETA_STYPE_TYPE_INT32 6 #define IGTL_IMGMETA_STYPE_TYPE_UINT32 7 #define IGTL_IMGMETA_STYPE_TYPE_FLOAT32 10 #define IGTL_IMGMETA_STYPE_TYPE_FLOAT64 11 */ #define IGTL_IMGMETA_LEN_NAME 64 #define IGTL_IMGMETA_LEN_DEVICE_NAME 20 #define IGTL_IMGMETA_LEN_MODALITY 32 #define IGTL_IMGMETA_LEN_PATIENT_NAME 64 #define IGTL_IMGMETA_LEN_PATIENT_ID 64 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** IMAGEMETA is a message type to transfer a list of images available in a server. * A IMGMETA message may contain information of multiple images. * The client determins the number of image meta by the size of the body included * in the message header (see igtl_imgmeta_getdata_n() macro). */ typedef struct { char name[IGTL_IMGMETA_LEN_NAME]; /* name / description */ char device_name[IGTL_IMGMETA_LEN_DEVICE_NAME]; /* device name to query the IMAGE and COLORT */ char modality[IGTL_IMGMETA_LEN_MODALITY]; /* modality name */ char patient_name[IGTL_IMGMETA_LEN_PATIENT_NAME]; /* patient name */ char patient_id[IGTL_IMGMETA_LEN_PATIENT_ID]; /* patient ID (MRN etc.) */ igtl_uint64 timestamp; /* scan time */ igtl_uint16 size[3]; /* entire image volume size */ igtl_uint8 scalar_type; /* scalar type. see scalar_type in IMAGE message */ igtl_uint8 reserved; } igtl_imgmeta_element; #pragma pack() /** igtl_imgmeta_get_data_size(n) macro calculates the size of body based on the number * of images.The size of body is used in the message header. * igtl_imgmeta_get_data_n(size) calculates the number of images in the body, based on * the body size. This function may be used when a client program parses IMGMETA message. */ #define igtl_imgmeta_get_data_size(n) ((n) * IGTL_IMGMETA_ELEMENT_SIZE) #define igtl_imgmeta_get_data_n(size) ((size) / IGTL_IMGMETA_ELEMENT_SIZE) /** Converts endianness of each member variable in igtl_imgmeta_element from host * byte order to network byte order, or vice versa. */ void igtl_export igtl_imgmeta_convert_byte_order(igtl_imgmeta_element* metalist, int nitem); /** Clculates CRC of image meta data body. */ igtl_uint64 igtl_export igtl_imgmeta_get_crc(igtl_imgmeta_element* metalist, int nitem); #ifdef __cplusplus } #endif #endif /* __IGTL_IMGMETA_H */ openigtlink-3.0.0/Source/igtlutil/igtl_lbmeta.c000066400000000000000000000025131501024245700215620ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_lbmeta.h" #include "igtl_util.h" void igtl_export igtl_lbmeta_convert_byte_order(igtl_lbmeta_element* metalist, int nitem) { igtl_lbmeta_element* elem; int i; for (i = 0; i < nitem; i ++) { elem = &(metalist[i]); if (igtl_is_little_endian()) { elem->size[0] = BYTE_SWAP_INT16(elem->size[0]); elem->size[1] = BYTE_SWAP_INT16(elem->size[1]); elem->size[2] = BYTE_SWAP_INT16(elem->size[2]); } } } igtl_uint64 igtl_export igtl_lbmeta_get_crc(igtl_lbmeta_element* metalist, int nitem) { igtl_lbmeta_element* elem; int i; igtl_uint64 crc; crc = crc64(0, 0, 0); for (i = 0; i < nitem; i ++) { elem = &(metalist[i]); crc = crc64((unsigned char*) elem, IGTL_LBMETA_ELEMENT_SIZE, crc); } return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_lbmeta.h000066400000000000000000000100051501024245700215620ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_LBMETA_H #define __IGTL_LBMETA_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #define IGTL_LBMETA_ELEMENT_SIZE 116 #define IGTL_LBMETA_LEN_NAME 64 #define IGTL_LBMETA_LEN_DEVICE_NAME 20 #define IGTL_LBMETA_LEN_OWNER 20 #ifdef __cplusplus extern "C" { #endif /** * Label meta data in OpenIGTLinik protocol * * LBMETA is a data type to send a list of label image data available in a server. * In OpenIGTLink protocol, actual label data is transfered as an IMAGE message. * LBMETA message lets the receiving client know which IMAGE data are available * as label maps. * Multiple labels in a LBMETA message can point the same IMAGE message, if there * are multiple lables are recoreded in a single IMAGE mesage. For example, given * the following label map as IMAGE data with name "LableImage1": * * 0 0 0 1 0 0 value | name / description * 2 0 1 1 1 0 --------+---------------------------- * 2 2 1 1 1 0 0 | None * 2 2 2 1 0 0 1 | Liver * 2 2 2 2 0 0 2 | Kidney * * To send the label information recorded in "LabelImage1," one can create * a following LBMETA message: * * DATA | Contents * ---------------+--------------------------- * NAME 1 | Liver * IMAGE NAME 1 | LabelImage * Labe l | 1 * RGBA 1 | 0xFF0000 * SIZE 1 | (6, 5, 1) * OWNER 1 | * --------------+--------------------------- * NAME 2 | Kidney * IMAGE NAME 2 | LabelImage * Labe 2 | 2 * RGBA 2 | 0xFF2222 * SIZE 2 | (6, 5, 1) * OWNER 2 | * --------------+--------------------------- * * ... .... * * --------------+--------------------------- * * The client determins the number of image meta by the size of the body included * in the message header (see igtl_lbmeta_getdata_n() macro). */ #pragma pack(1) /* For 1-byte boundary in memroy */ typedef struct { char name[IGTL_LBMETA_LEN_NAME]; /* name / description */ char device_name[IGTL_LBMETA_LEN_DEVICE_NAME]; /* device name to query the IMAGE */ igtl_uint8 label; /* label */ igtl_uint8 reserved; igtl_uint8 rgba[4]; /* Color in RGBA. default: (0, 0, 0, 0) */ igtl_uint16 size[3]; /* Number of pixels in each direction */ char owner[IGTL_LBMETA_LEN_OWNER];/* Device name of the owner image. (can be empty) */ } igtl_lbmeta_element; #pragma pack() /** igtl_lbmeta_get_data_size(n) calculates the size of body based on the number * of images.The size of body is used in the message header.*/ #define igtl_lbmeta_get_data_size(n) ((n) * IGTL_LBMETA_ELEMENT_SIZE) /** igtl_lbmeta_get_data_n(size) calculates the number of images in the body, based on * the body size. This function may be used when a client program parses LBMETA message. */ #define igtl_lbmeta_get_data_n(size) ((size) / IGTL_LBMETA_ELEMENT_SIZE) /** Converts endianness of each member variable in igtl_lbmeta_element * from host byte order to network byte order, or vice versa. */ void igtl_export igtl_lbmeta_convert_byte_order(igtl_lbmeta_element* metalist, int nitem); /** Calculates CRC of image meta data body. */ igtl_uint64 igtl_export igtl_lbmeta_get_crc(igtl_lbmeta_element* metalist, int nitem); #ifdef __cplusplus } #endif #endif /* __IGTL_LBMETA_H */ openigtlink-3.0.0/Source/igtlutil/igtl_ndarray.c000066400000000000000000000210651501024245700217610ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_ndarray.h" #include "igtl_util.h" void igtl_export igtl_ndarray_init_info(igtl_ndarray_info * info) { info->type = 0; info->dim = 0; info->size = NULL; info->array = NULL; } /* Calculate number of bytes / element */ igtl_uint32 igtl_ndarray_get_nbyte(int type) { igtl_uint32 bytes; switch (type) { case IGTL_NDARRAY_STYPE_TYPE_INT8: case IGTL_NDARRAY_STYPE_TYPE_UINT8: bytes = 1; break; case IGTL_NDARRAY_STYPE_TYPE_INT16: case IGTL_NDARRAY_STYPE_TYPE_UINT16: bytes = 2; break; case IGTL_NDARRAY_STYPE_TYPE_INT32: case IGTL_NDARRAY_STYPE_TYPE_UINT32: case IGTL_NDARRAY_STYPE_TYPE_FLOAT32: bytes = 4; break; case IGTL_NDARRAY_STYPE_TYPE_FLOAT64: bytes = 8; break; case IGTL_NDARRAY_STYPE_TYPE_COMPLEX: bytes = 16; break; default: bytes = 0; break; } return bytes; } int igtl_export igtl_ndarray_alloc_info(igtl_ndarray_info * info, const igtl_uint16 * size) { int i; igtl_uint64 len; if (info->size == NULL && info->array == NULL) { info->size = malloc(sizeof(igtl_uint16) * (igtl_uint16) info->dim); if (info->size == NULL) { return 0; } len = 1; for (i = 0; i < info->dim; i ++) { info->size[i] = size[i]; len *= size[i]; } info->array = malloc((size_t)(igtl_ndarray_get_nbyte(info->type) * len)); if (info->array == NULL) { free(info->size); return 0; } return 1; } else { return 0; } } int igtl_export igtl_ndarray_free_info(igtl_ndarray_info * info) { if (info->size) { free(info->size); } if (info->array) { free(info->array); } return 1; } int igtl_export igtl_ndarray_unpack(int type, void * byte_array, igtl_ndarray_info * info, igtl_uint64 pack_size) { char * ptr; igtl_uint16 dim; igtl_uint16 * size; igtl_uint16 i; igtl_uint64 len; igtl_uint16 * ptr16_src; igtl_uint16 * ptr16_src_end; igtl_uint16 * ptr16_dst; igtl_uint32 * ptr32_src; igtl_uint32 * ptr32_src_end; igtl_uint32 * ptr32_dst; igtl_uint64 * ptr64_src; igtl_uint64 * ptr64_src_end; igtl_uint64 * ptr64_dst; if (byte_array == NULL || info == NULL) { return 0; } igtl_ndarray_init_info(info); ptr = (char *) byte_array; /*** Type field ***/ info->type = * (igtl_uint8 *) ptr; ptr ++; /*** Dimension field ***/ info->dim = * (igtl_uint8 *) ptr; ptr ++; /*** Size array field ***/ size = (igtl_uint16 *) ptr; dim = info->dim; if (igtl_is_little_endian()) { /* Change byte order -- this overwrites memory area for the pack !!*/ for (i = 0; i < dim; i ++) { size[i] = BYTE_SWAP_INT16(size[i]); } } igtl_ndarray_alloc_info(info, size); memcpy(info->size, size, sizeof(igtl_uint16) * dim); if (igtl_is_little_endian()) { /* Resotore the overwritten memory area */ /* Don't use size[] array after this !! */ for (i = 0; i < dim; i ++) { size[i] = BYTE_SWAP_INT16(size[i]); } } ptr += sizeof(igtl_uint16) * dim; /*** N-D array field ***/ /* Calculate number of elements in N-D array */ len = 1; for (i = 0; i < dim; i ++) { len *= info->size[i]; } /* Copy array */ if (igtl_ndarray_get_nbyte(info->type) == 1 || !igtl_is_little_endian()) { /* If single-byte data type is used or the program runs on a big-endian machine, just copy the array from the pack to the strucutre */ memcpy(info->array, ptr, (size_t)(len * igtl_ndarray_get_nbyte(info->type))); } else if (igtl_ndarray_get_nbyte(info->type) == 2) /* 16-bit */ { ptr16_src = (igtl_uint16 *) ptr; ptr16_src_end = ptr16_src + len; ptr16_dst = (igtl_uint16 *) info->array; while (ptr16_src < ptr16_src_end) { *ptr16_dst = BYTE_SWAP_INT16(*ptr16_src); ptr16_dst ++; ptr16_src ++; } } else if (igtl_ndarray_get_nbyte(info->type) == 4) /* 32-bit */ { ptr32_src = (igtl_uint32 *) ptr; ptr32_src_end = ptr32_src + len; ptr32_dst = (igtl_uint32 *) info->array; while (ptr32_src < ptr32_src_end) { *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src); ptr32_dst ++; ptr32_src ++; } } else /* 64-bit or Complex type */ { ptr64_src = (igtl_uint64 *) ptr; /* Adding number of elements to the pointer -- 64-bit: len * 1; Complex: len * 2*/ ptr64_src_end = ptr64_src + len * igtl_ndarray_get_nbyte(info->type)/8; ptr64_dst = (igtl_uint64 *) info->array; while (ptr64_src < ptr64_src_end) { *ptr64_dst = BYTE_SWAP_INT64(*ptr64_src); ptr64_dst ++; ptr64_src ++; } } /* TODO: check if the pack size is valid */ return 1; } int igtl_export igtl_ndarray_pack(igtl_ndarray_info * info, void * byte_array, int type) { char * ptr; igtl_uint16 dim; igtl_uint16 * size; igtl_uint16 i; igtl_uint64 len; igtl_uint16 * ptr16_src; igtl_uint16 * ptr16_src_end; igtl_uint16 * ptr16_dst; igtl_uint32 * ptr32_src; igtl_uint32 * ptr32_src_end; igtl_uint32 * ptr32_dst; igtl_uint64 * ptr64_src; igtl_uint64 * ptr64_src_end; igtl_uint64 * ptr64_dst; if (byte_array == NULL || info == NULL) { return 0; } ptr = (char *) byte_array; /*** Type field ***/ * (igtl_uint8 *) ptr = info->type; ptr ++; /*** Dimension field ***/ * (igtl_uint8 *) ptr = info->dim; ptr ++; /*** Size array field ***/ size = (igtl_uint16 *) ptr; if (igtl_is_little_endian()) { for (i = 0; i < info->dim; i ++) { size[i] = BYTE_SWAP_INT16(info->size[i]); } } else { memcpy(ptr, info->size, sizeof(igtl_uint16) * info->dim); } dim = info->dim; ptr += sizeof(igtl_uint16) * dim; /*** N-D array field ***/ /* Calculate number of elements in N-D array */ len = 1; for (i = 0; i < dim; i ++) { len *= info->size[i]; } /* Copy array */ if (igtl_ndarray_get_nbyte(info->type) == 1 || !igtl_is_little_endian()) { /* If single-byte data type is used or the program runs on a big-endian machine, just copy the array from the pack to the strucutre */ memcpy(ptr, info->array, (size_t) (len * igtl_ndarray_get_nbyte(info->type))); } else if (igtl_ndarray_get_nbyte(info->type) == 2) /* 16-bit */ { ptr16_src = (igtl_uint16 *) info->array; ptr16_src_end = ptr16_src + len; ptr16_dst = (igtl_uint16 *) ptr; while (ptr16_src < ptr16_src_end) { *ptr16_dst = BYTE_SWAP_INT16(*ptr16_src); ptr16_dst ++; ptr16_src ++; } } else if (igtl_ndarray_get_nbyte(info->type) == 4) /* 32-bit */ { ptr32_src = (igtl_uint32 *) info->array; ptr32_src_end = ptr32_src + len; ptr32_dst = (igtl_uint32 *) ptr; while (ptr32_src < ptr32_src_end) { *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src); ptr32_dst ++; ptr32_src ++; } } else /* 64-bit or Complex type */ { ptr64_src = (igtl_uint64 *) info->array; /* Adding number of elements to the pointer -- 64-bit: len * 1; Complex: len * 2*/ ptr64_src_end = ptr64_src + len * igtl_ndarray_get_nbyte(info->type)/8; ptr64_dst = (igtl_uint64 *) ptr; while (ptr64_src < ptr64_src_end) { *ptr64_dst = BYTE_SWAP_INT64(*ptr64_src); ptr64_dst ++; ptr64_src ++; } } return 1; } igtl_uint64 igtl_export igtl_ndarray_get_size(igtl_ndarray_info * info, int type) { igtl_uint64 len; igtl_uint64 data_size; igtl_uint16 i; igtl_uint16 dim; dim = info->dim; len = 1; for (i = 0; i < dim; i ++) { len *= (igtl_uint64)info->size[i]; } data_size = sizeof(igtl_uint8) * 2 + sizeof(igtl_uint16) * (igtl_uint64) dim + len * igtl_ndarray_get_nbyte(info->type); return data_size; } igtl_uint64 igtl_export igtl_ndarray_get_crc(igtl_ndarray_info * info, int type, void* data) { igtl_uint64 crc; igtl_uint64 data_size; data_size = igtl_ndarray_get_size(info, type); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) data, data_size, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_ndarray.h000066400000000000000000000066131501024245700217700ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_NDARRAY_H #define __IGTL_NDARRAY_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_win32header.h" #define IGTL_NDARRAY_HEADER_SIZE 2 /* Scalar type */ #define IGTL_NDARRAY_STYPE_TYPE_INT8 2 #define IGTL_NDARRAY_STYPE_TYPE_UINT8 3 #define IGTL_NDARRAY_STYPE_TYPE_INT16 4 #define IGTL_NDARRAY_STYPE_TYPE_UINT16 5 #define IGTL_NDARRAY_STYPE_TYPE_INT32 6 #define IGTL_NDARRAY_STYPE_TYPE_UINT32 7 #define IGTL_NDARRAY_STYPE_TYPE_FLOAT32 10 #define IGTL_NDARRAY_STYPE_TYPE_FLOAT64 11 #define IGTL_NDARRAY_STYPE_TYPE_COMPLEX 13 #define IGTL_NDARRAY_HOST_TO_NETWORK 0 #define IGTL_NDARRAY_NETWORK_TO_HOST 1 #ifdef __cplusplus extern "C" { #endif /** NDARRAY is a data type, which is designed to transfer N-dimensional numerical array. * The message body consists of N-D array header, size table, and N-D array body. */ typedef struct { igtl_uint8 type; /* Scalar type (2:int8 3:uint8 4:int16 5:uint16 6:int32 7:uint32 10:float32 11:float64 13:complex) */ igtl_uint8 dim; /* Dimension of array */ igtl_uint16 * size; /* Array size */ void * array; } igtl_ndarray_info; /** Initializes igtl_ndarray_info */ void igtl_export igtl_ndarray_init_info(igtl_ndarray_info * info); /** Allocates size array and ND-array pointed from igtl_ndarray_info. * 'type' and 'dim' in igtl_ndarray_info must be specified before * calling igtl_ndarray_alloc_info(). */ int igtl_export igtl_ndarray_alloc_info(igtl_ndarray_info * info, const igtl_uint16 * size); /** Frees ndarray */ int igtl_export igtl_ndarray_free_info(igtl_ndarray_info * info); /** Unpacks and extracts information in a byte array of NDARRAY messages and store * it in a igtl_ndarray_info structure. 'type' argument specifies * a message type prefix (none, GET_, STT_, STP_ or RTS_) by IGTL_TYPE_PREFIX_* macro. * Returns 1 if success, otherwise 0. */ int igtl_export igtl_ndarray_unpack(int type, void * byte_array, igtl_ndarray_info * info, igtl_uint64 pack_size); /** Converts an igtl_ndarray_info structure to a byte array. * 'byte_array' should be allocated prior to calling igtl_ndarray_pack() with memory size * calculated by igtl_ndarray_get_size(). 'type' argument specifies a message type prefix * (none, or GET_) by IGTL_TYPE_PREFIX_* macro. Returns 1 if success, otherwise 0. */ int igtl_export igtl_ndarray_pack(igtl_ndarray_info * info, void * byte_array, int type); /** Calculates size of N-D array body including * size table (defined by UINT16[dim]) and array data. */ igtl_uint64 igtl_export igtl_ndarray_get_size(igtl_ndarray_info * info, int type); /** Calculates CRC of image data body including header and array of pixel data. */ igtl_uint64 igtl_export igtl_ndarray_get_crc(igtl_ndarray_info * info, int type, void* byte_array); #ifdef __cplusplus } #endif #endif /* __IGTL_NDARRAY_H */ openigtlink-3.0.0/Source/igtlutil/igtl_point.c000066400000000000000000000026301501024245700214470ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_point.h" #include "igtl_util.h" void igtl_export igtl_point_convert_byte_order(igtl_point_element* pointlist, int nitem) { igtl_point_element* elem; int i; int j; igtl_int32* tmp; for (i = 0; i < nitem; i ++) { elem = &(pointlist[i]); if (igtl_is_little_endian()) { for (j = 0; j < 3; j ++) { tmp = (igtl_int32*)&(elem->position[j]); *tmp = BYTE_SWAP_INT32(*tmp); } tmp = (igtl_int32*)&(elem->radius); *tmp = BYTE_SWAP_INT32(*tmp); } } } igtl_uint64 igtl_export igtl_point_get_crc(igtl_point_element* pointlist, int nitem) { igtl_point_element* elem; int i; igtl_uint64 crc; crc = crc64(0, 0, 0); for (i = 0; i < nitem; i ++) { elem = &(pointlist[i]); crc = crc64((unsigned char*) elem, IGTL_POINT_ELEMENT_SIZE, crc); } return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_point.h000066400000000000000000000044621501024245700214610ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_POINT_H #define __IGTL_POINT_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #define IGTL_POINT_ELEMENT_SIZE 136 #define IGTL_POINT_LEN_NAME 64 #define IGTL_POINT_LEN_GROUP_NAME 32 #define IGTL_POINT_LEN_OWNER 20 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Status data header for OpenIGTLinik protocol */ typedef struct { char name[IGTL_POINT_LEN_NAME]; /* Name or description of the point */ char group_name[IGTL_POINT_LEN_GROUP_NAME]; /* Can be "Labeled Point", "Landmark", Fiducial", ... */ igtl_uint8 rgba[4]; /* Color in R/G/B/A */ igtl_float32 position[3]; /* Coordinate of the point */ igtl_float32 radius; /* Radius of the point. Can be 0. */ char owner[IGTL_POINT_LEN_OWNER];/* Device name of the ower image */ } igtl_point_element; #pragma pack() /** igtl_point_get_data_size(n) calculates the size of body based on the number * of points. The size of body is used in the message header.*/ #define igtl_point_get_data_size(n) ((n) * IGTL_POINT_ELEMENT_SIZE) /** igtl_point_get_data_n(size) calculates the number of images in the body, based on * the body size. This function may be used when a client program parses a POINT message. */ #define igtl_point_get_data_n(size) ((size) / IGTL_POINT_ELEMENT_SIZE) /** Converts endianness of each element in an array of * igtl_igtl_point_element from host byte order to network byte order, * or vice versa. */ void igtl_export igtl_point_convert_byte_order(igtl_point_element* pointlist, int nelem); /** Calculates CRC of point message */ igtl_uint64 igtl_export igtl_point_get_crc(igtl_point_element* pointlist, int nelem); #ifdef __cplusplus } #endif #endif /* __IGTL_POINT_H */ openigtlink-3.0.0/Source/igtlutil/igtl_polydata.c000066400000000000000000000453741501024245700221470ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_polydata.h" #include "igtl_util.h" void igtl_export igtl_polydata_init_info(igtl_polydata_info * info) { if (info) { info->header.npoints = 0; info->header.nvertices = 0; info->header.size_vertices = 0; info->header.nlines = 0; info->header.size_lines = 0; info->header.npolygons = 0; info->header.size_polygons = 0; info->header.ntriangle_strips = 0; info->header.size_triangle_strips = 0; info->header.nattributes = 0; info->points = NULL; info->vertices = NULL; info->lines = NULL; info->polygons = NULL; info->triangle_strips = NULL; info->attributes = NULL; } } int igtl_export igtl_polydata_alloc_info(igtl_polydata_info * info) { /*size_t size;*/ unsigned int i; if (info == NULL) { return 0; } /** Points **/ if (info->points) { free(info->points); info->points = NULL; } if (info->header.npoints > 0) { info->points = malloc(info->header.npoints * sizeof(igtl_float32) * 3); if (info->points == NULL) { return 0; } } /** Vertices **/ if (info->vertices) { free(info->vertices); info->vertices = NULL; } if (info->header.nvertices > 0) { info->vertices = malloc(info->header.size_vertices); if (info->vertices == NULL) { return 0; } } /** Lines **/ if (info->lines) { free(info->lines); info->lines = NULL; } if (info->header.nlines > 0) { info->lines = malloc(info->header.size_lines); if (info->lines == NULL) { return 0; } } /** Polygons **/ if (info->polygons) { free(info->polygons); } if (info->header.npolygons > 0) { info->polygons = malloc(info->header.size_polygons); if (info->polygons == NULL) { return 0; } } /** Triangle strips **/ if (info->triangle_strips) { free(info->triangle_strips); } if (info->header.ntriangle_strips > 0) { info->triangle_strips = malloc(info->header.size_triangle_strips); if (info->triangle_strips == NULL) { return 0; } } /** Attributes **/ if (info->attributes) { for (i = 0; i < info->header.nattributes; i ++) { if (info->attributes[i].name) { free(info->attributes[i].name); } if (info->attributes[i].data) { free(info->attributes[i].data); } } free(info->attributes); } if (info->header.nattributes > 0) { info->attributes = malloc(sizeof(igtl_polydata_attribute) * info->header.nattributes); if (info->attributes == NULL) { return 0; } for (i = 0; i < info->header.nattributes; i ++) { info->attributes[i].type = 0; info->attributes[i].ncomponents = 1; info->attributes[i].n = 0; info->attributes[i].name = NULL; info->attributes[i].data = NULL; } } return 1; } int igtl_export igtl_polydata_free_info(igtl_polydata_info * info) { unsigned int i; if (info == NULL) { return 0; } /** Points **/ if (info->points) { free(info->points); info->points = NULL; } /** Vertices **/ if (info->vertices) { free(info->vertices); info->vertices = NULL; } /** Lines **/ if (info->lines) { free(info->lines); info->lines = NULL; } /** Polygons **/ if (info->polygons) { free(info->polygons); info->polygons = NULL; } /** Triangle strips **/ if (info->triangle_strips) { free(info->triangle_strips); info->triangle_strips = NULL; } /** Attributes **/ if (info->attributes) { for (i = 0; i < info->header.nattributes; i ++) { if (info->attributes[i].name) { free(info->attributes[i].name); } if (info->attributes[i].data) { free(info->attributes[i].data); } } free(info->attributes); } return 1; } int igtl_polydata_convert_byteorder_topology(igtl_uint32 * dst, igtl_uint32 * src, igtl_uint32 size) { igtl_uint32 * ptr32_src; igtl_uint32 * ptr32_src_end; igtl_uint32 * ptr32_dst; if (size == 0) { return 1; } if (!src || !dst) { /* Return error, if either src or dst is NULL despite size>0 */ return 0; } if (!igtl_is_little_endian()) { memcpy((void*)dst, (void*)src, size); } else { ptr32_src = (igtl_uint32 *) src; ptr32_src_end = ptr32_src + (size/sizeof(igtl_uint32)); ptr32_dst = (igtl_uint32 *) dst; while (ptr32_src < ptr32_src_end) { *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src); ptr32_dst ++; ptr32_src ++; } } return 1; } int igtl_export igtl_polydata_unpack(int type, void * byte_array, igtl_polydata_info * info, igtl_uint64 size) { /* size = number of ponits (not number of bytes). In case of vertices, this is specfied by size_vertices in igtl_polydata_header. */ igtl_polydata_header * header; char * ptr; igtl_uint32 * ptr32_src; igtl_uint32 * ptr32_src_end; igtl_uint32 * ptr32_dst; igtl_uint32 s; igtl_polydata_attribute_header * att_header; igtl_polydata_attribute * att; int total_name_length; int name_length; char name_buf[IGTL_POLY_MAX_ATTR_NAME_LEN+1]; unsigned int i; int n; if (byte_array == NULL || info == NULL || size == 0) { return 0; } /* POLYDATA header */ header = (igtl_polydata_header *) byte_array; if (igtl_is_little_endian()) { info->header.npoints = BYTE_SWAP_INT32(header->npoints); info->header.nvertices = BYTE_SWAP_INT32(header->nvertices); info->header.size_vertices = BYTE_SWAP_INT32(header->size_vertices); info->header.nlines = BYTE_SWAP_INT32(header->nlines); info->header.size_lines = BYTE_SWAP_INT32(header->size_lines); info->header.npolygons = BYTE_SWAP_INT32(header->npolygons); info->header.size_polygons = BYTE_SWAP_INT32(header->size_polygons); info->header.ntriangle_strips = BYTE_SWAP_INT32(header->ntriangle_strips); info->header.size_triangle_strips = BYTE_SWAP_INT32(header->size_triangle_strips); info->header.nattributes = BYTE_SWAP_INT32(header->nattributes); } else { memcpy(&(info->header), header, sizeof(igtl_polydata_header)); } /* Allocate memory to read data */ /* TODO: compare the size of info before copying the header. */ /* If the size doesn't change, avoid reallocation of memory. */ if (igtl_polydata_alloc_info(info) == 0) { return 0; } /* POINT section */ ptr = (char*) byte_array + sizeof(igtl_polydata_header); if (!igtl_is_little_endian()) { memcpy(info->points, ptr, sizeof(igtl_float32)*info->header.npoints*3); } else { ptr32_src = (igtl_uint32 *) ptr; ptr32_src_end = ptr32_src + info->header.npoints*3; ptr32_dst = (igtl_uint32 *) info->points; while (ptr32_src < ptr32_src_end) { *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src); ptr32_dst ++; ptr32_src ++; } } ptr += sizeof(igtl_float32)*info->header.npoints*3; /* Check size parameters */ if (info->header.size_vertices%sizeof(igtl_uint32) != 0 || info->header.size_lines%sizeof(igtl_uint32) != 0 || info->header.size_polygons%sizeof(igtl_uint32) != 0 || info->header.size_triangle_strips%sizeof(igtl_uint32)) { /* More than one of size parameters is multiples of 4 (size of 32-bit value) */ return 0; } /* VERTICES section */ igtl_polydata_convert_byteorder_topology(info->vertices, (igtl_uint32*)ptr, info->header.size_vertices); ptr += info->header.size_vertices; /* LINES section */ igtl_polydata_convert_byteorder_topology(info->lines, (igtl_uint32*)ptr, info->header.size_lines); ptr += info->header.size_lines; /* POLYGONS section */ igtl_polydata_convert_byteorder_topology(info->polygons, (igtl_uint32*)ptr, info->header.size_polygons); ptr += info->header.size_polygons; /* TRIANGLE_STRIPS section */ igtl_polydata_convert_byteorder_topology(info->triangle_strips, (igtl_uint32*)ptr, info->header.size_triangle_strips); ptr += info->header.size_triangle_strips; /* Attribute header */ for (i = 0; i < info->header.nattributes; i ++) { att = &(info->attributes[i]); att_header = (igtl_polydata_attribute_header *) ptr; att->type = att_header->type; att->ncomponents = att_header->ncomponents; if (igtl_is_little_endian()) { att->n = BYTE_SWAP_INT32(att_header->n); } else { att->n = att_header->n; } ptr += sizeof(igtl_polydata_attribute_header); } /* Attribute names */ total_name_length = 0; name_buf[IGTL_POLY_MAX_ATTR_NAME_LEN] = '\0'; for (i = 0; i < info->header.nattributes; i ++) { name_length = strlen(ptr); if (name_length <= IGTL_POLY_MAX_ATTR_NAME_LEN) { info->attributes[i].name = malloc(name_length+1); strcpy(info->attributes[i].name, ptr); } else { /* invalid name length */ return 0; } total_name_length += (name_length+1); ptr += (name_length+1); } if (total_name_length % 2 > 0) { /* add padding */ ptr ++; } /* Attributes */ for (i = 0; i < info->header.nattributes; i ++) { if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_SCALAR) { n = info->attributes[i].ncomponents * info->attributes[i].n; s = n * sizeof(igtl_float32); } else if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_NORMAL) { n = 3 * info->attributes[i].n; s = n * sizeof(igtl_float32); } else if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_VECTOR) { n = 3 * info->attributes[i].n; s = n * sizeof(igtl_float32); } else /* TENSOR */ { n = 9 * info->attributes[i].n; s = n * sizeof(igtl_float32); } info->attributes[i].data = (igtl_float32*)malloc((size_t)s); ptr32_dst = (igtl_uint32*)info->attributes[i].data; ptr32_src = (igtl_uint32*)ptr; ptr32_src_end = ptr32_src + n; if (igtl_is_little_endian()) { while (ptr32_src < ptr32_src_end) { *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src); ptr32_dst ++; ptr32_src ++; } } else { memcpy(ptr32_dst, ptr32_src, s); } ptr += s; } return 1; } int igtl_export igtl_polydata_pack(igtl_polydata_info * info, void * byte_array, int type) { /* size = number of ponits (not number of bytes). In case of vertices, this is specfied by size_vertices in igtl_polydata_header. */ igtl_polydata_header * header; char * ptr; igtl_uint32 * ptr32_src; igtl_uint32 * ptr32_src_end; igtl_uint32 * ptr32_dst; igtl_polydata_attribute_header * att_header; igtl_polydata_attribute * att; int total_name_length; int name_length; unsigned int i; int n; int size; if (byte_array == NULL || info == NULL) { return 0; } /* POLYDATA header */ header = (igtl_polydata_header *) byte_array; if (igtl_is_little_endian()) { header->npoints = BYTE_SWAP_INT32(info->header.npoints); header->nvertices = BYTE_SWAP_INT32(info->header.nvertices); header->size_vertices = BYTE_SWAP_INT32(info->header.size_vertices); header->nlines = BYTE_SWAP_INT32(info->header.nlines); header->size_lines = BYTE_SWAP_INT32(info->header.size_lines); header->npolygons = BYTE_SWAP_INT32(info->header.npolygons); header->size_polygons = BYTE_SWAP_INT32(info->header.size_polygons); header->ntriangle_strips = BYTE_SWAP_INT32(info->header.ntriangle_strips); header->size_triangle_strips = BYTE_SWAP_INT32(info->header.size_triangle_strips); header->nattributes = BYTE_SWAP_INT32(info->header.nattributes); } else { memcpy(header, &(info->header), sizeof(igtl_polydata_header)); } /* POINT section */ ptr = (char*) byte_array + sizeof(igtl_polydata_header); if (!igtl_is_little_endian()) { memcpy((void*)ptr, (void*)info->points, sizeof(igtl_float32)*info->header.npoints*3); } else { ptr32_src = (igtl_uint32 *) info->points; ptr32_src_end = ptr32_src + info->header.npoints*3; ptr32_dst = (igtl_uint32 *) ptr; while (ptr32_src < ptr32_src_end) { *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src); ptr32_dst ++; ptr32_src ++; } } ptr += sizeof(igtl_float32)*info->header.npoints*3; /* Check size parameters */ if (info->header.size_vertices%sizeof(igtl_uint32) != 0 || info->header.size_lines%sizeof(igtl_uint32) != 0 || info->header.size_polygons%sizeof(igtl_uint32) != 0 || info->header.size_triangle_strips%sizeof(igtl_uint32)) { /* More than one of size parameters is multiples of 4 (size of 32-bit value) */ return 0; } /* VERTICES section */ igtl_polydata_convert_byteorder_topology((igtl_uint32*)ptr, info->vertices, info->header.size_vertices); ptr += info->header.size_vertices; /* LINES section */ igtl_polydata_convert_byteorder_topology((igtl_uint32*)ptr, info->lines, info->header.size_lines); ptr += info->header.size_lines; /* POLYGONS section */ igtl_polydata_convert_byteorder_topology((igtl_uint32*)ptr, info->polygons, info->header.size_polygons); ptr += info->header.size_polygons; /* TRIANGLE_STRIPS section */ igtl_polydata_convert_byteorder_topology((igtl_uint32*)ptr, info->triangle_strips, info->header.size_triangle_strips); ptr += info->header.size_triangle_strips; /* Attribute header */ for (i = 0; i < info->header.nattributes; i ++) { att = &(info->attributes[i]); att_header = (igtl_polydata_attribute_header *) ptr; att_header->type = att->type; if (att->type == IGTL_POLY_ATTR_TYPE_SCALAR) { att_header->ncomponents = att->ncomponents; } else if (att->type == IGTL_POLY_ATTR_TYPE_VECTOR) { att_header->ncomponents = 3; } else if (att->type == IGTL_POLY_ATTR_TYPE_NORMAL) { att_header->ncomponents = 3; } else /* att->type == IGTL_POLY_ATTR_TYPE_TENSOR */ { att_header->ncomponents = 9; } if (igtl_is_little_endian()) { att_header->n = BYTE_SWAP_INT32(att->n); } else { att_header->n = att->n; } ptr += sizeof(igtl_polydata_attribute_header); } /* Attribute names */ total_name_length = 0; for (i = 0; i < info->header.nattributes; i ++) { name_length = strlen(info->attributes[i].name); if (name_length > IGTL_POLY_MAX_ATTR_NAME_LEN) { return 0; } strcpy(ptr, info->attributes[i].name); total_name_length += (name_length+1); ptr += (name_length+1); } if (total_name_length % 2 > 0) { /* add padding */ *(char*)ptr = '\0'; ptr ++; } /* Attributes */ for (i = 0; i < info->header.nattributes; i ++) { if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_SCALAR) { n = info->attributes[i].ncomponents * info->attributes[i].n; size = n * sizeof(igtl_float32); } else if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_NORMAL) { n = 3 * info->attributes[i].n; size = n * sizeof(igtl_float32); } else if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_VECTOR) { n = 3 * info->attributes[i].n; size = n * sizeof(igtl_float32); } else /* TENSOR */ { n = 9 * info->attributes[i].n; size = n * sizeof(igtl_float32); } if (igtl_is_little_endian()) { ptr32_dst = (igtl_uint32*)ptr; ptr32_src = (igtl_uint32*)info->attributes[i].data; ptr32_src_end = ptr32_src + n; while (ptr32_src < ptr32_src_end) { *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src); ptr32_dst ++; ptr32_src ++; } } else { memcpy(ptr, info->attributes[i].data, size); } ptr += size; } return 1; } igtl_uint64 igtl_export igtl_polydata_get_size(igtl_polydata_info * info, int type) { igtl_uint64 data_size; int name_len; unsigned int i; int n; int size; /* Header */ data_size = sizeof(igtl_polydata_header); /* POINT section */ data_size += sizeof(igtl_float32)*info->header.npoints*3; /* VERTICES */ data_size += info->header.size_vertices; /* LINES */ data_size += info->header.size_lines; /* POLYGONS */ data_size += info->header.size_polygons; /* TRIANGLE_STRIPS */ data_size += info->header.size_triangle_strips; /* Attribute header */ data_size += sizeof(igtl_polydata_attribute_header) * info->header.nattributes; /* Attribute names */ for (i = 0; i < info->header.nattributes; i ++) { name_len = strlen(info->attributes[i].name); if (name_len > IGTL_POLY_MAX_ATTR_NAME_LEN) { /* Invaid name length */ return 0; } data_size += name_len + 1; /* Including terminator */ } /* Padding */ if (data_size % 2 > 0) { data_size ++; } /* Attributes */ for (i = 0; i < info->header.nattributes; i ++) { if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_SCALAR) { n = info->attributes[i].ncomponents * info->attributes[i].n; size = n * sizeof(igtl_float32); } else if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_NORMAL) { n = 3 * info->attributes[i].n; size = n * sizeof(igtl_float32); } else if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_VECTOR) { n = 3 * info->attributes[i].n; size = n * sizeof(igtl_float32); } else /* TENSOR */ { n = 9 * info->attributes[i].n; size = n * sizeof(igtl_float32); } data_size += size; } return data_size; } igtl_uint64 igtl_export igtl_polydata_get_crc(igtl_polydata_info * info, int type, void* polydata_message) { igtl_uint64 crc; igtl_uint64 polydata_length; /*igtl_uint16 i;*/ /*igtl_uint16 nc;*/ polydata_length = (igtl_uint32)igtl_polydata_get_size(info, type); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) polydata_message, (int)polydata_length, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_polydata.h000066400000000000000000000137041501024245700221440ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_POLYDATA_H #define __IGTL_POLYDATA_H #include "igtl_win32header.h" #include "igtl_header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_win32header.h" #ifdef __cplusplus extern "C" { #endif #define IGTL_POLY_MAX_ATTR_NAME_LEN 255 #define IGTL_POLY_ATTR_TYPE_SCALAR 0x00 #define IGTL_POLY_ATTR_TYPE_VECTOR 0x01 #define IGTL_POLY_ATTR_TYPE_NORMAL 0x02 #define IGTL_POLY_ATTR_TYPE_TENSOR 0x03 #define IGTL_POLY_ATTR_TYPE_RGBA 0x04 #pragma pack(1) /* For 1-byte boundary in memory */ /** POLYDATA Header */ typedef struct { igtl_uint32 npoints; /* Number of points */ igtl_uint32 nvertices; /* Number of vertices */ igtl_uint32 size_vertices; /* Size of vertex data (bytes) */ igtl_uint32 nlines; /* Number of lines */ igtl_uint32 size_lines; /* Size of line data (bytes) */ igtl_uint32 npolygons; /* Number of polygons */ igtl_uint32 size_polygons; /* Size of polygon data (bytes) */ igtl_uint32 ntriangle_strips; /* Number of triangle strips */ igtl_uint32 size_triangle_strips; /* Size of triangle strips data (bytes) */ igtl_uint32 nattributes; /* Number of attributes */ } igtl_polydata_header; typedef struct { igtl_uint8 type; /* attribute type */ /* Values for TYPE_ATTRIBUTE (16-bit) 0x00: POINT_DATA / Scalars 0x01: POINT_DATA / Vectors 0x02: POINT_DATA / Normals 0x03: POINT_DATA / Tensors 0x10: CELL_DATA / Scalars 0x11: CELL_DATA / Vectors 0x12: CELL_DATA / Normals 0x13: CELL_DATA Tensors */ igtl_uint8 ncomponents; /* number of components */ /* must be 3 for Vectors and Normal, 9 for Tensor.*/ igtl_uint32 n; } igtl_polydata_attribute_header; #pragma pack() /** Attribute info */ typedef struct { igtl_uint8 type; igtl_uint8 ncomponents; igtl_uint32 n; char * name; igtl_float32 * data; } igtl_polydata_attribute; /** POLYDATA info */ typedef struct { igtl_polydata_header header; /* Header */ igtl_float32* points; /* Points */ igtl_uint32 * vertices; /* Vertices -- array of (N, i1, i2, i3 ...iN) */ igtl_uint32 * lines; /* Lines -- array of (N, i1, i2, i3 ...iN) */ igtl_uint32 * polygons; /* Polygons -- array of (N, i1, i2, i3 ...iN) */ igtl_uint32 * triangle_strips; /* Triangle strips -- array of (N, i1, i2, i3 ...iN) */ igtl_polydata_attribute * attributes; /* Array of attributes */ } igtl_polydata_info; /** Initializes igtl_polydata_info */ void igtl_export igtl_polydata_init_info(igtl_polydata_info * info); /** Allocates free arrays in polydata_info. * Note that igtl_polydata_alloc_info() does not allocate memory for 'name' and 'data' * in each igtl_polydata_attribute. Those elements have to be allocated in the developers * responsibility. * igtl_polydata_free_info() function assumes that igtl_polydata_info is allocated by * igtl_polydata_alloc_info() and all memory blocks pointed from igtl_polydata_attribute * have been allocated by malloc(). * Return 1 if the array is successfully allocated/freed. */ int igtl_export igtl_polydata_alloc_info(igtl_polydata_info * info); int igtl_export igtl_polydata_free_info(igtl_polydata_info * info); /** Extracts information about child messages in a byte array of POLYDATA messages and store * it in a igtl_polydata_info structure. 'type' argument specifies a message type prefix * (none, GET_, STT_, STP_ or RTS_) by IGTL_TYPE_PREFIX_* macro. * Returns 1 if success, otherwise 0. */ int igtl_export igtl_polydata_unpack(int type, void * byte_array, igtl_polydata_info * info, igtl_uint64 size); /** Converts an igtl_polydata_info structure to a byte array. * 'byte_array' should be allocated prior to calling igtl_polydata_pack() with memory size * calculated by igtl_polydata_get_size(). 'type' argument specifies a message type prefix * (none, GET_, STT_, STP_ or RTS_) by IGTL_TYPE_PREFIX_* macro. * Returns 1 if success, otherwise 0. */ int igtl_export igtl_polydata_pack(igtl_polydata_info * info, void * byte_array, int type); /** igtl_polydata_get_size() calculates the size of polydata header, consisting of * POLYDATA hearder section (including number of child messages) and * name table section based on a igtl_polydata_header. * The size returned from this function does not include size of child message data. * 'type' argument specifies a message type prefix * (none, GET_, STT_, STP_ or RTS_) by IGTL_TYPE_PREFIX_* macro. */ igtl_uint64 igtl_export igtl_polydata_get_size(igtl_polydata_info * info, int type); /** Calculates CRC of POLYDATA message. Note that 'info' is used only for * getting size of the message. */ igtl_uint64 igtl_export igtl_polydata_get_crc(igtl_polydata_info * info, int type, void* polydata_message); #ifdef __cplusplus } #endif #endif /* __IGTL_POLYDATA_H */openigtlink-3.0.0/Source/igtlutil/igtl_position.c000066400000000000000000000052311501024245700221620ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include "igtl_position.h" #include "igtl_util.h" #include void igtl_export igtl_position_convert_byte_order(igtl_position* pos) { igtl_uint32 tmp[4]; if (igtl_is_little_endian()) { /* position */ memcpy((void*)tmp, (void*)(pos->position), sizeof(igtl_float32)*3); tmp[0] = BYTE_SWAP_INT32(tmp[0]); tmp[1] = BYTE_SWAP_INT32(tmp[1]); tmp[2] = BYTE_SWAP_INT32(tmp[2]); memcpy((void*)(pos->position), (void*)tmp, sizeof(igtl_float32)*3); /* quaternion */ memcpy((void*)tmp, (void*)(pos->quaternion), sizeof(igtl_float32)*4); tmp[0] = BYTE_SWAP_INT32(tmp[0]); tmp[1] = BYTE_SWAP_INT32(tmp[1]); tmp[2] = BYTE_SWAP_INT32(tmp[2]); tmp[3] = BYTE_SWAP_INT32(tmp[3]); memcpy((void*)(pos->quaternion), (void*)tmp, sizeof(igtl_float32)*4); } } void igtl_export igtl_position_convert_byte_order_position_only(igtl_position* pos) { igtl_uint32 tmp[4]; if (igtl_is_little_endian()) { /* position */ memcpy((void*)tmp, (void*)(pos->position), sizeof(igtl_float32)*3); tmp[0] = BYTE_SWAP_INT32(tmp[0]); tmp[1] = BYTE_SWAP_INT32(tmp[1]); tmp[2] = BYTE_SWAP_INT32(tmp[2]); memcpy((void*)(pos->position), (void*)tmp, sizeof(igtl_float32)*3); } } void igtl_export igtl_position_convert_byte_order_quaternion3(igtl_position* pos) { igtl_uint32 tmp[4]; if (igtl_is_little_endian()) { /* position */ memcpy((void*)tmp, (void*)(pos->position), sizeof(igtl_float32)*3); tmp[0] = BYTE_SWAP_INT32(tmp[0]); tmp[1] = BYTE_SWAP_INT32(tmp[1]); tmp[2] = BYTE_SWAP_INT32(tmp[2]); memcpy((void*)(pos->position), (void*)tmp, sizeof(igtl_float32)*3); /* quaternion */ memcpy((void*)tmp, (void*)(pos->quaternion), sizeof(igtl_float32)*3); tmp[0] = BYTE_SWAP_INT32(tmp[0]); tmp[1] = BYTE_SWAP_INT32(tmp[1]); tmp[2] = BYTE_SWAP_INT32(tmp[2]); memcpy((void*)(pos->quaternion), (void*)tmp, sizeof(igtl_float32)*3); } } igtl_uint64 igtl_export igtl_position_get_crc(igtl_position* pos) { igtl_uint64 crc = crc64(0, 0, 0); crc = crc64((unsigned char*)pos, IGTL_POSITION_MESSAGE_DEFAULT_SIZE, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_position.h000066400000000000000000000034131501024245700221670ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_POSITION_H #define __IGTL_POSITION_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #define IGTL_POSITION_MESSAGE_DEFAULT_SIZE 28 /** NOTE: the size varies if orientation is omitted **/ #define IGTL_POSITION_MESSAGE_POSITON_ONLY_SIZE 12 /* size w/o quaternion */ #define IGTL_POSITION_MESSAGE_WITH_QUATERNION3_SIZE 24 /* size 3-element quaternion */ #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Status data header for OpenIGTLinik protocol */ typedef struct { igtl_float32 position[3]; /* (x, y, z) */ igtl_float32 quaternion[4]; /* (ox, oy, oz, w) */ } igtl_position; #pragma pack() /** Converts endianness of each member variable * in igtl_status_header from host byte order to network byte order, * or vice versa. */ void igtl_export igtl_position_convert_byte_order(igtl_position* pos); void igtl_export igtl_position_convert_byte_order_position_only(igtl_position* pos); void igtl_export igtl_position_convert_byte_order_quaternion3(igtl_position* pos); /** Calculates CRC of position message */ igtl_uint64 igtl_export igtl_position_get_crc(igtl_position* pos); #ifdef __cplusplus } #endif #endif /* __IGTL_POSITION_H */ openigtlink-3.0.0/Source/igtlutil/igtl_qtdata.c000066400000000000000000000043531501024245700216000ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_qtdata.h" #include "igtl_util.h" void igtl_export igtl_qtdata_convert_byte_order(igtl_qtdata_element* qtdatalist, int nitem) { igtl_qtdata_element* elem; int i; int j; int k; igtl_int32* tmp; for (i = 0; i < nitem; i ++) { elem = &(qtdatalist[i]); if (igtl_is_little_endian()) { for (j = 0; j < 3; j ++) { tmp = (igtl_int32*)&(elem->position[j]); *tmp = BYTE_SWAP_INT32(*tmp); } for (k = 0; k < 4; k ++) { tmp = (igtl_int32*)&(elem->quaternion[k]); *tmp = BYTE_SWAP_INT32(*tmp); } } } } void igtl_export igtl_stt_qtdata_convert_byte_order(igtl_stt_qtdata* stt_qtdata) { igtl_int32* tmp; if (igtl_is_little_endian()) { tmp = (igtl_int32*)&(stt_qtdata->resolution); *tmp = BYTE_SWAP_INT32(*tmp); } } void igtl_export igtl_rts_qtdata_convert_byte_order(igtl_rts_qtdata* rts_qtdata) { /* do nothing */ } igtl_uint64 igtl_export igtl_qtdata_get_crc(igtl_qtdata_element* qtdatalist, int nitem) { igtl_qtdata_element* elem; int i; igtl_uint64 crc; crc = crc64(0, 0, 0); for (i = 0; i < nitem; i ++) { elem = &(qtdatalist[i]); crc = crc64((unsigned char*) elem, IGTL_QTDATA_ELEMENT_SIZE, crc); } return crc; } igtl_uint64 igtl_export igtl_stt_qtdata_get_crc(igtl_stt_qtdata* stt_qtdata) { igtl_uint64 crc; crc = crc64(0, 0, 0); crc = crc64((unsigned char*) stt_qtdata, IGTL_STT_QTDATA_SIZE, crc); return crc; } igtl_uint64 igtl_export igtl_rts_qtdata_get_crc(igtl_rts_qtdata* rts_qtdata) { igtl_uint64 crc; crc = crc64(0, 0, 0); crc = crc64((unsigned char*) rts_qtdata, IGTL_RTS_QTDATA_SIZE, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_qtdata.h000066400000000000000000000071741501024245700216110ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_QTDATA_H #define __IGTL_QTDATA_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #define IGTL_QTDATA_ELEMENT_SIZE 50 #define IGTL_STT_QTDATA_SIZE 36 #define IGTL_RTS_QTDATA_SIZE 1 #define IGTL_QTDATA_LEN_NAME 20 /* Maximum length of tracking instrument name */ #define IGTL_STT_QTDATA_LEN_COORDNAME 32 /* Maximum length of coordinate system name */ #define IGTL_QTDATA_TYPE_TRACKER 1 /* Tracker */ #define IGTL_QTDATA_TYPE_6D 2 /* 6D instrument (regular instrument) */ #define IGTL_QTDATA_TYPE_3D 3 /* 3D instrument (only tip of the instrument defined) */ #define IGTL_QTDATA_TYPE_5D 4 /* 5D instrument (tip and handle are defined, but not the normal vector) */ #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Status data header for OpenIGTLinik protocol */ typedef struct { char name[IGTL_QTDATA_LEN_NAME]; /* Name of instrument / tracker */ igtl_uint8 type; /* Tracking data type (1-4) */ igtl_uint8 reserved; /* Reserved byte */ igtl_float32 position[3]; /* position (x, y, z) */ igtl_float32 quaternion[4]; /* orientation as quaternion (qx, qy, qz, w) */ } igtl_qtdata_element; typedef struct { igtl_int32 resolution; /* Minimum time between two frames. Use 0 for as fast as possible. */ /* If e.g. 50 ms is specified, the maximum update rate will be 20 Hz. */ char coord_name[IGTL_STT_QTDATA_LEN_COORDNAME]; /* Name of the coordinate system */ } igtl_stt_qtdata; typedef struct { igtl_int8 status; /* 0: Success 1: Error */ } igtl_rts_qtdata; #pragma pack() /** igtl_qtdata_get_data_size(n) calculates the size of body based on the number * of qtdatas. The size of body is used in the message header.*/ #define igtl_qtdata_get_data_size(n) ((n) * IGTL_QTDATA_ELEMENT_SIZE) /** igtl_qtdata_get_data_n(size) calculates the number of qtdatas in the body, based on * the body size. This function may be used when a client program parses a QTDATA message. */ #define igtl_qtdata_get_data_n(size) ((size) / IGTL_QTDATA_ELEMENT_SIZE) /** Byte order conversion for an array of QTDATA, STT_QTDATA and RTS_QTDATA data structure * Converts endianness of each element in an array of igtl_qtdata_element from host byte * order to network byte order, or vice versa. */ void igtl_export igtl_qtdata_convert_byte_order(igtl_qtdata_element* qtdatalist, int nelem); void igtl_export igtl_stt_qtdata_convert_byte_order(igtl_stt_qtdata* stt_qtdata); void igtl_export igtl_rts_qtdata_convert_byte_order(igtl_rts_qtdata* rts_qtdata); /** Calculates CRC of QTDATA, STT_QTDATA and RTS_QTDATA messages */ igtl_uint64 igtl_export igtl_qtdata_get_crc(igtl_qtdata_element* qtdatalist, int nelem); igtl_uint64 igtl_export igtl_stt_qtdata_get_crc(igtl_stt_qtdata* stt_qtdata); igtl_uint64 igtl_export igtl_rts_qtdata_get_crc(igtl_rts_qtdata* rts_qtdata); #ifdef __cplusplus } #endif #endif /* __IGTL_QTDATA_H */ openigtlink-3.0.0/Source/igtlutil/igtl_qtrans.c000066400000000000000000000030011501024245700216170ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include "igtl_qtrans.h" #include "igtl_util.h" #include void igtl_export igtl_qtrans_convert_byte_order(igtl_qtrans* pos) { igtl_uint32 tmp[4]; if (igtl_is_little_endian()) { /* qtrans */ memcpy((void*)tmp, (void*)(pos->qtrans), sizeof(igtl_float32)*3); tmp[0] = BYTE_SWAP_INT32(tmp[0]); tmp[1] = BYTE_SWAP_INT32(tmp[1]); tmp[2] = BYTE_SWAP_INT32(tmp[2]); memcpy((void*)(pos->qtrans), (void*)tmp, sizeof(igtl_float32)*3); /* quaternion */ memcpy((void*)tmp, (void*)(pos->quaternion), sizeof(igtl_float32)*4); tmp[0] = BYTE_SWAP_INT32(tmp[0]); tmp[1] = BYTE_SWAP_INT32(tmp[1]); tmp[2] = BYTE_SWAP_INT32(tmp[2]); tmp[3] = BYTE_SWAP_INT32(tmp[3]); memcpy((void*)(pos->quaternion), (void*)tmp, sizeof(igtl_float32)*4); } } igtl_uint64 igtl_export igtl_qtrans_get_crc(igtl_qtrans* pos) { igtl_uint64 crc = crc64(0, 0, 0); crc = crc64((unsigned char*)pos, IGTL_QTRANS_MESSAGE_DEFAULT_SIZE, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_qtrans.h000066400000000000000000000031061501024245700216320ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_QTRANS_H #define __IGTL_QTRANS_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #define IGTL_QTRANS_MESSAGE_DEFAULT_SIZE 28 /** NOTE: the size varies if orientation is omitted **/ #define IGTL_QTRANS_MESSAGE_POSITON_ONLY_SIZE 12 /* size w/o quaternion */ #define IGTL_QTRANS_MESSAGE_WITH_QUATERNION3_SIZE 24 /* size 3-element quaternion */ #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Status data header for OpenIGTLinik protocol */ typedef struct { igtl_float32 qtrans[3]; /* (x, y, z) */ igtl_float32 quaternion[4]; /* (ox, oy, oz, w) */ } igtl_qtrans; #pragma pack() /** Converts endianness of each member variable in igtl_status_header * from host byte order to network byte order, or vice versa. */ void igtl_export igtl_qtrans_convert_byte_order(igtl_qtrans* pos); /** Calculates CRC of qtrans message */ igtl_uint64 igtl_export igtl_qtrans_get_crc(igtl_qtrans* pos); #ifdef __cplusplus } #endif #endif /* __IGTL_QTRANS_H */ openigtlink-3.0.0/Source/igtlutil/igtl_query.c000066400000000000000000000025111501024245700214610ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_query.h" #include "igtl_util.h" void igtl_export igtl_query_convert_byte_order(igtl_query_header* header) { if (igtl_is_little_endian()) { header->queryID = BYTE_SWAP_INT32(header->queryID); header->deviceUIDLength = BYTE_SWAP_INT16(header->deviceUIDLength); } } igtl_uint64 igtl_export igtl_query_get_crc(igtl_query_header * header, void* query) { igtl_uint64 crc; igtl_uint32 query_length; /* convert byte order to get query length */ igtl_query_convert_byte_order(header); query_length = (igtl_uint32)(header->deviceUIDLength); igtl_query_convert_byte_order(header); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) header, IGTL_QUERY_HEADER_SIZE, crc); crc = crc64((unsigned char*) query, query_length, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_query.h000066400000000000000000000031721501024245700214720ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_QUERY_H #define __IGTL_QUERY_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_win32header.h" #define IGTL_QUERY_HEADER_SIZE 38 #define IGTL_QUERY_DATE_TYPE_SIZE 32 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memory */ typedef struct { igtl_uint32 queryID; /* The unique ID of this QUERY */ igtl_uint8 queryDataType[IGTL_QUERY_DATE_TYPE_SIZE]; /* The query data type of the message */ igtl_uint16 deviceUIDLength; /* Length of DEVICE Name */ } igtl_query_header; #pragma pack() /** Converts endian-ness from host byte order to network byte order, * or vice versa. NOTE: It is developer's responsibility to have the command body with BOM * (byte order mark) or in big endian order. */ void igtl_export igtl_query_convert_byte_order(igtl_query_header * header); /** Calculates CRC of image data body including header * and array of pixel data. */ igtl_uint64 igtl_export igtl_query_get_crc(igtl_query_header * header, void* query); #ifdef __cplusplus } #endif #endif /* __IGTL_QUERY_H */openigtlink-3.0.0/Source/igtlutil/igtl_sensor.c000066400000000000000000000031571501024245700216340ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_sensor.h" #include "igtl_util.h" igtl_uint32 igtl_export igtl_sensor_get_data_size(igtl_sensor_header * header) { igtl_uint32 data_size; data_size = (igtl_uint32)(header->larray) * sizeof(igtl_float64); return data_size; } void igtl_export igtl_sensor_convert_byte_order(igtl_sensor_header* header, igtl_float64* data) { int i; int larray; igtl_uint64* tmp; if (igtl_is_little_endian()) { larray = (int) header->larray; /* NOTE: larray is 8-bit (doesn't depend on endianness) */ header->unit = BYTE_SWAP_INT64(header->unit); tmp = (igtl_uint64*) data; for (i = 0; i < larray; i ++) { tmp[i] = BYTE_SWAP_INT64(tmp[i]); } } } igtl_uint64 igtl_export igtl_sensor_get_crc(igtl_sensor_header * header, igtl_float64* data) { igtl_uint64 crc; igtl_uint64 data_size; data_size = (igtl_uint32)(header->larray) * sizeof(igtl_float64); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) header, IGTL_SENSOR_HEADER_SIZE, crc); crc = crc64((unsigned char*) data, (int)data_size, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_sensor.h000066400000000000000000000032531501024245700216360ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_SENSOR_H #define __IGTL_SENSOR_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_unit.h" #include "igtl_win32header.h" #define IGTL_SENSOR_HEADER_SIZE 10 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ typedef struct { igtl_uint8 larray; /* Length of array (0-255) */ igtl_uint8 status; /* (reserved) sensor status */ igtl_unit unit; /* Unit */ } igtl_sensor_header; #pragma pack() /** This function calculates size of the pixel array, which will be * transferred with the specified header. */ igtl_uint32 igtl_export igtl_sensor_get_data_size(igtl_sensor_header * header); /** This function converts endianness from host byte order to network byte order, * or vice versa. */ void igtl_export igtl_sensor_convert_byte_order(igtl_sensor_header * header, igtl_float64* data); /** Calculates CRC of image data body including header * and array of pixel data. */ igtl_uint64 igtl_export igtl_sensor_get_crc(igtl_sensor_header * header, igtl_float64* data); #ifdef __cplusplus } #endif #endif /* __IGTL_SENSOR_H */ openigtlink-3.0.0/Source/igtlutil/igtl_status.c000066400000000000000000000021401501024245700216350ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include "igtl_status.h" #include "igtl_util.h" #include void igtl_export igtl_status_convert_byte_order(igtl_status_header* status) { if (igtl_is_little_endian()) { status->code = BYTE_SWAP_INT16(status->code); status->subcode = BYTE_SWAP_INT64(status->subcode); } } igtl_uint64 igtl_export igtl_status_get_crc(igtl_status_header* status, igtl_uint32 msglen, const char* msg) { igtl_uint64 crc = crc64(0, 0, 0); crc = crc64((unsigned char*)status, IGTL_STATUS_HEADER_SIZE, crc); crc = crc64((unsigned char*)msg, msglen, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_status.h000066400000000000000000000057521501024245700216560ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_STATUS_H #define __IGTL_STATUS_H #include "igtl_util.h" #include "igtl_types.h" #define IGTL_STATUS_HEADER_SIZE 30 #define IGTL_STATUS_ERROR_NAME_LENGTH 20 /* Status codes */ #define IGTL_STATUS_INVALID 0 #define IGTL_STATUS_OK 1 #define IGTL_STATUS_UNKNOWN_ERROR 2 #define IGTL_STATUS_PANICK_MODE 3 /* emergency */ #define IGTL_STATUS_NOT_FOUND 4 /* file, configuration, device etc */ #define IGTL_STATUS_ACCESS_DENIED 5 #define IGTL_STATUS_BUSY 6 #define IGTL_STATUS_TIME_OUT 7 /* Time out / Connection lost */ #define IGTL_STATUS_OVERFLOW 8 /* Overflow / Can't be reached */ #define IGTL_STATUS_CHECKSUM_ERROR 9 /* Checksum error */ #define IGTL_STATUS_CONFIG_ERROR 10 /* Configuration error */ #define IGTL_STATUS_RESOURCE_ERROR 11 /* Not enough resource (memory, storage etc) */ #define IGTL_STATUS_ILLEGAL_INSTRUCTION 12 /* Illegal/Unknown instruction */ #define IGTL_STATUS_NOT_READY 13 /* Device not ready (starting up)*/ #define IGTL_STATUS_MANUAL_MODE 14 /* Manual mode (device does not accept commands) */ #define IGTL_STATUS_DISABLED 15 /* Device disabled */ #define IGTL_STATUS_NOT_PRESENT 16 /* Device not present */ #define IGTL_STATUS_UNKNOWN_VERSION 17 /* Device version not known */ #define IGTL_STATUS_HARDWARE_FAILURE 18 /* Hardware failure */ #define IGTL_STATUS_SHUT_DOWN 19 /* Exiting / shut down in progress */ #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Status data header for OpenIGTLinik protocol */ typedef struct { igtl_uint16 code; /* status code defined above */ igtl_int64 subcode; /* sub code for the error */ char error_name[IGTL_STATUS_ERROR_NAME_LENGTH]; /* error name -- can be anything, don't rely on this */ /*char status_message[]; */ } igtl_status_header; #pragma pack() /** Converts endianness of each member variable * in igtl_status_header from host byte order to network byte order, * or vice versa. */ void igtl_export igtl_status_convert_byte_order(igtl_status_header* status); /** Calculates CRC of status data body including status message part */ igtl_uint64 igtl_export igtl_status_get_crc(igtl_status_header* status, igtl_uint32 msglen, const char* msg); #ifdef __cplusplus } #endif #endif /* __IGTL_IMAGE_H */ openigtlink-3.0.0/Source/igtlutil/igtl_string.c000066400000000000000000000027571501024245700216360ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_string.h" #include "igtl_util.h" igtl_uint32 igtl_export igtl_string_get_string_length(igtl_string_header * header) { igtl_uint32 length; length = (igtl_uint32)(header->length); return length; } void igtl_export igtl_string_convert_byte_order(igtl_string_header* header) { if (igtl_is_little_endian()) { header->encoding = BYTE_SWAP_INT16(header->encoding); header->length = BYTE_SWAP_INT16(header->length); } } igtl_uint64 igtl_export igtl_string_get_crc(igtl_string_header * header, void* string) { igtl_uint64 crc; igtl_uint64 string_length; /* convert byte order to get string length */ igtl_string_convert_byte_order(header); string_length = (igtl_uint32)(header->length); igtl_string_convert_byte_order(header); crc = crc64(0, 0, 0); crc = crc64((unsigned char*) header, IGTL_STRING_HEADER_SIZE, crc); crc = crc64((unsigned char*) string, (int)string_length, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_string.h000066400000000000000000000035031501024245700216310ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_STRING_H #define __IGTL_STRING_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #include "igtl_win32header.h" #define IGTL_STRING_HEADER_SIZE 4 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ typedef struct { igtl_uint16 encoding; /* Character encoding type as MIBenum value (defined by IANA). Default=3. */ /* Please refer http://www.iana.org/assignments/character-sets for detail */ igtl_uint16 length; /* Length of string */ } igtl_string_header; #pragma pack() /** Calculates size of the pixel array, which will be * transferred with the specified header. */ igtl_uint32 igtl_export igtl_string_get_string_length(igtl_string_header * header); /** Converts endianness from host byte order to network byte order, * or vice versa. NOTE: It is developer's responsibility to have the string body with BOM * (byte order mark) or in big endian ordrer. */ void igtl_export igtl_string_convert_byte_order(igtl_string_header * header); /** Calculates CRC of image data body including header * and array of pixel data. */ igtl_uint64 igtl_export igtl_string_get_crc(igtl_string_header * header, void* string); #ifdef __cplusplus } #endif #endif /* __IGTL_STRING_H */ openigtlink-3.0.0/Source/igtlutil/igtl_tdata.c000066400000000000000000000040731501024245700214160ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_tdata.h" #include "igtl_util.h" void igtl_export igtl_tdata_convert_byte_order(igtl_tdata_element* tdatalist, int nitem) { igtl_tdata_element* elem; int i; int j; igtl_int32* tmp; for (i = 0; i < nitem; i ++) { elem = &(tdatalist[i]); if (igtl_is_little_endian()) { for (j = 0; j < 12; j ++) { tmp = (igtl_int32*)&(elem->transform[j]); *tmp = BYTE_SWAP_INT32(*tmp); } } } } void igtl_export igtl_stt_tdata_convert_byte_order(igtl_stt_tdata* stt_tdata) { igtl_int32* tmp; if (igtl_is_little_endian()) { tmp = (igtl_int32*)&(stt_tdata->resolution); *tmp = BYTE_SWAP_INT32(*tmp); } } void igtl_export igtl_rts_tdata_convert_byte_order(igtl_rts_tdata* rts_tdata) { /* do nothing */ } igtl_uint64 igtl_export igtl_tdata_get_crc(igtl_tdata_element* tdatalist, int nitem) { igtl_tdata_element* elem; int i; igtl_uint64 crc; crc = crc64(0, 0, 0); for (i = 0; i < nitem; i ++) { elem = &(tdatalist[i]); crc = crc64((unsigned char*) elem, IGTL_TDATA_ELEMENT_SIZE, crc); } return crc; } igtl_uint64 igtl_export igtl_stt_tdata_get_crc(igtl_stt_tdata* stt_tdata) { igtl_uint64 crc; crc = crc64(0, 0, 0); crc = crc64((unsigned char*) stt_tdata, IGTL_STT_TDATA_SIZE, crc); return crc; } igtl_uint64 igtl_export igtl_rts_tdata_get_crc(igtl_rts_tdata* rts_tdata) { igtl_uint64 crc; crc = crc64(0, 0, 0); crc = crc64((unsigned char*) rts_tdata, IGTL_RTS_TDATA_SIZE, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_tdata.h000066400000000000000000000066421501024245700214270ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TDATA_H #define __IGTL_TDATA_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #define IGTL_TDATA_ELEMENT_SIZE 70 #define IGTL_STT_TDATA_SIZE 36 #define IGTL_RTS_TDATA_SIZE 1 #define IGTL_TDATA_LEN_NAME 20 /* Maximum length of tracking instrument name */ #define IGTL_STT_TDATA_LEN_COORDNAME 32 /* Maximum length of coordinate system name */ #define IGTL_TDATA_TYPE_TRACKER 1 /* Tracker */ #define IGTL_TDATA_TYPE_6D 2 /* 6D instrument (regular instrument) */ #define IGTL_TDATA_TYPE_3D 3 /* 3D instrument (only tip of the instrument defined) */ #define IGTL_TDATA_TYPE_5D 4 /* 5D instrument (tip and handle are defined, but not the normal vector) */ #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Status data header for OpenIGTLinik protocol */ typedef struct { char name[IGTL_TDATA_LEN_NAME]; /* Name of instrument / tracker */ igtl_uint8 type; /* Tracking data type (1-4) */ igtl_uint8 reserved; /* Reserved byte */ igtl_float32 transform[12]; /* same as TRANSFORM */ } igtl_tdata_element; typedef struct { igtl_int32 resolution; /* Minimum time between two frames. Use 0 for as fast as possible. */ /* If e.g. 50 ms is specified, the maximum update rate will be 20 Hz. */ char coord_name[IGTL_STT_TDATA_LEN_COORDNAME]; /* Name of the coordinate system */ } igtl_stt_tdata; typedef struct { igtl_int8 status; /* 0: Success 1: Error */ } igtl_rts_tdata; #pragma pack() /** igtl_tdata_get_data_size(n) calculates the size of body based on the number * of tdatas. The size of body is used in the message header.*/ #define igtl_tdata_get_data_size(n) ((n) * IGTL_TDATA_ELEMENT_SIZE) /** igtl_tdata_get_data_n(size) calculates the number of tdatas in the body, based on * the body size. This function may be used when a client program parses a TDATA message. */ #define igtl_tdata_get_data_n(size) ((size) / IGTL_TDATA_ELEMENT_SIZE) /** Converts endianness of each element in an array of * igtl_tdata_element from host byte order to network byte order, * or vice versa.*/ void igtl_export igtl_tdata_convert_byte_order(igtl_tdata_element* tdatalist, int nelem); void igtl_export igtl_stt_tdata_convert_byte_order(igtl_stt_tdata* stt_tdata); void igtl_export igtl_rts_tdata_convert_byte_order(igtl_rts_tdata* rts_tdata); /** Calculates CRC of TDATA, STT_TDATA and RTS_TDATA messages.*/ igtl_uint64 igtl_export igtl_tdata_get_crc(igtl_tdata_element* tdatalist, int nelem); igtl_uint64 igtl_export igtl_stt_tdata_get_crc(igtl_stt_tdata* stt_tdata); igtl_uint64 igtl_export igtl_rts_tdata_get_crc(igtl_rts_tdata* rts_tdata); #ifdef __cplusplus } #endif #endif /* __IGTL_TDATA_H */ openigtlink-3.0.0/Source/igtlutil/igtl_trajectory.c000066400000000000000000000030561501024245700225070ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_trajectory.h" #include "igtl_util.h" void igtl_export igtl_trajectory_convert_byte_order(igtl_trajectory_element* trajectorylist, int nitem) { igtl_trajectory_element* elem; int i; int j; igtl_int32* tmp; for (i = 0; i < nitem; i ++) { elem = &(trajectorylist[i]); if (igtl_is_little_endian()) { for (j = 0; j < 3; j ++) { tmp = (igtl_int32*)&(elem->entry_pos[j]); *tmp = BYTE_SWAP_INT32(*tmp); tmp = (igtl_int32*)&(elem->target_pos[j]); *tmp = BYTE_SWAP_INT32(*tmp); } tmp = (igtl_int32*)&(elem->radius); *tmp = BYTE_SWAP_INT32(*tmp); } } } igtl_uint64 igtl_export igtl_trajectory_get_crc(igtl_trajectory_element* trajectorylist, int nitem) { igtl_trajectory_element* elem; int i; igtl_uint64 crc; crc = crc64(0, 0, 0); for (i = 0; i < nitem; i ++) { elem = &(trajectorylist[i]); crc = crc64((unsigned char*) elem, IGTL_TRAJECTORY_ELEMENT_SIZE, crc); } return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_trajectory.h000066400000000000000000000054721501024245700225200ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TRAJECTORY_H #define __IGTL_TRAJECTORY_H #include "igtl_win32header.h" #include "igtl_util.h" #include "igtl_types.h" #define IGTL_TRAJECTORY_ELEMENT_SIZE 150 #define IGTL_TRAJECTORY_LEN_NAME 64 #define IGTL_TRAJECTORY_LEN_GROUP_NAME 32 #define IGTL_TRAJECTORY_LEN_OWNER 20 #define IGTL_TRAJECTORY_TYPE_ENTRY_ONLY 1 #define IGTL_TRAJECTORY_TYPE_TARGET_ONLY 2 #define IGTL_TRAJECTORY_TYPE_ENTRY_TARGET 3 #ifdef __cplusplus extern "C" { #endif #pragma pack(1) /* For 1-byte boundary in memroy */ /** Status data header for OpenIGTLinik protocol */ typedef struct { char name[IGTL_TRAJECTORY_LEN_NAME]; /* Name or description of the trajectory */ char group_name[IGTL_TRAJECTORY_LEN_GROUP_NAME]; /* Can be "Trajectory", ... */ igtl_int8 type; /* Trajectory type (see IGTL_TRAJECTORY_TYPE_* macros) */ igtl_int8 reserved; igtl_uint8 rgba[4]; /* Color in R/G/B/A */ igtl_float32 entry_pos[3]; /* Coordinate of the entry point */ igtl_float32 target_pos[3]; /* Coordinate of the target point */ igtl_float32 radius; /* Radius of the trajectory. Can be 0. */ char owner_name[IGTL_TRAJECTORY_LEN_OWNER]; /* Device name of the ower image */ } igtl_trajectory_element; #pragma pack() /** igtl_trajectory_get_data_size(n) calculates the size of body based on the number * of trajectorys. The size of body is used in the message header. */ #define igtl_trajectory_get_data_size(n) ((n) * IGTL_TRAJECTORY_ELEMENT_SIZE) /** igtl_trajectory_get_data_n(size) calculates the number of images in the body, based on * the body size. This function may be used when a client program parses a TRAJECTORY message. */ #define igtl_trajectory_get_data_n(size) ((size) / IGTL_TRAJECTORY_ELEMENT_SIZE) /** Converts endianness of each element in an array of * igtl_igtl_trajectory_element from host byte order to network byte order, * or vice versa. */ void igtl_export igtl_trajectory_convert_byte_order(igtl_trajectory_element* trajectorylist, int nelem); /** Calculates CRC of trajectory message */ igtl_uint64 igtl_export igtl_trajectory_get_crc(igtl_trajectory_element* trajectorylist, int nelem); #ifdef __cplusplus } #endif #endif /* __IGTL_POSITION_H */ openigtlink-3.0.0/Source/igtlutil/igtl_transform.c000066400000000000000000000022321501024245700223270ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include "igtl_transform.h" #include "igtl_util.h" /*#include "crc32.h"*/ #include void igtl_export igtl_transform_convert_byte_order(igtl_float32* transform) { int i; igtl_uint32 tmp[12]; if (igtl_is_little_endian()) { memcpy(tmp, transform, sizeof(igtl_uint32)*12); for (i = 0; i < 12; i ++) { tmp[i] = BYTE_SWAP_INT32(tmp[i]); } memcpy(transform, tmp, sizeof(igtl_uint32)*12); } } igtl_uint64 igtl_export igtl_transform_get_crc(igtl_float32* transform) { igtl_uint64 crc = crc64(0, 0, 0); crc = crc64((unsigned char*)transform, sizeof(igtl_float32)*12, crc); return crc; } openigtlink-3.0.0/Source/igtlutil/igtl_transform.h000066400000000000000000000021531501024245700223360ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TRANSFORM_H #define __IGTL_TRANSFORM_H #include "igtl_win32header.h" #include "igtl_util.h" #define IGTL_TRANSFORM_SIZE 48 #ifdef __cplusplus extern "C" { #endif /* typedef igtl_float32[12] transform; */ /** Converts endianness of each member variable * in igtl_image_header from host byte order to network byte order, * or vice versa. */ void igtl_export igtl_transform_convert_byte_order(igtl_float32* transform); /** Calculates CRC of transform data. */ igtl_uint64 igtl_export igtl_transform_get_crc(igtl_float32* transform); #ifdef __cplusplus } #endif #endif /*__IGTL_TRANSFORM_H*/ openigtlink-3.0.0/Source/igtlutil/igtl_types.h000066400000000000000000000244641501024245700215000ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TYPES_H #define __IGTL_TYPES_H #include "igtl_typeconfig.h" enum IANA_ENCODING_TYPE { IANA_TYPE_US_ASCII = 3, IANA_TYPE_ISO_8859_1 = 4, IANA_TYPE_ISO_8859_2 = 5, IANA_TYPE_ISO_8859_3 = 6, IANA_TYPE_ISO_8859_4 = 7, IANA_TYPE_ISO_8859_5 = 8, IANA_TYPE_ISO_8859_6 = 9, IANA_TYPE_ISO_8859_7 = 10, IANA_TYPE_ISO_8859_8 = 11, IANA_TYPE_ISO_8859_9 = 12, IANA_TYPE_ISO_8859_10 = 13, IANA_TYPE_ISO_6937_2_add = 14, IANA_TYPE_JIS_X0201 = 15, IANA_TYPE_JIS_Encoding = 16, IANA_TYPE_Shift_JIS = 17, IANA_TYPE_EUC_JP = 18, IANA_TYPE_Extended_UNIX_Code_Fixed_Width_for_Japanese = 19, IANA_TYPE_BS_4730 = 20, IANA_TYPE_SEN_850200_C = 21, IANA_TYPE_IT = 22, IANA_TYPE_ES = 23, IANA_TYPE_DIN_66003 = 24, IANA_TYPE_NS_4551_1 = 25, IANA_TYPE_NF_Z_62_010 = 26, IANA_TYPE_ISO_10646_UTF_1 = 27, IANA_TYPE_ISO_646_basic_1983 = 28, IANA_TYPE_INVARIANT = 29, IANA_TYPE_ISO_646_irv_1983 = 30, IANA_TYPE_NATS_SEFI = 31, IANA_TYPE_NATS_SEFI_ADD = 32, IANA_TYPE_NATS_DANO = 33, IANA_TYPE_NATS_DANO_ADD = 34, IANA_TYPE_SEN_850200_B = 35, IANA_TYPE_KS_C_5601_1987 = 36, IANA_TYPE_ISO_2022_KR = 37, IANA_TYPE_EUC_KR = 38, IANA_TYPE_ISO_2022_JP = 39, IANA_TYPE_ISO_2022_JP_2 = 40, IANA_TYPE_JIS_C6220_1969_jp = 41, IANA_TYPE_JIS_C6220_1969_ro = 42, IANA_TYPE_PT = 43, IANA_TYPE_greek7_old = 44, IANA_TYPE_latin_greek = 45, IANA_TYPE_NF_Z_62_010_1973 = 46, IANA_TYPE_Latin_greek_1 = 47, IANA_TYPE_ISO_5427 = 48, IANA_TYPE_JIS_C6226_1978 = 49, IANA_TYPE_BS_viewdata = 50, IANA_TYPE_INIS = 51, IANA_TYPE_INIS_8 = 52, IANA_TYPE_INIS_cyrillic = 53, IANA_TYPE_ISO_5427_1981 = 54, IANA_TYPE_ISO_5428_1980 = 55, IANA_TYPE_GB_1988_80 = 56, IANA_TYPE_GB_2312_80 = 57, IANA_TYPE_NS_4551_2 = 58, IANA_TYPE_videotex_suppl = 59, IANA_TYPE_PT2 = 60, IANA_TYPE_ES2 = 61, IANA_TYPE_MSZ_7795_3 = 62, IANA_TYPE_JIS_C6226_1983 = 63, IANA_TYPE_greek7 = 64, IANA_TYPE_ASMO_449 = 65, IANA_TYPE_iso_ir_90 = 66, IANA_TYPE_JIS_C6229_1984_a = 67, IANA_TYPE_JIS_C6229_1984_b = 68, IANA_TYPE_JIS_C6229_1984_b_add = 69, IANA_TYPE_JIS_C6229_1984_hand = 70, IANA_TYPE_JIS_C6229_1984_hand_add = 71, IANA_TYPE_JIS_C6229_1984_kana = 72, IANA_TYPE_ISO_2033_1983 = 73, IANA_TYPE_ANSI_X3_110_1983 = 74, IANA_TYPE_T_61_7bit = 75, IANA_TYPE_T_61_8bit = 76, IANA_TYPE_ECMA_cyrillic = 77, IANA_TYPE_CSA_Z243_4_1985_1 = 78, IANA_TYPE_CSA_Z243_4_1985_2 = 79, IANA_TYPE_CSA_Z243_4_1985_gr = 80, IANA_TYPE_ISO_8859_6_E = 81, IANA_TYPE_ISO_8859_6_I = 82, IANA_TYPE_T_101_G2 = 83, IANA_TYPE_ISO_8859_8_E = 84, IANA_TYPE_ISO_8859_8_I = 85, IANA_TYPE_CSN_369103 = 86, IANA_TYPE_JUS_I_B1_002 = 87, IANA_TYPE_IEC_P27_1 = 88, IANA_TYPE_JUS_I_B1_003_serb = 89, IANA_TYPE_JUS_I_B1_003_mac = 90, IANA_TYPE_greek_ccitt = 91, IANA_TYPE_NC_NC00_10_81 = 92, IANA_TYPE_ISO_6937_2_25 = 93, IANA_TYPE_GOST_19768_74 = 94, IANA_TYPE_ISO_8859_supp = 95, IANA_TYPE_ISO_10367_box = 96, IANA_TYPE_latin_lap = 97, IANA_TYPE_JIS_X0212_1990 = 98, IANA_TYPE_DS_2089 = 99, IANA_TYPE_us_dk = 100, IANA_TYPE_dk_us = 101, IANA_TYPE_KSC5636 = 102, IANA_TYPE_UNICODE_1_1_UTF_7 = 103, IANA_TYPE_ISO_2022_CN = 104, IANA_TYPE_ISO_2022_CN_EXT = 105, IANA_TYPE_UTF_8 = 106, IANA_TYPE_ISO_8859_13 = 109, IANA_TYPE_ISO_8859_14 = 110, IANA_TYPE_ISO_8859_15 = 111, IANA_TYPE_ISO_8859_16 = 112, IANA_TYPE_GBK = 113, IANA_TYPE_GB18030 = 114, IANA_TYPE_OSD_EBCDIC_DF04_15 = 115, IANA_TYPE_OSD_EBCDIC_DF03_IRV = 116, IANA_TYPE_OSD_EBCDIC_DF04_1 = 117, IANA_TYPE_ISO_11548_1 = 118, IANA_TYPE_KZ_1048 = 119, IANA_TYPE_ISO_10646_UCS_2 = 1000, IANA_TYPE_ISO_10646_UCS_4 = 1001, IANA_TYPE_ISO_10646_UCS_Basic = 1002, IANA_TYPE_ISO_10646_Unicode_Latin1 = 1003, IANA_TYPE_ISO_10646_J_1 = 1004, IANA_TYPE_ISO_Unicode_IBM_1261 = 1005, IANA_TYPE_ISO_Unicode_IBM_1268 = 1006, IANA_TYPE_ISO_Unicode_IBM_1276 = 1007, IANA_TYPE_ISO_Unicode_IBM_1264 = 1008, IANA_TYPE_ISO_Unicode_IBM_1265 = 1009, IANA_TYPE_UNICODE_1_1 = 1010, IANA_TYPE_SCSU = 1011, IANA_TYPE_UTF_7 = 1012, IANA_TYPE_UTF_16BE = 1013, IANA_TYPE_UTF_16LE = 1014, IANA_TYPE_UTF_16 = 1015, IANA_TYPE_CESU_8 = 1016, IANA_TYPE_UTF_32 = 1017, IANA_TYPE_UTF_32BE = 1018, IANA_TYPE_UTF_32LE = 1019, IANA_TYPE_BOCU_1 = 1020, IANA_TYPE_ISO_8859_1_Windows_3_0_Latin_1 = 2000, IANA_TYPE_ISO_8859_1_Windows_3_1_Latin_1 = 2001, IANA_TYPE_ISO_8859_2_Windows_Latin_2 = 2002, IANA_TYPE_ISO_8859_9_Windows_Latin_5 = 2003, IANA_TYPE_hp_roman8 = 2004, IANA_TYPE_Adobe_Standard_Encoding = 2005, IANA_TYPE_Ventura_US = 2006, IANA_TYPE_Ventura_International = 2007, IANA_TYPE_DEC_MCS = 2008, IANA_TYPE_IBM850 = 2009, IANA_TYPE_PC8_Danish_Norwegian = 2012, IANA_TYPE_IBM862 = 2013, IANA_TYPE_PC8_Turkish = 2014, IANA_TYPE_IBM_Symbols = 2015, IANA_TYPE_IBM_Thai = 2016, IANA_TYPE_HP_Legal = 2017, IANA_TYPE_HP_Pi_font = 2018, IANA_TYPE_HP_Math8 = 2019, IANA_TYPE_Adobe_Symbol_Encoding = 2020, IANA_TYPE_HP_DeskTop = 2021, IANA_TYPE_Ventura_Math = 2022, IANA_TYPE_Microsoft_Publishing = 2023, IANA_TYPE_Windows_31J = 2024, IANA_TYPE_GB2312 = 2025, IANA_TYPE_Big5 = 2026, IANA_TYPE_macintosh = 2027, IANA_TYPE_IBM037 = 2028, IANA_TYPE_IBM038 = 2029, IANA_TYPE_IBM273 = 2030, IANA_TYPE_IBM274 = 2031, IANA_TYPE_IBM275 = 2032, IANA_TYPE_IBM277 = 2033, IANA_TYPE_IBM278 = 2034, IANA_TYPE_IBM280 = 2035, IANA_TYPE_IBM281 = 2036, IANA_TYPE_IBM284 = 2037, IANA_TYPE_IBM285 = 2038, IANA_TYPE_IBM290 = 2039, IANA_TYPE_IBM297 = 2040, IANA_TYPE_IBM420 = 2041, IANA_TYPE_IBM423 = 2042, IANA_TYPE_IBM424 = 2043, IANA_TYPE_IBM437 = 2011, IANA_TYPE_IBM500 = 2044, IANA_TYPE_IBM851 = 2045, IANA_TYPE_IBM852 = 2010, IANA_TYPE_IBM855 = 2046, IANA_TYPE_IBM857 = 2047, IANA_TYPE_IBM860 = 2048, IANA_TYPE_IBM861 = 2049, IANA_TYPE_IBM863 = 2050, IANA_TYPE_IBM864 = 2051, IANA_TYPE_IBM865 = 2052, IANA_TYPE_IBM868 = 2053, IANA_TYPE_IBM869 = 2054, IANA_TYPE_IBM870 = 2055, IANA_TYPE_IBM871 = 2056, IANA_TYPE_IBM880 = 2057, IANA_TYPE_IBM891 = 2058, IANA_TYPE_IBM903 = 2059, IANA_TYPE_IBM904 = 2060, IANA_TYPE_IBM905 = 2061, IANA_TYPE_IBM918 = 2062, IANA_TYPE_IBM1026 = 2063, IANA_TYPE_EBCDIC_AT_DE = 2064, IANA_TYPE_EBCDIC_AT_DE_A = 2065, IANA_TYPE_EBCDIC_CA_FR = 2066, IANA_TYPE_EBCDIC_DK_NO = 2067, IANA_TYPE_EBCDIC_DK_NO_A = 2068, IANA_TYPE_EBCDIC_FI_SE = 2069, IANA_TYPE_EBCDIC_FI_SE_A = 2070, IANA_TYPE_EBCDIC_FR = 2071, IANA_TYPE_EBCDIC_IT = 2072, IANA_TYPE_EBCDIC_PT = 2073, IANA_TYPE_EBCDIC_ES = 2074, IANA_TYPE_EBCDIC_ES_A = 2075, IANA_TYPE_EBCDIC_ES_S = 2076, IANA_TYPE_EBCDIC_UK = 2077, IANA_TYPE_EBCDIC_US = 2078, IANA_TYPE_UNKNOWN_8BIT = 2079, IANA_TYPE_MNEMONIC = 2080, IANA_TYPE_MNEM = 2081, IANA_TYPE_VISCII = 2082, IANA_TYPE_VIQR = 2083, IANA_TYPE_KOI8_R = 2084, IANA_TYPE_HZ_GB_2312 = 2085, IANA_TYPE_IBM866 = 2086, IANA_TYPE_IBM775 = 2087, IANA_TYPE_KOI8_U = 2088, IANA_TYPE_IBM00858 = 2089, IANA_TYPE_IBM00924 = 2090, IANA_TYPE_IBM01140 = 2091, IANA_TYPE_IBM01141 = 2092, IANA_TYPE_IBM01142 = 2093, IANA_TYPE_IBM01143 = 2094, IANA_TYPE_IBM01144 = 2095, IANA_TYPE_IBM01145 = 2096, IANA_TYPE_IBM01146 = 2097, IANA_TYPE_IBM01147 = 2098, IANA_TYPE_IBM01148 = 2099, IANA_TYPE_IBM01149 = 2100, IANA_TYPE_Big5_HKSCS = 2101, IANA_TYPE_IBM1047 = 2102, IANA_TYPE_PTCP154 = 2103, IANA_TYPE_Amiga_1251 = 2104, IANA_TYPE_KOI7_switched = 2105, IANA_TYPE_BRF = 2106, IANA_TYPE_TSCII = 2107, IANA_TYPE_CP51932 = 2108, IANA_TYPE_windows_874 = 2109, IANA_TYPE_windows_1250 = 2250, IANA_TYPE_windows_1251 = 2251, IANA_TYPE_windows_1252 = 2252, IANA_TYPE_windows_1253 = 2253, IANA_TYPE_windows_1254 = 2254, IANA_TYPE_windows_1255 = 2255, IANA_TYPE_windows_1256 = 2256, IANA_TYPE_windows_1257 = 2257, IANA_TYPE_windows_1258 = 2258, IANA_TYPE_TIS_620 = 2259, IANA_TYPE_CP50220 = 2260 }; /* 8-bit integer type */ #if IGTL_SIZEOF_CHAR == 1 typedef unsigned char igtl_uint8; typedef signed char igtl_int8; #else # error "No native data type can represent an 8-bit integer." #endif /* 16-bit integer type */ #if IGTL_SIZEOF_SHORT == 2 typedef unsigned short igtl_uint16; typedef signed short igtl_int16; #elif IGTL_SIZEOF_INT == 2 typedef unsigned int igtl_uint16; typedef signed int igtl_int16; #else # error "No native data type can represent a 16-bit integer." #endif /* 32-bit integer type */ #if IGTL_SIZEOF_INT == 4 typedef unsigned int igtl_uint32; typedef signed int igtl_int32; #elif IGTL_SIZEOF_LONG == 4 typedef unsigned long igtl_uint32; typedef signed long igtl_int32; #else # error "No native data type can represent a 32-bit integer." #endif /* 64-bit integer type */ #if defined(IGTL_TYPE_USE_LONG_LONG) && IGTL_SIZEOF_LONG_LONG == 8 typedef unsigned long long igtl_uint64; typedef signed long long igtl_int64; #elif IGTL_SIZEOF_INT == 8 typedef unsigned int igtl_uint64; typedef signed int igtl_int64; #elif IGTL_SIZEOF_LONG == 8 typedef unsigned long igtl_uint64; typedef signed long igtl_int64; #elif defined(IGTL_TYPE_USE___INT64) && IGTL_SIZEOF___INT64 == 8 typedef unsigned __int64 igtl_uint64; typedef signed __int64 igtl_int64; #elif defined(IGTL_TYPE_USE_INT64_T) && IGTL_SIZEOF_INT64_T == 8 typedef unsigned int64_t igtl_uint64; typedef signed int64_t igtl_int64; #else # error "No native data type can represent a 64-bit integer." #endif /* 32-bit floating point type */ #if IGTL_SIZEOF_FLOAT == 4 typedef float igtl_float32; #else # error "No native data type can represent a 32-bit floating point value." #endif /* 64-bit floating point type */ #if IGTL_SIZEOF_DOUBLE == 8 typedef double igtl_float64; #else # error "No native data type can represent a 64-bit floating point value." #endif /* 128-bit complex type (64-bit real + 64-bit imaginal)*/ typedef double igtl_complex[2]; #endif /* __IGTL_TYPES_H */ openigtlink-3.0.0/Source/igtlutil/igtl_unit.c000066400000000000000000000035101501024245700212730ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_unit.h" #include "igtl_util.h" void igtl_export igtl_unit_init(igtl_unit_data* data) { int i; data->prefix = 0; for (i = 0; i < 6; i ++) { data->unit[i] = 0; data->exp[i] = 0; } } igtl_unit igtl_export igtl_unit_pack(igtl_unit_data* data) { igtl_unit pack; igtl_uint8 exp; int i; pack = 0x0; /* Prefix */ pack |= ((igtl_uint64) data->prefix) << 60; /* Units */ for (i = 0; i < 6; i ++) { /* Check if exp is within the valid range */ if (data->exp[i] < -7 || data->exp[i] > 7) { return 0; } /* Convert signed value from 8-bit to 4-bit */ exp = data->exp[i] & 0x0F; /* put into the pack */ pack |= ((igtl_uint64)data->unit[i]) << (10*(5-i) + 4); pack |= ((igtl_uint64)exp) << (10*(5-i)); } return pack; } int igtl_export igtl_unit_unpack(igtl_unit pack, igtl_unit_data* data) { int i; /* Prefix */ data->prefix = (igtl_uint8) (pack >> 60); /* Units */ for (i = 0; i < 6; i ++) { data->unit[i] = (igtl_uint8) (pack >> (10*(5-i) + 4)) & 0x3F; data->exp[i] = (igtl_uint8) (pack >> (10*(5-i))) & 0x0F; /* Convert signed value in exponent field from 4-bit to 8-bit */ if (data->exp[i] & 0x08) { data->exp[i] |= 0xF0; } } return 1; } openigtlink-3.0.0/Source/igtlutil/igtl_unit.h000066400000000000000000000100751501024245700213040ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_UNIT_H #define __IGTL_UNIT_H #include "igtl_types.h" #include "igtl_win32header.h" #include "igtl_unit.h" /* PREFIX */ #define IGTL_UNIT_PREFIX_NONE 0x0 /* None */ #define IGTL_UNIT_PREFIX_DEKA 0x1 /* deka (deca) (1e1) */ #define IGTL_UNIT_PREFIX_HECTO 0x2 /* hecto (1e2) */ #define IGTL_UNIT_PREFIX_KILO 0x3 /* kilo (1e3) */ #define IGTL_UNIT_PREFIX_MEGA 0x4 /* mega (1e6) */ #define IGTL_UNIT_PREFIX_GIGA 0x5 /* giga (1e9) */ #define IGTL_UNIT_PREFIX_TERA 0x6 /* tera (1e12) */ #define IGTL_UNIT_PREFIX_PETA 0x7 /* peta (1e15) */ #define IGTL_UNIT_PREFIX_DECI 0x9 /* deci (1e-1) */ #define IGTL_UNIT_PREFIX_CENTI 0xA /* centi (1e-2) */ #define IGTL_UNIT_PREFIX_MILLI 0xB /* milli (1e-3) */ #define IGTL_UNIT_PREFIX_MICRO 0xC /* micro (1e-6) */ #define IGTL_UNIT_PREFIX_NANO 0xD /* nano (1e-9) */ #define IGTL_UNIT_PREFIX_PICO 0xE /* pico (1e-12) */ #define IGTL_UNIT_PREFIX_FEMTO 0xF /* femto (1e-15) */ /* SI Base Units */ #define IGTL_UNIT_SI_BASE_NONE 0x00 #define IGTL_UNIT_SI_BASE_METER 0x01 /* meter */ #define IGTL_UNIT_SI_BASE_GRAM 0x02 /* gram */ #define IGTL_UNIT_SI_BASE_SECOND 0x03 /* second */ #define IGTL_UNIT_SI_BASE_AMPERE 0x04 /* ampere */ #define IGTL_UNIT_SI_BASE_KELVIN 0x05 /* kelvin */ #define IGTL_UNIT_SI_BASE_MOLE 0x06 /* mole */ #define IGTL_UNIT_SI_BASE_CANDELA 0x07 /* candela */ /* SI Derived Units */ #define IGTL_UNIT_SI_DERIVED_RADIAN 0x08 /* radian meter/meter */ #define IGTL_UNIT_SI_DERIVED_STERADIAN 0x09 /* steradian meter^2/meter^2 */ #define IGTL_UNIT_SI_DERIVED_HERTZ 0x0A /* hertz /second */ #define IGTL_UNIT_SI_DERIVED_NEWTON 0x0B /* newton meter-kilogram/second^2 */ #define IGTL_UNIT_SI_DERIVED_PASCAL 0x0C /* pascal kilogram/meter-second^2 */ #define IGTL_UNIT_SI_DERIVED_JOULE 0x0D /* joule meter^2-kilogram/second^2 */ #define IGTL_UNIT_SI_DERIVED_WATT 0x0E /* watt meter^2-kilogram/second^3 */ #define IGTL_UNIT_SI_DERIVED_COULOMB 0x0F /* coulomb second-ampere */ #define IGTL_UNIT_SI_DERIVED_VOLT 0x10 /* volt meter^2-kilogram/second^3-ampere */ #define IGTL_UNIT_SI_DERIVED_FARAD 0x11 /* farad second^4-ampere^2/meter^2-kilogram */ #define IGTL_UNIT_SI_DERIVED_OHM 0x12 /* ohm meter^2-kilogram/second^3-ampere^2 */ #define IGTL_UNIT_SI_DERIVED_SIEMENS 0x13 /* siemens second^3-ampere^2/meter^2-kilogram */ #define IGTL_UNIT_SI_DERIVED_WEBER 0x14 /* weber meter^2-kilogram/second^2-ampere */ #define IGTL_UNIT_SI_DERIVED_TESLA 0x15 /* tesla kilogram/second^2-ampere */ #define IGTL_UNIT_SI_DERIVED_HENRY 0x16 /* henry meter^2-kilogram/second^2-ampere^2 */ #define IGTL_UNIT_SI_DERIVED_LUMEN 0x17 /* lumen candela-steradian */ #define IGTL_UNIT_SI_DERIVED_LUX 0x18 /* lux candela-steradian/meter^2 */ #define IGTL_UNIT_SI_DERIVED_BECQUEREL 0x19 /* becquerel /second */ #define IGTL_UNIT_SI_DERIVED_GRAY 0x1A /* gray meter^2/second^2 */ #define IGTL_UNIT_SI_DERIVED_SIEVERT 0x1B /* sievert meter^2/second^2 */ typedef igtl_uint64 igtl_unit; #ifdef __cplusplus extern "C" { #endif typedef struct { igtl_uint8 prefix; /* Prefix */ igtl_uint8 unit[6]; /* Either SI-Base or SI-Derived */ igtl_int8 exp[6]; /* Must be within [-7, 7] */ } igtl_unit_data; void igtl_export igtl_unit_init(igtl_unit_data* data); igtl_unit igtl_export igtl_unit_pack(igtl_unit_data* data); int igtl_export igtl_unit_unpack(igtl_unit pack, igtl_unit_data* data); #ifdef __cplusplus } #endif #endif /* __IGTL_UNIT_H */ openigtlink-3.0.0/Source/igtlutil/igtl_util.c000066400000000000000000000215621501024245700213000ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_util.h" int igtl_export igtl_is_little_endian() { short a = 1; return ((char*)&a)[0]; } igtl_uint64 igtl_export crc64(unsigned char *data, igtl_uint64 len, igtl_uint64 crc) { static const igtl_uint64 table[256] = { 0x0000000000000000ULL,0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL,0x0BC387AEA7A8DA4CULL, 0xCCD2A5925D9681F9ULL,0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL,0x5577EEB6E6BB820BULL, 0xDB55AACF12C73561ULL,0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL,0x24CD9914390BB37CULL, 0xE3DCBB28C335E8C9ULL,0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL,0xE81F3C86649D3285ULL, 0xF45BB4758C645C51ULL,0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL,0xFF9833DB2BCC861DULL, 0x388911E7D1F2DDA8ULL,0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,0x8E8A101488293D4DULL, 0x499B3228721766F8ULL,0x0B6BD3C3DBFD506BULL, 0x854997BA2F81E701ULL,0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL,0x1CECDC9E94ACE4F3ULL, 0xDBFDFEA26E92BF46ULL,0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL,0xD03E790CC93A650AULL, 0xAA478900B1228E31ULL,0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL,0xA1840EAE168A547DULL, 0x66952C92ECB40FC8ULL,0x2465CD79455E395BULL, 0x3821458AADA7578FULL,0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL,0xFF3067B657990C3AULL, 0x711223CFA3E5BB50ULL,0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL,0x98F5E3FE438617BCULL, 0x5FE4C1C2B9B84C09ULL,0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL,0x5427466C1E109645ULL, 0x4863CE9FF6E9F891ULL,0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL,0x43A04931514122DDULL, 0x84B16B0DAB7F7968ULL,0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL,0x7B2958D680B3FF75ULL, 0xF50B1CAF74CF481FULL,0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL,0x6CAE578BCFE24BEDULL, 0xABBF75B735DC1058ULL,0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL,0xA07CF2199274CA14ULL, 0x167FF3EACBAF2AF1ULL,0x548F120162451C62ULL, 0x939E303D987B47D7ULL,0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL,0x1DBC74446C07F0BDULL, 0xDAAD56789639AB08ULL,0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL,0x43081D5C2D14A8FAULL, 0xCD2A5925D9681F90ULL,0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL,0x32B26AFEF2A4998DULL, 0xF5A348C2089AC238ULL,0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL,0xFE60CF6CAF321874ULL, 0xE224479F47CB76A0ULL,0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL,0xE9E7C031E063ACECULL, 0x2EF6E20D1A5DF759ULL,0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL,0x31EBC7FC870C2F78ULL, 0xBFC9838573709812ULL,0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL,0x266CC8A1C85D9BE0ULL, 0xE17DEA9D3263C055ULL,0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL,0xEABE6D3395CB1A19ULL, 0x90C79D3FEDD3F122ULL,0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL,0x9B041A914A7B2B6EULL, 0x5C1538ADB04570DBULL,0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL,0xC5B073890B687329ULL, 0x4B9237F0FF14C443ULL,0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL,0x7870F5D4F51B4980ULL, 0xBF61D7E80F251235ULL,0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL,0xB4A25046A88DC879ULL, 0xA8E6D8B54074A6ADULL,0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL,0xA3255F1BE7DC7CE1ULL, 0x64347D271DE22754ULL,0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL,0x9BAC4EFC362EA149ULL, 0x158E0A85C2521623ULL,0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL,0x8C2B41A1797F15D1ULL, 0x4B3A639D83414E64ULL,0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL,0x40F9E43324E99428ULL, 0x2CFFE7D5975E55E2ULL,0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL,0x273C607B30F68FAEULL, 0xE02D4247CAC8D41BULL,0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL,0x7988096371E5D7E9ULL, 0xF7AA4D1A85996083ULL,0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL,0x08327EC1AE55E69EULL, 0xCF235CFD546BBD2BULL,0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL,0xC4E0DB53F3C36767ULL, 0xD8A453A01B3A09B3ULL,0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,0x1FB5719CE1045206ULL, 0x919735E51578E56CULL,0xD367D40EBC92D3FFULL, 0x1476F63246AC884AULL,0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL,0x279434164CA30589ULL, 0xA9B6706FB8DFB2E3ULL,0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL,0x30133B4B03F2B111ULL, 0xF7021977F9CCEAA4ULL,0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL,0xFCC19ED95E6430E8ULL, 0x86B86ED5267CDBD3ULL,0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL,0x8D7BE97B81D4019FULL, 0x4A6ACB477BEA5A2AULL,0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,0x562E43B4931334FEULL, 0x913F6188692D6F4BULL,0xD3CF8063C0C759D8ULL, 0x5DEDC41A34BBEEB2ULL,0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL,0x9AFCE626CE85B507ULL, }; while (len > 0) { crc = table[*data ^ (unsigned char)(crc >> 56)] ^ (crc << 8); data++; len--; } return crc; } igtl_uint32 igtl_export igtl_nanosec_to_frac(igtl_uint32 nanosec) { igtl_uint32 base = 1000000000; /*10^9*/ igtl_uint32 mask = 0x80000000; igtl_uint32 r = 0x00000000; do { base++; base >>= 1; if (nanosec >= base) { r |= mask; nanosec -= base; } mask >>= 1; } while (mask); return r; } igtl_uint32 igtl_export igtl_frac_to_nanosec(igtl_uint32 frac) { igtl_uint32 base = 1000000000; /*10^9*/ igtl_uint32 mask = 0x80000000; igtl_uint32 r = 0x00000000; do { base++; base >>= 1; r += (frac & mask)? base : 0; mask >>= 1; } while (mask); return r; } void igtl_export igtl_message_dump_hex(FILE* stream, const void* message, int bytes) { /* Print first 256 bytes as HEX values in STDERR for debug */ unsigned char* p; int row; int cols_in_last_row; int i; int j; p = (unsigned char*)message; row = bytes / 16; cols_in_last_row = bytes % 16; for (i = 0; i < row; i ++) { for (j = 0; j < 16; j ++) { fprintf(stream, "%02x ", *p); p++; } fprintf(stream, "\n"); } for (j = 0; j < cols_in_last_row; j ++) { fprintf(stream, "%02x ", p[i]); } fprintf(stream, "\n"); } /* Calculate number of bytes / element */ igtl_uint32 igtl_export igtl_get_scalar_size(int type) { igtl_uint32 bytes; switch (type) { case IGTL_SCALAR_INT8: case IGTL_SCALAR_UINT8: bytes = 1; break; case IGTL_SCALAR_INT16: case IGTL_SCALAR_UINT16: bytes = 2; break; case IGTL_SCALAR_INT32: case IGTL_SCALAR_UINT32: case IGTL_SCALAR_FLOAT32: bytes = 4; break; case IGTL_SCALAR_FLOAT64: bytes = 8; break; case IGTL_SCALAR_COMPLEX: bytes = 16; break; default: bytes = 0; break; } return bytes; } openigtlink-3.0.0/Source/igtlutil/igtl_util.h000066400000000000000000000037701501024245700213060ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_UTIL_H #define __IGTL_UTIL_H #include #include "igtl_win32header.h" #include "igtl_types.h" #ifdef __cplusplus extern "C" { #endif /* Scalar type for point data */ #define IGTL_SCALAR_INT8 2 #define IGTL_SCALAR_UINT8 3 #define IGTL_SCALAR_INT16 4 #define IGTL_SCALAR_UINT16 5 #define IGTL_SCALAR_INT32 6 #define IGTL_SCALAR_UINT32 7 #define IGTL_SCALAR_FLOAT32 10 #define IGTL_SCALAR_FLOAT64 11 #define IGTL_SCALAR_COMPLEX 13 /** Byte order conversion macros */ #define BYTE_SWAP_INT16(S) (((S) & 0xFF) << 8 \ | (((S) >> 8) & 0xFF)) #define BYTE_SWAP_INT32(L) ((BYTE_SWAP_INT16 ((L) & 0xFFFF) << 16) \ | BYTE_SWAP_INT16 (((L) >> 16) & 0xFFFF)) #define BYTE_SWAP_INT64(LL) ((BYTE_SWAP_INT32 ((LL) & 0xFFFFFFFF) << 32) \ | BYTE_SWAP_INT32 (((LL) >> 32) & 0xFFFFFFFF)) /** Tests endian of the host */ int igtl_export igtl_is_little_endian(); igtl_uint64 igtl_export crc64(unsigned char *data, igtl_uint64 len, igtl_uint64 crc); /** Converts nanosecond to fraction / fraction to nanosec. */ igtl_uint32 igtl_export igtl_nanosec_to_frac(igtl_uint32 nanosec); igtl_uint32 igtl_export igtl_frac_to_nanosec(igtl_uint32 frac); void igtl_export igtl_message_dump_hex(FILE* stream, const void* message, int max_size); /** Gets size of scalar. Type should be IGTL_SCALAR_* */ igtl_uint32 igtl_export igtl_get_scalar_size(int type); #ifdef __cplusplus } #endif #endif /*__IGTL_UTIL_H*/ openigtlink-3.0.0/Source/igtlutil/igtl_win32header.h000066400000000000000000000022251501024245700224360ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_WIN32HEADER_H #define __IGTL_WIN32HEADER_H #include "igtl_typeconfig.h" #if (defined(_WIN32) || defined(WIN32)) && !defined(IGTLSTATIC) # ifdef IGTLCommon_EXPORTS # define igtl_export __declspec(dllexport) # else # define igtl_export __declspec(dllimport) # endif /* igtl_common_exports */ #else /* unix needs nothing */ #define igtl_export #endif #if defined(_WIN32) # include #endif #if defined(_MSC_VER) /* Enable MSVC compiler warning messages that are useful but off by default.*/ # pragma warning ( disable : 4996 ) /* 'strncpy': This function or variable may be unsafe. */ #endif #endif /*__IGTL_WIN32HEADER_H*/ openigtlink-3.0.0/Testing/000077500000000000000000000000001501024245700154525ustar00rootroot00000000000000openigtlink-3.0.0/Testing/CMakeLists.txt000066400000000000000000000261041501024245700202150ustar00rootroot00000000000000PROJECT( OpenIGTLinkTesting ) cmake_minimum_required(VERSION 2.9) find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) include_directories(${OpenIGTLink_INCLUDE_DIRS}) link_directories(${OpenIGTLink_LIBRARY_DIRS}) include_directories(${PROJECT_BINARY_DIR}) OPTION(USE_GTEST "Build the testing tree." ON) IF(USE_GTEST) SET(OpenIGTLink_USE_GTEST "1") ELSE() SET(OpenIGTLink_USE_GTEST "0") ENDIF() configure_file(${PROJECT_SOURCE_DIR}/igtlTestConfig.h.in ${PROJECT_BINARY_DIR}/igtlTestConfig.h) ENABLE_TESTING() ADD_SUBDIRECTORY( igtlutil ) IF(OpenIGTLink_USE_GTEST) #----------- #download of GoogleTest if( MSVC ) # VS2012 doesn't support correctly the tuples yet add_definitions("-D_VARIADIC_MAX=10") endif() # Download and unpack googletest at configure time configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt) execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/googletest-download" ) execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/googletest-download" ) # Prevent GoogleTest from overriding our compiler/linker options # when building with Visual Studio set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # Add googletest directly to our build. This adds # the following targets: gtest, gtest_main, gmock # and gmock_main add_subdirectory("${PROJECT_BINARY_DIR}/gmock" "${PROJECT_BINARY_DIR}/gmock-build" ) # The gtest/gmock targets carry header search path # dependencies automatically when using CMake 2.8.11 or # later. Otherwise we have to add them here ourselves. include_directories("${gtest_SOURCE_DIR}/include") include_directories("${gmock_SOURCE_DIR}/include") #--------------- ENDIF() ADD_EXECUTABLE(igtlMultiThreaderTest1 igtlMultiThreaderTest1.cxx) ADD_EXECUTABLE(igtlMultiThreaderTest2 igtlMultiThreaderTest2.cxx) ADD_EXECUTABLE(igtlMultiThreaderTest3 igtlMultiThreaderTest3.cxx) ADD_EXECUTABLE(igtlMessageFactoryTest igtlMessageFactoryTest.cxx) ADD_EXECUTABLE(igtlTimeStampTest1 igtlTimeStampTest1.cxx) ADD_EXECUTABLE(igtlMessageBaseTest igtlMessageBaseTest.cxx) ADD_EXECUTABLE(igtlConditionVariableTest igtlConditionVariableTest.cxx) ADD_EXECUTABLE(igtlImageMessageTest igtlImageMessageTest.cxx) ADD_EXECUTABLE(igtlImageMessage2Test igtlImageMessage2Test.cxx) ADD_EXECUTABLE(igtlTransformMessageTest igtlTransformMessageTest.cxx) ADD_EXECUTABLE(igtlPositionMessageTest igtlPositionMessageTest.cxx) ADD_EXECUTABLE(igtlStatusMessageTest igtlStatusMessageTest.cxx) ADD_EXECUTABLE(igtlCapabilityMessageTest igtlCapabilityMessageTest.cxx) #ADD_EXECUTABLE(igtlSocketTest igtlSocketTest.cxx) #ADD_EXECUTABLE(igtlServerSocketTest igtlServerSocketTest.cxx) #ADD_EXECUTABLE(igtlClientSocketTest igtlClientSocketTest.cxx) # Message Tests Added in Version 2 IF(${OpenIGTLink_PROTOCOL_VERSION} GREATER "1") ADD_EXECUTABLE(igtlBindMessageTest igtlBindMessageTest.cxx) ADD_EXECUTABLE(igtlColorTableMessageTest igtlColorTableMessageTest.cxx) ADD_EXECUTABLE(igtlLabelMetaMessageTest igtlLabelMetaMessageTest.cxx) ADD_EXECUTABLE(igtlNDArrayMessageTest igtlNDArrayMessageTest.cxx) ADD_EXECUTABLE(igtlImageMetaMessageTest igtlImageMetaMessageTest.cxx) ADD_EXECUTABLE(igtlPointMessageTest igtlPointMessageTest.cxx) ADD_EXECUTABLE(igtlPolyDataMessageTest igtlPolyDataMessageTest.cxx) ADD_EXECUTABLE(igtlSensorMessageTest igtlSensorMessageTest.cxx) ADD_EXECUTABLE(igtlStringMessageTest igtlStringMessageTest.cxx) ADD_EXECUTABLE(igtlTrackingDataMessageTest igtlTrackingDataMessageTest.cxx) ADD_EXECUTABLE(igtlTrajectoryMessageTest igtlTrajectoryMessageTest.cxx) ENDIF() # Message Tests Added in Version 3 IF(${OpenIGTLink_PROTOCOL_VERSION} GREATER "2") ADD_EXECUTABLE(igtlCommandMessageTest igtlCommandMessageTest.cxx) ENDIF() IF(USE_GTEST) SET(GTEST_LINK OpenIGTLink gtest_main gtest gmock_main gmock) ELSE() SET(GTEST_LINK OpenIGTLink) ENDIF() TARGET_LINK_LIBRARIES(igtlMultiThreaderTest1 OpenIGTLink) TARGET_LINK_LIBRARIES(igtlMultiThreaderTest2 OpenIGTLink) TARGET_LINK_LIBRARIES(igtlMultiThreaderTest3 OpenIGTLink) TARGET_LINK_LIBRARIES(igtlMessageFactoryTest OpenIGTLink) TARGET_LINK_LIBRARIES(igtlTimeStampTest1 OpenIGTLink) TARGET_LINK_LIBRARIES(igtlMessageBaseTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlConditionVariableTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlImageMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlImageMessage2Test ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlCapabilityMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlStatusMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlTransformMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlPositionMessageTest ${GTEST_LINK}) # Message Tests Added in Version 2 IF(${OpenIGTLink_PROTOCOL_VERSION} GREATER "1") TARGET_LINK_LIBRARIES(igtlBindMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlColorTableMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlLabelMetaMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlNDArrayMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlImageMetaMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlPointMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlPolyDataMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlSensorMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlStringMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlTrackingDataMessageTest ${GTEST_LINK}) TARGET_LINK_LIBRARIES(igtlTrajectoryMessageTest ${GTEST_LINK}) ENDIF() # Message Tests Added in Version 3 IF(${OpenIGTLink_PROTOCOL_VERSION} GREATER "2") TARGET_LINK_LIBRARIES(igtlCommandMessageTest ${GTEST_LINK}) ENDIF() #TARGET_LINK_LIBRARIES(igtlSocketTest ${GTEST_LINK}) #TARGET_LINK_LIBRARIES(igtlClientSocketTest ${GTEST_LINK}) #TARGET_LINK_LIBRARIES(igtlServerSocketTest ${GTEST_LINK}) set(TestStringFormat1 "--gtest_filter=*.*FormatVersion1") ADD_TEST(igtlMultiThreaderTest1 ${OpenIGTLink_EXECUTABLE_PATH}/igtlMultiThreaderTest1) ADD_TEST(igtlMultiThreaderTest2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlMultiThreaderTest2) ADD_TEST(igtlMultiThreaderTest3 ${OpenIGTLink_EXECUTABLE_PATH}/igtlMultiThreaderTest3) ADD_TEST(igtlMessageFactoryTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlMessageFactoryTest) ADD_TEST(igtlTimeStampTest1 ${OpenIGTLink_EXECUTABLE_PATH}/igtlTimeStampTest1) ADD_TEST(igtlMessageBaseTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlMessageBaseTest ${TestStringFormat1}) ADD_TEST(igtlConditionVariableTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlConditionVariableTest ${TestStringFormat1}) ADD_TEST(igtlImageMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlImageMessageTest ${TestStringFormat1}) ADD_TEST(igtlImageMessage2Test ${OpenIGTLink_EXECUTABLE_PATH}/igtlImageMessage2Test ${TestStringFormat1}) ADD_TEST(igtlCapabilityMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlCapabilityMessageTest ${TestStringFormat1}) ADD_TEST(igtlStatusMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlStatusMessageTest ${TestStringFormat1}) ADD_TEST(igtlTransformMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlTransformMessageTest ${TestStringFormat1}) ADD_TEST(igtlPositionMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlPositionMessageTest ${TestStringFormat1}) # Message Tests Added in Version 2 IF(${OpenIGTLink_PROTOCOL_VERSION} GREATER "1") ADD_TEST(igtlBindMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlBindMessageTest ${TestStringFormat1}) ADD_TEST(igtlColorTableMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlColorTableMessageTest ${TestStringFormat1}) ADD_TEST(igtlLabelMetaMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlLabelMetaMessageTest ${TestStringFormat1}) ADD_TEST(igtlNDArrayMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlNDArrayMessageTest ${TestStringFormat1}) ADD_TEST(igtlImageMetaMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlLabelMetaMessageTest ${TestStringFormat1}) ADD_TEST(igtlPointMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlPointMessageTest ${TestStringFormat1}) ADD_TEST(igtlPolyDataMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlPolyDataMessageTest ${TestStringFormat1}) ADD_TEST(igtlSensorMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlSensorMessageTest ${TestStringFormat1}) ADD_TEST(igtlStringMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlStringMessageTest ${TestStringFormat1}) ADD_TEST(igtlTrackingDataMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlTrackingDataMessageTest ${TestStringFormat1}) ADD_TEST(igtlTrajectoryMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlTrajectoryMessageTest ${TestStringFormat1}) ENDIF() # Message Tests Added in Version 3 IF(${OpenIGTLink_PROTOCOL_VERSION} GREATER "2") set(TestStringFormat2 "--gtest_filter=*.*FormatVersion2") ADD_TEST(igtlMessageBaseTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlMessageBaseTest ${TestStringFormat2}) ADD_TEST(igtlImageMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlImageMessageTest ${TestStringFormat2}) ADD_TEST(igtlImageMessage2TestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlImageMessage2Test ${TestStringFormat2}) ADD_TEST(igtlBindMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlBindMessageTest ${TestStringFormat2}) ADD_TEST(igtlCapabilityMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlCapabilityMessageTest ${TestStringFormat2}) ADD_TEST(igtlColorTableMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlColorTableMessageTest ${TestStringFormat2}) ADD_TEST(igtlConditionVariableTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlConditionVariableTest ${TestStringFormat2}) ADD_TEST(igtlLabelMetaMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlLabelMetaMessageTest ${TestStringFormat2}) ADD_TEST(igtlNDArrayMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlNDArrayMessageTest ${TestStringFormat2}) ADD_TEST(igtlImageMetaMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlLabelMetaMessageTest ${TestStringFormat2}) ADD_TEST(igtlPointMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlPointMessageTest ${TestStringFormat2}) ADD_TEST(igtlPolyDataMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlPolyDataMessageTest ${TestStringFormat2}) ADD_TEST(igtlSensorMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlSensorMessageTest ${TestStringFormat2}) ADD_TEST(igtlStatusMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlStatusMessageTest ${TestStringFormat2}) ADD_TEST(igtlStringMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlStringMessageTest ${TestStringFormat2}) ADD_TEST(igtlTrackingDataMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlTrackingDataMessageTest ${TestStringFormat2}) ADD_TEST(igtlTrajectoryMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlTrajectoryMessageTest ${TestStringFormat2}) ADD_TEST(igtlTransformMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlTransformMessageTest ${TestStringFormat2}) ADD_TEST(igtlPositionMessageTest ${OpenIGTLink_EXECUTABLE_PATH}/igtlPositionMessageTest) ADD_TEST(igtlCommandMessageTestFormatVersion1 ${OpenIGTLink_EXECUTABLE_PATH}/igtlCommandMessageTest ${TestStringFormat1}) ADD_TEST(igtlCommandMessageTestFormatVersion2 ${OpenIGTLink_EXECUTABLE_PATH}/igtlCommandMessageTest ${TestStringFormat2}) ENDIF() openigtlink-3.0.0/Testing/CMakeLists.txt.in000066400000000000000000000014171501024245700206220ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.2) project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest URL https://github.com/google/googletest/archive/release-1.7.0.zip #GIT_REPOSITORY https://github.com/google/googletest.git #GIT_TAG master SOURCE_DIR "${PROJECT_BINARY_DIR}/gtest" BINARY_DIR "${PROJECT_BINARY_DIR}/gtest-build" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" TEST_COMMAND "" ) ExternalProject_Add(googlemock URL https://github.com/google/googlemock/archive/release-1.7.0.zip SOURCE_DIR "${PROJECT_BINARY_DIR}/gmock" BINARY_DIR "${PROJECT_BINARY_DIR}/gmock-build" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" TEST_COMMAND "" ) openigtlink-3.0.0/Testing/igtlBindMessageTest.cxx000066400000000000000000000243401501024245700221020ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlBindMessage.h" #include "igtlutil/igtl_test_data_bind.h" #include "igtlutil/igtl_test_data_image.h" #include "igtlTransformMessage.h" #include "igtlImageMessage.h" #include "igtlSensorMessage.h" #include "igtlMessageDebugFunction.h" #include "igtlUnit.h" #include "igtl_unit.h" #include "igtl_header.h" #include "igtl_image.h" #include "igtl_transform.h" #include "igtl_bind.h" #include "igtlTestConfig.h" #include "string.h" #define MESSAGE_BIND_HEADER_SIZE 98 #define MESSAGE_BIND_BODY_SIZE 2678 #define TEST_IMAGE_MESSAGE_SIZE 2500 #define MESSAGE_SENSOR_BODY_SIZE 58 igtl::ImageMessage::Pointer imageSendMsg2 = igtl::ImageMessage::New(); igtl::ImageMessage::Pointer imageReceiveMsg2 = igtl::ImageMessage::New(); igtl::SensorMessage::Pointer sensorDataSendMsg = igtl::SensorMessage::New(); igtl::SensorMessage::Pointer sensorDataReceiveMsg = igtl::SensorMessage::New(); igtl::TransformMessage::Pointer transformSendMsg = igtl::TransformMessage::New(); igtl::TransformMessage::Pointer transformReceiveMsg = igtl::TransformMessage::New(); igtl::BindMessage::Pointer bindSendMsg = igtl::BindMessage::New(); igtl::BindMessage::Pointer bindReceiveMsg = igtl::BindMessage::New(); igtl::Unit::Pointer unit = igtl::Unit::New(); igtl::GetBindMessage::Pointer getBindSendMessage = igtl::GetBindMessage::New(); igtl::GetBindMessage::Pointer getBindReceiveMessage = igtl::GetBindMessage::New(); igtl::StartBindMessage::Pointer startBindSendMessage = igtl::StartBindMessage::New(); igtl::StartBindMessage::Pointer startBindReceiveMessage = igtl::StartBindMessage::New(); float inT[4] = {-0.954892f, 0.196632f, -0.222525f, 0.0}; float inS[4] = {-0.196632f, 0.142857f, 0.970014f, 0.0}; float inN[4] = {0.222525f, 0.970014f, -0.0977491f, 0.0}; float inOrigin[4] = {46.0531f,19.4709f,46.0531f, 1.0}; igtl::Matrix4x4 inMatrix = {{inT[0],inS[0],inN[0],inOrigin[0]}, {inT[1],inS[1],inN[1],inOrigin[1]}, {inT[2],inS[2],inN[2],inOrigin[2]}, {inT[3],inS[3],inN[3],inOrigin[3]}}; int size[3] = {50, 50, 1}; // image dimension float spacing[3] = {1.0f, 1.0f, 1.0f}; // spacing (mm/pixel) int svsize[3] = {50, 50, 1}; // sub-volume size int svoffset[3] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage::TYPE_UINT8;// scalar type igtlFloat64 sensorValues[6] = {123456.78,12345.678,1234.5678,123.45678,12.345678,1.2345678}; void BuildUpElements() { imageSendMsg2 = igtl::ImageMessage::New(); imageSendMsg2->SetHeaderVersion(IGTL_HEADER_VERSION_1); imageSendMsg2->SetTimeStamp(0, 1234567892); imageSendMsg2->SetDeviceName("ChildImage"); //Initialization of a image message imageSendMsg2->SetDimensions(size); imageSendMsg2->SetSpacing(spacing); imageSendMsg2->SetScalarType(scalarType); imageSendMsg2->SetSubVolume(svsize, svoffset); imageSendMsg2->SetNumComponents(1); imageSendMsg2->SetScalarType(IGTL_IMAGE_STYPE_TYPE_UINT8); imageSendMsg2->SetEndian(IGTL_IMAGE_ENDIAN_LITTLE); imageSendMsg2->SetCoordinateSystem(IGTL_IMAGE_COORD_RAS); imageSendMsg2->SetMatrix(inMatrix); //imageSendMsg2->AllocateBuffer(IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE); imageSendMsg2->AllocateScalars(); memcpy(imageSendMsg2->GetPackBodyPointer(), (const void*)(test_image_message+IGTL_HEADER_SIZE), (size_t)(IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE));//here m_Body is set. //imageSendMsg2->SetScalarPointer((void*)test_image); imageSendMsg2->Pack(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)imageSendMsg2->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); imageReceiveMsg2->SetMessageHeader(headerMsg); imageReceiveMsg2->AllocatePack(); sensorDataSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); sensorDataSendMsg->AllocatePack(); sensorDataSendMsg->SetLength(6); sensorDataSendMsg->SetDeviceName("ChildSensor"); sensorDataSendMsg->SetTimeStamp(0, 1234567892); unit->Init(); unit->SetPrefix(IGTL_UNIT_PREFIX_NONE); unit->Append(IGTL_UNIT_SI_BASE_METER, (igtl_int8) 1); unit->Append(IGTL_UNIT_SI_BASE_SECOND, (igtl_int8) -2); unit->Pack(); sensorDataSendMsg->SetUnit(unit); for (int i =0; i < 6; i++) { sensorDataSendMsg->SetValue(i, sensorValues[i]); } sensorDataSendMsg->Pack(); sensorDataReceiveMsg->AllocatePack(); sensorDataReceiveMsg->SetLength(6); transformSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); transformSendMsg->AllocatePack(); transformSendMsg->SetTimeStamp(0, 1234567892); transformSendMsg->SetDeviceName("ChildTrans"); transformSendMsg->SetMatrix(inMatrix); transformSendMsg->Pack(); transformReceiveMsg->AllocatePack(); bindSendMsg->Init(); bindSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); bindSendMsg->SetTimeStamp(0, 1234567892); bindSendMsg->SetDeviceName("DeviceName"); bindSendMsg->AppendChildMessage(transformSendMsg); bindSendMsg->AppendChildMessage(imageSendMsg2); bindSendMsg->AppendChildMessage(sensorDataSendMsg); bindSendMsg->Pack(); } TEST(BindMessageTest, Pack) { BuildUpElements(); char * messageBody = (char*)bindSendMsg->GetPackBodyPointer() + MESSAGE_BIND_HEADER_SIZE; int r = memcmp((const void*)bindSendMsg->GetPackPointer(), (const void*)test_bind_message_header, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)bindSendMsg->GetPackBodyPointer(), (const void*)test_bind_message_bind_header, MESSAGE_BIND_HEADER_SIZE); EXPECT_EQ(r, 0); messageBody = (char*)bindSendMsg->GetPackBodyPointer() + MESSAGE_BIND_HEADER_SIZE; r = memcmp((const void*)(messageBody), (const void*)test_bind_message_bind_body, MESSAGE_BIND_BODY_SIZE); EXPECT_EQ(r, 0); } TEST(BindMessageTest, Unpack) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), bindSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); bindReceiveMsg->SetMessageHeader(headerMsg); bindReceiveMsg->AllocatePack(); memcpy(bindReceiveMsg->GetPackBodyPointer(), bindSendMsg->GetPackBodyPointer(),MESSAGE_BIND_HEADER_SIZE + MESSAGE_BIND_BODY_SIZE); bindReceiveMsg->Unpack(1); bindReceiveMsg->GetChildMessage(0, transformReceiveMsg); bindReceiveMsg->GetChildMessage(1, imageReceiveMsg2); bindReceiveMsg->GetChildMessage(2, sensorDataReceiveMsg); igtl_header *messageHeader = (igtl_header *)bindReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "BIND"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, MESSAGE_BIND_HEADER_SIZE + MESSAGE_BIND_BODY_SIZE); int r = memcmp(bindReceiveMsg->GetPackBodyPointer(), test_bind_message_bind_header, MESSAGE_BIND_HEADER_SIZE); EXPECT_EQ(r, 0); igtl_header *imageHeader = (igtl_header *)imageReceiveMsg2->GetPackPointer(); EXPECT_STREQ(imageHeader->device_name, "ChildImage"); EXPECT_STREQ(imageHeader->name, "IMAGE"); EXPECT_EQ(imageHeader->header_version, 1); EXPECT_EQ(imageHeader->timestamp, 1234567892); EXPECT_EQ(imageHeader->body_size, IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE); int returnSize[3] = {0,0,0}; imageReceiveMsg2->GetDimensions(returnSize); EXPECT_THAT(returnSize,testing::ElementsAreArray(size)); float returnSpacing[3] = {0.0f,0.0f,0.0f}; imageReceiveMsg2->GetSpacing(returnSpacing); EXPECT_TRUE(ArrayFloatComparison(returnSpacing, spacing, 3, ABS_ERROR)); int returnSvsize[3] = {0,0,0}, returnSvoffset[3] = {0,0,0}; imageReceiveMsg2->GetSubVolume(returnSvsize, returnSvoffset); EXPECT_THAT(returnSvsize,testing::ElementsAreArray(svsize)); EXPECT_THAT(returnSvoffset,testing::ElementsAreArray(svoffset)); EXPECT_EQ(imageReceiveMsg2->GetScalarType(), IGTL_IMAGE_STYPE_TYPE_UINT8); EXPECT_EQ(imageReceiveMsg2->GetEndian(), IGTL_IMAGE_ENDIAN_LITTLE); EXPECT_EQ(imageReceiveMsg2->GetCoordinateSystem(), IGTL_IMAGE_COORD_RAS); r = memcmp((const char*)imageReceiveMsg2->GetPackBodyPointer()+IGTL_IMAGE_HEADER_SIZE, test_image, TEST_IMAGE_MESSAGE_SIZE); EXPECT_EQ(r, 0); igtl_header *transformHeader = (igtl_header *)transformReceiveMsg->GetPackPointer(); EXPECT_STREQ(transformHeader->device_name, "ChildTrans"); EXPECT_STREQ(transformHeader->name, "TRANSFORM"); EXPECT_EQ(transformHeader->header_version, 1); EXPECT_EQ(transformHeader->timestamp, 1234567892); EXPECT_EQ(transformHeader->body_size, IGTL_TRANSFORM_SIZE); igtl::Matrix4x4 outMatrix = {{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.0,0.0,0.0}}; transformReceiveMsg->GetMatrix(outMatrix); EXPECT_TRUE(MatrixComparison(outMatrix, inMatrix, ABS_ERROR)); igtl_header *sensorHeader = (igtl_header *)sensorDataReceiveMsg->GetPackPointer(); EXPECT_STREQ(sensorHeader->device_name, "ChildSensor"); EXPECT_STREQ(sensorHeader->name, "SENSOR"); EXPECT_EQ(sensorHeader->header_version, 1); EXPECT_EQ(sensorHeader->timestamp, 1234567892); EXPECT_EQ(sensorHeader->body_size, MESSAGE_SENSOR_BODY_SIZE); igtl::igtlUnit unitTruth = 0x443E0000000000; EXPECT_EQ(sensorDataReceiveMsg->GetUnit(), unitTruth); EXPECT_EQ(sensorDataReceiveMsg->GetLength(),6); EXPECT_FLOAT_EQ(sensorDataReceiveMsg->GetValue(0),123456.78); EXPECT_FLOAT_EQ(sensorDataReceiveMsg->GetValue(1),12345.678); EXPECT_FLOAT_EQ(sensorDataReceiveMsg->GetValue(2),1234.5678); EXPECT_FLOAT_EQ(sensorDataReceiveMsg->GetValue(3),123.45678); EXPECT_FLOAT_EQ(sensorDataReceiveMsg->GetValue(4),12.345678); EXPECT_FLOAT_EQ(sensorDataReceiveMsg->GetValue(5),1.2345678); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlCapabilityMessageTest.cxx000066400000000000000000000056041501024245700233110ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlCapabilityMessage.h" #include "igtlutil/igtl_test_data_capability.h" #include "igtlMessageDebugFunction.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" #define CAPABILITY_MESSAGE_BODY_SIZE 48 igtl::CapabilityMessage::Pointer capabilitySendMsg = igtl::CapabilityMessage::New(); igtl::CapabilityMessage::Pointer capabilityReceiveMsg = igtl::CapabilityMessage::New(); TEST(ColorTableMessageTest, Pack) { capabilitySendMsg->SetTimeStamp(0, 1234567892); capabilitySendMsg->SetDeviceName("DeviceName"); capabilitySendMsg->SetNumberOfTypes(4); capabilitySendMsg->SetType(0, "IMAGE"); capabilitySendMsg->SetType(1, "GET_IMAGE"); capabilitySendMsg->SetType(2, "TRANSFORM"); capabilitySendMsg->SetType(3, "GET_TRANS"); capabilitySendMsg->Pack(); TestDebugCharArrayCmp(capabilitySendMsg->GetPackPointer(), test_capability_message, IGTL_HEADER_SIZE); int r = memcmp((const void*)capabilitySendMsg->GetPackPointer(), (const void*)test_capability_message, IGTL_HEADER_SIZE); EXPECT_EQ(r, 0); r = memcmp((const void*)capabilitySendMsg->GetPackBodyPointer(), (const void*)(test_capability_message+IGTL_HEADER_SIZE), CAPABILITY_MESSAGE_BODY_SIZE); EXPECT_EQ(r, 0); } TEST(ColorTableMessageTest, Unpack) { igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); memcpy(headerMsg->GetPackPointer(), capabilitySendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); capabilityReceiveMsg->SetMessageHeader(headerMsg); capabilityReceiveMsg->AllocatePack(); memcpy(capabilityReceiveMsg->GetPackBodyPointer(), capabilitySendMsg->GetPackBodyPointer(), capabilitySendMsg->GetPackBodySize()); capabilityReceiveMsg->Unpack(); EXPECT_EQ(capabilityReceiveMsg->GetNumberOfTypes(),4); EXPECT_STREQ(capabilityReceiveMsg->GetType(0),"IMAGE"); EXPECT_STREQ(capabilityReceiveMsg->GetType(1),"GET_IMAGE"); EXPECT_STREQ(capabilityReceiveMsg->GetType(2),"TRANSFORM"); EXPECT_STREQ(capabilityReceiveMsg->GetType(3),"GET_TRANS"); std::vector typeStrings = capabilityReceiveMsg->GetTypes(); EXPECT_EQ(typeStrings.size(),4); EXPECT_STREQ(typeStrings[0].c_str(),"IMAGE"); EXPECT_STREQ(typeStrings[1].c_str(),"GET_IMAGE"); EXPECT_STREQ(typeStrings[2].c_str(),"TRANSFORM"); EXPECT_STREQ(typeStrings[3].c_str(),"GET_TRANS"); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlClientSocketTest.cxx000066400000000000000000000050111501024245700223020ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlServerSocket.h" #include "igtlSocket.h" #include "igtl_types.h" #include "igtl_header.h" #include "igtlMessageHeader.h" #include "igtl_util.h" #include "igtlOSUtil.h" #include "igtlClientSocket.h" #include "igtlMultiThreader.h" #include "igtlQuaternionTrackingDataMessage.h" #include "igtlTestConfig.h" #include "string.h" using ::testing::_; using ::testing::AtLeast; using ::testing::Invoke; using ::testing::IsNull; using igtl::ServerSocket; using igtl::ClientSocket; using igtl::Socket; class ClientSocketMock { public: ClientSocketMock(ClientSocket::Pointer pointer) { real_ = pointer; // By default, all calls are delegated to the real object. ON_CALL(*this, ConnectToServer(_,_,_)) .WillByDefault(Invoke(real_.GetPointer(), &ClientSocket::ConnectToServer)); } ClientSocketMock(){real_.~SmartPointer();}; MOCK_METHOD3(ConnectToServer, int(const char* hostName, int port, bool logErrorIfServerConnectionFailed)); ClientSocket::Pointer getPointer(){return real_;}; private: ClientSocket::Pointer real_; }; void* ThreadFunction(void* ptr); int port = 18944; TEST(ClientSocketTest, ConnectToServerTest) { igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); igtl::ClientSocket::Pointer clientSocket; clientSocket = igtl::ClientSocket::New(); ClientSocketMock clientSocketMock(clientSocket); EXPECT_CALL(clientSocketMock, ConnectToServer(_,_,_)).Times(2); EXPECT_EQ(clientSocketMock.ConnectToServer("localhost", port,0), -1); threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, NULL); igtl::Sleep(1000); EXPECT_EQ(clientSocketMock.ConnectToServer("localhost", port,1), 0); clientSocketMock.getPointer()->CloseSocket(); } void* ThreadFunction(void* ptr) { int waitingTime = 10000; ServerSocket::Pointer serverSocket = ServerSocket::New(); serverSocket->CreateServer(port); serverSocket->WaitForConnection(waitingTime); serverSocket->CloseSocket(); return NULL; } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlColorTableMessageTest.cxx000066400000000000000000000052701501024245700232550ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlColorTableMessage.h" #include "igtlutil/igtl_test_data_colortable2.h" #include "igtlMessageDebugFunction.h" #include "igtl_colortable.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" #define COLOR_TABLE_SIZE 256 igtl::ColorTableMessage::Pointer colorTableSendMsg = igtl::ColorTableMessage::New(); igtl::ColorTableMessage::Pointer colorTableReceiveMsg = igtl::ColorTableMessage::New(); TEST(ColorTableMessageTest, Pack) { colorTableSendMsg->SetTimeStamp(0, 1234567892); colorTableSendMsg->SetDeviceName("DeviceName"); colorTableSendMsg->SetIndexType(IGTL_COLORTABLE_INDEX_UINT8); colorTableSendMsg->SetMapType(IGTL_COLORTABLE_MAP_UINT8); colorTableSendMsg->AllocateTable(); memcpy(colorTableSendMsg->GetTablePointer(), test_colortable_message+IGTL_HEADER_SIZE+IGTL_COLORTABLE_HEADER_SIZE, (size_t)(COLOR_TABLE_SIZE)); colorTableSendMsg->Pack(); TestDebugCharArrayCmp(colorTableSendMsg->GetPackPointer(), test_colortable_message, IGTL_HEADER_SIZE); int r = memcmp((const void*)colorTableSendMsg->GetPackPointer(), (const void*)test_colortable_message, IGTL_HEADER_SIZE); EXPECT_EQ(r, 0); r = memcmp((const void*)colorTableSendMsg->GetPackBodyPointer(), (const void*)(test_colortable_message+IGTL_HEADER_SIZE), IGTL_COLORTABLE_HEADER_SIZE+COLOR_TABLE_SIZE); EXPECT_EQ(r, 0); } TEST(ColorTableMessageTest, Unpack) { igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); memcpy(headerMsg->GetPackPointer(), colorTableSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); colorTableReceiveMsg->SetMessageHeader(headerMsg); colorTableReceiveMsg->AllocatePack(); memcpy(colorTableReceiveMsg->GetPackBodyPointer(), colorTableSendMsg->GetPackBodyPointer(), colorTableSendMsg->GetPackBodySize()); colorTableReceiveMsg->Unpack(); EXPECT_EQ(colorTableReceiveMsg->GetMapType(),IGTL_COLORTABLE_MAP_UINT8); EXPECT_EQ(colorTableReceiveMsg->GetIndexType(),IGTL_COLORTABLE_INDEX_UINT8); for (int i = 0; i < 256; i ++) { EXPECT_EQ(((unsigned char*)colorTableReceiveMsg->GetTablePointer())[i], i); } } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlCommandMessageTest.cxx000066400000000000000000000125301501024245700226020ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlCommandMessage.h" #include "igtlutil/igtl_test_data_command.h" #include "igtlMessageDebugFunction.h" #include "igtl_command.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::CommandMessage::Pointer sendCommandMsg = igtl::CommandMessage::New(); igtl::CommandMessage::Pointer receiveCommandMsg = igtl::CommandMessage::New(); void BuildMessageFormat1() { sendCommandMsg = igtl::CommandMessage::New(); sendCommandMsg->SetHeaderVersion(1); sendCommandMsg->SetCommandId(5); sendCommandMsg->SetContentEncoding(3); sendCommandMsg->SetCommandName("This is a test command"); sendCommandMsg->SetCommandContent("Start the tracking machine"); sendCommandMsg->Pack(); } TEST(CommandMessageTest, Pack) { BuildMessageFormat1(); int r = memcmp((const void*)sendCommandMsg->GetBufferPointer(), (const void*)test_command_message,(size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)sendCommandMsg->GetBufferBodyPointer(), (const void*)(test_command_message+(size_t)(IGTL_HEADER_SIZE)), sizeof(test_command_message)-IGTL_HEADER_SIZE); EXPECT_EQ(r, 0); } TEST(CommandMessageTest, UnPack) { BuildMessageFormat1(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->InitBuffer(); memcpy(headerMsg->GetBufferPointer(), (const void*)sendCommandMsg->GetBufferPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); receiveCommandMsg->SetMessageHeader(headerMsg); receiveCommandMsg->AllocatePack(); memcpy(receiveCommandMsg->GetBufferBodyPointer(), sendCommandMsg->GetBufferBodyPointer(), headerMsg->GetBodySizeToRead()); receiveCommandMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)receiveCommandMsg->GetBufferPointer(); EXPECT_STREQ(messageHeader->device_name, ""); EXPECT_STREQ(messageHeader->name, "COMMAND"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 0); EXPECT_EQ(messageHeader->body_size, sizeof(test_command_message)-IGTL_HEADER_SIZE); igtl_uint64 crc; memcpy(&crc, &test_command_message[IGTL_HEADER_SIZE-sizeof(igtl_uint64)], sizeof(igtl_uint64)); if(igtl_is_little_endian()) { crc = BYTE_SWAP_INT64(crc); } EXPECT_EQ(messageHeader->crc, crc); EXPECT_STREQ(receiveCommandMsg->GetCommandContent().c_str(), "Start the tracking machine"); } #if OpenIGTLink_PROTOCOL_VERSION >= 3 #include "igtlutil/igtl_test_data_commandFormat2.h" #include "igtlMessageFormat2TestMacro.h" void BuildMessageFormat2() { sendCommandMsg = igtl::CommandMessage::New(); sendCommandMsg->SetHeaderVersion(2); sendCommandMsg->SetCommandId(5); sendCommandMsg->SetContentEncoding(3); sendCommandMsg->SetCommandName("This is a test command"); sendCommandMsg->SetCommandContent("Start the tracking machine"); sendCommandMsg->SetDeviceName("OpticalTracker"); igtlMetaDataAddElementMacro(sendCommandMsg); sendCommandMsg->Pack(); } TEST(CommandMessageTest, PackFormatVersion2) { BuildMessageFormat2(); int r = memcmp((const void*)sendCommandMsg->GetBufferPointer(), (const void*)test_command_messageFormat2, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)sendCommandMsg->GetBufferBodyPointer(), (const void*)(test_command_messageFormat2+(size_t)(IGTL_HEADER_SIZE)), sizeof(test_command_messageFormat2)-IGTL_HEADER_SIZE); EXPECT_EQ(r, 0); } TEST(CommandMessageTest, UnpackFormatVersion2) { BuildMessageFormat2(); igtlMetaDataAddElementMacro(sendCommandMsg); sendCommandMsg->Pack(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->SetHeaderVersion(IGTL_HEADER_VERSION_2); headerMsg->InitBuffer(); memcpy(headerMsg->GetBufferPointer(), (const void*)sendCommandMsg->GetBufferPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); receiveCommandMsg->SetMessageHeader(headerMsg); receiveCommandMsg->AllocatePack(); memcpy(receiveCommandMsg->GetBufferBodyPointer(), sendCommandMsg->GetBufferBodyPointer(), headerMsg->GetBodySizeToRead()); receiveCommandMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)receiveCommandMsg->GetBufferPointer(); EXPECT_STREQ(messageHeader->device_name, "OpticalTracker"); EXPECT_STREQ(messageHeader->name, "COMMAND"); EXPECT_EQ(messageHeader->header_version, 2); EXPECT_EQ(messageHeader->timestamp, 0); int size = sizeof(test_command_messageFormat2) - IGTL_HEADER_SIZE; EXPECT_EQ(messageHeader->body_size, sizeof(test_command_messageFormat2)-IGTL_HEADER_SIZE); igtl_uint64 crc; memcpy(&crc, &test_command_messageFormat2[IGTL_HEADER_SIZE-sizeof(igtl_uint64)], sizeof(igtl_uint64)); if(igtl_is_little_endian()) { crc = BYTE_SWAP_INT64(crc); } EXPECT_EQ(messageHeader->crc, crc); EXPECT_STREQ(receiveCommandMsg->GetCommandContent().c_str(), "Start the tracking machine"); igtlMetaDataComparisonMacro(receiveCommandMsg); } #endif int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlConditionVariableTest.cxx000066400000000000000000000121571501024245700233200ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlConditionVariable.h" #include "igtlMultiThreader.h" #include "igtlOSUtil.h" #include "igtlTestConfig.h" #include "string.h" void* TestThreadCounter(void* ptr); void* TestThreadWaiting1(void* ptr); void* TestThreadWaiting2(void* ptr); typedef struct { igtl::SimpleMutexLock* glock; igtl::ConditionVariable::Pointer conditionVar; bool isBroadCast; int iFinalCount; bool condition; std::vector threads; } ThreadData; TEST(ConditionVariableTest, SingleChildThreadTest) { // From this test we can see that, the wait function really works, // the main thread waits until the spawned thread is finished, otherwize the icount1 will be 0. igtl::ConditionVariable::Pointer conditionVar = igtl::ConditionVariable::New(); igtl::SimpleMutexLock *localMutex = new igtl::SimpleMutexLock(); ThreadData td; td.threads = std::vector(1); td.conditionVar = conditionVar; td.glock = localMutex; td.isBroadCast = false; td.iFinalCount = 0; td.condition = false; igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadWaiting1, &td); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadCounter, &td); while (td.threads[0] == false) { igtl::Sleep(20); } std::cerr<<"The child thread is released"; EXPECT_EQ(td.iFinalCount, 10); } TEST(ConditionVariableTest, MultiChildThreadTest) { igtl::ConditionVariable::Pointer conditionVar = igtl::ConditionVariable::New(); igtl::SimpleMutexLock *localMutex = new igtl::SimpleMutexLock(); ThreadData td; td.conditionVar = conditionVar; td.glock = localMutex; td.isBroadCast = false; td.threads = std::vector(2,false); td.iFinalCount = 0; td.condition = false; igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadWaiting1, &td); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadCounter, &td); igtl::Sleep(1000); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadWaiting2, &td); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadCounter, &td); while (td.threads[0] == false || td.threads[1] == false) igtl::Sleep(20); EXPECT_EQ(td.iFinalCount, 20); std::cerr<<"The child threads are released"; } TEST(ConditionVariableTest, Broadcast) { igtl::ConditionVariable::Pointer conditionVar = igtl::ConditionVariable::New(); igtl::SimpleMutexLock *localMutex = new igtl::SimpleMutexLock(); ThreadData td; td.conditionVar = conditionVar; td.glock = localMutex; td.isBroadCast = true; td.threads = std::vector(2); td.iFinalCount = 0; td.condition = false; igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadWaiting1, &td); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadCounter, &td); igtl::Sleep(1000); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadWaiting2, &td); threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadCounter, &td); while (td.threads[0] == false || td.threads[1] == false) igtl::Sleep(20); EXPECT_LT(td.iFinalCount, 20); std::cerr<<"The child threads are released"; } void* TestThreadWaiting1(void* ptr) { igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ThreadData* td = static_cast(info->UserData); td->glock->Lock(); while(!td->condition) { td->conditionVar->Wait(td->glock); } td->threads[0]= true; td->glock->Unlock(); return NULL; } void* TestThreadWaiting2(void* ptr) { igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ThreadData* td = static_cast(info->UserData); td->glock->Lock(); while(!td->condition) { td->conditionVar->Wait(td->glock); } td->threads[1]= true; td->glock->Unlock(); return NULL; } void* TestThreadCounter(void* ptr) { //------------------------------------------------------------ // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ThreadData* td = static_cast(info->UserData); //igtl::SimpleMutexLock *glock = td->glocks[0]; int i = 0; while(++i <=10) { std::cerr<iFinalCount++; }; td->condition = true; if (td->isBroadCast) { td->conditionVar->Broadcast(); } else { td->conditionVar->Signal(); } return NULL; } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlImageMessage2Test.cxx000066400000000000000000000145731501024245700223410ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlImageMessage2.h" #include "igtlutil/igtl_test_data_image.h" #include "igtlMessageDebugFunction.h" #include "igtl_image.h" #include "igtl_types.h" #include "igtl_header.h" #include "igtl_util.h" #include "igtlTestConfig.h" #include "string.h" igtl::ImageMessage2::Pointer imageSendMsg2 = igtl::ImageMessage2::New(); igtl::ImageMessage2::Pointer imageReceiveMsg2 = igtl::ImageMessage2::New(); float inT[4] = {-0.954892f, 0.196632f, -0.222525f, 0.0}; float inS[4] = {-0.196632f, 0.142857f, 0.970014f, 0.0}; float inN[4] = {0.222525f, 0.970014f, -0.0977491f, 0.0}; float inOrigin[4] = {46.0531f,19.4709f,46.0531f, 1.0}; igtl::Matrix4x4 inMatrix = {{inT[0],inS[0],inN[0],inOrigin[0]}, {inT[1],inS[1],inN[1],inOrigin[1]}, {inT[2],inS[2],inN[2],inOrigin[2]}, {inT[3],inS[3],inN[3],inOrigin[3]}}; int size[3] = {50, 50, 1}; // image dimension float spacing[3] = {1.0f, 1.0f, 1.0f}; // spacing (mm/pixel) int svsize[3] = {50, 50, 1}; // sub-volume size int svoffset[3] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage2::TYPE_UINT8;// scalar type void BuildUp() { imageSendMsg2 = igtl::ImageMessage2::New(); imageSendMsg2->SetTimeStamp(0, 1234567892); imageSendMsg2->SetDeviceName("DeviceName"); //Initialization of a image message imageSendMsg2->SetDimensions(size); imageSendMsg2->SetSpacing(spacing); imageSendMsg2->SetScalarType(scalarType); imageSendMsg2->SetSubVolume(svsize, svoffset); imageSendMsg2->SetNumComponents(1); imageSendMsg2->SetScalarType(IGTL_IMAGE_STYPE_TYPE_UINT8); imageSendMsg2->SetEndian(IGTL_IMAGE_ENDIAN_LITTLE); imageSendMsg2->SetCoordinateSystem(IGTL_IMAGE_COORD_RAS); imageSendMsg2->SetMatrix(inMatrix); imageSendMsg2->AllocateBuffer(IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE); imageSendMsg2->AllocateScalars(); memcpy(imageSendMsg2->GetPackFragmentPointer(1), (void*)(test_image_message+IGTL_HEADER_SIZE), IGTL_IMAGE_HEADER_SIZE);//here m_ImageHeader is set. imageSendMsg2->SetScalarPointer((void*)test_image); //m_Image and m_Body are set imageSendMsg2->Pack(); } TEST(ImageMessage2Test, Pack) { BuildUp(); int r = memcmp((const void*)imageSendMsg2->GetPackPointer(), (const void*)test_image_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)imageSendMsg2->GetPackFragmentPointer(1), (const void*)(test_image_message+IGTL_HEADER_SIZE), (size_t)(IGTL_IMAGE_HEADER_SIZE)); EXPECT_EQ(r, 0); } TEST(ImageMessage2Test, Unpack) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)imageSendMsg2->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); imageReceiveMsg2->SetMessageHeader(headerMsg); imageReceiveMsg2->SetDimensions(50, 50, 1); imageReceiveMsg2->SetSubVolume(50, 50, 1, 0, 0, 0); imageReceiveMsg2->AllocateScalars(); memcpy(imageReceiveMsg2->GetPackFragmentPointer(0), imageSendMsg2->GetPackFragmentPointer(0), IGTL_HEADER_SIZE); memcpy(imageReceiveMsg2->GetPackBodyPointer(), imageSendMsg2->GetPackBodyPointer(), IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE); imageReceiveMsg2->Unpack(); igtl_header *messageHeader = (igtl_header *)headerMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "IMAGE"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_IMAGE_HEADER_SIZE + TEST_IMAGE_MESSAGE_SIZE); int returnSize[3] = {0,0,0}; imageReceiveMsg2->GetDimensions(returnSize); EXPECT_THAT(returnSize,testing::ElementsAreArray(size)); float returnSpacing[3] = {0.0f,0.0f,0.0f}; imageReceiveMsg2->GetSpacing(returnSpacing); for(int i=0;i < 3; i++) { EXPECT_NEAR(returnSpacing[i], spacing[i], ABS_ERROR); } int returnSvsize[3] = {0,0,0}, returnSvoffset[3] = {0,0,0}; imageReceiveMsg2->GetSubVolume(returnSvsize, returnSvoffset); EXPECT_THAT(returnSvsize,testing::ElementsAreArray(svsize)); EXPECT_THAT(returnSvoffset,testing::ElementsAreArray(svoffset)); EXPECT_EQ(imageReceiveMsg2->GetScalarType(), IGTL_IMAGE_STYPE_TYPE_UINT8); EXPECT_EQ(imageReceiveMsg2->GetEndian(), IGTL_IMAGE_ENDIAN_LITTLE); EXPECT_EQ(imageReceiveMsg2->GetCoordinateSystem(), IGTL_IMAGE_COORD_RAS); igtl::Matrix4x4 outMatrix = {{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.0,0.0,0.0}}; imageReceiveMsg2->GetMatrix(outMatrix); EXPECT_TRUE(MatrixComparison(outMatrix, inMatrix, ABS_ERROR)); int r = memcmp(imageReceiveMsg2->GetPackFragmentPointer(2), (unsigned char*)test_image, TEST_IMAGE_MESSAGE_SIZE); EXPECT_EQ(r, 0); } TEST(ImageMessage2Test, FragmentImageTest) { EXPECT_TRUE(true); /* int TEST_FRAGMENTIMAGE_MESSAGE_SIZE = TEST_IMAGE_MESSAGE_SIZE/2; unsigned char test_fragmentImage[TEST_FRAGMENTIMAGE_MESSAGE_SIZE]; memcpy(test_fragmentImage, test_image_message+IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE+TEST_FRAGMENTIMAGE_MESSAGE_SIZE, TEST_FRAGMENTIMAGE_MESSAGE_SIZE); // copy the last half of the image unsigned char * charwholeImagePointer = (unsigned char *)imageSendMsg2->GetScalarPointer(); EXPECT_EQ(strcmp((const char *)charwholeImagePointer, (const char *)test_image), 0); imageSendMsg2->SetScalarPointer((void*)test_fragmentImage); unsigned char * fragmentImagePointer = (unsigned char *)imageSendMsg2->GetScalarPointer(); EXPECT_NE(strcmp((const char *)charwholeImagePointer, (const char *)fragmentImagePointer),0); EXPECT_EQ(strcmp((const char *)fragmentImagePointer, (const char *)(test_image_message+IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE+TEST_FRAGMENTIMAGE_MESSAGE_SIZE)),0); */ } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlImageMessageTest.cxx000066400000000000000000000121131501024245700222430ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlImageMessage.h" #include "igtlutil/igtl_test_data_image.h" #include "igtlMessageDebugFunction.h" #include "igtl_types.h" #include "igtl_header.h" #include "igtl_image.h" #include "igtl_util.h" #include "igtlTestConfig.h" #include "string.h" igtl::ImageMessage::Pointer imageSendMsg = igtl::ImageMessage::New(); igtl::ImageMessage::Pointer imageReceiveMsg = igtl::ImageMessage::New(); float inT[4] = {-0.954892f, 0.196632f, -0.222525f, 0.0}; float inS[4] = {-0.196632f, 0.142857f, 0.970014f, 0.0}; float inN[4] = {0.222525f, 0.970014f, -0.0977491f, 0.0}; float inOrigin[4] = {46.0531f,19.4709f,46.0531f, 1.0}; igtl::Matrix4x4 inMatrix = {{inT[0],inS[0],inN[0],inOrigin[0]}, {inT[1],inS[1],inN[1],inOrigin[1]}, {inT[2],inS[2],inN[2],inOrigin[2]}, {inT[3],inS[3],inN[3],inOrigin[3]}}; int size[3] = {50, 50, 1}; // image dimension float spacing[3] = {1.0f, 1.0f, 1.0f}; // spacing (mm/pixel) int svsize[3] = {50, 50, 1}; // sub-volume size int svoffset[3] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage::TYPE_UINT8;// scalar type void BuildUp() { imageSendMsg = igtl::ImageMessage::New(); imageSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); imageSendMsg->SetTimeStamp(0, 1234567892); imageSendMsg->SetDeviceName("DeviceName"); //Initialization of a image message imageSendMsg->SetDimensions(size); imageSendMsg->SetSpacing(spacing); imageSendMsg->SetScalarType(scalarType); imageSendMsg->SetSubVolume(svsize, svoffset); imageSendMsg->SetNumComponents(1); imageSendMsg->SetScalarType(IGTL_IMAGE_STYPE_TYPE_UINT8); imageSendMsg->SetEndian(IGTL_IMAGE_ENDIAN_LITTLE); imageSendMsg->SetCoordinateSystem(IGTL_IMAGE_COORD_RAS); imageSendMsg->SetMatrix(inMatrix); imageSendMsg->AllocateScalars(); memcpy((void*)imageSendMsg->GetScalarPointer(), test_image_message+IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE, TEST_IMAGE_MESSAGE_SIZE);//here m_Image is set. imageSendMsg->Pack(); } TEST(ImageMessageTest, Pack) { BuildUp(); int r = memcmp((const void*)imageSendMsg->GetPackPointer(), (const void*)test_image_message, (size_t)(IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE)); EXPECT_EQ(r, 0); } TEST(ImageMessageTest, Unpack) { BuildUp(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)imageSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); imageReceiveMsg->SetMessageHeader(headerMsg); imageReceiveMsg->AllocatePack(); memcpy(imageReceiveMsg->GetPackBodyPointer(), imageSendMsg->GetPackBodyPointer(), IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE); imageReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)imageReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "IMAGE"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE); int returnSize[3] = {0,0,0}; imageReceiveMsg->GetDimensions(returnSize); EXPECT_THAT(returnSize,testing::ElementsAreArray(size)); float returnSpacing[3] = {0.0f,0.0f,0.0f}; imageReceiveMsg->GetSpacing(returnSpacing); EXPECT_TRUE(ArrayFloatComparison(returnSpacing, spacing, 3, ABS_ERROR)); int returnSvsize[3] = {0,0,0}, returnSvoffset[3] = {0,0,0}; imageReceiveMsg->GetSubVolume(returnSvsize, returnSvoffset); EXPECT_THAT(returnSvsize,testing::ElementsAreArray(svsize)); EXPECT_THAT(returnSvoffset,testing::ElementsAreArray(svoffset)); EXPECT_EQ(imageReceiveMsg->GetScalarType(), IGTL_IMAGE_STYPE_TYPE_UINT8); EXPECT_EQ(imageReceiveMsg->GetEndian(), IGTL_IMAGE_ENDIAN_LITTLE); EXPECT_EQ(imageReceiveMsg->GetCoordinateSystem(), IGTL_IMAGE_COORD_RAS); igtl::Matrix4x4 outMatrix = {{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.0,0.0,0.0}}; imageReceiveMsg->GetMatrix(outMatrix); EXPECT_TRUE(MatrixComparison(outMatrix, inMatrix, ABS_ERROR)); //The imageHeader is byte-wized converted, so we skip the comparison of the image header. int r = memcmp((const char*)imageReceiveMsg->GetPackBodyPointer()+IGTL_IMAGE_HEADER_SIZE, (const void*)(test_image_message+IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE), (size_t)(TEST_IMAGE_MESSAGE_SIZE)); EXPECT_EQ(r, 0); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlImageMetaMessageTest.cxx000066400000000000000000000161721501024245700230630ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlImageMetaMessage.h" #include "igtlutil/igtl_test_data_imgmeta.h" #include "igtlMessageDebugFunction.h" #include "igtl_imgmeta.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::ImageMetaElement::Pointer imageMetaElement0 = igtl::ImageMetaElement::New(); igtl::ImageMetaElement::Pointer imageMetaElement1 = igtl::ImageMetaElement::New(); igtl::ImageMetaElement::Pointer imageMetaElement2 = igtl::ImageMetaElement::New(); igtl::ImageMetaMessage::Pointer imageMetaSendMsg; igtl::ImageMetaMessage::Pointer imageMetaReceiveMsg; void BuildUpLabelElements() { igtl::TimeStamp::Pointer timestamp = igtl::TimeStamp::New(); timestamp->SetTime((igtlUint64)1234567892);//1234567850,1234567870,1234567890 are all fractions imageMetaElement0->SetName("IMAGE_DESCRIPTION_0"); imageMetaElement0->SetDeviceName("IMAGE_0"); imageMetaElement0->SetModality("CT"); imageMetaElement0->SetPatientName("PATIENT_0"); imageMetaElement0->SetPatientID("PATIENT_ID_0"); imageMetaElement0->SetTimeStamp(timestamp); imageMetaElement0->SetScalarType(IGTL_IMAGE_STYPE_TYPE_UINT16); imageMetaElement0->SetSize(512,512,64); timestamp = igtl::TimeStamp::New(); timestamp->SetTime((igtlUint64)1234567896); imageMetaElement1->SetName("IMAGE_DESCRIPTION_1"); imageMetaElement1->SetDeviceName("IMAGE_1"); imageMetaElement1->SetModality("MRI"); imageMetaElement1->SetPatientName("PATIENT_1"); imageMetaElement1->SetPatientID("PATIENT_ID_1"); imageMetaElement1->SetTimeStamp(timestamp); imageMetaElement1->SetScalarType(IGTL_IMAGE_STYPE_TYPE_UINT16); imageMetaElement1->SetSize(256,128,32); timestamp = igtl::TimeStamp::New(); timestamp->SetTime((igtl_uint64)1234567900); imageMetaElement2->SetName("IMAGE_DESCRIPTION_2"); imageMetaElement2->SetDeviceName("IMAGE_2"); imageMetaElement2->SetModality("PET"); imageMetaElement2->SetPatientName("PATIENT_2"); imageMetaElement2->SetPatientID("PATIENT_ID_2"); imageMetaElement2->SetTimeStamp(timestamp); imageMetaElement2->SetScalarType(IGTL_IMAGE_STYPE_TYPE_UINT16); imageMetaElement2->SetSize(256,256,32); timestamp = igtl::TimeStamp::New(); timestamp->SetTime((igtlUint64)1234567892); imageMetaSendMsg = igtl::ImageMetaMessage::New(); imageMetaSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); imageMetaSendMsg->SetDeviceName("DeviceName"); imageMetaSendMsg->SetTimeStamp(timestamp); imageMetaSendMsg->AddImageMetaElement(imageMetaElement0); imageMetaSendMsg->AddImageMetaElement(imageMetaElement1); imageMetaSendMsg->AddImageMetaElement(imageMetaElement2); imageMetaSendMsg->Pack(); } TEST(ImageMetaMessageTest, TimeStampTrival) { igtl::TimeStamp::Pointer timestamp = igtl::TimeStamp::New(); igtlUint32 tm = 1234567892; igtlUint32 tm_forward = igtl_frac_to_nanosec(tm); igtlUint32 tm_return; //= igtl_nanosec_to_frac(tm_forward); tm_return = igtl_nanosec_to_frac(tm_forward); EXPECT_EQ(tm_return, tm); } TEST(ImageMetaMessageTest, Pack) { BuildUpLabelElements(); int r = memcmp((const void*)imageMetaSendMsg->GetPackPointer(), (const void*)test_imgmeta_message, (size_t)(IGTL_HEADER_SIZE)); TestDebugCharArrayCmp(imageMetaSendMsg->GetPackPointer(),test_imgmeta_message, 58); EXPECT_EQ(r, 0); r = memcmp((const void*)imageMetaSendMsg->GetPackBodyPointer(), (const void*)(test_imgmeta_message+(size_t)(IGTL_HEADER_SIZE)), IGTL_IMGMETA_ELEMENT_SIZE*3 ); EXPECT_EQ(r, 0); } TEST(ImageMetaMessageTest, Unpack) { BuildUpLabelElements(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)imageMetaSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); imageMetaReceiveMsg = igtl::ImageMetaMessage::New(); imageMetaReceiveMsg->InitPack(); imageMetaReceiveMsg->SetMessageHeader(headerMsg); imageMetaReceiveMsg->AllocatePack(); memcpy(imageMetaReceiveMsg->GetPackBodyPointer(), imageMetaSendMsg->GetPackBodyPointer(), IGTL_IMGMETA_ELEMENT_SIZE*3); imageMetaReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)imageMetaReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "IMGMETA"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_IMGMETA_ELEMENT_SIZE*3); std::vector > groundTruthSize(3,std::vector(3)); igtlUint16 tempIni1[3] = {512,512,64}; groundTruthSize[0].assign(tempIni1,tempIni1+3); igtlUint16 tempIni2[3] = {256,128,32}; groundTruthSize[1].assign(tempIni2,tempIni2+3); igtlUint16 tempIni3[3] = {256,256,32}; groundTruthSize[2].assign(tempIni3,tempIni3+3); std::vector name; name.push_back((char*)"IMAGE_DESCRIPTION_0"); name.push_back((char*)"IMAGE_DESCRIPTION_1"); name.push_back((char*)"IMAGE_DESCRIPTION_2"); std::vector deviceName; deviceName.push_back((char*)"IMAGE_0"); deviceName.push_back((char*)"IMAGE_1"); deviceName.push_back((char*)"IMAGE_2"); std::vector modality; modality.push_back((char*)"CT\0"); modality.push_back((char*)"MRI"); modality.push_back((char*)"PET"); std::vector patientName; patientName.push_back((char*)"PATIENT_0"); patientName.push_back((char*)"PATIENT_1"); patientName.push_back((char*)"PATIENT_2"); std::vector patientID; patientID.push_back((char*)"PATIENT_ID_0"); patientID.push_back((char*)"PATIENT_ID_1"); patientID.push_back((char*)"PATIENT_ID_2"); std::vector nanoSecond(3); nanoSecond[0]=287445240; nanoSecond[1]=287445241; nanoSecond[2]=287445242; for (int i = 0; i<3;++i) { igtl::ImageMetaElement::Pointer elem = igtl::ImageMetaElement::New(); imageMetaSendMsg->GetImageMetaElement(i, elem); EXPECT_EQ(strncmp((char*)(elem->GetName()), name[i], 19),0); EXPECT_EQ(strncmp((char*)(elem->GetDeviceName()), deviceName[i], 7),0); EXPECT_EQ(strncmp((char*)(elem->GetModality()), modality[i], 3),0); EXPECT_EQ(strncmp((char*)(elem->GetPatientName()), patientName[i], 9),0); EXPECT_EQ(strncmp((char*)(elem->GetPatientID()), patientID[i], 12),0); igtl::TimeStamp::Pointer timestamp = igtl::TimeStamp::New(); elem->GetTimeStamp(timestamp); EXPECT_EQ(timestamp->GetNanosecond(), nanoSecond[i]); EXPECT_EQ(timestamp->GetSecond(), 0); igtlUint16 returnedSize[3] ={0,0,0}; elem->GetSize(returnedSize); EXPECT_THAT(returnedSize, testing::ElementsAreArray(groundTruthSize[i])); EXPECT_EQ(elem->GetScalarType(), (int)IGTL_IMAGE_STYPE_TYPE_UINT16); } } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlLabelMetaMessageTest.cxx000066400000000000000000000124631501024245700230570ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlLabelMetaMessage.h" #include "igtlutil/igtl_test_data_lbmeta.h" #include "igtlutil/igtl_lbmeta.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::LabelMetaElement::Pointer labelMetaElement0 = igtl::LabelMetaElement::New(); igtl::LabelMetaElement::Pointer labelMetaElement1 = igtl::LabelMetaElement::New(); igtl::LabelMetaElement::Pointer labelMetaElement2 = igtl::LabelMetaElement::New(); igtl::LabelMetaMessage::Pointer labelMetaSendMsg = igtl::LabelMetaMessage::New(); igtl::LabelMetaMessage::Pointer labelMetaReceiveMsg = igtl::LabelMetaMessage::New(); void BuildUpLabelElements() { labelMetaElement0->SetName("LABEL_DESCRIPTION_0"); labelMetaElement0->SetDeviceName("LABEL_0"); labelMetaElement0->SetLabel(1); labelMetaElement0->SetRGBA(255,0,0,255); labelMetaElement0->SetSize(256,128,32); labelMetaElement0->SetOwner("IMAGE_0"); labelMetaElement1->SetName("LABEL_DESCRIPTION_1"); labelMetaElement1->SetDeviceName("LABEL_1"); labelMetaElement1->SetLabel(2); labelMetaElement1->SetRGBA(0,255,0,255); labelMetaElement1->SetSize(256,128,32); labelMetaElement1->SetOwner("IMAGE_0"); labelMetaElement2->SetName("LABEL_DESCRIPTION_2"); labelMetaElement2->SetDeviceName("LABEL_2"); labelMetaElement2->SetLabel(3); labelMetaElement2->SetRGBA(0,0,255,255); labelMetaElement2->SetSize(256,128,32); labelMetaElement2->SetOwner("IMAGE_0"); labelMetaSendMsg = igtl::LabelMetaMessage::New(); labelMetaSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); labelMetaSendMsg->SetDeviceName("DeviceName"); labelMetaSendMsg->SetTimeStamp(0, 1234567892); labelMetaSendMsg->AddLabelMetaElement(labelMetaElement0); labelMetaSendMsg->AddLabelMetaElement(labelMetaElement1); labelMetaSendMsg->AddLabelMetaElement(labelMetaElement2); labelMetaSendMsg->Pack(); } TEST(LabelMetaMessageTest, Pack) { BuildUpLabelElements(); int r = memcmp((const void*)labelMetaSendMsg->GetPackPointer(), (const void*)test_lbmeta_message, (size_t)(IGTL_HEADER_SIZE)); //The header comparison, however, the crc is different. because the igtl_lbmeta_get_crc() is different from the crc generation in MessageBase::Pack() EXPECT_EQ(r, 0); r = memcmp((const void*)labelMetaSendMsg->GetPackBodyPointer(), (const void*)(test_lbmeta_message+(size_t)(IGTL_HEADER_SIZE)), IGTL_LBMETA_ELEMENT_SIZE*3 ); EXPECT_EQ(r, 0); } TEST(LabelMetaMessageTest, Unpack) { BuildUpLabelElements(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)labelMetaSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); labelMetaReceiveMsg->SetMessageHeader(headerMsg); labelMetaReceiveMsg->AllocatePack(); memcpy(labelMetaReceiveMsg->GetPackBodyPointer(), labelMetaSendMsg->GetPackBodyPointer(), IGTL_LBMETA_ELEMENT_SIZE*3); labelMetaReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)labelMetaReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "LBMETA"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, 348); std::vector > groundTruthRGBA(3,std::vector(4)); igtlUint8 tempIni1[4] = {255,0,0,255}; groundTruthRGBA[0].assign(tempIni1,tempIni1+4); igtlUint8 tempIni2[4] = {0,255,0,255}; groundTruthRGBA[1].assign(tempIni2,tempIni2+4); igtlUint8 tempIni3[4] = {0,0,255,255}; groundTruthRGBA[2].assign(tempIni3,tempIni3+4); igtlUint16 groundTruthSize[3] = {256,128,32}; std::vector labelDescription; labelDescription.push_back((char*)"LABEL_DESCRIPTION_0"); labelDescription.push_back((char*)"LABEL_DESCRIPTION_1"); labelDescription.push_back((char*)"LABEL_DESCRIPTION_2"); std::vector label; label.push_back((char*)"LABEL_0"); label.push_back((char*)"LABEL_1"); label.push_back((char*)"LABEL_2"); for (int i = 0; i<3;++i) { igtl::LabelMetaElement::Pointer elem = igtl::LabelMetaElement::New(); labelMetaReceiveMsg->GetLabelMetaElement(i, elem); EXPECT_EQ(strncmp((char*)(elem->GetName()), labelDescription[i], 19),0); EXPECT_EQ(strncmp((char*)(elem->GetDeviceName()), label[i], 7),0); igtlUint8 returnedRGBA[4] ={0,0,0,0}; elem->GetRGBA(returnedRGBA); EXPECT_THAT(returnedRGBA, testing::ElementsAreArray(groundTruthRGBA[i])); igtlUint16 returnedSize[3] ={0,0,0}; elem->GetSize(returnedSize); EXPECT_THAT(returnedSize, testing::ElementsAreArray(groundTruthSize)); EXPECT_EQ(strncmp((char*)elem->GetOwner(), "IMAGE_0", 7),0); } } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlMessageBaseTest.cxx000066400000000000000000000046101501024245700220760ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlMessageBase.h" #include "igtlMessageHeader.h" #include "igtlTestConfig.h" #include "string.h" TEST(MessageBaseTest, InitializationTest) { igtl::MessageBase::Pointer messageBaseTest = igtl::MessageBase::New(); messageBaseTest->SetDeviceName("DeviceTest"); EXPECT_STREQ(messageBaseTest->GetDeviceName(), "DeviceTest"); messageBaseTest->InitPack(); EXPECT_STREQ(messageBaseTest->GetDeviceName(),""); } TEST(MessageBaseTest, SetDeviceNameTest) { igtl::MessageBase::Pointer messageBaseTest = igtl::MessageBase::New(); messageBaseTest->InitPack(); EXPECT_STREQ(messageBaseTest->GetDeviceName(), ""); messageBaseTest->SetDeviceName("DeviceTest"); EXPECT_STREQ(messageBaseTest->GetDeviceName(), "DeviceTest"); } TEST(MessageBaseTest, GetDeviceNameTest) { igtl::MessageBase::Pointer messageBaseTest = igtl::MessageBase::New(); messageBaseTest->SetDeviceName("DeviceTest"); EXPECT_STREQ(messageBaseTest->GetDeviceName(), "DeviceTest"); } TEST(MessageBaseTest, TimeStampTest) { igtl::MessageBase::Pointer messageBaseTest = igtl::MessageBase::New(); messageBaseTest->SetTimeStamp(1,2); unsigned int sec=0, nanosec=0; messageBaseTest->GetTimeStamp(&sec,&nanosec); EXPECT_EQ(sec, 1); EXPECT_EQ(nanosec, 2); igtl::TimeStamp::Pointer ts_input = igtl::TimeStamp::New(); ts_input->SetTime(123,500000000); //nanosecond can not be larger or equal to 1e9. //5e8 nanosecond equals 2147483647 frac second. messageBaseTest->SetTimeStamp(ts_input); messageBaseTest->GetTimeStamp(&sec,&nanosec); EXPECT_EQ(sec, 123); EXPECT_EQ(nanosec, 2147483648); } TEST(MessageBaseTest, UNPACKTEST) { igtl::MessageBase::Pointer messageBaseTest = igtl::MessageBase::New(); messageBaseTest->AllocateBuffer(); int status = messageBaseTest->Unpack(); EXPECT_EQ(status, static_cast(messageBaseTest->UNPACK_HEADER)); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlMessageFactoryTest.cxx000066400000000000000000000047541501024245700226440ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 namespace igtl { // Create a nonsense message type that won't exist in main library. igtlCreateDefaultQueryMessageClass(BananaMessage, "BANANA") } /** * Author: Matt Clarkson (m.clarkson@ucl.ac.uk). */ int main(int , char * [] ) { igtl::MessageFactory::Pointer factory = igtl::MessageFactory::New(); igtl::MessageHeader::Pointer header = NULL; if (factory->IsValid(header)) { std::cerr << "A null header is not valid." << std::endl; return EXIT_FAILURE; } header = igtl::MessageHeader::New(); if (factory->IsValid(header)) { std::cerr << "A header without a DeviceType e.g. STRING, TRANSFORM is invalid." << std::endl; return EXIT_FAILURE; } igtl::TransformMessage::Pointer transformMessage = igtl::TransformMessage::New(); if (!factory->IsValid(transformMessage.GetPointer())) { std::cerr << "The IsValid method should check for not null, and a valid DeviceType. TRANSFORM should be valid." << std::endl; return EXIT_FAILURE; } // Test with an invalid message. try { igtl::BananaMessage::Pointer bananaMessage = igtl::BananaMessage::New(); // Check firstly its not valid. if (factory->IsValid(bananaMessage.GetPointer())) { std::cerr << "The IsValid method should fail for BANANA messages." << std::endl; return EXIT_FAILURE; } factory->GetMessage(bananaMessage.GetPointer()); throw std::logic_error("Should not reach this line, as the previous line should throw invalid_argument, as BANANA messages are not valid."); } catch (const std::invalid_argument& e) { std::cerr << "Caught exception e=" << e.what() << std::endl; } catch (const std::exception& e) { std::cerr << "Caught std::exception, which should not happen. e=" << e.what() << std::endl; throw e; } return EXIT_SUCCESS; } openigtlink-3.0.0/Testing/igtlMessageFormat2TestMacro.h000066400000000000000000000035341501024245700231510ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C++ Web page: http://openigtlink.org/ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __igltMessageFormat2TestMarco_h #define __igltMessageFormat2TestMarco_h #include #define EXTENDED_CONTENT_SIZE 69 // the extended content size variable sums up the size of the Extended header, meta data header and meta data. #define igtlMetaDataAddElementMacro(object) \ object->SetHeaderVersion(IGTL_HEADER_VERSION_2);\ IANA_ENCODING_TYPE codingScheme = IANA_TYPE_US_ASCII; /* 3 corresponding to US-ASCII */ \ object->SetMetaDataElement("First patient age", codingScheme, "22");\ object->SetMetaDataElement("Second patient age",codingScheme, "25");\ object->SetMessageID(1); #define igtlMetaDataComparisonMacro(object) \ std::vector groundTruth(0); \ groundTruth.push_back("First patient age");\ groundTruth.push_back("Second patient age");\ \ std::vector groundTruthAge(0);\ groundTruthAge.push_back("22");\ groundTruthAge.push_back("25");\ \ EXPECT_EQ(object->GetMessageID(),1);\ \ \ int i = 0;\ for (igtl::MessageBase::MetaDataMap::const_iterator it = object->GetMetaData().begin(); it != object->GetMetaData().end(); ++it, ++i)\ {\ EXPECT_STREQ(it->first.c_str(), groundTruth[i].c_str());\ EXPECT_EQ(it->second.first, IANA_TYPE_US_ASCII);\ EXPECT_STREQ(it->second.second.c_str(), groundTruthAge[i].c_str());\ } #endif // __igltMessageFormat2TestMarco_h openigtlink-3.0.0/Testing/igtlMultiThreaderTest1.cxx000066400000000000000000000056411501024245700225560ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ //========================================================================= // // MultiThreader Test 1 --- Single Method Test // // This test check the behaviour of igtl::MultiThreader::SingleMethodExecute() // and igtl::MutexLock. // The test create NUM_THREAD threads from a single method that repeats: // // s1 = s; // sleep(interval) // s2 = s; // s = s1 + s2; // // for NUM_REPEAT times, where 's' is a global variable (shared by all // threads) initialized with 1, and 's1', 's2' and 'interval' are local // variables. 'interval' differs from thread to thread. // If the threads work correctly, and the code block above is properly // protected by a semaphore, 's' finally becomes 2^(NUM_REPEAT * NUM_THREAD-1). // //========================================================================= #include "igtlMultiThreader.h" #include "igtlOSUtil.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 // NOTE: (NUM_THREAD + NUM_REPEAT) < 32 on 32-bit environment #if IGTL_MAX_THREADS > 1 #define NUM_THREAD 5 #define NUM_REPEAT 4 #else #define NUM_THREAD 1 #define NUM_REPEAT 4 #endif typedef struct { int nloop; int *sum; igtl::MutexLock::Pointer glock; } ThreadData; void* ThreadFunction(void* ptr) { // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); int id = info->ThreadID; // Set interval at 100 * id (ms) long interval = 10*id; ThreadData* data = static_cast(info->UserData); int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; for (int i = 0; i < nloop; i ++) { glock->Lock(); int s1 = *(data->sum); igtl::Sleep(interval); int s2 = *(data->sum); *(data->sum) = s1 + s2; glock->Unlock(); } return NULL; } int main(int, char * [] ) { igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); int sum = 1; ThreadData td; td.nloop = NUM_REPEAT; td.sum = ∑ td.glock = glock; igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); threader->SetNumberOfThreads(NUM_THREAD); threader->SetSingleMethod((igtl::ThreadFunctionType) &ThreadFunction, &td); threader->SingleMethodExecute(); int answer = 0x00000001; answer <<= (NUM_THREAD * NUM_REPEAT); //std::cerr << "sum = " << sum << " answer = " << answer << std::endl; if (sum == answer) { return EXIT_SUCCESS; } else { return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlMultiThreaderTest2.cxx000066400000000000000000000125621501024245700225570ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ //========================================================================= // // MultiThreader Test 2 --- Multiple Method Test // // This test check the behaviour of igtl::MultiThreader::MultipleMethodExecute() // and igtl::MutexLock. // The test create NUM_THREAD threads from methods that repeats: // // s1 = s; // sleep(interval) // s2 = s; // s = s1 + s2; // // for NUM_REPEAT times, where 's' is a global variable (shared by all // threads) initialized with 1, and 's1', 's2' and 'interval' are local // variables. 'interval' differs from thread to thread. // If the threads work correctly, and the code block above is properly // protected by a semaphore, 's' finally becomes 2^(NUM_REPEAT * NUM_THREAD-1). // //========================================================================= #include "igtlMultiThreader.h" #include "igtlOSUtil.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 // NOTE: (NUM_THREAD + NUM_REPEAT) < 32 on 32-bit environment #if IGTL_MAX_THREADS > 1 #define NUM_THREAD 5 #define NUM_REPEAT 4 #else #define NUM_THREAD 1 #define NUM_REPEAT 4 #endif typedef struct { int nloop; int *sum; igtl::MutexLock::Pointer glock; } ThreadData; void* ThreadFunction1(void* ptr) { long interval = 10; // (ms) // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ThreadData* data = static_cast(info->UserData); int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; for (int i = 0; i < nloop; i ++) { glock->Lock(); int s1 = *(data->sum); igtl::Sleep(interval); int s2 = *(data->sum); *(data->sum) = s1 + s2; glock->Unlock(); } return NULL; } void* ThreadFunction2(void* ptr) { long interval = 20; // (ms) // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ThreadData* data = static_cast(info->UserData); int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; for (int i = 0; i < nloop; i ++) { glock->Lock(); int s1 = *(data->sum); igtl::Sleep(interval); int s2 = *(data->sum); *(data->sum) = s1 + s2; glock->Unlock(); } return NULL; } void* ThreadFunction3(void* ptr) { long interval = 30; // (ms) // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ThreadData* data = static_cast(info->UserData); int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; for (int i = 0; i < nloop; i ++) { glock->Lock(); int s1 = *(data->sum); igtl::Sleep(interval); int s2 = *(data->sum); *(data->sum) = s1 + s2; glock->Unlock(); } return NULL; } void* ThreadFunction4(void* ptr) { long interval = 40; // (ms) // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ThreadData* data = static_cast(info->UserData); int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; for (int i = 0; i < nloop; i ++) { glock->Lock(); int s1 = *(data->sum); igtl::Sleep(interval); int s2 = *(data->sum); *(data->sum) = s1 + s2; glock->Unlock(); } return NULL; } void* ThreadFunction5(void* ptr) { long interval = 50; // (ms) // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ThreadData* data = static_cast(info->UserData); int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; for (int i = 0; i < nloop; i ++) { glock->Lock(); int s1 = *(data->sum); igtl::Sleep(interval); int s2 = *(data->sum); *(data->sum) = s1 + s2; glock->Unlock(); } return NULL; } int main(int , char * [] ) { igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); int sum = 1; ThreadData td; td.nloop = NUM_REPEAT; td.sum = ∑ td.glock = glock; igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); threader->SetNumberOfThreads(NUM_THREAD); threader->SetMultipleMethod(0, (igtl::ThreadFunctionType) &ThreadFunction1, &td); #if IGTL_MAX_THREADS > 1 threader->SetMultipleMethod(1, (igtl::ThreadFunctionType) &ThreadFunction2, &td); threader->SetMultipleMethod(2, (igtl::ThreadFunctionType) &ThreadFunction3, &td); threader->SetMultipleMethod(3, (igtl::ThreadFunctionType) &ThreadFunction4, &td); threader->SetMultipleMethod(4, (igtl::ThreadFunctionType) &ThreadFunction5, &td); #endif threader->MultipleMethodExecute(); int answer = 0x00000001; answer <<= (NUM_THREAD * NUM_REPEAT); //std::cerr << "sum = " << sum << " answer = " << answer << std::endl; if (sum == answer) { return EXIT_SUCCESS; } else { return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlMultiThreaderTest3.cxx000066400000000000000000000065441501024245700225630ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ //========================================================================= // // MultiThreader Test 1 --- Spawn Thread Test // // This test check the behaviour of igtl::MultiThreader::SpawnThread // and igtl::MutexLock. // The test create NUM_THREAD threads from a single method that repeats: // // s1 = s; // sleep(interval) // s2 = s; // s = s1 + s2; // // for NUM_REPEAT times, where 's' is a global variable (shared by all // threads) initialized with 1, and 's1', 's2' and 'interval' are local // variables. 'interval' differs from thread to thread. // If the threads work correctly, and the code block above is properly // protected by a semaphore, 's' finally becomes 2^(NUM_REPEAT * NUM_THREAD-1). // //========================================================================= #include "igtlMultiThreader.h" #include "igtlOSUtil.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 // NOTE: (NUM_THREAD + NUM_REPEAT) < 32 on 32-bit environment #if IGTL_MAX_THREADS > 1 #define NUM_THREAD 5 #define NUM_REPEAT 4 #else #define NUM_THREAD 1 #define NUM_REPEAT 4 #endif typedef struct { int nloop; int *sum; igtl::MutexLock::Pointer glock; } ThreadData; void* ThreadFunction(void* ptr) { // Get thread information igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); int id = info->ThreadID; // Set interval at 100 * id (ms) long interval = 10*id; ThreadData* data = static_cast(info->UserData); int nloop = data->nloop; igtl::MutexLock::Pointer glock = data->glock; for (int i = 0; i < nloop; i ++) { glock->Lock(); int s1 = *(data->sum); igtl::Sleep(interval); int s2 = *(data->sum); *(data->sum) = s1 + s2; glock->Unlock(); } return NULL; } int main(int , char * [] ) { igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); int sum = 1; ThreadData td; td.nloop = NUM_REPEAT; td.sum = ∑ td.glock = glock; igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); int id1 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); int id2 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); int id3 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); int id4 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); int id5 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td); // wait for the threads threader->TerminateThread(id1); threader->TerminateThread(id2); threader->TerminateThread(id3); threader->TerminateThread(id4); threader->TerminateThread(id5); int answer = 0x00000001; answer <<= (NUM_THREAD * NUM_REPEAT); //std::cerr << "sum = " << sum << " answer = " << answer << std::endl; if (sum == answer) { return EXIT_SUCCESS; } else { return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlNDArrayMessageTest.cxx000066400000000000000000000103251501024245700225240ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlNDArrayMessage.h" #include "igtlutil/igtl_test_data_ndarray.h" #include "igtl_ndarray.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" #define NDARRAY_MESSAGE_BODY_SIZE 488 igtl::NDArrayMessage::Pointer NDArraySendMsg = igtl::NDArrayMessage::New(); igtl::NDArrayMessage::Pointer NDArrayReceiveMsg = igtl::NDArrayMessage::New(); igtl::Array array; std::vector size(3); void BuildUpArrayElements() { size[0] = 5; size[1] = 4; size[2] = 3; array.SetSize(size); int i,j,k; igtl_float64 arrayFloat[120]; for (i = 0; i < size[0]; i ++) { for (j = 0; j < size[1]; j ++) { for (k = 0; k < size[2]; k ++) { arrayFloat[i*(4*3) + j*3 + k] = (igtl_float64) (i*(4*3) + j*3 + k); } } } array.SetArray((void*) arrayFloat); NDArraySendMsg = igtl::NDArrayMessage::New(); NDArraySendMsg->SetDeviceName("DeviceName"); NDArraySendMsg->SetArray(igtl::NDArrayMessage::TYPE_FLOAT64, &array); NDArraySendMsg->SetTimeStamp(0, 1234567892); NDArraySendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); NDArraySendMsg->Pack(); } TEST(NDArrayMessageTest, SetAndGetValue) { BuildUpArrayElements(); igtl::ArrayBase::IndexType index(array.GetSize()); index.at(0) = 0; index.at(1) = 0; index.at(2) = 0; igtl_float64 inputValue = 3.0; array.SetValue(index, inputValue); igtl_float64 returnValue = 1.0; array.GetValue(index, returnValue); EXPECT_FLOAT_EQ(inputValue, returnValue); } TEST(NDArrayMessageTest, Pack) { BuildUpArrayElements(); int r = memcmp((const void*)NDArraySendMsg->GetPackPointer(), (const void*)(test_ndarray_message_header), IGTL_HEADER_SIZE); EXPECT_EQ(r, 0); r = memcmp((const void*)NDArraySendMsg->GetPackBodyPointer(), (const void*)(test_ndarray_message_body), NDArraySendMsg->GetPackSize()-IGTL_HEADER_SIZE); EXPECT_EQ(r, 0); } TEST(NDArrayMessageTest, Unpack) { BuildUpArrayElements(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)NDArraySendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); NDArrayReceiveMsg->InitPack(); NDArrayReceiveMsg->SetMessageHeader(headerMsg); NDArrayReceiveMsg->AllocatePack(); memcpy(NDArrayReceiveMsg->GetPackBodyPointer(), NDArraySendMsg->GetPackBodyPointer(), NDARRAY_MESSAGE_BODY_SIZE); NDArrayReceiveMsg->Unpack(); memcpy(NDArrayReceiveMsg->GetPackBodyPointer(), test_ndarray_message_body, NDArraySendMsg->GetPackSize()-IGTL_HEADER_SIZE); NDArrayReceiveMsg->Unpack(); igtl::ArrayBase *tempArrayBase = NDArrayReceiveMsg->GetArray(); igtl_float64* arraytemp = (igtl_float64 *)tempArrayBase->GetRawArray(); int i,j,k; for (i = 0; i < size[0]; i ++) { for (j = 0; j < size[1]; j ++) { for (k = 0; k < size[2]; k ++) { EXPECT_EQ(i*(4*3) + j*3 + k, (igtl_float64)(*(arraytemp+i*(4*3) + j*3 + k))); } } } } TEST(NDArrayMessageTest, 64BitConversion) { igtl_ndarray_info info; igtl_ndarray_init_info(&info); info.dim = 3; info.type = igtl::NDArrayMessage::TYPE_FLOAT64; igtlUint16 sizeTemp[3] = {5,4,3}; info.size = sizeTemp; unsigned char *data = new unsigned char [480]; memcpy(data, (const void*)(test_ndarray_message_body+8), 480); info.array = (void*)data; unsigned char *dataArray = new unsigned char [488]; igtl_ndarray_pack(&info, dataArray, IGTL_TYPE_PREFIX_NONE); igtl_ndarray_info info_return; igtl_ndarray_init_info(&info_return); igtl_ndarray_unpack(IGTL_TYPE_PREFIX_NONE, dataArray, &info_return, 488); int r = memcmp(info.array, info_return.array,480); EXPECT_EQ(r, 0); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlPointMessageTest.cxx000066400000000000000000000121561501024245700223210ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlPointMessage.h" #include "igtlutil/igtl_test_data_point.h" #include "igtl_point.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::PointMessage::Pointer pointSendMsg = igtl::PointMessage::New(); igtl::PointMessage::Pointer pointReceiveMsg = igtl::PointMessage::New(); igtl::PointElement::Pointer pointElement0 = igtl::PointElement::New(); igtl::PointElement::Pointer pointElement1 = igtl::PointElement::New(); igtl::PointElement::Pointer pointElement2 = igtl::PointElement::New(); void BuildUpElements() { pointElement0->SetName("POINT_DESCRIPTION_0"); pointElement0->SetGroupName("Landmark"); pointElement0->SetRGBA(255,0,0,255); pointElement0->SetPosition(10.0, 15.0, 20.0); pointElement0->SetRadius(5.0); pointElement0->SetOwner("IMAGE_0"); pointElement1->SetName("POINT_DESCRIPTION_1"); pointElement1->SetGroupName("Landmark"); pointElement1->SetRGBA(0,255,0,255); pointElement1->SetPosition(25.0, 30.0, 35.0); pointElement1->SetRadius(3.0); pointElement1->SetOwner("IMAGE_0"); pointElement2->SetName("POINT_DESCRIPTION_2"); pointElement2->SetGroupName("Landmark"); pointElement2->SetRGBA(0,0,255,255); pointElement2->SetPosition(40.0, 45.0, 50.0); pointElement2->SetRadius(1.0); pointElement2->SetOwner("IMAGE_0"); pointSendMsg = igtl::PointMessage::New(); pointSendMsg->SetDeviceName("DeviceName"); pointSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); pointSendMsg->SetTimeStamp(0, 1234567892); pointSendMsg->AddPointElement(pointElement0); pointSendMsg->AddPointElement(pointElement1); pointSendMsg->AddPointElement(pointElement2); pointSendMsg->Pack(); } TEST(PointMessageTest, Pack) { BuildUpElements(); int r = memcmp((const void*)pointSendMsg->GetPackPointer(), (const void*)test_point_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)pointSendMsg->GetPackBodyPointer(), (const void*)(test_point_message+(size_t)(IGTL_HEADER_SIZE)), IGTL_POINT_ELEMENT_SIZE*3 ); EXPECT_EQ(r, 0); } TEST(PointMessageTest, Unpack) { BuildUpElements(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), pointSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); pointReceiveMsg = igtl::PointMessage::New(); pointReceiveMsg->SetMessageHeader(headerMsg); pointReceiveMsg->AllocatePack(); memcpy(pointReceiveMsg->GetPackBodyPointer(), pointSendMsg->GetPackBodyPointer(), IGTL_POINT_ELEMENT_SIZE*3); pointReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)pointReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "POINT"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_POINT_ELEMENT_SIZE*3); std::vector > groundTruthRGBA(3,std::vector(4)); igtlUint8 tempIni1[4] = {255,0,0,255}; groundTruthRGBA[0].assign(tempIni1,tempIni1+4); igtlUint8 tempIni2[4] = {0,255,0,255}; groundTruthRGBA[1].assign(tempIni2,tempIni2+4); igtlUint8 tempIni3[4] = {0,0,255,255}; groundTruthRGBA[2].assign(tempIni3,tempIni3+4); std::vector > groundTruthPos(3,std::vector(3)); igtlFloat32 tempFloat1[3] = {10.0,15.0,20.0}; groundTruthPos[0].assign(tempFloat1,tempFloat1+3); igtlFloat32 tempFloat2[3] = {25.0,30.0,35.0}; groundTruthPos[1].assign(tempFloat2,tempFloat2+3); igtlFloat32 tempFloat3[3] = {40.0,45.0,50.0}; groundTruthPos[2].assign(tempFloat3,tempFloat3+3); igtlFloat32 groundTruthRadius[3] = {5.0,3.0,1.0}; std::vector pointDescription; pointDescription.push_back((char*)"POINT_DESCRIPTION_0"); pointDescription.push_back((char*)"POINT_DESCRIPTION_1"); pointDescription.push_back((char*)"POINT_DESCRIPTION_2"); for (int i = 0; i<3;++i) { igtl::PointElement::Pointer elem = igtl::PointElement::New(); pointReceiveMsg->GetPointElement(i, elem); EXPECT_EQ(strncmp((char*)(elem->GetName()), pointDescription[i], 19),0); igtlUint8 returnedRGBA[4] ={0,0,0,0}; elem->GetRGBA(returnedRGBA); EXPECT_THAT(returnedRGBA, testing::ElementsAreArray(groundTruthRGBA[i])); igtlFloat32 returnedPosition[3] ={0,0,0}; elem->GetPosition(returnedPosition); EXPECT_THAT(returnedPosition, testing::ElementsAreArray(groundTruthPos[i])); EXPECT_EQ(elem->GetRadius(), groundTruthRadius[i]); EXPECT_EQ(strncmp((char*)elem->GetOwner(), "IMAGE_0", 7),0); } } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlPolyDataMessageTest.cxx000066400000000000000000000111101501024245700227320ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlPolyDataMessage.h" #include "igtlutil/igtl_test_data_polydata.h" #include "igtlMessageDebugFunction.h" #include "igtl_polydata.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" #include #define POLY_BODY_SIZE 300 igtl::PolyDataMessage::Pointer polyDataSendMsg = igtl::PolyDataMessage::New(); igtl::PolyDataMessage::Pointer polyDataReceiveMsg = igtl::PolyDataMessage::New(); igtl::PolyDataPointArray::Pointer polyPoint = igtl::PolyDataPointArray::New(); igtl::PolyDataCellArray::Pointer polyGon = igtl::PolyDataCellArray::New(); igtl::PolyDataAttribute::Pointer polyAttr = igtl::PolyDataAttribute::New(); static igtl_float32 points[8][3]={{0,0,0}, {1,0,0}, {1,1,0}, {0,1,0}, {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1}}; static igtl_uint32 polyArray[6][4]={{0,1,2,3}, {4,5,6,7}, {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7}}; static igtl_float32 attribute[8]={0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; std::vector >poly(6, std::list(4)); void BuildUpElements() { polyPoint->Clear(); polyGon->Clear(); for (int i =0; i<6; i++) { poly[i].assign(polyArray[i],polyArray[i]+4); } for (int i = 0; i < 8 ;i++) { polyPoint->AddPoint(points[i]); } for (int i = 0; i < 6 ;i++) { polyGon->AddCell(poly[i]); } polyAttr->SetType(IGTL_POLY_ATTR_TYPE_SCALAR); polyAttr->SetSize(8); polyAttr->SetName("attr"); polyAttr->SetData(attribute); polyDataSendMsg = igtl::PolyDataMessage::New(); polyDataSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); polyDataSendMsg->SetPoints(polyPoint.GetPointer()); polyDataSendMsg->SetPolygons(polyGon.GetPointer()); polyDataSendMsg->AddAttribute(polyAttr.GetPointer()); polyDataSendMsg->SetDeviceName("DeviceName"); polyDataSendMsg->SetTimeStamp(0, 1234567892); polyDataSendMsg->Pack(); } TEST(PolyDataMessageTest, Pack) { BuildUpElements(); int r = memcmp((const void*)polyDataSendMsg->GetPackPointer(), (const void*)test_polydata_message_header, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)polyDataSendMsg->GetPackBodyPointer(), (const void*)test_polydata_message_body, POLY_BODY_SIZE); EXPECT_EQ(r, 0); } TEST(PolyDataMessageTest, Unpack) { BuildUpElements(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)test_polydata_message_header, IGTL_HEADER_SIZE); headerMsg->Unpack(); polyDataReceiveMsg = igtl::PolyDataMessage::New(); polyDataReceiveMsg->SetMessageHeader(headerMsg); polyDataReceiveMsg->AllocatePack(); igtl_header *messageHeader = (igtl_header *)polyDataReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "POLYDATA"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, POLY_BODY_SIZE); memcpy(polyDataReceiveMsg->GetPackBodyPointer(), polyDataSendMsg->GetPackBodyPointer(), POLY_BODY_SIZE); polyDataReceiveMsg->Unpack(); igtl::PolyDataPointArray::Pointer pointUnpacked = polyDataReceiveMsg->GetPoints();; igtl::PolyDataCellArray::Pointer polygonUnpacked = polyDataReceiveMsg->GetPolygons(); igtl::PolyDataAttribute::Pointer attrUnpacked = polyDataReceiveMsg->GetAttribute(0); for (int i = 0; i<8; i++) { igtlFloat32 point[3] = {0,0,0}; pointUnpacked->GetPoint(i, point); EXPECT_TRUE(ArrayFloatComparison(point, points[i], 3, ABS_ERROR)); } for (int i = 0; i<6; i++) { igtl_uint32 polygon[4] = {0,0,0,0}; polygonUnpacked->GetCell(i, polygon); EXPECT_THAT(polygon, ::testing::ElementsAreArray(polyArray[i])); } igtl_float32 attributeValue[8]; for (int i = 0; i<8; i++) { igtl_float32 value[1]; attrUnpacked->GetNthData(i, value); attributeValue[i] = *value; } EXPECT_TRUE(ArrayFloatComparison(attributeValue, attribute,8,ABS_ERROR)); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlPositionMessageTest.cxx000066400000000000000000000121061501024245700230270ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlPositionMessage.h" #include "igtlutil/igtl_test_data_position.h" #include "igtlMessageDebugFunction.h" #include "igtl_position.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" #define PositionBodySize 28 igtl::PositionMessage::Pointer positionSendMsg = igtl::PositionMessage::New(); igtl::PositionMessage::Pointer positionReceiveMsg = igtl::PositionMessage::New(); TEST(PositionMessageTest, PackFormateVersion1) { positionSendMsg->AllocatePack(); positionSendMsg->SetTimeStamp(0, 1234567892); positionSendMsg->SetDeviceName("DeviceName"); positionSendMsg->SetPosition(46.0531f, 19.4709f, 46.0531f); positionSendMsg->SetQuaternion(0.0f, 0.5773502691f, 0.5773502692f, 0.3333333333f); positionSendMsg->Pack(); int r = memcmp((const void*)positionSendMsg->GetPackPointer(), (const void*)test_position_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)positionSendMsg->GetPackBodyPointer(), (const void*)(test_position_message+IGTL_HEADER_SIZE), PositionBodySize); EXPECT_EQ(r, 0); } TEST(PositionMessageTest, UnpackFormateVersion1) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)test_position_message, IGTL_HEADER_SIZE); headerMsg->Unpack(); positionReceiveMsg->SetMessageHeader(headerMsg); positionReceiveMsg->AllocatePack(); memcpy(positionReceiveMsg->GetPackBodyPointer(), positionSendMsg->GetPackBodyPointer(), positionSendMsg->GetPackBodySize()); positionReceiveMsg->Unpack(); igtl_float32 position_Truth[3] = {46.0531f, 19.4709f, 46.0531f}; igtl_float32 position[3] = {0.0,0.0,0.0}; positionReceiveMsg->GetPosition(position); EXPECT_THAT(position, ::testing::ElementsAreArray(position_Truth)); igtl_float32 quaternion_Truth[4] = {0.0f, 0.5773502691f, 0.5773502692f, 0.3333333333f}; igtl_float32 quaternion[4] = {0.0,0.0,0.0,0.0}; positionReceiveMsg->GetQuaternion(quaternion); EXPECT_THAT(quaternion, ::testing::ElementsAreArray(quaternion_Truth)); } #if OpenIGTLink_PROTOCOL_VERSION >= 3 #include "igtlutil/igtl_test_data_positionFormat2.h" #include "igtlMessageFormat2TestMacro.h" TEST(PositionMessageTest, PackFormatVersion2) { positionSendMsg = igtl::PositionMessage::New(); positionSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_2); positionSendMsg->AllocatePack(); positionSendMsg->SetTimeStamp(0, 1234567892); positionSendMsg->SetDeviceName("DeviceName"); positionSendMsg->SetPosition(46.0531f, 19.4709f, 46.0531f); positionSendMsg->SetQuaternion(0.0f, 0.5773502691f, 0.5773502692f, 0.3333333333f); igtlMetaDataAddElementMacro(positionSendMsg); positionSendMsg->Pack(); /*FILE *fp; fp = fopen("position.bin", "w"); fwrite(positionSendMsg->GetPackPointer(), positionSendMsg->GetPackBodySize()+IGTL_HEADER_SIZE, 1, fp); fclose(fp);*/ int r = memcmp((const void*)positionSendMsg->GetPackPointer(), (const void*)test_position_messageFormat2, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)positionSendMsg->GetPackBodyPointer(), (const void*)(test_position_messageFormat2+IGTL_HEADER_SIZE),PositionBodySize + EXTENDED_CONTENT_SIZE); EXPECT_EQ(r, 0); } TEST(PositionMessageTest, UnpackFormatVersion2) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)test_position_messageFormat2, IGTL_HEADER_SIZE); headerMsg->Unpack(); positionReceiveMsg = igtl::PositionMessage::New(); positionReceiveMsg->SetMessageHeader(headerMsg); positionReceiveMsg->AllocatePack(); memcpy(positionReceiveMsg->GetPackBodyPointer(), positionSendMsg->GetPackBodyPointer(), positionSendMsg->GetPackBodySize()); positionReceiveMsg->Unpack(1); igtl_float32 position_Truth[3] = {46.0531f, 19.4709f, 46.0531f}; igtl_float32 position[3] = {0.0,0.0,0.0}; positionReceiveMsg->GetPosition(position); for(int i = 0; i<3 ; i++) { EXPECT_FLOAT_EQ(position_Truth[i], position[i]); } igtl_float32 quaternion_Truth[4] = {0.0f, 0.5773502691f, 0.5773502692f, 0.3333333333f}; igtl_float32 quaternion[4] = {0.0,0.0,0.0,0.0}; positionReceiveMsg->GetQuaternion(quaternion); for(int i = 0; i<4 ; i++) { EXPECT_FLOAT_EQ(quaternion_Truth[i], quaternion[i]); } igtlMetaDataComparisonMacro(positionReceiveMsg); } #endif int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlSensorMessageTest.cxx000066400000000000000000000061751501024245700225050ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlSensorMessage.h" #include "igtlutil/igtl_test_data_sensor.h" #include "igtlUnit.h" #include "igtl_sensor.h" #include "igtl_unit.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::SensorMessage::Pointer sensorDataSendMsg = igtl::SensorMessage::New(); igtl::SensorMessage::Pointer sensorDataReceiveMsg = igtl::SensorMessage::New(); igtlFloat64 sensorValues[6] = {123456.78,12345.678,1234.5678,123.45678,12.345678,1.2345678}; igtl::Unit::Pointer unit = igtl::Unit::New(); void UnitInitization() { unit = igtl::Unit::New(); unit->Init(); unit->SetPrefix(IGTL_UNIT_PREFIX_NONE); unit->Append(IGTL_UNIT_SI_BASE_METER, (igtl_int8) 1); unit->Append(IGTL_UNIT_SI_BASE_SECOND, (igtl_int8) -2); unit->Pack(); } TEST(SensorMessageTest, Pack) { UnitInitization(); sensorDataSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); sensorDataSendMsg->AllocatePack(); sensorDataSendMsg->SetLength(6); sensorDataSendMsg->SetDeviceName("DeviceName"); sensorDataSendMsg->SetTimeStamp(0, 1234567892); sensorDataSendMsg->SetUnit(unit); for (int i =0; i < 6; i++) { sensorDataSendMsg->SetValue(i, sensorValues[i]); } sensorDataSendMsg->Pack(); int r = memcmp((const void*)sensorDataSendMsg->GetPackPointer(), (const void*)test_sensor_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)sensorDataSendMsg->GetPackBodyPointer(), (const void*)(test_sensor_message+IGTL_HEADER_SIZE),sensorDataSendMsg->GetPackBodySize()); EXPECT_EQ(r, 0); } TEST(SensorMessageTest, Unpack) { UnitInitization(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)test_sensor_message, IGTL_HEADER_SIZE); headerMsg->Unpack(); sensorDataReceiveMsg = igtl::SensorMessage::New(); sensorDataReceiveMsg->SetMessageHeader(headerMsg); sensorDataReceiveMsg->AllocatePack(); memcpy(sensorDataReceiveMsg->GetPackBodyPointer(), sensorDataSendMsg->GetPackBodyPointer(), 58); sensorDataReceiveMsg->Unpack(); igtl::igtlUnit unitTruth = 0x443E0000000000; EXPECT_EQ(sensorDataReceiveMsg->GetUnit(), unitTruth); EXPECT_EQ(sensorDataReceiveMsg->GetLength(),6); EXPECT_EQ(sensorDataReceiveMsg->GetValue(0),123456.78); EXPECT_EQ(sensorDataReceiveMsg->GetValue(1),12345.678); EXPECT_EQ(sensorDataReceiveMsg->GetValue(2),1234.5678); EXPECT_EQ(sensorDataReceiveMsg->GetValue(3),123.45678); EXPECT_EQ(sensorDataReceiveMsg->GetValue(4),12.345678); EXPECT_EQ(sensorDataReceiveMsg->GetValue(5),1.2345678); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlServerSocketTest.cxx000066400000000000000000000256661501024245700223540ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlServerSocket.h" #include "igtlImageMessage2.h" #include "igtlutil/igtl_test_data_image.h" #include "igtlClientSocket.h" #include "igtlMultiThreader.h" #include "igtl_types.h" #include "igtl_header.h" #include "igtl_image.h" #include "igtl_util.h" #include "igtlOSUtil.h" #include "igtlTestConfig.h" #include "string.h" using ::testing::_; using ::testing::AtLeast; using ::testing::Invoke; using igtl::ServerSocket; using ::testing::IsNull; class ServerSocketMock { public: //typedef igtl::SmartPointer Pointer; //ServerSocketMock(){}; ServerSocketMock(ServerSocket::Pointer pointer) { real_ = pointer; // By default, all calls are delegated to the real object. ON_CALL(*this, CreateServer(_)) .WillByDefault(Invoke(real_.GetPointer(), &ServerSocket::CreateServer)); ON_CALL(*this, GetServerPort()) .WillByDefault(Invoke(real_.GetPointer(), &ServerSocket::GetServerPort)); ON_CALL(*this, WaitForConnection(_)) .WillByDefault(Invoke(real_.GetPointer(), &ServerSocket::WaitForConnection)); ON_CALL(*this, Send(_,_)) .WillByDefault(Invoke(real_.GetPointer(), &ServerSocket::Send)); } ~ServerSocketMock(){real_.~SmartPointer();}; ServerSocket::Pointer getPointer(){return real_;}; void setPointer(ServerSocket::Pointer server){real_ = server;}; MOCK_METHOD0(GetServerPort, int()); MOCK_METHOD1(CreateServer, int(int port)); MOCK_METHOD1(WaitForConnection, igtl::ClientSocket::Pointer(unsigned long msec)); MOCK_METHOD2(Send, int(const void* data, int length)); private: ServerSocket::Pointer real_; }; void* ThreadFunction(void* ptr); int ReceiveImageData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); class StopImageSendingMessage: public igtl::MessageBase { public: typedef StopImageSendingMessage Self; typedef MessageBase Superclass; typedef igtl::SmartPointer Pointer; typedef igtl::SmartPointer ConstPointer; igtlTypeMacro(StopImageSendingMessage, igtl::MessageBase); igtlNewMacro(StopImageSendingMessage); protected: StopImageSendingMessage() : MessageBase() { this->m_SendMessageType = "STP_IMAGE"; }; ~StopImageSendingMessage() {}; protected: virtual int GetBodyPackSize() { return 0; }; virtual int PackBody() { AllocatePack(); return 1; }; virtual int UnpackBody() { return 1; }; }; class StartImageSendingMessage: public igtl::MessageBase { public: typedef StartImageSendingMessage Self; typedef MessageBase Superclass; typedef igtl::SmartPointer Pointer; typedef igtl::SmartPointer ConstPointer; igtlTypeMacro(StartImageSendingMessage, igtl::MessageBase); igtlNewMacro(StartImageSendingMessage); protected: StartImageSendingMessage() : MessageBase() { this->m_SendMessageType = "STT_IMAGE"; }; ~StartImageSendingMessage() {}; protected: virtual int GetBodyPackSize() { return 0; }; virtual int PackBody() { AllocatePack(); return 1; }; virtual int UnpackBody() { return 1; }; }; igtl::ImageMessage2::Pointer imageMessage2Test = igtl::ImageMessage2::New(); long interval = 200; int threadID; int port = 18944; int size[] = {50, 50, 1}; // image dimension float spacing[] = {1.0, 1.0, 5.0}; // spacing (mm/pixel) int svsize[] = {50, 50, 1}; // sub-volume size int svoffset[] = {0, 0, 0}; // sub-volume offset int scalarType = igtl::ImageMessage2::TYPE_UINT8;// scalar type void setupTest() { //Initialization of a image message imageMessage2Test->SetDimensions(size); imageMessage2Test->SetSpacing(spacing); imageMessage2Test->SetScalarType(scalarType); imageMessage2Test->SetDeviceName("Image"); imageMessage2Test->SetSubVolume(svsize, svoffset); imageMessage2Test->AllocateBuffer(IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE); imageMessage2Test->AllocateScalars(); memcpy((void*)imageMessage2Test->GetPackBodyPointer(), test_image_message+IGTL_HEADER_SIZE, IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE);//here m_Body is set. imageMessage2Test->SetScalarPointer((void*)test_image); imageMessage2Test->Pack(); } TEST(ServerSocketTest, ConnectionAndSending) { igtl::ServerSocket::Pointer tempServerSocket = igtl::ServerSocket::New(); ServerSocketMock mockServerSocket(tempServerSocket); EXPECT_CALL(mockServerSocket, CreateServer(port)).Times(1); int waitingTime = 3000; //EXPECT_CALL(*mockServerSocket, GetServerPort()).Times(1); //EXPECT_CALL(*mockServerSocket, WaitForConnection(_)).Times(2); //EXPECT_CALL(*mockServerSocket, Send(_,_)).Times(0); //mockServerSocket.GetServerPort(); int bCreation = mockServerSocket.CreateServer(port); EXPECT_EQ(bCreation,0); if(1==0) { igtl::ClientSocket::Pointer returnSocket = mockServerSocket.WaitForConnection(waitingTime); /**Connecting to a established server, however, time out happened, return NULL */ EXPECT_TRUE(returnSocket.IsNull()); //EXPECT_EQ(mockServerSocket->CreateServer(port),-1); //----------------------- //Use multi threader to create a subprocess, which connects to the server. igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); int loop = 0; threadID = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &mockServerSocket); igtl::ClientSocket::Pointer clientSocket; clientSocket = igtl::ClientSocket::New(); bool notConnected = true; while(notConnected) { int r = clientSocket->ConnectToServer("localhost", port); if(r!=0) { continue; } else { notConnected=false; } } StartImageSendingMessage::Pointer StartImageSending; StartImageSending = StartImageSendingMessage::New(); StartImageSending->Pack(); clientSocket->Send(StartImageSending->GetPackPointer(), StartImageSending->GetPackSize()); while(1) { igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = clientSocket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { std::cerr << "Connection closed." << std::endl; clientSocket->CloseSocket(); exit(0); } if (rs != headerMsg->GetPackSize()) { continue; } headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceName(),"Image")== 0) { ReceiveImageData(clientSocket, headerMsg); } else { EXPECT_TRUE(false)<< "Receiving : " << headerMsg->GetDeviceName() << std::endl; clientSocket->Skip(headerMsg->GetBodySizeToRead(), 0); } if (++loop >= 10) // if received 10 times { StopImageSendingMessage::Pointer StopImageSending; StopImageSending = StopImageSendingMessage::New(); StopImageSending->Pack(); clientSocket->Send(StopImageSending->GetPackPointer(), StopImageSending->GetPackSize()); threadID = -1; break; //---------------------------------------- } } } else { mockServerSocket.getPointer()->CloseSocket(); } //delete mockServerSocket; //clientSocket::send } int ReceiveImageData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving QTDATA data type." << std::endl; igtl::ImageMessage2::Pointer imageData; imageData = igtl::ImageMessage2::New(); imageData->SetDimensions(size); imageData->SetSpacing(spacing); imageData->SetScalarType(scalarType); imageData->SetSubVolume(svsize, svoffset); imageData->AllocateBuffer(IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE); imageData->AllocateScalars(); // Receive imageHeader from the socket socket->Receive(imageData->GetPackBodyPointer(), imageData->GetPackBodySize()); // Deserialize position and quaternion (orientation) data // If you want to skip CRC check, call Unpack() without argument. int c = imageData->Unpack(); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { std::cout << "================================" << std::endl; std::cout << " Name : " << imageData->GetDeviceType(); std::cout << "================================" << std::endl; } return 1; } void* ThreadFunction(void* ptr) { //------------------------------------------------------------ // Get the server socket igtl::MultiThreader::ThreadInfo* info = static_cast(ptr); ServerSocketMock* mockServerSocket = static_cast(info->UserData); //------------------------------------------------------------ // Get user data std::cout << "Interval = " << interval << " (ms)" << std::endl; igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); //------------------------------------------------------------ // Loop igtl::Socket::Pointer socket; igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); socket = mockServerSocket->WaitForConnection(10000); if (socket.IsNotNull()) { igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); for (;;) { headerMsg->InitPack(); int rs = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (rs == 0) { EXPECT_TRUE(false) << "Disconnecting the client."; socket->CloseSocket(); break; } if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "StartSending") == 0) { while(!(threadID==-1)) { glock->Lock(); for (int i = 0; i < imageMessage2Test->GetNumberOfPackFragments(); i ++) { socket->Send(imageMessage2Test->GetPackFragmentPointer(i), imageMessage2Test->GetPackFragmentSize(i)); } glock->Unlock(); igtl::Sleep(interval); } } else if (strcmp(headerMsg->GetDeviceType(), "StopSending") == 0) { std::cerr << "Received a stop message." << std::endl; socket->CloseSocket(); break; } } } else { EXPECT_TRUE(false) << "No client connected."; } delete mockServerSocket; return NULL; } int main(int argc, char **argv) { setupTest(); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlSocketTest.cxx000066400000000000000000000243371501024245700211570ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlServerSocket.h" #include "igtlSocket.h" #include "igtlMessageHeader.h" #include "igtlClientSocket.h" #include "igtlMultiThreader.h" #include "igtlQuaternionTrackingDataMessage.h" #include "igtl_types.h" #include "igtl_header.h" #include "igtl_util.h" #include "igtlOSUtil.h" #include "igtlTestConfig.h" #include "string.h" using ::testing::_; using ::testing::AtLeast; using ::testing::Invoke; using igtl::ServerSocket; using igtl::ClientSocket; using igtl::Socket; using ::testing::IsNull; class SocketMock { public: SocketMock(Socket::Pointer pointer) { real_ = pointer; // By default, all calls are delegated to the real object. ON_CALL(*this, GetConnected()) .WillByDefault(Invoke(real_.GetPointer(), &Socket::GetConnected)); ON_CALL(*this, Send(_,_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::Send)); ON_CALL(*this, Receive(_,_,_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::Receive)); ON_CALL(*this, SetTimeout(_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::SetTimeout)); ON_CALL(*this, SetReceiveTimeout(_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::SetReceiveTimeout)); ON_CALL(*this, SetSendTimeout(_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::SetSendTimeout)); ON_CALL(*this, SetReceiveBlocking(_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::SetReceiveBlocking)); ON_CALL(*this, SetSendBlocking(_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::SetSendBlocking)); ON_CALL(*this, GetSocketAddressAndPort(_,_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::GetSocketAddressAndPort)); ON_CALL(*this, Skip(_,_)) .WillByDefault(Invoke(real_.GetPointer(), &Socket::Skip)); } ~SocketMock(){real_.~SmartPointer();}; Socket::Pointer getPointer(){return real_;}; MOCK_METHOD0(GetConnected, int()); MOCK_METHOD1(SetTimeout, int(int timeout)); MOCK_METHOD1(SetReceiveTimeout, int(int timeout)); MOCK_METHOD1(SetSendTimeout, int(int timeout)); MOCK_METHOD1(SetReceiveBlocking, int(int sw)); MOCK_METHOD1(SetSendBlocking, int(int sw)); MOCK_METHOD2(Send, int(const void* data, int length)); MOCK_METHOD2(GetSocketAddressAndPort, int(std::string& address, int& port)); MOCK_METHOD2(Skip, int(int length, int skipFully)); MOCK_METHOD3(Receive, int(void* data, int length, int readFully)); private: Socket::Pointer real_; }; void* TestThreadFunction(void* ptr); int ReceiveQuaternionTrackingData(ClientSocket::Pointer socket, igtl::MessageHeader::Pointer& header); void clientServerProcess(); long interval = 200; int threadID; int port = 18944; bool threadrunning = false; bool msgReceived = true; TEST(SocketTest, GeneralTest) { igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New(); threadID = threader->SpawnThread((igtl::ThreadFunctionType) &TestThreadFunction, NULL); clientServerProcess(); while(threadrunning) { igtl::Sleep(interval); }; } void* TestThreadFunction(void* ptr) { threadrunning = true; igtl::MutexLock::Pointer glock = igtl::MutexLock::New(); int waitingTime = 3000; ServerSocket::Pointer serverSocket = ServerSocket::New(); serverSocket->CreateServer(port); SocketMock socketMock(static_cast(serverSocket->WaitForConnection(10*waitingTime))); EXPECT_CALL(socketMock, GetConnected()).Times(1); //The send command is called 10 times, it keep on sending at an interval(200ms) until a stop command is received. EXPECT_CALL(socketMock, Send(_,_)).Times(10); // Receive function should be called three times, the start command header, the start command body, and the stop command EXPECT_CALL(socketMock, Receive(_,_,_)).Times(3); EXPECT_CALL(socketMock, SetTimeout(_)).Times(0); EXPECT_CALL(socketMock, SetSendTimeout(_)).Times(0); if (socketMock.getPointer().IsNotNull()) { EXPECT_GT(socketMock.GetConnected(),0); igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); for (;;) { headerMsg->InitPack(); int rs = socketMock.Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize(), 0); if (rs != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "STT_QTDATA") == 0) { std::cerr << "Received a STT_QTDATA message." << std::endl; igtl::StartQuaternionTrackingDataMessage::Pointer startQuaternionTracking; startQuaternionTracking = igtl::StartQuaternionTrackingDataMessage::New(); startQuaternionTracking->SetMessageHeader(headerMsg); startQuaternionTracking->AllocatePack(); socketMock.Receive(startQuaternionTracking->GetPackBodyPointer(), startQuaternionTracking->GetPackBodySize(),0); int c = startQuaternionTracking->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { igtl::QuaternionTrackingDataMessage::Pointer quaternionTrackingMsg; quaternionTrackingMsg = igtl::QuaternionTrackingDataMessage::New(); quaternionTrackingMsg->SetDeviceName("Tracker"); igtl::QuaternionTrackingDataElement::Pointer quaternionTrackElement0; quaternionTrackElement0 = igtl::QuaternionTrackingDataElement::New(); quaternionTrackElement0->SetName("Channel 0"); quaternionTrackElement0->SetType(igtl::QuaternionTrackingDataElement::TYPE_TRACKER); quaternionTrackingMsg->AddQuaternionTrackingDataElement(quaternionTrackElement0); while(!(threadID==-1)) { if(msgReceived) { glock->Lock(); quaternionTrackingMsg->Pack(); socketMock.Send(quaternionTrackingMsg->GetPackPointer(), quaternionTrackingMsg->GetPackSize()); glock->Unlock(); msgReceived = false; } igtl::Sleep(interval); } } } else if (strcmp(headerMsg->GetDeviceType(), "STP_QTDATA") == 0) { std::cerr << "Received a stop message." << std::endl; socketMock.getPointer()->CloseSocket(); threadrunning = false; break; } } } else { EXPECT_TRUE(false) << "No client connected."; } return NULL; } void clientServerProcess() { igtl::ClientSocket::Pointer clientSocket; clientSocket = igtl::ClientSocket::New(); bool notConnected = true; while(notConnected) { int r = clientSocket->ConnectToServer("localhost", port); if(r!=0) { continue; } else { notConnected=false; } } //socketMock.setPointer(clientSocket); igtl::StartQuaternionTrackingDataMessage::Pointer startQuaternionTrackingMsg; startQuaternionTrackingMsg = igtl::StartQuaternionTrackingDataMessage::New(); startQuaternionTrackingMsg->SetDeviceName("QTDataClient"); startQuaternionTrackingMsg->SetResolution(interval); startQuaternionTrackingMsg->SetCoordinateName("Patient"); startQuaternionTrackingMsg->Pack(); clientSocket->Send(startQuaternionTrackingMsg->GetPackPointer(), startQuaternionTrackingMsg->GetPackSize()); int loop = 0; while (1) { //------------------------------------------------------------ // Wait for a reply igtl::Sleep(interval); igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); headerMsg->InitPack(); int rs = clientSocket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize(),0); if (rs == 0) { std::cerr << "Connection closed." << std::endl; clientSocket->CloseSocket(); exit(0); } headerMsg->Unpack(); if (strcmp(headerMsg->GetDeviceType(), "QTDATA") == 0) { ReceiveQuaternionTrackingData(clientSocket, headerMsg); msgReceived = true; } else { std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; clientSocket->Skip(headerMsg->GetBodySizeToRead(), 0); } if (++loop >= 10) // if received 11 times { //------------------------------------------------------------ // Ask the server to stop pushing quaternion tracking data std::cerr << "Sending STP_QTDATA message....." << std::endl; igtl::StopQuaternionTrackingDataMessage::Pointer stopQuaternionTrackingMsg; stopQuaternionTrackingMsg = igtl::StopQuaternionTrackingDataMessage::New(); stopQuaternionTrackingMsg->SetDeviceName("QTDataClient"); stopQuaternionTrackingMsg->Pack(); clientSocket->Send(stopQuaternionTrackingMsg->GetPackPointer(), stopQuaternionTrackingMsg->GetPackSize()); threadID = -1; break; } } } int ReceiveQuaternionTrackingData(ClientSocket::Pointer socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving QTDATA data type." << std::endl; //------------------------------------------------------------ // Allocate QuaternionTrackingData Message Class igtl::QuaternionTrackingDataMessage::Pointer quaternionTrackingData; quaternionTrackingData = igtl::QuaternionTrackingDataMessage::New(); quaternionTrackingData->SetMessageHeader(header); quaternionTrackingData->AllocatePack(); // Receive body from the socket socket->Receive(quaternionTrackingData->GetPackBodyPointer(), quaternionTrackingData->GetPackBodySize(),0); // Deserialize position and quaternion (orientation) data // If you want to skip CRC check, call Unpack() without argument. int c = quaternionTrackingData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = quaternionTrackingData->GetNumberOfQuaternionTrackingDataElements(); EXPECT_EQ(nElements, 1); return 1; } return 0; } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlStatusMessageTest.cxx000066400000000000000000000052701501024245700225120ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlStatusMessage.h" #include "igtlutil/igtl_test_data_status.h" #include "string.h" #include "igtl_status.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::StatusMessage::Pointer statusSendMsg = igtl::StatusMessage::New(); igtl::StatusMessage::Pointer statusReceiveMsg = igtl::StatusMessage::New(); #define STR_ERROR_NAME "ACTUATOR_DISABLED" /* within 20 characters */ #define STR_ERROR_MESSAGE "Actuator A is disabled." TEST(StatusMessageTest, Pack) { std::string statusString = "randomstringrandomstring"; statusSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); statusSendMsg->SetStatusString(statusString.c_str());// pass an empty string with size 54,just to initialize the memory statusSendMsg->AllocatePack(); statusSendMsg->SetTimeStamp(0, 1234567892); statusSendMsg->SetDeviceName("DeviceName"); statusSendMsg->SetCode(IGTL_STATUS_DISABLED); statusSendMsg->SetSubCode(0x0A); statusSendMsg->SetErrorName(STR_ERROR_NAME); statusSendMsg->SetStatusString(STR_ERROR_MESSAGE); statusSendMsg->Pack(); int r = memcmp((const void*)statusSendMsg->GetPackPointer(), (const void*)test_status_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)statusSendMsg->GetPackBodyPointer(), (const void*)(test_status_message+IGTL_HEADER_SIZE),statusSendMsg->GetPackBodySize()); EXPECT_EQ(r, 0); } TEST(StatusMessageTest, Unpack) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), statusSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); statusReceiveMsg->SetMessageHeader(headerMsg); statusReceiveMsg->AllocatePack(); memcpy(statusReceiveMsg->GetPackBodyPointer(), statusSendMsg->GetPackBodyPointer(), statusSendMsg->GetPackBodySize()); statusReceiveMsg->Unpack(); EXPECT_EQ(statusReceiveMsg->GetCode(),IGTL_STATUS_DISABLED); EXPECT_EQ(statusReceiveMsg->GetSubCode(),(igtlInt64)0x0A); EXPECT_STREQ(statusReceiveMsg->GetErrorName(),STR_ERROR_NAME); EXPECT_STREQ(statusReceiveMsg->GetStatusString(),STR_ERROR_MESSAGE); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlStringMessageTest.cxx000066400000000000000000000043521501024245700224750ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlStringMessage.h" #include "igtlutil/igtl_test_data_string.h" #include "igtl_string.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" #define IGTL_STRING_TEST_STRING "Welcome to OpenIGTLink" #define IGTL_STRING_TEST_STRING_LEN 22 igtl::StringMessage::Pointer stringSendMsg = igtl::StringMessage::New(); igtl::StringMessage::Pointer stringReceiveMsg = igtl::StringMessage::New(); TEST(StringMessageTest, Pack) { stringSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); stringSendMsg->SetString(IGTL_STRING_TEST_STRING); stringSendMsg->AllocatePack(); stringSendMsg->SetTimeStamp(0, 1234567892); stringSendMsg->SetDeviceName("DeviceName"); stringSendMsg->SetEncoding(3); stringSendMsg->Pack(); int r = memcmp((const void*)stringSendMsg->GetPackPointer(), (const void*)test_string_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)stringSendMsg->GetPackBodyPointer(), (const void*)(test_string_message+IGTL_HEADER_SIZE),stringSendMsg->GetPackBodySize()); EXPECT_EQ(r, 0); } TEST(StringMessageTest, Unpack) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)test_string_message, IGTL_HEADER_SIZE); headerMsg->Unpack(); stringReceiveMsg->SetMessageHeader(headerMsg); stringReceiveMsg->AllocatePack(); memcpy(stringReceiveMsg->GetPackBodyPointer(), stringSendMsg->GetPackBodyPointer(), stringSendMsg->GetPackBodySize()); stringReceiveMsg->Unpack(); EXPECT_EQ(stringReceiveMsg->GetEncoding(),3); EXPECT_STREQ(stringReceiveMsg->GetString(),IGTL_STRING_TEST_STRING); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlTestConfig.h.in000066400000000000000000000210201501024245700211500ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // // This header file switches the definition of TEST() macro. It includes // gtest.h if GTest supports the platform. Otherwise, this header file defines // its own TEST() macro. // // This is a temporary workaround for the GTest issues in Windows. For long term, // we will switch entirely to the GTest. // #define OpenIGTLink_USE_GTEST @OpenIGTLink_USE_GTEST@ #if OpenIGTLink_USE_GTEST == 1 #include "gtest/gtest.h" #include "gmock/gmock.h" #else #include #include #include #ifdef _WIN32 #include #endif #define TEST_FAILURE 1 #define TEST_SUCCESS 0 // void function to skip InitGoogleTest() call namespace testing { void InitGoogleTest(int* argc, char **argv) {} // Implements ElementsAreArray(). template class IGTLCommon_EXPORT ElementsAreArrayMatcher { public: ElementsAreArrayMatcher(::std::vector a); int Compare(::std::vector b); int Compare(const T* b); private: ::std::vector arrayA; }; template ElementsAreArrayMatcher::ElementsAreArrayMatcher(::std::vector a) { this->arrayA = a; } template int ElementsAreArrayMatcher::Compare(::std::vector b) { typename ::std::vector::iterator iterA = arrayA.begin(); typename ::std::vector::iterator iterB = b.begin(); while( iterA!=arrayA.end() && iterB!=b.end()) { if ((*iterA-*iterB)>1e-6 || (*iterA-*iterB)<-1e-6) { return 0; } iterA ++; iterB ++; } return 1; } template int ElementsAreArrayMatcher::Compare(const T* b) { int N = arrayA; for (int i = 0; i < N; i ++) { if ((arrayA[i] - b[i])>1e-6 || (arrayA[i] - b[i])<-1e-6) { return 0; } } return 1; } template inline ElementsAreArrayMatcher ElementsAreArray(::std::vector & array) { return ElementsAreArrayMatcher(array); } template inline ElementsAreArrayMatcher ElementsAreArray(const T (&array)[N]) { ::std::vector vec; for (int i = 0; i < N; i ++) vec.push_back(array[i]); return ElementsAreArrayMatcher(vec); } class IGTLCommon_EXPORT TestBase { public: virtual void Run() = 0; inline ::std::string GetCaseName() { return caseName; } inline ::std::string GetTestName() { return testName; } inline int GetResult() { return result; } protected: ::std::string caseName; ::std::string testName; int result; }; class IGTLCommon_EXPORT TestInfo { public: int Add( TestBase* ); int Run(); private: static ::std::vector< TestBase* > TestList; }; ::std::vector< TestBase* > TestInfo::TestList; TestInfo testInfo; int TestInfo::Add( TestBase* test ) { TestInfo::TestList.push_back(test); return 1; } int TestInfo::Run() { ::std::vector< TestBase* >::iterator iter; int result = TEST_SUCCESS; for (iter = TestInfo::TestList.begin(); iter != TestInfo::TestList.end(); iter ++) { (*iter)->Run(); if ((*iter)->GetResult() == TEST_FAILURE) { std::cerr << "[ERROR] "; result = TEST_FAILURE; } else { std::cerr << "[ OK ] "; } std::cerr << (*iter)->GetCaseName() << "."; std::cerr << (*iter)->GetTestName() << std::endl; } return result; } } #define EXPECT_EQ(a, b) \ if (a != b) \ { \ this->result = TEST_FAILURE; \ return; \ } #define EXPECT_LT(a, b) \ if (a >= b) \ { \ this->result = TEST_FAILURE; \ return; \ } #define EXPECT_NEAR(a, b, err) \ if ((a-b) >= err || (a-b) <= -err) \ { \ this->result = TEST_FAILURE; \ return; \ } #define EXPECT_FLOAT_EQ(a, b) \ if ((a-b) > 1e-6 || (a-b) < -1e-6) \ { \ this->result = TEST_FAILURE; \ return; \ } #define EXPECT_STREQ(a, b) \ if (strcmp(a, b) != 0) \ { \ this->result = TEST_FAILURE; \ return; \ } #ifdef _WIN32 #define EXPECT_THAT(a, comp) \ { \ const int N = sizeof(a)/sizeof(a[0]); \ auto dataType = a[0]; \ testing::ElementsAreArrayMatcher< decltype(dataType) > matcher = comp; \ ::std::vector< decltype(dataType) > vecA; \ for (int i = 0; i < N; i ++) vecA.push_back(a[i]); \ if (!matcher.Compare(vecA)) \ { \ this->result = TEST_FAILURE; \ return; \ } \ } #else #define EXPECT_THAT(a, comp) \ { \ const int N = sizeof(a)/sizeof(a[0]); \ std::string dataType = typeid(a[0]).name(); \ testing::ElementsAreArrayMatcher< typeof(a[0]) > matcher = comp; \ ::std::vector< typeof(a[0]) > vecA; \ for (int i = 0; i < N; i ++) vecA.push_back(a[i]); \ if (!matcher.Compare(vecA)) \ { \ this->result = TEST_FAILURE; \ return; \ } \ } #endif #define EXPECT_TRUE(a) \ if (a != true) \ { \ this->result = TEST_FAILURE; \ return; \ } #define TEST(test_case_name, test_name) \ class IGTLCommon_EXPORT test_case_name##_##test_name##_Test : ::testing::TestBase { \ public: \ test_case_name##_##test_name##_Test(); \ void Run(); \ }; \ test_case_name##_##test_name##_Test instance_##test_case_name##_##test_name##_Test; \ test_case_name##_##test_name##_Test::test_case_name##_##test_name##_Test() \ { \ ::testing::testInfo.Add(this); \ caseName = #test_case_name; \ testName = #test_name; \ } \ void test_case_name##_##test_name##_Test::Run() inline int RUN_ALL_TESTS() { if (::testing::testInfo.Run() == TEST_FAILURE) { return 1; } else { return 0; } } /// TestList.push_back(new test_case_name##_##test_name##_Test) \ #endif openigtlink-3.0.0/Testing/igtlTimeStampTest1.cxx000066400000000000000000000023231501024245700217020ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #include int main(int, char * [] ) { // Simply testing Setter/Getter igtl::TimeStamp::Pointer ts = igtl::TimeStamp::New(); ts->GetTime(); igtlUint64 totalNanosSinceEpochBefore = ts->GetTimeStampInNanoseconds(); ts->SetTime(0.0); ts->SetTimeInNanoseconds(totalNanosSinceEpochBefore); igtlUint64 totalNanosSinceEpochAfter = ts->GetTimeStampInNanoseconds(); if (totalNanosSinceEpochAfter != totalNanosSinceEpochBefore) { std::cerr << "Expected totalNanosSinceEpochBefore=" << totalNanosSinceEpochBefore << " to equal totalNanosSinceEpochAfter=" << totalNanosSinceEpochAfter << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; } openigtlink-3.0.0/Testing/igtlTrackingDataMessageTest.cxx000066400000000000000000000162041501024245700235620ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlTrackingDataMessage.h" #include "igtlutil/igtl_test_data_tdata.h" #include "igtlMessageDebugFunction.h" #include "igtl_tdata.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::TrackingDataMessage::Pointer trackingSendMsg = igtl::TrackingDataMessage::New(); igtl::TrackingDataMessage::Pointer trackingReceiveMsg = igtl::TrackingDataMessage::New(); igtl::TrackingDataElement::Pointer trackingElement0 = igtl::TrackingDataElement::New(); igtl::TrackingDataElement::Pointer trackingElement1 = igtl::TrackingDataElement::New(); igtl::TrackingDataElement::Pointer trackingElement2 = igtl::TrackingDataElement::New(); float inT[4] = {-0.954892f, 0.196632f, -0.222525f, 0.0}; float inS[4] = {-0.196632f, 0.142857f, 0.970014f, 0.0}; float inN[4] = {0.222525f, 0.970014f, -0.0977491f, 0.0}; float inOrigin[4] = {46.0531f,19.4709f,46.0531f, 1.0}; igtl::Matrix4x4 inMatrix = {{inT[0],inS[0],inN[0],inOrigin[0]}, {inT[1],inS[1],inN[1],inOrigin[1]}, {inT[2],inS[2],inN[2],inOrigin[2]}, {inT[3],inS[3],inN[3],inOrigin[3]}}; void BuildUpElements() { trackingElement0->SetName("Tracker0"); trackingElement0->SetType(IGTL_TDATA_TYPE_6D); trackingElement0->SetMatrix(inMatrix); trackingElement1->SetName("Tracker1"); trackingElement1->SetType(IGTL_TDATA_TYPE_6D); trackingElement1->SetMatrix(inMatrix); trackingElement2->SetName("Tracker2"); trackingElement2->SetType(IGTL_TDATA_TYPE_6D); trackingElement2->SetMatrix(inMatrix); trackingSendMsg = igtl::TrackingDataMessage::New(); trackingSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); trackingSendMsg->SetDeviceName("DeviceName"); trackingSendMsg->SetTimeStamp(0, 1234567892); trackingSendMsg->AddTrackingDataElement(trackingElement0); trackingSendMsg->AddTrackingDataElement(trackingElement1); trackingSendMsg->AddTrackingDataElement(trackingElement2); } TEST(TrackingMessageTest, Pack) { BuildUpElements(); trackingSendMsg->Pack(); int r = memcmp((const void*)trackingSendMsg->GetPackPointer(), (const void*)test_tdata_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)trackingSendMsg->GetPackBodyPointer(), (const void*)(test_tdata_message+(size_t)(IGTL_HEADER_SIZE)), IGTL_TDATA_ELEMENT_SIZE*3 ); EXPECT_EQ(r, 0); } TEST(TrackingMessageTest, Unpack) { BuildUpElements(); trackingSendMsg->Pack(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)trackingSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); trackingReceiveMsg->SetMessageHeader(headerMsg); trackingReceiveMsg->AllocatePack(); memcpy(trackingReceiveMsg->GetPackBodyPointer(), trackingSendMsg->GetPackBodyPointer(), IGTL_TDATA_ELEMENT_SIZE*3); trackingReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)trackingReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "TDATA"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_TDATA_ELEMENT_SIZE*3); std::vector trackerDescription; trackerDescription.push_back((char*)"Tracker0"); trackerDescription.push_back((char*)"Tracker1"); trackerDescription.push_back((char*)"Tracker2"); for (int i = 0; i<3;++i) { igtl::TrackingDataElement::Pointer elem = igtl::TrackingDataElement::New(); trackingReceiveMsg->GetTrackingDataElement(i, elem); EXPECT_EQ(strncmp((char*)(elem->GetName()), trackerDescription[i], 8),0); igtl::Matrix4x4 outMatrix = {{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.0,0.0,0.0}}; elem->GetMatrix(outMatrix); EXPECT_TRUE(MatrixComparison(outMatrix, inMatrix, ABS_ERROR)); } } #if OpenIGTLink_PROTOCOL_VERSION >= 3 #include "igtlutil/igtl_test_data_tdataFormat2.h" #include "igtlMessageFormat2TestMacro.h" TEST(TrackingMessageTest, PackFormatVersion2) { BuildUpElements(); igtlMetaDataAddElementMacro(trackingSendMsg); trackingSendMsg->Pack(); FILE *fp; fp = fopen("TrackingData.bin", "w"); fwrite(trackingSendMsg->GetPackPointer(), trackingSendMsg->GetPackBodySize()+IGTL_HEADER_SIZE, 1, fp); fclose(fp); int r = memcmp((const void*)trackingSendMsg->GetPackPointer(), (const void*)test_tdata_messageFormat2, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)trackingSendMsg->GetPackBodyPointer(), (const void*)(test_tdata_messageFormat2+(size_t)(IGTL_HEADER_SIZE)), IGTL_TDATA_ELEMENT_SIZE*3+EXTENDED_CONTENT_SIZE); EXPECT_EQ(r, 0); } TEST(TrackingMessageTest, UnpackFormatVersion2) { BuildUpElements(); igtlMetaDataAddElementMacro(trackingSendMsg); trackingSendMsg->Pack(); igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)trackingSendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); trackingReceiveMsg->SetMessageHeader(headerMsg); trackingReceiveMsg->AllocatePack(); memcpy(trackingReceiveMsg->GetPackBodyPointer(), trackingSendMsg->GetPackBodyPointer(), IGTL_TDATA_ELEMENT_SIZE*3 + EXTENDED_CONTENT_SIZE); trackingReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)trackingReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "TDATA"); EXPECT_EQ(messageHeader->header_version, 2); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_TDATA_ELEMENT_SIZE*3 + EXTENDED_CONTENT_SIZE); std::vector trackerDescription; trackerDescription.push_back((char*)"Tracker0"); trackerDescription.push_back((char*)"Tracker1"); trackerDescription.push_back((char*)"Tracker2"); for (int i = 0; i<3;++i) { igtl::TrackingDataElement::Pointer elem = igtl::TrackingDataElement::New(); trackingReceiveMsg->GetTrackingDataElement(i, elem); EXPECT_EQ(strncmp((char*)(elem->GetName()), trackerDescription[i], 8),0); igtl::Matrix4x4 outMatrix = {{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.0,0.0,0.0}}; elem->GetMatrix(outMatrix); EXPECT_TRUE(MatrixComparison(outMatrix, inMatrix, ABS_ERROR)); } igtlMetaDataComparisonMacro(trackingReceiveMsg); } #endif int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlTrajectoryMessageTest.cxx000066400000000000000000000246711501024245700233630ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ //#define IGTL_LEGACY_TEST #include "igtlTrajectoryMessage.h" #include "igtlutil/igtl_test_data_trajectory.h" #include "igtlMessageDebugFunction.h" #include "igtl_trajectory.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::TrajectoryMessage::Pointer trajectorySendMsg = igtl::TrajectoryMessage::New(); igtl::TrajectoryMessage::Pointer trajectoryReceiveMsg = igtl::TrajectoryMessage::New(); igtl::TrajectoryElement::Pointer trajectoryElement0 = igtl::TrajectoryElement::New(); igtl::TrajectoryElement::Pointer trajectoryElement1 = igtl::TrajectoryElement::New(); igtl::TrajectoryElement::Pointer trajectoryElement2 = igtl::TrajectoryElement::New(); void BuildUpElements() { trajectoryElement0->SetName("TRAJECTORY_DESCRIPTION_0"); trajectoryElement0->SetGroupName("TRAJECTORY"); trajectoryElement0->SetType(IGTL_TRAJECTORY_TYPE_ENTRY_TARGET); trajectoryElement0->SetRGBA(255,0,0,255); trajectoryElement0->SetEntryPosition(10.0,15.0,20.0); trajectoryElement0->SetTargetPosition(25.0,30.0,35.0); trajectoryElement0->SetRadius(5.0); trajectoryElement0->SetOwner("IMAGE_0"); trajectoryElement1->SetName("TRAJECTORY_DESCRIPTION_1"); trajectoryElement1->SetGroupName("TRAJECTORY"); trajectoryElement1->SetType(IGTL_TRAJECTORY_TYPE_ENTRY_TARGET); trajectoryElement1->SetRGBA(0,255,0,255); trajectoryElement1->SetEntryPosition(40.0,45.0,50.0); trajectoryElement1->SetTargetPosition(55.0,60.0,65.0); trajectoryElement1->SetRadius(2.5); trajectoryElement1->SetOwner("IMAGE_0"); trajectoryElement2->SetName("TRAJECTORY_DESCRIPTION_2"); trajectoryElement2->SetGroupName("TRAJECTORY"); trajectoryElement2->SetType(IGTL_TRAJECTORY_TYPE_ENTRY_TARGET); trajectoryElement2->SetRGBA(0,0,255,255); trajectoryElement2->SetEntryPosition(70.0,75.0,80.0); trajectoryElement2->SetTargetPosition(85.0,90.0,95.0); trajectoryElement2->SetRadius(0.0); trajectoryElement2->SetOwner("IMAGE_0"); trajectorySendMsg = igtl::TrajectoryMessage::New(); trajectorySendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); trajectorySendMsg->SetDeviceName("DeviceName"); trajectorySendMsg->SetTimeStamp(0, 1234567892); trajectorySendMsg->AddTrajectoryElement(trajectoryElement0); trajectorySendMsg->AddTrajectoryElement(trajectoryElement1); trajectorySendMsg->AddTrajectoryElement(trajectoryElement2); } TEST(TrajectoryMessageTest, DeprecatedMethodTest) { BuildUpElements(); int size = trajectorySendMsg->GetNumberOfTrajectoryElement(); EXPECT_EQ(size, 3); igtl::TrajectoryElement::Pointer trajectoryElementNotUsed = igtl::TrajectoryElement::New(); trajectorySendMsg->ClearTrajectoryElement(trajectoryElementNotUsed); size = trajectorySendMsg->GetNumberOfTrajectoryElement(); EXPECT_EQ(size, 0); BuildUpElements(); size = trajectorySendMsg->GetNumberOfTrajectoryElement(); EXPECT_EQ(size, 3); trajectorySendMsg->ClearTrajectoryElement(trajectoryElementNotUsed); size = trajectorySendMsg->GetNumberOfTrajectoryElement(); EXPECT_EQ(size, 0); } TEST(TrajectoryMessageTest, PackFormatVersion1) { BuildUpElements(); trajectorySendMsg->Pack(); int r = memcmp((const void*)trajectorySendMsg->GetPackPointer(), (const void*)test_trajectory_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)trajectorySendMsg->GetPackBodyPointer(), (const void*)(test_trajectory_message+(size_t)(IGTL_HEADER_SIZE)), IGTL_TRAJECTORY_ELEMENT_SIZE*3 ); EXPECT_EQ(r, 0); } TEST(TrajectoryMessageTest, UnpackFormatVersion1) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), trajectorySendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); trajectoryReceiveMsg->SetMessageHeader(headerMsg); trajectoryReceiveMsg->AllocatePack(); memcpy(trajectoryReceiveMsg->GetPackBodyPointer(), trajectorySendMsg->GetPackBodyPointer(), IGTL_TRAJECTORY_ELEMENT_SIZE*3); trajectoryReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)trajectoryReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "TRAJ"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_TRAJECTORY_ELEMENT_SIZE*3); std::vector > groundTruthRGBA(3,std::vector(4)); igtlUint8 tempIni1[4] = {255,0,0,255}; groundTruthRGBA[0].assign(tempIni1,tempIni1+4); igtlUint8 tempIni2[4] = {0,255,0,255}; groundTruthRGBA[1].assign(tempIni2,tempIni2+4); igtlUint8 tempIni3[4] = {0,0,255,255}; groundTruthRGBA[2].assign(tempIni3,tempIni3+4); igtlFloat32 groundTruthEntryPoints[3][3] ={{10.0,15.0,20.0}, {40.0,45.0,50.0}, {70.0,75.0,80.0}}; igtlFloat32 groundTruthTargetPoints[3][3] = {{25.0,30.0,35.0}, {55.0,60.0,65.0}, {85.0,90.0,95.0}}; igtlFloat32 groundTruthRadius[3] = {5.0,2.5,0.0}; std::vector trajectoryDescription; trajectoryDescription.push_back((char*)"TRAJECTORY_DESCRIPTION_0"); trajectoryDescription.push_back((char*)"TRAJECTORY_DESCRIPTION_1"); trajectoryDescription.push_back((char*)"TRAJECTORY_DESCRIPTION_2"); for (int i = 0; i<3;++i) { igtl::TrajectoryElement::Pointer elem = igtl::TrajectoryElement::New(); trajectoryReceiveMsg->GetTrajectoryElement(i, elem); EXPECT_EQ(strncmp((char*)(elem->GetName()), trajectoryDescription[i], 24),0); igtlUint8 returnedRGBA[4] ={0,0,0,0}; elem->GetRGBA(returnedRGBA); EXPECT_THAT(returnedRGBA, testing::ElementsAreArray(groundTruthRGBA[i])); igtlFloat32 returnedEntryPoint[3] ={0,0,0}; elem->GetEntryPosition(returnedEntryPoint); EXPECT_TRUE(ArrayFloatComparison(returnedEntryPoint, groundTruthEntryPoints[i], 3, ABS_ERROR)); igtlFloat32 returnedTargetPoint[3] ={0,0,0}; elem->GetTargetPosition(returnedTargetPoint); EXPECT_TRUE(ArrayFloatComparison(returnedTargetPoint, groundTruthTargetPoints[i], 3, ABS_ERROR)); EXPECT_EQ(elem->GetRadius(), groundTruthRadius[i]); EXPECT_EQ(strncmp((char*)elem->GetOwner(), "IMAGE_0", 7),0); } } #if OpenIGTLink_PROTOCOL_VERSION >= 3 #include "igtlutil/igtl_test_data_trajectoryFormat2.h" #include "igtlMessageFormat2TestMacro.h" TEST(TrajectoryMessageTest, PackFormatVersion2) { trajectorySendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_2); BuildUpElements(); igtlMetaDataAddElementMacro(trajectorySendMsg); trajectorySendMsg->Pack(); int r = memcmp((const void*)trajectorySendMsg->GetPackPointer(), (const void*)test_trajectory_message_Format2, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)trajectorySendMsg->GetPackBodyPointer(), (const void*)(test_trajectory_message_Format2+(size_t)(IGTL_HEADER_SIZE)), IGTL_TRAJECTORY_ELEMENT_SIZE*3 + EXTENDED_CONTENT_SIZE); EXPECT_EQ(r, 0); } TEST(TrajectoryMessageTest, UnpackFormatVersion2) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), trajectorySendMsg->GetPackPointer(), IGTL_HEADER_SIZE); headerMsg->Unpack(); trajectoryReceiveMsg->SetMessageHeader(headerMsg); trajectoryReceiveMsg->AllocatePack(); memcpy(trajectoryReceiveMsg->GetPackBodyPointer(), trajectorySendMsg->GetPackBodyPointer(), IGTL_TRAJECTORY_ELEMENT_SIZE*3 + EXTENDED_CONTENT_SIZE); trajectoryReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)trajectoryReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "TRAJ"); EXPECT_EQ(messageHeader->header_version, 2); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_TRAJECTORY_ELEMENT_SIZE*3 + EXTENDED_CONTENT_SIZE); std::vector > groundTruthRGBA(3,std::vector(4)); igtlUint8 tempIni1[4] = {255,0,0,255}; groundTruthRGBA[0].assign(tempIni1,tempIni1+4); igtlUint8 tempIni2[4] = {0,255,0,255}; groundTruthRGBA[1].assign(tempIni2,tempIni2+4); igtlUint8 tempIni3[4] = {0,0,255,255}; groundTruthRGBA[2].assign(tempIni3,tempIni3+4); igtlFloat32 groundTruthEntryPoints[3][3] ={{10.0,15.0,20.0}, {40.0,45.0,50.0}, {70.0,75.0,80.0}}; igtlFloat32 groundTruthTargetPoints[3][3] = {{25.0,30.0,35.0}, {55.0,60.0,65.0}, {85.0,90.0,95.0}}; igtlFloat32 groundTruthRadius[3] = {5.0,2.5,0.0}; std::vector trajectoryDescription; trajectoryDescription.push_back((char*)"TRAJECTORY_DESCRIPTION_0"); trajectoryDescription.push_back((char*)"TRAJECTORY_DESCRIPTION_1"); trajectoryDescription.push_back((char*)"TRAJECTORY_DESCRIPTION_2"); for (int i = 0; i<3;++i) { igtl::TrajectoryElement::Pointer elem = igtl::TrajectoryElement::New(); trajectoryReceiveMsg->GetTrajectoryElement(i, elem); EXPECT_EQ(strncmp((char*)(elem->GetName()), trajectoryDescription[i], 24),0); igtlUint8 returnedRGBA[4] ={0,0,0,0}; elem->GetRGBA(returnedRGBA); EXPECT_THAT(returnedRGBA, testing::ElementsAreArray(groundTruthRGBA[i])); igtlFloat32 returnedEntryPoint[3] ={0,0,0}; elem->GetEntryPosition(returnedEntryPoint); EXPECT_TRUE(ArrayFloatComparison(returnedEntryPoint, groundTruthEntryPoints[i], 3, ABS_ERROR)); igtlFloat32 returnedTargetPoint[3] ={0,0,0}; elem->GetTargetPosition(returnedTargetPoint); EXPECT_TRUE(ArrayFloatComparison(returnedTargetPoint, groundTruthTargetPoints[i], 3, ABS_ERROR)); EXPECT_EQ(elem->GetRadius(), groundTruthRadius[i]); EXPECT_EQ(strncmp((char*)elem->GetOwner(), "IMAGE_0", 7),0); } igtlMetaDataComparisonMacro(trajectoryReceiveMsg); } #endif int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlTransformMessageTest.cxx000066400000000000000000000130651501024245700232030ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Language: C++ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtlTransformMessage.h" #include "igtlutil/igtl_test_data_transform.h" #include "igtlMessageDebugFunction.h" #include "igtl_transform.h" #include "igtl_header.h" #include "igtlTestConfig.h" #include "string.h" igtl::TransformMessage::Pointer transformSendMsg = igtl::TransformMessage::New(); igtl::TransformMessage::Pointer transformReceiveMsg = igtl::TransformMessage::New(); float inT[4] = {-0.954892f, 0.196632f, -0.222525f, 0.0}; float inS[4] = {-0.196632f, 0.142857f, 0.970014f, 0.0}; float inN[4] = {0.222525f, 0.970014f, -0.0977491f, 0.0}; float inOrigin[4] = {46.0531f,19.4709f,46.0531f, 1.0}; igtl::Matrix4x4 inMatrix = {{inT[0],inS[0],inN[0],inOrigin[0]}, {inT[1],inS[1],inN[1],inOrigin[1]}, {inT[2],inS[2],inN[2],inOrigin[2]}, {inT[3],inS[3],inN[3],inOrigin[3]}}; TEST(TransformMessageTest, PackFormatVersion1) { transformSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_1); transformSendMsg->AllocatePack(); transformSendMsg->SetTimeStamp(0, 1234567892); transformSendMsg->SetDeviceName("DeviceName"); transformSendMsg->SetMatrix(inMatrix); transformSendMsg->Pack(); int r = memcmp((const void*)transformSendMsg->GetPackPointer(), (const void*)test_transform_message, (size_t)(IGTL_HEADER_SIZE)); EXPECT_EQ(r, 0); r = memcmp((const void*)transformSendMsg->GetPackBodyPointer(), (const void*)(test_transform_message+IGTL_HEADER_SIZE), IGTL_TRANSFORM_SIZE); EXPECT_EQ(r, 0); } TEST(TransformMessageTest, UnpackFormatVersion1) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)test_transform_message, IGTL_HEADER_SIZE); headerMsg->Unpack(); transformReceiveMsg->SetMessageHeader(headerMsg); transformReceiveMsg->AllocatePack(); memcpy(transformReceiveMsg->GetPackBodyPointer(), transformSendMsg->GetPackBodyPointer(), transformReceiveMsg->GetPackBodySize()); transformReceiveMsg->Unpack(); igtl_header *messageHeader = (igtl_header *)transformReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "TRANSFORM"); EXPECT_EQ(messageHeader->header_version, 1); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_TRANSFORM_SIZE); igtl::Matrix4x4 outMatrix = {{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.0,0.0,0.0}}; transformReceiveMsg->GetMatrix(outMatrix); EXPECT_TRUE(MatrixComparison(outMatrix, inMatrix, ABS_ERROR)); } #if OpenIGTLink_PROTOCOL_VERSION >= 3 #include "igtlutil/igtl_test_data_transformFormat2.h" #include "igtlMessageFormat2TestMacro.h" TEST(TransformMessageTest, PackFormatVersion2) { transformSendMsg = igtl::TransformMessage::New(); transformSendMsg->SetHeaderVersion(IGTL_HEADER_VERSION_2); transformSendMsg->AllocatePack(); transformSendMsg->SetTimeStamp(0, 1234567892); transformSendMsg->SetDeviceName("DeviceName"); transformSendMsg->SetMatrix(inMatrix); igtlMetaDataAddElementMacro(transformSendMsg); transformSendMsg->Pack(); int r = memcmp((const void*)transformSendMsg->GetPackPointer(), (const void*)test_transform_message_Format2, (size_t)(IGTL_HEADER_SIZE)); TestDebugCharArrayCmp(transformSendMsg->GetPackPointer(), test_transform_message_Format2, IGTL_HEADER_SIZE); EXPECT_EQ(r, 0); r = memcmp((const void*)transformSendMsg->GetPackBodyPointer(), (const void*)(test_transform_message_Format2+IGTL_HEADER_SIZE), IGTL_TRANSFORM_SIZE + EXTENDED_CONTENT_SIZE); EXPECT_EQ(r, 0); } TEST(TransformMessageTest, UnpackFormatVersion2) { igtl::MessageHeader::Pointer headerMsg = igtl::MessageHeader::New(); headerMsg->AllocatePack(); memcpy(headerMsg->GetPackPointer(), (const void*)test_transform_message_Format2, IGTL_HEADER_SIZE); headerMsg->Unpack(); transformReceiveMsg = igtl::TransformMessage::New(); transformReceiveMsg->SetMessageHeader(headerMsg); transformReceiveMsg->AllocatePack(); memcpy(transformReceiveMsg->GetPackBodyPointer(), transformSendMsg->GetPackBodyPointer(), transformReceiveMsg->GetPackBodySize()); transformReceiveMsg->Unpack(1); igtl_header *messageHeader = (igtl_header *)transformReceiveMsg->GetPackPointer(); EXPECT_STREQ(messageHeader->device_name, "DeviceName"); EXPECT_STREQ(messageHeader->name, "TRANSFORM"); EXPECT_EQ(messageHeader->header_version, 2); EXPECT_EQ(messageHeader->timestamp, 1234567892); EXPECT_EQ(messageHeader->body_size, IGTL_TRANSFORM_SIZE + EXTENDED_CONTENT_SIZE); igtl::Matrix4x4 outMatrix = {{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.0,0.0,0.0}}; transformReceiveMsg->GetMatrix(outMatrix); EXPECT_TRUE(MatrixComparison(outMatrix, inMatrix, ABS_ERROR)); igtlMetaDataComparisonMacro(transformReceiveMsg); } #endif int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } openigtlink-3.0.0/Testing/igtlutil/000077500000000000000000000000001501024245700173075ustar00rootroot00000000000000openigtlink-3.0.0/Testing/igtlutil/CMakeLists.txt000066400000000000000000000074101501024245700220510ustar00rootroot00000000000000find_package(OpenIGTLink REQUIRED) include(${OpenIGTLink_USE_FILE}) include_directories(${OpenIGTLink_INCLUDE_DIRS}) link_directories(${OpenIGTLink_LIBRARY_DIRS}) ADD_EXECUTABLE(igtl_image_test igtl_image_test.c) ADD_EXECUTABLE(igtl_header_test igtl_header_test.c) ADD_EXECUTABLE(igtl_transform_test igtl_transform_test.c) ADD_EXECUTABLE(igtl_status_test igtl_status_test.c) ADD_EXECUTABLE(igtl_util_test igtl_util_test.c) ADD_EXECUTABLE(igtl_position_test igtl_position_test.c) ADD_EXECUTABLE(igtl_capability_test igtl_capability_test.c) if (${OpenIGTLink_PROTOCOL_VERSION} GREATER "1") ADD_EXECUTABLE(igtl_colortable_test igtl_colortable_test.c) ADD_EXECUTABLE(igtl_imgmeta_test igtl_imgmeta_test.c) ADD_EXECUTABLE(igtl_lbmeta_test igtl_lbmeta_test.c) ADD_EXECUTABLE(igtl_point_test igtl_point_test.c) ADD_EXECUTABLE(igtl_tdata_test igtl_tdata_test.c) ADD_EXECUTABLE(igtl_trajectory_test igtl_trajectory_test.c) ADD_EXECUTABLE(igtl_sensor_test igtl_sensor_test.c) ADD_EXECUTABLE(igtl_string_test igtl_string_test.c) ADD_EXECUTABLE(igtl_bind_test igtl_bind_test.c) ADD_EXECUTABLE(igtl_ndarray_test igtl_ndarray_test.c) ADD_EXECUTABLE(igtl_polydata_test igtl_polydata_test.c) endif () TARGET_LINK_LIBRARIES(igtl_image_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_header_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_transform_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_status_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_util_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_position_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_capability_test OpenIGTLink) if (${OpenIGTLink_PROTOCOL_VERSION} GREATER "1") TARGET_LINK_LIBRARIES(igtl_colortable_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_imgmeta_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_lbmeta_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_point_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_tdata_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_trajectory_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_sensor_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_string_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_bind_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_ndarray_test OpenIGTLink) TARGET_LINK_LIBRARIES(igtl_polydata_test OpenIGTLink) endif () ADD_TEST( igtl_image_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_image_test ) ADD_TEST( igtl_header_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_header_test ) ADD_TEST( igtl_transform_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_transform_test ) ADD_TEST( igtl_status_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_status_test ) ADD_TEST( igtl_util_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_util_test ) ADD_TEST( igtl_position_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_position_test ) ADD_TEST( igtl_capability_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_capability_test ) if (${OpenIGTLink_PROTOCOL_VERSION} GREATER "1") ADD_TEST( igtl_colortable_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_colortable_test ) ADD_TEST( igtl_imgmeta_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_imgmeta_test ) ADD_TEST( igtl_lbmeta_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_lbmeta_test ) ADD_TEST( igtl_point_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_point_test ) ADD_TEST( igtl_tdata_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_tdata_test ) ADD_TEST( igtl_trajectory_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_trajectory_test ) ADD_TEST( igtl_sensor_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_sensor_test ) ADD_TEST( igtl_string_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_string_test ) ADD_TEST( igtl_bind_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_bind_test ) ADD_TEST( igtl_ndarray_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_ndarray_test ) ADD_TEST( igtl_polydata_test_01 ${OpenIGTLink_EXECUTABLE_PATH}/igtl_polydata_test ) endif () openigtlink-3.0.0/Testing/igtlutil/igtl_bind_test.c000066400000000000000000000207211501024245700224470ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_types.h" #include "igtl_header.h" #include "igtl_image.h" #include "igtl_sensor.h" #include "igtl_bind.h" #include "igtl_util.h" #include "igtl_transform.h" #include #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 /* Include serialized test data (gold standard) */ #include "igtl_test_data_bind.h" #include "igtl_test_data_transform.h" #include "igtl_test_data_image.h" #include "igtl_test_data_status.h" #pragma pack(1) /* * Structure for byte array of test message body. * Since sizes of all child messages in this test program are even, * there is no padding inserted at the end of each child message. * In general, a padding byte is added to the end of each message body, * if the message body size is odd. * */ typedef struct { igtl_float32 transform[12]; } transform_message_body; typedef struct { igtl_image_header iheader; /* image header */ igtl_uint8 image[TEST_IMAGE_MESSAGE_SIZE]; } image_message_body; typedef struct { igtl_sensor_header sensor; igtl_float64 value[6]; } sensor_message_body; typedef struct { transform_message_body transform; image_message_body image; sensor_message_body sensor; } child_message_body; #pragma pack() void generate_transform_body(transform_message_body * body) { body->transform[0] = -0.954892f; body->transform[1] = 0.196632f; body->transform[2] = -0.222525f; body->transform[3] = -0.196632f; body->transform[4] = 0.142857f; body->transform[5] = 0.970014f; body->transform[6] = 0.222525f; body->transform[7] = 0.970014f; body->transform[8] = -0.0977491f; body->transform[9] = 46.0531f; body->transform[10] = 19.4709f; body->transform[11] = 46.0531f; igtl_transform_convert_byte_order(body->transform); } igtl_uint64 generate_image_body(image_message_body * body) { igtl_uint64 image_size; igtl_float32 spacing[] = {1.0f, 1.0f, 1.0f}; igtl_float32 origin[] = {46.0531f, 19.4709f, 46.0531f}; igtl_float32 norm_i[] = {-0.954892f, 0.196632f, -0.222525f}; igtl_float32 norm_j[] = {-0.196632f, 0.142857f, 0.970014f}; igtl_float32 norm_k[] = {0.222525f, 0.970014f, -0.0977491f}; /* Set data */ body->iheader.header_version = 1; body->iheader.num_components = 1; /* Scalar */ body->iheader.scalar_type = 3; /* uint8 */ body->iheader.endian = 2; /* Little endian */ body->iheader.coord = 1; /* RAS */ body->iheader.size[0] = 50; body->iheader.size[1] = 50; body->iheader.size[2] = 1; /* Dimensions */ body->iheader.subvol_offset[0] = 0; body->iheader.subvol_offset[1] = 0; body->iheader.subvol_offset[2] = 0; body->iheader.subvol_size[0] = 50; body->iheader.subvol_size[1] = 50; body->iheader.subvol_size[2] = 1; igtl_image_set_matrix(spacing, origin, norm_i, norm_j, norm_k, &(body->iheader)); /* Copy image data */ memcpy((void*)body->image, (void*)test_image, TEST_IMAGE_MESSAGE_SIZE); /* Get image data size -- note that this should be done before byte order swapping. */ image_size = igtl_image_get_data_size(&(body->iheader)); /* Swap byte order if necessary */ igtl_image_convert_byte_order(&(body->iheader)); return image_size; } unsigned int generate_sensor_body(sensor_message_body * body) { igtl_unit_data unit_data; /*igtl_uint64 crc;*/ unsigned int value_size; /* Create unit (m/s^2) */ igtl_unit_init(&unit_data); unit_data.prefix = IGTL_UNIT_PREFIX_NONE; unit_data.unit[0] = IGTL_UNIT_SI_BASE_METER; unit_data.exp[0] = (igtl_int8) 1; unit_data.unit[1] = IGTL_UNIT_SI_BASE_SECOND; unit_data.exp[1] = (igtl_int8) -2; /* Set dummy sensor header and values */ body->sensor.larray = 6; body->sensor.status = 0; body->sensor.unit = igtl_unit_pack(&(unit_data)); body->value[0] = 123456.78; body->value[1] = 12345.678; body->value[2] = 1234.5678; body->value[3] = 123.45678; body->value[4] = 12.345678; body->value[5] = 1.2345678; value_size = igtl_sensor_get_data_size(&(body->sensor)); igtl_sensor_convert_byte_order(&(body->sensor), body->value); return value_size; } int main( int argc, char * argv [] ) { /* Message structures and byte array */ igtl_header header; void* bind_header; child_message_body child_body; igtl_bind_info bind_info; size_t bind_size; size_t child_body_size; int rh; /* Comparison result for header */ int rb; /* Comparison result for BIND header section*/ int rc; /* Comparison result for child body section */ int s; igtl_bind_init_info(&bind_info); /* Generate transform message */ generate_transform_body(&(child_body.transform)); /* Generate image message */ generate_image_body(&(child_body.image)); /* Generate sensor message */ generate_sensor_body(&(child_body.sensor)); /* Set up BIND info structure */ if (igtl_bind_alloc_info(&bind_info, 3) == 0) { return EXIT_FAILURE; } strncpy(bind_info.child_info_array[0].type, "TRANSFORM", IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[0].name, "ChildTrans", IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[0].size = sizeof(transform_message_body); bind_info.child_info_array[0].ptr = (void*)&child_body.transform; strncpy(bind_info.child_info_array[1].type, "IMAGE", IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[1].name, "ChildImage", IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[1].size = sizeof(image_message_body); bind_info.child_info_array[1].ptr = (void*)&child_body.image; strncpy(bind_info.child_info_array[2].type, "SENSOR", IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[2].name, "ChildSensor", IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[2].size = sizeof(sensor_message_body); bind_info.child_info_array[2].ptr = (void*)&child_body.sensor; bind_size = (size_t)igtl_bind_get_size(&bind_info, IGTL_TYPE_PREFIX_NONE); bind_header = malloc(bind_size); if (bind_header == NULL) { igtl_bind_free_info(&bind_info); return EXIT_FAILURE; } igtl_bind_pack(&bind_info, bind_header, IGTL_TYPE_PREFIX_NONE); /* Calculate the sum of child body size and paddings (0 in this test program) */ child_body_size = (size_t) (bind_info.child_info_array[0].size + bind_info.child_info_array[1].size + bind_info.child_info_array[2].size); /* Set header */ header.header_version = 1; strncpy( (char*)&(header.name), "BIND", 12 ); strncpy( (char*)&(header.device_name), "DeviceName", 20 ); header.timestamp = 1234567892; header.body_size = bind_size + sizeof(child_message_body); header.crc = igtl_bind_get_crc(&bind_info, IGTL_TYPE_PREFIX_NONE, bind_header); igtl_header_convert_byte_order( &(header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("bind.bin", "w"); fwrite(&(header), IGTL_HEADER_SIZE, 1, fp); fwrite(bind_header, bind_size, 1, fp); fwrite(&(child_body), child_body_size, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ rh = memcmp((const void*)&header, (const void*)test_bind_message_header, IGTL_HEADER_SIZE); rb = memcmp((const void*)bind_header, (const void*)test_bind_message_bind_header, bind_size); rc = memcmp((const void*)&child_body, (const void*)test_bind_message_bind_body, child_body_size); igtl_bind_free_info(&bind_info); free(bind_header); if (rh == 0 && rb == 0 && rc == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+bind_size+child_body_size; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&header, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_capability_test.c000066400000000000000000000057011501024245700236550ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_types.h" #include "igtl_header.h" #include "igtl_capability.h" #include "igtl_util.h" /* include test capability data and serialized capability message */ #include "igtl_test_data_capability.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #define TEST_CAPABILITY_SIZE 256 #pragma pack(1) struct capability_message { igtl_header header; unsigned char body[IGTL_HEADER_TYPE_SIZE*4]; }; #pragma pack() int main( int argc, char * argv [] ) { igtl_capability_info info; struct capability_message message; int r; int s; igtl_capability_alloc_info(&info, 4); /* Test structure size */ if (sizeof(message) != IGTL_HEADER_SIZE+igtl_capability_get_length(&info)) { fprintf(stdout, "Invalid size of capability message structure.\n"); return EXIT_FAILURE; } strcpy((char*)info.typenames[0], "IMAGE"); strcpy((char*)info.typenames[1], "GET_IMAGE"); strcpy((char*)info.typenames[2], "TRANSFORM"); strcpy((char*)info.typenames[3], "GET_TRANS"); igtl_capability_pack(&info, message.body); /* Create OpenIGTLink header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "CAPABILITY", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = igtl_capability_get_length(&info); message.header.crc = igtl_capability_get_crc(&info, message.body); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for debugging */ /* FILE *fp; fp = fopen("capability.bin", "w"); fwrite(&(message), IGTL_HEADER_SIZE+igtl_capability_get_length(&info), 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_capability_message, (size_t)(IGTL_HEADER_SIZE+igtl_capability_get_length(&info))); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+igtl_capability_get_length(&info); if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_colortable_test.c000066400000000000000000000062621501024245700236650ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_types.h" #include "igtl_header.h" #include "igtl_colortable.h" #include "igtl_util.h" /* include test colortable data and serialized colortable message */ #include "igtl_test_data_colortable.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #define TEST_COLORTABLE_SIZE 256 #pragma pack(1) struct colortable_message { igtl_header header; igtl_colortable_header cheader; /* colortable header */ igtl_uint8 table[TEST_COLORTABLE_SIZE]; }; #pragma pack() int main( int argc, char * argv [] ) { struct colortable_message message; igtl_uint64 table_size; int r; int s; int i; /* Test structure size */ if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_COLORTABLE_HEADER_SIZE+TEST_COLORTABLE_SIZE) { fprintf(stdout, "Invalid size of colortable message structure.\n"); return EXIT_FAILURE; } /* Set COLORTABLE message */ message.cheader.indexType = IGTL_COLORTABLE_INDEX_UINT8; message.cheader.mapType = IGTL_COLORTABLE_MAP_UINT8; for (i = 0; i < 256; i ++) { message.table[i] = i; } /* Get image data size -- note that this should be done before byte order swapping. */ table_size = igtl_colortable_get_table_size(&(message.cheader)); /* Swap byte order if necessary */ igtl_colortable_convert_byte_order(&(message.cheader), (void*)&(message.table)); /* Create OpenIGTLink header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "COLORTABLE", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_COLORTABLE_HEADER_SIZE + table_size; message.header.crc = igtl_colortable_get_crc(&(message.cheader), (void*)message.table); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for debugging */ /* FILE *fp; fp = fopen("colortable.bin", "w"); fwrite(&(message), IGTL_HEADER_SIZE+IGTL_COLORTABLE_HEADER_SIZE+TEST_COLORTABLE_SIZE, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_colortable_message, (size_t)(IGTL_HEADER_SIZE+IGTL_COLORTABLE_HEADER_SIZE)); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_COLORTABLE_HEADER_SIZE+(int)table_size; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_header_test.c000066400000000000000000000041231501024245700227610ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include "igtl_util.h" #include "igtl_header.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 char barray[] = { 0x00, 0x01, /* Version number */ 0x54, 0x59, 0x50, 0x45, 0x4e, 0x41, 0x4d, 0x45, 0x00, 0x00, 0x00, 0x00, /* TYPENAME */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd2, /* Time stamp */ 0x00, 0x00, 0x00, 0x07, 0x50, 0x88, 0xFF, 0x06, /* Body size */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x7E, 0xA7, /* CRC */ }; int main( int argc, char * argv [] ) { igtl_header header; // Test structure size if (sizeof(header) != IGTL_HEADER_SIZE) { fprintf(stdout, "Invalid size of header structure.\n"); return EXIT_FAILURE; } // Test binary header.header_version = 1; strncpy( header.name, "TYPENAME", 12 ); strncpy( header.device_name, "DeviceName", 20 ); header.timestamp = 1234567890; header.body_size = 31415926534; header.crc = 1343143; igtl_header_convert_byte_order( &header ); if (memcmp((const void*)&header, (const void*)barray, IGTL_HEADER_SIZE) == 0) { return EXIT_SUCCESS; } else { /* Print message as HEX values in STDERR for debug */ fprintf(stdout, "\n===== First %d bytes of the test message =====\n", IGTL_HEADER_SIZE); igtl_message_dump_hex(stdout, (const void*)&header, IGTL_HEADER_SIZE); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_image_test.c000066400000000000000000000075701501024245700226240ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_types.h" #include "igtl_header.h" #include "igtl_image.h" #include "igtl_util.h" /* include test image data and serialized image message */ #include "igtl_test_data_image.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #pragma pack(1) struct image_message { igtl_header header; igtl_image_header iheader; /* image header */ igtl_uint8 image[TEST_IMAGE_MESSAGE_SIZE]; }; #pragma pack() int main( int argc, char * argv [] ) { struct image_message message; int r; igtl_uint64 image_size; int s; igtl_float32 spacing[] = {1.0f, 1.0f, 1.0f}; igtl_float32 origin[] = {46.0531f, 19.4709f, 46.0531f}; igtl_float32 norm_i[] = {-0.954892f, 0.196632f, -0.222525f}; igtl_float32 norm_j[] = {-0.196632f, 0.142857f, 0.970014f}; igtl_float32 norm_k[] = {0.222525f, 0.970014f, -0.0977491f}; /* Test structure size */ if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE+TEST_IMAGE_MESSAGE_SIZE) { fprintf(stdout, "Invalid size of image message structure.\n"); return EXIT_FAILURE; } /* Set data */ message.iheader.header_version = 1; message.iheader.num_components = 1; /* Scalar */ message.iheader.scalar_type = 3; /* uint8 */ message.iheader.endian = 2; /* Little endian */ message.iheader.coord = 1; /* RAS */ message.iheader.size[0] = 50; message.iheader.size[1] = 50; message.iheader.size[2] = 1; /* Dimensions */ message.iheader.subvol_offset[0] = 0; message.iheader.subvol_offset[1] = 0; message.iheader.subvol_offset[2] = 0; message.iheader.subvol_size[0] = 50; message.iheader.subvol_size[1] = 50; message.iheader.subvol_size[2] = 1; igtl_image_set_matrix(spacing, origin, norm_i, norm_j, norm_k, &(message.iheader)); /* Copy image data */ memcpy((void*)message.image, (void*)test_image, TEST_IMAGE_MESSAGE_SIZE); /* Get image data size -- note that this should be done before byte order swapping. */ image_size = igtl_image_get_data_size(&(message.iheader)); /* Swap byte order if necessary */ igtl_image_convert_byte_order(&(message.iheader)); /* Create OpenIGTLink header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "IMAGE", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_IMAGE_HEADER_SIZE + image_size; message.header.crc = igtl_image_get_crc(&(message.iheader), message.image); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for debugging */ /* FILE *fp; fp = fopen("image.bin", "w"); fwrite(&(message), IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE+image_size, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_image_message, (size_t)(IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE+image_size)); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_IMAGE_HEADER_SIZE+ (int)image_size; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_imgmeta_test.c000066400000000000000000000110541501024245700231550ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_types.h" #include "igtl_header.h" #include "igtl_imgmeta.h" #include "igtl_util.h" /* include test imgmeta data and serialized imgmeta message */ #include "igtl_test_data_imgmeta.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #define TEST_IMGMETA_NUM 3 #pragma pack(1) struct imgmeta_message { igtl_header header; igtl_imgmeta_element metalist[TEST_IMGMETA_NUM]; }; #pragma pack() int main( int argc, char * argv [] ) { struct imgmeta_message message; int r; int s; /* Test structure size */ if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_IMGMETA_ELEMENT_SIZE*TEST_IMGMETA_NUM) { fprintf(stdout, "Invalid size of imgmeta message structure.\n"); return EXIT_FAILURE; } /* Image meta data 0 */ strncpy((char*)&(message.metalist[0].name), "IMAGE_DESCRIPTION_0", 64); strncpy((char*)&(message.metalist[0].device_name), "IMAGE_0", 20); strncpy((char*)&(message.metalist[0].modality), "CT", 32); strncpy((char*)&(message.metalist[0].patient_name), "PATIENT_0", 64); strncpy((char*)&(message.metalist[0].patient_id), "PATIENT_ID_0", 64); message.metalist[0].timestamp = 1234567892; message.metalist[0].size[0] = 512; message.metalist[0].size[1] = 512; message.metalist[0].size[2] = 64; message.metalist[0].scalar_type = IGTL_IMAGE_STYPE_TYPE_UINT16; message.metalist[0].reserved = 0; /* Image meta data 1 */ strncpy((char*)&(message.metalist[1].name), "IMAGE_DESCRIPTION_1", 64); strncpy((char*)&(message.metalist[1].device_name), "IMAGE_1", 20); strncpy((char*)&(message.metalist[1].modality), "MRI", 32); strncpy((char*)&(message.metalist[1].patient_name), "PATIENT_1", 64); strncpy((char*)&(message.metalist[1].patient_id), "PATIENT_ID_1", 64); message.metalist[1].timestamp = 1234567896; message.metalist[1].size[0] = 256; message.metalist[1].size[1] = 128; message.metalist[1].size[2] = 32; message.metalist[1].scalar_type = IGTL_IMAGE_STYPE_TYPE_UINT16; message.metalist[1].reserved = 0; /* Image meta data 2 */ strncpy((char*)&(message.metalist[2].name), "IMAGE_DESCRIPTION_2", 64); strncpy((char*)&(message.metalist[2].device_name), "IMAGE_2", 20); strncpy((char*)&(message.metalist[2].modality), "PET", 32); strncpy((char*)&(message.metalist[2].patient_name), "PATIENT_2", 64); strncpy((char*)&(message.metalist[2].patient_id), "PATIENT_ID_2", 64); message.metalist[2].timestamp = 1234567900; message.metalist[2].size[0] = 256; message.metalist[2].size[1] = 256; message.metalist[2].size[2] = 32; message.metalist[2].scalar_type = IGTL_IMAGE_STYPE_TYPE_UINT16; message.metalist[2].reserved = 0; /* Swap byte order if necessary */ igtl_imgmeta_convert_byte_order(message.metalist, TEST_IMGMETA_NUM); /* Create OpenIGTLink header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "IMGMETA", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_IMGMETA_ELEMENT_SIZE*TEST_IMGMETA_NUM; message.header.crc = igtl_imgmeta_get_crc(message.metalist, TEST_IMGMETA_NUM); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for debugging */ /* FILE *fp; fp = fopen("imgmeta.bin", "w"); fwrite(&(message), IGTL_HEADER_SIZE+IGTL_IMGMETA_ELEMENT_SIZE*TEST_IMGMETA_NUM, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_imgmeta_message, (size_t)(IGTL_HEADER_SIZE+IGTL_IMGMETA_ELEMENT_SIZE*TEST_IMGMETA_NUM)); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_IMGMETA_ELEMENT_SIZE*TEST_IMGMETA_NUM; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_lbmeta_test.c000066400000000000000000000104451501024245700230010ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_types.h" #include "igtl_header.h" #include "igtl_lbmeta.h" #include "igtl_util.h" /* include test lbmeta data and serialized lbmeta message */ #include "igtl_test_data_lbmeta.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #define TEST_LBMETA_NUM 3 #pragma pack(1) struct lbmeta_message { igtl_header header; igtl_lbmeta_element metalist[TEST_LBMETA_NUM]; }; #pragma pack() int main( int argc, char * argv [] ) { struct lbmeta_message message; int r; int s; // Test structure size if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_LBMETA_ELEMENT_SIZE*TEST_LBMETA_NUM) { fprintf(stdout, "Invalid size of lbmeta message structure.\n"); return EXIT_FAILURE; } /* Label meta data 0 */ strncpy((char*)&(message.metalist[0].name), "LABEL_DESCRIPTION_0", 64); strncpy((char*)&(message.metalist[0].device_name), "LABEL_0", 20); message.metalist[0].label = 1; message.metalist[0].reserved = 0; message.metalist[0].rgba[0] = 255; message.metalist[0].rgba[1] = 0; message.metalist[0].rgba[2] = 0; message.metalist[0].rgba[3] = 255; message.metalist[0].size[0] = 256; message.metalist[0].size[1] = 128; message.metalist[0].size[2] = 32; strncpy((char*)&(message.metalist[0].owner), "IMAGE_0", 20); /* Label meta data 1 */ strncpy((char*)&(message.metalist[1].name), "LABEL_DESCRIPTION_1", 64); strncpy((char*)&(message.metalist[1].device_name), "LABEL_1", 20); message.metalist[1].label = 2; message.metalist[1].reserved = 0; message.metalist[1].rgba[0] = 0; message.metalist[1].rgba[1] = 255; message.metalist[1].rgba[2] = 0; message.metalist[1].rgba[3] = 255; message.metalist[1].size[0] = 256; message.metalist[1].size[1] = 128; message.metalist[1].size[2] = 32; strncpy((char*)&(message.metalist[1].owner), "IMAGE_0", 20); /* Label meta data 2 */ strncpy((char*)&(message.metalist[2].name), "LABEL_DESCRIPTION_2", 64); strncpy((char*)&(message.metalist[2].device_name), "LABEL_2", 20); message.metalist[2].label = 3; message.metalist[2].reserved = 0; message.metalist[2].rgba[0] = 0; message.metalist[2].rgba[1] = 0; message.metalist[2].rgba[2] = 255; message.metalist[2].rgba[3] = 255; message.metalist[2].size[0] = 256; message.metalist[2].size[1] = 128; message.metalist[2].size[2] = 32; strncpy((char*)&(message.metalist[2].owner), "IMAGE_0", 20); /* Swap byte order if necessary */ igtl_lbmeta_convert_byte_order(message.metalist, TEST_LBMETA_NUM); /* Create OpenIGTLink header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "LBMETA", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_LBMETA_ELEMENT_SIZE*TEST_LBMETA_NUM; message.header.crc = igtl_lbmeta_get_crc(message.metalist, TEST_LBMETA_NUM); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for debugging */ /* FILE *fp; fp = fopen("lbmeta.bin", "w"); fwrite(&(message), IGTL_HEADER_SIZE+IGTL_LBMETA_ELEMENT_SIZE*TEST_LBMETA_NUM, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_lbmeta_message, (size_t)(IGTL_HEADER_SIZE+IGTL_LBMETA_ELEMENT_SIZE*TEST_LBMETA_NUM)); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_LBMETA_ELEMENT_SIZE*TEST_LBMETA_NUM; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_ndarray_test.c000066400000000000000000000064361501024245700232020ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_types.h" #include "igtl_header.h" #include "igtl_ndarray.h" #include "igtl_util.h" #include #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 /* Include serialized test data (gold standard) */ #include "igtl_test_data_ndarray.h" int main( int argc, char * argv [] ) { /*** Message structures and byte array ***/ igtl_header header; void * body; igtl_ndarray_info info; size_t body_size; igtl_uint16 size[3]; int i, j, k; igtl_float64 * array; int rh; /* Comparison result for header */ int rb; /* Comparison result for body */ int s; /*** Generate test data ***/ igtl_ndarray_init_info(&info); info.type = IGTL_NDARRAY_STYPE_TYPE_FLOAT64; /* Array size is 5x4x3 */ info.dim = 3; size[0] = 5; size[1] = 4; size[2] = 3; if (igtl_ndarray_alloc_info(&info, size) == 0) { return EXIT_FAILURE; } /* Generate dummy array */ array = (igtl_float64 *) info.array; for (i = 0; i < 5; i ++) { for (j = 0; j < 4; j ++) { for (k = 0; k < 3; k ++) { array[i*(4*3) + j*3 + k] = (igtl_float64) (i*(4*3) + j*3 + k); } } } /** Allocate memory for pack **/ body_size = (size_t)igtl_ndarray_get_size(&info, IGTL_TYPE_PREFIX_NONE); body = malloc(body_size); if (body == NULL) { igtl_ndarray_free_info(&info); return EXIT_FAILURE; } igtl_ndarray_pack(&info, body, IGTL_TYPE_PREFIX_NONE); /*** Set OpenIGTLink header ***/ header.header_version = 1; strncpy( (char*)&(header.name), "NDARRAY", 12 ); strncpy( (char*)&(header.device_name), "DeviceName", 20 ); header.timestamp = 1234567892; header.body_size = body_size; header.crc = igtl_ndarray_get_crc(&info, IGTL_TYPE_PREFIX_NONE, body); igtl_header_convert_byte_order( &(header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("ndarray.bin", "w"); fwrite(&(header), IGTL_HEADER_SIZE, 1, fp); fwrite(body, body_size, 1, fp); fclose(fp); */ rh = memcmp((const void*)&header, (const void*)test_ndarray_message_header, IGTL_HEADER_SIZE); rb = memcmp((const void*)body, (const void*)test_ndarray_message_body, body_size); igtl_ndarray_free_info(&info); free(body); if (rh == 0 && rb == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE + body_size; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&header, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_point_test.c000066400000000000000000000103761501024245700226710ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_types.h" #include "igtl_header.h" #include "igtl_point.h" #include "igtl_util.h" /* include test point data and serialized point message */ #include "igtl_test_data_point.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #define TEST_POINT_NUM 3 #pragma pack(1) struct point_message { igtl_header header; igtl_point_element pointlist[TEST_POINT_NUM]; }; #pragma pack() int main( int argc, char * argv [] ) { struct point_message message; int r; int s; /* Test structure size */ if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_POINT_ELEMENT_SIZE*TEST_POINT_NUM) { fprintf(stdout, "Invalid size of point message structure.\n"); return EXIT_FAILURE; } /* Point data 0 */ strncpy((char*)&(message.pointlist[0].name), "POINT_DESCRIPTION_0", 64); strncpy((char*)&(message.pointlist[0].group_name), "Landmark", 32); message.pointlist[0].rgba[0] = 255; message.pointlist[0].rgba[1] = 0; message.pointlist[0].rgba[2] = 0; message.pointlist[0].rgba[3] = 255; message.pointlist[0].position[0] = 10.0; message.pointlist[0].position[1] = 15.0; message.pointlist[0].position[2] = 20.0; message.pointlist[0].radius = 5.0; strncpy((char*)&(message.pointlist[0].owner), "IMAGE_0", 20); /* Point data 1 */ strncpy((char*)&(message.pointlist[1].name), "POINT_DESCRIPTION_1", 64); strncpy((char*)&(message.pointlist[1].group_name), "Landmark", 32); message.pointlist[1].rgba[0] = 0; message.pointlist[1].rgba[1] = 255; message.pointlist[1].rgba[2] = 0; message.pointlist[1].rgba[3] = 255; message.pointlist[1].position[0] = 25.0; message.pointlist[1].position[1] = 30.0; message.pointlist[1].position[2] = 35.0; message.pointlist[1].radius = 3.0; strncpy((char*)&(message.pointlist[1].owner), "IMAGE_0", 20); /* Point data 2 */ strncpy((char*)&(message.pointlist[2].name), "POINT_DESCRIPTION_2", 64); strncpy((char*)&(message.pointlist[2].group_name), "Landmark", 32); message.pointlist[2].rgba[0] = 0; message.pointlist[2].rgba[1] = 0; message.pointlist[2].rgba[2] = 255; message.pointlist[2].rgba[3] = 255; message.pointlist[2].position[0] = 40.0; message.pointlist[2].position[1] = 45.0; message.pointlist[2].position[2] = 50.0; message.pointlist[2].radius = 1.0; strncpy((char*)&(message.pointlist[2].owner), "IMAGE_0", 20); /* Swap byte order if necessary */ igtl_point_convert_byte_order(message.pointlist, TEST_POINT_NUM); /* Create OpenIGTLink header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "POINT", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_POINT_ELEMENT_SIZE*TEST_POINT_NUM; message.header.crc = igtl_point_get_crc(message.pointlist, TEST_POINT_NUM); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for debugging */ /* FILE *fp; fp = fopen("point.bin", "w"); fwrite(&(message), IGTL_HEADER_SIZE+IGTL_POINT_ELEMENT_SIZE*TEST_POINT_NUM, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_point_message, (size_t)(IGTL_HEADER_SIZE+IGTL_POINT_ELEMENT_SIZE*TEST_POINT_NUM)); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_POINT_ELEMENT_SIZE*TEST_POINT_NUM; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_polydata_test.c000066400000000000000000000121161501024245700233470ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_types.h" #include "igtl_header.h" #include "igtl_polydata.h" #include "igtl_util.h" #include #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 /* Include serialized test data (gold standard) */ #include "igtl_test_data_polydata.h" int main( int argc, char * argv [] ) { /*** Message structures and byte array ***/ igtl_header header; void * body; igtl_polydata_info info; int rh; /* Comparison result for header */ int rb; /* Comparison result for body */ unsigned int i; int s; igtl_float32 * ptr_f; igtl_uint32 * ptr_i; igtl_uint64 body_size; static igtl_float32 points[8][3]={{0,0,0}, {1,0,0}, {1,1,0}, {0,1,0}, {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1}}; static igtl_uint32 poly[6][4]={{0,1,2,3}, {4,5,6,7}, {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7}}; static igtl_float32 attribute[8]={0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; /*** Generate test data ***/ /* Note that the size of polygon data (or other cell data) is calculated by * number of polygons * (number of points + 1) * '+ 1' is required because of the number of points in the polygon (uint32) * is stored at the begining of polygon data. */ igtl_polydata_init_info(&info); info.header.npoints = 8; info.header.nvertices = 0; info.header.size_vertices = 0; info.header.nlines = 0; info.header.size_lines = 0; info.header.npolygons = 6; info.header.size_polygons = 6 * ((4+1) * sizeof(igtl_float32)); info.header.ntriangle_strips = 0; info.header.size_triangle_strips = 0; info.header.nattributes = 1; if (igtl_polydata_alloc_info(&info) == 0) { return EXIT_FAILURE; } /*** Substitute cube point data ***/ if (info.points) { ptr_f = info.points; for (i = 0; i < info.header.npoints; i ++) { *(ptr_f++) = points[i][0]; *(ptr_f++) = points[i][1]; *(ptr_f++) = points[i][2]; } } else { return EXIT_FAILURE; } /*** Substitute polygon data ***/ if (info.polygons) { ptr_i = info.polygons; for (i = 0; i < info.header.npolygons; i ++) { *(ptr_i++) = 4; /* Number of points in the polygon */ *(ptr_i++) = poly[i][0]; *(ptr_i++) = poly[i][1]; *(ptr_i++) = poly[i][2]; *(ptr_i++) = poly[i][3]; } } /*** Substitute attribute data ***/ if (info.attributes) { info.attributes[0].type = IGTL_POLY_ATTR_TYPE_SCALAR; info.attributes[0].ncomponents = 1; info.attributes[0].n = 8; info.attributes[0].name = malloc(5); strcpy(info.attributes[0].name, "attr"); info.attributes[0].data = malloc(sizeof(igtl_float32) * 8); ptr_f = info.attributes[0].data; for (i = 0; i < 8; i ++) { *(ptr_f++) = attribute[i]; } } /** Allocate memory for pack **/ body_size = igtl_polydata_get_size(&info, IGTL_TYPE_PREFIX_NONE); body = malloc((igtl_uint32)body_size); if (body == NULL) { igtl_polydata_free_info(&info); return EXIT_FAILURE; } igtl_polydata_pack(&info, body, IGTL_TYPE_PREFIX_NONE); /*** Set OpenIGTLink header ***/ header.header_version = 1; strncpy( (char*)&(header.name), "POLYDATA", 12 ); strncpy( (char*)&(header.device_name), "DeviceName", 20 ); header.timestamp = 1234567892; header.body_size = body_size; header.crc = igtl_polydata_get_crc(&info, IGTL_TYPE_PREFIX_NONE, body); igtl_header_convert_byte_order( &(header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("polydata.bin", "w"); fwrite(&(header), IGTL_HEADER_SIZE, 1, fp); fwrite(body, body_size, 1, fp); fclose(fp); */ rh = memcmp((const void*)&header, (const void*)test_polydata_message_header, IGTL_HEADER_SIZE); rb = memcmp((const void*)body, (const void*)test_polydata_message_body, (size_t) body_size); igtl_polydata_free_info(&info); free(body); if (rh == 0 && rb == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE + (int)body_size; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&header, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_position_test.c000066400000000000000000000055701501024245700234040ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_types.h" #include "igtl_header.h" #include "igtl_position.h" #include "igtl_util.h" #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 /* The decimal is rounded when it is converted to IEEE 754 floating point */ /* Include serialized test data (gold standard) */ #include "igtl_test_data_position.h" #pragma pack(1) struct position_message { igtl_header header; igtl_position position; }; #pragma pack() int main( int argc, char * argv [] ) { struct position_message message; int r; // Test structure size if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_POSITION_MESSAGE_DEFAULT_SIZE) { fprintf(stdout, "Invalid size of position message structure.\n"); return EXIT_FAILURE; } /* Set dummy position */ message.position.position[0] = 46.0531f; message.position.position[1] = 19.4709f; message.position.position[2] = 46.0531f; message.position.quaternion[0] = 0.0; message.position.quaternion[1] = 0.5773502691f; message.position.quaternion[2] = 0.5773502692f; message.position.quaternion[3] = 0.3333333333f; igtl_position_convert_byte_order(&(message.position)); /* Set header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "POSITION", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_POSITION_MESSAGE_DEFAULT_SIZE; message.header.crc = igtl_position_get_crc(&(message.position)); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("position.bin", "w"); fwrite(&(message.header), IGTL_HEADER_SIZE+IGTL_POSITION_MESSAGE_DEFAULT_SIZE, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_position_message, IGTL_HEADER_SIZE+IGTL_POSITION_MESSAGE_DEFAULT_SIZE); if (r == 0) { return EXIT_SUCCESS; } else { /* Print message as HEX values in STDERR for debug */ fprintf(stdout, "\n===== First %d bytes of the test message =====\n", IGTL_HEADER_SIZE+IGTL_POSITION_MESSAGE_DEFAULT_SIZE); igtl_message_dump_hex(stdout, (const void*)&message, IGTL_HEADER_SIZE+IGTL_POSITION_MESSAGE_DEFAULT_SIZE); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_sensor_test.c000066400000000000000000000065401501024245700230470ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_types.h" #include "igtl_header.h" #include "igtl_sensor.h" #include "igtl_util.h" #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 /* Include serialized test data (gold standard) */ #include "igtl_test_data_sensor.h" #pragma pack(1) /* Test sensor message data (6-ch 64-bit float data, m/s^2) */ struct sensor_message { igtl_header header; igtl_sensor_header sensor; igtl_float64 value[6]; }; #pragma pack() int main( int argc, char * argv [] ) { struct sensor_message message; igtl_unit_data unit_data; /*igtl_uint64 crc;*/ unsigned int value_size; int r; int s; // Test structure size if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_SENSOR_HEADER_SIZE+sizeof(igtl_float64)*6) { fprintf(stdout, "Invalid size of sensor message structure.\n"); return EXIT_FAILURE; } /* Create unit (m/s^2) */ igtl_unit_init(&unit_data); unit_data.prefix = IGTL_UNIT_PREFIX_NONE; unit_data.unit[0] = IGTL_UNIT_SI_BASE_METER; unit_data.exp[0] = (igtl_int8) 1; unit_data.unit[1] = IGTL_UNIT_SI_BASE_SECOND; unit_data.exp[1] = (igtl_int8) -2; /* Set dummy sensor header and values */ message.sensor.larray = 6; message.sensor.status = 0; message.sensor.unit = igtl_unit_pack(&(unit_data)); message.value[0] = 123456.78; message.value[1] = 12345.678; message.value[2] = 1234.5678; message.value[3] = 123.45678; message.value[4] = 12.345678; message.value[5] = 1.2345678; value_size = igtl_sensor_get_data_size(&(message.sensor)); igtl_sensor_convert_byte_order(&(message.sensor), message.value); /* Set header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "SENSOR", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_SENSOR_HEADER_SIZE + value_size; message.header.crc = igtl_sensor_get_crc(&(message.sensor), message.value); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("sensor.bin", "w"); fwrite(&(message.header), IGTL_HEADER_SIZE+IGTL_SENSOR_HEADER_SIZE + value_size, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_sensor_message, IGTL_HEADER_SIZE+IGTL_SENSOR_HEADER_SIZE+value_size); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_SENSOR_HEADER_SIZE+value_size; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_status_test.c000066400000000000000000000057371501024245700230700ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_types.h" #include "igtl_header.h" #include "igtl_status.h" #include "igtl_util.h" #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 /* Include serialized test data (gold standard) */ #include "igtl_test_data_status.h" #define STR_ERROR_NAME "ACTUATOR_DISABLED" /* within 20 characters */ #define STR_ERROR_MESSAGE "Actuator A is disabled." #pragma pack(1) struct status_message { igtl_header header; igtl_status_header status; char err_msg[sizeof(STR_ERROR_MESSAGE)]; }; #pragma pack() int main( int argc, char * argv [] ) { struct status_message message; /*igtl_uint64 crc;*/ unsigned int msglen; int r; int s; // Test structure size if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_STATUS_HEADER_SIZE+sizeof(STR_ERROR_MESSAGE)) { fprintf(stdout, "Invalid size of image message structure.\n"); return EXIT_FAILURE; } // Test binary msglen = sizeof(STR_ERROR_MESSAGE); /* Set dummy status */ message.status.code = IGTL_STATUS_DISABLED; message.status.subcode = 0x0A; strcpy(message.err_msg, STR_ERROR_MESSAGE); strncpy(message.status.error_name, STR_ERROR_NAME, 20); igtl_status_convert_byte_order(&message.status); /* Set header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "STATUS", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_STATUS_HEADER_SIZE + msglen; message.header.crc = igtl_status_get_crc(&(message.status), msglen, message.err_msg); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("status.bin", "w"); fwrite(&(message.header), IGTL_HEADER_SIZE+IGTL_STATUS_HEADER_SIZE + msglen, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_status_message, IGTL_HEADER_SIZE+IGTL_STATUS_HEADER_SIZE+msglen); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_STATUS_HEADER_SIZE+msglen; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_string_test.c000066400000000000000000000060671501024245700230500ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_types.h" #include "igtl_header.h" #include "igtl_string.h" #include "igtl_util.h" #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 /* Include serialized test data (gold standard) */ #include "igtl_test_data_string.h" #pragma pack(1) #define IGTL_STRING_TEST_STRING "Welcome to OpenIGTLink" #define IGTL_STRING_TEST_STRING_LEN 22 /* Test string message data (6-ch 64-bit float data, m/s^2) */ struct string_message { igtl_header header; igtl_string_header string_header; igtl_uint8 string[IGTL_STRING_TEST_STRING_LEN]; }; #pragma pack() int main( int argc, char * argv [] ) { struct string_message message; /*igtl_uint64 crc;*/ int r; int s; // Test structure size if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_STRING_HEADER_SIZE+IGTL_STRING_TEST_STRING_LEN) { fprintf(stdout, "Invalid size of image message structure.\n"); return EXIT_FAILURE; } /* Set dummy string header and values */ message.string_header.encoding = 3; message.string_header.length = IGTL_STRING_TEST_STRING_LEN; strncpy((char*)message.string, IGTL_STRING_TEST_STRING, IGTL_STRING_TEST_STRING_LEN); igtl_string_convert_byte_order(&(message.string_header)); /* Set header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "STRING", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_STRING_HEADER_SIZE + IGTL_STRING_TEST_STRING_LEN; message.header.crc = igtl_string_get_crc(&(message.string_header), (void*) message.string); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("string.bin", "w"); fwrite(&(message.header), IGTL_HEADER_SIZE+IGTL_STRING_HEADER_SIZE + IGTL_STRING_TEST_STRING_LEN, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_string_message, IGTL_HEADER_SIZE+IGTL_STRING_HEADER_SIZE+IGTL_STRING_TEST_STRING_LEN); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_STRING_HEADER_SIZE+IGTL_STRING_TEST_STRING_LEN; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_tdata_test.c000066400000000000000000000113001501024245700226210ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_types.h" #include "igtl_header.h" #include "igtl_tdata.h" #include "igtl_util.h" /* include test tdata data and serialized tdata message */ #include "igtl_test_data_tdata.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #define TEST_TDATA_NUM 3 #pragma pack(1) struct tdata_message { igtl_header header; igtl_tdata_element tlist[TEST_TDATA_NUM]; }; #pragma pack() int main( int argc, char * argv [] ) { struct tdata_message message; int r; int s; // Test structure size if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_TDATA_ELEMENT_SIZE*TEST_TDATA_NUM) { fprintf(stdout, "Invalid size of tdata message structure.\n"); return EXIT_FAILURE; } /* Tracking data 0 */ strncpy((char*)&(message.tlist[0].name), "Tracker0", 20); message.tlist[0].type = IGTL_TDATA_TYPE_6D; message.tlist[0].reserved = 0; message.tlist[0].transform[0] = -0.954892f; message.tlist[0].transform[1] = 0.196632f; message.tlist[0].transform[2] = -0.222525f; message.tlist[0].transform[3] = -0.196632f; message.tlist[0].transform[4] = 0.142857f; message.tlist[0].transform[5] = 0.970014f; message.tlist[0].transform[6] = 0.222525f; message.tlist[0].transform[7] = 0.970014f; message.tlist[0].transform[8] = -0.0977491f; message.tlist[0].transform[9] = 46.0531f; message.tlist[0].transform[10] = 19.4709f; message.tlist[0].transform[11] = 46.0531f; /* Tracking data 1 */ strncpy((char*)&(message.tlist[1].name), "Tracker1", 20); message.tlist[1].type = IGTL_TDATA_TYPE_6D; message.tlist[1].reserved = 0; message.tlist[1].transform[0] = -0.954892f; message.tlist[1].transform[1] = 0.196632f; message.tlist[1].transform[2] = -0.222525f; message.tlist[1].transform[3] = -0.196632f; message.tlist[1].transform[4] = 0.142857f; message.tlist[1].transform[5] = 0.970014f; message.tlist[1].transform[6] = 0.222525f; message.tlist[1].transform[7] = 0.970014f; message.tlist[1].transform[8] = -0.0977491f; message.tlist[1].transform[9] = 46.0531f; message.tlist[1].transform[10] = 19.4709f; message.tlist[1].transform[11] = 46.0531f; /* Tracking data 2 */ strncpy((char*)&(message.tlist[2].name), "Tracker2", 20); message.tlist[2].type = IGTL_TDATA_TYPE_6D; message.tlist[2].reserved = 0; message.tlist[2].transform[0] = -0.954892f; message.tlist[2].transform[1] = 0.196632f; message.tlist[2].transform[2] = -0.222525f; message.tlist[2].transform[3] = -0.196632f; message.tlist[2].transform[4] = 0.142857f; message.tlist[2].transform[5] = 0.970014f; message.tlist[2].transform[6] = 0.222525f; message.tlist[2].transform[7] = 0.970014f; message.tlist[2].transform[8] = -0.0977491f; message.tlist[2].transform[9] = 46.0531f; message.tlist[2].transform[10] = 19.4709f; message.tlist[2].transform[11] = 46.0531f; /* Swap byte order if necessary */ igtl_tdata_convert_byte_order(message.tlist, TEST_TDATA_NUM); /* Create OpenIGTLink header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "TDATA", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_TDATA_ELEMENT_SIZE*TEST_TDATA_NUM; message.header.crc = igtl_tdata_get_crc(message.tlist, TEST_TDATA_NUM); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for debugging */ /* FILE *fp; fp = fopen("tdata.bin", "w"); fwrite(&(message), IGTL_HEADER_SIZE+IGTL_TDATA_ELEMENT_SIZE*TEST_TDATA_NUM, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_tdata_message, (size_t)(IGTL_HEADER_SIZE+IGTL_TDATA_ELEMENT_SIZE*TEST_TDATA_NUM)); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_TDATA_ELEMENT_SIZE*TEST_TDATA_NUM; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); /*igtl_message_dump_hex(stdout, (const void*)&message, s);*/ return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_bind.h000066400000000000000000000472341501024245700234550ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy status data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_BIND_H #define __IGTL_TEST_DATA_BIND_H unsigned char test_bind_message_header[] = { 0x00, 0x01, /* Version number */ 0x42, 0x49, 0x4e, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* BIND */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd8, /* Body size */ 0xd3, 0x4d, 0x56, 0xba, 0x63, 0xaf, 0x8a, 0x6a, /* CRC */ }; unsigned char test_bind_message_bind_header[] = { /* 98 bytes */ 0x00, 0x03, /* Number of child messages */ 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x4f, 0x52, 0x4d, 0x00, 0x00, 0x00, /* Device type 0 (TRANSFORM) */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, /* Data size 0 */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device type 1 (IMAGE) */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0c, /* Data size 1 */ 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device type 2 (SENSOR)*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, /* Body size 2 */ 0x00, 0x22, /* Length of device name table */ 0x43, 0x68, 0x69, 0x6c, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x00, /* Device name 0 ("ChildTrans") */ 0x43, 0x68, 0x69, 0x6c, 0x64, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x00, /* Device name 1 ("ChildImage") */ 0x43, 0x68, 0x69, 0x6c, 0x64, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x00, /* Device name 2 ("ChildSensor") */ }; unsigned char test_bind_message_bind_body[] = { /* 48+2572+58 = 2678 bytes */ /* TRANSFORM */ 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ /* IMAGE */ /* Image header */ 0x00, 0x01, /* Version number */ 0x01, /* Number of components (scalar) */ 0x03, /* Scalar type (8-bit unsigned int) */ 0x02, /* Little endian */ 0x01, /* Image coordinate */ 0x00, 0x32, 0x00, 0x32, 0x00, 0x01, /* Number of pixels */ 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, 0xBE, 0x63, 0xDD, 0x98, /* tx, ty, tz */ 0xBE, 0x49, 0x59, 0xE6, 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sx, sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, 0xBD, 0xC8, 0x30, 0xAE, /* nx, ny, nz */ 0x42, 0x38, 0x36, 0x60, 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* px, py, pz */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Starting index of subvolume */ 0x00, 0x32, 0x00, 0x32, 0x00, 0x01, /* Number of pixels in subvolume */ /* Image data */ 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x44, 0x14, 0xfd, 0x27, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x77, 0x9a, 0xfd, 0xfd, 0xfd, 0xfd, 0x52, 0xfd, 0x98, 0xfd, 0x2f, 0xfd, 0x2d, 0x46, 0x1f, 0x0d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2b, 0xfd, 0xfd, 0x86, 0xfd, 0xfd, 0xfd, 0xfd, 0x66, 0xfd, 0x00, 0xfd, 0x22, 0x83, 0xfd, 0x34, 0x79, 0x62, 0x00, 0x23, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x08, 0x39, 0xfd, 0x5c, 0x76, 0xfd, 0x20, 0xfd, 0x45, 0xfd, 0xfd, 0x58, 0x4f, 0xb0, 0xfd, 0x73, 0xfd, 0x13, 0xa0, 0x23, 0x44, 0x26, 0xfd, 0x03, 0x9e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2c, 0x0d, 0x16, 0xfd, 0x1b, 0x67, 0x59, 0x51, 0x72, 0x41, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1c, 0x27, 0x9c, 0x3d, 0x4e, 0x95, 0xfd, 0x53, 0xfd, 0x26, 0x20, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0xd5, 0x22, 0x09, 0x01, 0x67, 0xfd, 0x98, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0xfd, 0x6f, 0x74, 0xfd, 0xfd, 0x34, 0x80, 0x61, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x00, 0x2f, 0x44, 0xfd, 0x7b, 0x5e, 0xb9, 0x5e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x28, 0x06, 0x7e, 0x43, 0x09, 0x00, 0x85, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x78, 0xfd, 0xfd, 0x9a, 0x9c, 0xb6, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0f, 0x36, 0xfd, 0x05, 0x01, 0x31, 0xa0, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x25, 0x01, 0x2a, 0xfd, 0x24, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x15, 0x18, 0x6d, 0x2a, 0xa2, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa8, 0xfd, 0xfd, 0x17, 0x14, 0x40, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x36, 0xfd, 0x18, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x01, 0xfd, 0x7c, 0x64, 0x74, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x08, 0x66, 0xfd, 0xfd, 0x5f, 0x3b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc0, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xb9, 0xfd, 0xfd, 0xfd, 0x71, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x95, 0x6c, 0xca, 0x08, 0x39, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x09, 0x39, 0x09, 0x8d, 0x20, 0xfd, 0x06, 0x34, 0x19, 0x19, 0x19, 0x19, 0x33, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0xfd, 0xb0, 0x30, 0x9e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfd, 0xfd, 0x64, 0xfd, 0x1c, 0x70, 0x9f, 0xdb, 0xdd, 0x9f, 0xd8, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0xfd, 0x18, 0x2a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x6f, 0x92, 0x38, 0x46, 0xfd, 0xfd, 0xfd, 0xfd, 0x8b, 0xfc, 0xac, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x8f, 0x55, 0xfd, 0x22, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x14, 0x10, 0xfd, 0x96, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0x21, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x34, 0xfd, 0xfd, 0xab, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x60, 0x61, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0xeb, 0xfc, 0xc5, 0xea, 0x57, 0x0a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x32, 0x15, 0x41, 0xfd, 0x1f, 0xfd, 0xfd, 0xfd, 0xfd, 0x6e, 0x53, 0x4a, 0xa9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x6e, 0x8a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x57, 0xfc, 0xfc, 0xd0, 0xfd, 0xfd, 0xfd, 0x78, 0x57, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3c, 0x49, 0x2f, 0x16, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0x2b, 0x16, 0x05, 0xfd, 0xfd, 0xfd, 0x0d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xe3, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xaa, 0xfd, 0xfd, 0xfd, 0xfd, 0x13, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3e, 0x69, 0xfd, 0x68, 0xfd, 0xfd, 0xfd, 0x43, 0x35, 0x8e, 0x39, 0x05, 0xfd, 0xfd, 0xfd, 0x1c, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xac, 0xfd, 0xfd, 0xba, 0xfc, 0xfc, 0xfc, 0xfc, 0x82, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x69, 0x12, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x92, 0x17, 0x58, 0x2c, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x99, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xaa, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xcd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x39, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x01, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x57, 0xfd, 0x97, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xaf, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x70, 0xfd, 0xda, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x1d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xe2, 0xfd, 0xc0, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xae, 0xfd, 0xa7, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0xa1, 0x70, 0xe8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xea, 0xaa, 0xe3, 0xfc, 0x96, 0xb6, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x62, 0xfd, 0xfd, 0x84, 0xfd, 0xfd, 0xfd, 0xfd, 0x1e, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xd0, 0xfd, 0x51, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xed, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x97, 0xfd, 0x2d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0x2e, 0x42, 0x1f, 0x25, 0xfd, 0xfd, 0xfd, 0x49, 0x20, 0x42, 0x31, 0xfd, 0xfd, 0xfd, 0xfd, 0x1f, 0xa1, 0x47, 0x47, 0x47, 0x47, 0xd2, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xc9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa8, 0xfd, 0xfd, 0x6d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x1b, 0xfd, 0xfd, 0xfd, 0xfd, 0x29, 0x2f, 0x1e, 0x8e, 0xfd, 0xfd, 0xfd, 0x59, 0xfd, 0xfd, 0xfd, 0x01, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xf7, 0xfc, 0xfc, 0xfc, 0xfc, 0x70, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0xd1, 0xfd, 0xfd, 0x4d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x14, 0xfd, 0xfd, 0xfd, 0xfd, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0x04, 0x8a, 0x35, 0x58, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0x57, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfd, 0xfd, 0xfd, 0x85, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x7a, 0xfd, 0xfd, 0xfd, 0xfd, 0x42, 0x52, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5c, 0x0a, 0x58, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0xfc, 0xfc, 0xfc, 0x82, 0xfd, 0xfd, 0xfd, 0x4f, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xa5, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x53, 0xfd, 0xfd, 0xfd, 0x0c, 0x46, 0x93, 0xfd, 0x84, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0x07, 0x81, 0xb3, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x49, 0xd6, 0xd6, 0x21, 0xc8, 0xfc, 0x81, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2b, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x23, 0xfd, 0xfd, 0xfd, 0x05, 0xfd, 0x0f, 0x65, 0x0f, 0xfd, 0xfd, 0xfd, 0xfd, 0x5d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x51, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x23, 0xfd, 0xfd, 0x07, 0x0b, 0xfd, 0xfd, 0x05, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xb3, 0xc4, 0x8b, 0xc4, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x63, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x36, 0xfd, 0xfd, 0xfd, 0x35, 0xfd, 0x2a, 0x7a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0x2e, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x33, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x29, 0xfd, 0xfd, 0xfd, 0xfd, 0xb5, 0x00, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xba, 0xfd, 0x4b, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x24, 0x1a, 0xfd, 0xfd, 0x37, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xab, 0xfd, 0xfd, 0x37, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0x41, 0x95, 0x33, 0x14, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3f, 0x38, 0xfd, 0x26, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1b, 0xfd, 0x6e, 0x04, 0x01, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1f, 0xbf, 0x3c, 0x0f, 0x87, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x19, 0x62, 0xfd, 0xfd, 0x52, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0f, 0x12, 0x76, 0xc2, 0x23, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x4d, 0x33, 0x72, 0x58, 0xdf, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x03, 0xfd, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x09, 0x5e, 0x45, 0xfd, 0x3d, 0x4e, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc1, 0x04, 0x05, 0x0a, 0xfd, 0x8b, 0x80, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x65, 0x62, 0xfd, 0x56, 0x31, 0x00, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x6b, 0xfd, 0x05, 0x31, 0x06, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa3, 0xd4, 0xfd, 0x1e, 0x45, 0xfd, 0x16, 0x07, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc7, 0x80, 0x00, 0xfd, 0x3d, 0x6f, 0x38, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5c, 0xfd, 0x4d, 0xfd, 0xfd, 0xf9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x35, 0x55, 0x23, 0x9b, 0xfd, 0x46, 0xfd, 0x11, 0xa7, 0x09, 0x85, 0x5c, 0xfd, 0x5d, 0x9d, 0x21, 0xa5, 0xa5, 0x4b, 0xfd, 0xfd, 0xfd, 0xfd, 0x9b, 0x2a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x52, 0xfd, 0x67, 0xfd, 0x08, 0x1e, 0xfd, 0x20, 0xfd, 0x7f, 0x0e, 0xfd, 0x5b, 0xfd, 0x8a, 0xfd, 0x02, 0xfd, 0xfd, 0xfd, 0x6d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x30, 0x94, 0xfd, 0xfd, 0x9b, 0xfd, 0xfd, 0x7a, 0xfd, 0x9a, 0xfd, 0x69, 0x5c, 0xfd, 0x21, 0xfd, 0x67, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x1b, 0x46, 0xfd, 0xab, 0x25, 0x5c, 0xfd, 0x62, 0x4c, 0x4f, 0x14, 0x4b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x18, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, /* SENSOR */ 0x06, /* larray */ 0x00, /* status */ 0x00, 0x44, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, /* unit */ 0x40, 0xfe, 0x24, 0x0c, 0x7a, 0xe1, 0x47, 0xae, /* value: sensor #0 */ 0x40, 0xc8, 0x1c, 0xd6, 0xc8, 0xb4, 0x39, 0x58, /* value: sensor #1 */ 0x40, 0x93, 0x4a, 0x45, 0x6d, 0x5c, 0xfa, 0xad, /* value: sensor #2 */ 0x40, 0x5e, 0xdd, 0x3b, 0xe2, 0x2e, 0x5d, 0xe1, /* value: sensor #3 */ 0x40, 0x28, 0xb0, 0xfc, 0xb4, 0xf1, 0xe4, 0xb4, /* value: sensor #4 */ 0x3f, 0xf3, 0xc0, 0xca, 0x2a, 0x5b, 0x1d, 0x5d, /* value: sensor #4 */ }; #endif /* IGTL_TEST_DATA_BIND_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_capability.h000066400000000000000000000033231501024245700246510ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy status data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_CAPABILITY_H #define __IGTL_TEST_DATA_CAPABILITY_H unsigned char test_capability_message[] = { 0x00, 0x01, /* Version number */ 0x43, 0x41, 0x50, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x00, 0x00, /* CAPABILITY */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, /* Body size */ 0x69, 0x57, 0xe2, 0x9e, 0x2b, 0x35, 0xea, 0x1e, /* CRC */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* IMAGE */ 0x47, 0x45, 0x54, 0x5f, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x00, 0x00, 0x00, /* GET_IMAGE */ 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x4f, 0x52, 0x4d, 0x00, 0x00, 0x00, /* TRANSFORM */ 0x47, 0x45, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x00, 0x00, 0x00, /* GET_TRANS */ }; #endif /* IGTL_TEST_DATA_SENSOR_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_colortable.h000066400000000000000000000061071501024245700246610ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy colortable data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_COLORTABLE_H #define __IGTL_TEST_DATA_COLORTABLE_H unsigned char test_colortable_message[] = { /*------- OpenIGTLink message header -------*/ 0x00, 0x01, /* Version number */ 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x00, 0x00, /* COLORTABLE */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* Body size */ 0x39, 0xfc, 0xde, 0xcb, 0xe9, 0x6b, 0x68, 0x35, /* CRC */ /*--------- COLORTABLE message body ---------*/ 0x03, /* Index type */ 0x03, /* Map type */ /* color table */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, }; #endif /* IGTL_TEST_DATA_COLORTABLE_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_colortable2.h000066400000000000000000000061021501024245700247360ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy colortable data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_COLORTABLE_H #define __IGTL_TEST_DATA_COLORTABLE_H unsigned char test_colortable_message[] = { /*------- OpenIGTLink message header -------*/ 0x00, 0x01, /* Version number */ 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* COLORT */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* Body size */ 0x39, 0xfc, 0xde, 0xcb, 0xe9, 0x6b, 0x68, 0x35, /* CRC */ /*--------- COLORTABLE message body ---------*/ 0x03, /* Index type */ 0x03, /* Map type */ /* color table */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, }; #endif /* IGTL_TEST_DATA_COLORTABLE_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_command.h000066400000000000000000000051251501024245700241500ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy status data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_COMMAND_H #define __IGTL_TEST_DATA_COMMAND_H unsigned char test_command_message[] = { /*-------- OpenIGTLink message header -------*/ 0x00, 0x01, /* Version number */ 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, /* COMMAND */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, /* Body size */ 0x2B, 0xC7, 0xCD, 0x95, 0xB7, 0xC5, 0x95, 0x45, /* CRC */ /////// End of header ////// Start of command message header 0x00, 0x00, 0x00, 0x05, /*Command ID*/ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Command name*/ 0x00, 0x03, /* Encoding */ 0x00, 0x00, 0x00, 0x1A, /* Command length*/ ////// End of command message header 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x63, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x61, 0x63, 0x68, 0x69, 0x6E, 0x65 /* Command */ }; #endif /* __IGTL_TEST_DATA_COMMAND_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_commandFormat2.h000066400000000000000000000072611501024245700254060ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy position data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_COMMAND_FORMAT2_H #define __IGTL_TEST_DATA_COMMAND_FORMAT2_H unsigned char test_command_messageFormat2[] = { /*-------- OpenIGTLink message header -------*/ 0x00, 0x02, /* Version number */ 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, /* COMMAND */ 0x4F, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6C, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, /* Body size */ 0x85, 0xD2, 0x5E, 0xE9, 0x41, 0x90, 0x17, 0x70, /* CRC */ /* Extended header 0 2 4 8 12 +-----------------+----------------------+---------------+-------------+ | EXT_HEADER_SIZE | METADATA_HEADER_SIZE | METADATA_SIZE | MESSAGE_ID | +-----------------+----------------------+---------------+-------------+*/ 0x00, 0x0c, 0x00, 0x12, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, ////// Start of command message header 0x00, 0x00, 0x00, 0x05, /*Command ID*/ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Command name*/ 0x00, 0x03, /* Encoding */ 0x00, 0x00, 0x00, 0x1A, /* Command length*/ ////// End of command message header 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x63, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x61, 0x63, 0x68, 0x69, 0x6E, 0x65, /* Command */ /*---------- Command Message Meta data body ------------*/ 0x00, 0x02, /* Index Count */ 0x00, 0x11, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* first element Key size(2 Bytes), value coding(2 Bytes), value size(4 Bytes)*/ 0x00, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* second element Key size, value coding, value size*/ 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x70, 0x61, /* First Patient Age 22*/ 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x32, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, /* Second Patient Age 25*/ 0x70, 0x61, 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x35 }; #endif /* __IGTL_TEST_DATA_COMMAND_FORMAT2_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_image.h000066400000000000000000001005411501024245700236120ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- NCIGT Logo Data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __TSET_DATA_IMAGE_H #define __TSET_DATA_IMAGE_H #define TEST_IMAGE_MESSAGE_SIZE 2500 unsigned const char test_image[] = { 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x44, 0x14, 0xfd, 0x27, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x77, 0x9a, 0xfd, 0xfd, 0xfd, 0xfd, 0x52, 0xfd, 0x98, 0xfd, 0x2f, 0xfd, 0x2d, 0x46, 0x1f, 0x0d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2b, 0xfd, 0xfd, 0x86, 0xfd, 0xfd, 0xfd, 0xfd, 0x66, 0xfd, 0x00, 0xfd, 0x22, 0x83, 0xfd, 0x34, 0x79, 0x62, 0x00, 0x23, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x08, 0x39, 0xfd, 0x5c, 0x76, 0xfd, 0x20, 0xfd, 0x45, 0xfd, 0xfd, 0x58, 0x4f, 0xb0, 0xfd, 0x73, 0xfd, 0x13, 0xa0, 0x23, 0x44, 0x26, 0xfd, 0x03, 0x9e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2c, 0x0d, 0x16, 0xfd, 0x1b, 0x67, 0x59, 0x51, 0x72, 0x41, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1c, 0x27, 0x9c, 0x3d, 0x4e, 0x95, 0xfd, 0x53, 0xfd, 0x26, 0x20, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0xd5, 0x22, 0x09, 0x01, 0x67, 0xfd, 0x98, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0xfd, 0x6f, 0x74, 0xfd, 0xfd, 0x34, 0x80, 0x61, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x00, 0x2f, 0x44, 0xfd, 0x7b, 0x5e, 0xb9, 0x5e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x28, 0x06, 0x7e, 0x43, 0x09, 0x00, 0x85, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x78, 0xfd, 0xfd, 0x9a, 0x9c, 0xb6, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0f, 0x36, 0xfd, 0x05, 0x01, 0x31, 0xa0, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x25, 0x01, 0x2a, 0xfd, 0x24, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x15, 0x18, 0x6d, 0x2a, 0xa2, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa8, 0xfd, 0xfd, 0x17, 0x14, 0x40, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x36, 0xfd, 0x18, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x01, 0xfd, 0x7c, 0x64, 0x74, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x08, 0x66, 0xfd, 0xfd, 0x5f, 0x3b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc0, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xb9, 0xfd, 0xfd, 0xfd, 0x71, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x95, 0x6c, 0xca, 0x08, 0x39, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x09, 0x39, 0x09, 0x8d, 0x20, 0xfd, 0x06, 0x34, 0x19, 0x19, 0x19, 0x19, 0x33, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0xfd, 0xb0, 0x30, 0x9e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfd, 0xfd, 0x64, 0xfd, 0x1c, 0x70, 0x9f, 0xdb, 0xdd, 0x9f, 0xd8, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0xfd, 0x18, 0x2a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x6f, 0x92, 0x38, 0x46, 0xfd, 0xfd, 0xfd, 0xfd, 0x8b, 0xfc, 0xac, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x8f, 0x55, 0xfd, 0x22, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x14, 0x10, 0xfd, 0x96, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0x21, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x34, 0xfd, 0xfd, 0xab, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x60, 0x61, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0xeb, 0xfc, 0xc5, 0xea, 0x57, 0x0a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x32, 0x15, 0x41, 0xfd, 0x1f, 0xfd, 0xfd, 0xfd, 0xfd, 0x6e, 0x53, 0x4a, 0xa9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x6e, 0x8a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x57, 0xfc, 0xfc, 0xd0, 0xfd, 0xfd, 0xfd, 0x78, 0x57, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3c, 0x49, 0x2f, 0x16, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0x2b, 0x16, 0x05, 0xfd, 0xfd, 0xfd, 0x0d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xe3, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xaa, 0xfd, 0xfd, 0xfd, 0xfd, 0x13, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3e, 0x69, 0xfd, 0x68, 0xfd, 0xfd, 0xfd, 0x43, 0x35, 0x8e, 0x39, 0x05, 0xfd, 0xfd, 0xfd, 0x1c, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xac, 0xfd, 0xfd, 0xba, 0xfc, 0xfc, 0xfc, 0xfc, 0x82, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x69, 0x12, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x92, 0x17, 0x58, 0x2c, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x99, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xaa, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xcd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x39, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x01, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x57, 0xfd, 0x97, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xaf, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x70, 0xfd, 0xda, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x1d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xe2, 0xfd, 0xc0, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xae, 0xfd, 0xa7, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0xa1, 0x70, 0xe8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xea, 0xaa, 0xe3, 0xfc, 0x96, 0xb6, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x62, 0xfd, 0xfd, 0x84, 0xfd, 0xfd, 0xfd, 0xfd, 0x1e, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xd0, 0xfd, 0x51, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xed, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x97, 0xfd, 0x2d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0x2e, 0x42, 0x1f, 0x25, 0xfd, 0xfd, 0xfd, 0x49, 0x20, 0x42, 0x31, 0xfd, 0xfd, 0xfd, 0xfd, 0x1f, 0xa1, 0x47, 0x47, 0x47, 0x47, 0xd2, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xc9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa8, 0xfd, 0xfd, 0x6d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x1b, 0xfd, 0xfd, 0xfd, 0xfd, 0x29, 0x2f, 0x1e, 0x8e, 0xfd, 0xfd, 0xfd, 0x59, 0xfd, 0xfd, 0xfd, 0x01, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xf7, 0xfc, 0xfc, 0xfc, 0xfc, 0x70, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0xd1, 0xfd, 0xfd, 0x4d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x14, 0xfd, 0xfd, 0xfd, 0xfd, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0x04, 0x8a, 0x35, 0x58, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0x57, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfd, 0xfd, 0xfd, 0x85, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x7a, 0xfd, 0xfd, 0xfd, 0xfd, 0x42, 0x52, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5c, 0x0a, 0x58, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0xfc, 0xfc, 0xfc, 0x82, 0xfd, 0xfd, 0xfd, 0x4f, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xa5, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x53, 0xfd, 0xfd, 0xfd, 0x0c, 0x46, 0x93, 0xfd, 0x84, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0x07, 0x81, 0xb3, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x49, 0xd6, 0xd6, 0x21, 0xc8, 0xfc, 0x81, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2b, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x23, 0xfd, 0xfd, 0xfd, 0x05, 0xfd, 0x0f, 0x65, 0x0f, 0xfd, 0xfd, 0xfd, 0xfd, 0x5d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x51, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x23, 0xfd, 0xfd, 0x07, 0x0b, 0xfd, 0xfd, 0x05, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xb3, 0xc4, 0x8b, 0xc4, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x63, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x36, 0xfd, 0xfd, 0xfd, 0x35, 0xfd, 0x2a, 0x7a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0x2e, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x33, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x29, 0xfd, 0xfd, 0xfd, 0xfd, 0xb5, 0x00, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xba, 0xfd, 0x4b, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x24, 0x1a, 0xfd, 0xfd, 0x37, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xab, 0xfd, 0xfd, 0x37, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0x41, 0x95, 0x33, 0x14, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3f, 0x38, 0xfd, 0x26, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1b, 0xfd, 0x6e, 0x04, 0x01, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1f, 0xbf, 0x3c, 0x0f, 0x87, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x19, 0x62, 0xfd, 0xfd, 0x52, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0f, 0x12, 0x76, 0xc2, 0x23, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x4d, 0x33, 0x72, 0x58, 0xdf, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x03, 0xfd, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x09, 0x5e, 0x45, 0xfd, 0x3d, 0x4e, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc1, 0x04, 0x05, 0x0a, 0xfd, 0x8b, 0x80, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x65, 0x62, 0xfd, 0x56, 0x31, 0x00, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x6b, 0xfd, 0x05, 0x31, 0x06, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa3, 0xd4, 0xfd, 0x1e, 0x45, 0xfd, 0x16, 0x07, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc7, 0x80, 0x00, 0xfd, 0x3d, 0x6f, 0x38, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5c, 0xfd, 0x4d, 0xfd, 0xfd, 0xf9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x35, 0x55, 0x23, 0x9b, 0xfd, 0x46, 0xfd, 0x11, 0xa7, 0x09, 0x85, 0x5c, 0xfd, 0x5d, 0x9d, 0x21, 0xa5, 0xa5, 0x4b, 0xfd, 0xfd, 0xfd, 0xfd, 0x9b, 0x2a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x52, 0xfd, 0x67, 0xfd, 0x08, 0x1e, 0xfd, 0x20, 0xfd, 0x7f, 0x0e, 0xfd, 0x5b, 0xfd, 0x8a, 0xfd, 0x02, 0xfd, 0xfd, 0xfd, 0x6d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x30, 0x94, 0xfd, 0xfd, 0x9b, 0xfd, 0xfd, 0x7a, 0xfd, 0x9a, 0xfd, 0x69, 0x5c, 0xfd, 0x21, 0xfd, 0x67, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x1b, 0x46, 0xfd, 0xab, 0x25, 0x5c, 0xfd, 0x62, 0x4c, 0x4f, 0x14, 0x4b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x18, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, }; unsigned const char test_image_message[] = { /* OpenIGTLink header */ 0x00, 0x01, /* Version number */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* IMAGE */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0c, /* Body size */ 0x55, 0x4f, 0xc4, 0x87, 0x69, 0xfd, 0x7c, 0xff, /* CRC */ /* Image header */ 0x00, 0x01, /* Version number */ 0x01, /* Image type (scalar) */ 0x03, /* Scalar type (8-bit unsigned int) */ 0x02, /* Little endian */ 0x01, /* Image coordinate */ 0x00, 0x32, 0x00, 0x32, 0x00, 0x01, /* Number of pixels */ 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, 0xBE, 0x63, 0xDD, 0x98, /* tx, ty, tz */ 0xBE, 0x49, 0x59, 0xE6, 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sx, sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, 0xBD, 0xC8, 0x30, 0xAE, /* nx, ny, nz */ 0x42, 0x38, 0x36, 0x60, 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* px, py, pz */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Starting index of subvolume */ 0x00, 0x32, 0x00, 0x32, 0x00, 0x01, /* Number of pixels in subvolume */ /* Image data */ 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x44, 0x14, 0xfd, 0x27, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x77, 0x9a, 0xfd, 0xfd, 0xfd, 0xfd, 0x52, 0xfd, 0x98, 0xfd, 0x2f, 0xfd, 0x2d, 0x46, 0x1f, 0x0d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2b, 0xfd, 0xfd, 0x86, 0xfd, 0xfd, 0xfd, 0xfd, 0x66, 0xfd, 0x00, 0xfd, 0x22, 0x83, 0xfd, 0x34, 0x79, 0x62, 0x00, 0x23, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x08, 0x39, 0xfd, 0x5c, 0x76, 0xfd, 0x20, 0xfd, 0x45, 0xfd, 0xfd, 0x58, 0x4f, 0xb0, 0xfd, 0x73, 0xfd, 0x13, 0xa0, 0x23, 0x44, 0x26, 0xfd, 0x03, 0x9e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2c, 0x0d, 0x16, 0xfd, 0x1b, 0x67, 0x59, 0x51, 0x72, 0x41, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1c, 0x27, 0x9c, 0x3d, 0x4e, 0x95, 0xfd, 0x53, 0xfd, 0x26, 0x20, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0xd5, 0x22, 0x09, 0x01, 0x67, 0xfd, 0x98, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0xfd, 0x6f, 0x74, 0xfd, 0xfd, 0x34, 0x80, 0x61, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x00, 0x2f, 0x44, 0xfd, 0x7b, 0x5e, 0xb9, 0x5e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x28, 0x06, 0x7e, 0x43, 0x09, 0x00, 0x85, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x78, 0xfd, 0xfd, 0x9a, 0x9c, 0xb6, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0f, 0x36, 0xfd, 0x05, 0x01, 0x31, 0xa0, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x25, 0x01, 0x2a, 0xfd, 0x24, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x15, 0x18, 0x6d, 0x2a, 0xa2, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa8, 0xfd, 0xfd, 0x17, 0x14, 0x40, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x36, 0xfd, 0x18, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x01, 0xfd, 0x7c, 0x64, 0x74, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x08, 0x66, 0xfd, 0xfd, 0x5f, 0x3b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc0, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xb9, 0xfd, 0xfd, 0xfd, 0x71, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x95, 0x6c, 0xca, 0x08, 0x39, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x09, 0x39, 0x09, 0x8d, 0x20, 0xfd, 0x06, 0x34, 0x19, 0x19, 0x19, 0x19, 0x33, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0xfd, 0xb0, 0x30, 0x9e, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfd, 0xfd, 0x64, 0xfd, 0x1c, 0x70, 0x9f, 0xdb, 0xdd, 0x9f, 0xd8, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0xfd, 0x18, 0x2a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x6f, 0x92, 0x38, 0x46, 0xfd, 0xfd, 0xfd, 0xfd, 0x8b, 0xfc, 0xac, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x8f, 0x55, 0xfd, 0x22, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x14, 0x10, 0xfd, 0x96, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0x21, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x34, 0xfd, 0xfd, 0xab, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x60, 0x61, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0xeb, 0xfc, 0xc5, 0xea, 0x57, 0x0a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x32, 0x15, 0x41, 0xfd, 0x1f, 0xfd, 0xfd, 0xfd, 0xfd, 0x6e, 0x53, 0x4a, 0xa9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x6e, 0x8a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x57, 0xfc, 0xfc, 0xd0, 0xfd, 0xfd, 0xfd, 0x78, 0x57, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3c, 0x49, 0x2f, 0x16, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0x2b, 0x16, 0x05, 0xfd, 0xfd, 0xfd, 0x0d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xe3, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xaa, 0xfd, 0xfd, 0xfd, 0xfd, 0x13, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3e, 0x69, 0xfd, 0x68, 0xfd, 0xfd, 0xfd, 0x43, 0x35, 0x8e, 0x39, 0x05, 0xfd, 0xfd, 0xfd, 0x1c, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xac, 0xfd, 0xfd, 0xba, 0xfc, 0xfc, 0xfc, 0xfc, 0x82, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x69, 0x12, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x92, 0x17, 0x58, 0x2c, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x99, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xaa, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xcd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x39, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x01, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x57, 0xfd, 0x97, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xaf, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x70, 0xfd, 0xda, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x1d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x06, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xe2, 0xfd, 0xc0, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xae, 0xfd, 0xa7, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0xa1, 0x70, 0xe8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xea, 0xaa, 0xe3, 0xfc, 0x96, 0xb6, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x62, 0xfd, 0xfd, 0x84, 0xfd, 0xfd, 0xfd, 0xfd, 0x1e, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xd0, 0xfd, 0x51, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xed, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x97, 0xfd, 0x2d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0x2e, 0x42, 0x1f, 0x25, 0xfd, 0xfd, 0xfd, 0x49, 0x20, 0x42, 0x31, 0xfd, 0xfd, 0xfd, 0xfd, 0x1f, 0xa1, 0x47, 0x47, 0x47, 0x47, 0xd2, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xc9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa8, 0xfd, 0xfd, 0x6d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x1b, 0xfd, 0xfd, 0xfd, 0xfd, 0x29, 0x2f, 0x1e, 0x8e, 0xfd, 0xfd, 0xfd, 0x59, 0xfd, 0xfd, 0xfd, 0x01, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xf7, 0xfc, 0xfc, 0xfc, 0xfc, 0x70, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0xd1, 0xfd, 0xfd, 0x4d, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x14, 0xfd, 0xfd, 0xfd, 0xfd, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0x04, 0x8a, 0x35, 0x58, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0x57, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfd, 0xfd, 0xfd, 0x85, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x7a, 0xfd, 0xfd, 0xfd, 0xfd, 0x42, 0x52, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5c, 0x0a, 0x58, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x04, 0xfc, 0xfc, 0xfc, 0x82, 0xfd, 0xfd, 0xfd, 0x4f, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xa5, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x53, 0xfd, 0xfd, 0xfd, 0x0c, 0x46, 0x93, 0xfd, 0x84, 0xfd, 0xfd, 0xfd, 0xfd, 0x0a, 0x07, 0x81, 0xb3, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x49, 0xd6, 0xd6, 0x21, 0xc8, 0xfc, 0x81, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x2b, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x23, 0xfd, 0xfd, 0xfd, 0x05, 0xfd, 0x0f, 0x65, 0x0f, 0xfd, 0xfd, 0xfd, 0xfd, 0x5d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x51, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x23, 0xfd, 0xfd, 0x07, 0x0b, 0xfd, 0xfd, 0x05, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xb3, 0xc4, 0x8b, 0xc4, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x63, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x36, 0xfd, 0xfd, 0xfd, 0x35, 0xfd, 0x2a, 0x7a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x05, 0x2e, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x33, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x29, 0xfd, 0xfd, 0xfd, 0xfd, 0xb5, 0x00, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xba, 0xfd, 0x4b, 0x6b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x24, 0x1a, 0xfd, 0xfd, 0x37, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xab, 0xfd, 0xfd, 0x37, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0c, 0x41, 0x95, 0x33, 0x14, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3f, 0x38, 0xfd, 0x26, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1b, 0xfd, 0x6e, 0x04, 0x01, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x1f, 0xbf, 0x3c, 0x0f, 0x87, 0x4d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x19, 0x62, 0xfd, 0xfd, 0x52, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0f, 0x12, 0x76, 0xc2, 0x23, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x4d, 0x33, 0x72, 0x58, 0xdf, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x03, 0xfd, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x09, 0x5e, 0x45, 0xfd, 0x3d, 0x4e, 0x08, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc1, 0x04, 0x05, 0x0a, 0xfd, 0x8b, 0x80, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x65, 0x62, 0xfd, 0x56, 0x31, 0x00, 0x13, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x6b, 0xfd, 0x05, 0x31, 0x06, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xa3, 0xd4, 0xfd, 0x1e, 0x45, 0xfd, 0x16, 0x07, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xc7, 0x80, 0x00, 0xfd, 0x3d, 0x6f, 0x38, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x5c, 0xfd, 0x4d, 0xfd, 0xfd, 0xf9, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x35, 0x55, 0x23, 0x9b, 0xfd, 0x46, 0xfd, 0x11, 0xa7, 0x09, 0x85, 0x5c, 0xfd, 0x5d, 0x9d, 0x21, 0xa5, 0xa5, 0x4b, 0xfd, 0xfd, 0xfd, 0xfd, 0x9b, 0x2a, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x52, 0xfd, 0x67, 0xfd, 0x08, 0x1e, 0xfd, 0x20, 0xfd, 0x7f, 0x0e, 0xfd, 0x5b, 0xfd, 0x8a, 0xfd, 0x02, 0xfd, 0xfd, 0xfd, 0x6d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x30, 0x94, 0xfd, 0xfd, 0x9b, 0xfd, 0xfd, 0x7a, 0xfd, 0x9a, 0xfd, 0x69, 0x5c, 0xfd, 0x21, 0xfd, 0x67, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x64, 0x1b, 0x46, 0xfd, 0xab, 0x25, 0x5c, 0xfd, 0x62, 0x4c, 0x4f, 0x14, 0x4b, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x18, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, }; #endif /* __TSET_DATA_IMAGE_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_imgmeta.h000066400000000000000000000161271501024245700241610ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy imgmeta data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_IMGMETA_H #define __IGTL_TEST_DATA_IMGMETA_H unsigned char test_imgmeta_message[] = { /*------- OpenIGTLink message header -------*/ 0x00, 0x01, /* Version number */ 0x49, 0x4d, 0x47, 0x4d, 0x45, 0x54, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, /* IMGMETA */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, /* Body size */ 0x38, 0x07, 0xd4, 0x2d, 0x9b, 0xde, 0xe0, 0xc9, /* CRC */ /*---------- IMGMETA message body -----------*/ /* Image meta data 0 */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image name (device name) */ 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Modality */ 0x50, 0x41, 0x54, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Patient name */ 0x50, 0x41, 0x54, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x44, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Patient ID */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x02, 0x00, 0x02, 0x00, 0x00, 0x40, /* Image size */ 0x05, /* Scalar type */ 0x00, /* Reserved byte */ /* Image meta data 1 */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image name (device name) */ 0x4d, 0x52, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Modality */ 0x50, 0x41, 0x54, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Patient name */ 0x50, 0x41, 0x54, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x44, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Patient ID */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd8, /* Time stamp */ 0x01, 0x00, 0x00, 0x80, 0x00, 0x20, /* Image size */ 0x05, /* Scalar type */ 0x00, /* Reserved byte */ /* Image meta data 2 */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image name (device name) */ 0x50, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Modality */ 0x50, 0x41, 0x54, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Patient name */ 0x50, 0x41, 0x54, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x44, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Patient ID */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xdc, /* Time stamp */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x20, /* Image size */ 0x05, /* Scalar type */ 0x00, /* Reserved byte */ }; #endif /* IGTL_TEST_DATA_IMGMETA_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_lbmeta.h000066400000000000000000000106551501024245700240020ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy lbmeta data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_LBMETA_H #define __IGTL_TEST_DATA_LBMETA_H unsigned char test_lbmeta_message[] = { /*------- OpenIGTLink message header --------*/ 0x00, 0x01, /* Version number */ 0x4c, 0x42, 0x4d, 0x45, 0x54, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* LBMETA */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5c, /* Body size */ 0x1a, 0x5b, 0x87, 0xbb, 0x24, 0x8d, 0x80, 0x07, /* CRC */ /*---------- LBMETA message body ------------*/ /* Image meta data 0 */ 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image name (device name) */ 0x01, /* Label */ 0x00, /* Reserved */ 0xff, 0x00, 0x00, 0xff, /* RGBA */ 0x01, 0x00, 0x00, 0x80, 0x00, 0x20, /* Size */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /* Image meta data 1 */ 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image name (device name) */ 0x02, /* Label */ 0x00, /* Reserved */ 0x00, 0xff, 0x00, 0xff, /* RGBA */ 0x01, 0x00, 0x00, 0x80, 0x00, 0x20, /* Size */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /* Image meta data 2 */ 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image name (device name) */ 0x03, /* Label */ 0x00, /* Reserved */ 0x00, 0x00, 0xff, 0xff, /* RGBA */ 0x01, 0x00, 0x00, 0x80, 0x00, 0x20, /* Size */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ }; #endif /* IGTL_TEST_DATA_LBMETA_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_ndarray.h000066400000000000000000000107771501024245700242030ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy status data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_NDARRAY_H #define __IGTL_TEST_DATA_NDARRAY_H unsigned char test_ndarray_message_header[] = { 0x00, 0x01, /* Version number */ 0x4e, 0x44, 0x41, 0x52, 0x52, 0x41, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, /* NDARRAY */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe8, /* Body size */ 0x1b, 0xe0, 0xce, 0x29, 0x55, 0x4f, 0x9a, 0x92, /* CRC */ }; unsigned char test_ndarray_message_body[] = { 0x0b, /* 11: 64-bit float */ 0x03, /* 3-dimensional array */ 0x00, 0x05, 0x00, 0x04, 0x00, 0x03, /* size[] = {5, 4, 3} */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0.0 */ 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1.0 */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2.0 */ 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3.0 */ 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ... */ 0x40, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x47, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x48, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, }; #endif /* IGTL_TEST_DATA_NDARRAY_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_point.h000066400000000000000000000110501501024245700236550ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy point data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_POINT_H #define __IGTL_TEST_DATA_POINT_H unsigned char test_point_message[] = { /*------- OpenIGTLink message header --------*/ 0x00, 0x01, /* Version number */ 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* POINT */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, /* Body size */ 0xa5, 0x5c, 0xc6, 0x2d, 0x99, 0xc1, 0x82, 0x10, /* CRC */ /*---------- POINT message body ------------*/ /* Image meta data 0 */ 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x4c, 0x61, 0x6e, 0x64, 0x6d, 0x61, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Landmark etc.) */ 0xff, 0x00, 0x00, 0xff, /* RGBA */ 0x41, 0x20, 0x00, 0x00, 0x41, 0x70, 0x00, 0x00, 0x41, 0xa0, 0x00, 0x00, /* Position */ 0x40, 0xa0, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /* Image meta data 1 */ 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x4c, 0x61, 0x6e, 0x64, 0x6d, 0x61, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Landmark etc.) */ 0x00, 0xff, 0x00, 0xff, /* RGBA */ 0x41, 0xc8, 0x00, 0x00, 0x41, 0xf0, 0x00, 0x00, 0x42, 0x0c, 0x00, 0x00, /* Position */ 0x40, 0x40, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /* Image meta data 2 */ 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Image description */ 0x4c, 0x61, 0x6e, 0x64, 0x6d, 0x61, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Landmark etc.) */ 0x00, 0x00, 0xff, 0xff, /* RGBA */ 0x42, 0x20, 0x00, 0x00, 0x42, 0x34, 0x00, 0x00, 0x42, 0x48, 0x00, 0x00, /* Position */ 0x3f, 0x80, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ }; #endif /* IGTL_TEST_DATA_POINT_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_polydata.h000066400000000000000000000165601501024245700243540ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy point data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_POLYDATA_H #define __IGTL_TEST_DATA_POLYDATA_H unsigned char test_polydata_message_header[] = { /*------- OpenIGTLink message header --------*/ 0x00, 0x01, /* Version number */ 0x50, 0x4f, 0x4c, 0x59, 0x44, 0x41, 0x54, 0x41, 0x00, 0x00, 0x00, 0x00, /* POLYDATA */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2c, /* Body size */ 0x73, 0xdd, 0xdf, 0xc8, 0x0c, 0x48, 0xc6, 0x2b, /* CRC */ }; unsigned char test_polydata_message_body[] = { /*---------- POLYDATA message header ------------*/ 0x00, 0x00, 0x00, 0x08, /* Number of points */ 0x00, 0x00, 0x00, 0x00, /* Number of vertices */ 0x00, 0x00, 0x00, 0x00, /* size of vertice data */ 0x00, 0x00, 0x00, 0x00, /* Number of lines */ 0x00, 0x00, 0x00, 0x00, /* size of line data */ 0x00, 0x00, 0x00, 0x06, /* Number of polygons */ 0x00, 0x00, 0x00, 0x78, /* size of polygon data */ 0x00, 0x00, 0x00, 0x00, /* Number of triangle strips */ 0x00, 0x00, 0x00, 0x00, /* size of triangle strip data */ 0x00, 0x00, 0x00, 0x01, /* number of attributes */ /*---------- POLYDATA message body (geometry section) ------------*/ 0x00, 0x00, 0x00, 0x00, /* Point #0 - x*/ 0x00, 0x00, 0x00, 0x00, /* Point #0 - y*/ 0x00, 0x00, 0x00, 0x00, /* Point #0 - z*/ 0x3f, 0x80, 0x00, 0x00, /* Point #1 - x*/ 0x00, 0x00, 0x00, 0x00, /* Point #1 - y*/ 0x00, 0x00, 0x00, 0x00, /* Point #1 - z*/ 0x3f, 0x80, 0x00, 0x00, /* Point #2 - x*/ 0x3f, 0x80, 0x00, 0x00, /* Point #2 - y*/ 0x00, 0x00, 0x00, 0x00, /* Point #2 - z*/ 0x00, 0x00, 0x00, 0x00, /* Point #3 - x*/ 0x3f, 0x80, 0x00, 0x00, /* Point #3 - y*/ 0x00, 0x00, 0x00, 0x00, /* Point #3 - z*/ 0x00, 0x00, 0x00, 0x00, /* Point #4 - x*/ 0x00, 0x00, 0x00, 0x00, /* Point #4 - y*/ 0x3f, 0x80, 0x00, 0x00, /* Point #4 - z*/ 0x3f, 0x80, 0x00, 0x00, /* Point #5 - x*/ 0x00, 0x00, 0x00, 0x00, /* Point #5 - y*/ 0x3f, 0x80, 0x00, 0x00, /* Point #5 - z*/ 0x3f, 0x80, 0x00, 0x00, /* Point #6 - x*/ 0x3f, 0x80, 0x00, 0x00, /* Point #6 - y*/ 0x3f, 0x80, 0x00, 0x00, /* Point #6 - z*/ 0x00, 0x00, 0x00, 0x00, /* Point #7 - x*/ 0x3f, 0x80, 0x00, 0x00, /* Point #7 - y*/ 0x3f, 0x80, 0x00, 0x00, /* Point #7 - z*/ /* No vertices */ /* No lines */ 0x00, 0x00, 0x00, 0x04, /* Polygon #0 - number of data */ 0x00, 0x00, 0x00, 0x00, /* Polygon #0 - point #0 */ 0x00, 0x00, 0x00, 0x01, /* Polygon #0 - point #1 */ 0x00, 0x00, 0x00, 0x02, /* Polygon #0 - point #2 */ 0x00, 0x00, 0x00, 0x03, /* Polygon #0 - point #3 */ 0x00, 0x00, 0x00, 0x04, /* Polygon #1 - number of data */ 0x00, 0x00, 0x00, 0x04, /* Polygon #1 - point #0 */ 0x00, 0x00, 0x00, 0x05, /* Polygon #1 - point #1 */ 0x00, 0x00, 0x00, 0x06, /* Polygon #1 - point #2 */ 0x00, 0x00, 0x00, 0x07, /* Polygon #1 - point #3 */ 0x00, 0x00, 0x00, 0x04, /* Polygon #2 - number of data */ 0x00, 0x00, 0x00, 0x00, /* Polygon #2 - point #0 */ 0x00, 0x00, 0x00, 0x01, /* Polygon #2 - point #1 */ 0x00, 0x00, 0x00, 0x05, /* Polygon #2 - point #2 */ 0x00, 0x00, 0x00, 0x04, /* Polygon #2 - point #3 */ 0x00, 0x00, 0x00, 0x04, /* Polygon #3 - number of data */ 0x00, 0x00, 0x00, 0x01, /* Polygon #3 - point #0 */ 0x00, 0x00, 0x00, 0x02, /* Polygon #3 - point #1 */ 0x00, 0x00, 0x00, 0x06, /* Polygon #3 - point #2 */ 0x00, 0x00, 0x00, 0x05, /* Polygon #3 - point #3 */ 0x00, 0x00, 0x00, 0x04, /* Polygon #4 - number of data */ 0x00, 0x00, 0x00, 0x02, /* Polygon #4 - point #0 */ 0x00, 0x00, 0x00, 0x03, /* Polygon #4 - point #1 */ 0x00, 0x00, 0x00, 0x07, /* Polygon #4 - point #2 */ 0x00, 0x00, 0x00, 0x06, /* Polygon #4 - point #3 */ 0x00, 0x00, 0x00, 0x04, /* Polygon #5 - number of data */ 0x00, 0x00, 0x00, 0x03, /* Polygon #5 - point #0 */ 0x00, 0x00, 0x00, 0x00, /* Polygon #5 - point #1 */ 0x00, 0x00, 0x00, 0x04, /* Polygon #5 - point #2 */ 0x00, 0x00, 0x00, 0x07, /* Polygon #5 - point #3 */ /*---------- POLYDATA message body (attribute section) ------------*/ 0x00, /* Attribute #0 Type (upper 8bit) - type */ 0x01, /* Attribute #0 Type (lower 8bit) - number of components */ 0x00, 0x00, 0x00, 0x08, /* Attribute #0 Size */ 0x61, 0x74, 0x74, 0x72, /* Attribute #0 - name */ 0x00, /* Name string terminater */ 0x00, /* Padding required */ 0x00, 0x00, 0x00, 0x00, /* Point #0 */ 0x3f, 0x80, 0x00, 0x00, /* Point #1 */ 0x40, 0x00, 0x00, 0x00, /* Point #2 */ 0x40, 0x40, 0x00, 0x00, /* Point #3 */ 0x40, 0x80, 0x00, 0x00, /* Point #4 */ 0x40, 0xa0, 0x00, 0x00, /* Point #5 */ 0x40, 0xc0, 0x00, 0x00, /* Point #6 */ 0x40, 0xe0, 0x00, 0x00, /* Point #7 */ }; #endif /* IGTL_TEST_DATA_POLYDATA_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_position.h000066400000000000000000000031401501024245700243710ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy position data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_POSITION_H #define __IGTL_TEST_DATA_POSITION_H unsigned char test_position_message[] = { /*-------- OpenIGTLink message header -------*/ 0x00, 0x01, /* Version number */ 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, /* POSITION */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, /* Body size */ 0x6b, 0xc8, 0xd6, 0x28, 0x2b, 0x79, 0xa3, 0xa1, /* CRC */ /*-------- POSITION message body -------*/ 0x42, 0x38, 0x36, 0x60, 0x41, 0x9b, 0xc4, 0x67, /* px, py */ 0x42, 0x38, 0x36, 0x60, 0x00, 0x00, 0x00, 0x00, /* pz, ox */ 0x3f, 0x13, 0xcd, 0x3a, 0x3f, 0x13, 0xcd, 0x3a, /* oy, oz */ 0x3e, 0xaa, 0xaa, 0xab, /* ow */ }; #endif /* IGTL_TEST_DATA_POSITION_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_positionFormat2.h000066400000000000000000000052541501024245700256340ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy position data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_POSITION_FORMAT2_H #define __IGTL_TEST_DATA_POSITION_FORMAT2_H unsigned char test_position_messageFormat2[] = { /*-------- OpenIGTLink message header -------*/ 0x00, 0x02, /* Version number */ 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, /* POSITION */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, /* Body size */ 0xc7, 0x11, 0x16, 0x42, 0x76, 0x81, 0xc1, 0xe2, /* CRC */ /* Extended header 0 2 4 8 12 +-----------------+----------------------+---------------+-------------+ | EXT_HEADER_SIZE | METADATA_HEADER_SIZE | METADATA_SIZE | MESSAGE_ID | +-----------------+----------------------+---------------+-------------+*/ 0x00, 0x0c, 0x00, 0x12, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, /*-------- POSITION message body -------*/ 0x42, 0x38, 0x36, 0x60, 0x41, 0x9b, 0xc4, 0x67, /* px, py */ 0x42, 0x38, 0x36, 0x60, 0x00, 0x00, 0x00, 0x00, /* pz, ox */ 0x3f, 0x13, 0xcd, 0x3a, 0x3f, 0x13, 0xcd, 0x3a, /* oy, oz */ 0x3e, 0xaa, 0xaa, 0xab, /* ow */ /*---------- TRAJECTORY Meta data body ------------*/ 0x00, 0x02, /* Index Count */ 0x00, 0x11, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* first element Key size(2 Bytes), value coding(2 Bytes), value size(4 Bytes)*/ 0x00, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* second element Key size, value coding, value size*/ 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x70, 0x61, /* First Patient Age 22*/ 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x32, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, /* Second Patient Age 25*/ 0x70, 0x61, 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x35 }; #endif /* IGTL_TEST_DATA_POSITION_FORMAT2_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_sensor.h000066400000000000000000000035471501024245700240510ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy status data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_SENSOR_H #define __IGTL_TEST_DATA_SENSOR_H unsigned char test_sensor_message[] = { 0x00, 0x01, /* Version number */ 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* SENSOR */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, /* Body size */ 0x63, 0x7b, 0x80, 0x08, 0x66, 0x20, 0x20, 0xe7, /* CRC */ 0x06, /* larray */ 0x00, /* status */ 0x00, 0x44, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, /* unit */ 0x40, 0xfe, 0x24, 0x0c, 0x7a, 0xe1, 0x47, 0xae, /* value: sensor #0 */ 0x40, 0xc8, 0x1c, 0xd6, 0xc8, 0xb4, 0x39, 0x58, /* value: sensor #1 */ 0x40, 0x93, 0x4a, 0x45, 0x6d, 0x5c, 0xfa, 0xad, /* value: sensor #2 */ 0x40, 0x5e, 0xdd, 0x3b, 0xe2, 0x2e, 0x5d, 0xe1, /* value: sensor #3 */ 0x40, 0x28, 0xb0, 0xfc, 0xb4, 0xf1, 0xe4, 0xb4, /* value: sensor #4 */ 0x3f, 0xf3, 0xc0, 0xca, 0x2a, 0x5b, 0x1d, 0x5d, /* value: sensor #4 */ }; #endif /* IGTL_TEST_DATA_SENSOR_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_status.h000066400000000000000000000032671501024245700240620ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy status data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_STATUS_H #define __IGTL_TEST_DATA_STATUS_H unsigned char test_status_message[] = { 0x00, 0x01, /* Version number */ 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* STATUS */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, /* Body size */ 0x98, 0xee, 0x43, 0xee, 0xd8, 0xe4, 0x31, 0xcf, /* CRC */ 0x00, 0x0f, /* Status code */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, /* Sub code */ 0x41, 0x43, 0x54, 0x55, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x00, 0x00, 0x00, /* Status name */ 0x41, 0x63, 0x74, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x41, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x00, }; #endif /* IGTL_TEST_DATA_STATUS_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_string.h000066400000000000000000000030401501024245700240320ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy status data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_STRING_H #define __IGTL_TEST_DATA_STRING_H unsigned char test_string_message[] = { 0x00, 0x01, /* Version number */ 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* STRING */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, /* Body size */ 0xce, 0xf1, 0xb4, 0x2a, 0x70, 0x11, 0x04, 0xd4, /* CRC */ 0x00, 0x03, /* encoding */ 0x00, 0x16, /* length */ 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x49, 0x47, 0x54, 0x4c, 0x69, 0x6e ,0x6b, /* string content */ }; #endif /* IGTL_TEST_DATA_SENSOR_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_tdata.h000066400000000000000000000063311501024245700236270ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy tdata data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_TDATA_H #define __IGTL_TEST_DATA_TDATA_H unsigned char test_tdata_message[] = { /*------- OpenIGTLink message header --------*/ 0x00, 0x01, /* Version number */ 0x54, 0x44, 0x41, 0x54, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* TDATA */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, /* Body size */ 0x5c, 0x7c, 0xeb, 0xfd, 0x27, 0x67, 0x68, 0x77, /* CRC */ /*---------- TDATA message body ------------*/ /* Tracker data 0 */ 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Name */ 0x02, /* Instrument type */ 0x00, 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ /* Tracker data 1 */ 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Name */ 0x02, /* Instrument type */ 0x00, 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ /* Tracker data 1 */ 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Name */ 0x02, /* Instrument type */ 0x00, 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ }; #endif /* IGTL_TEST_DATA_TDATA_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_tdataFormat2.h000066400000000000000000000104451501024245700250630ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy tdata data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_TDATA_FORMAT2_H #define __IGTL_TEST_DATA_TDATA_FORMAT2_H unsigned char test_tdata_messageFormat2[] = { /*------- OpenIGTLink message header --------*/ 0x00, 0x02, /* Version number */ 0x54, 0x44, 0x41, 0x54, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* TDATA */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x17, /* Body size */ 0xbd, 0x30, 0x9e, 0x0e, 0x33, 0x10, 0x1c, 0x37, /* CRC */ /* Extended header 0 2 4 8 12 +-----------------+----------------------+---------------+-------------+ | EXT_HEADER_SIZE | METADATA_HEADER_SIZE | METADATA_SIZE | MESSAGE_ID | +-----------------+----------------------+---------------+-------------+*/ 0x00, 0x0c, 0x00, 0x12, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, /*---------- TDATA message body ------------*/ /* Tracker data 0 */ 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Name */ 0x02, /* Instrument type */ 0x00, 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ /* Tracker data 1 */ 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Name */ 0x02, /* Instrument type */ 0x00, 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ /* Tracker data 1 */ 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Name */ 0x02, /* Instrument type */ 0x00, 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ /*---------- TRAJECTORY Meta data body ------------*/ 0x00, 0x02, /* Index Count */ 0x00, 0x11, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* first element Key size(2 Bytes), value coding(2 Bytes), value size(4 Bytes)*/ 0x00, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* second element Key size, value coding, value size*/ 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x70, 0x61, /* First Patient Age 22*/ 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x32, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, /* Second Patient Age 25*/ 0x70, 0x61, 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x35 }; #endif /* IGTL_TEST_DATA_TDATA_FORMAT2_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_trajectory.h000066400000000000000000000125321501024245700247200ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy trajectory data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_TRAJECTORY_H #define __IGTL_TEST_DATA_TRAJECTORY_H unsigned char test_trajectory_message[] = { /*------- OpenIGTLink message header --------*/ 0x00, 0x01, /* Version number */ 0x54, 0x52, 0x41, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* TRAJECTORY */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc2, /* Body size */ 0x62, 0x05, 0xa3, 0x66, 0x18, 0x57, 0x76, 0x30, /* CRC */ /*---------- TRAJECTORY message body ------------*/ /* Trajectory data 0 */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Trajectory description */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Trajectory etc.) */ 0x03, /* Type */ 0x00, /* Reserved */ 0xff, 0x00, 0x00, 0xff, /* RGBA */ 0x41, 0x20, 0x00, 0x00, 0x41, 0x70, 0x00, 0x00, 0x41, 0xa0, 0x00, 0x00, /* Entry position */ 0x41, 0xc8, 0x00, 0x00, 0x41, 0xf0, 0x00, 0x00, 0x42, 0x0c, 0x00, 0x00, /* Target position */ 0x40, 0xa0, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /* Trajectory data 1 */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Trajectory description */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Trajectory etc.) */ 0x03, /* Type */ 0x00, /* Reserved */ 0x00, 0xff, 0x00, 0xff, /* RGBA */ 0x42, 0x20, 0x00, 0x00, 0x42, 0x34, 0x00, 0x00, 0x42, 0x48, 0x00, 0x00, /* Entry position */ 0x42, 0x5c, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x42, 0x82, 0x00, 0x00, /* Target position */ 0x40, 0x20, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /* Trajectory data 2 */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Trajectory description */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Trajectory etc.) */ 0x03, /* Type */ 0x00, /* Reserved */ 0x00, 0x00, 0xff, 0xff, /* RGBA */ 0x42, 0x8c, 0x00, 0x00, 0x42, 0x96, 0x00, 0x00, 0x42, 0xa0, 0x00, 0x00, /* Entry position */ 0x42, 0xaa, 0x00, 0x00, 0x42, 0xb4, 0x00, 0x00, 0x42, 0xbe, 0x00, 0x00, /* Target position */ 0x00, 0x00, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ }; #endif /* IGTL_TEST_DATA_TRAJECTORY_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_trajectoryFormat2.h000066400000000000000000000146471501024245700261640ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy trajectory data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_TRAJECTORY_FORMAT2_H #define __IGTL_TEST_DATA_TRAJECTORY_FORMAT2_H unsigned char test_trajectory_message_Format2[] = { /*------- OpenIGTLink message header --------*/ 0x00, 0x02, /* Version number */ 0x54, 0x52, 0x41, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* TRAJECTORY */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x07, /* Body size */ 0x29, 0x44, 0x65, 0x7a, 0xc8, 0xa3, 0x96, 0xe9, /* CRC */ /* Extended header 0 2 4 8 12 +-----------------+----------------------+---------------+-------------+ | EXT_HEADER_SIZE | METADATA_HEADER_SIZE | METADATA_SIZE | MESSAGE_ID | +-----------------+----------------------+---------------+-------------+*/ 0x00, 0x0c, 0x00, 0x12, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, /*---------- TRAJECTORY message body ------------*/ /* Trajectory data 0 */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Trajectory description */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Trajectory etc.) */ 0x03, /* Type */ 0x00, /* Reserved */ 0xff, 0x00, 0x00, 0xff, /* RGBA */ 0x41, 0x20, 0x00, 0x00, 0x41, 0x70, 0x00, 0x00, 0x41, 0xa0, 0x00, 0x00, /* Entry position */ 0x41, 0xc8, 0x00, 0x00, 0x41, 0xf0, 0x00, 0x00, 0x42, 0x0c, 0x00, 0x00, /* Target position */ 0x40, 0xa0, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /* Trajectory data 1 */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Trajectory description */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Trajectory etc.) */ 0x03, /* Type */ 0x00, /* Reserved */ 0x00, 0xff, 0x00, 0xff, /* RGBA */ 0x42, 0x20, 0x00, 0x00, 0x42, 0x34, 0x00, 0x00, 0x42, 0x48, 0x00, 0x00, /* Entry position */ 0x42, 0x5c, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x42, 0x82, 0x00, 0x00, /* Target position */ 0x40, 0x20, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /* Trajectory data 2 */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Trajectory description */ 0x54, 0x52, 0x41, 0x4a, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Group name (Trajectory etc.) */ 0x03, /* Type */ 0x00, /* Reserved */ 0x00, 0x00, 0xff, 0xff, /* RGBA */ 0x42, 0x8c, 0x00, 0x00, 0x42, 0x96, 0x00, 0x00, 0x42, 0xa0, 0x00, 0x00, /* Entry position */ 0x42, 0xaa, 0x00, 0x00, 0x42, 0xb4, 0x00, 0x00, 0x42, 0xbe, 0x00, 0x00, /* Target position */ 0x00, 0x00, 0x00, 0x00, /* Radius */ 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Owner image */ /*---------- TRAJECTORY Meta data body ------------*/ 0x00, 0x02, /* Index Count */ 0x00, 0x11, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* first element Key size(2 Bytes), value coding(2 Bytes), value size(4 Bytes)*/ 0x00, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* second element Key size, value coding, value size*/ 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x70, 0x61, /* First Patient Age 22*/ 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x32, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, /* Second Patient Age 25*/ 0x70, 0x61, 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x35 }; #endif /* IGTL_TEST_DATA_TRAJECTORY_FORMAT2_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_transform.h000066400000000000000000000032001501024245700245350ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy transform data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_TRANSFORM_H #define __IGTL_TEST_DATA_TRANSFORM_H unsigned char test_transform_message[] = { 0x00, 0x01, /* Version number */ 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x4f, 0x52, 0x4d, 0x00, 0x00, 0x00, /* TRANSFORM */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, /* Body size */ 0xf6, 0xdd, 0x2b, 0x8e, 0xb4, 0xdf, 0x6d, 0xd2, /* CRC */ 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ }; #endif /* IGTL_TEST_DATA_TRANSFORM_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_test_data_transformFormat2.h000066400000000000000000000053161501024245700260020ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLLink Library -- Dummy transform data Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TEST_DATA_TRANSFORM_FORMAT2_H #define __IGTL_TEST_DATA_TRANSFORM_FORMAT2_H unsigned char test_transform_message_Format2[] = { 0x00, 0x02, /* Version number */ 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x4f, 0x52, 0x4d, 0x00, 0x00, 0x00, /* TRANSFORM */ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Device name */ 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xd4, /* Time stamp */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, /* Body size */ 0xf6, 0x98, 0xf6, 0x4f, 0xda, 0xe2, 0x66, 0xdd, /* CRC */ /* Extended header 0 2 4 8 12 +-----------------+----------------------+---------------+-------------+ | EXT_HEADER_SIZE | METADATA_HEADER_SIZE | METADATA_SIZE | MESSAGE_ID | +-----------------+----------------------+---------------+-------------+*/ 0x00, 0x0c, 0x00, 0x12, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, 0xBF, 0x74, 0x73, 0xCD, 0x3E, 0x49, 0x59, 0xE6, /* tx, ty */ 0xBE, 0x63, 0xDD, 0x98, 0xBE, 0x49, 0x59, 0xE6, /* tz, sx */ 0x3E, 0x12, 0x49, 0x1B, 0x3F, 0x78, 0x52, 0xD6, /* sy, sz */ 0x3E, 0x63, 0xDD, 0x98, 0x3F, 0x78, 0x52, 0xD6, /* nx, ny */ 0xBD, 0xC8, 0x30, 0xAE, 0x42, 0x38, 0x36, 0x60, /* nz, px */ 0x41, 0x9B, 0xC4, 0x67, 0x42, 0x38, 0x36, 0x60, /* py, pz */ /*---------- Transformation Meta data body ------------*/ 0x00, 0x02, /* Index Count */ 0x00, 0x11, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* first element Key size(2 Bytes), value coding(2 Bytes), value size(4 Bytes)*/ 0x00, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, /* second element Key size, value coding, value size*/ 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x70, 0x61, /* First Patient Age 22*/ 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x32, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, /* Second Patient Age 25*/ 0x70, 0x61, 0x74, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x67, 0x65, 0x32, 0x35 }; #endif /* IGTL_TEST_DATA_TRANSFORM_FORMAT2_H */ openigtlink-3.0.0/Testing/igtlutil/igtl_trajectory_test.c000066400000000000000000000117211501024245700237210ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include "igtl_types.h" #include "igtl_header.h" #include "igtl_trajectory.h" #include "igtl_util.h" /* include test trajectory data and serialized trajectory message */ #include "igtl_test_data_trajectory.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #define TEST_TRAJECTORY_NUM 3 #pragma pack(1) struct trajectory_message { igtl_header header; igtl_trajectory_element tlist[TEST_TRAJECTORY_NUM]; }; #pragma pack() int main( int argc, char * argv [] ) { struct trajectory_message message; int r; int s; // Test structure size if (sizeof(message) != IGTL_HEADER_SIZE+IGTL_TRAJECTORY_ELEMENT_SIZE*TEST_TRAJECTORY_NUM) { fprintf(stdout, "Invalid size of trajectory message structure.\n"); return EXIT_FAILURE; } /* Trajectory data 0 */ strncpy((char*)&(message.tlist[0].name), "TRAJECTORY_DESCRIPTION_0", 64); strncpy((char*)&(message.tlist[0].group_name), "TRAJECTORY", 32); message.tlist[0].type = IGTL_TRAJECTORY_TYPE_ENTRY_TARGET; message.tlist[0].reserved = 0; message.tlist[0].rgba[0] = 255; message.tlist[0].rgba[1] = 0; message.tlist[0].rgba[2] = 0; message.tlist[0].rgba[3] = 255; message.tlist[0].entry_pos[0] = 10.0; message.tlist[0].entry_pos[1] = 15.0; message.tlist[0].entry_pos[2] = 20.0; message.tlist[0].target_pos[0] = 25.0; message.tlist[0].target_pos[1] = 30.0; message.tlist[0].target_pos[2] = 35.0; message.tlist[0].radius = 5.0; strncpy((char*)&(message.tlist[0].owner_name), "IMAGE_0", 20); /* Trajectory data 1 */ strncpy((char*)&(message.tlist[1].name), "TRAJECTORY_DESCRIPTION_1", 64); strncpy((char*)&(message.tlist[1].group_name), "TRAJECTORY", 32); message.tlist[1].type = IGTL_TRAJECTORY_TYPE_ENTRY_TARGET; message.tlist[1].reserved = 0; message.tlist[1].rgba[0] = 0; message.tlist[1].rgba[1] = 255; message.tlist[1].rgba[2] = 0; message.tlist[1].rgba[3] = 255; message.tlist[1].entry_pos[0] = 40.0; message.tlist[1].entry_pos[1] = 45.0; message.tlist[1].entry_pos[2] = 50.0; message.tlist[1].target_pos[0] = 55.0; message.tlist[1].target_pos[1] = 60.0; message.tlist[1].target_pos[2] = 65.0; message.tlist[1].radius = 2.5; strncpy((char*)&(message.tlist[1].owner_name), "IMAGE_0", 20); /* Trajectory data 1 */ strncpy((char*)&(message.tlist[2].name), "TRAJECTORY_DESCRIPTION_2", 64); strncpy((char*)&(message.tlist[2].group_name), "TRAJECTORY", 32); message.tlist[2].type = IGTL_TRAJECTORY_TYPE_ENTRY_TARGET; message.tlist[2].reserved = 0; message.tlist[2].rgba[0] = 0; message.tlist[2].rgba[1] = 0; message.tlist[2].rgba[2] = 255; message.tlist[2].rgba[3] = 255; message.tlist[2].entry_pos[0] = 70.0; message.tlist[2].entry_pos[1] = 75.0; message.tlist[2].entry_pos[2] = 80.0; message.tlist[2].target_pos[0] = 85.0; message.tlist[2].target_pos[1] = 90.0; message.tlist[2].target_pos[2] = 95.0; message.tlist[2].radius = 0.0; strncpy((char*)&(message.tlist[2].owner_name), "IMAGE_0", 20); /* Swap byte order if necessary */ igtl_trajectory_convert_byte_order(message.tlist, TEST_TRAJECTORY_NUM); /* Create OpenIGTLink header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "TRAJ", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_TRAJECTORY_ELEMENT_SIZE*TEST_TRAJECTORY_NUM; message.header.crc = igtl_trajectory_get_crc(message.tlist, TEST_TRAJECTORY_NUM); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for debugging */ /* FILE *fp; fp = fopen("trajectory.bin", "w"); fwrite(&(message), IGTL_HEADER_SIZE+IGTL_TRAJECTORY_ELEMENT_SIZE*TEST_TRAJECTORY_NUM, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_trajectory_message, (size_t)(IGTL_HEADER_SIZE+IGTL_TRAJECTORY_ELEMENT_SIZE*TEST_TRAJECTORY_NUM)); if (r == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+IGTL_TRAJECTORY_ELEMENT_SIZE*TEST_TRAJECTORY_NUM; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); //igtl_message_dump_hex(stdout, (const void*)&message, s); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_transform_test.c000066400000000000000000000053341501024245700235510ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_types.h" #include "igtl_header.h" #include "igtl_transform.h" #include "igtl_util.h" #include #include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 /* The decimal is rounded when it is converted to IEEE 754 floating point */ /* Include serialized test data (gold standard) */ #include "igtl_test_data_transform.h" #pragma pack(1) struct transform_message { igtl_header header; igtl_float32 transform[12]; }; #pragma pack() int main( int argc, char * argv [] ) { struct transform_message message; int r; /* Set dummy transform */ message.transform[0] = -0.954892f; message.transform[1] = 0.196632f; message.transform[2] = -0.222525f; message.transform[3] = -0.196632f; message.transform[4] = 0.142857f; message.transform[5] = 0.970014f; message.transform[6] = 0.222525f; message.transform[7] = 0.970014f; message.transform[8] = -0.0977491f; message.transform[9] = 46.0531f; message.transform[10] = 19.4709f; message.transform[11] = 46.0531f; igtl_transform_convert_byte_order(message.transform); /* Set header */ message.header.header_version = 1; strncpy( (char*)&(message.header.name), "TRANSFORM", 12 ); strncpy( (char*)&(message.header.device_name), "DeviceName", 20 ); message.header.timestamp = 1234567892; message.header.body_size = IGTL_TRANSFORM_SIZE; message.header.crc = igtl_transform_get_crc(message.transform); igtl_header_convert_byte_order( &(message.header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("transform.bin", "w"); fwrite(&(message.header), IGTL_HEADER_SIZE+IGTL_TRANSFORM_SIZE, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ r = memcmp((const void*)&message, (const void*)test_transform_message, IGTL_HEADER_SIZE+IGTL_TRANSFORM_SIZE); if (r == 0) { return EXIT_SUCCESS; } else { /* Print message as HEX values in STDERR for debug */ fprintf(stdout, "\n===== First %d bytes of the test message =====\n", IGTL_HEADER_SIZE+IGTL_TRANSFORM_SIZE); igtl_message_dump_hex(stdout, (const void*)&message, IGTL_HEADER_SIZE+IGTL_TRANSFORM_SIZE); return EXIT_FAILURE; } } openigtlink-3.0.0/Testing/igtlutil/igtl_util_test.c000066400000000000000000000012521501024245700225060ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $RCSfile: $ Language: C Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "igtl_util.h" #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 int main( int argc, char * argv [] ) { return EXIT_SUCCESS; } openigtlink-3.0.0/Tools/000077500000000000000000000000001501024245700151355ustar00rootroot00000000000000openigtlink-3.0.0/Tools/CMakeLists.txt000077500000000000000000000001001501024245700176670ustar00rootroot00000000000000# # Add here Tools that provide OpenIGTLink functionalities. # openigtlink-3.0.0/UseOpenIGTLink.cmake.in000066400000000000000000000021631501024245700202060ustar00rootroot00000000000000# # This file sets up include directories, link directories, and # compiler settings for a project to use OpenIGTLink. It should not be # included directly, but rather through the OpenIGTLink_USE_FILE setting # obtained from OpenIGTLinkConfig.cmake. # IF(OpenIGTLink_BUILD_SETTINGS_FILE AND NOT SKIP_OpenIGTLink_BUILD_SETTINGS_FILE) INCLUDE(${CMAKE_ROOT}/Modules/CMakeImportBuildSettings.cmake) CMAKE_IMPORT_BUILD_SETTINGS(${OpenIGTLink_BUILD_SETTINGS_FILE}) ENDIF() # Add compiler flags needed to use OpenIGTLink. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenIGTLink_REQUIRED_C_FLAGS}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenIGTLink_REQUIRED_CXX_FLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenIGTLink_REQUIRED_LINK_FLAGS}") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OpenIGTLink_REQUIRED_LINK_FLAGS}") SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OpenIGTLink_REQUIRED_LINK_FLAGS}") # Add include directories needed to use OpenIGTLink. INCLUDE_DIRECTORIES(BEFORE ${OpenIGTLink_INCLUDE_DIRS}) # Load the OpenIGTLink targets include(${OpenIGTLink_LIBRARY_TARGETS_FILE})openigtlink-3.0.0/Utilities/000077500000000000000000000000001501024245700160105ustar00rootroot00000000000000openigtlink-3.0.0/Utilities/Doxygen/000077500000000000000000000000001501024245700174255ustar00rootroot00000000000000openigtlink-3.0.0/Utilities/Doxygen/doxygen.config.in000066400000000000000000001627041501024245700227100ustar00rootroot00000000000000# Doxyfile 1.4.3-20050530 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a 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 #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = OpenIGTLink # 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 = @OpenIGTLink_VERSION_MAJOR@.@OpenIGTLink_VERSION_MINOR@.@OpenIGTLink_VERSION_PATCH@ # 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 = @OpenIGTLink_BINARY_DIR@/Documents/Doxygen # 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 cause performance problems for the file system. # OpenIGTLinkcommments: Links specific to OpenIGTLink will then require relative paths or absolute # paths and will create issues. CREATE_SUBDIRS = 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. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, # Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, # Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, # Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, # Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # 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 = 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 # 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" "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. 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. INLINE_INHERITED_MEMB = YES # If the FULL_PATH_NAMES tag is set to YES then 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. 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. STRIP_FROM_PATH = @OpenIGTLink_BINARY_DIR@/Documents/ # 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 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. 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 # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_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 behaviour. # 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 behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = 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. DISTRIBUTE_GROUP_DOC = 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. 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. TAB_SIZE = 2 # This tag can be used to specify a number of aliases that acts # 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 = # 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. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources # only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the SUBGROUPING tag to YES (the default) 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. SUBGROUPING = YES #--------------------------------------------------------------------------- # 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 and EXTRACT_STATIC tags are set to YES 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 EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. 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. EXTRACT_LOCAL_CLASSES = YES # 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 (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) 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. 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 (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. 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 (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # 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 (the default) these blocks will be appended to the # function's detailed documentation block. 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 (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # 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. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) 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. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # 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 default), 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. SORT_BY_SCOPE_NAME = 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. GENERATE_TODOLIST = YES # 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. 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. GENERATE_BUGLIST = YES # 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. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of 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 initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # 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. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. SHOW_DIRECTORIES = 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 , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the progam writes to standard output # is used as the file version. See the manual for examples. # # FILE_VERSION_FILTER = "@OpenIGTLink_SOURCE_DIR@/Utilities/Doxygen/cvsVersionFilter.sh" # FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # 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 # If WARN_IF_UNDOCUMENTED 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. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR 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. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. 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) 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 stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # 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 = "@OpenIGTLink_SOURCE_DIR@/Source" "@OpenIGTLink_SOURCE_DIR@/Documents/Doxygen" # 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 the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm FILE_PATTERNS = *.h *.dox # 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 = YES # 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 = "@OpenIGTLink_SOURCE_DIR@/Code/Common/itkPixelTraits.h" \ "@OpenIGTLink_SOURCE_DIR@/Code/Common/itkNumericTraits.h" \ "@OpenIGTLink_SOURCE_DIR@/Code/Common/itkNumericTraitsRGB.h" \ "@OpenIGTLink_SOURCE_DIR@/Code/Common/itkNumericTraitsVectorPixel.h" \ "@OpenIGTLink_SOURCE_DIR@/Code/Common/itkNumericTraitsTensorPixel.h" \ "@OpenIGTLink_SOURCE_DIR@/Code/Common/itkNumericTraitsCovariantVectorPixel.h" \ "@OpenIGTLink_SOURCE_DIR@/Code/Common/itkNumericTraitsVariableLengthVectorPixel.h" \ "@OpenIGTLink_SOURCE_DIR@/Code/IO/itkPixelData.h" \ "@OpenIGTLink_SOURCE_DIR@/Code/IO/itkAnalyzeDbh.h" # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. 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. EXCLUDE_PATTERNS = "*/vxl_copyright.h" "*/vcl/*" "*/dll.h" \ "*/test*" "*/example*" "*config*" "*/contrib/*" \ "*/Templates/*" "*_mocced.cxx" # "*impl*" # 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 = "@OpenIGTLink_SOURCE_DIR@/Testing/Code" "@OpenIGTLink_SOURCE_DIR@/Examples" "@OpenIGTLink_SOURCE_DIR@/Examples" # 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 = *.cxx # 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. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = "@OpenIGTLink_SOURCE_DIR@/Documents/Art" # 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 , where # is the value of the INPUT_FILTER tag, and 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. INPUT_FILTER = "perl @OpenIGTLink_BINARY_DIR@/Utilities/Doxygen/igtldoxygen.pl" # 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 # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = YES #--------------------------------------------------------------------------- # 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 also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = 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. USE_HTAGS = 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 = 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. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) 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 one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # 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 = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # 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 = "@OpenIGTLink_SOURCE_DIR@/Documents/Doxygen/DoxygenHeader.html" # 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 = "@OpenIGTLink_SOURCE_DIR@/Documents/Doxygen/DoxygenFooter.html" # 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 the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = "@OpenIGTLink_SOURCE_DIR@/Documents/Doxygen/DoxygenStyle.css" # 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 GENERATE_HTMLHELP tag is set to YES, 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. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, 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. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, 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). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, 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. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # 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 = YES # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 1 # If the GENERATE_TREEVIEW tag 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 (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # 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. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # 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 = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. 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. 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 = letter # 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 = # 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. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). 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. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # 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. LATEX_BATCHMODE = YES # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # 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 very pretty with # other RTF readers or editors. 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. If left blank `rtf' will be used as the default path. 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. 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 other # programs which support those fields. # Note: wordpad (write) and others do not support links. 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. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # 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 = man # 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 # 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 is NO. 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. 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. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # 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. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see 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. 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. 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. 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. 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. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # 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 can be done in a controlled # way by setting EXPAND_ONLY_PREDEF 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_PREDEFINED tags. EXPAND_ONLY_PREDEF = YES # 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 = NO # 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 = # 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. 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 # 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. 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();" \ "itkTypeMacro(thisClass,superclass)= \ virtual const char *GetNameOfClass() const;" \ "itkEventMacro(thisClass,superclass)= \ class thisClass : public superclass {};" \ "itkConceptMacro(thisName,thisConcept)= \ /** This class requires thisName \ in the form of thisConcept */ \ typedef thisConcept thisName;" \ "vcl_numeric_limits= \ std::numeric_limits" \ "OpenIGTLink_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" # 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. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all 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. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. 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. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that 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. GENERATE_TAGFILE = @OpenIGTLink_BINARY_DIR@/Documents/Doxygen/InsightDoxygen.tag # 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 # 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. EXTERNAL_GROUPS = YES # 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 dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # 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. 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, 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) HAVE_DOT = YES # If the CLASS_GRAPH and HAVE_DOT tags are 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 # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are 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. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies 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. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # 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. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are 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. CALL_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are 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. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH 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. 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). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # 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 a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # 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). 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. DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions 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 openigtlink-3.0.0/Utilities/Doxygen/igtldoxygen.pl.in000077500000000000000000000001241501024245700227240ustar00rootroot00000000000000 system ("perl @OpenIGTLink_SOURCE_DIR@/Utilities/Doxygen/igtlgroup.pl $ARGV[0]"); openigtlink-3.0.0/Utilities/Doxygen/igtlgroup.pl000077500000000000000000000037051501024245700220060ustar00rootroot00000000000000# if regular doxycomment add a @{ # at next empty line add a //@} $ingroup = 0; $semicount =0; $endbracecount = 0; $endparencount = 0; while(<>) { chomp; $line = $_; # if the line is not an empty line if( $line =~ /\S+/ ) { if ( /\/\*\*(.*)/ ) { # I guess it was not a group, dump savebuffer if($ingroup) { print "/**" . $savebuffer . "\n"; } # if it is a class or brief then output the line but # do not start a group if ( /(\\class|\\brief)/ ) { print $line . "\n"; } # must be a group so start saving else { $savebuffer = "$1" . "\n"; $ingroup = 1; $semicount = 0; $endbracecount = 0; $endparencount = 0; } } else { # add to save buffer if in group if($ingroup) { $savebuffer = $savebuffer . $_ . "\n"; } else { # non empty line that is not the start of a doxy comment print $_ . "\n"; } } if($line =~ /;/ ) { $semicount = $semicount + 1; } if($line =~ /\}/ ) { $endbracecount = $endbracecount + 1; } if($line =~ /\)/ ) { $endparencount = $endparencount + 1; } } else { if($ingroup) { if($endparencount > 1 && ($semicount > 1 || $endbracecount > 1)) { print "/**@\{" . $savebuffer . "//@}\n\n"; } else { print "/**" . $savebuffer . "\n"; } $savebuffer = ""; $ingroup = 0; } else { print $line . "\n"; } } } openigtlink-3.0.0/Utilities/OpenIGTLinkReleaseScript.sh000077500000000000000000000111101501024245700231120ustar00rootroot00000000000000#! /usr/bin/env bash # Bash script to release a new revision of OpenIGTLink library. # Run the command without arugment for the usage. GITHUB_ORG="tokjun" GITHUB_REPO="OpenIGTLink.git" GITHUB_PAGES_REPO="openigtlink.github.com" GIT_URL="https://github.com/$GITHUB_ORG/$GITHUB_REPO" GIT_WEB_URL="https://github.com/$GITHUB_ORG/$GITHUB_PAGES_REPO" # # Major, minor, and patch version numbers # MAJ=0 MIN=0 PAT=0 printUsage() { echo '' echo 'Usage: Utilities/OpenIGTLinkReleaseScript.sh ' echo '' echo ' RELEASE_TYPE: Type of release' echo ' major : Major version release' echo ' minor : Minor version release' echo ' patch : Patch release' } # # Extract OpenIGTLink protocol version numbers from the specified CMake file # getVersionNumbers() { local FILE=$1 echo "Examining the existing version numbers in $FILE..." MAJ=`sed -rn 's/(\s*SET\(OpenIGTLink_VERSION_MAJOR\s+\")([0-9]+)(.*)/\2/p' $FILE` MIN=`sed -rn 's/(\s*SET\(OpenIGTLink_VERSION_MINOR\s+\")([0-9]+)(.*)/\2/p' $FILE` PAT=`sed -rn 's/(\s*SET\(OpenIGTLink_VERSION_PATCH\s+\")([0-9]+)(.*)/\2/p' $FILE` echo "Old version: $MAJ.$MIN.$PAT" } # # Update OpenIGTLink protocol version numbers in the specified CMake file # updateVersionNumbers() { local FILE=$1 echo "New version: $MAJ.$MIN.$PAT" cat $FILE \ | sed -r 's/(\s*SET\(OpenIGTLink_VERSION_MAJOR\s+\")([0-9]+)(.*)/\1'"$MAJ"'\3/g' \ | sed -r 's/(\s*SET\(OpenIGTLink_VERSION_MINOR\s+\")([0-9]+)(.*)/\1'"$MIN"'\3/g' \ | sed -r 's/(\s*SET\(OpenIGTLink_VERSION_PATCH\s+\")([0-9]+)(.*)/\1'"$PAT"'\3/g' > $FILE.back mv $FILE.back $FILE } replacePageLine() { local FILE=$1 local STRING1=$2 local STRING2=$3 cat $FILE \ | sed -r 's/'"$STRING1"'.*)/'"$STRING2"'/g' > $FILE.back mv $FILE.back $FILE } updatePage() { local FILE=$1 local VERSION=$2 local STRING=$3 cat $FILE \ | sed -r 's/(\[AUTO_VER'"$VERSION"'\]\:\s+\<\>\s+\(.*\).*)/'"$STRING"'/g' > $FILE.back mv $FILE.back $FILE } # Validate the number of arguments if [ "$#" -ne 1 ]; then printUsage exit 1 fi RELEASE_TYPE=$1 getVersionNumbers CMakeLists.txt if [ $RELEASE_TYPE == "major" ]; then MAJ=$(($MAJ+1)) MIN=0 PAT=0 elif [ $RELEASE_TYPE == "minor" ]; then MIN=$(($MIN+1)) PAT=0 elif [ $RELEASE_TYPE == "patch" ]; then PAT=$(($PAT+1)) else echo "ERROR: Invaid release type: $TYPE" exit 1 fi BRANCH_NAME="release-$MAJ.$MIN" TAG_NAME="v$MAJ.$MIN.$PAT" CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD` # Major release must be performed under the master branch if [ $RELEASE_TYPE == "major" ]]; then if [ $CURRENT_BRANCH != "master" ]]; then echo "ERROR: Cannot perform major release from non-master branch." exit 1 fi fi updateVersionNumbers CMakeLists.txt # If the current branch is not master, switch to the appropriate release branch if [ $CURRENT_BRANCH != "master" ]]; then git checkout -B $BRANCH_NAME CURRENT_BRANCH=$BRANCH_NAME fi # Commit the updated CMakeFileLists.txt to the current branch git commit -a -m "Update version number in CMakeLists.txt to $MAJ.$MIN.$PAT." git push $GIT_URL $CURRENT_BRANCH # Change to the release branch, if the current branch is master git checkout -B $BRANCH_NAME # Add release tag git tag -a $TAG_NAME -m "Relase $MAJ.$MIN.$PAT" git push --tags $GIT_URL $CURRENT_BRANCH # Generate Doxygen in a temporary directory TEMP_DIR=`mktemp -d` SOURCE_DIR=`pwd` cd $TEMP_DIR mkdir OpenIGTLink-build cd OpenIGTLink-build cmake -DBUILD_DOCUMENTATION:BOOL=ON $SOURCE_DIR make Documentation # Download the repository of OpenIGTLink website cd $TEMP_DIR git clone $GIT_WEB_URL cd $GITHUB_PAGES_REPO # Copy Doxygen-generated API document mkdir api/v$MAJ.$MIN cp -rp $TEMP_DIR/OpenIGTLink-build/Documents/Doxygen/html/* api/v$MAJ.$MIN git add api/v$MAJ.$MIN/* git commit -a -m "Add API document for release $MAJ.$MIN.$PAT." DATE=`date +"%b %d, %G"` updatePage releaselog.md 0 " - $DATE : Version $MAJ.$MIN.$PAT is released." if [ $RELEASE_TYPE == "patch" ]]; then replacePageLine spec.md "- [Relase $MAJ.$MIN]" "- [Release $MAJ.$MIN]](https://github.com/openigtlink/OpenIGTLink/blob/release-v$MAJ.$MIN.$PAT/Documents/Protocol/index.md)" replacePageLine api/index.md "- [Relase $MAJ.$MIN]" "- [Release $MAJ.$MIN]](https://github.com/openigtlink/OpenIGTLink/blob/release-v$MAJ.$MIN.$PAT/Documents/Protocol/index.md)" fi if [ $RELEASE_TYPE == "minor" ]]; then updatePage spec.md $MAJ " - [Release $MAJ.$MIN](https://github.com/openigtlink/OpenIGTLink/blob/release-v$MAJ.$MIN.$PAT/Documents/Protocol/index.md)" fi rm -rf $TEMP_DIR openigtlink-3.0.0/Utilities/Scripts/000077500000000000000000000000001501024245700174375ustar00rootroot00000000000000openigtlink-3.0.0/Utilities/Scripts/SetupGitAliases.sh000077500000000000000000000013631501024245700230470ustar00rootroot00000000000000#!/usr/bin/env bash echo "Setting up useful Git aliases..." && # General aliases that could be global git config alias.pullall '!bash -c "git pull && git submodule update --init"' && git config alias.prepush 'log --graph --stat origin/master..' && # Staging aliases stage_disabled="VTK no longer uses the topic stage. Please use GitHub." && git config alias.stage-cmd '!sh -c "echo '"${stage_disabled}"'"' && git config alias.stage-push '!sh -c "echo '"${stage_disabled}"'"' && git config alias.stage-branch '!sh -c "echo '"${stage_disabled}"'"' && git config alias.stage-merge '!sh -c "echo '"${stage_disabled}"'"' && # Alias to push the current topic branch to GitHub git config alias.github-push '!bash Utilities/GitSetup/git-github-push' && true openigtlink-3.0.0/Utilities/Scripts/pre-commit000077500000000000000000000060771501024245700214530ustar00rootroot00000000000000#!/usr/bin/env bash egrep-q() { egrep "$@" >/dev/null 2>/dev/null } die() { echo 'pre-commit hook failure' 1>&2 echo '-----------------------' 1>&2 echo '' 1>&2 echo "$@" 1>&2 exit 1 } ExternalData_stage_linked_content() { # Identify the hash algorithm used. case "$file" in *.md5) algo=MD5 ; base="${file/.md5}" ; validate="^[0-9a-fA-F]{32}$" ;; *) die "$file: invalid content link (unrecognized extension)" ;; esac # Load and validate the hash stored in the staged blob. hash=$(git cat-file blob $dst_obj) || hash="" echo "$hash" | egrep-q "$validate" || die "$file: invalid content link (does not match '$validate')" # Reject simultaneous raw file and content link. files=$(git ls-files -- "$base") if test -n "$files"; then die "$file: content link may not coexist with $files" fi # Find the content referenced by the link. staged="$(dirname "$file")/.ExternalData_${algo}_${hash}" stored="${ExternalData_STORE}/$algo/$hash" ref="refs/data/$algo/$hash" obj=$(git rev-parse --verify -q "$ref") || obj="" if test -z "$obj" -a -f "$staged"; then # Content is staged by the ExternalData module. Store it in Git. obj=$(git hash-object -w -- "$staged") || die "$file: git hash-object failed to load $staged" git update-ref "$ref" "$obj" "" || die "$file: git update-ref failed to create $ref = $obj" echo "$file: Added content to Git at $ref" fi # Move staged object to local store if it is in Git. if test -f "$staged" && test -n "$obj"; then mkdir -p "${stored%/*}" && mv "$staged" "$stored" && rm -f "$staged" && echo "$file: Added content to local store at $stored" fi # Report destination of content link. if test -f "$stored"; then echo "Content link $file -> $stored" else echo "Content link $file -> (object not in local store)" fi } ExternalData_non_content_link() { # Reject simultaneous raw file and content link. files=$(git ls-files -- "$file.md5") if test -n "$files"; then die "$file: file may not coexist with $files" fi } #----------------------------------------------------------------------------- # Check that developmer setup is up-to-date. lastSetupForDevelopment=$(git config --get hooks.SetupForDevelopment || echo 0) eval $(grep '^SetupForDevelopment_VERSION=' "${BASH_SOURCE%/*}/../SetupForDevelopment.sh") test -n "$SetupForDevelopment_VERSION" || SetupForDevelopment_VERSION=0 if test $lastSetupForDevelopment -lt $SetupForDevelopment_VERSION; then die 'Developer setup in this work tree is out of date. Please re-run Utilities/SetupForDevelopment.sh ' fi #----------------------------------------------------------------------------- # Local ExternalData object repository. ExternalData_STORE=".ExternalData" # Process content links created by/for the CMake ExternalData module. git diff-index --cached HEAD --diff-filter=AM | while read src_mode dst_mode src_obj dst_obj status file; do if echo "$dst_mode $file" | egrep-q '^100644 .*\.(md5)$'; then ExternalData_stage_linked_content else ExternalData_non_content_link fi done || exit 1 openigtlink-3.0.0/Utilities/Scripts/prepare-commit-msg000077500000000000000000000010401501024245700230700ustar00rootroot00000000000000#!/usr/bin/env bash egrep-q() { egrep "$@" >/dev/null 2>/dev/null } # First argument is file containing commit message. commit_msg="$1" # Check for our extra instructions. egrep-q "^# Start the commit message" -- "$commit_msg" && return 0 # Insert our extra instructions. commit_msg_tmp="$commit_msg.$$" sed 's/^# \(On\|Not currently on any\) branch.*/'\ '# Start the commit message in "WIP: " to indicate Work In Progress\ # that is not yet ready to merge.\ #\ &/' "$commit_msg" > "$commit_msg_tmp" && mv "$commit_msg_tmp" "$commit_msg" openigtlink-3.0.0/Utilities/SetupForDevelopment.sh000077500000000000000000000012511501024245700223200ustar00rootroot00000000000000#!/usr/bin/env bash cd "${BASH_SOURCE%/*}/.." && Utilities/GitSetup/setup-user && echo && Utilities/GitSetup/setup-hooks && echo && Utilities/Scripts/SetupGitAliases.sh && echo && (Utilities/GitSetup/setup-upstream || echo 'Failed to setup origin. Run this again to retry.') && echo && (Utilities/GitSetup/setup-github|| echo 'Failed to setup GitHub. Run this again to retry.') && echo && Utilities/GitSetup/tips # Rebase master by default git config rebase.stat true git config branch.master.rebase true # Record the version of this setup so Scripts/pre-commit can check it. SetupForDevelopment_VERSION=2 git config hooks.SetupForDevelopment ${SetupForDevelopment_VERSION} openigtlink-3.0.0/appveyor.yml000066400000000000000000000045051501024245700164310ustar00rootroot00000000000000version: 1.0.{build} os: Visual Studio 2015 #Google Test is not build correctly for v120 and v110, but the TestConfigure.h file is a workaround solution for the testing environment: matrix: - Toolset: v140 - Toolset: v120 - Toolset: v110 platform: - x86 - x64 - ARM configuration: - Debug - Release build: verbosity: minimal branches: #whitelist only: - master - Version3-Development - Test clone_depth: 1 skip_tags: true clone_folder: c:\projects\openigtlink before_build: - ps: | Write-Output "Configuration: $env:CONFIGURATION" Write-Output "Platform: $env:PLATFORM" $generator = switch ($env:TOOLSET) { "v140" {"Visual Studio 14 2015"} "v120" {"Visual Studio 12 2013"} "v110" {"Visual Studio 11 2012"} } $generator = "$generator Win64" build_script: - ps: | mkdir build -Force | Out-Null cd build & cmake -G "$generator" -DOpenIGTLink_PROTOCOL_VERSION_3=ON .. if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } & cmake --build . --config $env:CONFIGURATION if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } mkdir build -Force | Out-Null cd .. mkdir TestBuild cd TestBuild & cmake -G "$generator" -DCMAKE_PREFIX_PATH:PATH=..\build ..\Testing if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } & cmake --build . --config $env:CONFIGURATION if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } & ctest -C $env:CONFIGURATION --output-on-failure if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } cd ..\build & cmake -G "$generator" -DOpenIGTLink_PROTOCOL_VERSION_3=OFF .. if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } & cmake --build . --config $env:CONFIGURATION if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } cd ..\TestBuild & cmake -G "$generator" -DCMAKE_PREFIX_PATH:PATH=..\build ..\Testing if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } & cmake --build . --config $env:CONFIGURATION if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } & ctest -C $env:CONFIGURATION --output-on-failure if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } openigtlink-3.0.0/igtlConfigure.h.in000066400000000000000000000030121501024245700174100ustar00rootroot00000000000000/*========================================================================= Program: OpenIGTLink Library Module: $HeadURL: http://svn.na-mic.org/NAMICSandBox/trunk/OpenIGTLink/igtlConfigure.h.in $ Language: C Date: $Date: 2010-06-09 16:16:36 -0400 (Wed, 09 Jun 2010) $ Version: $Revision: 6525 $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_CONFIGURE_H #define __IGTL_CONFIGURE_H #cmakedefine OpenIGTLink_PLATFORM_MACOSX #cmakedefine OpenIGTLink_PLATFORM_LINUX #cmakedefine OpenIGTLink_PLATFORM_SUNOS #cmakedefine OpenIGTLink_PLATFORM_WIN32 #ifdef OpenIGTLink_PLATFORM_WIN32 #ifndef _WIN32 #define _WIN32 #endif #ifndef WIN32 #define WIN32 #endif #define IGTLCommon_EXPORTS #endif #cmakedefine OpenIGTLink_USE_PTHREADS #cmakedefine OpenIGTLink_USE_WIN32_THREADS #cmakedefine OpenIGTLink_USE_SPROC #cmakedefine OpenIGTLink_HAVE_GETSOCKNAME_WITH_SOCKLEN_T #cmakedefine OpenIGTLink_HAVE_STRNLEN #define OpenIGTLink_PROTOCOL_VERSION_1 1 #define OpenIGTLink_PROTOCOL_VERSION_2 2 #define OpenIGTLink_PROTOCOL_VERSION_3 3 #define OpenIGTLink_PROTOCOL_VERSION @OpenIGTLink_PROTOCOL_VERSION@ #define OpenIGTLink_HEADER_VERSION @OpenIGTLink_HEADER_VERSION@ #endif /*__IGTL_CONFIGURE_H*/ openigtlink-3.0.0/igtlTypeConfig.h.in000066400000000000000000000037051501024245700175470ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TYPECONFIG_H #define __IGTL_TYPECONFIG_H #cmakedefine CMAKE_SIZEOF_CHAR #ifdef CMAKE_SIZEOF_CHAR #define IGTL_SIZEOF_CHAR @CMAKE_SIZEOF_CHAR@ #endif #cmakedefine CMAKE_SIZEOF_INT #ifdef CMAKE_SIZEOF_INT #define IGTL_SIZEOF_INT @CMAKE_SIZEOF_INT@ #endif #cmakedefine CMAKE_SIZEOF_SHORT #ifdef CMAKE_SIZEOF_SHORT #define IGTL_SIZEOF_SHORT @CMAKE_SIZEOF_SHORT@ #endif #cmakedefine CMAKE_SIZEOF_LONG #ifdef CMAKE_SIZEOF_LONG #define IGTL_SIZEOF_LONG @CMAKE_SIZEOF_LONG@ #endif #cmakedefine CMAKE_SIZEOF_FLOAT #ifdef CMAKE_SIZEOF_FLOAT #define IGTL_SIZEOF_FLOAT @CMAKE_SIZEOF_FLOAT@ #endif #cmakedefine CMAKE_SIZEOF_DOUBLE #ifdef CMAKE_SIZEOF_DOUBLE #define IGTL_SIZEOF_DOUBLE @CMAKE_SIZEOF_DOUBLE@ #endif #cmakedefine CMAKE_SIZEOF_LONG_LONG #cmakedefine CMAKE_SIZEOF___INT64 #cmakedefine CMAKE_SIZEOF_INT64_T #ifdef CMAKE_SIZEOF_LONG_LONG #define IGTL_TYPE_USE_LONG_LONG 1 #define IGTL_SIZEOF_LONG_LONG @CMAKE_SIZEOF_LONG_LONG@ #elif defined(CMAKE_SIZEOF___INT64) #define IGTL_TYPE_USE___INT64 1 #define IGTL_SIZEOF___INT64 @CMAKE_SIZEOF___INT64@ #elif defined(CMAKE_SIZEOF_INT64_T) #define IGTL_TYPE_USE_INT64_T 1 #define IGTL_SIZEOF_INT64_T @CMAKE_SIZEOF_INT64_T@ #endif #cmakedefine CMAKE_SIZEOF_VOID_P #cmakedefine OpenIGTLink_PLATFORM_WIN32 #ifdef OpenIGTLink_PLATFORM_WIN32 #ifndef _WIN32 #define _WIN32 #endif #ifndef WIN32 #define WIN32 #endif #define IGTLCommon_EXPORTS #endif #endif /*__IGTL_TYPECONFIG_H*/ openigtlink-3.0.0/igtl_typeconfig.h.in000066400000000000000000000037011501024245700200020ustar00rootroot00000000000000/*========================================================================= Program: The OpenIGTLink Library Language: C Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __IGTL_TYPECONFIG_H #define __IGTL_TYPECONFIG_H #cmakedefine CMAKE_SIZEOF_CHAR #ifdef CMAKE_SIZEOF_CHAR #define IGTL_SIZEOF_CHAR @CMAKE_SIZEOF_CHAR@ #endif #cmakedefine CMAKE_SIZEOF_INT #ifdef CMAKE_SIZEOF_INT #define IGTL_SIZEOF_INT @CMAKE_SIZEOF_INT@ #endif #cmakedefine CMAKE_SIZEOF_SHORT #ifdef CMAKE_SIZEOF_SHORT #define IGTL_SIZEOF_SHORT @CMAKE_SIZEOF_SHORT@ #endif #cmakedefine CMAKE_SIZEOF_LONG #ifdef CMAKE_SIZEOF_LONG #define IGTL_SIZEOF_LONG @CMAKE_SIZEOF_LONG@ #endif #cmakedefine CMAKE_SIZEOF_FLOAT #ifdef CMAKE_SIZEOF_FLOAT #define IGTL_SIZEOF_FLOAT @CMAKE_SIZEOF_FLOAT@ #endif #cmakedefine CMAKE_SIZEOF_DOUBLE #ifdef CMAKE_SIZEOF_DOUBLE #define IGTL_SIZEOF_DOUBLE @CMAKE_SIZEOF_DOUBLE@ #endif #cmakedefine CMAKE_SIZEOF_LONG_LONG #cmakedefine CMAKE_SIZEOF___INT64 #cmakedefine CMAKE_SIZEOF_INT64_T #ifdef CMAKE_SIZEOF_LONG_LONG #define IGTL_TYPE_USE_LONG_LONG 1 #define IGTL_SIZEOF_LONG_LONG @CMAKE_SIZEOF_LONG_LONG@ #elif defined(CMAKE_SIZEOF___INT64) #define IGTL_TYPE_USE___INT64 1 #define IGTL_SIZEOF___INT64 @CMAKE_SIZEOF___INT64@ #elif defined(CMAKE_SIZEOF_INT64_T) #define IGTL_TYPE_USE_INT64_T 1 #define IGTL_SIZEOF_INT64_T @CMAKE_SIZEOF_INT64_T@ #endif #cmakedefine CMAKE_SIZEOF_VOID_P #cmakedefine OpenIGTLink_PLATFORM_WIN32 #ifdef OpenIGTLink_PLATFORM_WIN32 #ifndef _WIN32 #define _WIN32 #endif #ifndef WIN32 #define WIN32 #endif #define IGTLCommon_EXPORTS #endif #endif /*__IGTL_TYPECONFIG_H*/