[med-svn] [Git][med-team/orthanc-dicomweb][upstream] New upstream version 1.2+dfsg
Sebastien Jodogne
gitlab at salsa.debian.org
Wed May 27 15:05:00 BST 2020
Sebastien Jodogne pushed to branch upstream at Debian Med / orthanc-dicomweb
Commits:
c12a0b6a by jodogne-guest at 2020-05-27T15:21:37+02:00
New upstream version 1.2+dfsg
- - - - -
22 changed files:
- .hg_archival.txt
- CMakeLists.txt
- NEWS
- Plugin/Configuration.cpp
- Plugin/Configuration.h
- Plugin/DicomWebFormatter.cpp
- Plugin/DicomWebFormatter.h
- − Plugin/GdcmParsedDicomFile.cpp
- − Plugin/GdcmParsedDicomFile.h
- Plugin/Plugin.cpp
- Plugin/QidoRs.cpp
- Plugin/StowRs.cpp
- Plugin/WadoRs.cpp
- Plugin/WadoRs.h
- Plugin/WadoRsRetrieveFrames.cpp
- − Resources/CMake/GdcmConfiguration.cmake
- Resources/Orthanc/DownloadOrthancFramework.cmake
- Resources/Orthanc/LinuxStandardBaseToolchain.cmake
- − Resources/Orthanc/Sdk-1.5.4/orthanc/OrthancCPlugin.h
- Resources/Orthanc/Sdk-1.5.7/orthanc/OrthancCPlugin.h → Resources/Orthanc/Sdk-1.7.0/orthanc/OrthancCPlugin.h
- Resources/SyncOrthancFolder.py
- Status.txt
Changes:
=====================================
.hg_archival.txt
=====================================
@@ -1,6 +1,6 @@
repo: d5f45924411123cfd02d035fd50b8e37536eadef
-node: 1e19bf059f49747d3f28ab8e3cf24607c7a64689
-branch: OrthancDicomWeb-1.1
+node: 76233f8f867fe027b31698fe8596e727d1e4dd67
+branch: OrthancDicomWeb-1.2
latesttag: null
-latesttagdistance: 380
-changessincelatesttag: 398
+latesttagdistance: 400
+changessincelatesttag: 429
=====================================
CMakeLists.txt
=====================================
@@ -21,13 +21,13 @@ cmake_minimum_required(VERSION 2.8)
project(OrthancDicomWeb)
-set(ORTHANC_DICOM_WEB_VERSION "1.1")
+set(ORTHANC_DICOM_WEB_VERSION "1.2")
if (ORTHANC_DICOM_WEB_VERSION STREQUAL "mainline")
set(ORTHANC_FRAMEWORK_DEFAULT_VERSION "mainline")
set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
else()
- set(ORTHANC_FRAMEWORK_DEFAULT_VERSION "ae0e3fd609df") # This is pre-1.6.0
+ set(ORTHANC_FRAMEWORK_DEFAULT_VERSION "1.7.0")
set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
endif()
@@ -41,9 +41,8 @@ set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if O
set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"")
# Advanced parameters to fine-tune linking against system libraries
-set(USE_SYSTEM_GDCM ON CACHE BOOL "Use the system version of Grassroot DICOM (GDCM)")
set(USE_SYSTEM_ORTHANC_SDK ON CACHE BOOL "Use the system version of the Orthanc plugin SDK")
-set(ORTHANC_SDK_VERSION "1.5.7" CACHE STRING "Version of the Orthanc plugin SDK to use, if not using the system version (can be \"1.5.4\", \"1.5.7\", or \"framework\")")
+set(ORTHANC_SDK_VERSION "1.7.0" CACHE STRING "Version of the Orthanc plugin SDK to use, if not using the system version (can be \"1.7.0\", or \"framework\")")
set(BUILD_BOOTSTRAP_VUE OFF CACHE BOOL "Compile Bootstrap-Vue from sources")
@@ -66,15 +65,12 @@ set(USE_BOOST_ICONV ON)
include(${ORTHANC_ROOT}/Resources/CMake/OrthancFrameworkConfiguration.cmake)
include_directories(${ORTHANC_ROOT})
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/GdcmConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/JavaScriptLibraries.cmake)
if (STATIC_BUILD OR NOT USE_SYSTEM_ORTHANC_SDK)
- if (ORTHANC_SDK_VERSION STREQUAL "1.5.4")
- include_directories(${CMAKE_SOURCE_DIR}/Resources/Orthanc/Sdk-1.5.4)
- elseif (ORTHANC_SDK_VERSION STREQUAL "1.5.7")
- include_directories(${CMAKE_SOURCE_DIR}/Resources/Orthanc/Sdk-1.5.7)
+ if (ORTHANC_SDK_VERSION STREQUAL "1.7.0")
+ include_directories(${CMAKE_SOURCE_DIR}/Resources/Orthanc/Sdk-1.7.0)
elseif (ORTHANC_SDK_VERSION STREQUAL "framework")
include_directories(${ORTHANC_ROOT}/Plugins/Include)
else()
@@ -146,7 +142,6 @@ add_definitions(
set(CORE_SOURCES
Plugin/Configuration.cpp
- Plugin/GdcmParsedDicomFile.cpp
${ORTHANC_ROOT}/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
${ORTHANC_CORE_SOURCES}
@@ -166,8 +161,6 @@ add_library(OrthancDicomWeb SHARED ${CORE_SOURCES}
${AUTOGENERATED_SOURCES}
)
-target_link_libraries(OrthancDicomWeb ${GDCM_LIBRARIES})
-
message("Setting the version of the library to ${ORTHANC_DICOM_WEB_VERSION}")
add_definitions(-DORTHANC_DICOM_WEB_VERSION="${ORTHANC_DICOM_WEB_VERSION}")
@@ -191,11 +184,5 @@ add_executable(UnitTests
)
target_link_libraries(UnitTests
- ${GDCM_LIBRARIES}
${GOOGLE_TEST_LIBRARIES}
)
-
-if (STATIC_BUILD OR NOT USE_SYSTEM_GDCM)
- add_dependencies(OrthancDicomWeb GDCM)
- add_dependencies(UnitTests GDCM)
-endif()
=====================================
NEWS
=====================================
@@ -2,6 +2,16 @@ Pending changes in the mainline
===============================
+
+Version 1.2 (2020-05-26)
+========================
+
+=> Minimum SDK version: 1.7.0 <=
+
+* Removed dependency on GDCM
+* "QidoCaseSensitive" defaults to "CaseSensitivePN" of Orthanc configuration (instead of "true")
+
+
Version 1.1 (2020-03-04)
========================
=====================================
Plugin/Configuration.cpp
=====================================
@@ -334,6 +334,14 @@ namespace OrthancPlugins
}
+ bool LookupBooleanValue(bool& target,
+ const std::string& key)
+ {
+ assert(configuration_.get() != NULL);
+ return configuration_->LookupBooleanValue(target, key);
+ }
+
+
unsigned int GetUnsignedIntegerValue(const std::string& key,
unsigned int defaultValue)
{
=====================================
Plugin/Configuration.h
=====================================
@@ -92,12 +92,14 @@ namespace OrthancPlugins
{
void Initialize();
- std::string GetStringValue(const std::string& key,
- const std::string& defaultValue);
-
+ bool HasKey(const std::string& key);
+
bool GetBooleanValue(const std::string& key,
bool defaultValue);
+ bool LookupBooleanValue(bool& target,
+ const std::string& key);
+
unsigned int GetUnsignedIntegerValue(const std::string& key,
unsigned int defaultValue);
=====================================
Plugin/DicomWebFormatter.cpp
=====================================
@@ -47,9 +47,10 @@ namespace OrthancPlugins
const uint32_t *levelIndex,
uint16_t tagGroup,
uint16_t tagElement,
- OrthancPluginValueRepresentation vr)
+ OrthancPluginValueRepresentation vr,
+ void* payload)
{
- const DicomWebFormatter& that = GetSingleton();
+ const DicomWebFormatter& that = *reinterpret_cast<const DicomWebFormatter*>(payload);
switch (that.mode_)
{
@@ -60,7 +61,7 @@ namespace OrthancPlugins
case OrthancPluginDicomWebBinaryMode_BulkDataUri:
{
- std::string uri = GetSingleton().bulkRoot_;
+ std::string uri = that.bulkRoot_;
for (size_t i = 0; i < levelDepth; i++)
{
@@ -77,31 +78,25 @@ namespace OrthancPlugins
}
- DicomWebFormatter::Locker::Locker(OrthancPluginDicomWebBinaryMode mode,
- const std::string& bulkRoot) :
- that_(GetSingleton()),
- lock_(that_.mutex_)
- {
- that_.mode_ = mode;
- that_.bulkRoot_ = bulkRoot;
- }
-
-
- void DicomWebFormatter::Locker::Apply(std::string& target,
- OrthancPluginContext* context,
- const void* data,
- size_t size,
- bool xml)
+ void DicomWebFormatter::Apply(std::string& target,
+ OrthancPluginContext* context,
+ const void* data,
+ size_t size,
+ bool xml,
+ OrthancPluginDicomWebBinaryMode mode,
+ const std::string& bulkRoot)
{
+ DicomWebFormatter payload(mode, bulkRoot);
+
OrthancString s;
if (xml)
{
- s.Assign(OrthancPluginEncodeDicomWebXml(context, data, size, Callback));
+ s.Assign(OrthancPluginEncodeDicomWebXml2(context, data, size, Callback, &payload));
}
else
{
- s.Assign(OrthancPluginEncodeDicomWebJson(context, data, size, Callback));
+ s.Assign(OrthancPluginEncodeDicomWebJson2(context, data, size, Callback, &payload));
}
if (s.GetContent() == NULL)
@@ -116,14 +111,16 @@ namespace OrthancPlugins
}
- void DicomWebFormatter::Locker::Apply(std::string& target,
- OrthancPluginContext* context,
- const Json::Value& value,
- bool xml)
+ void DicomWebFormatter::Apply(std::string& target,
+ OrthancPluginContext* context,
+ const Json::Value& value,
+ bool xml,
+ OrthancPluginDicomWebBinaryMode mode,
+ const std::string& bulkRoot)
{
MemoryBuffer dicom;
dicom.CreateDicom(value, OrthancPluginCreateDicomFlags_None);
- Apply(target, context, dicom.GetData(), dicom.GetSize(), xml);
+ Apply(target, context, dicom.GetData(), dicom.GetSize(), xml, mode, bulkRoot);
}
@@ -166,11 +163,8 @@ namespace OrthancPlugins
std::string item;
- {
- // TODO - Avoid a global mutex => Need to change Orthanc SDK
- OrthancPlugins::DicomWebFormatter::Locker locker(mode, bulkRoot);
- locker.Apply(item, context_, dicom, size, isXml_);
- }
+ OrthancPlugins::DicomWebFormatter::Apply(
+ item, context_, dicom, size, isXml_, mode, bulkRoot);
if (isXml_)
{
=====================================
Plugin/DicomWebFormatter.h
=====================================
@@ -29,7 +29,6 @@
#include <json/value.h>
#include <boost/noncopyable.hpp>
-#include <boost/thread/mutex.hpp>
namespace OrthancPlugins
@@ -37,16 +36,9 @@ namespace OrthancPlugins
class DicomWebFormatter : public boost::noncopyable
{
private:
- boost::mutex mutex_;
OrthancPluginDicomWebBinaryMode mode_;
std::string bulkRoot_;
- static DicomWebFormatter& GetSingleton()
- {
- static DicomWebFormatter formatter;
- return formatter;
- }
-
static void Callback(OrthancPluginDicomWebNode *node,
OrthancPluginDicomWebSetBinaryNode setter,
uint32_t levelDepth,
@@ -55,30 +47,31 @@ namespace OrthancPlugins
const uint32_t *levelIndex,
uint16_t tagGroup,
uint16_t tagElement,
- OrthancPluginValueRepresentation vr);
+ OrthancPluginValueRepresentation vr,
+ void* payload);
- public:
- class Locker : public boost::noncopyable
+ DicomWebFormatter(OrthancPluginDicomWebBinaryMode mode,
+ const std::string& bulkRoot) :
+ mode_(mode),
+ bulkRoot_(bulkRoot)
{
- private:
- DicomWebFormatter& that_;
- boost::mutex::scoped_lock lock_;
-
- public:
- Locker(OrthancPluginDicomWebBinaryMode mode,
- const std::string& bulkRoot);
-
- void Apply(std::string& target,
- OrthancPluginContext* context,
- const void* data,
- size_t size,
- bool xml);
-
- void Apply(std::string& target,
- OrthancPluginContext* context,
- const Json::Value& value,
- bool xml);
- };
+ }
+
+ public:
+ static void Apply(std::string& target,
+ OrthancPluginContext* context,
+ const void* data,
+ size_t size,
+ bool xml,
+ OrthancPluginDicomWebBinaryMode mode,
+ const std::string& bulkRoot);
+
+ static void Apply(std::string& target,
+ OrthancPluginContext* context,
+ const Json::Value& value,
+ bool xml,
+ OrthancPluginDicomWebBinaryMode mode,
+ const std::string& bulkRoot);
class HttpWriter : public boost::noncopyable
{
=====================================
Plugin/GdcmParsedDicomFile.cpp deleted
=====================================
@@ -1,435 +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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "GdcmParsedDicomFile.h"
-
-#include "ChunkedBuffer.h"
-
-#include <Core/Toolbox.h>
-
-#include <gdcmDict.h>
-#include <gdcmDictEntry.h>
-#include <gdcmDicts.h>
-#include <gdcmGlobal.h>
-#include <gdcmStringFilter.h>
-
-#include <boost/lexical_cast.hpp>
-#include <json/writer.h>
-
-
-namespace OrthancPlugins
-{
- static const gdcm::Dict* dictionary_ = NULL;
-
-
- void GdcmParsedDicomFile::Initialize()
- {
- if (dictionary_ != NULL)
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
- }
- else
- {
- dictionary_ = &gdcm::Global::GetInstance().GetDicts().GetPublicDict();
-
- if (dictionary_ == NULL)
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
- "Cannot initialize the DICOM dictionary of GDCM");
- }
- }
- }
-
-
- static std::string MyStripSpaces(const std::string& source)
- {
- size_t first = 0;
-
- while (first < source.length() &&
- (isspace(source[first]) ||
- source[first] == '\0'))
- {
- first++;
- }
-
- if (first == source.length())
- {
- // String containing only spaces
- return "";
- }
-
- size_t last = source.length();
- while (last > first &&
- (isspace(source[last - 1]) ||
- source[last - 1] == '\0'))
- {
- last--;
- }
-
- assert(first <= last);
- return source.substr(first, last - first);
- }
-
-
- static const char* GetVRName(bool& isSequence,
- const gdcm::Tag& tag,
- gdcm::VR vr)
- {
- if (dictionary_ == NULL)
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls,
- "GDCM has not been initialized");
- }
-
- if (vr == gdcm::VR::INVALID)
- {
- const gdcm::DictEntry &entry = dictionary_->GetDictEntry(tag);
- vr = entry.GetVR();
-
- if (vr == gdcm::VR::OB_OW)
- {
- vr = gdcm::VR::OB;
- }
- }
-
- isSequence = (vr == gdcm::VR::SQ);
-
- const char* str = gdcm::VR::GetVRString(vr);
- if (isSequence)
- {
- return str;
- }
-
- if (str == NULL ||
- strlen(str) != 2 ||
- !(str[0] >= 'A' && str[0] <= 'Z') ||
- !(str[1] >= 'A' && str[1] <= 'Z'))
- {
- return "UN";
- }
- else
- {
- return str;
- }
- }
-
-
- static const char* GetVRName(bool& isSequence,
- const gdcm::DataElement& element)
- {
- return GetVRName(isSequence, element.GetTag(), element.GetVR());
- }
-
-
- template <int T>
- static void ConvertNumberTag(std::string& target,
- const gdcm::DataElement& source)
- {
- if (source.IsEmpty())
- {
- target.clear();
- }
- else
- {
- typename gdcm::Element<T, gdcm::VM::VM1_n> element;
-
- element.Set(source.GetValue());
-
- for (unsigned int i = 0; i < element.GetLength(); i++)
- {
- if (i != 0)
- {
- target += "\\";
- }
-
- target = boost::lexical_cast<std::string>(element.GetValue());
- }
- }
- }
-
-
- static bool ConvertDicomStringToUtf8(std::string& result,
- const gdcm::DataElement& element,
- const Orthanc::Encoding sourceEncoding)
- {
- const gdcm::ByteValue* data = element.GetByteValue();
- if (!data)
- {
- return false;
- }
-
- bool isSequence;
- std::string vr = GetVRName(isSequence, element);
-
- if (!isSequence)
- {
- if (vr == "FL")
- {
- ConvertNumberTag<gdcm::VR::FL>(result, element);
- return true;
- }
- else if (vr == "FD")
- {
- ConvertNumberTag<gdcm::VR::FD>(result, element);
- return true;
- }
- else if (vr == "SL")
- {
- ConvertNumberTag<gdcm::VR::SL>(result, element);
- return true;
- }
- else if (vr == "SS")
- {
- ConvertNumberTag<gdcm::VR::SS>(result, element);
- return true;
- }
- else if (vr == "UL")
- {
- ConvertNumberTag<gdcm::VR::UL>(result, element);
- return true;
- }
- else if (vr == "US")
- {
- ConvertNumberTag<gdcm::VR::US>(result, element);
- return true;
- }
- }
-
- if (sourceEncoding == Orthanc::Encoding_Utf8)
- {
- result.assign(data->GetPointer(), data->GetLength());
- }
- else
- {
- std::string tmp(data->GetPointer(), data->GetLength());
- result = Orthanc::Toolbox::ConvertToUtf8(tmp, sourceEncoding, false);
- }
-
- result = MyStripSpaces(result);
- return true;
- }
-
-
-
- void GdcmParsedDicomFile::Setup(const std::string& dicom)
- {
- // Prepare a memory stream over the DICOM instance
- std::stringstream stream(dicom);
-
- // Parse the DICOM instance using GDCM
- reader_.SetStream(stream);
-
- if (!reader_.Read())
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
- "GDCM cannot decode this DICOM instance of length " +
- boost::lexical_cast<std::string>(dicom.size()));
- }
- }
-
-
- GdcmParsedDicomFile::GdcmParsedDicomFile(const OrthancPlugins::MemoryBuffer& buffer)
- {
- // TODO Avoid this unnecessary memcpy by defining a stream over the MemoryBuffer
- std::string dicom(buffer.GetData(), buffer.GetData() + buffer.GetSize());
- Setup(dicom);
- }
-
-
- static bool GetRawTag(std::string& result,
- const gdcm::DataSet& dataset,
- const gdcm::Tag& tag,
- bool stripSpaces)
- {
- if (dataset.FindDataElement(tag))
- {
- const gdcm::ByteValue* value = dataset.GetDataElement(tag).GetByteValue();
- if (value)
- {
- result.assign(value->GetPointer(), value->GetLength());
-
- if (stripSpaces)
- {
- result = MyStripSpaces(result);
- }
-
- return true;
- }
- }
-
- return false;
- }
-
-
- bool GdcmParsedDicomFile::GetRawTag(std::string& result,
- const gdcm::Tag& tag,
- bool stripSpaces) const
- {
- return OrthancPlugins::GetRawTag(result, GetDataSet(), tag, stripSpaces);
- }
-
-
- std::string GdcmParsedDicomFile::GetRawTagWithDefault(const gdcm::Tag& tag,
- const std::string& defaultValue,
- bool stripSpaces) const
- {
- std::string result;
- if (!GetRawTag(result, tag, stripSpaces))
- {
- return defaultValue;
- }
- else
- {
- return result;
- }
- }
-
-
- std::string GdcmParsedDicomFile::GetRawTagWithDefault(const Orthanc::DicomTag& tag,
- const std::string& defaultValue,
- bool stripSpaces) const
- {
- gdcm::Tag t(tag.GetGroup(), tag.GetElement());
- return GetRawTagWithDefault(t, defaultValue, stripSpaces);
- }
-
-
- bool GdcmParsedDicomFile::GetStringTag(std::string& result,
- const gdcm::Tag& tag,
- bool stripSpaces) const
- {
- if (!GetDataSet().FindDataElement(tag))
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
- }
-
- const gdcm::DataElement& element = GetDataSet().GetDataElement(tag);
-
- if (!ConvertDicomStringToUtf8(result, element, GetEncoding()))
- {
- return false;
- }
-
- if (stripSpaces)
- {
- result = MyStripSpaces(result);
- }
-
- return true;
- }
-
-
- bool GdcmParsedDicomFile::GetIntegerTag(int& result,
- const gdcm::Tag& tag) const
- {
- std::string tmp;
- if (!GetStringTag(tmp, tag, true))
- {
- return false;
- }
-
- try
- {
- result = boost::lexical_cast<int>(tmp);
- return true;
- }
- catch (boost::bad_lexical_cast&)
- {
- return false;
- }
- }
-
-
- std::string FormatTag(const gdcm::Tag& tag)
- {
- char tmp[16];
- sprintf(tmp, "%04X%04X", tag.GetGroup(), tag.GetElement());
- return std::string(tmp);
- }
-
-
- static std::string GetWadoUrl(const std::string& wadoBase,
- const gdcm::DataSet& dicom)
- {
- static const gdcm::Tag DICOM_TAG_STUDY_INSTANCE_UID(0x0020, 0x000d);
- static const gdcm::Tag DICOM_TAG_SERIES_INSTANCE_UID(0x0020, 0x000e);
- static const gdcm::Tag DICOM_TAG_SOP_INSTANCE_UID(0x0008, 0x0018);
-
- std::string study, series, instance;
-
- if (!GetRawTag(study, dicom, DICOM_TAG_STUDY_INSTANCE_UID, true) ||
- !GetRawTag(series, dicom, DICOM_TAG_SERIES_INSTANCE_UID, true) ||
- !GetRawTag(instance, dicom, DICOM_TAG_SOP_INSTANCE_UID, true))
- {
- return "";
- }
- else
- {
- return Configuration::GetWadoUrl(wadoBase, study, series, instance);
- }
- }
-
-
- static Orthanc::Encoding DetectEncoding(const gdcm::DataSet& dicom)
- {
- static const gdcm::Tag DICOM_TAG_SPECIFIC_CHARACTER_SET(0x0008, 0x0005);
-
- if (!dicom.FindDataElement(DICOM_TAG_SPECIFIC_CHARACTER_SET))
- {
- return Orthanc::Encoding_Ascii;
- }
-
- const gdcm::DataElement& element =
- dicom.GetDataElement(DICOM_TAG_SPECIFIC_CHARACTER_SET);
-
- const gdcm::ByteValue* data = element.GetByteValue();
- if (!data)
- {
- return Configuration::GetDefaultEncoding();
- }
-
- std::string tmp(data->GetPointer(), data->GetLength());
- tmp = MyStripSpaces(tmp);
-
- Orthanc::Encoding encoding;
- if (Orthanc::GetDicomEncoding(encoding, tmp.c_str()))
- {
- return encoding;
- }
- else
- {
- return Configuration::GetDefaultEncoding();
- }
- }
-
-
- Orthanc::Encoding GdcmParsedDicomFile::GetEncoding() const
- {
- return DetectEncoding(GetDataSet());
- }
-
-
- std::string GdcmParsedDicomFile::GetWadoUrl(const OrthancPluginHttpRequest* request) const
- {
- const std::string base = OrthancPlugins::Configuration::GetBaseUrl(request);
- return OrthancPlugins::GetWadoUrl(base, GetDataSet());
- }
-}
=====================================
Plugin/GdcmParsedDicomFile.h deleted
=====================================
@@ -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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "Configuration.h"
-
-#include <Core/ChunkedBuffer.h>
-#include <Core/Enumerations.h>
-#include <Core/DicomFormat/DicomTag.h>
-#include <Plugins/Samples/Common/OrthancPluginCppWrapper.h>
-
-#include <gdcmReader.h>
-#include <gdcmDataSet.h>
-#include <pugixml.hpp>
-#include <list>
-
-
-namespace OrthancPlugins
-{
- class GdcmParsedDicomFile : public boost::noncopyable
- {
- private:
- gdcm::Reader reader_;
-
- void Setup(const std::string& dicom);
-
- Orthanc::Encoding GetEncoding() const;
-
- public:
- static void Initialize();
-
- explicit GdcmParsedDicomFile(const OrthancPlugins::MemoryBuffer& item);
-
- explicit GdcmParsedDicomFile(const std::string& dicom)
- {
- Setup(dicom);
- }
-
- const gdcm::File& GetFile() const
- {
- return reader_.GetFile();
- }
-
- const gdcm::DataSet& GetDataSet() const
- {
- return reader_.GetFile().GetDataSet();
- }
-
- bool GetRawTag(std::string& result,
- const gdcm::Tag& tag,
- bool stripSpaces) const;
-
- std::string GetRawTagWithDefault(const gdcm::Tag& tag,
- const std::string& defaultValue,
- bool stripSpaces) const;
-
- std::string GetRawTagWithDefault(const Orthanc::DicomTag& tag,
- const std::string& defaultValue,
- bool stripSpaces) const;
-
- bool GetStringTag(std::string& result,
- const gdcm::Tag& tag,
- bool stripSpaces) const;
-
- bool GetIntegerTag(int& result,
- const gdcm::Tag& tag) const;
-
- std::string GetWadoUrl(const OrthancPluginHttpRequest* request) const;
- };
-}
=====================================
Plugin/Plugin.cpp
=====================================
@@ -20,7 +20,6 @@
#include "DicomWebClient.h"
#include "DicomWebServers.h"
-#include "GdcmParsedDicomFile.h"
#include "QidoRs.h"
#include "StowRs.h"
#include "WadoRs.h"
@@ -483,9 +482,6 @@ extern "C"
// Read the configuration
OrthancPlugins::Configuration::Initialize();
- // Initialize GDCM
- OrthancPlugins::GdcmParsedDicomFile::Initialize();
-
// Configure the DICOMweb callbacks
if (OrthancPlugins::Configuration::GetBooleanValue("Enable", true))
{
@@ -513,8 +509,8 @@ extern "C"
OrthancPlugins::RegisterRestCallback<RetrieveBulkData>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/bulk/(.*)", true);
OrthancPlugins::RegisterRestCallback<RetrieveInstanceMetadata>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/metadata", true);
OrthancPlugins::RegisterRestCallback<RetrieveSeriesMetadata>(root + "studies/([^/]*)/series/([^/]*)/metadata", true);
- OrthancPlugins::RegisterRestCallback<RetrieveFrames>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/frames", true);
- OrthancPlugins::RegisterRestCallback<RetrieveFrames>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/frames/([^/]*)", true);
+ OrthancPlugins::RegisterRestCallback<RetrieveAllFrames>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/frames", true);
+ OrthancPlugins::RegisterRestCallback<RetrieveSelectedFrames>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/frames/([^/]*)", true);
OrthancPlugins::RegisterRestCallback<ListServers>(root + "servers", true);
OrthancPlugins::RegisterRestCallback<ListServerOperations>(root + "servers/([^/]*)", true);
=====================================
Plugin/QidoRs.cpp
=====================================
@@ -265,8 +265,13 @@ namespace
throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
}
+ bool caseSensitive;
+ if (OrthancPlugins::Configuration::LookupBooleanValue(caseSensitive, "QidoCaseSensitive"))
+ {
+ result["CaseSensitive"] = caseSensitive;
+ }
+
result["Expand"] = false;
- result["CaseSensitive"] = OrthancPlugins::Configuration::GetBooleanValue("QidoCaseSensitive", true);
result["Query"] = Json::objectValue;
result["Limit"] = limit_;
result["Since"] = offset_;
@@ -483,6 +488,8 @@ static void ApplyMatcher(OrthancPluginRestOutput* output,
Json::Value find;
matcher.ConvertToOrthanc(find, level);
+ LOG(INFO) << "Body of the call from QIDO-RS to /tools/find: " << find.toStyledString();
+
std::string body;
{
=====================================
Plugin/StowRs.cpp
=====================================
@@ -191,10 +191,8 @@ namespace OrthancPlugins
std::string answer;
- {
- DicomWebFormatter::Locker locker(OrthancPluginDicomWebBinaryMode_Ignore, "");
- locker.Apply(answer, context_, result_, xml_);
- }
+ DicomWebFormatter::Apply(answer, context_, result_, xml_,
+ OrthancPluginDicomWebBinaryMode_Ignore, "");
OrthancPluginAnswerBuffer(context_, output, answer.c_str(), answer.size(),
xml_ ? "application/dicom+xml" : "application/dicom+json");
=====================================
Plugin/WadoRs.cpp
=====================================
@@ -692,9 +692,9 @@ static void WriteInstanceMetadata(OrthancPlugins::DicomWebFormatter::HttpWriter&
std::string dicomweb;
{
// TODO - Avoid a global mutex => Need to change Orthanc SDK
- OrthancPlugins::DicomWebFormatter::Locker locker(OrthancPluginDicomWebBinaryMode_Ignore, "");
- locker.Apply(dicomweb, OrthancPlugins::GetGlobalContext(),
- buffer.GetData(), buffer.GetSize(), false /* JSON */);
+ OrthancPlugins::DicomWebFormatter::Apply(
+ dicomweb, OrthancPlugins::GetGlobalContext(), buffer.GetData(), buffer.GetSize(),
+ false /* JSON */, OrthancPluginDicomWebBinaryMode_Ignore, "");
}
buffer.RestApiPut("/instances/" + orthancId + "/attachments/4444", dicomweb, false);
=====================================
Plugin/WadoRs.h
=====================================
@@ -70,9 +70,13 @@ void RetrieveBulkData(OrthancPluginRestOutput* output,
const char* url,
const OrthancPluginHttpRequest* request);
-void RetrieveFrames(OrthancPluginRestOutput* output,
- const char* url,
- const OrthancPluginHttpRequest* request);
+void RetrieveAllFrames(OrthancPluginRestOutput* output,
+ const char* url,
+ const OrthancPluginHttpRequest* request);
+
+void RetrieveSelectedFrames(OrthancPluginRestOutput* output,
+ const char* url,
+ const OrthancPluginHttpRequest* request);
void RetrieveInstanceRendered(OrthancPluginRestOutput* output,
const char* url,
=====================================
Plugin/WadoRsRetrieveFrames.cpp
=====================================
@@ -21,21 +21,15 @@
#include "WadoRs.h"
-#include "GdcmParsedDicomFile.h"
-
#include <Core/Toolbox.h>
#include <Plugins/Samples/Common/OrthancPluginCppWrapper.h>
#include <memory>
#include <list>
-#include <gdcmImageReader.h>
-#include <gdcmImageWriter.h>
-#include <gdcmImageChangeTransferSyntax.h>
#include <boost/algorithm/string/replace.hpp>
#include <boost/lexical_cast.hpp>
-
static void TokenizeAndNormalize(std::vector<std::string>& tokens,
const std::string& source,
char separator)
@@ -62,8 +56,8 @@ static void RemoveSurroundingQuotes(std::string& value)
-static gdcm::TransferSyntax ParseTransferSyntax(const OrthancPluginHttpRequest* request,
- gdcm::TransferSyntax sourceTransferSyntax)
+static bool ParseTransferSyntax(Orthanc::DicomTransferSyntax& syntax,
+ const OrthancPluginHttpRequest* request)
{
for (uint32_t i = 0; i < request->headersCount; i++)
{
@@ -78,7 +72,8 @@ static gdcm::TransferSyntax ParseTransferSyntax(const OrthancPluginHttpRequest*
if (tokens.size() == 0 ||
tokens[0] == "*/*")
{
- return gdcm::TransferSyntax::ExplicitVRLittleEndian;
+ syntax = Orthanc::DicomTransferSyntax_LittleEndianExplicit;
+ return true;
}
if (tokens[0] != "multipart/related")
@@ -114,14 +109,21 @@ static gdcm::TransferSyntax ParseTransferSyntax(const OrthancPluginHttpRequest*
if (type == "application/octet-stream")
{
- if (transferSyntax.empty())
+ if (transferSyntax.empty() ||
+ transferSyntax == "1.2.840.10008.1.2.1")
{
- return gdcm::TransferSyntax(gdcm::TransferSyntax::ExplicitVRLittleEndian);
+ syntax = Orthanc::DicomTransferSyntax_LittleEndianExplicit;
+ return true;
+ }
+ else if (transferSyntax == "1.2.840.10008.1.2")
+ {
+ syntax = Orthanc::DicomTransferSyntax_LittleEndianImplicit;
+ return true;
}
else if (transferSyntax == "*")
{
// New in DICOMweb plugin 1.1.0
- return sourceTransferSyntax;
+ return false;
}
else
{
@@ -140,51 +142,62 @@ static gdcm::TransferSyntax ParseTransferSyntax(const OrthancPluginHttpRequest*
if (type == "image/jpeg" && (transferSyntax.empty() || // Default
transferSyntax == "1.2.840.10008.1.2.4.70"))
{
- return gdcm::TransferSyntax::JPEGLosslessProcess14_1;
+ syntax = Orthanc::DicomTransferSyntax_JPEGProcess14SV1;
+ return true;
}
else if (type == "image/jpeg" && transferSyntax == "1.2.840.10008.1.2.4.50")
{
- return gdcm::TransferSyntax::JPEGBaselineProcess1;
+ syntax = Orthanc::DicomTransferSyntax_JPEGProcess1;
+ return true;
}
else if (type == "image/jpeg" && transferSyntax == "1.2.840.10008.1.2.4.51")
{
- return gdcm::TransferSyntax::JPEGExtendedProcess2_4;
+ syntax = Orthanc::DicomTransferSyntax_JPEGProcess2_4;
+ return true;
}
else if (type == "image/jpeg" && transferSyntax == "1.2.840.10008.1.2.4.57")
{
- return gdcm::TransferSyntax::JPEGLosslessProcess14;
+ syntax = Orthanc::DicomTransferSyntax_JPEGProcess14;
+ return true;
}
else if (type == "image/x-dicom-rle" && (transferSyntax.empty() || // Default
transferSyntax == "1.2.840.10008.1.2.5"))
{
- return gdcm::TransferSyntax::RLELossless;
+ syntax = Orthanc::DicomTransferSyntax_RLELossless;
+ return true;
}
else if (type == "image/x-jls" && (transferSyntax.empty() || // Default
transferSyntax == "1.2.840.10008.1.2.4.80"))
{
- return gdcm::TransferSyntax::JPEGLSLossless;
+ syntax = Orthanc::DicomTransferSyntax_JPEGLSLossless;
+ return true;
}
else if (type == "image/x-jls" && transferSyntax == "1.2.840.10008.1.2.4.81")
{
- return gdcm::TransferSyntax::JPEGLSNearLossless;
+ syntax = Orthanc::DicomTransferSyntax_JPEGLSLossy;
+ return true;
}
else if (type == "image/jp2" && (transferSyntax.empty() || // Default
transferSyntax == "1.2.840.10008.1.2.4.90"))
{
- return gdcm::TransferSyntax::JPEG2000Lossless;
+ syntax = Orthanc::DicomTransferSyntax_JPEG2000LosslessOnly;
+ return true;
}
else if (type == "image/jp2" && transferSyntax == "1.2.840.10008.1.2.4.91")
{
- return gdcm::TransferSyntax::JPEG2000;
+ syntax = Orthanc::DicomTransferSyntax_JPEG2000;
+ return true;
}
else if (type == "image/jpx" && (transferSyntax.empty() || // Default
transferSyntax == "1.2.840.10008.1.2.4.92"))
{
- return gdcm::TransferSyntax::JPEG2000Part2Lossless;
+ syntax = Orthanc::DicomTransferSyntax_JPEG2000MulticomponentLosslessOnly;
+ return true;
}
else if (type == "image/jpx" && transferSyntax == "1.2.840.10008.1.2.4.93")
{
- return gdcm::TransferSyntax::JPEG2000Part2;
+ syntax = Orthanc::DicomTransferSyntax_JPEG2000Multicomponent;
+ return true;
}
@@ -194,52 +207,63 @@ static gdcm::TransferSyntax ParseTransferSyntax(const OrthancPluginHttpRequest*
**/
if (type == "image/dicom+jpeg" && transferSyntax == "1.2.840.10008.1.2.4.50")
{
- return gdcm::TransferSyntax::JPEGBaselineProcess1;
+ syntax = Orthanc::DicomTransferSyntax_JPEGProcess1;
+ return true;
}
else if (type == "image/dicom+jpeg" && transferSyntax == "1.2.840.10008.1.2.4.51")
{
- return gdcm::TransferSyntax::JPEGExtendedProcess2_4;
+ syntax = Orthanc::DicomTransferSyntax_JPEGProcess2_4;
+ return true;
}
else if (type == "image/dicom+jpeg" && transferSyntax == "1.2.840.10008.1.2.4.57")
{
- return gdcm::TransferSyntax::JPEGLosslessProcess14;
+ syntax = Orthanc::DicomTransferSyntax_JPEGProcess14;
+ return true;
}
else if (type == "image/dicom+jpeg" && (transferSyntax.empty() ||
transferSyntax == "1.2.840.10008.1.2.4.70"))
{
- return gdcm::TransferSyntax::JPEGLosslessProcess14_1;
+ syntax = Orthanc::DicomTransferSyntax_JPEGProcess14SV1;
+ return true;
}
else if (type == "image/dicom+rle" && (transferSyntax.empty() ||
transferSyntax == "1.2.840.10008.1.2.5"))
{
- return gdcm::TransferSyntax::RLELossless;
+ syntax = Orthanc::DicomTransferSyntax_RLELossless;
+ return true;
}
else if (type == "image/dicom+jpeg-ls" && (transferSyntax.empty() ||
transferSyntax == "1.2.840.10008.1.2.4.80"))
{
- return gdcm::TransferSyntax::JPEGLSLossless;
+ syntax = Orthanc::DicomTransferSyntax_JPEGLSLossless;
+ return true;
}
else if (type == "image/dicom+jpeg-ls" && transferSyntax == "1.2.840.10008.1.2.4.81")
{
- return gdcm::TransferSyntax::JPEGLSNearLossless;
+ syntax = Orthanc::DicomTransferSyntax_JPEGLSLossy;
+ return true;
}
else if (type == "image/dicom+jp2" && (transferSyntax.empty() ||
transferSyntax == "1.2.840.10008.1.2.4.90"))
{
- return gdcm::TransferSyntax::JPEG2000Lossless;
+ syntax = Orthanc::DicomTransferSyntax_JPEG2000LosslessOnly;
+ return true;
}
else if (type == "image/dicom+jp2" && transferSyntax == "1.2.840.10008.1.2.4.91")
{
- return gdcm::TransferSyntax::JPEG2000;
+ syntax = Orthanc::DicomTransferSyntax_JPEG2000;
+ return true;
}
else if (type == "image/dicom+jpx" && (transferSyntax.empty() ||
transferSyntax == "1.2.840.10008.1.2.4.92"))
{
- return gdcm::TransferSyntax::JPEG2000Part2Lossless;
+ syntax = Orthanc::DicomTransferSyntax_JPEG2000MulticomponentLosslessOnly;
+ return true;
}
else if (type == "image/dicom+jpx" && transferSyntax == "1.2.840.10008.1.2.4.93")
{
- return gdcm::TransferSyntax::JPEG2000Part2;
+ syntax = Orthanc::DicomTransferSyntax_JPEG2000Multicomponent;
+ return true;
}
throw Orthanc::OrthancException(
@@ -251,7 +275,8 @@ static gdcm::TransferSyntax ParseTransferSyntax(const OrthancPluginHttpRequest*
}
// By default, DICOMweb expectes Little Endian uncompressed pixel data
- return gdcm::TransferSyntax::ExplicitVRLittleEndian;
+ syntax = Orthanc::DicomTransferSyntax_LittleEndianExplicit;
+ return true;
}
@@ -287,52 +312,51 @@ static void ParseFrameList(std::list<unsigned int>& frames,
}
-
-static const char* GetMimeType(const gdcm::TransferSyntax& syntax)
+static const char* GetMimeType(const Orthanc::DicomTransferSyntax& syntax)
{
// http://dicom.nema.org/medical/dicom/current/output/html/part18.html#table_6.1.1.8-3b
// http://dicom.nema.org/MEDICAL/dicom/2019a/output/chtml/part18/chapter_6.html#table_6.1.1.8-3b
switch (syntax)
{
- case gdcm::TransferSyntax::ImplicitVRLittleEndian:
+ case Orthanc::DicomTransferSyntax_LittleEndianImplicit:
// The "transfer-syntax" info was added in version 1.1 of the plugin
return "application/octet-stream; transfer-syntax=1.2.840.10008.1.2";
- case gdcm::TransferSyntax::ExplicitVRLittleEndian:
+ case Orthanc::DicomTransferSyntax_LittleEndianExplicit:
return "application/octet-stream; transfer-syntax=1.2.840.10008.1.2.1";
- case gdcm::TransferSyntax::JPEGBaselineProcess1:
+ case Orthanc::DicomTransferSyntax_JPEGProcess1:
return "image/jpeg; transfer-syntax=1.2.840.10008.1.2.4.50";
- case gdcm::TransferSyntax::JPEGExtendedProcess2_4:
+ case Orthanc::DicomTransferSyntax_JPEGProcess2_4:
return "image/jpeg; transfer-syntax=1.2.840.10008.1.2.4.51";
- case gdcm::TransferSyntax::JPEGLosslessProcess14:
+ case Orthanc::DicomTransferSyntax_JPEGProcess14:
return "image/jpeg; transfer-syntax=1.2.840.10008.1.2.4.57";
- case gdcm::TransferSyntax::JPEGLosslessProcess14_1:
- return "image/jpeg; transferSyntax=1.2.840.10008.1.2.4.70";
+ case Orthanc::DicomTransferSyntax_JPEGProcess14SV1:
+ return "image/jpeg; transfer-syntax=1.2.840.10008.1.2.4.70";
- case gdcm::TransferSyntax::RLELossless:
- return "image/x-dicom-rle; transferSyntax=1.2.840.10008.1.2.5";
+ case Orthanc::DicomTransferSyntax_RLELossless:
+ return "image/x-dicom-rle; transfer-syntax=1.2.840.10008.1.2.5";
- case gdcm::TransferSyntax::JPEGLSLossless:
- return "image/x-jls; transferSyntax=1.2.840.10008.1.2.4.80";
+ case Orthanc::DicomTransferSyntax_JPEGLSLossless:
+ return "image/x-jls; transfer-syntax=1.2.840.10008.1.2.4.80";
- case gdcm::TransferSyntax::JPEGLSNearLossless:
+ case Orthanc::DicomTransferSyntax_JPEGLSLossy:
return "image/x-jls; transfer-syntax=1.2.840.10008.1.2.4.81";
- case gdcm::TransferSyntax::JPEG2000Lossless:
- return "image/jp2; transferSyntax=1.2.840.10008.1.2.4.90";
+ case Orthanc::DicomTransferSyntax_JPEG2000LosslessOnly:
+ return "image/jp2; transfer-syntax=1.2.840.10008.1.2.4.90";
- case gdcm::TransferSyntax::JPEG2000:
+ case Orthanc::DicomTransferSyntax_JPEG2000:
return "image/jp2; transfer-syntax=1.2.840.10008.1.2.4.91";
- case gdcm::TransferSyntax::JPEG2000Part2Lossless:
- return "image/jpx; transferSyntax=1.2.840.10008.1.2.4.92";
+ case Orthanc::DicomTransferSyntax_JPEG2000MulticomponentLosslessOnly:
+ return "image/jpx; transfer-syntax=1.2.840.10008.1.2.4.92";
- case gdcm::TransferSyntax::JPEG2000Part2:
+ case Orthanc::DicomTransferSyntax_JPEG2000Multicomponent:
return "image/jpx; transfer-syntax=1.2.840.10008.1.2.4.93";
default:
@@ -341,278 +365,70 @@ static const char* GetMimeType(const gdcm::TransferSyntax& syntax)
}
-
-static void ConvertYbrToRgb(uint8_t rgb[3],
- const uint8_t ybr[3])
-{
- // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2
- // https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion
-
- const float Y = ybr[0];
- const float Cb = ybr[1];
- const float Cr = ybr[2];
-
- const float result[3] = {
- Y + 1.402f * (Cr - 128.0f),
- Y - 0.344136f * (Cb - 128.0f) - 0.714136f * (Cr - 128.0f),
- Y + 1.772f * (Cb - 128.0f)
- };
-
- for (uint8_t i = 0; i < 3 ; i++)
- {
- if (result[i] < 0)
- {
- rgb[i] = 0;
- }
- else if (result[i] > 255)
- {
- rgb[i] = 255;
- }
- else
- {
- rgb[i] = static_cast<uint8_t>(result[i]);
- }
- }
-}
-
-
-static void AnswerSingleFrame(OrthancPluginRestOutput* output,
- const OrthancPluginHttpRequest* request,
- const OrthancPlugins::GdcmParsedDicomFile& dicom,
- const char* frame,
- size_t size,
- unsigned int frameIndex,
- bool convertYbr)
-{
- /**
- * Fix the photometric interpretation, typically needed for some
- * multiframe US images (as the one in issue 164). Also check out
- * the "Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp" file in
- * the source distribution of Orthanc, and Osimis issue WVB-319
- * ("Some images are not loading in US_MF").
- **/
-
- std::vector<uint8_t> copied; // Don't move this variable inside the
- // "if", as "frame" might point to it
-
- if (convertYbr &&
- size > 0)
- {
- copied.resize(size);
- memcpy(&copied[0], frame, size);
-
- uint8_t *p = &copied[0];
- for (size_t i = 0; i < size / 3; i++)
- {
- uint8_t ybr[3], rgb[3];
- ybr[0] = p[0];
- ybr[1] = p[1];
- ybr[2] = p[2];
-
- ConvertYbrToRgb(rgb, ybr);
- p[0] = rgb[0];
- p[1] = rgb[1];
- p[2] = rgb[2];
-
- p += 3;
- }
-
- frame = reinterpret_cast<const char*>(&copied[0]);
- }
-
-
- OrthancPluginErrorCode error;
-
-#if HAS_SEND_MULTIPART_ITEM_2 == 1
- std::string location = dicom.GetWadoUrl(request) + "frames/" + boost::lexical_cast<std::string>(frameIndex + 1);
- const char *keys[] = { "Content-Location" };
- const char *values[] = { location.c_str() };
- error = OrthancPluginSendMultipartItem2(OrthancPlugins::GetGlobalContext(), output, frame, size, 1, keys, values);
-#else
- error = OrthancPluginSendMultipartItem(OrthancPlugins::GetGlobalContext(), output, frame, size);
-#endif
-
- if (error != OrthancPluginErrorCode_Success)
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
- }
-}
-
-
-static bool AnswerFrames(OrthancPluginRestOutput* output,
+static void AnswerFrames(OrthancPluginRestOutput* output,
const OrthancPluginHttpRequest* request,
- const OrthancPlugins::GdcmParsedDicomFile& dicom,
- const gdcm::TransferSyntax& syntax,
- std::list<unsigned int>& frames)
+ const OrthancPlugins::DicomInstance& instance,
+ const std::string& studyInstanceUid,
+ const std::string& seriesInstanceUid,
+ const std::string& sopInstanceUid,
+ const std::list<unsigned int>& frames,
+ Orthanc::DicomTransferSyntax outputSyntax)
{
- static const gdcm::Tag DICOM_TAG_BITS_ALLOCATED(0x0028, 0x0100);
- static const gdcm::Tag DICOM_TAG_COLUMNS(0x0028, 0x0011);
- static const gdcm::Tag DICOM_TAG_PIXEL_DATA(0x7fe0, 0x0010);
- static const gdcm::Tag DICOM_TAG_ROWS(0x0028, 0x0010);
- static const gdcm::Tag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002);
- static const gdcm::Tag DICOM_TAG_PHOTOMETRIC_INTERPRETATION(0x0028, 0x0004);
-
- if (!dicom.GetDataSet().FindDataElement(DICOM_TAG_PIXEL_DATA))
+ if (OrthancPluginStartMultipartAnswer(
+ OrthancPlugins::GetGlobalContext(),
+ output, "related", GetMimeType(outputSyntax)) != OrthancPluginErrorCode_Success)
{
- throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
+ throw Orthanc::OrthancException(Orthanc::ErrorCode_Plugin,
+ "Cannot start a multipart answer");
}
- const gdcm::DataElement& pixelData = dicom.GetDataSet().GetDataElement(DICOM_TAG_PIXEL_DATA);
- const gdcm::SequenceOfFragments* fragments = pixelData.GetSequenceOfFragments();
-
- if (OrthancPluginStartMultipartAnswer(OrthancPlugins::GetGlobalContext(),
- output, "related", GetMimeType(syntax)) != OrthancPluginErrorCode_Success)
- {
- return false;
- }
-
- int samplesPerPixel;
-
- if (!dicom.GetIntegerTag(samplesPerPixel, DICOM_TAG_SAMPLES_PER_PIXEL))
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
- }
-
- bool convertYbr = false;
+ const std::string base = OrthancPlugins::Configuration::GetBaseUrl(request);
+ for (std::list<unsigned int>::const_iterator
+ frame = frames.begin(); frame != frames.end(); ++frame)
{
- std::string photometric;
- if (samplesPerPixel == 3 &&
- dicom.GetStringTag(photometric, DICOM_TAG_PHOTOMETRIC_INTERPRETATION, true) &&
- photometric == "YBR_FULL")
- {
- convertYbr = true;
- }
- }
-
- if (fragments == NULL)
- {
- // Single-fragment image
-
- if (pixelData.GetByteValue() == NULL)
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
- "Image was not properly decoded");
- }
-
- int width, height, bits;
-
- if (!dicom.GetIntegerTag(height, DICOM_TAG_ROWS) ||
- !dicom.GetIntegerTag(width, DICOM_TAG_COLUMNS) ||
- !dicom.GetIntegerTag(bits, DICOM_TAG_BITS_ALLOCATED))
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
- }
-
- size_t frameSize = height * width * bits * samplesPerPixel / 8;
-
- if (frameSize == 0)
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
- }
-
- /**
- * The number of bytes in "pixelData" might not be divisible by
- * "frameSize", because "pixelData" might contain one padding byte
- * to have an even number of bytes.
- * https://bitbucket.org/sjodogne/orthanc/issues/164/
- **/
-
- if (pixelData.GetByteValue()->GetLength() % frameSize != 0 &&
- (/* allow one padding byte to be present */
- pixelData.GetByteValue()->GetLength() % 2 == 0 &&
- pixelData.GetByteValue()->GetLength() % frameSize != 1))
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
- }
-
- size_t framesCount = pixelData.GetByteValue()->GetLength() / frameSize;
+ std::string content;
+ instance.GetRawFrame(content, *frame);
- if (frames.empty())
- {
- // If no frame is provided, return all the frames (this is an extension)
- for (size_t i = 0; i < framesCount; i++)
- {
- frames.push_back(i);
- }
- }
-
- const char* buffer = pixelData.GetByteValue()->GetPointer();
- assert(sizeof(char) == 1);
-
- for (std::list<unsigned int>::const_iterator
- frame = frames.begin(); frame != frames.end(); ++frame)
- {
- if (*frame >= framesCount)
- {
- throw Orthanc::OrthancException(
- Orthanc::ErrorCode_ParameterOutOfRange,
- "Trying to access frame number " + boost::lexical_cast<std::string>(*frame + 1) +
- " of an image with " + boost::lexical_cast<std::string>(framesCount) + " frames");
- }
- else
- {
- const char* p = buffer + (*frame) * frameSize;
- AnswerSingleFrame(output, request, dicom, p, frameSize, *frame, convertYbr);
- }
- }
- }
- else
- {
- // Multi-fragment image, we assume that each fragment corresponds to one frame
+ const char* data = content.empty() ? NULL : content.c_str();
+ size_t size = content.size();
+
+ OrthancPluginErrorCode error;
- if (frames.empty())
- {
- // If no frame is provided, return all the frames (this is an extension)
- for (size_t i = 0; i < fragments->GetNumberOfFragments(); i++)
- {
- frames.push_back(i);
- }
- }
+#if HAS_SEND_MULTIPART_ITEM_2 == 1
+ std::string location = (
+ OrthancPlugins::Configuration::GetWadoUrl(base, studyInstanceUid, seriesInstanceUid, sopInstanceUid) +
+ "frames/" + boost::lexical_cast<std::string>(*frame + 1));
+ const char *keys[] = { "Content-Location" };
+ const char *values[] = { location.c_str() };
+ error = OrthancPluginSendMultipartItem2(OrthancPlugins::GetGlobalContext(), output, data, size, 1, keys, values);
+#else
+ error = OrthancPluginSendMultipartItem(OrthancPlugins::GetGlobalContext(), output, data, size);
+#endif
- for (std::list<unsigned int>::const_iterator
- frame = frames.begin(); frame != frames.end(); ++frame)
+ if (error != OrthancPluginErrorCode_Success)
{
- if (*frame >= fragments->GetNumberOfFragments())
- {
- // TODO A frame is not a fragment, looks like a bug
- throw Orthanc::OrthancException(
- Orthanc::ErrorCode_ParameterOutOfRange,
- "Trying to access frame number " +
- boost::lexical_cast<std::string>(*frame + 1) +
- " of an image with " +
- boost::lexical_cast<std::string>(fragments->GetNumberOfFragments()) +
- " frames");
- }
- else
- {
- AnswerSingleFrame(output, request, dicom,
- fragments->GetFragment(*frame).GetByteValue()->GetPointer(),
- fragments->GetFragment(*frame).GetByteValue()->GetLength(),
- *frame, convertYbr);
- }
+ throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
}
}
-
- return true;
}
-
-void RetrieveFrames(OrthancPluginRestOutput* output,
- const char* url,
- const OrthancPluginHttpRequest* request)
+static void RetrieveFrames(OrthancPluginRestOutput* output,
+ const OrthancPluginHttpRequest* request,
+ bool allFrames,
+ std::list<unsigned int>& frames)
{
- std::list<unsigned int> frames;
- ParseFrameList(frames, request);
-
- Json::Value header;
std::string orthancId, studyInstanceUid, seriesInstanceUid, sopInstanceUid;
OrthancPlugins::MemoryBuffer content;
if (LocateInstance(output, orthancId, studyInstanceUid, seriesInstanceUid, sopInstanceUid, request) &&
- content.RestApiGet("/instances/" + orthancId + "/file", false) &&
- OrthancPlugins::RestApiGet(header, "/instances/" + orthancId + "/header?simplify", false))
+ content.RestApiGet("/instances/" + orthancId + "/file", false))
{
+ if (allFrames)
+ {
+ OrthancPlugins::LogInfo("DICOMweb RetrieveFrames on " + orthancId + ", all frames");
+ }
+ else
{
std::string s = "DICOMweb RetrieveFrames on " + orthancId + ", frames: ";
for (std::list<unsigned int>::const_iterator
@@ -624,79 +440,56 @@ void RetrieveFrames(OrthancPluginRestOutput* output,
OrthancPlugins::LogInfo(s);
}
- std::auto_ptr<OrthancPlugins::GdcmParsedDicomFile> source;
+ Orthanc::DicomTransferSyntax targetSyntax;
- gdcm::TransferSyntax sourceSyntax;
-
- if (header.type() == Json::objectValue &&
- header.isMember("TransferSyntaxUID"))
+ std::unique_ptr<OrthancPlugins::DicomInstance> instance;
+ if (ParseTransferSyntax(targetSyntax, request))
{
- sourceSyntax = gdcm::TransferSyntax::GetTSType(header["TransferSyntaxUID"].asCString());
+ OrthancPlugins::LogInfo("DICOMweb RetrieveFrames: Transcoding instance " + orthancId +
+ " to transfer syntax " + Orthanc::GetTransferSyntaxUid(targetSyntax));
+
+ instance.reset(OrthancPlugins::DicomInstance::Transcode(
+ content.GetData(), content.GetSize(), GetTransferSyntaxUid(targetSyntax)));
}
else
{
- source.reset(new OrthancPlugins::GdcmParsedDicomFile(content));
- sourceSyntax = source->GetFile().GetHeader().GetDataSetTransferSyntax();
+ instance.reset(new OrthancPlugins::DicomInstance(content.GetData(), content.GetSize()));
}
- gdcm::TransferSyntax targetSyntax(ParseTransferSyntax(request, sourceSyntax));
-
- if (sourceSyntax == targetSyntax)
+ if (instance.get() == NULL)
{
- // No need to change the transfer syntax
-
- if (source.get() == NULL)
- {
- source.reset(new OrthancPlugins::GdcmParsedDicomFile(content));
- }
-
- AnswerFrames(output, request, *source, targetSyntax, frames);
+ throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
}
- else
- {
- // Need to convert the transfer syntax
+ if (allFrames)
+ {
+ frames.clear();
+ for (unsigned int i = 0; i < instance->GetFramesCount(); i++)
{
- OrthancPlugins::LogInfo("DICOMweb RetrieveFrames: Transcoding instance " + orthancId +
- " from transfer syntax " + std::string(sourceSyntax.GetString()) +
- " to " + std::string(targetSyntax.GetString()));
+ frames.push_back(i + 1); // Frames are numbered starting from 1
}
+ }
- gdcm::ImageChangeTransferSyntax change;
- change.SetTransferSyntax(targetSyntax);
-
- // TODO Avoid this unnecessary memcpy by defining a stream over the MemoryBuffer
- std::string dicom(content.GetData(), content.GetData() + content.GetSize());
- std::stringstream stream(dicom);
+ AnswerFrames(output, request, *instance, studyInstanceUid, seriesInstanceUid,
+ sopInstanceUid, frames, targetSyntax);
+ }
+}
- gdcm::ImageReader reader;
- reader.SetStream(stream);
- if (!reader.Read())
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
- "Cannot decode the image");
- }
- change.SetInput(reader.GetImage());
- if (!change.Change())
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
- "Cannot change the transfer syntax of the image");
- }
+void RetrieveAllFrames(OrthancPluginRestOutput* output,
+ const char* url,
+ const OrthancPluginHttpRequest* request)
+{
+ std::list<unsigned int> frames;
+ RetrieveFrames(output, request, true, frames);
+}
- gdcm::ImageWriter writer;
- writer.SetImage(change.GetOutput());
- writer.SetFile(reader.GetFile());
-
- std::stringstream ss;
- writer.SetStream(ss);
- if (!writer.Write())
- {
- throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory);
- }
- OrthancPlugins::GdcmParsedDicomFile transcoded(ss.str());
- AnswerFrames(output, request, transcoded, targetSyntax, frames);
- }
- }
+void RetrieveSelectedFrames(OrthancPluginRestOutput* output,
+ const char* url,
+ const OrthancPluginHttpRequest* request)
+{
+ std::list<unsigned int> frames;
+ ParseFrameList(frames, request);
+ RetrieveFrames(output, request, false, frames);
}
=====================================
Resources/CMake/GdcmConfiguration.cmake deleted
=====================================
@@ -1,144 +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 <http://www.gnu.org/licenses/>.
-
-
-if (STATIC_BUILD OR NOT USE_SYSTEM_GDCM)
- if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD")
- # If using gcc, build GDCM with the "-fPIC" argument to allow its
- # embedding into the shared library containing the Orthanc plugin
- set(AdditionalFlags "-fPIC")
- elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
- # This definition is necessary to compile
- # "Source/MediaStorageAndFileFormat/gdcmFileStreamer.cxx"
- set(AdditionalFlags "-Doff64_t=off_t")
- endif()
-
- set(Flags
- "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} ${AdditionalFlags}"
- "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} ${AdditionalFlags}"
- -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG}
- -DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG}
- -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE}
- -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE}
- -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL}
- -DCMAKE_CXX_FLAGS_MINSIZEREL=${CMAKE_CXX_FLAGS_MINSIZEREL}
- -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO}
- -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
- )
-
- if (CMAKE_TOOLCHAIN_FILE)
- # Take absolute path to the toolchain
- get_filename_component(TMP ${CMAKE_TOOLCHAIN_FILE} REALPATH BASE ${CMAKE_SOURCE_DIR})
- list(APPEND Flags -DCMAKE_TOOLCHAIN_FILE=${TMP})
- endif()
-
- # Don't build manpages (since gdcm 2.8.4)
- list(APPEND Flags -DGDCM_BUILD_DOCBOOK_MANPAGES=OFF)
-
- if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
- # Trick to disable the compilation of socket++ by gdcm, which is
- # incompatible with LSB, but fortunately only required for DICOM
- # Networking
- list(APPEND Flags -DGDCM_USE_SYSTEM_SOCKETXX=ON)
-
- # Detect the number of CPU cores to run "make" with as much
- # parallelism as possible
- include(ProcessorCount)
- ProcessorCount(N)
- if (NOT N EQUAL 0)
- set(MAKE_PARALLEL -j${N})
- endif()
-
- # For Linux Standard Base, avoid building incompatible target gdcmMEXD (*)
- set(BUILD_COMMAND BUILD_COMMAND
- ${CMAKE_MAKE_PROGRAM} ${MAKE_PARALLEL}
- gdcmMSFF gdcmcharls gdcmDICT gdcmDSED gdcmIOD gdcmjpeg8
- gdcmjpeg12 gdcmjpeg16 gdcmopenjp2 gdcmzlib gdcmCommon gdcmexpat gdcmuuid)
- endif()
-
- include(ExternalProject)
- externalproject_add(GDCM
- URL "http://orthanc.osimis.io/ThirdPartyDownloads/gdcm-3.0.4.tar.gz"
- URL_MD5 "f12dbded708356d5fa0b5ed37ccdb66e"
- TIMEOUT 60
- CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} ${Flags}
- ${BUILD_COMMAND} # Customize "make", only for Linux Standard Base (*)
- INSTALL_COMMAND "" # Skip the install step
- )
-
- if(MSVC)
- set(Suffix ".lib")
- set(Prefix "")
- else()
- set(Suffix ".a")
- list(GET CMAKE_FIND_LIBRARY_PREFIXES 0 Prefix)
- endif()
-
- set(GDCM_LIBRARIES
- # WARNING: The order of the libraries below *is* important!
- ${Prefix}gdcmMSFF${Suffix}
- ${Prefix}gdcmcharls${Suffix}
- ${Prefix}gdcmDICT${Suffix}
- ${Prefix}gdcmDSED${Suffix}
- ${Prefix}gdcmIOD${Suffix}
- ${Prefix}gdcmjpeg8${Suffix}
- ${Prefix}gdcmjpeg12${Suffix}
- ${Prefix}gdcmjpeg16${Suffix}
- ${Prefix}gdcmopenjp2${Suffix}
- ${Prefix}gdcmzlib${Suffix}
- ${Prefix}gdcmCommon${Suffix}
- ${Prefix}gdcmexpat${Suffix}
-
- #${Prefix}socketxx${Suffix}
- #${Prefix}gdcmMEXD${Suffix} # DICOM Networking, unneeded by Orthanc plugins
- #${Prefix}gdcmgetopt${Suffix}
- )
-
- if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
- list(APPEND GDCM_LIBRARIES
- rpcrt4 # For UUID stuff
- )
- else()
- list(APPEND GDCM_LIBRARIES
- ${Prefix}gdcmuuid${Suffix}
- )
- endif()
-
- ExternalProject_Get_Property(GDCM binary_dir)
- include_directories(${binary_dir}/Source/Common)
- link_directories(${binary_dir}/bin)
-
- ExternalProject_Get_Property(GDCM source_dir)
- include_directories(
- ${source_dir}/Source/Common
- ${source_dir}/Source/DataDictionary
- ${source_dir}/Source/MediaStorageAndFileFormat
- ${source_dir}/Source/DataStructureAndEncodingDefinition
- )
-
-else()
- find_package(GDCM REQUIRED)
- if (GDCM_FOUND)
- include(${GDCM_USE_FILE})
- set(GDCM_LIBRARIES gdcmCommon gdcmMSFF)
- else(GDCM_FOUND)
- message(FATAL_ERROR "Cannot find GDCM, did you set GDCM_DIR?")
- endif(GDCM_FOUND)
-endif()
=====================================
Resources/Orthanc/DownloadOrthancFramework.cmake
=====================================
@@ -112,6 +112,12 @@ if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg" OR
set(ORTHANC_FRAMEWORK_MD5 "e1b76f01116d9b5d4ac8cc39980560e3")
elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.5.8")
set(ORTHANC_FRAMEWORK_MD5 "82323e8c49a667f658a3639ea4dbc336")
+ elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.6.0")
+ set(ORTHANC_FRAMEWORK_MD5 "eab428d6e53f61e847fa360bb17ebe25")
+ elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.6.1")
+ set(ORTHANC_FRAMEWORK_MD5 "3971f5de96ba71dc9d3f3690afeaa7c0")
+ elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.7.0")
+ set(ORTHANC_FRAMEWORK_MD5 "ce5f689e852b01d3672bd3d2f952a5ef")
# Below this point are development snapshots that were used to
# release some plugin, before an official release of the Orthanc
@@ -214,7 +220,7 @@ if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg")
else()
message("Forking the Orthanc source repository using Mercurial")
execute_process(
- COMMAND ${ORTHANC_FRAMEWORK_HG} clone "https://bitbucket.org/sjodogne/orthanc"
+ COMMAND ${ORTHANC_FRAMEWORK_HG} clone "https://hg.orthanc-server.com/orthanc/"
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
RESULT_VARIABLE Failure
)
=====================================
Resources/Orthanc/LinuxStandardBaseToolchain.cmake
=====================================
@@ -1,11 +1,19 @@
-# LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../Resources/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON -DUSE_LEGACY_LIBICU=ON -DBOOST_LOCALE_BACKEND=icu
+#
+# Full build, as used on the BuildBot CIS:
+#
+# $ LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../Resources/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON -DUSE_LEGACY_LIBICU=ON -DBOOST_LOCALE_BACKEND=icu -DENABLE_PKCS11=ON -G Ninja
+#
+# Or, more lightweight version (without libp11 and ICU):
+#
+# $ LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../Resources/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON -G Ninja
+#
INCLUDE(CMakeForceCompiler)
-SET(LSB_PATH $ENV{LSB_PATH})
-SET(LSB_CC $ENV{LSB_CC})
-SET(LSB_CXX $ENV{LSB_CXX})
-SET(LSB_TARGET_VERSION "4.0")
+SET(LSB_PATH $ENV{LSB_PATH} CACHE STRING "")
+SET(LSB_CC $ENV{LSB_CC} CACHE STRING "")
+SET(LSB_CXX $ENV{LSB_CXX} CACHE STRING "")
+SET(LSB_TARGET_VERSION "4.0" CACHE STRING "")
IF ("${LSB_PATH}" STREQUAL "")
SET(LSB_PATH "/opt/lsb")
=====================================
Resources/Orthanc/Sdk-1.5.4/orthanc/OrthancCPlugin.h deleted
=====================================
The diff for this file was not included because it is too large.
=====================================
Resources/Orthanc/Sdk-1.5.7/orthanc/OrthancCPlugin.h → Resources/Orthanc/Sdk-1.7.0/orthanc/OrthancCPlugin.h
=====================================
@@ -26,6 +26,9 @@
* - Possibly register a callback to unserialize jobs using OrthancPluginRegisterJobsUnserializer().
* - Possibly register a callback to refresh its metrics using OrthancPluginRegisterRefreshMetricsCallback().
* - Possibly register a callback to answer chunked HTTP transfers using ::OrthancPluginRegisterChunkedRestCallback().
+ * - Possibly register a callback for Storage Commitment SCP using ::OrthancPluginRegisterStorageCommitmentScpCallback().
+ * - Possibly register a callback to filter incoming DICOM instance using OrthancPluginRegisterIncomingDicomInstanceFilter().
+ * - Possibly register a custom transcoder for DICOM images using OrthancPluginRegisterTranscoderCallback().
* -# <tt>void OrthancPluginFinalize()</tt>:
* This function is invoked by Orthanc during its shutdown. The plugin
* must free all its memory.
@@ -58,10 +61,13 @@
* @brief Functions to register and manage callbacks by the plugins.
*
* @defgroup DicomCallbacks DicomCallbacks
- * @brief Functions to register and manage DICOM callbacks (worklists, C-Find, C-MOVE).
+ * @brief Functions to register and manage DICOM callbacks (worklists, C-FIND, C-MOVE, storage commitment).
*
* @defgroup Orthanc Orthanc
* @brief Functions to access the content of the Orthanc server.
+ *
+ * @defgroup DicomInstance DicomInstance
+ * @brief Functions to access DICOM images that are managed by the Orthanc core.
**/
@@ -77,7 +83,7 @@
* Orthanc - A Lightweight, RESTful DICOM Store
* Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
* Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., 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 General Public License as
@@ -122,16 +128,16 @@
#endif
#define ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER 1
-#define ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER 5
-#define ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER 7
+#define ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER 7
+#define ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER 0
#if !defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE)
-#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \
- (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major || \
- (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major && \
- (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor || \
- (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \
+#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \
+ (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major || \
+ (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major && \
+ (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor || \
+ (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \
ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision))))
#endif
@@ -178,7 +184,7 @@
/**
* For Microsoft Visual Studio, a compatibility "stdint.h" can be
* downloaded at the following URL:
- * https://bitbucket.org/sjodogne/orthanc/raw/default/Resources/ThirdParty/VisualStudio/stdint.h
+ * https://hg.orthanc-server.com/orthanc/raw-file/tip/Resources/ThirdParty/VisualStudio/stdint.h
**/
#include <stdint.h>
@@ -242,6 +248,7 @@ extern "C"
OrthancPluginErrorCode_DatabaseUnavailable = 36 /*!< The database is currently not available (probably a transient situation) */,
OrthancPluginErrorCode_CanceledJob = 37 /*!< This job was canceled */,
OrthancPluginErrorCode_BadGeometry = 38 /*!< Geometry error encountered in Stone */,
+ OrthancPluginErrorCode_SslInitialization = 39 /*!< Cannot initialize SSL encryption, check out your certificates */,
OrthancPluginErrorCode_SQLiteNotOpened = 1000 /*!< SQLite: The database is not opened */,
OrthancPluginErrorCode_SQLiteAlreadyOpened = 1001 /*!< SQLite: Connection is already open */,
OrthancPluginErrorCode_SQLiteCannotOpen = 1002 /*!< SQLite: Unable to open the database */,
@@ -301,6 +308,8 @@ extern "C"
OrthancPluginErrorCode_CannotOrderSlices = 2040 /*!< Unable to order the slices of the series */,
OrthancPluginErrorCode_NoWorklistHandler = 2041 /*!< No request handler factory for DICOM C-Find Modality SCP */,
OrthancPluginErrorCode_AlreadyExistingTag = 2042 /*!< Cannot override the value of a tag that already exists */,
+ OrthancPluginErrorCode_NoStorageCommitmentHandler = 2043 /*!< No request handler factory for DICOM N-ACTION SCP (storage commitment) */,
+ OrthancPluginErrorCode_NoCGetHandler = 2044 /*!< No request handler factory for DICOM C-GET SCP */,
OrthancPluginErrorCode_UnsupportedMediaType = 3000 /*!< Unsupported media type */,
_OrthancPluginErrorCode_INTERNAL = 0x7fffffff
@@ -433,8 +442,11 @@ extern "C"
_OrthancPluginService_SetMetricsValue = 31,
_OrthancPluginService_EncodeDicomWebJson = 32,
_OrthancPluginService_EncodeDicomWebXml = 33,
- _OrthancPluginService_ChunkedHttpClient = 34, /* New in Orthanc 1.5.7 */
- _OrthancPluginService_GetTagName = 35, /* New in Orthanc 1.5.7 */
+ _OrthancPluginService_ChunkedHttpClient = 34, /* New in Orthanc 1.5.7 */
+ _OrthancPluginService_GetTagName = 35, /* New in Orthanc 1.5.7 */
+ _OrthancPluginService_EncodeDicomWebJson2 = 36, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_EncodeDicomWebXml2 = 37, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_CreateMemoryBuffer = 38, /* New in Orthanc 1.7.0 */
/* Registration of callbacks */
_OrthancPluginService_RegisterRestCallback = 1000,
@@ -450,7 +462,10 @@ extern "C"
_OrthancPluginService_RegisterIncomingHttpRequestFilter2 = 1010,
_OrthancPluginService_RegisterRefreshMetricsCallback = 1011,
_OrthancPluginService_RegisterChunkedRestCallback = 1012, /* New in Orthanc 1.5.7 */
-
+ _OrthancPluginService_RegisterStorageCommitmentScpCallback = 1013,
+ _OrthancPluginService_RegisterIncomingDicomInstanceFilter = 1014,
+ _OrthancPluginService_RegisterTranscoderCallback = 1015, /* New in Orthanc 1.7.0 */
+
/* Sending answers to REST calls */
_OrthancPluginService_AnswerBuffer = 2000,
_OrthancPluginService_CompressAndAnswerPngImage = 2001, /* Unused as of Orthanc 0.9.4 */
@@ -494,7 +509,19 @@ extern "C"
_OrthancPluginService_HasInstanceMetadata = 4005,
_OrthancPluginService_GetInstanceMetadata = 4006,
_OrthancPluginService_GetInstanceOrigin = 4007,
-
+ _OrthancPluginService_GetInstanceTransferSyntaxUid = 4008,
+ _OrthancPluginService_HasInstancePixelData = 4009,
+ _OrthancPluginService_CreateDicomInstance = 4010, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_FreeDicomInstance = 4011, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_GetInstanceFramesCount = 4012, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_GetInstanceRawFrame = 4013, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_GetInstanceDecodedFrame = 4014, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_TranscodeDicomInstance = 4015, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_SerializeDicomInstance = 4016, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_GetInstanceAdvancedJson = 4017, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_GetInstanceDicomWebJson = 4018, /* New in Orthanc 1.7.0 */
+ _OrthancPluginService_GetInstanceDicomWebXml = 4019, /* New in Orthanc 1.7.0 */
+
/* Services for plugins implementing a database back-end */
_OrthancPluginService_RegisterDatabaseBackend = 5000,
_OrthancPluginService_DatabaseAnswer = 5001,
@@ -909,14 +936,14 @@ extern "C"
**/
typedef enum
{
- OrthancPluginMetricsType_Default, /*!< Default metrics */
+ OrthancPluginMetricsType_Default = 0, /*!< Default metrics */
/**
* This metrics represents a time duration. Orthanc will keep the
* maximum value of the metrics over a sliding window of ten
* seconds, which is useful if the metrics is sampled frequently.
**/
- OrthancPluginMetricsType_Timer
+ OrthancPluginMetricsType_Timer = 1
} OrthancPluginMetricsType;
@@ -926,11 +953,47 @@ extern "C"
**/
typedef enum
{
- OrthancPluginDicomWebBinaryMode_Ignore, /*!< Don't include binary tags */
- OrthancPluginDicomWebBinaryMode_InlineBinary, /*!< Inline encoding using Base64 */
- OrthancPluginDicomWebBinaryMode_BulkDataUri /*!< Use a bulk data URI field */
+ OrthancPluginDicomWebBinaryMode_Ignore = 0, /*!< Don't include binary tags */
+ OrthancPluginDicomWebBinaryMode_InlineBinary = 1, /*!< Inline encoding using Base64 */
+ OrthancPluginDicomWebBinaryMode_BulkDataUri = 2 /*!< Use a bulk data URI field */
} OrthancPluginDicomWebBinaryMode;
+
+ /**
+ * The available values for the Failure Reason (0008,1197) during
+ * storage commitment.
+ * http://dicom.nema.org/medical/dicom/2019e/output/chtml/part03/sect_C.14.html#sect_C.14.1.1
+ **/
+ typedef enum
+ {
+ OrthancPluginStorageCommitmentFailureReason_Success = 0,
+ /*!< Success: The DICOM instance is properly stored in the SCP */
+
+ OrthancPluginStorageCommitmentFailureReason_ProcessingFailure = 1,
+ /*!< 0110H: A general failure in processing the operation was encountered */
+
+ OrthancPluginStorageCommitmentFailureReason_NoSuchObjectInstance = 2,
+ /*!< 0112H: One or more of the elements in the Referenced SOP
+ Instance Sequence was not available */
+
+ OrthancPluginStorageCommitmentFailureReason_ResourceLimitation = 3,
+ /*!< 0213H: The SCP does not currently have enough resources to
+ store the requested SOP Instance(s) */
+
+ OrthancPluginStorageCommitmentFailureReason_ReferencedSOPClassNotSupported = 4,
+ /*!< 0122H: Storage Commitment has been requested for a SOP
+ Instance with a SOP Class that is not supported by the SCP */
+
+ OrthancPluginStorageCommitmentFailureReason_ClassInstanceConflict = 5,
+ /*!< 0119H: The SOP Class of an element in the Referenced SOP
+ Instance Sequence did not correspond to the SOP class registered
+ for this SOP Instance at the SCP */
+
+ OrthancPluginStorageCommitmentFailureReason_DuplicateTransactionUID = 6
+ /*!< 0131H: The Transaction UID of the Storage Commitment Request
+ is already in use */
+ } OrthancPluginStorageCommitmentFailureReason;
+
/**
@@ -965,7 +1028,8 @@ extern "C"
/**
- * @brief Opaque structure that represents a DICOM instance received by Orthanc.
+ * @brief Opaque structure that represents a DICOM instance that is managed by the Orthanc core.
+ * @ingroup DicomInstance
**/
typedef struct _OrthancPluginDicomInstance_t OrthancPluginDicomInstance;
@@ -1023,7 +1087,7 @@ extern "C"
* @brief Opaque structure to an object that can be used to check whether a DICOM instance matches a C-Find query.
* @ingroup Toolbox
**/
- typedef struct _OrthancPluginFindAnswers_t OrthancPluginFindMatcher;
+ typedef struct _OrthancPluginFindMatcher_t OrthancPluginFindMatcher;
@@ -1064,11 +1128,11 @@ extern "C"
/**
- * @brief Signature of a callback function that is triggered when Orthanc receives a DICOM instance.
+ * @brief Signature of a callback function that is triggered when Orthanc stores a new DICOM instance.
* @ingroup Callbacks
**/
typedef OrthancPluginErrorCode (*OrthancPluginOnStoredInstanceCallback) (
- OrthancPluginDicomInstance* instance,
+ const OrthancPluginDicomInstance* instance,
const char* instanceId);
@@ -1148,6 +1212,12 @@ extern "C"
* @param type The content type corresponding to this file.
* @return 0 if success, other value if error.
* @ingroup Callbacks
+ *
+ * @warning The "content" buffer *must* have been allocated using
+ * the "malloc()" function of your C standard library (i.e. nor
+ * "new[]", neither a pointer to a buffer). The "free()" function of
+ * your C standard library will automatically be invoked on the
+ * "content" pointer.
**/
typedef OrthancPluginErrorCode (*OrthancPluginStorageRead) (
void** content,
@@ -1539,7 +1609,7 @@ extern "C"
* "levelTagElement", and "levelIndex" arrays.
* @param levelTagGroup The group of the parent DICOM tags in the hierarchy.
* @param levelTagElement The element of the parent DICOM tags in the hierarchy.
- * @param levelIndex The index of the node in the parent sequences of the hiearchy.
+ * @param levelIndex The index of the node in the parent sequences of the hierarchy.
* @param tagGroup The group of the DICOM tag of interest.
* @param tagElement The element of the DICOM tag of interest.
* @param vr The value representation of the binary DICOM node.
@@ -1558,6 +1628,45 @@ extern "C"
+ /**
+ * @brief Callback executed to encode a binary tag in DICOMweb.
+ *
+ * Signature of a callback function that is called by Orthanc
+ * whenever a DICOM tag that contains a binary value must be written
+ * to a JSON or XML node, while a DICOMweb document is being
+ * generated. The value representation (VR) of the DICOM tag can be
+ * OB, OD, OF, OL, OW, or UN.
+ *
+ * @see OrthancPluginEncodeDicomWebJson() and OrthancPluginEncodeDicomWebXml()
+ * @param node The node being generated, as provided by Orthanc.
+ * @param setter The setter to be used to encode the content of the node. If
+ * the setter is not called, the binary tag is not written to the output document.
+ * @param levelDepth The depth of the node in the DICOM hierarchy of sequences.
+ * This parameter gives the number of elements in the "levelTagGroup",
+ * "levelTagElement", and "levelIndex" arrays.
+ * @param levelTagGroup The group of the parent DICOM tags in the hierarchy.
+ * @param levelTagElement The element of the parent DICOM tags in the hierarchy.
+ * @param levelIndex The index of the node in the parent sequences of the hierarchy.
+ * @param tagGroup The group of the DICOM tag of interest.
+ * @param tagElement The element of the DICOM tag of interest.
+ * @param vr The value representation of the binary DICOM node.
+ * @param payload The user payload.
+ * @ingroup Callbacks
+ **/
+ typedef void (*OrthancPluginDicomWebBinaryCallback2) (
+ OrthancPluginDicomWebNode* node,
+ OrthancPluginDicomWebSetBinaryNode setter,
+ uint32_t levelDepth,
+ const uint16_t* levelTagGroup,
+ const uint16_t* levelTagElement,
+ const uint32_t* levelIndex,
+ uint16_t tagGroup,
+ uint16_t tagElement,
+ OrthancPluginValueRepresentation vr,
+ void* payload);
+
+
+
/**
* @brief Data structure that contains information about the Orthanc core.
**/
@@ -1652,7 +1761,8 @@ extern "C"
sizeof(int32_t) != sizeof(OrthancPluginJobStepStatus) ||
sizeof(int32_t) != sizeof(OrthancPluginConstraintType) ||
sizeof(int32_t) != sizeof(OrthancPluginMetricsType) ||
- sizeof(int32_t) != sizeof(OrthancPluginDicomWebBinaryMode))
+ sizeof(int32_t) != sizeof(OrthancPluginDicomWebBinaryMode) ||
+ sizeof(int32_t) != sizeof(OrthancPluginStorageCommitmentFailureReason))
{
/* Mismatch in the size of the enumerations */
return 0;
@@ -1915,7 +2025,7 @@ extern "C"
typedef struct
{
OrthancPluginRestOutput* output;
- const char* answer;
+ const void* answer;
uint32_t answerSize;
const char* mimeType;
} _OrthancPluginAnswerBuffer;
@@ -1935,7 +2045,7 @@ extern "C"
ORTHANC_PLUGIN_INLINE void OrthancPluginAnswerBuffer(
OrthancPluginContext* context,
OrthancPluginRestOutput* output,
- const char* answer,
+ const void* answer,
uint32_t answerSize,
const char* mimeType)
{
@@ -2646,12 +2756,12 @@ extern "C"
typedef struct
{
- char** resultStringToFree;
- const char** resultString;
- int64_t* resultInt64;
- const char* key;
- OrthancPluginDicomInstance* instance;
- OrthancPluginInstanceOrigin* resultOrigin; /* New in Orthanc 0.9.5 SDK */
+ char** resultStringToFree;
+ const char** resultString;
+ int64_t* resultInt64;
+ const char* key;
+ const OrthancPluginDicomInstance* instance;
+ OrthancPluginInstanceOrigin* resultOrigin; /* New in Orthanc 0.9.5 SDK */
} _OrthancPluginAccessDicomInstance;
@@ -2664,11 +2774,11 @@ extern "C"
* @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
* @param instance The instance of interest.
* @return The AET if success, NULL if error.
- * @ingroup Callbacks
+ * @ingroup DicomInstance
**/
ORTHANC_PLUGIN_INLINE const char* OrthancPluginGetInstanceRemoteAet(
- OrthancPluginContext* context,
- OrthancPluginDicomInstance* instance)
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
{
const char* result;
@@ -2697,11 +2807,11 @@ extern "C"
* @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
* @param instance The instance of interest.
* @return The size of the file, -1 in case of error.
- * @ingroup Callbacks
+ * @ingroup DicomInstance
**/
ORTHANC_PLUGIN_INLINE int64_t OrthancPluginGetInstanceSize(
- OrthancPluginContext* context,
- OrthancPluginDicomInstance* instance)
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
{
int64_t size;
@@ -2730,11 +2840,11 @@ extern "C"
* @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
* @param instance The instance of interest.
* @return The pointer to the DICOM data, NULL in case of error.
- * @ingroup Callbacks
+ * @ingroup DicomInstance
**/
- ORTHANC_PLUGIN_INLINE const char* OrthancPluginGetInstanceData(
- OrthancPluginContext* context,
- OrthancPluginDicomInstance* instance)
+ ORTHANC_PLUGIN_INLINE const void* OrthancPluginGetInstanceData(
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
{
const char* result;
@@ -2766,11 +2876,11 @@ extern "C"
* @param instance The instance of interest.
* @return The NULL value in case of error, or a string containing the JSON file.
* This string must be freed by OrthancPluginFreeString().
- * @ingroup Callbacks
+ * @ingroup DicomInstance
**/
ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceJson(
- OrthancPluginContext* context,
- OrthancPluginDicomInstance* instance)
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
{
char* result;
@@ -2804,11 +2914,11 @@ extern "C"
* @param instance The instance of interest.
* @return The NULL value in case of error, or a string containing the JSON file.
* This string must be freed by OrthancPluginFreeString().
- * @ingroup Callbacks
+ * @ingroup DicomInstance
**/
ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceSimplifiedJson(
- OrthancPluginContext* context,
- OrthancPluginDicomInstance* instance)
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
{
char* result;
@@ -2843,12 +2953,12 @@ extern "C"
* @param instance The instance of interest.
* @param metadata The metadata of interest.
* @return 1 if the metadata is present, 0 if it is absent, -1 in case of error.
- * @ingroup Callbacks
+ * @ingroup DicomInstance
**/
ORTHANC_PLUGIN_INLINE int OrthancPluginHasInstanceMetadata(
- OrthancPluginContext* context,
- OrthancPluginDicomInstance* instance,
- const char* metadata)
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance,
+ const char* metadata)
{
int64_t result;
@@ -2880,13 +2990,16 @@ extern "C"
* @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
* @param instance The instance of interest.
* @param metadata The metadata of interest.
- * @return The metadata value if success, NULL if error.
- * @ingroup Callbacks
+ * @return The metadata value if success, NULL if error. Please note that the
+ * returned string belongs to the instance object and must NOT be
+ * deallocated. Please make a copy of the string if you wish to access
+ * it later.
+ * @ingroup DicomInstance
**/
ORTHANC_PLUGIN_INLINE const char* OrthancPluginGetInstanceMetadata(
- OrthancPluginContext* context,
- OrthancPluginDicomInstance* instance,
- const char* metadata)
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance,
+ const char* metadata)
{
const char* result;
@@ -5053,11 +5166,11 @@ extern "C"
* @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
* @param instance The instance of interest.
* @return The origin of the instance.
- * @ingroup Callbacks
+ * @ingroup DicomInstance
**/
ORTHANC_PLUGIN_INLINE OrthancPluginInstanceOrigin OrthancPluginGetInstanceOrigin(
- OrthancPluginContext* context,
- OrthancPluginDicomInstance* instance)
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
{
OrthancPluginInstanceOrigin origin;
@@ -5129,8 +5242,11 @@ extern "C"
/**
* @brief Register a callback to handle the decoding of DICOM images.
*
- * This function registers a custom callback to the decoding of
- * DICOM images, replacing the built-in decoder of Orthanc.
+ * This function registers a custom callback to decode DICOM images,
+ * extending the built-in decoder of Orthanc that uses
+ * DCMTK. Starting with Orthanc 1.7.0, the exact behavior is
+ * affected by the configuration option
+ * "BuiltinDecoderTranscoderOrder" of Orthanc.
*
* @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
* @param callback The callback.
@@ -5262,6 +5378,7 @@ extern "C"
* @param frameIndex The index of the frame of interest in a multi-frame image.
* @return The uncompressed image. It must be freed with OrthancPluginFreeImage().
* @ingroup Images
+ * @see OrthancPluginGetInstanceDecodedFrame()
**/
ORTHANC_PLUGIN_INLINE OrthancPluginImage* OrthancPluginDecodeDicomImage(
OrthancPluginContext* context,
@@ -6737,6 +6854,7 @@ extern "C"
* @see OrthancPluginCreateDicom()
* @return The NULL value in case of error, or the JSON document. This string must
* be freed by OrthancPluginFreeString().
+ * @deprecated OrthancPluginEncodeDicomWebJson2()
* @ingroup Toolbox
**/
ORTHANC_PLUGIN_INLINE char* OrthancPluginEncodeDicomWebJson(
@@ -6775,9 +6893,10 @@ extern "C"
* @param dicom Pointer to the DICOM instance.
* @param dicomSize Size of the DICOM instance.
* @param callback Callback to set the value of the binary tags.
- * @return The NULL value in case of error, or the JSON document. This string must
+ * @return The NULL value in case of error, or the XML document. This string must
* be freed by OrthancPluginFreeString().
* @see OrthancPluginCreateDicom()
+ * @deprecated OrthancPluginEncodeDicomWebXml2()
* @ingroup Toolbox
**/
ORTHANC_PLUGIN_INLINE char* OrthancPluginEncodeDicomWebXml(
@@ -6807,6 +6926,104 @@ extern "C"
+ typedef struct
+ {
+ char** target;
+ const void* dicom;
+ uint32_t dicomSize;
+ OrthancPluginDicomWebBinaryCallback2 callback;
+ void* payload;
+ } _OrthancPluginEncodeDicomWeb2;
+
+ /**
+ * @brief Convert a DICOM instance to DICOMweb JSON.
+ *
+ * This function converts a memory buffer containing a DICOM instance,
+ * into its DICOMweb JSON representation.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param dicom Pointer to the DICOM instance.
+ * @param dicomSize Size of the DICOM instance.
+ * @param callback Callback to set the value of the binary tags.
+ * @param payload User payload.
+ * @return The NULL value in case of error, or the JSON document. This string must
+ * be freed by OrthancPluginFreeString().
+ * @see OrthancPluginCreateDicom()
+ * @ingroup Toolbox
+ **/
+ ORTHANC_PLUGIN_INLINE char* OrthancPluginEncodeDicomWebJson2(
+ OrthancPluginContext* context,
+ const void* dicom,
+ uint32_t dicomSize,
+ OrthancPluginDicomWebBinaryCallback2 callback,
+ void* payload)
+ {
+ char* target = NULL;
+
+ _OrthancPluginEncodeDicomWeb2 params;
+ params.target = ⌖
+ params.dicom = dicom;
+ params.dicomSize = dicomSize;
+ params.callback = callback;
+ params.payload = payload;
+
+ if (context->InvokeService(context, _OrthancPluginService_EncodeDicomWebJson2, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return NULL;
+ }
+ else
+ {
+ return target;
+ }
+ }
+
+
+ /**
+ * @brief Convert a DICOM instance to DICOMweb XML.
+ *
+ * This function converts a memory buffer containing a DICOM instance,
+ * into its DICOMweb XML representation.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param dicom Pointer to the DICOM instance.
+ * @param dicomSize Size of the DICOM instance.
+ * @param callback Callback to set the value of the binary tags.
+ * @param payload User payload.
+ * @return The NULL value in case of error, or the XML document. This string must
+ * be freed by OrthancPluginFreeString().
+ * @see OrthancPluginCreateDicom()
+ * @ingroup Toolbox
+ **/
+ ORTHANC_PLUGIN_INLINE char* OrthancPluginEncodeDicomWebXml2(
+ OrthancPluginContext* context,
+ const void* dicom,
+ uint32_t dicomSize,
+ OrthancPluginDicomWebBinaryCallback2 callback,
+ void* payload)
+ {
+ char* target = NULL;
+
+ _OrthancPluginEncodeDicomWeb2 params;
+ params.target = ⌖
+ params.dicom = dicom;
+ params.dicomSize = dicomSize;
+ params.callback = callback;
+ params.payload = payload;
+
+ if (context->InvokeService(context, _OrthancPluginService_EncodeDicomWebXml2, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return NULL;
+ }
+ else
+ {
+ return target;
+ }
+ }
+
+
+
/**
* @brief Callback executed when a HTTP header is received during a chunked transfer.
*
@@ -7250,7 +7467,720 @@ extern "C"
}
+
+ /**
+ * @brief Callback executed by the storage commitment SCP.
+ *
+ * Signature of a factory function that creates an object to handle
+ * one incoming storage commitment request.
+ *
+ * @remark The factory receives the list of the SOP class/instance
+ * UIDs of interest to the remote storage commitment SCU. This gives
+ * the factory the possibility to start some prefetch process
+ * upfront in the background, before the handler object is actually
+ * queried about the status of these DICOM instances.
+ *
+ * @param handler Output variable where the factory puts the handler object it created.
+ * @param jobId ID of the Orthanc job that is responsible for handling
+ * the storage commitment request. This job will successively look for the
+ * status of all the individual queried DICOM instances.
+ * @param transactionUid UID of the storage commitment transaction
+ * provided by the storage commitment SCU. It contains the value of the
+ * (0008,1195) DICOM tag.
+ * @param sopClassUids Array of the SOP class UIDs (0008,0016) that are queried by the SCU.
+ * @param sopInstanceUids Array of the SOP instance UIDs (0008,0018) that are queried by the SCU.
+ * @param countInstances Number of DICOM instances that are queried. This is the size
+ * of the `sopClassUids` and `sopInstanceUids` arrays.
+ * @param remoteAet The AET of the storage commitment SCU.
+ * @param calledAet The AET used by the SCU to contact the storage commitment SCP (i.e. Orthanc).
+ * @return 0 if success, other value if error.
+ * @ingroup DicomCallbacks
+ **/
+ typedef OrthancPluginErrorCode (*OrthancPluginStorageCommitmentFactory) (
+ void** handler /* out */,
+ const char* jobId,
+ const char* transactionUid,
+ const char* const* sopClassUids,
+ const char* const* sopInstanceUids,
+ uint32_t countInstances,
+ const char* remoteAet,
+ const char* calledAet);
+
+
+ /**
+ * @brief Callback to free one storage commitment SCP handler.
+ *
+ * Signature of a callback function that releases the resources
+ * allocated by the factory of the storage commitment SCP. The
+ * handler is the return value of a previous call to the
+ * OrthancPluginStorageCommitmentFactory() callback.
+ *
+ * @param handler The handler object to be destructed.
+ * @ingroup DicomCallbacks
+ **/
+ typedef void (*OrthancPluginStorageCommitmentDestructor) (void* handler);
+
+
+ /**
+ * @brief Callback to get the status of one DICOM instance in the
+ * storage commitment SCP.
+ *
+ * Signature of a callback function that is successively invoked for
+ * each DICOM instance that is queried by the remote storage
+ * commitment SCU. The function must be tought of as a method of
+ * the handler object that was created by a previous call to the
+ * OrthancPluginStorageCommitmentFactory() callback. After each call
+ * to this method, the progress of the associated Orthanc job is
+ * updated.
+ *
+ * @param target Output variable where to put the status for the queried instance.
+ * @param handler The handler object associated with this storage commitment request.
+ * @param sopClassUid The SOP class UID (0008,0016) of interest.
+ * @param sopInstanceUid The SOP instance UID (0008,0018) of interest.
+ * @ingroup DicomCallbacks
+ **/
+ typedef OrthancPluginErrorCode (*OrthancPluginStorageCommitmentLookup) (
+ OrthancPluginStorageCommitmentFailureReason* target,
+ void* handler,
+ const char* sopClassUid,
+ const char* sopInstanceUid);
+
+
+ typedef struct
+ {
+ OrthancPluginStorageCommitmentFactory factory;
+ OrthancPluginStorageCommitmentDestructor destructor;
+ OrthancPluginStorageCommitmentLookup lookup;
+ } _OrthancPluginRegisterStorageCommitmentScpCallback;
+
+ /**
+ * @brief Register a callback to handle incoming requests to the storage commitment SCP.
+ *
+ * This function registers a callback to handle storage commitment SCP requests.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param factory Factory function that creates the handler object
+ * for incoming storage commitment requests.
+ * @param destructor Destructor function to destroy the handler object..
+ * @param lookup Callback method to get the status of one DICOM instance.
+ * @return 0 if success, other value if error.
+ * @ingroup DicomCallbacks
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterStorageCommitmentScpCallback(
+ OrthancPluginContext* context,
+ OrthancPluginStorageCommitmentFactory factory,
+ OrthancPluginStorageCommitmentDestructor destructor,
+ OrthancPluginStorageCommitmentLookup lookup)
+ {
+ _OrthancPluginRegisterStorageCommitmentScpCallback params;
+ params.factory = factory;
+ params.destructor = destructor;
+ params.lookup = lookup;
+ return context->InvokeService(context, _OrthancPluginService_RegisterStorageCommitmentScpCallback, ¶ms);
+ }
+
+
+ /**
+ * @brief Callback to filter incoming DICOM instances received by Orthanc.
+ *
+ * Signature of a callback function that is triggered whenever
+ * Orthanc receives a new DICOM instance (e.g. through REST API or
+ * DICOM protocol), and that answers whether this DICOM instance
+ * should be accepted or discarded by Orthanc.
+ *
+ * Note that the metadata information is not available
+ * (i.e. GetInstanceMetadata() should not be used on "instance").
+ *
+ * @param instance The received DICOM instance.
+ * @return 0 to discard the instance, 1 to store the instance, -1 if error.
+ * @ingroup Callback
+ **/
+ typedef int32_t (*OrthancPluginIncomingDicomInstanceFilter) (
+ const OrthancPluginDicomInstance* instance);
+
+
+ typedef struct
+ {
+ OrthancPluginIncomingDicomInstanceFilter callback;
+ } _OrthancPluginIncomingDicomInstanceFilter;
+
+ /**
+ * @brief Register a callback to filter incoming DICOM instance.
+ *
+ * This function registers a custom callback to filter incoming
+ * DICOM instances received by Orthanc (either through the REST API
+ * or through the DICOM protocol).
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param callback The callback.
+ * @return 0 if success, other value if error.
+ * @ingroup Callbacks
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingDicomInstanceFilter(
+ OrthancPluginContext* context,
+ OrthancPluginIncomingDicomInstanceFilter callback)
+ {
+ _OrthancPluginIncomingDicomInstanceFilter params;
+ params.callback = callback;
+
+ return context->InvokeService(context, _OrthancPluginService_RegisterIncomingDicomInstanceFilter, ¶ms);
+ }
+
+
+ /**
+ * @brief Get the transfer syntax of a DICOM file.
+ *
+ * This function returns a pointer to a newly created string that
+ * contains the transfer syntax UID of the DICOM instance. The empty
+ * string might be returned if this information is unknown.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param instance The instance of interest.
+ * @return The NULL value in case of error, or a string containing the
+ * transfer syntax UID. This string must be freed by OrthancPluginFreeString().
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceTransferSyntaxUid(
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
+ {
+ char* result;
+
+ _OrthancPluginAccessDicomInstance params;
+ memset(¶ms, 0, sizeof(params));
+ params.resultStringToFree = &result;
+ params.instance = instance;
+
+ if (context->InvokeService(context, _OrthancPluginService_GetInstanceTransferSyntaxUid, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return NULL;
+ }
+ else
+ {
+ return result;
+ }
+ }
+
+
+ /**
+ * @brief Check whether the DICOM file has pixel data.
+ *
+ * This function returns a Boolean value indicating whether the
+ * DICOM instance contains the pixel data (7FE0,0010) tag.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param instance The instance of interest.
+ * @return "1" if the DICOM instance contains pixel data, or "0" if
+ * the tag is missing, or "-1" in the case of an error.
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE int32_t OrthancPluginHasInstancePixelData(
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
+ {
+ int64_t hasPixelData;
+
+ _OrthancPluginAccessDicomInstance params;
+ memset(¶ms, 0, sizeof(params));
+ params.resultInt64 = &hasPixelData;
+ params.instance = instance;
+
+ if (context->InvokeService(context, _OrthancPluginService_HasInstancePixelData, ¶ms) != OrthancPluginErrorCode_Success ||
+ hasPixelData < 0 ||
+ hasPixelData > 1)
+ {
+ /* Error */
+ return -1;
+ }
+ else
+ {
+ return (hasPixelData != 0);
+ }
+ }
+
+
+
+
+
+
+ typedef struct
+ {
+ OrthancPluginDicomInstance** target;
+ const void* buffer;
+ uint32_t size;
+ const char* transferSyntax;
+ } _OrthancPluginCreateDicomInstance;
+
+ /**
+ * @brief Parse a DICOM instance.
+ *
+ * This function parses a memory buffer that contains a DICOM
+ * file. The function returns a new pointer to a data structure that
+ * is managed by the Orthanc core.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param buffer The memory buffer containing the DICOM instance.
+ * @param size The size of the memory buffer.
+ * @return The newly allocated DICOM instance. It must be freed with OrthancPluginFreeDicomInstance().
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginDicomInstance* OrthancPluginCreateDicomInstance(
+ OrthancPluginContext* context,
+ const void* buffer,
+ uint32_t size)
+ {
+ OrthancPluginDicomInstance* target = NULL;
+
+ _OrthancPluginCreateDicomInstance params;
+ params.target = ⌖
+ params.buffer = buffer;
+ params.size = size;
+
+ if (context->InvokeService(context, _OrthancPluginService_CreateDicomInstance, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return NULL;
+ }
+ else
+ {
+ return target;
+ }
+ }
+
+ typedef struct
+ {
+ OrthancPluginDicomInstance* dicom;
+ } _OrthancPluginFreeDicomInstance;
+
+ /**
+ * @brief Free a DICOM instance.
+ *
+ * This function frees a DICOM instance that was parsed using
+ * OrthancPluginCreateDicomInstance().
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param dicom The DICOM instance.
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE void OrthancPluginFreeDicomInstance(
+ OrthancPluginContext* context,
+ OrthancPluginDicomInstance* dicom)
+ {
+ _OrthancPluginFreeDicomInstance params;
+ params.dicom = dicom;
+
+ context->InvokeService(context, _OrthancPluginService_FreeDicomInstance, ¶ms);
+ }
+
+
+ typedef struct
+ {
+ uint32_t* targetUint32;
+ OrthancPluginMemoryBuffer* targetBuffer;
+ OrthancPluginImage** targetImage;
+ char** targetStringToFree;
+ const OrthancPluginDicomInstance* instance;
+ uint32_t frameIndex;
+ OrthancPluginDicomToJsonFormat format;
+ OrthancPluginDicomToJsonFlags flags;
+ uint32_t maxStringLength;
+ OrthancPluginDicomWebBinaryCallback2 dicomWebCallback;
+ void* dicomWebPayload;
+ } _OrthancPluginAccessDicomInstance2;
+
+ /**
+ * @brief Get the number of frames in a DICOM instance.
+ *
+ * This function returns the number of frames that are part of a
+ * DICOM image managed by the Orthanc core.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param instance The instance of interest.
+ * @return The number of frames (will be zero in the case of an error)..
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE uint32_t OrthancPluginGetInstanceFramesCount(
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance)
+ {
+ uint32_t count;
+
+ _OrthancPluginAccessDicomInstance2 params;
+ memset(¶ms, 0, sizeof(params));
+ params.targetUint32 = &count;
+ params.instance = instance;
+
+ if (context->InvokeService(context, _OrthancPluginService_GetInstanceFramesCount, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return 0;
+ }
+ else
+ {
+ return count;
+ }
+ }
+
+
+ /**
+ * @brief Get the raw content of a frame in a DICOM instance.
+ *
+ * This function returns a memory buffer containing the raw content
+ * of a frame in a DICOM instance that is managed by the Orthanc
+ * core. This is notably useful for compressed transfer syntaxes, as
+ * it gives access to the embedded files (such as JPEG, JPEG-LS or
+ * JPEG2k). The Orthanc core transparently reassembles the fragments
+ * to extract the raw frame.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer().
+ * @param instance The instance of interest.
+ * @param frameIndex The index of the frame of interest.
+ * @return 0 if success, or the error code if failure.
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginGetInstanceRawFrame(
+ OrthancPluginContext* context,
+ OrthancPluginMemoryBuffer* target,
+ const OrthancPluginDicomInstance* instance,
+ uint32_t frameIndex)
+ {
+ _OrthancPluginAccessDicomInstance2 params;
+ memset(¶ms, 0, sizeof(params));
+ params.targetBuffer = target;
+ params.instance = instance;
+ params.frameIndex = frameIndex;
+
+ return context->InvokeService(context, _OrthancPluginService_GetInstanceRawFrame, ¶ms);
+ }
+
+
+ /**
+ * @brief Decode one frame from a DICOM instance.
+ *
+ * This function decodes one frame of a DICOM image that is managed
+ * by the Orthanc core.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param instance The instance of interest.
+ * @param frameIndex The index of the frame of interest.
+ * @return The uncompressed image. It must be freed with OrthancPluginFreeImage().
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginImage* OrthancPluginGetInstanceDecodedFrame(
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance,
+ uint32_t frameIndex)
+ {
+ OrthancPluginImage* target = NULL;
+
+ _OrthancPluginAccessDicomInstance2 params;
+ memset(¶ms, 0, sizeof(params));
+ params.targetImage = ⌖
+ params.instance = instance;
+ params.frameIndex = frameIndex;
+
+ if (context->InvokeService(context, _OrthancPluginService_GetInstanceDecodedFrame, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ return NULL;
+ }
+ else
+ {
+ return target;
+ }
+ }
+
+
+ /**
+ * @brief Parse and transcode a DICOM instance.
+ *
+ * This function parses a memory buffer that contains a DICOM file,
+ * then transcodes it to the given transfer syntax. The function
+ * returns a new pointer to a data structure that is managed by the
+ * Orthanc core.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param buffer The memory buffer containing the DICOM instance.
+ * @param size The size of the memory buffer.
+ * @param transferSyntax The transfer syntax UID for the transcoding.
+ * @return The newly allocated DICOM instance. It must be freed with OrthancPluginFreeDicomInstance().
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginDicomInstance* OrthancPluginTranscodeDicomInstance(
+ OrthancPluginContext* context,
+ const void* buffer,
+ uint32_t size,
+ const char* transferSyntax)
+ {
+ OrthancPluginDicomInstance* target = NULL;
+
+ _OrthancPluginCreateDicomInstance params;
+ params.target = ⌖
+ params.buffer = buffer;
+ params.size = size;
+ params.transferSyntax = transferSyntax;
+
+ if (context->InvokeService(context, _OrthancPluginService_TranscodeDicomInstance, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return NULL;
+ }
+ else
+ {
+ return target;
+ }
+ }
+
+ /**
+ * @brief Writes a DICOM instance to a memory buffer.
+ *
+ * This function returns a memory buffer containing the
+ * serialization of a DICOM instance that is managed by the Orthanc
+ * core.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer().
+ * @param instance The instance of interest.
+ * @return 0 if success, or the error code if failure.
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginSerializeDicomInstance(
+ OrthancPluginContext* context,
+ OrthancPluginMemoryBuffer* target,
+ const OrthancPluginDicomInstance* instance)
+ {
+ _OrthancPluginAccessDicomInstance2 params;
+ memset(¶ms, 0, sizeof(params));
+ params.targetBuffer = target;
+ params.instance = instance;
+
+ return context->InvokeService(context, _OrthancPluginService_SerializeDicomInstance, ¶ms);
+ }
+
+
+ /**
+ * @brief Format a DICOM memory buffer as a JSON string.
+ *
+ * This function takes as DICOM instance managed by the Orthanc
+ * core, and outputs a JSON string representing the tags of this
+ * DICOM file.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param instance The DICOM instance of interest.
+ * @param format The output format.
+ * @param flags Flags governing the output.
+ * @param maxStringLength The maximum length of a field. Too long fields will
+ * be output as "null". The 0 value means no maximum length.
+ * @return The NULL value if the case of an error, or the JSON
+ * string. This string must be freed by OrthancPluginFreeString().
+ * @ingroup DicomInstance
+ * @see OrthancPluginDicomBufferToJson
+ **/
+ ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceAdvancedJson(
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance,
+ OrthancPluginDicomToJsonFormat format,
+ OrthancPluginDicomToJsonFlags flags,
+ uint32_t maxStringLength)
+ {
+ char* result = NULL;
+
+ _OrthancPluginAccessDicomInstance2 params;
+ memset(¶ms, 0, sizeof(params));
+ params.targetStringToFree = &result;
+ params.instance = instance;
+ params.format = format;
+ params.flags = flags;
+ params.maxStringLength = maxStringLength;
+
+ if (context->InvokeService(context, _OrthancPluginService_GetInstanceAdvancedJson, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return NULL;
+ }
+ else
+ {
+ return result;
+ }
+ }
+
+
+ /**
+ * @brief Convert a DICOM instance to DICOMweb JSON.
+ *
+ * This function converts a DICOM instance that is managed by the
+ * Orthanc core, into its DICOMweb JSON representation.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param instance The DICOM instance of interest.
+ * @param callback Callback to set the value of the binary tags.
+ * @param payload User payload.
+ * @return The NULL value in case of error, or the JSON document. This string must
+ * be freed by OrthancPluginFreeString().
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceDicomWebJson(
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance,
+ OrthancPluginDicomWebBinaryCallback2 callback,
+ void* payload)
+ {
+ char* target = NULL;
+
+ _OrthancPluginAccessDicomInstance2 params;
+ params.targetStringToFree = ⌖
+ params.instance = instance;
+ params.dicomWebCallback = callback;
+ params.dicomWebPayload = payload;
+
+ if (context->InvokeService(context, _OrthancPluginService_GetInstanceDicomWebJson, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return NULL;
+ }
+ else
+ {
+ return target;
+ }
+ }
+
+
+ /**
+ * @brief Convert a DICOM instance to DICOMweb XML.
+ *
+ * This function converts a DICOM instance that is managed by the
+ * Orthanc core, into its DICOMweb XML representation.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param instance The DICOM instance of interest.
+ * @param callback Callback to set the value of the binary tags.
+ * @param payload User payload.
+ * @return The NULL value in case of error, or the XML document. This string must
+ * be freed by OrthancPluginFreeString().
+ * @ingroup DicomInstance
+ **/
+ ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceDicomWebXml(
+ OrthancPluginContext* context,
+ const OrthancPluginDicomInstance* instance,
+ OrthancPluginDicomWebBinaryCallback2 callback,
+ void* payload)
+ {
+ char* target = NULL;
+
+ _OrthancPluginAccessDicomInstance2 params;
+ params.targetStringToFree = ⌖
+ params.instance = instance;
+ params.dicomWebCallback = callback;
+ params.dicomWebPayload = payload;
+
+ if (context->InvokeService(context, _OrthancPluginService_GetInstanceDicomWebXml, ¶ms) != OrthancPluginErrorCode_Success)
+ {
+ /* Error */
+ return NULL;
+ }
+ else
+ {
+ return target;
+ }
+ }
+
+
+
+ /**
+ * @brief Signature of a callback function to transcode a DICOM instance.
+ * @param transcoded Target memory buffer. It must be allocated by the
+ * plugin using OrthancPluginCreateMemoryBuffer().
+ * @param buffer Memory buffer containing the source DICOM instance.
+ * @param size Size of the source memory buffer.
+ * @param allowedSyntaxes A C array of possible transfer syntaxes UIDs for the
+ * result of the transcoding. The plugin must choose by itself the
+ * transfer syntax that will be used for the resulting DICOM image.
+ * @param countSyntaxes The number of transfer syntaxes that are contained
+ * in the "allowedSyntaxes" array.
+ * @param allowNewSopInstanceUid Whether the transcoding plugin can select
+ * a transfer syntax that will change the SOP instance UID (or, in other
+ * terms, whether the plugin can transcode using lossy compression).
+ * @return 0 if success (i.e. image successfully transcoded and stored into
+ * "transcoded"), or the error code if failure.
+ * @ingroup Callbacks
+ **/
+ typedef OrthancPluginErrorCode (*OrthancPluginTranscoderCallback) (
+ OrthancPluginMemoryBuffer* transcoded /* out */,
+ const void* buffer,
+ uint64_t size,
+ const char* const* allowedSyntaxes,
+ uint32_t countSyntaxes,
+ uint8_t allowNewSopInstanceUid);
+
+
+ typedef struct
+ {
+ OrthancPluginTranscoderCallback callback;
+ } _OrthancPluginTranscoderCallback;
+
+ /**
+ * @brief Register a callback to handle the transcoding of DICOM images.
+ *
+ * This function registers a custom callback to transcode DICOM
+ * images, extending the built-in transcoder of Orthanc that uses
+ * DCMTK. The exact behavior is affected by the configuration option
+ * "BuiltinDecoderTranscoderOrder" of Orthanc.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param callback The callback.
+ * @return 0 if success, other value if error.
+ * @ingroup Callbacks
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterTranscoderCallback(
+ OrthancPluginContext* context,
+ OrthancPluginTranscoderCallback callback)
+ {
+ _OrthancPluginTranscoderCallback params;
+ params.callback = callback;
+
+ return context->InvokeService(context, _OrthancPluginService_RegisterTranscoderCallback, ¶ms);
+ }
+
+
+
+ typedef struct
+ {
+ OrthancPluginMemoryBuffer* target;
+ uint32_t size;
+ } _OrthancPluginCreateMemoryBuffer;
+
+ /**
+ * @brief Create a memory buffer.
+ *
+ * This function creates a memory buffer that is managed by the
+ * Orthanc core. The main use case of this function is for plugins
+ * that act as DICOM transcoders.
+ *
+ * Your plugin should never call "free()" on the resulting memory
+ * buffer, as the C library that is used by the plugin is in general
+ * not the same as the one used by the Orthanc core.
+ *
+ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+ * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer().
+ * @param size Size of the memory buffer to be created.
+ * @return 0 if success, or the error code if failure.
+ * @ingroup Toolbox
+ **/
+ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginCreateMemoryBuffer(
+ OrthancPluginContext* context,
+ OrthancPluginMemoryBuffer* target,
+ uint32_t size)
+ {
+ _OrthancPluginCreateMemoryBuffer params;
+ params.target = target;
+ params.size = size;
+
+ return context->InvokeService(context, _OrthancPluginService_CreateMemoryBuffer, ¶ms);
+ }
+
+
#ifdef __cplusplus
}
#endif
=====================================
Resources/SyncOrthancFolder.py
=====================================
@@ -11,8 +11,8 @@ import stat
import urllib2
TARGET = os.path.join(os.path.dirname(__file__), 'Orthanc')
-PLUGIN_SDK_VERSION = '1.5.7'
-REPOSITORY = 'https://bitbucket.org/sjodogne/orthanc/raw'
+PLUGIN_SDK_VERSION = '1.7.0'
+REPOSITORY = 'https://hg.orthanc-server.com/orthanc/raw-file'
FILES = [
'DownloadOrthancFramework.cmake',
=====================================
Status.txt
=====================================
@@ -1,5 +1,9 @@
Reference: http://dicom.nema.org/MEDICAL/dicom/2019a/output/html/part18.html
+If you need some missing feature as an industrial player, please
+consider hiring the development team from Osimis by filling the
+dedicated form on the Orthanc Web site:
+https://www.orthanc-server.com/orthanc-pro.php
=======================================
@@ -103,7 +107,6 @@ Not supported
* GIF output
* The following "Retrieve Rendered Query Parameters" (table 6.5.8-2):
annotation, charset, iccprofile
-* URI "/studies/.../rendered" (only available for series, instances and frames)
@@ -148,6 +151,22 @@ Ignored
+===================
+6.8 RS Capabilities
+===================
+
+Not supported.
+
+
+
+===================
+6.9 UPS-RS Worklist
+===================
+
+Not supported.
+
+
+
==========================================================
CP 1509 - Refactor media type description for web services
==========================================================
View it on GitLab: https://salsa.debian.org/med-team/orthanc-dicomweb/-/commit/c12a0b6ae2530e36dd2b20f6b293196a4937ddc1
--
View it on GitLab: https://salsa.debian.org/med-team/orthanc-dicomweb/-/commit/c12a0b6ae2530e36dd2b20f6b293196a4937ddc1
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20200527/42e97f8c/attachment-0001.html>
More information about the debian-med-commit
mailing list