# HG changeset patch # User Sebastien Jodogne # Date 1374243258 -7200 # Node ID 58841db7b64e867bb7dfb7d20e2b96f48577fb7f # Parent 49a1228d6fe72e5548341869ce33fc4a6a9967e3# Parent 5bb96a6100c0ceb65e5af8f16ad3c18c57e3ebfd mainline to laaw integration diff -r 5bb96a6100c0 -r 58841db7b64e CMakeLists.txt --- a/CMakeLists.txt Fri Jul 19 16:11:13 2013 +0200 +++ b/CMakeLists.txt Fri Jul 19 16:14:18 2013 +0200 @@ -7,6 +7,11 @@ -DORTHANC_VERSION="mainline" ) + +##################################################################### +## CMake parameters tunable at the command line +##################################################################### + # Parameters of the build SET(STATIC_BUILD ON CACHE BOOL "Static build of the third-party libraries (necessary for Windows)") SET(STANDALONE_BUILD ON CACHE BOOL "Standalone build (all the resources are embedded, necessary for releases)") @@ -41,6 +46,15 @@ include(${CMAKE_SOURCE_DIR}/Resources/CMake/DownloadPackage.cmake) include(${CMAKE_SOURCE_DIR}/Resources/CMake/Compiler.cmake) +set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR}) + + + + +##################################################################### +## Inclusion of third-party dependencies +##################################################################### + # Configuration of the standalone builds if (${CMAKE_CROSSCOMPILING}) # Cross-compilation implies the standalone build @@ -78,6 +92,11 @@ include(${CMAKE_SOURCE_DIR}/Resources/CMake/LuaConfiguration.cmake) + +##################################################################### +## Autogeneration of files +##################################################################### + # Prepare the embedded files set(EMBEDDED_FILES PREPARE_DATABASE ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/PrepareDatabase.sql @@ -105,11 +124,17 @@ -# The main instructions to build the Orthanc binaries +##################################################################### +## Build the core of Orthanc +##################################################################### + +add_library(OpenSSL STATIC ${OPENSSL_SOURCES}) + add_library(CoreLibrary STATIC ${AUTOGENERATED_SOURCES} ${THIRD_PARTY_SOURCES} + ${CURL_SOURCES} Core/Cache/MemoryCache.cpp Core/ChunkedBuffer.cpp @@ -166,6 +191,10 @@ if(NOT ONLY_CORE_LIBRARY) + ##################################################################### + ## Build the Orthanc server + ##################################################################### + add_library(ServerLibrary STATIC ${DCMTK_SOURCES} @@ -194,14 +223,18 @@ OrthancServer/main.cpp ) - target_link_libraries(Orthanc ServerLibrary CoreLibrary) + target_link_libraries(Orthanc ServerLibrary CoreLibrary OpenSSL) install( TARGETS Orthanc RUNTIME DESTINATION bin ) - # Build the unit tests if required + + ##################################################################### + ## Build the unit tests if required + ##################################################################### + if (BUILD_UNIT_TESTS) add_definitions(-DORTHANC_BUILD_UNIT_TESTS=1) include(${CMAKE_SOURCE_DIR}/Resources/CMake/GoogleTestConfiguration.cmake) @@ -219,12 +252,75 @@ UnitTests/Lua.cpp UnitTests/main.cpp ) - target_link_libraries(UnitTests ServerLibrary CoreLibrary) + target_link_libraries(UnitTests ServerLibrary CoreLibrary OpenSSL) endif() endif() -# Generate the Doxygen documentation if Doxygen is present +##################################################################### +## Create the standalone DLL containing the Orthanc Client API +##################################################################### + +# include_directories(${ORTHANC_ROOT}/OrthancCppClient/Package/Laaw) + +# if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") +# if (${CMAKE_SIZEOF_VOID_P} EQUAL 4) +# set(ORTHANC_CPP_CLIENT_DEF ${ORTHANC_ROOT}/OrthancCppClient/Package/Build/Windows32.def) +# elseif (${CMAKE_SIZEOF_VOID_P} EQUAL 8) +# set(ORTHANC_CPP_CLIENT_DEF ${ORTHANC_ROOT}/OrthancCppClient/Package/Build/Windows64.def) +# else() +# message(FATAL_ERROR "Support your platform here") +# endif() +# endif() + +# add_library(OrthancCppClient SHARED +# ${ORTHANC_ROOT}/Core/OrthancException.cpp +# ${ORTHANC_ROOT}/Core/Enumerations.cpp +# ${ORTHANC_ROOT}/Core/Toolbox.cpp +# ${ORTHANC_ROOT}/Core/HttpClient.cpp +# ${ORTHANC_ROOT}/Core/MultiThreading/ArrayFilledByThreads.cpp +# ${ORTHANC_ROOT}/Core/MultiThreading/ThreadedCommandProcessor.cpp +# ${ORTHANC_ROOT}/Core/MultiThreading/SharedMessageQueue.cpp +# ${ORTHANC_ROOT}/Core/FileFormats/PngReader.cpp +# ${ORTHANC_ROOT}/OrthancCppClient/OrthancConnection.cpp +# ${ORTHANC_ROOT}/OrthancCppClient/Series.cpp +# ${ORTHANC_ROOT}/OrthancCppClient/Study.cpp +# ${ORTHANC_ROOT}/OrthancCppClient/Instance.cpp +# ${ORTHANC_ROOT}/OrthancCppClient/Patient.cpp +# ${ORTHANC_ROOT}/OrthancCppClient/Package/SharedLibrary.cpp +# ${ORTHANC_ROOT}/Resources/sha1/sha1.cpp +# ${ORTHANC_ROOT}/Resources/md5/md5.c +# ${ORTHANC_ROOT}/Resources/base64/base64.cpp +# ${ORTHANC_CPP_CLIENT_DEF} +# ${THIRD_PARTY_SOURCES} +# ${OPENSSL_SOURCES} +# ${CURL_SOURCES} +# ) + +# if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") +# set_target_properties(OrthancCppClient +# PROPERTIES LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--version-script=${ORTHANC_ROOT}/OrthancCppClient/Package/Laaw/VersionScript.map" +# ) +# target_link_libraries(OrthancCppClient pthread) +# elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") +# if (${CMAKE_COMPILER_IS_GNUCXX}) +# set_target_properties(OrthancCppClient +# PROPERTIES LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--allow-multiple-definition -static-libgcc -static-libstdc++" +# ) +# target_link_libraries(OrthancCppClient ws2_32) +# else() +# message(FATAL_ERROR "Support Visual Studio here") +# endif() +# else() +# message(FATAL_ERROR "Support your platform here") +# endif() + + + +##################################################################### +## Generate the documentation if Doxygen is present +##################################################################### + find_package(Doxygen) if (DOXYGEN_FOUND) configure_file( diff -r 5bb96a6100c0 -r 58841db7b64e Core/Enumerations.h --- a/Core/Enumerations.h Fri Jul 19 16:11:13 2013 +0200 +++ b/Core/Enumerations.h Fri Jul 19 16:14:18 2013 +0200 @@ -32,6 +32,8 @@ #pragma once +#include "../OrthancCppClient/Package/Laaw/laaw.h" + namespace Orthanc { enum Endianness @@ -67,7 +69,7 @@ ErrorCode_FullStorage }; - enum PixelFormat + enum LAAW_API PixelFormat { PixelFormat_RGB24, PixelFormat_Grayscale8, @@ -75,7 +77,7 @@ PixelFormat_SignedGrayscale16 }; - enum ImageExtractionMode + enum LAAW_API ImageExtractionMode { ImageExtractionMode_Preview, ImageExtractionMode_UInt8, diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Instance.cpp --- a/OrthancCppClient/Instance.cpp Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/Instance.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -33,7 +33,6 @@ #include "Instance.h" #include "OrthancConnection.h" -#include "../Core/OrthancException.h" #include @@ -63,16 +62,16 @@ break; default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + throw OrthancClientException(Orthanc::ErrorCode_NotImplemented); } Orthanc::HttpClient client(connection_.GetHttpClient()); - client.SetUrl(connection_.GetOrthancUrl() + "/instances/" + id_ + "/" + suffix); + client.SetUrl(std::string(connection_.GetOrthancUrl()) + "/instances/" + id_ + "/" + suffix); std::string png; if (!client.Apply(png)) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + throw OrthancClientException(Orthanc::ErrorCode_NotImplemented); } reader_.reset(new Orthanc::PngReader); @@ -81,34 +80,34 @@ } Instance::Instance(const OrthancConnection& connection, - const std::string& id) : + const char* id) : connection_(connection), id_(id), mode_(Orthanc::ImageExtractionMode_Int16) { Orthanc::HttpClient client(connection_.GetHttpClient()); - client.SetUrl(connection_.GetOrthancUrl() + "/instances/" + id_ + "/simplified-tags"); + client.SetUrl(std::string(connection_.GetOrthancUrl()) + "/instances/" + id_ + "/simplified-tags"); Json::Value v; if (!client.Apply(tags_)) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol); + throw OrthancClientException(Orthanc::ErrorCode_NetworkProtocol); } } - std::string Instance::GetTagAsString(const char* tag) + const char* Instance::GetTagAsString(const char* tag) const { if (tags_.isMember(tag)) { - return tags_[tag].asString(); + return tags_[tag].asCString(); } else { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem); + throw OrthancClientException(Orthanc::ErrorCode_InexistentItem); } } - float Instance::GetTagAsFloat(const char* tag) + float Instance::GetTagAsFloat(const char* tag) const { std::string value = GetTagAsString(tag); @@ -118,11 +117,11 @@ } catch (boost::bad_lexical_cast) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + throw OrthancClientException(Orthanc::ErrorCode_BadFileFormat); } } - int Instance::GetTagAsInt(const char* tag) + int Instance::GetTagAsInt(const char* tag) const { std::string value = GetTagAsString(tag); @@ -132,7 +131,7 @@ } catch (boost::bad_lexical_cast) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + throw OrthancClientException(Orthanc::ErrorCode_BadFileFormat); } } @@ -218,7 +217,7 @@ catch (boost::bad_lexical_cast) { // Unable to parse the Image Orientation Patient. - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + throw OrthancClientException(Orthanc::ErrorCode_BadFileFormat); } } } diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Instance.h --- a/OrthancCppClient/Instance.h Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/Instance.h Fri Jul 19 16:14:18 2013 +0200 @@ -35,6 +35,7 @@ #include #include +#include "OrthancClientException.h" #include "../Core/IDynamicObject.h" #include "../Core/FileFormats/PngReader.h" @@ -42,7 +43,7 @@ { class OrthancConnection; - class Instance : public Orthanc::IDynamicObject + class LAAW_API Instance : public Orthanc::IDynamicObject { private: const OrthancConnection& connection_; @@ -55,11 +56,11 @@ public: Instance(const OrthancConnection& connection, - const std::string& id); + const char* id); - const std::string& GetId() const + const char* GetId() const { - return id_; + return id_.c_str(); } void SetImageExtractionMode(Orthanc::ImageExtractionMode mode); @@ -69,27 +70,27 @@ return mode_; } - std::string GetTagAsString(const char* tag); + const char* GetTagAsString(const char* tag) const; - float GetTagAsFloat(const char* tag); + float GetTagAsFloat(const char* tag) const; - int GetTagAsInt(const char* tag); + int32_t GetTagAsInt(const char* tag) const; - unsigned int GetWidth(); + uint32_t GetWidth(); - unsigned int GetHeight(); + uint32_t GetHeight(); - unsigned int GetPitch(); + uint32_t GetPitch(); Orthanc::PixelFormat GetPixelFormat(); const void* GetBuffer(); - const void* GetBuffer(unsigned int y); + const void* GetBuffer(uint32_t y); void DiscardImage(); - void SplitVectorOfFloats(std::vector& target, - const char* tag); + LAAW_API_INTERNAL void SplitVectorOfFloats(std::vector& target, + const char* tag); }; } diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/OrthancClientException.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/OrthancClientException.h Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,58 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2013 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "../Core/OrthancException.h" +#include "Package/Laaw/laaw.h" + +namespace OrthancClient +{ + class OrthancClientException : public ::Laaw::LaawException + { + public: + OrthancClientException(Orthanc::ErrorCode code) : + LaawException(Orthanc::OrthancException::GetDescription(code)) + { + } + + OrthancClientException(const char* message) : + LaawException(message) + { + } + + OrthancClientException(const std::string& message) : + LaawException(message) + { + } + }; +} diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/OrthancConnection.cpp --- a/OrthancCppClient/OrthancConnection.cpp Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/OrthancConnection.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -32,8 +32,6 @@ #include "OrthancConnection.h" -#include "../Core/OrthancException.h" - namespace OrthancClient { void OrthancConnection::ReadPatients() @@ -42,14 +40,15 @@ Json::Value v; if (!client_.Apply(content_)) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol); + throw OrthancClientException(Orthanc::ErrorCode_NetworkProtocol); } } Orthanc::IDynamicObject* OrthancConnection::GetFillerItem(size_t index) { Json::Value::ArrayIndex tmp = static_cast(index); - return new Patient(*this, content_[tmp].asString()); + std::string id = content_[tmp].asString(); + return new Patient(*this, id.c_str()); } Patient& OrthancConnection::GetPatient(unsigned int index) @@ -71,6 +70,4 @@ client_.SetCredentials(username, password); ReadPatients(); } - - } diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/OrthancConnection.h --- a/OrthancCppClient/OrthancConnection.h Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/OrthancConnection.h Fri Jul 19 16:14:18 2013 +0200 @@ -38,7 +38,7 @@ namespace OrthancClient { - class OrthancConnection : + class LAAW_API OrthancConnection : public boost::noncopyable, private Orthanc::ArrayFilledByThreads::IFiller { @@ -64,12 +64,16 @@ const char* username, const char* password); - unsigned int GetThreadCount() const + virtual ~OrthancConnection() + { + } + + uint32_t GetThreadCount() const { return patients_.GetThreadCount(); } - void SetThreadCount(unsigned int threadCount) + void SetThreadCount(uint32_t threadCount) { patients_.SetThreadCount(threadCount); } @@ -79,21 +83,21 @@ patients_.Reload(); } - const Orthanc::HttpClient& GetHttpClient() const + LAAW_API_INTERNAL const Orthanc::HttpClient& GetHttpClient() const { return client_; } - const std::string& GetOrthancUrl() const + const char* GetOrthancUrl() const { - return orthancUrl_; + return orthancUrl_.c_str(); } - unsigned int GetPatientCount() + uint32_t GetPatientCount() { return patients_.GetSize(); } - Patient& GetPatient(unsigned int index); + Patient& GetPatient(uint32_t index); }; } diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/ConfigurationCpp.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/ConfigurationCpp.json Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,5 @@ +{ + "InternalsNamespace" : [ "OrthancClient", "Internals" ], + "PublicNamespace" : [ "OrthancClient" ], + "ExceptionClassName" : "OrthancClientException" +} diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Laaw/VersionScript.map --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Laaw/VersionScript.map Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,9 @@ +# This is a version-script + +{ +global: + LAAW_EXTERNC_*; + +local: + *; +}; diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Laaw/laaw-exports.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Laaw/laaw-exports.h Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,85 @@ +/** + * Laaw - A Lightweight, Automated API Wrapper + * Copyright (C) 2010-2013 Alain Mazy, Benjamin Golinvaux, Sebastien + * Jodogne + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +/******************************************************************** + ** Windows target + ********************************************************************/ + +#if defined _WIN32 + +#include + +#if defined(__GNUC__) +// This is Mingw +#define LAAW_EXPORT_DLL_API // The exports are handled by the .DEF file +#else +// This is MSVC +#define LAAW_EXPORT_DLL_API __declspec(dllexport) +#endif + +#ifdef _M_X64 +// 64 bits target +#define LAAW_CALL_CONVENTION +#else +// 32 bits target +#define LAAW_CALL_CONVENTION __stdcall // Use the StdCall in Windows32 (for VB6) +#endif + + +/******************************************************************** + ** Linux target + ********************************************************************/ + +#elif defined(__linux) + +// Try the gcc visibility support +// http://gcc.gnu.org/wiki/Visibility +#if ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +#define LAAW_EXPORT_DLL_API __attribute__ ((visibility("default"))) +#define LAAW_CALL_CONVENTION +#else +#error No support for visibility in your version of GCC +#endif + + +/******************************************************************** + ** Max OS X target + ********************************************************************/ + +#else + +#define LAAW_EXPORT_DLL_API __attribute__ ((visibility("default"))) +#define LAAW_CALL_CONVENTION + +#endif diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Laaw/laaw.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Laaw/laaw.h Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,89 @@ +/** + * Laaw - A Lightweight, Automated API Wrapper + * Copyright (C) 2010-2013 Alain Mazy, Benjamin Golinvaux, Sebastien + * Jodogne + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "laaw-exports.h" +#include +#include + +#if (LAAW_PARSING == 1) + +#define LAAW_API __attribute__((deprecated(""))) +#define LAAW_API_INTERNAL __attribute__((deprecated(""))) +#define LAAW_API_OVERLOAD(name) __attribute__((deprecated(""))) +#define LAAW_API_PROPERTY __attribute__((deprecated(""))) +#define LAAW_API_STATIC_CLASS __attribute__((deprecated(""))) +#define LAAW_API_CUSTOM(name, value) __attribute__((deprecated(""))) + +#else + +#define LAAW_API +#define LAAW_API_INTERNAL +#define LAAW_API_OVERLOAD(name) +#define LAAW_API_PROPERTY +#define LAAW_API_STATIC_CLASS +#define LAAW_API_CUSTOM(name, value) + +#endif + + +namespace Laaw +{ + /** + * This is the base class from which all the public exceptions in + * the SDK should derive. + **/ + class LaawException + { + private: + std::string what_; + + public: + LaawException() + { + } + + LaawException(const std::string& what) : what_(what) + { + } + + LaawException(const char* what) : what_(what) + { + } + + virtual const char* What() const + { + return what_.c_str(); + } + }; +} diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/OrthancCppClient.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/OrthancCppClient.cmake Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,62 @@ +include_directories(${ORTHANC_ROOT}/OrthancCppClient/Package/Laaw) + +set(STATIC_BUILD ON) +include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/JsonCppConfiguration.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/LibCurlConfiguration.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/LibPngConfiguration.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/BoostConfiguration.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/ZlibConfiguration.cmake) + +if (${CMAKE_COMPILER_IS_GNUCXX}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wno-implicit-function-declaration") # --std=c99 makes libcurl not to compile + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Wno-long-long -Wno-variadic-macros") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") +elseif (${MSVC}) + add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) +endif() + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + if (${CMAKE_SIZEOF_VOID_P} EQUAL 4) + set(WINDOWS_DEF ${ORTHANC_ROOT}/OrthancCppClient/Package/Build/Windows32.def) + elseif (${CMAKE_SIZEOF_VOID_P} EQUAL 8) + set(WINDOWS_DEF ${ORTHANC_ROOT}/OrthancCppClient/Package/Build/Windows64.def) + else() + message(FATAL_ERROR "Support your platform here") + endif() +endif() + +add_library(OrthancCppClient SHARED + ${THIRD_PARTY_SOURCES} + ${ORTHANC_ROOT}/Core/OrthancException.cpp + ${ORTHANC_ROOT}/Core/Enumerations.cpp + ${ORTHANC_ROOT}/Core/Toolbox.cpp + ${ORTHANC_ROOT}/Core/HttpClient.cpp + ${ORTHANC_ROOT}/Core/MultiThreading/ArrayFilledByThreads.cpp + ${ORTHANC_ROOT}/Core/MultiThreading/ThreadedCommandProcessor.cpp + ${ORTHANC_ROOT}/Core/MultiThreading/SharedMessageQueue.cpp + ${ORTHANC_ROOT}/Core/FileFormats/PngReader.cpp + ${ORTHANC_ROOT}/OrthancCppClient/OrthancConnection.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Series.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Study.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Instance.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Patient.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Package/SharedLibrary.cpp + ${ORTHANC_ROOT}/Resources/sha1/sha1.cpp + ${ORTHANC_ROOT}/Resources/md5/md5.c + ${ORTHANC_ROOT}/Resources/base64/base64.cpp + ${WINDOWS_DEF} + ) + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set_target_properties(OrthancCppClient + PROPERTIES LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--version-script=${ORTHANC_ROOT}/OrthancCppClient/Package/Laaw/VersionScript.map" + ) + target_link_libraries(OrthancCppClient pthread) +else() + set_target_properties(OrthancCppClient + PROPERTIES LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--allow-multiple-definition -static-libgcc -static-libstdc++" + ) + target_link_libraries(OrthancCppClient ws2_32) +endif() diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Product.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Product.json Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,8 @@ +{ + "Product" : "OrthancClient", + "Description" : "Native client to the REST API of Orthanc", + "Company" : "CHU of Liege", + "Copyright" : "(c) 2012-2013 CHU of Liege", + "Legal" : "Licensing information is available on https://code.google.com/p/orthanc/", + "Version" : "1.0.1" +} diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/SharedLibrary.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/SharedLibrary.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,23 @@ +#include "../../Core/HttpClient.h" +#include "../OrthancConnection.h" + + +class SharedLibrarySingleton +{ +public: + SharedLibrarySingleton() + { + Orthanc::HttpClient::GlobalInitialize(); + } + + ~SharedLibrarySingleton() + { + Orthanc::HttpClient::GlobalFinalize(); + } +}; + + +static SharedLibrarySingleton singleton_; + + +#include "Build/ExternC.cpp" diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Test.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Test.sh Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,11 @@ +#!/bin/bash + +mkdir -p Build +LAAW_ROOT=~/Subversion/Jomago/Src/Labo/Laaw + +${LAAW_ROOT}/Parser/Build/LaawParser.exe Build/CodeModelRaw.json ../OrthancConnection.h -I`pwd`/../../s/jsoncpp-src-0.6.0-rc2/include -fms-extensions && \ + python ${LAAW_ROOT}/Generators/CodeModelPostProcessing.py Build/CodeModel.json Build/CodeModelRaw.json Product.json && \ + python ${LAAW_ROOT}/Generators/GenerateWrapperCpp.py Build/OrthancClient.h Build/CodeModel.json Product.json ConfigurationCpp.json && \ + python ${LAAW_ROOT}/Generators/GenerateExternC.py Build/ExternC.cpp Build/CodeModel.json Product.json && \ + python ${LAAW_ROOT}/Generators/GenerateWindows32Def.py Build/Windows32.def Build/CodeModel.json && \ + python ${LAAW_ROOT}/Generators/GenerateWindows64Def.py Build/Windows64.def Build/CodeModel.json diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Test/Basic/Build.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Test/Basic/Build.sh Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,16 @@ +#!/bin/bash + +rm -rf i w32 w64 +mkdir i +mkdir w32 +mkdir w64 + +cd i && cmake .. && cd .. && \ + cd w32 && cmake .. -DCMAKE_TOOLCHAIN_FILE=../../../../Resources/MinGWToolchain.cmake && cd .. && \ + cd w64 && cmake .. -DCMAKE_TOOLCHAIN_FILE=../../../../Resources/MinGW64Toolchain.cmake && cd .. + +make -C i -j12 +make -C w32 -j12 +make -C w64 -j12 + +nm -C -D --defined-only i/libOrthancCppClient.so diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Test/Basic/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Test/Basic/CMakeLists.txt Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 2.8) + +project(OrthancCppClientTest) + +set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR}/../../../..) +include(../../OrthancCppClient.cmake) + +add_executable(Test main.cpp) + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + target_link_libraries(Test dl) +else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") +endif() diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Test/Basic/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Test/Basic/main.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,75 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2013 Medical Physics Department, CHU of Liege, + * Belgium + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + **/ + + +#include + +#include "../../Build/OrthancClient.h" + +int main() +{ + try + { +#ifdef _WIN32 + OrthancClient::Initialize("libOrthancCppClient.dll"); +#else + OrthancClient::Initialize("libOrthancCppClient.so"); +#endif + + // Display the content of the local Orthanc instance + OrthancClient::OrthancConnection orthanc("http://localhost:8042"); + + for (unsigned int i = 0; i < orthanc.GetPatientCount(); i++) + { + OrthancClient::Patient patient = orthanc.GetPatient(i); + std::cout << "Patient: " << patient.GetId() << std::endl; + + for (unsigned int j = 0; j < patient.GetStudyCount(); j++) + { + OrthancClient::Study study = patient.GetStudy(j); + std::cout << " Study: " << study.GetId() << std::endl; + + for (unsigned int k = 0; k < study.GetSeriesCount(); k++) + { + OrthancClient::Series series = study.GetSeries(k); + std::cout << " Series: " << series.GetId() << std::endl; + + for (unsigned int l = 0; l < series.GetInstanceCount(); l++) + { + std::cout << " Instance: " << series.GetInstance(l).GetId() << std::endl; + } + } + } + } + + return 0; + } + catch (OrthancClient::OrthancClientException e) + { + std::cerr << "EXCEPTION: [" << e.What() << "]" << std::endl; + return -1; + } +} diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Test/Vtk/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Test/Vtk/CMakeLists.txt Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8) + +project(OrthancCppClientTest) + +set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR}/../../../..) +include(../../OrthancCppClient.cmake) + +find_package(VTK REQUIRED) +include(${VTK_USE_FILE}) + +add_executable(Test + main.cpp + ) + +if(VTK_LIBRARIES) + target_link_libraries(Test ${VTK_LIBRARIES}) +else() + target_link_libraries(Test vtkHybrid vtkVolumeRendering) +endif() diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Package/Test/Vtk/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/Package/Test/Vtk/main.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,179 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2013 Medical Physics Department, CHU of Liege, + * Belgium + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + **/ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../Build/OrthancClient.h" + + +void Display(OrthancClient::Series& series) +{ + /** + * Load the 3D image from Orthanc into VTK. + **/ + + vtkSmartPointer image = vtkSmartPointer::New(); + image->SetDimensions(series.GetWidth(), series.GetHeight(), series.GetInstanceCount()); + image->SetScalarType(VTK_SHORT); + image->AllocateScalars(); + + if (series.GetWidth() != 0 && + series.GetHeight() != 0 && + series.GetInstanceCount() != 0) + { + series.Load3DImage(image->GetScalarPointer(0, 0, 0), Orthanc::PixelFormat_SignedGrayscale16, + 2 * series.GetWidth(), 2 * series.GetHeight() * series.GetWidth()); + } + + image->SetSpacing(series.GetVoxelSizeX(), + series.GetVoxelSizeY(), + series.GetVoxelSizeZ()); + + + /** + * The following code is based on the VTK sample for MIP + * http://www.vtk.org/Wiki/VTK/Examples/Cxx/VolumeRendering/MinIntensityRendering + **/ + + // Create a transfer function mapping scalar value to opacity + double range[2]; + image->GetScalarRange(range); + + vtkSmartPointer opacityTransfer = + vtkSmartPointer::New(); + opacityTransfer->AddSegment(range[0], 0.0, range[1], 1.0); + + vtkSmartPointer colorTransfer = + vtkSmartPointer::New(); + colorTransfer->AddRGBPoint(0, 1.0, 1.0, 1.0); + colorTransfer->AddRGBPoint(range[1], 1.0, 1.0, 1.0); + + vtkSmartPointer property = + vtkSmartPointer::New(); + property->SetScalarOpacity(opacityTransfer); + property->SetColor(colorTransfer); + property->SetInterpolationTypeToLinear(); + + // Create a Maximum Intensity Projection rendering + vtkSmartPointer mapper = + vtkSmartPointer::New(); + mapper->SetBlendModeToMaximumIntensity(); + mapper->SetInput(image); + + vtkSmartPointer volume = vtkSmartPointer::New(); + volume->SetMapper(mapper); + volume->SetProperty(property); + + vtkSmartPointer renderer = vtkSmartPointer::New(); + renderer->AddViewProp(volume); + renderer->SetBackground(0.1, 0.2, 0.3); // Background color dark blue + + vtkSmartPointer style = + vtkSmartPointer::New(); + + vtkSmartPointer window = vtkSmartPointer::New(); + window->AddRenderer(renderer); + + vtkSmartPointer interactor = vtkSmartPointer::New(); + interactor->SetRenderWindow(window); + interactor->SetInteractorStyle(style); + interactor->Start(); +} + + +int main() +{ + try + { + OrthancClient::Initialize("libOrthancCppClient.so"); + + // Use the commented code below if you know the identifier of a + // series that corresponds to a 3D image. + + /* + { + OrthancClient::OrthancConnection orthanc("http://localhost:8042"); + OrthancClient::Series series(orthanc, "c1c4cb95-05e3bd11-8da9f5bb-87278f71-0b2b43f5"); + Display(series); + return 0; + } + */ + + + // Try and find a 3D image inside the local store + OrthancClient::OrthancConnection orthanc("http://localhost:8042"); + + for (unsigned int i = 0; i < orthanc.GetPatientCount(); i++) + { + OrthancClient::Patient patient = orthanc.GetPatient(i); + std::cout << "Patient: " << patient.GetId() << std::endl; + + for (unsigned int j = 0; j < patient.GetStudyCount(); j++) + { + OrthancClient::Study study = patient.GetStudy(j); + std::cout << " Study: " << study.GetId() << std::endl; + + for (unsigned int k = 0; k < study.GetSeriesCount(); k++) + { + OrthancClient::Series series = study.GetSeries(k); + std::cout << " Series: " << series.GetId() << std::endl; + + if (series.Is3DImage()) + { + Display(series); + return 0; + } + else + { + std::cout << " => Not a 3D image..." << std::endl; + } + } + } + } + + std::cout << "Unable to find a 3D image in the local Orthanc store" << std::endl; + + return 0; + } + catch (OrthancClient::OrthancClientException e) + { + std::cerr << "EXCEPTION: [" << e.What() << "]" << std::endl; + return -1; + } +} diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Patient.cpp --- a/OrthancCppClient/Patient.cpp Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/Patient.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -33,29 +33,30 @@ #include "Patient.h" #include "OrthancConnection.h" -#include "../Core/OrthancException.h" namespace OrthancClient { void Patient::ReadPatient() { Orthanc::HttpClient client(connection_.GetHttpClient()); - client.SetUrl(connection_.GetOrthancUrl() + "/patients/" + id_); + client.SetUrl(std::string(connection_.GetOrthancUrl()) + "/patients/" + id_); + Json::Value v; if (!client.Apply(patient_)) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol); + throw OrthancClientException(Orthanc::ErrorCode_NetworkProtocol); } } Orthanc::IDynamicObject* Patient::GetFillerItem(size_t index) { Json::Value::ArrayIndex tmp = static_cast(index); - return new Study(connection_, patient_["Studies"][tmp].asString()); + std::string id = patient_["Studies"][tmp].asString(); + return new Study(connection_, id.c_str()); } Patient::Patient(const OrthancConnection& connection, - const std::string& id) : + const char* id) : connection_(connection), id_(id), studies_(*this) @@ -64,11 +65,11 @@ ReadPatient(); } - std::string Patient::GetMainDicomTag(const char* tag, const char* defaultValue) const + const char* Patient::GetMainDicomTag(const char* tag, const char* defaultValue) const { if (patient_["MainDicomTags"].isMember(tag)) { - return patient_["MainDicomTags"][tag].asString(); + return patient_["MainDicomTags"][tag].asCString(); } else { diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Patient.h --- a/OrthancCppClient/Patient.h Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/Patient.h Fri Jul 19 16:14:18 2013 +0200 @@ -36,7 +36,7 @@ namespace OrthancClient { - class Patient : + class LAAW_API Patient : public Orthanc::IDynamicObject, private Orthanc::ArrayFilledByThreads::IFiller { @@ -57,29 +57,29 @@ public: Patient(const OrthancConnection& connection, - const std::string& id); + const char* id); void Reload() { studies_.Reload(); } - unsigned int GetStudyCount() + uint32_t GetStudyCount() { return studies_.GetSize(); } - Study& GetStudy(unsigned int index) + Study& GetStudy(uint32_t index) { return dynamic_cast(studies_.GetItem(index)); } - const std::string& GetId() const + const char* GetId() const { - return id_; + return id_.c_str(); } - std::string GetMainDicomTag(const char* tag, + const char* GetMainDicomTag(const char* tag, const char* defaultValue) const; }; } diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Series.cpp --- a/OrthancCppClient/Series.cpp Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/Series.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -33,7 +33,6 @@ #include "Series.h" #include "OrthancConnection.h" -#include "../Core/OrthancException.h" #include #include @@ -61,7 +60,7 @@ if (cosines.size() != 6) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + throw OrthancClientException(Orthanc::ErrorCode_BadFileFormat); } normal_[0] = cosines[1] * cosines[5] - cosines[2] * cosines[4]; @@ -79,7 +78,7 @@ instance.SplitVectorOfFloats(ipp, "ImagePositionPatient"); if (ipp.size() != 3) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + throw OrthancClientException(Orthanc::ErrorCode_BadFileFormat); } float dist = 0; @@ -144,7 +143,7 @@ } else { - throw OrthancException(ErrorCode_NotImplemented); + throw OrthancClientException(ErrorCode_NotImplemented); } } @@ -161,7 +160,7 @@ { if (!Is3DImage()) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + throw OrthancClientException(Orthanc::ErrorCode_NotImplemented); } } @@ -174,13 +173,17 @@ return true; } + Instance& i1 = GetInstance(0); + for (unsigned int i = 0; i < GetInstanceCount(); i++) { - if (GetInstance(0).GetTagAsString("Columns") != GetInstance(i).GetTagAsString("Columns") || - GetInstance(0).GetTagAsString("Rows") != GetInstance(i).GetTagAsString("Rows") || - GetInstance(0).GetTagAsString("ImageOrientationPatient") != GetInstance(i).GetTagAsString("ImageOrientationPatient") || - GetInstance(0).GetTagAsString("SliceThickness") != GetInstance(i).GetTagAsString("SliceThickness") || - GetInstance(0).GetTagAsString("PixelSpacing") != GetInstance(i).GetTagAsString("PixelSpacing")) + Instance& i2 = GetInstance(1); + + if (std::string(i1.GetTagAsString("Columns")) != std::string(i2.GetTagAsString("Columns")) || + std::string(i1.GetTagAsString("Rows")) != std::string(i2.GetTagAsString("Rows")) || + std::string(i1.GetTagAsString("ImageOrientationPatient")) != std::string(i2.GetTagAsString("ImageOrientationPatient")) || + std::string(i1.GetTagAsString("SliceThickness")) != std::string(i2.GetTagAsString("SliceThickness")) || + std::string(i1.GetTagAsString("PixelSpacing")) != std::string(i2.GetTagAsString("PixelSpacing"))) { return false; } @@ -195,7 +198,7 @@ return l.size() == GetInstanceCount(); } - catch (Orthanc::OrthancException) + catch (OrthancClientException) { return false; } @@ -205,28 +208,31 @@ { Orthanc::HttpClient client(connection_.GetHttpClient()); - client.SetUrl(connection_.GetOrthancUrl() + "/series/" + id_); + client.SetUrl(std::string(connection_.GetOrthancUrl()) + "/series/" + id_); Json::Value v; if (!client.Apply(series_)) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol); + throw OrthancClientException(Orthanc::ErrorCode_NetworkProtocol); } } Orthanc::IDynamicObject* Series::GetFillerItem(size_t index) { Json::Value::ArrayIndex tmp = static_cast(index); - return new Instance(connection_, series_["Instances"][tmp].asString()); + std::string id = series_["Instances"][tmp].asString(); + return new Instance(connection_, id.c_str()); } Series::Series(const OrthancConnection& connection, - const std::string& id) : + const char* id) : connection_(connection), id_(id), instances_(*this) { ReadSeries(); status_ = Status3DImage_NotTested; + url_ = std::string(connection_.GetOrthancUrl()) + "/series/" + id_; + isVoxelSizeRead_ = false; instances_.SetThreadCount(connection.GetThreadCount()); } @@ -252,11 +258,6 @@ return dynamic_cast(instances_.GetItem(index)); } - std::string Series::GetUrl() const - { - return connection_.GetOrthancUrl() + "/series/" + id_; - } - unsigned int Series::GetWidth() { Check3DImage(); @@ -277,15 +278,21 @@ return GetInstance(0).GetTagAsInt("Rows"); } - void Series::GetVoxelSize(float& sizeX, float& sizeY, float& sizeZ) + void Series::LoadVoxelSize() { + if (isVoxelSizeRead_) + { + return; + } + Check3DImage(); if (GetInstanceCount() == 0) { - sizeX = 0; - sizeY = 0; - sizeZ = 0; + // Empty image, use some default value + voxelSizeX_ = 1; + voxelSizeY_ = 1; + voxelSizeZ_ = 1; } else { @@ -297,23 +304,25 @@ std::string sy = s.substr(0, pos); std::string sx = s.substr(pos + 1); - sizeX = boost::lexical_cast(sx); - sizeY = boost::lexical_cast(sy); - sizeZ = GetInstance(0).GetTagAsFloat("SliceThickness"); + voxelSizeX_ = boost::lexical_cast(sx); + voxelSizeY_ = boost::lexical_cast(sy); + voxelSizeZ_ = GetInstance(0).GetTagAsFloat("SliceThickness"); } catch (boost::bad_lexical_cast) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + throw OrthancClientException(Orthanc::ErrorCode_NotImplemented); } } + + isVoxelSizeRead_ = true; } - std::string Series::GetMainDicomTag(const char* tag, const char* defaultValue) const + const char* Series::GetMainDicomTag(const char* tag, const char* defaultValue) const { if (series_["MainDicomTags"].isMember(tag)) { - return series_["MainDicomTags"][tag].asString(); + return series_["MainDicomTags"][tag].asCString(); } else { @@ -361,7 +370,7 @@ break; default: - throw OrthancException(ErrorCode_NotImplemented); + throw OrthancClientException(ErrorCode_NotImplemented); } @@ -372,7 +381,7 @@ if (lineStride < sx * bytesPerPixel || stackStride < sx * sy * bytesPerPixel) { - throw OrthancException(ErrorCode_BadRequest); + throw OrthancClientException(ErrorCode_BadRequest); } if (sx == 0 || sy == 0 || GetInstanceCount() == 0) @@ -402,7 +411,7 @@ if (instances.size() != GetInstanceCount()) { // Several instances have the same Z coordinate - throw OrthancException(ErrorCode_NotImplemented); + throw OrthancClientException(ErrorCode_NotImplemented); } @@ -425,8 +434,26 @@ // Wait for all the stacks to be downloaded if (!processor.Join()) { - throw OrthancException(ErrorCode_NetworkProtocol); + throw OrthancClientException(ErrorCode_NetworkProtocol); } } + float Series::GetVoxelSizeX() + { + LoadVoxelSize(); + return voxelSizeX_; + } + + float Series::GetVoxelSizeY() + { + LoadVoxelSize(); + return voxelSizeY_; + } + + float Series::GetVoxelSizeZ() + { + LoadVoxelSize(); + return voxelSizeZ_; + } + } diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Series.h --- a/OrthancCppClient/Series.h Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/Series.h Fri Jul 19 16:14:18 2013 +0200 @@ -39,7 +39,7 @@ namespace OrthancClient { - class Series : + class LAAW_API Series : public Orthanc::IDynamicObject, private Orthanc::ArrayFilledByThreads::IFiller { @@ -52,10 +52,15 @@ }; const OrthancConnection& connection_; - std::string id_; + std::string id_, url_; Json::Value series_; Orthanc::ArrayFilledByThreads instances_; Status3DImage status_; + + bool isVoxelSizeRead_; + float voxelSizeX_; + float voxelSizeY_; + float voxelSizeZ_; void Check3DImage(); @@ -76,9 +81,11 @@ size_t stackStride, Orthanc::ThreadedCommandProcessor::IListener* listener); + void LoadVoxelSize(); + public: Series(const OrthancConnection& connection, - const std::string& id); + const char* id); void Reload() { @@ -87,39 +94,46 @@ bool Is3DImage(); - unsigned int GetInstanceCount(); - - Instance& GetInstance(unsigned int index); + uint32_t GetInstanceCount(); + + Instance& GetInstance(uint32_t index); - const std::string& GetId() const + const char* GetId() const { - return id_; + return id_.c_str(); + } + + const char* GetUrl() const + { + return url_.c_str(); } - std::string GetUrl() const; + uint32_t GetWidth(); - unsigned int GetWidth(); + uint32_t GetHeight(); + + float GetVoxelSizeX(); - unsigned int GetHeight(); + float GetVoxelSizeY(); - void GetVoxelSize(float& sizeX, float& sizeY, float& sizeZ); + float GetVoxelSizeZ(); - std::string GetMainDicomTag(const char* tag, + const char* GetMainDicomTag(const char* tag, const char* defaultValue) const; - void Load3DImage(void* target, - Orthanc::PixelFormat format, - size_t lineStride, - size_t stackStride, - Orthanc::ThreadedCommandProcessor::IListener& listener) + LAAW_API_INTERNAL void Load3DImage(void* target, + Orthanc::PixelFormat format, + int64_t lineStride, + int64_t stackStride, + Orthanc::ThreadedCommandProcessor::IListener& listener) { Load3DImage(target, format, lineStride, stackStride, &listener); } void Load3DImage(void* target, Orthanc::PixelFormat format, - size_t lineStride, - size_t stackStride) + int64_t lineStride, + int64_t stackStride) { Load3DImage(target, format, lineStride, stackStride, NULL); } diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Study.cpp --- a/OrthancCppClient/Study.cpp Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/Study.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -33,29 +33,30 @@ #include "Study.h" #include "OrthancConnection.h" -#include "../Core/OrthancException.h" namespace OrthancClient { void Study::ReadStudy() { Orthanc::HttpClient client(connection_.GetHttpClient()); - client.SetUrl(connection_.GetOrthancUrl() + "/studies/" + id_); + client.SetUrl(std::string(connection_.GetOrthancUrl()) + "/studies/" + id_); + Json::Value v; if (!client.Apply(study_)) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol); + throw OrthancClientException(Orthanc::ErrorCode_NetworkProtocol); } } Orthanc::IDynamicObject* Study::GetFillerItem(size_t index) { Json::Value::ArrayIndex tmp = static_cast(index); - return new Series(connection_, study_["Series"][tmp].asString()); + std::string id = study_["Series"][tmp].asString(); + return new Series(connection_, id.c_str()); } Study::Study(const OrthancConnection& connection, - const std::string& id) : + const char* id) : connection_(connection), id_(id), series_(*this) @@ -64,11 +65,11 @@ ReadStudy(); } - std::string Study::GetMainDicomTag(const char* tag, const char* defaultValue) const + const char* Study::GetMainDicomTag(const char* tag, const char* defaultValue) const { if (study_["MainDicomTags"].isMember(tag)) { - return study_["MainDicomTags"][tag].asString(); + return study_["MainDicomTags"][tag].asCString(); } else { diff -r 5bb96a6100c0 -r 58841db7b64e OrthancCppClient/Study.h --- a/OrthancCppClient/Study.h Fri Jul 19 16:11:13 2013 +0200 +++ b/OrthancCppClient/Study.h Fri Jul 19 16:14:18 2013 +0200 @@ -36,7 +36,7 @@ namespace OrthancClient { - class Study : + class LAAW_API Study : public Orthanc::IDynamicObject, private Orthanc::ArrayFilledByThreads::IFiller { @@ -57,29 +57,29 @@ public: Study(const OrthancConnection& connection, - const std::string& id); + const char* id); void Reload() { series_.Reload(); } - unsigned int GetSeriesCount() + uint32_t GetSeriesCount() { return series_.GetSize(); } - Series& GetSeries(unsigned int index) + Series& GetSeries(uint32_t index) { return dynamic_cast(series_.GetItem(index)); } - const std::string& GetId() const + const char* GetId() const { - return id_; + return id_.c_str(); } - std::string GetMainDicomTag(const char* tag, + const char* GetMainDicomTag(const char* tag, const char* defaultValue) const; }; } diff -r 5bb96a6100c0 -r 58841db7b64e Resources/CMake/LibCurlConfiguration.cmake --- a/Resources/CMake/LibCurlConfiguration.cmake Fri Jul 19 16:11:13 2013 +0200 +++ b/Resources/CMake/LibCurlConfiguration.cmake Fri Jul 19 16:14:18 2013 +0200 @@ -9,8 +9,8 @@ AUX_SOURCE_DIRECTORY(${CURL_SOURCES_DIR}/lib CURL_SOURCES) source_group(ThirdParty\\LibCurl REGULAR_EXPRESSION ${CURL_SOURCES_DIR}/.*) - add_library(Curl STATIC ${CURL_SOURCES}) - link_libraries(Curl) + #add_library(Curl STATIC ${CURL_SOURCES}) + #link_libraries(Curl) add_definitions( -DCURL_STATICLIB=1 diff -r 5bb96a6100c0 -r 58841db7b64e Resources/CMake/OpenSslConfiguration.cmake --- a/Resources/CMake/OpenSslConfiguration.cmake Fri Jul 19 16:11:13 2013 +0200 +++ b/Resources/CMake/OpenSslConfiguration.cmake Fri Jul 19 16:14:18 2013 +0200 @@ -164,6 +164,20 @@ ${OPENSSL_SOURCES_DIR}/crypto/sha/sha512t.c ${OPENSSL_SOURCES_DIR}/crypto/sha/shatest.c ${OPENSSL_SOURCES_DIR}/crypto/srp/srptest.c + + ${OPENSSL_SOURCES_DIR}/crypto/bn/divtest.c + ${OPENSSL_SOURCES_DIR}/crypto/bn/bnspeed.c + ${OPENSSL_SOURCES_DIR}/crypto/des/destest.c + ${OPENSSL_SOURCES_DIR}/crypto/dh/p192.c + ${OPENSSL_SOURCES_DIR}/crypto/dh/p512.c + ${OPENSSL_SOURCES_DIR}/crypto/dh/p1024.c + ${OPENSSL_SOURCES_DIR}/crypto/des/rpw.c + ${OPENSSL_SOURCES_DIR}/ssl/ssltest.c + ${OPENSSL_SOURCES_DIR}/crypto/dsa/dsagen.c + ${OPENSSL_SOURCES_DIR}/crypto/dsa/dsatest.c + ${OPENSSL_SOURCES_DIR}/crypto/dh/dhtest.c + ${OPENSSL_SOURCES_DIR}/crypto/pqueue/pq_test.c + ${OPENSSL_SOURCES_DIR}/crypto/des/ncbc_enc.c ) #if (${MSVC}) @@ -174,8 +188,8 @@ "OPENSSL_SYSNAME_WIN32;SO_WIN32;WIN32_LEAN_AND_MEAN;L_ENDIAN") endif() - add_library(OpenSSL STATIC ${OPENSSL_SOURCES}) - link_libraries(OpenSSL) + #add_library(OpenSSL STATIC ${OPENSSL_SOURCES}) + #link_libraries(OpenSSL) else() include(FindOpenSSL) diff -r 5bb96a6100c0 -r 58841db7b64e Resources/CMake/ZlibConfiguration.cmake --- a/Resources/CMake/ZlibConfiguration.cmake Fri Jul 19 16:11:13 2013 +0200 +++ b/Resources/CMake/ZlibConfiguration.cmake Fri Jul 19 16:14:18 2013 +0200 @@ -1,7 +1,7 @@ # This is the minizip distribution to create ZIP files list(APPEND THIRD_PARTY_SOURCES - ${CMAKE_SOURCE_DIR}/Resources/minizip/ioapi.c - ${CMAKE_SOURCE_DIR}/Resources/minizip/zip.c + ${ORTHANC_ROOT}/Resources/minizip/ioapi.c + ${ORTHANC_ROOT}/Resources/minizip/zip.c ) if (${STATIC_BUILD}) diff -r 5bb96a6100c0 -r 58841db7b64e Resources/MinGW64Toolchain.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/MinGW64Toolchain.cmake Fri Jul 19 16:14:18 2013 +0200 @@ -0,0 +1,34 @@ +# http://sourceforge.net/apps/trac/mingw-w64/wiki/GeneralUsageInstructions + +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# Detect the prefix of the mingw-w64 compiler +execute_process( + COMMAND uname -p + OUTPUT_VARIABLE MINGW64_ARCHITECTURE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + +if (${MINGW64_ARCHITECTURE} STREQUAL "x86_64") + set(MINGW64_PREFIX "x86_64") +else() + set(MINGW64_PREFIX "i686") +endif() + +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER ${MINGW64_PREFIX}-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER ${MINGW64_PREFIX}-w64-mingw32-g++) +SET(CMAKE_RC_COMPILER ${MINGW64_PREFIX}-w64-mingw32-windres) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +SET(CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILER} -O coff -I${CMAKE_CURRENT_SOURCE_DIR} ") diff -r 5bb96a6100c0 -r 58841db7b64e Resources/Samples/OrthancCppClient/Vtk/main.cpp --- a/Resources/Samples/OrthancCppClient/Vtk/main.cpp Fri Jul 19 16:11:13 2013 +0200 +++ b/Resources/Samples/OrthancCppClient/Vtk/main.cpp Fri Jul 19 16:14:18 2013 +0200 @@ -88,9 +88,9 @@ 2 * series.GetWidth(), 2 * series.GetHeight() * series.GetWidth(), listener); } - float sx, sy, sz; - series.GetVoxelSize(sx, sy, sz); - image->SetSpacing(sx, sy, sz); + image->SetSpacing(series.GetVoxelSizeX(), + series.GetVoxelSizeY(), + series.GetVoxelSizeZ()); /**