# HG changeset patch # User Sebastien Jodogne # Date 1593619058 -7200 # Node ID b0bd22077cd8eebd029f04dfd4ed9224be506cba # Parent fda17c92d7843750749fe44ea45dfa84ab656178 sharing code with orthanc-stone diff -r fda17c92d784 -r b0bd22077cd8 Applications/CMakeLists.txt --- a/Applications/CMakeLists.txt Tue Jun 30 18:11:30 2020 +0200 +++ b/Applications/CMakeLists.txt Wed Jul 01 17:57:38 2020 +0200 @@ -150,14 +150,11 @@ ${AUTOGENERATED_SOURCES} ${BOOST_EXTENDED_SOURCES} - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/DicomDatasetReader.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/DicomPath.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/DicomTag.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/FullOrthancDataset.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/IOrthancConnection.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/OrthancHttpConnection.cpp - #${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/OrthancPluginConnection.cpp # For plugins only - #${ORTHANC_WSI_DIR}/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp # For plugins only + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/DicomDatasetReader.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/DicomPath.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/FullOrthancDataset.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/IOrthancConnection.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/OrthancHttpConnection.cpp # Mandatory components ${LIBTIFF_SOURCES} diff -r fda17c92d784 -r b0bd22077cd8 Applications/DicomToTiff.cpp --- a/Applications/DicomToTiff.cpp Tue Jun 30 18:11:30 2020 +0200 +++ b/Applications/DicomToTiff.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -22,9 +22,9 @@ #include "../Framework/DicomToolbox.h" #include "../Framework/ImageToolbox.h" #include "../Framework/Inputs/DicomPyramid.h" -#include "../Framework/Inputs/Orthanc/OrthancHttpConnection.h" #include "../Framework/Inputs/TiledPyramidStatistics.h" #include "../Framework/Outputs/HierarchicalTiffWriter.h" +#include "../Resources/Orthanc/Stone/OrthancHttpConnection.h" #include #include @@ -318,7 +318,7 @@ OrthancWSI::ApplicationToolbox::SetupRestApi(params, options); - OrthancPlugins::OrthancHttpConnection orthanc(params); + OrthancStone::OrthancHttpConnection orthanc(params); OrthancWSI::DicomPyramid source(orthanc, options[OPTION_INPUT].as(), false /* don't use cached metadata */); diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/DicomPyramid.cpp --- a/Framework/Inputs/DicomPyramid.cpp Tue Jun 30 18:11:30 2020 +0200 +++ b/Framework/Inputs/DicomPyramid.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -65,7 +65,7 @@ bool useCache) { Json::Value series; - OrthancPlugins::IOrthancConnection::RestApiGet(series, orthanc_, "/series/" + seriesId); + OrthancStone::IOrthancConnection::RestApiGet(series, orthanc_, "/series/" + seriesId); if (series.type() != Json::objectValue || !series.isMember("Instances") || @@ -139,7 +139,7 @@ } - DicomPyramid::DicomPyramid(OrthancPlugins::IOrthancConnection& orthanc, + DicomPyramid::DicomPyramid(OrthancStone::IOrthancConnection& orthanc, const std::string& seriesId, bool useCache) : orthanc_(orthanc), diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/DicomPyramid.h --- a/Framework/Inputs/DicomPyramid.h Tue Jun 30 18:11:30 2020 +0200 +++ b/Framework/Inputs/DicomPyramid.h Wed Jul 01 17:57:38 2020 +0200 @@ -32,10 +32,10 @@ private: struct Comparator; - OrthancPlugins::IOrthancConnection& orthanc_; - std::string seriesId_; - std::vector instances_; - std::vector levels_; + OrthancStone::IOrthancConnection& orthanc_; + std::string seriesId_; + std::vector instances_; + std::vector levels_; void Clear(); @@ -47,7 +47,7 @@ void CheckLevel(size_t level) const; public: - DicomPyramid(OrthancPlugins::IOrthancConnection& orthanc, + DicomPyramid(OrthancStone::IOrthancConnection& orthanc, const std::string& seriesId, bool useCache); diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/DicomPyramidInstance.cpp --- a/Framework/Inputs/DicomPyramidInstance.cpp Tue Jun 30 18:11:30 2020 +0200 +++ b/Framework/Inputs/DicomPyramidInstance.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -23,8 +23,8 @@ #include "DicomPyramidInstance.h" #include "../DicomToolbox.h" -#include "Orthanc/DicomDatasetReader.h" -#include "Orthanc/FullOrthancDataset.h" +#include "../../Resources/Orthanc/Stone/DicomDatasetReader.h" +#include "../../Resources/Orthanc/Stone/FullOrthancDataset.h" #include #include @@ -35,18 +35,26 @@ #define SERIALIZED_METADATA "4200" + namespace OrthancWSI { - static ImageCompression DetectImageCompression(OrthancPlugins::IOrthancConnection& orthanc, + static const Orthanc::DicomTag DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021e); + static const Orthanc::DicomTag DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE(0x5200, 0x9230); + static const Orthanc::DicomTag DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE(0x0048, 0x021a); + static const Orthanc::DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f); + static const Orthanc::DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS(0x0048, 0x0006); + static const Orthanc::DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS(0x0048, 0x0007); + + static ImageCompression DetectImageCompression(OrthancStone::IOrthancConnection& orthanc, const std::string& instanceId) { - using namespace OrthancPlugins; + using namespace OrthancStone; FullOrthancDataset dataset(orthanc, "/instances/" + instanceId + "/header"); DicomDatasetReader header(dataset); std::string s = Orthanc::Toolbox::StripSpaces - (header.GetMandatoryStringValue(DICOM_TAG_TRANSFER_SYNTAX_UID)); + (header.GetMandatoryStringValue(Orthanc::DICOM_TAG_TRANSFER_SYNTAX_UID)); if (s == "1.2.840.10008.1.2" || s == "1.2.840.10008.1.2.1") @@ -72,12 +80,12 @@ static void DetectPixelFormat(Orthanc::PixelFormat& format, Orthanc::PhotometricInterpretation& photometric, - OrthancPlugins::DicomDatasetReader& reader) + OrthancStone::DicomDatasetReader& reader) { - using namespace OrthancPlugins; + using namespace OrthancStone; std::string p = Orthanc::Toolbox::StripSpaces - (reader.GetMandatoryStringValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION)); + (reader.GetMandatoryStringValue(Orthanc::DICOM_TAG_PHOTOMETRIC_INTERPRETATION)); photometric = Orthanc::StringToPhotometricInterpretation(p.c_str()); @@ -89,9 +97,9 @@ unsigned int bitsStored, samplesPerPixel, tmp; - if (!reader.GetUnsignedIntegerValue(bitsStored, DICOM_TAG_BITS_STORED) || - !reader.GetUnsignedIntegerValue(samplesPerPixel, DICOM_TAG_SAMPLES_PER_PIXEL) || - !reader.GetUnsignedIntegerValue(tmp, DICOM_TAG_PIXEL_REPRESENTATION)) + if (!reader.GetUnsignedIntegerValue(bitsStored, Orthanc::DICOM_TAG_BITS_STORED) || + !reader.GetUnsignedIntegerValue(samplesPerPixel, Orthanc::DICOM_TAG_SAMPLES_PER_PIXEL) || + !reader.GetUnsignedIntegerValue(tmp, Orthanc::DICOM_TAG_PIXEL_REPRESENTATION)) { throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag); } @@ -117,7 +125,7 @@ } - ImageCompression DicomPyramidInstance::GetImageCompression(OrthancPlugins::IOrthancConnection& orthanc) + ImageCompression DicomPyramidInstance::GetImageCompression(OrthancStone::IOrthancConnection& orthanc) { /** * Lazy detection of the image compression using the transfer @@ -138,16 +146,16 @@ } - void DicomPyramidInstance::Load(OrthancPlugins::IOrthancConnection& orthanc, + void DicomPyramidInstance::Load(OrthancStone::IOrthancConnection& orthanc, const std::string& instanceId) { - using namespace OrthancPlugins; + using namespace OrthancStone; FullOrthancDataset dataset(orthanc, "/instances/" + instanceId + "/tags"); DicomDatasetReader reader(dataset); - if (reader.GetMandatoryStringValue(DICOM_TAG_SOP_CLASS_UID) != "1.2.840.10008.5.1.4.1.1.77.1.6" || - reader.GetMandatoryStringValue(DICOM_TAG_MODALITY) != "SM") + if (reader.GetMandatoryStringValue(Orthanc::DICOM_TAG_SOP_CLASS_UID) != "1.2.840.10008.5.1.4.1.1.77.1.6" || + reader.GetMandatoryStringValue(Orthanc::DICOM_TAG_MODALITY) != "SM") { throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } @@ -156,11 +164,11 @@ DetectPixelFormat(format_, photometric_, reader); unsigned int tmp; - if (!reader.GetUnsignedIntegerValue(tileWidth_, DICOM_TAG_COLUMNS) || - !reader.GetUnsignedIntegerValue(tileHeight_, DICOM_TAG_ROWS) || + if (!reader.GetUnsignedIntegerValue(tileWidth_, Orthanc::DICOM_TAG_COLUMNS) || + !reader.GetUnsignedIntegerValue(tileHeight_, Orthanc::DICOM_TAG_ROWS) || !reader.GetUnsignedIntegerValue(totalWidth_, DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS) || !reader.GetUnsignedIntegerValue(totalHeight_, DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS) || - !reader.GetUnsignedIntegerValue(tmp, DICOM_TAG_NUMBER_OF_FRAMES)) + !reader.GetUnsignedIntegerValue(tmp, Orthanc::DICOM_TAG_NUMBER_OF_FRAMES)) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } @@ -221,7 +229,7 @@ } - DicomPyramidInstance::DicomPyramidInstance(OrthancPlugins::IOrthancConnection& orthanc, + DicomPyramidInstance::DicomPyramidInstance(OrthancStone::IOrthancConnection& orthanc, const std::string& instanceId, bool useCache) : instanceId_(instanceId), @@ -313,7 +321,7 @@ hasCompression_ = false; Json::Value content; - OrthancPlugins::IOrthancConnection::ParseJson(content, s); + OrthancStone::IOrthancConnection::ParseJson(content, s); if (content.type() != Json::objectValue || !content.isMember("Frames") || diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/DicomPyramidInstance.h --- a/Framework/Inputs/DicomPyramidInstance.h Tue Jun 30 18:11:30 2020 +0200 +++ b/Framework/Inputs/DicomPyramidInstance.h Wed Jul 01 17:57:38 2020 +0200 @@ -22,7 +22,7 @@ #pragma once #include "../Enumerations.h" -#include "Orthanc/IOrthancConnection.h" +#include "../../Resources/Orthanc/Stone/IOrthancConnection.h" #include #include @@ -45,13 +45,13 @@ std::vector frames_; Orthanc::PhotometricInterpretation photometric_; - void Load(OrthancPlugins::IOrthancConnection& orthanc, + void Load(OrthancStone::IOrthancConnection& orthanc, const std::string& instanceId); void Deserialize(const std::string& content); public: - DicomPyramidInstance(OrthancPlugins::IOrthancConnection& orthanc, + DicomPyramidInstance(OrthancStone::IOrthancConnection& orthanc, const std::string& instanceId, bool useCache); @@ -60,7 +60,7 @@ return instanceId_; } - ImageCompression GetImageCompression(OrthancPlugins::IOrthancConnection& orthanc); + ImageCompression GetImageCompression(OrthancStone::IOrthancConnection& orthanc); Orthanc::PixelFormat GetPixelFormat() const { diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/DicomPyramidLevel.cpp --- a/Framework/Inputs/DicomPyramidLevel.cpp Tue Jun 30 18:11:30 2020 +0200 +++ b/Framework/Inputs/DicomPyramidLevel.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -120,7 +120,7 @@ bool DicomPyramidLevel::DownloadRawTile(std::string& raw /* out */, Orthanc::PixelFormat& format /* out */, ImageCompression& compression /* out */, - OrthancPlugins::IOrthancConnection& orthanc, + OrthancStone::IOrthancConnection& orthanc, unsigned int tileX, unsigned int tileY) const { diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/DicomPyramidLevel.h --- a/Framework/Inputs/DicomPyramidLevel.h Tue Jun 30 18:11:30 2020 +0200 +++ b/Framework/Inputs/DicomPyramidLevel.h Wed Jul 01 17:57:38 2020 +0200 @@ -88,7 +88,7 @@ bool DownloadRawTile(std::string& raw /* out */, Orthanc::PixelFormat& format /* out */, ImageCompression& compression /* out */, - OrthancPlugins::IOrthancConnection& orthanc, + OrthancStone::IOrthancConnection& orthanc, unsigned int tileX, unsigned int tileY) const; }; diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/DicomDatasetReader.cpp --- a/Framework/Inputs/Orthanc/DicomDatasetReader.cpp Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "DicomDatasetReader.h" - -#include - -#include - -namespace OrthancPlugins -{ - // This function is copied-pasted from "../../../Core/Toolbox.cpp", - // in order to avoid the dependency of plugins against the Orthanc core - static std::string StripSpaces(const std::string& source) - { - size_t first = 0; - - while (first < source.length() && - isspace(source[first])) - { - first++; - } - - if (first == source.length()) - { - // String containing only spaces - return ""; - } - - size_t last = source.length(); - while (last > first && - isspace(source[last - 1])) - { - last--; - } - - assert(first <= last); - return source.substr(first, last - first); - } - - - DicomDatasetReader::DicomDatasetReader(const IDicomDataset& dataset) : - dataset_(dataset) - { - } - - - std::string DicomDatasetReader::GetStringValue(const DicomPath& path, - const std::string& defaultValue) const - { - std::string s; - if (dataset_.GetStringValue(s, path)) - { - return s; - } - else - { - return defaultValue; - } - } - - - std::string DicomDatasetReader::GetMandatoryStringValue(const DicomPath& path) const - { - std::string s; - if (dataset_.GetStringValue(s, path)) - { - return s; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag); - } - } - - - template - static bool GetValueInternal(T& target, - const IDicomDataset& dataset, - const DicomPath& path) - { - try - { - std::string s; - - if (dataset.GetStringValue(s, path)) - { - target = boost::lexical_cast(StripSpaces(s)); - return true; - } - else - { - return false; - } - } - catch (boost::bad_lexical_cast&) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - } - - - bool DicomDatasetReader::GetIntegerValue(int& target, - const DicomPath& path) const - { - return GetValueInternal(target, dataset_, path); - } - - - bool DicomDatasetReader::GetUnsignedIntegerValue(unsigned int& target, - const DicomPath& path) const - { - int value; - - if (!GetIntegerValue(value, path)) - { - return false; - } - else if (value >= 0) - { - target = static_cast(value); - return true; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - } - - - bool DicomDatasetReader::GetFloatValue(float& target, - const DicomPath& path) const - { - return GetValueInternal(target, dataset_, path); - } - - - bool DicomDatasetReader::GetDoubleValue(double& target, - const DicomPath& path) const - { - return GetValueInternal(target, dataset_, path); - } -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/DicomDatasetReader.h --- a/Framework/Inputs/Orthanc/DicomDatasetReader.h Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "IDicomDataset.h" - -#include -#include - -namespace OrthancPlugins -{ - class DicomDatasetReader : public boost::noncopyable - { - private: - const IDicomDataset& dataset_; - - public: - DicomDatasetReader(const IDicomDataset& dataset); - - const IDicomDataset& GetDataset() const - { - return dataset_; - } - - std::string GetStringValue(const DicomPath& path, - const std::string& defaultValue) const; - - std::string GetMandatoryStringValue(const DicomPath& path) const; - - bool GetIntegerValue(int& target, - const DicomPath& path) const; - - bool GetUnsignedIntegerValue(unsigned int& target, - const DicomPath& path) const; - - bool GetFloatValue(float& target, - const DicomPath& path) const; - - bool GetDoubleValue(double& target, - const DicomPath& path) const; - }; -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/DicomPath.cpp --- a/Framework/Inputs/Orthanc/DicomPath.cpp Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "DicomPath.h" - -#include - -#include - -namespace OrthancPlugins -{ - const DicomPath::Prefix& DicomPath::GetPrefixItem(size_t depth) const - { - if (depth >= prefix_.size()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - else - { - return prefix_[depth]; - } - } - - - DicomPath::Prefix& DicomPath::GetPrefixItem(size_t depth) - { - if (depth >= prefix_.size()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - else - { - return prefix_[depth]; - } - } - - - DicomPath::DicomPath(const DicomTag& sequence, - size_t index, - const DicomTag& tag) : - finalTag_(tag) - { - AddToPrefix(sequence, index); - } - - - DicomPath::DicomPath(const DicomTag& sequence1, - size_t index1, - const DicomTag& sequence2, - size_t index2, - const DicomTag& tag) : - finalTag_(tag) - { - AddToPrefix(sequence1, index1); - AddToPrefix(sequence2, index2); - } - - - DicomPath::DicomPath(const DicomTag& sequence1, - size_t index1, - const DicomTag& sequence2, - size_t index2, - const DicomTag& sequence3, - size_t index3, - const DicomTag& tag) : - finalTag_(tag) - { - AddToPrefix(sequence1, index1); - AddToPrefix(sequence2, index2); - AddToPrefix(sequence3, index3); - } - - - std::string DicomPath::Format() const - { - std::string s; - - for (size_t i = 0; i < GetPrefixLength(); i++) - { - s += (GetPrefixTag(i).FormatHexadecimal() + " / " + - boost::lexical_cast(i) + " / "); - } - - return s + GetFinalTag().FormatHexadecimal(); - } -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/DicomPath.h --- a/Framework/Inputs/Orthanc/DicomPath.h Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "DicomTag.h" - -#include -#include - -namespace OrthancPlugins -{ - class DicomPath - { - private: - typedef std::pair Prefix; - - std::vector prefix_; - DicomTag finalTag_; - - const Prefix& GetPrefixItem(size_t depth) const; - - Prefix& GetPrefixItem(size_t depth); - - public: - DicomPath(const DicomTag& finalTag) : - finalTag_(finalTag) - { - } - - DicomPath(const DicomTag& sequence, - size_t index, - const DicomTag& tag); - - DicomPath(const DicomTag& sequence1, - size_t index1, - const DicomTag& sequence2, - size_t index2, - const DicomTag& tag); - - DicomPath(const DicomTag& sequence1, - size_t index1, - const DicomTag& sequence2, - size_t index2, - const DicomTag& sequence3, - size_t index3, - const DicomTag& tag); - - void AddToPrefix(const DicomTag& tag, - size_t position) - { - prefix_.push_back(std::make_pair(tag, position)); - } - - size_t GetPrefixLength() const - { - return prefix_.size(); - } - - DicomTag GetPrefixTag(size_t depth) const - { - return GetPrefixItem(depth).first; - } - - size_t GetPrefixIndex(size_t depth) const - { - return GetPrefixItem(depth).second; - } - - void SetPrefixIndex(size_t depth, - size_t value) - { - GetPrefixItem(depth).second = value; - } - - const DicomTag& GetFinalTag() const - { - return finalTag_; - } - - void SetFinalTag(const DicomTag& tag) - { - finalTag_ = tag; - } - - std::string Format() const; - }; -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/DicomTag.cpp --- a/Framework/Inputs/Orthanc/DicomTag.cpp Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "DicomTag.h" - -#include - -namespace OrthancPlugins -{ - const char* DicomTag::GetName() const - { - if (*this == DICOM_TAG_BITS_STORED) - { - return "BitsStored"; - } - else if (*this == DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX) - { - return "ColumnPositionInTotalImagePixelMatrix"; - } - else if (*this == DICOM_TAG_COLUMNS) - { - return "Columns"; - } - else if (*this == DICOM_TAG_MODALITY) - { - return "Modality"; - } - else if (*this == DICOM_TAG_NUMBER_OF_FRAMES) - { - return "NumberOfFrames"; - } - else if (*this == DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE) - { - return "PerFrameFunctionalGroupsSequence"; - } - else if (*this == DICOM_TAG_PHOTOMETRIC_INTERPRETATION) - { - return "PhotometricInterpretation"; - } - else if (*this == DICOM_TAG_PIXEL_REPRESENTATION) - { - return "PixelRepresentation"; - } - else if (*this == DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE) - { - return "PlanePositionSlideSequence"; - } - else if (*this == DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX) - { - return "RowPositionInTotalImagePixelMatrix"; - } - else if (*this == DICOM_TAG_ROWS) - { - return "Rows"; - } - else if (*this == DICOM_TAG_SOP_CLASS_UID) - { - return "SOPClassUID"; - } - else if (*this == DICOM_TAG_SAMPLES_PER_PIXEL) - { - return "SamplesPerPixel"; - } - else if (*this == DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS) - { - return "TotalPixelMatrixColumns"; - } - else if (*this == DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS) - { - return "TotalPixelMatrixRows"; - } - else if (*this == DICOM_TAG_TRANSFER_SYNTAX_UID) - { - return "TransferSyntaxUID"; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); - } - } - - - std::string DicomTag::FormatHexadecimal() const - { - char buf[16]; - sprintf(buf, "(%04x,%04x)", group_, element_); - return buf; - } -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/DicomTag.h --- a/Framework/Inputs/Orthanc/DicomTag.h Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include -#include - -namespace OrthancPlugins -{ - class DicomTag - { - private: - uint16_t group_; - uint16_t element_; - - DicomTag(); // Forbidden - - public: - DicomTag(uint16_t group, - uint16_t element) : - group_(group), - element_(element) - { - } - - uint16_t GetGroup() const - { - return group_; - } - - uint16_t GetElement() const - { - return element_; - } - - const char* GetName() const; - - bool operator== (const DicomTag& other) const - { - return group_ == other.group_ && element_ == other.element_; - } - - bool operator!= (const DicomTag& other) const - { - return !(*this == other); - } - - std::string FormatHexadecimal() const; - }; - - - static const DicomTag DICOM_TAG_BITS_STORED(0x0028, 0x0101); - static const DicomTag DICOM_TAG_COLUMNS(0x0028, 0x0011); - static const DicomTag DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021e); - static const DicomTag DICOM_TAG_IMAGE_ORIENTATION_PATIENT(0x0020, 0x0037); - static const DicomTag DICOM_TAG_IMAGE_POSITION_PATIENT(0x0020, 0x0032); - static const DicomTag DICOM_TAG_MODALITY(0x0008, 0x0060); - static const DicomTag DICOM_TAG_NUMBER_OF_FRAMES(0x0028, 0x0008); - static const DicomTag DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE(0x5200, 0x9230); - static const DicomTag DICOM_TAG_PHOTOMETRIC_INTERPRETATION(0x0028, 0x0004); - static const DicomTag DICOM_TAG_PIXEL_REPRESENTATION(0x0028, 0x0103); - static const DicomTag DICOM_TAG_PIXEL_SPACING(0x0028, 0x0030); - static const DicomTag DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE(0x0048, 0x021a); - static const DicomTag DICOM_TAG_RESCALE_INTERCEPT(0x0028, 0x1052); - static const DicomTag DICOM_TAG_RESCALE_SLOPE(0x0028, 0x1053); - static const DicomTag DICOM_TAG_ROWS(0x0028, 0x0010); - static const DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f); - static const DicomTag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002); - static const DicomTag DICOM_TAG_SERIES_INSTANCE_UID(0x0020, 0x000e); - static const DicomTag DICOM_TAG_SLICE_THICKNESS(0x0018, 0x0050); - static const DicomTag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016); - static const DicomTag DICOM_TAG_SOP_INSTANCE_UID(0x0008, 0x0018); - static const DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS(0x0048, 0x0006); - static const DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS(0x0048, 0x0007); - static const DicomTag DICOM_TAG_TRANSFER_SYNTAX_UID(0x0002, 0x0010); - static const DicomTag DICOM_TAG_WINDOW_CENTER(0x0028, 0x1050); - static const DicomTag DICOM_TAG_WINDOW_WIDTH(0x0028, 0x1051); -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/FullOrthancDataset.cpp --- a/Framework/Inputs/Orthanc/FullOrthancDataset.cpp Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "FullOrthancDataset.h" - -#include - -#include -#include - -namespace OrthancPlugins -{ - static const Json::Value* AccessTag(const Json::Value& dataset, - const DicomTag& tag) - { - if (dataset.type() != Json::objectValue) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - - char name[16]; - sprintf(name, "%04x,%04x", tag.GetGroup(), tag.GetElement()); - - if (!dataset.isMember(name)) - { - return NULL; - } - - const Json::Value& value = dataset[name]; - if (value.type() != Json::objectValue || - !value.isMember("Name") || - !value.isMember("Type") || - !value.isMember("Value") || - value["Name"].type() != Json::stringValue || - value["Type"].type() != Json::stringValue) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - - return &value; - } - - - static const Json::Value& GetSequenceContent(const Json::Value& sequence) - { - assert(sequence.type() == Json::objectValue); - assert(sequence.isMember("Type")); - assert(sequence.isMember("Value")); - - const Json::Value& value = sequence["Value"]; - - if (sequence["Type"].asString() != "Sequence" || - value.type() != Json::arrayValue) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - else - { - return value; - } - } - - - static bool GetStringInternal(std::string& result, - const Json::Value& tag) - { - assert(tag.type() == Json::objectValue); - assert(tag.isMember("Type")); - assert(tag.isMember("Value")); - - const Json::Value& value = tag["Value"]; - - if (tag["Type"].asString() != "String" || - value.type() != Json::stringValue) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - else - { - result = value.asString(); - return true; - } - } - - - const Json::Value* FullOrthancDataset::LookupPath(const DicomPath& path) const - { - const Json::Value* content = &root_; - - for (unsigned int depth = 0; depth < path.GetPrefixLength(); depth++) - { - const Json::Value* sequence = AccessTag(*content, path.GetPrefixTag(depth)); - if (sequence == NULL) - { - return NULL; - } - - const Json::Value& nextContent = GetSequenceContent(*sequence); - - size_t index = path.GetPrefixIndex(depth); - if (index >= nextContent.size()) - { - return NULL; - } - else - { - content = &nextContent[static_cast(index)]; - } - } - - return AccessTag(*content, path.GetFinalTag()); - } - - - void FullOrthancDataset::CheckRoot() const - { - if (root_.type() != Json::objectValue) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - } - - - FullOrthancDataset::FullOrthancDataset(IOrthancConnection& orthanc, - const std::string& uri) - { - IOrthancConnection::RestApiGet(root_, orthanc, uri); - CheckRoot(); - } - - - FullOrthancDataset::FullOrthancDataset(const std::string& content) - { - IOrthancConnection::ParseJson(root_, content); - CheckRoot(); - } - - - FullOrthancDataset::FullOrthancDataset(const void* content, - size_t size) - { - IOrthancConnection::ParseJson(root_, content, size); - CheckRoot(); - } - - - FullOrthancDataset::FullOrthancDataset(const Json::Value& root) : - root_(root) - { - CheckRoot(); - } - - - bool FullOrthancDataset::GetStringValue(std::string& result, - const DicomPath& path) const - { - const Json::Value* value = LookupPath(path); - - if (value == NULL) - { - return false; - } - else - { - return GetStringInternal(result, *value); - } - } - - - bool FullOrthancDataset::GetSequenceSize(size_t& size, - const DicomPath& path) const - { - const Json::Value* sequence = LookupPath(path); - - if (sequence == NULL) - { - return false; - } - else - { - size = GetSequenceContent(*sequence).size(); - return true; - } - } -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/FullOrthancDataset.h --- a/Framework/Inputs/Orthanc/FullOrthancDataset.h Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "IOrthancConnection.h" -#include "IDicomDataset.h" - -#include - -namespace OrthancPlugins -{ - class FullOrthancDataset : public IDicomDataset - { - private: - Json::Value root_; - - const Json::Value* LookupPath(const DicomPath& path) const; - - void CheckRoot() const; - - public: - FullOrthancDataset(IOrthancConnection& orthanc, - const std::string& uri); - - FullOrthancDataset(const std::string& content); - - FullOrthancDataset(const void* content, - size_t size); - - FullOrthancDataset(const Json::Value& root); - - virtual bool GetStringValue(std::string& result, - const DicomPath& path) const; - - virtual bool GetSequenceSize(size_t& size, - const DicomPath& path) const; - - FullOrthancDataset* Clone() const - { - return new FullOrthancDataset(this->root_); - } - }; -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/IDicomDataset.h --- a/Framework/Inputs/Orthanc/IDicomDataset.h Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "DicomPath.h" - -#include -#include - -namespace OrthancPlugins -{ - class IDicomDataset : public boost::noncopyable - { - public: - virtual ~IDicomDataset() - { - } - - virtual bool GetStringValue(std::string& result, - const DicomPath& path) const = 0; - - virtual bool GetSequenceSize(size_t& size, - const DicomPath& path) const = 0; - }; -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/IOrthancConnection.cpp --- a/Framework/Inputs/Orthanc/IOrthancConnection.cpp Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "IOrthancConnection.h" - -#include - -#include - -namespace OrthancPlugins -{ - void IOrthancConnection::ParseJson(Json::Value& result, - const std::string& content) - { - Json::Reader reader; - - if (!reader.parse(content, result)) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - } - - - void IOrthancConnection::ParseJson(Json::Value& result, - const void* content, - size_t size) - { - Json::Reader reader; - - if (!reader.parse(reinterpret_cast(content), - reinterpret_cast(content) + size, result)) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - } - - - void IOrthancConnection::RestApiGet(Json::Value& result, - IOrthancConnection& orthanc, - const std::string& uri) - { - std::string content; - orthanc.RestApiGet(content, uri); - ParseJson(result, content); - } - - - void IOrthancConnection::RestApiPost(Json::Value& result, - IOrthancConnection& orthanc, - const std::string& uri, - const std::string& body) - { - std::string content; - orthanc.RestApiPost(content, uri, body); - ParseJson(result, content); - } - - - void IOrthancConnection::RestApiPut(Json::Value& result, - IOrthancConnection& orthanc, - const std::string& uri, - const std::string& body) - { - std::string content; - orthanc.RestApiPut(content, uri, body); - ParseJson(result, content); - } -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/IOrthancConnection.h --- a/Framework/Inputs/Orthanc/IOrthancConnection.h Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "DicomPath.h" - -#include -#include -#include - -namespace OrthancPlugins -{ - class IOrthancConnection : public boost::noncopyable - { - public: - virtual ~IOrthancConnection() - { - } - - virtual void RestApiGet(std::string& result, - const std::string& uri) = 0; - - virtual void RestApiPost(std::string& result, - const std::string& uri, - const std::string& body) = 0; - - virtual void RestApiPut(std::string& result, - const std::string& uri, - const std::string& body) = 0; - - virtual void RestApiDelete(const std::string& uri) = 0; - - static void ParseJson(Json::Value& result, - const std::string& content); - - static void ParseJson(Json::Value& result, - const void* content, - size_t size); - - static void RestApiGet(Json::Value& result, - IOrthancConnection& orthanc, - const std::string& uri); - - static void RestApiPost(Json::Value& result, - IOrthancConnection& orthanc, - const std::string& uri, - const std::string& body); - - static void RestApiPut(Json::Value& result, - IOrthancConnection& orthanc, - const std::string& uri, - const std::string& body); - }; -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/OrthancHttpConnection.cpp --- a/Framework/Inputs/Orthanc/OrthancHttpConnection.cpp Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "OrthancHttpConnection.h" - -namespace OrthancPlugins -{ - void OrthancHttpConnection::Setup() - { - url_ = client_.GetUrl(); - - // Don't follow 3xx HTTP (avoid redirections to "unsupported.png" in Orthanc) - client_.SetRedirectionFollowed(false); - } - - - OrthancHttpConnection::OrthancHttpConnection() : - client_(Orthanc::WebServiceParameters(), "") - { - Setup(); - } - - - OrthancHttpConnection::OrthancHttpConnection(const Orthanc::WebServiceParameters& parameters) : - client_(parameters, "") - { - Setup(); - } - - - void OrthancHttpConnection::RestApiGet(std::string& result, - const std::string& uri) - { - boost::mutex::scoped_lock lock(mutex_); - - client_.SetMethod(Orthanc::HttpMethod_Get); - client_.SetUrl(url_ + uri); - client_.ApplyAndThrowException(result); - } - - - void OrthancHttpConnection::RestApiPost(std::string& result, - const std::string& uri, - const std::string& body) - { - boost::mutex::scoped_lock lock(mutex_); - - client_.SetMethod(Orthanc::HttpMethod_Post); - client_.SetUrl(url_ + uri); - client_.SetBody(body); - client_.ApplyAndThrowException(result); - } - - - void OrthancHttpConnection::RestApiPut(std::string& result, - const std::string& uri, - const std::string& body) - { - boost::mutex::scoped_lock lock(mutex_); - - client_.SetMethod(Orthanc::HttpMethod_Put); - client_.SetUrl(url_ + uri); - client_.SetBody(body); - client_.ApplyAndThrowException(result); - } - - - void OrthancHttpConnection::RestApiDelete(const std::string& uri) - { - boost::mutex::scoped_lock lock(mutex_); - - std::string result; - - client_.SetMethod(Orthanc::HttpMethod_Delete); - client_.SetUrl(url_ + uri); - client_.ApplyAndThrowException(result); - } -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/OrthancHttpConnection.h --- a/Framework/Inputs/Orthanc/OrthancHttpConnection.h Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "IOrthancConnection.h" - -#include - -#include - -namespace OrthancPlugins -{ - // This class is thread-safe - class OrthancHttpConnection : public IOrthancConnection - { - private: - boost::mutex mutex_; - Orthanc::HttpClient client_; - std::string url_; - - void Setup(); - - public: - OrthancHttpConnection(); - - OrthancHttpConnection(const Orthanc::WebServiceParameters& parameters); - - virtual void RestApiGet(std::string& result, - const std::string& uri); - - virtual void RestApiPost(std::string& result, - const std::string& uri, - const std::string& body); - - virtual void RestApiPut(std::string& result, - const std::string& uri, - const std::string& body); - - virtual void RestApiDelete(const std::string& uri); - }; -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/OrthancPluginConnection.cpp --- a/Framework/Inputs/Orthanc/OrthancPluginConnection.cpp Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "OrthancPluginConnection.h" - -#include "../../../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" - -#include - -namespace OrthancPlugins -{ - void OrthancPluginConnection::RestApiGet(std::string& result, - const std::string& uri) - { - OrthancPlugins::MemoryBuffer buffer; - - if (buffer.RestApiGet(uri, false)) - { - buffer.ToString(result); - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); - } - } - - - void OrthancPluginConnection::RestApiPost(std::string& result, - const std::string& uri, - const std::string& body) - { - OrthancPlugins::MemoryBuffer buffer; - - if (buffer.RestApiPost(uri, body.c_str(), body.size(), false)) - { - buffer.ToString(result); - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); - } - } - - - void OrthancPluginConnection::RestApiPut(std::string& result, - const std::string& uri, - const std::string& body) - { - OrthancPlugins::MemoryBuffer buffer; - - if (buffer.RestApiPut(uri, body.c_str(), body.size(), false)) - { - buffer.ToString(result); - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); - } - } - - - void OrthancPluginConnection::RestApiDelete(const std::string& uri) - { - OrthancPlugins::MemoryBuffer buffer; - - if (!::OrthancPlugins::RestApiDelete(uri, false)) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); - } - } -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Inputs/Orthanc/OrthancPluginConnection.h --- a/Framework/Inputs/Orthanc/OrthancPluginConnection.h Tue Jun 30 18:11:30 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "IOrthancConnection.h" - -#include - -namespace OrthancPlugins -{ - // This class is thread-safe - class OrthancPluginConnection : public IOrthancConnection - { - public: - virtual void RestApiGet(std::string& result, - const std::string& uri); - - virtual void RestApiPost(std::string& result, - const std::string& uri, - const std::string& body); - - virtual void RestApiPut(std::string& result, - const std::string& uri, - const std::string& body); - - virtual void RestApiDelete(const std::string& uri); - }; -} diff -r fda17c92d784 -r b0bd22077cd8 Framework/Targets/OrthancTarget.cpp --- a/Framework/Targets/OrthancTarget.cpp Tue Jun 30 18:11:30 2020 +0200 +++ b/Framework/Targets/OrthancTarget.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -23,7 +23,7 @@ #include "OrthancTarget.h" #include "../DicomToolbox.h" -#include "../Inputs/Orthanc/OrthancHttpConnection.h" +#include "../../Resources/Orthanc/Stone/OrthancHttpConnection.h" #include #include @@ -32,7 +32,7 @@ namespace OrthancWSI { OrthancTarget::OrthancTarget(const Orthanc::WebServiceParameters& parameters) : - orthanc_(new OrthancPlugins::OrthancHttpConnection(parameters)), + orthanc_(new OrthancStone::OrthancHttpConnection(parameters)), first_(true) { } @@ -41,7 +41,7 @@ void OrthancTarget::Write(const std::string& file) { Json::Value result; - OrthancPlugins::IOrthancConnection::RestApiPost(result, *orthanc_, "/instances", file); + OrthancStone::IOrthancConnection::RestApiPost(result, *orthanc_, "/instances", file); if (result.type() != Json::objectValue || !result.isMember("ID") || @@ -55,7 +55,7 @@ if (first_) { Json::Value instance; - OrthancPlugins::IOrthancConnection::RestApiGet(instance, *orthanc_, "/instances/" + instanceId); + OrthancStone::IOrthancConnection::RestApiGet(instance, *orthanc_, "/instances/" + instanceId); if (instance.type() != Json::objectValue || !instance.isMember("ParentSeries") || diff -r fda17c92d784 -r b0bd22077cd8 Framework/Targets/OrthancTarget.h --- a/Framework/Targets/OrthancTarget.h Tue Jun 30 18:11:30 2020 +0200 +++ b/Framework/Targets/OrthancTarget.h Wed Jul 01 17:57:38 2020 +0200 @@ -22,7 +22,7 @@ #pragma once #include "IFileTarget.h" -#include "../Inputs/Orthanc/IOrthancConnection.h" +#include "../../Resources/Orthanc/Stone/IOrthancConnection.h" #include @@ -33,13 +33,13 @@ class OrthancTarget : public IFileTarget { private: - std::auto_ptr orthanc_; + std::auto_ptr orthanc_; bool first_; public: explicit OrthancTarget(const Orthanc::WebServiceParameters& parameters); - explicit OrthancTarget(OrthancPlugins::IOrthancConnection* orthanc) : // Takes ownership + explicit OrthancTarget(OrthancStone::IOrthancConnection* orthanc) : // Takes ownership orthanc_(orthanc), first_(true) { diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/DownloadOrthancFramework.cmake --- a/Resources/Orthanc/DownloadOrthancFramework.cmake Tue Jun 30 18:11:30 2020 +0200 +++ b/Resources/Orthanc/DownloadOrthancFramework.cmake Wed Jul 01 17:57:38 2020 +0200 @@ -505,28 +505,36 @@ ${ORTHANC_FRAMEWORK_ROOT} ) endif() + + if (${ORTHANC_FRAMEWORK_INCLUDE_DIR} STREQUAL "ORTHANC_FRAMEWORK_INCLUDE_DIR-NOTFOUND") + message(FATAL_ERROR "Cannot locate the OrthancFramework.h header") + endif() message("Orthanc framework include dir: ${ORTHANC_FRAMEWORK_INCLUDE_DIR}") include_directories(${ORTHANC_FRAMEWORK_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES "${ORTHANC_FRAMEWORK_INCLUDE_DIR}") + if ("${ORTHANC_FRAMEWORK_LIBDIR}" STREQUAL "") + set(ORTHANC_FRAMEWORK_LIBRARIES OrthancFramework) + else() + if (MSVC) + set(Suffix ".lib") + set(Prefix "") + else() + list(GET CMAKE_FIND_LIBRARY_PREFIXES 0 Prefix) + list(GET CMAKE_FIND_LIBRARY_SUFFIXES 0 Suffix) + endif() + set(ORTHANC_FRAMEWORK_LIBRARIES ${ORTHANC_FRAMEWORK_LIBDIR}/${Prefix}OrthancFramework${Suffix}) + endif() - if (NOT "${ORTHANC_FRAMEWORK_LIBDIR}" STREQUAL "") - set(CMAKE_REQUIRED_LIBRARIES "-L${ORTHANC_FRAMEWORK_LIBDIR} -lOrthancFramework") - else() - set(CMAKE_REQUIRED_LIBRARIES "OrthancFramework") - endif() + set(CMAKE_REQUIRED_INCLUDES "${ORTHANC_FRAMEWORK_INCLUDE_DIR}") + set(CMAKE_REQUIRED_LIBRARIES "${ORTHANC_FRAMEWORK_LIBRARIES}") check_cxx_symbol_exists("Orthanc::InitializeFramework" "OrthancFramework.h" HAVE_ORTHANC_FRAMEWORK) - if(NOT HAVE_ORTHANC_FRAMEWORK) + if (NOT HAVE_ORTHANC_FRAMEWORK) message(FATAL_ERROR "Cannot find the Orthanc framework") endif() if (NOT "${ORTHANC_FRAMEWORK_ROOT}" STREQUAL "") include_directories(${ORTHANC_FRAMEWORK_ROOT}) endif() - - if (NOT "${ORTHANC_FRAMEWORK_LIBDIR}" STREQUAL "") - link_directories(${ORTHANC_FRAMEWORK_LIBDIR}) - endif() endif() diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/DicomDatasetReader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/DicomDatasetReader.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,132 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "DicomDatasetReader.h" + +#include +#include + +#include + +namespace OrthancStone +{ + DicomDatasetReader::DicomDatasetReader(const IDicomDataset& dataset) : + dataset_(dataset) + { + } + + + std::string DicomDatasetReader::GetStringValue(const DicomPath& path, + const std::string& defaultValue) const + { + std::string s; + if (dataset_.GetStringValue(s, path)) + { + return s; + } + else + { + return defaultValue; + } + } + + + std::string DicomDatasetReader::GetMandatoryStringValue(const DicomPath& path) const + { + std::string s; + if (dataset_.GetStringValue(s, path)) + { + return s; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag); + } + } + + + template + static bool GetValueInternal(T& target, + const IDicomDataset& dataset, + const DicomPath& path) + { + try + { + std::string s; + + if (dataset.GetStringValue(s, path)) + { + target = boost::lexical_cast(Orthanc::Toolbox::StripSpaces(s)); + return true; + } + else + { + return false; + } + } + catch (boost::bad_lexical_cast&) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + } + + + bool DicomDatasetReader::GetIntegerValue(int& target, + const DicomPath& path) const + { + return GetValueInternal(target, dataset_, path); + } + + + bool DicomDatasetReader::GetUnsignedIntegerValue(unsigned int& target, + const DicomPath& path) const + { + int value; + + if (!GetIntegerValue(value, path)) + { + return false; + } + else if (value >= 0) + { + target = static_cast(value); + return true; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + + bool DicomDatasetReader::GetFloatValue(float& target, + const DicomPath& path) const + { + return GetValueInternal(target, dataset_, path); + } + + + bool DicomDatasetReader::GetDoubleValue(double& target, + const DicomPath& path) const + { + return GetValueInternal(target, dataset_, path); + } +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/DicomDatasetReader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/DicomDatasetReader.h Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,61 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "IDicomDataset.h" + +#include +#include + +namespace OrthancStone +{ + class DicomDatasetReader : public boost::noncopyable + { + private: + const IDicomDataset& dataset_; + + public: + DicomDatasetReader(const IDicomDataset& dataset); + + const IDicomDataset& GetDataset() const + { + return dataset_; + } + + std::string GetStringValue(const DicomPath& path, + const std::string& defaultValue) const; + + std::string GetMandatoryStringValue(const DicomPath& path) const; + + bool GetIntegerValue(int& target, + const DicomPath& path) const; + + bool GetUnsignedIntegerValue(unsigned int& target, + const DicomPath& path) const; + + bool GetFloatValue(float& target, + const DicomPath& path) const; + + bool GetDoubleValue(double& target, + const DicomPath& path) const; + }; +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/DicomPath.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/DicomPath.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,112 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "DicomPath.h" + +#include + +#include + +namespace OrthancStone +{ + const DicomPath::Prefix& DicomPath::GetPrefixItem(size_t depth) const + { + if (depth >= prefix_.size()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + return prefix_[depth]; + } + } + + + DicomPath::Prefix& DicomPath::GetPrefixItem(size_t depth) + { + if (depth >= prefix_.size()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + return prefix_[depth]; + } + } + + + DicomPath::DicomPath(const Orthanc::DicomTag& sequence, + size_t index, + const Orthanc::DicomTag& tag) : + finalTag_(tag) + { + AddToPrefix(sequence, index); + } + + + DicomPath::DicomPath(const Orthanc::DicomTag& sequence1, + size_t index1, + const Orthanc::DicomTag& sequence2, + size_t index2, + const Orthanc::DicomTag& tag) : + finalTag_(tag) + { + AddToPrefix(sequence1, index1); + AddToPrefix(sequence2, index2); + } + + + DicomPath::DicomPath(const Orthanc::DicomTag& sequence1, + size_t index1, + const Orthanc::DicomTag& sequence2, + size_t index2, + const Orthanc::DicomTag& sequence3, + size_t index3, + const Orthanc::DicomTag& tag) : + finalTag_(tag) + { + AddToPrefix(sequence1, index1); + AddToPrefix(sequence2, index2); + AddToPrefix(sequence3, index3); + } + + + static std::string FormatHexadecimal(const Orthanc::DicomTag& tag) + { + char buf[16]; + sprintf(buf, "(%04x,%04x)", tag.GetGroup(), tag.GetElement()); + return buf; + } + + + std::string DicomPath::Format() const + { + std::string s; + + for (size_t i = 0; i < GetPrefixLength(); i++) + { + s += (FormatHexadecimal(GetPrefixTag(i)) + " / " + + boost::lexical_cast(i) + " / "); + } + + return s + FormatHexadecimal(GetFinalTag()); + } +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/DicomPath.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/DicomPath.h Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,106 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include + +#include +#include + +namespace OrthancStone +{ + class DicomPath + { + private: + typedef std::pair Prefix; + + std::vector prefix_; + Orthanc::DicomTag finalTag_; + + const Prefix& GetPrefixItem(size_t depth) const; + + Prefix& GetPrefixItem(size_t depth); + + public: + DicomPath(const Orthanc::DicomTag& finalTag) : + finalTag_(finalTag) + { + } + + DicomPath(const Orthanc::DicomTag& sequence, + size_t index, + const Orthanc::DicomTag& tag); + + DicomPath(const Orthanc::DicomTag& sequence1, + size_t index1, + const Orthanc::DicomTag& sequence2, + size_t index2, + const Orthanc::DicomTag& tag); + + DicomPath(const Orthanc::DicomTag& sequence1, + size_t index1, + const Orthanc::DicomTag& sequence2, + size_t index2, + const Orthanc::DicomTag& sequence3, + size_t index3, + const Orthanc::DicomTag& tag); + + void AddToPrefix(const Orthanc::DicomTag& tag, + size_t position) + { + prefix_.push_back(std::make_pair(tag, position)); + } + + size_t GetPrefixLength() const + { + return prefix_.size(); + } + + Orthanc::DicomTag GetPrefixTag(size_t depth) const + { + return GetPrefixItem(depth).first; + } + + size_t GetPrefixIndex(size_t depth) const + { + return GetPrefixItem(depth).second; + } + + void SetPrefixIndex(size_t depth, + size_t value) + { + GetPrefixItem(depth).second = value; + } + + const Orthanc::DicomTag& GetFinalTag() const + { + return finalTag_; + } + + void SetFinalTag(const Orthanc::DicomTag& tag) + { + finalTag_ = tag; + } + + std::string Format() const; + }; +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/FullOrthancDataset.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/FullOrthancDataset.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,203 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "FullOrthancDataset.h" + +#include + +#include +#include + +namespace OrthancStone +{ + static const Json::Value* AccessTag(const Json::Value& dataset, + const Orthanc::DicomTag& tag) + { + if (dataset.type() != Json::objectValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + + char name[16]; + sprintf(name, "%04x,%04x", tag.GetGroup(), tag.GetElement()); + + if (!dataset.isMember(name)) + { + return NULL; + } + + const Json::Value& value = dataset[name]; + if (value.type() != Json::objectValue || + !value.isMember("Name") || + !value.isMember("Type") || + !value.isMember("Value") || + value["Name"].type() != Json::stringValue || + value["Type"].type() != Json::stringValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + + return &value; + } + + + static const Json::Value& GetSequenceContent(const Json::Value& sequence) + { + assert(sequence.type() == Json::objectValue); + assert(sequence.isMember("Type")); + assert(sequence.isMember("Value")); + + const Json::Value& value = sequence["Value"]; + + if (sequence["Type"].asString() != "Sequence" || + value.type() != Json::arrayValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + else + { + return value; + } + } + + + static bool GetStringInternal(std::string& result, + const Json::Value& tag) + { + assert(tag.type() == Json::objectValue); + assert(tag.isMember("Type")); + assert(tag.isMember("Value")); + + const Json::Value& value = tag["Value"]; + + if (tag["Type"].asString() != "String" || + value.type() != Json::stringValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + else + { + result = value.asString(); + return true; + } + } + + + const Json::Value* FullOrthancDataset::LookupPath(const DicomPath& path) const + { + const Json::Value* content = &root_; + + for (unsigned int depth = 0; depth < path.GetPrefixLength(); depth++) + { + const Json::Value* sequence = AccessTag(*content, path.GetPrefixTag(depth)); + if (sequence == NULL) + { + return NULL; + } + + const Json::Value& nextContent = GetSequenceContent(*sequence); + + size_t index = path.GetPrefixIndex(depth); + if (index >= nextContent.size()) + { + return NULL; + } + else + { + content = &nextContent[static_cast(index)]; + } + } + + return AccessTag(*content, path.GetFinalTag()); + } + + + void FullOrthancDataset::CheckRoot() const + { + if (root_.type() != Json::objectValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + } + + + FullOrthancDataset::FullOrthancDataset(IOrthancConnection& orthanc, + const std::string& uri) + { + IOrthancConnection::RestApiGet(root_, orthanc, uri); + CheckRoot(); + } + + + FullOrthancDataset::FullOrthancDataset(const std::string& content) + { + IOrthancConnection::ParseJson(root_, content); + CheckRoot(); + } + + + FullOrthancDataset::FullOrthancDataset(const void* content, + size_t size) + { + IOrthancConnection::ParseJson(root_, content, size); + CheckRoot(); + } + + + FullOrthancDataset::FullOrthancDataset(const Json::Value& root) : + root_(root) + { + CheckRoot(); + } + + + bool FullOrthancDataset::GetStringValue(std::string& result, + const DicomPath& path) const + { + const Json::Value* value = LookupPath(path); + + if (value == NULL) + { + return false; + } + else + { + return GetStringInternal(result, *value); + } + } + + + bool FullOrthancDataset::GetSequenceSize(size_t& size, + const DicomPath& path) const + { + const Json::Value* sequence = LookupPath(path); + + if (sequence == NULL) + { + return false; + } + else + { + size = GetSequenceContent(*sequence).size(); + return true; + } + } +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/FullOrthancDataset.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/FullOrthancDataset.h Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,62 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "IOrthancConnection.h" +#include "IDicomDataset.h" + +#include + +namespace OrthancStone +{ + class FullOrthancDataset : public IDicomDataset + { + private: + Json::Value root_; + + const Json::Value* LookupPath(const DicomPath& path) const; + + void CheckRoot() const; + + public: + FullOrthancDataset(IOrthancConnection& orthanc, + const std::string& uri); + + FullOrthancDataset(const std::string& content); + + FullOrthancDataset(const void* content, + size_t size); + + FullOrthancDataset(const Json::Value& root); + + virtual bool GetStringValue(std::string& result, + const DicomPath& path) const; + + virtual bool GetSequenceSize(size_t& size, + const DicomPath& path) const; + + FullOrthancDataset* Clone() const + { + return new FullOrthancDataset(this->root_); + } + }; +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/IDicomDataset.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/IDicomDataset.h Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,44 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "DicomPath.h" + +#include +#include + +namespace OrthancStone +{ + class IDicomDataset : public boost::noncopyable + { + public: + virtual ~IDicomDataset() + { + } + + virtual bool GetStringValue(std::string& result, + const DicomPath& path) const = 0; + + virtual bool GetSequenceSize(size_t& size, + const DicomPath& path) const = 0; + }; +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/IOrthancConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/IOrthancConnection.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,86 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "IOrthancConnection.h" + +#include + +#include + +namespace OrthancStone +{ + void IOrthancConnection::ParseJson(Json::Value& result, + const std::string& content) + { + Json::Reader reader; + + if (!reader.parse(content, result)) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + } + + + void IOrthancConnection::ParseJson(Json::Value& result, + const void* content, + size_t size) + { + Json::Reader reader; + + if (!reader.parse(reinterpret_cast(content), + reinterpret_cast(content) + size, result)) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + } + + + void IOrthancConnection::RestApiGet(Json::Value& result, + IOrthancConnection& orthanc, + const std::string& uri) + { + std::string content; + orthanc.RestApiGet(content, uri); + ParseJson(result, content); + } + + + void IOrthancConnection::RestApiPost(Json::Value& result, + IOrthancConnection& orthanc, + const std::string& uri, + const std::string& body) + { + std::string content; + orthanc.RestApiPost(content, uri, body); + ParseJson(result, content); + } + + + void IOrthancConnection::RestApiPut(Json::Value& result, + IOrthancConnection& orthanc, + const std::string& uri, + const std::string& body) + { + std::string content; + orthanc.RestApiPut(content, uri, body); + ParseJson(result, content); + } +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/IOrthancConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/IOrthancConnection.h Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,73 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "DicomPath.h" + +#include +#include +#include + +namespace OrthancStone +{ + class IOrthancConnection : public boost::noncopyable + { + public: + virtual ~IOrthancConnection() + { + } + + virtual void RestApiGet(std::string& result, + const std::string& uri) = 0; + + virtual void RestApiPost(std::string& result, + const std::string& uri, + const std::string& body) = 0; + + virtual void RestApiPut(std::string& result, + const std::string& uri, + const std::string& body) = 0; + + virtual void RestApiDelete(const std::string& uri) = 0; + + static void ParseJson(Json::Value& result, + const std::string& content); + + static void ParseJson(Json::Value& result, + const void* content, + size_t size); + + static void RestApiGet(Json::Value& result, + IOrthancConnection& orthanc, + const std::string& uri); + + static void RestApiPost(Json::Value& result, + IOrthancConnection& orthanc, + const std::string& uri, + const std::string& body); + + static void RestApiPut(Json::Value& result, + IOrthancConnection& orthanc, + const std::string& uri, + const std::string& body); + }; +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/OrthancHttpConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/OrthancHttpConnection.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,96 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "OrthancHttpConnection.h" + +namespace OrthancStone +{ + void OrthancHttpConnection::Setup() + { + url_ = client_.GetUrl(); + + // Don't follow 3xx HTTP (avoid redirections to "unsupported.png" in Orthanc) + client_.SetRedirectionFollowed(false); + } + + + OrthancHttpConnection::OrthancHttpConnection() : + client_(Orthanc::WebServiceParameters(), "") + { + Setup(); + } + + + OrthancHttpConnection::OrthancHttpConnection(const Orthanc::WebServiceParameters& parameters) : + client_(parameters, "") + { + Setup(); + } + + + void OrthancHttpConnection::RestApiGet(std::string& result, + const std::string& uri) + { + boost::mutex::scoped_lock lock(mutex_); + + client_.SetMethod(Orthanc::HttpMethod_Get); + client_.SetUrl(url_ + uri); + client_.ApplyAndThrowException(result); + } + + + void OrthancHttpConnection::RestApiPost(std::string& result, + const std::string& uri, + const std::string& body) + { + boost::mutex::scoped_lock lock(mutex_); + + client_.SetMethod(Orthanc::HttpMethod_Post); + client_.SetUrl(url_ + uri); + client_.SetBody(body); + client_.ApplyAndThrowException(result); + } + + + void OrthancHttpConnection::RestApiPut(std::string& result, + const std::string& uri, + const std::string& body) + { + boost::mutex::scoped_lock lock(mutex_); + + client_.SetMethod(Orthanc::HttpMethod_Put); + client_.SetUrl(url_ + uri); + client_.SetBody(body); + client_.ApplyAndThrowException(result); + } + + + void OrthancHttpConnection::RestApiDelete(const std::string& uri) + { + boost::mutex::scoped_lock lock(mutex_); + + std::string result; + + client_.SetMethod(Orthanc::HttpMethod_Delete); + client_.SetUrl(url_ + uri); + client_.ApplyAndThrowException(result); + } +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/Orthanc/Stone/OrthancHttpConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Stone/OrthancHttpConnection.h Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,60 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "IOrthancConnection.h" + +#include + +#include + +namespace OrthancStone +{ + // This class is thread-safe + class OrthancHttpConnection : public IOrthancConnection + { + private: + boost::mutex mutex_; + Orthanc::HttpClient client_; + std::string url_; + + void Setup(); + + public: + OrthancHttpConnection(); + + OrthancHttpConnection(const Orthanc::WebServiceParameters& parameters); + + virtual void RestApiGet(std::string& result, + const std::string& uri); + + virtual void RestApiPost(std::string& result, + const std::string& uri, + const std::string& body); + + virtual void RestApiPut(std::string& result, + const std::string& uri, + const std::string& body); + + virtual void RestApiDelete(const std::string& uri); + }; +} diff -r fda17c92d784 -r b0bd22077cd8 Resources/SyncOrthancFolder.py --- a/Resources/SyncOrthancFolder.py Tue Jun 30 18:11:30 2020 +0200 +++ b/Resources/SyncOrthancFolder.py Wed Jul 01 17:57:38 2020 +0200 @@ -12,17 +12,30 @@ TARGET = os.path.join(os.path.dirname(__file__), 'Orthanc') PLUGIN_SDK_VERSION = '1.0.0' -REPOSITORY = 'https://hg.orthanc-server.com/orthanc/raw-file' +REPOSITORY = 'https://hg.orthanc-server.com/%s/raw-file' FILES = [ - ('OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake', '.'), - ('OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake', '.'), - ('OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake', '.'), - ('OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake', '.'), - ('OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake', '.'), - ('OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp', 'Plugins'), - ('OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h', 'Plugins'), - ('OrthancServer/Plugins/Samples/Common/OrthancPluginException.h', 'Plugins'), + ('orthanc', 'OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake', '.'), + ('orthanc', 'OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake', '.'), + ('orthanc', 'OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake', '.'), + ('orthanc', 'OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake', '.'), + ('orthanc', 'OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake', '.'), + + ('orthanc', 'OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp', 'Plugins'), + ('orthanc', 'OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h', 'Plugins'), + ('orthanc', 'OrthancServer/Plugins/Samples/Common/OrthancPluginException.h', 'Plugins'), + + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/DicomDatasetReader.cpp', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/DicomDatasetReader.h', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/DicomPath.cpp', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/DicomPath.h', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/FullOrthancDataset.cpp', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/FullOrthancDataset.h', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/IDicomDataset.h', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/IOrthancConnection.cpp', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/IOrthancConnection.h', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/OrthancHttpConnection.cpp', 'Stone'), + ('orthanc-stone', 'Framework/Toolbox/OrthancDatasets/OrthancHttpConnection.h', 'Stone'), ] SDK = [ @@ -31,9 +44,10 @@ def Download(x): - branch = x[0] - source = x[1] - target = os.path.join(TARGET, x[2]) + repository = x[0] + branch = x[1] + source = x[2] + target = os.path.join(TARGET, x[3]) print target try: @@ -41,21 +55,27 @@ except: pass - url = '%s/%s/%s' % (REPOSITORY, branch, source) + url = '%s/%s/%s' % (REPOSITORY % repository, branch, source) with open(target, 'w') as f: - f.write(urllib2.urlopen(url).read()) + try: + f.write(urllib2.urlopen(url).read()) + except: + print('ERROR: %s' % url) + raise commands = [] for f in FILES: - commands.append([ 'default', - f[0], - os.path.join(f[1], os.path.basename(f[0])) ]) + commands.append([ f[0], + 'default', + f[1], + os.path.join(f[2], os.path.basename(f[1])) ]) for f in SDK: commands.append([ + 'orthanc', 'Orthanc-%s' % PLUGIN_SDK_VERSION, 'Plugins/Include/%s' % f, 'Sdk-%s/%s' % (PLUGIN_SDK_VERSION, f) diff -r fda17c92d784 -r b0bd22077cd8 ViewerPlugin/CMakeLists.txt --- a/ViewerPlugin/CMakeLists.txt Tue Jun 30 18:11:30 2020 +0200 +++ b/ViewerPlugin/CMakeLists.txt Wed Jul 01 17:57:38 2020 +0200 @@ -146,6 +146,7 @@ set(ORTHANC_WSI_SOURCES DicomPyramidCache.cpp + OrthancPluginConnection.cpp Plugin.cpp ${ORTHANC_WSI_DIR}/Framework/DicomToolbox.cpp @@ -154,17 +155,15 @@ ${ORTHANC_WSI_DIR}/Framework/Inputs/DicomPyramid.cpp ${ORTHANC_WSI_DIR}/Framework/Inputs/DicomPyramidInstance.cpp ${ORTHANC_WSI_DIR}/Framework/Inputs/DicomPyramidLevel.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/DicomDatasetReader.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/DicomPath.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/DicomTag.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/FullOrthancDataset.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/IOrthancConnection.cpp - ${ORTHANC_WSI_DIR}/Framework/Inputs/Orthanc/OrthancPluginConnection.cpp ${ORTHANC_WSI_DIR}/Framework/Inputs/PyramidWithRawTiles.cpp ${ORTHANC_WSI_DIR}/Framework/Jpeg2000Reader.cpp ${ORTHANC_WSI_DIR}/Framework/Jpeg2000Writer.cpp - ${CMAKE_SOURCE_DIR}/../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/DicomDatasetReader.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/DicomPath.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/FullOrthancDataset.cpp + ${ORTHANC_WSI_DIR}/Resources/Orthanc/Stone/IOrthancConnection.cpp ) diff -r fda17c92d784 -r b0bd22077cd8 ViewerPlugin/DicomPyramidCache.cpp --- a/ViewerPlugin/DicomPyramidCache.cpp Tue Jun 30 18:11:30 2020 +0200 +++ b/ViewerPlugin/DicomPyramidCache.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -109,7 +109,7 @@ } - DicomPyramidCache::DicomPyramidCache(OrthancPlugins::IOrthancConnection& orthanc, + DicomPyramidCache::DicomPyramidCache(OrthancStone::IOrthancConnection& orthanc, size_t maxSize) : orthanc_(orthanc), maxSize_(maxSize) diff -r fda17c92d784 -r b0bd22077cd8 ViewerPlugin/DicomPyramidCache.h --- a/ViewerPlugin/DicomPyramidCache.h Tue Jun 30 18:11:30 2020 +0200 +++ b/ViewerPlugin/DicomPyramidCache.h Wed Jul 01 17:57:38 2020 +0200 @@ -34,10 +34,10 @@ private: typedef Orthanc::LeastRecentlyUsedIndex Cache; - boost::mutex mutex_; - OrthancPlugins::IOrthancConnection& orthanc_; - size_t maxSize_; - Cache cache_; + boost::mutex mutex_; + OrthancStone::IOrthancConnection& orthanc_; + size_t maxSize_; + Cache cache_; DicomPyramid* GetCachedPyramid(const std::string& seriesId); @@ -46,7 +46,7 @@ boost::mutex::scoped_lock& lock); public: - DicomPyramidCache(OrthancPlugins::IOrthancConnection& orthanc, + DicomPyramidCache(OrthancStone::IOrthancConnection& orthanc, size_t maxSize); ~DicomPyramidCache(); diff -r fda17c92d784 -r b0bd22077cd8 ViewerPlugin/OrthancPluginConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ViewerPlugin/OrthancPluginConnection.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,89 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "OrthancPluginConnection.h" + +#include "../../../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" + +#include + +namespace OrthancWSI +{ + void OrthancPluginConnection::RestApiGet(std::string& result, + const std::string& uri) + { + OrthancPlugins::MemoryBuffer buffer; + + if (buffer.RestApiGet(uri, false)) + { + buffer.ToString(result); + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); + } + } + + + void OrthancPluginConnection::RestApiPost(std::string& result, + const std::string& uri, + const std::string& body) + { + OrthancPlugins::MemoryBuffer buffer; + + if (buffer.RestApiPost(uri, body.c_str(), body.size(), false)) + { + buffer.ToString(result); + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); + } + } + + + void OrthancPluginConnection::RestApiPut(std::string& result, + const std::string& uri, + const std::string& body) + { + OrthancPlugins::MemoryBuffer buffer; + + if (buffer.RestApiPut(uri, body.c_str(), body.size(), false)) + { + buffer.ToString(result); + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); + } + } + + + void OrthancPluginConnection::RestApiDelete(const std::string& uri) + { + OrthancPlugins::MemoryBuffer buffer; + + if (!::OrthancPlugins::RestApiDelete(uri, false)) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); + } + } +} diff -r fda17c92d784 -r b0bd22077cd8 ViewerPlugin/OrthancPluginConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ViewerPlugin/OrthancPluginConnection.h Wed Jul 01 17:57:38 2020 +0200 @@ -0,0 +1,51 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "../Resources/Orthanc/Stone/IOrthancConnection.h" + +#include + +namespace OrthancWSI +{ + /** + * This file was originally part of the Orthanc repository, in + * releases up to 1.7.1 (in folder "Plugins/Samples/Common/"). This + * class is thread-safe. + **/ + class OrthancPluginConnection : public OrthancStone::IOrthancConnection + { + public: + virtual void RestApiGet(std::string& result, + const std::string& uri); + + virtual void RestApiPost(std::string& result, + const std::string& uri, + const std::string& body); + + virtual void RestApiPut(std::string& result, + const std::string& uri, + const std::string& body); + + virtual void RestApiDelete(const std::string& uri); + }; +} diff -r fda17c92d784 -r b0bd22077cd8 ViewerPlugin/Plugin.cpp --- a/ViewerPlugin/Plugin.cpp Tue Jun 30 18:11:30 2020 +0200 +++ b/ViewerPlugin/Plugin.cpp Wed Jul 01 17:57:38 2020 +0200 @@ -21,9 +21,9 @@ #include "../Framework/PrecompiledHeadersWSI.h" +#include "../Framework/Jpeg2000Reader.h" #include "DicomPyramidCache.h" -#include "../Framework/Jpeg2000Reader.h" -#include "../Framework/Inputs/Orthanc/OrthancPluginConnection.h" +#include "OrthancPluginConnection.h" #include #include @@ -38,9 +38,9 @@ #include -std::auto_ptr orthanc_; -std::auto_ptr cache_; -std::auto_ptr transcoderSemaphore_; +std::auto_ptr orthanc_; +std::auto_ptr cache_; +std::auto_ptr transcoderSemaphore_; static void AnswerSparseTile(OrthancPluginRestOutput* output, @@ -329,7 +329,7 @@ OrthancPluginSetDescription(context, "Provides a Web viewer of whole-slide microscopic images within Orthanc."); - orthanc_.reset(new OrthancPlugins::OrthancPluginConnection); + orthanc_.reset(new OrthancWSI::OrthancPluginConnection); cache_.reset(new OrthancWSI::DicomPyramidCache(*orthanc_, 10 /* Number of pyramids to be cached - TODO parameter */)); OrthancPluginRegisterOnChangeCallback(OrthancPlugins::GetGlobalContext(), OnChangeCallback);