# HG changeset patch # User Sebastien Jodogne # Date 1480086704 -3600 # Node ID de32f3b4ff09905063b17baafb6a5c9b4ae84d85 # Parent 037e7bc16541c055d6a696c41dad06c736769202 shared toolbox to access DICOM datasets from plugins diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/DicomDatasetReader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/DicomDatasetReader.cpp Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,122 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "DicomDatasetReader.h" + +#include "OrthancPluginCppWrapper.h" + +#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(IDicomDataset* dataset) : // takes ownership + dataset_(dataset) + { + if (dataset == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_NullPointer); + } + } + + + std::string DicomDatasetReader::GetMandatoryStringValue(const DicomPath& path) const + { + std::string s; + if (dataset_->GetStringValue(s, path)) + { + return s; + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InexistentTag); + } + } + + + int DicomDatasetReader::GetIntegerValue(const DicomPath& path) + { + try + { + std::string s = StripSpaces(GetMandatoryStringValue(path)); + return boost::lexical_cast(s); + } + catch (boost::bad_lexical_cast&) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + } + + + unsigned int DicomDatasetReader::GetUnsignedIntegerValue(const DicomPath& path) + { + int value = GetIntegerValue(path); + + if (value >= 0) + { + return static_cast(value); + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange); + } + } +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/DicomDatasetReader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/DicomDatasetReader.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,60 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "IDicomDataset.h" + +#include + +namespace OrthancPlugins +{ + class DicomDatasetReader : public boost::noncopyable + { + private: + std::auto_ptr dataset_; + + public: + DicomDatasetReader(IDicomDataset* dataset); // takes ownership + + IDicomDataset& GetDataset() const + { + return *dataset_; + } + + std::string GetMandatoryStringValue(const DicomPath& path) const; + + int GetIntegerValue(const DicomPath& path); + + unsigned int GetUnsignedIntegerValue(const DicomPath& path); + }; +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/DicomPath.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/DicomPath.cpp Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,86 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "DicomPath.h" + +#include "OrthancPluginCppWrapper.h" + +namespace OrthancPlugins +{ + const DicomPath::Prefix& DicomPath::GetPrefixItem(size_t depth) const + { + if (depth >= prefix_.size()) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_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); + } +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/DicomPath.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/DicomPath.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,107 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "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; + + 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; + } + + const DicomTag& GetFinalTag() const + { + return finalTag_; + } + + void SetFinalTag(const DicomTag& tag) + { + finalTag_ = tag; + } + }; +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/DicomTag.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/DicomTag.cpp Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,110 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "DicomTag.h" + +#include "OrthancPluginCppWrapper.h" + +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 + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_NotImplemented); + } + } +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/DicomTag.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/DicomTag.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,95 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include + +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); + } + }; + + + static const DicomTag DICOM_TAG_BITS_STORED(0x0028, 0x0101); + static const DicomTag DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021e); + static const DicomTag DICOM_TAG_COLUMNS(0x0028, 0x0011); + 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_PLANE_POSITION_SLIDE_SEQUENCE(0x0048, 0x021a); + static const DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f); + static const DicomTag DICOM_TAG_ROWS(0x0028, 0x0010); + static const DicomTag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016); + static const DicomTag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002); + 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); +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/FullOrthancDataset.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/FullOrthancDataset.cpp Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,195 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "FullOrthancDataset.h" + +#include "OrthancPluginCppWrapper.h" + +#include + +namespace OrthancPlugins +{ + void FullOrthancDataset::Parse(const std::string& source) + { + Json::Reader reader; + + if (!reader.parse(source, root_) || + root_.type() != Json::objectValue) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + } + + + static const Json::Value* AccessTag(const Json::Value& dataset, + const DicomTag& tag) + { + if (dataset.type() != Json::objectValue) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_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) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_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) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_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) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_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()); + } + + + FullOrthancDataset::FullOrthancDataset(IOrthancConnection& orthanc, + const std::string& uri) + { + std::string content; + orthanc.RestApiGet(content, uri); + Parse(content); + } + + + 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 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/FullOrthancDataset.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/FullOrthancDataset.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,66 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "IOrthancConnection.h" +#include "IDicomDataset.h" + +#include + +namespace OrthancPlugins +{ + class FullOrthancDataset : public IDicomDataset + { + private: + Json::Value root_; + + void Parse(const std::string& source); + + const Json::Value* LookupPath(const DicomPath& path) const; + + public: + FullOrthancDataset(IOrthancConnection& orthanc, + const std::string& uri); + + FullOrthancDataset(const std::string& content) + { + Parse(content); + } + + virtual bool GetStringValue(std::string& result, + const DicomPath& path) const; + + virtual bool GetSequenceSize(size_t& size, + const DicomPath& path) const; + }; +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/IDicomDataset.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/IDicomDataset.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,55 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "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 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/IOrthancConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/IOrthancConnection.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,56 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "DicomPath.h" + +#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; + }; +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/OrthancHttpConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/OrthancHttpConnection.cpp Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,82 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#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); + } +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/OrthancHttpConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/OrthancHttpConnection.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,69 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "IOrthancConnection.h" + +#if HAS_ORTHANC_EXCEPTION != 1 +# error The macro HAS_ORTHANC_EXCEPTION must be set to 1 if using this header +#endif + +#include "../../../Core/HttpClient.h" + +#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); + }; +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/OrthancPluginConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/OrthancPluginConnection.cpp Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,70 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "OrthancPluginConnection.h" + +#include "OrthancPluginCppWrapper.h" + +namespace OrthancPlugins +{ + void OrthancPluginConnection::RestApiGet(std::string& result, + const std::string& uri) + { + OrthancPlugins::MemoryBuffer buffer(context_); + + if (buffer.RestApiGet(uri, false)) + { + buffer.ToString(result); + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource); + } + } + + + void OrthancPluginConnection::RestApiPost(std::string& result, + const std::string& uri, + const std::string& body) + { + OrthancPlugins::MemoryBuffer buffer(context_); + + if (!buffer.RestApiPost(uri, body.c_str(), body.size(), false)) + { + buffer.ToString(result); + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource); + } + } +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/OrthancPluginConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/OrthancPluginConnection.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,60 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "IOrthancConnection.h" + +#include + +namespace OrthancPlugins +{ + // This class is thread-safe + class OrthancPluginConnection : public IOrthancConnection + { + private: + OrthancPluginContext* context_; + + public: + OrthancPluginConnection(OrthancPluginContext* context) : + context_(context) + { + } + + virtual void RestApiGet(std::string& result, + const std::string& uri); + + virtual void RestApiPost(std::string& result, + const std::string& uri, + const std::string& body); + }; +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/SimplifiedOrthancDataset.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,155 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "SimplifiedOrthancDataset.h" + +#include "OrthancPluginCppWrapper.h" + +#include + +namespace OrthancPlugins +{ + void SimplifiedOrthancDataset::Parse(const std::string& source) + { + Json::Reader reader; + + if (!reader.parse(source, root_) || + root_.type() != Json::objectValue) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + } + + + const Json::Value* SimplifiedOrthancDataset::LookupPath(const DicomPath& path) const + { + const Json::Value* content = &root_; + + for (unsigned int depth = 0; depth < path.GetPrefixLength(); depth++) + { + const char* name = path.GetPrefixTag(depth).GetName(); + if (content->type() != Json::objectValue) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + + if (!content->isMember(name)) + { + return NULL; + } + + const Json::Value& sequence = (*content) [name]; + if (sequence.type() != Json::arrayValue) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + + size_t index = path.GetPrefixIndex(depth); + if (index >= sequence.size()) + { + return NULL; + } + else + { + content = &sequence[static_cast(index)]; + } + } + + const char* name = path.GetFinalTag().GetName(); + + if (content->type() != Json::objectValue) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + if (!content->isMember(name)) + { + return NULL; + } + else + { + return &((*content) [name]); + } + } + + + SimplifiedOrthancDataset::SimplifiedOrthancDataset(IOrthancConnection& orthanc, + const std::string& uri) + { + std::string content; + orthanc.RestApiGet(content, uri); + Parse(content); + } + + + bool SimplifiedOrthancDataset::GetStringValue(std::string& result, + const DicomPath& path) const + { + const Json::Value* value = LookupPath(path); + + if (value == NULL) + { + return false; + } + else if (value->type() != Json::stringValue) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + else + { + result = value->asString(); + return true; + } + } + + + bool SimplifiedOrthancDataset::GetSequenceSize(size_t& size, + const DicomPath& path) const + { + const Json::Value* sequence = LookupPath(path); + + if (sequence == NULL) + { + // Inexistent path + return false; + } + else if (sequence->type() != Json::arrayValue) + { + // Not a sequence + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + else + { + size = sequence->size(); + return true; + } + } +} diff -r 037e7bc16541 -r de32f3b4ff09 Plugins/Samples/Common/SimplifiedOrthancDataset.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/SimplifiedOrthancDataset.h Fri Nov 25 16:11:44 2016 +0100 @@ -0,0 +1,66 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "IOrthancConnection.h" +#include "IDicomDataset.h" + +#include + +namespace OrthancPlugins +{ + class SimplifiedOrthancDataset : public IDicomDataset + { + private: + Json::Value root_; + + void Parse(const std::string& source); + + const Json::Value* LookupPath(const DicomPath& path) const; + + public: + SimplifiedOrthancDataset(IOrthancConnection& orthanc, + const std::string& uri); + + SimplifiedOrthancDataset(const std::string& content) + { + Parse(content); + } + + virtual bool GetStringValue(std::string& result, + const DicomPath& path) const; + + virtual bool GetSequenceSize(size_t& size, + const DicomPath& path) const; + }; +}