Mercurial > hg > orthanc
changeset 3205:6c86d4d407da
new in plugin sdk: OrthancPluginEncodeDicomWebJson() and OrthancPluginEncodeDicomWebXml()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 06 Feb 2019 18:01:43 +0100 |
parents | 8792867b739a |
children | d9e3d3340918 |
files | NEWS Plugins/Engine/OrthancPlugins.cpp Plugins/Include/orthanc/OrthancCPlugin.h Plugins/Samples/Basic/Plugin.c |
diffstat | 4 files changed, 243 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Wed Feb 06 16:46:08 2019 +0100 +++ b/NEWS Wed Feb 06 18:01:43 2019 +0100 @@ -22,7 +22,12 @@ Plugins ------- -* New primitives in the plugin SDK to set and refresh metrics +* New functions in the SDK: + - OrthancPluginSetMetricsValue() to set the value of a metrics + - OrthancPluginRegisterRefreshMetricsCallback() to ask to refresh metrics + - OrthancPluginEncodeDicomWebJson() to convert DICOM to "application/dicom+json" + - OrthancPluginEncodeDicomWebXml() to convert DICOM to "application/dicom+xml" +* New function: * New extensions in the database SDK: LookupResourceAndParent and GetAllMetadata Maintenance
--- a/Plugins/Engine/OrthancPlugins.cpp Wed Feb 06 16:46:08 2019 +0100 +++ b/Plugins/Engine/OrthancPlugins.cpp Wed Feb 06 18:01:43 2019 +0100 @@ -47,6 +47,7 @@ #include "../../Core/Compression/GzipCompressor.h" #include "../../Core/Compression/ZlibCompressor.h" #include "../../Core/DicomFormat/DicomArray.h" +#include "../../Core/DicomParsing/DicomWebJsonVisitor.h" #include "../../Core/DicomParsing/FromDcmtkBridge.h" #include "../../Core/DicomParsing/Internals/DicomImageDecoder.h" #include "../../Core/DicomParsing/ToDcmtkBridge.h" @@ -313,6 +314,94 @@ return parameters_[i]; } }; + + + class DicomWebBinaryFormatter : public DicomWebJsonVisitor::IBinaryFormatter + { + private: + OrthancPluginDicomWebBinaryCallback callback_; + DicomWebJsonVisitor::BinaryMode currentMode_; + std::string currentBulkDataUri_; + + static void Setter(OrthancPluginDicomWebNode* node, + OrthancPluginDicomWebBinaryMode mode, + const char* bulkDataUri) + { + DicomWebBinaryFormatter& that = *reinterpret_cast<DicomWebBinaryFormatter*>(node); + + switch (mode) + { + case OrthancPluginDicomWebBinaryMode_Ignore: + that.currentMode_ = DicomWebJsonVisitor::BinaryMode_Ignore; + break; + + case OrthancPluginDicomWebBinaryMode_InlineBinary: + that.currentMode_ = DicomWebJsonVisitor::BinaryMode_InlineBinary; + break; + + case OrthancPluginDicomWebBinaryMode_BulkDataUri: + if (bulkDataUri == NULL) + { + throw OrthancException(ErrorCode_NullPointer); + } + + that.currentBulkDataUri_ = bulkDataUri; + that.currentMode_ = DicomWebJsonVisitor::BinaryMode_BulkDataUri; + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } + + public: + DicomWebBinaryFormatter(const _OrthancPluginEncodeDicomWeb& parameters) : + callback_(parameters.callback) + { + } + + virtual DicomWebJsonVisitor::BinaryMode Format(std::string& bulkDataUri, + const std::vector<DicomTag>& parentTags, + const std::vector<size_t>& parentIndexes, + const DicomTag& tag, + ValueRepresentation vr) + { + if (callback_ == NULL) + { + return DicomWebJsonVisitor::BinaryMode_InlineBinary; + } + else + { + assert(parentTags.size() == parentIndexes.size()); + std::vector<uint16_t> groups(parentTags.size()); + std::vector<uint16_t> elements(parentTags.size()); + std::vector<uint32_t> indexes(parentTags.size()); + + for (size_t i = 0; i < parentTags.size(); i++) + { + groups[i] = parentTags[i].GetGroup(); + elements[i] = parentTags[i].GetElement(); + indexes[i] = static_cast<uint32_t>(parentIndexes[i]); + } + bool empty = parentTags.empty(); + + currentMode_ = DicomWebJsonVisitor::BinaryMode_Ignore; + + callback_(reinterpret_cast<OrthancPluginDicomWebNode*>(this), + DicomWebBinaryFormatter::Setter, + static_cast<uint32_t>(parentTags.size()), + (empty ? NULL : &groups[0]), + (empty ? NULL : &elements[0]), + (empty ? NULL : &indexes[0]), + tag.GetGroup(), + tag.GetElement(), + Plugins::Convert(vr)); + + bulkDataUri = currentBulkDataUri_; + return currentMode_; + } + } + }; } @@ -3140,6 +3229,37 @@ return true; } + case _OrthancPluginService_EncodeDicomWebJson: + case _OrthancPluginService_EncodeDicomWebXml: + { + const _OrthancPluginEncodeDicomWeb& p = + *reinterpret_cast<const _OrthancPluginEncodeDicomWeb*>(parameters); + + DicomWebBinaryFormatter formatter(p); + + DicomWebJsonVisitor visitor; + visitor.SetFormatter(formatter); + + { + ParsedDicomFile dicom(p.dicom, p.dicomSize); + dicom.Apply(visitor); + } + + std::string s; + + if (service == _OrthancPluginService_EncodeDicomWebJson) + { + s = visitor.GetResult().toStyledString(); + } + else + { + visitor.FormatXml(s); + } + + *p.target = CopyString(s); + return true; + } + default: return false; }
--- a/Plugins/Include/orthanc/OrthancCPlugin.h Wed Feb 06 16:46:08 2019 +0100 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Wed Feb 06 18:01:43 2019 +0100 @@ -426,6 +426,8 @@ _OrthancPluginService_RegisterPrivateDictionaryTag = 29, _OrthancPluginService_AutodetectMimeType = 30, _OrthancPluginService_SetMetricsValue = 31, + _OrthancPluginService_EncodeDicomWebJson = 32, + _OrthancPluginService_EncodeDicomWebXml = 33, /* Registration of callbacks */ _OrthancPluginService_RegisterRestCallback = 1000, @@ -6625,6 +6627,94 @@ context->InvokeService(context, _OrthancPluginService_RegisterRefreshMetricsCallback, ¶ms); } + + + + typedef enum + { + OrthancPluginDicomWebBinaryMode_Ignore, + OrthancPluginDicomWebBinaryMode_InlineBinary, + OrthancPluginDicomWebBinaryMode_BulkDataUri + } OrthancPluginDicomWebBinaryMode; + + + typedef struct _OrthancPluginDicomWebNode_t OrthancPluginDicomWebNode; + + typedef void (*OrthancPluginDicomWebSetBinaryNode) ( + OrthancPluginDicomWebNode* node, + OrthancPluginDicomWebBinaryMode mode, + const char* bulkDataUri); + + typedef OrthancPluginErrorCode (*OrthancPluginDicomWebBinaryCallback) ( + 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); + + typedef struct + { + char** target; + const void* dicom; + uint32_t dicomSize; + OrthancPluginDicomWebBinaryCallback callback; + } _OrthancPluginEncodeDicomWeb; + + ORTHANC_PLUGIN_INLINE char* OrthancPluginEncodeDicomWebJson( + OrthancPluginContext* context, + const void* dicom, + uint32_t dicomSize, + OrthancPluginDicomWebBinaryCallback callback) + { + char* target = NULL; + + _OrthancPluginEncodeDicomWeb params; + params.target = ⌖ + params.dicom = dicom; + params.dicomSize = dicomSize; + params.callback = callback; + + if (context->InvokeService(context, _OrthancPluginService_EncodeDicomWebJson, ¶ms) != OrthancPluginErrorCode_Success) + { + /* Error */ + return NULL; + } + else + { + return target; + } + } + + ORTHANC_PLUGIN_INLINE char* OrthancPluginEncodeDicomWebXml( + OrthancPluginContext* context, + const void* dicom, + uint32_t dicomSize, + OrthancPluginDicomWebBinaryCallback callback) + { + char* target = NULL; + + _OrthancPluginEncodeDicomWeb params; + params.target = ⌖ + params.dicom = dicom; + params.dicomSize = dicomSize; + params.callback = callback; + + if (context->InvokeService(context, _OrthancPluginService_EncodeDicomWebXml, ¶ms) != OrthancPluginErrorCode_Success) + { + /* Error */ + return NULL; + } + else + { + return target; + } + } + + #ifdef __cplusplus } #endif
--- a/Plugins/Samples/Basic/Plugin.c Wed Feb 06 16:46:08 2019 +0100 +++ b/Plugins/Samples/Basic/Plugin.c Wed Feb 06 18:01:43 2019 +0100 @@ -263,6 +263,21 @@ } +ORTHANC_PLUGINS_API OrthancPluginErrorCode DicomWebBinaryCallback( + 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) +{ + setter(node, OrthancPluginDicomWebBinaryMode_BulkDataUri, "HelloURI"); +} + + ORTHANC_PLUGINS_API OrthancPluginErrorCode OnStoredCallback(OrthancPluginDicomInstance* instance, const char* instanceId) { @@ -286,9 +301,7 @@ json = OrthancPluginGetInstanceSimplifiedJson(context, instance); if (first) { - /* Only print the first DICOM instance */ printf("[%s]\n", json); - first = 0; } OrthancPluginFreeString(context, json); @@ -301,6 +314,18 @@ OrthancPluginLogError(context, "Instance has no reception date, should never happen!"); } + json = OrthancPluginEncodeDicomWebXml(context, + OrthancPluginGetInstanceData(context, instance), + OrthancPluginGetInstanceSize(context, instance), + DicomWebBinaryCallback); + if (first) + { + printf("[%s]\n", json); + first = 0; /* Only print the first DICOM instance */ + } + OrthancPluginFreeString(context, json); + + return OrthancPluginErrorCode_Success; }