Mercurial > hg > orthanc
changeset 1827:4b6673e828f4
"OrthancPluginCreateImage()" and "OrthancPluginCreateImageAccessor()" to create images
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 25 Nov 2015 16:39:03 +0100 |
parents | ac5b0b4e2434 |
children | a71d74987090 |
files | NEWS OrthancServer/IDicomImageDecoder.h OrthancServer/ParsedDicomFile.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h Plugins/Include/orthanc/OrthancCPlugin.h |
diffstat | 6 files changed, 177 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Wed Nov 25 16:00:57 2015 +0100 +++ b/NEWS Wed Nov 25 16:39:03 2015 +0100 @@ -44,6 +44,7 @@ - "OrthancPluginRegisterDictionaryTag()" to declare custom DICOM tags - "OrthancPluginRestApiGet2()" to provide HTTP headers when calling Orthanc API - "OrthancPluginGetInstanceOrigin()" to know through which mechanism an instance was received + - "OrthancPluginCreateImage()" and "OrthancPluginCreateImageAccessor()" to create images * New events in change callbacks: - "OrthancStarted" - "OrthancStopped"
--- a/OrthancServer/IDicomImageDecoder.h Wed Nov 25 16:00:57 2015 +0100 +++ b/OrthancServer/IDicomImageDecoder.h Wed Nov 25 16:39:03 2015 +0100 @@ -32,7 +32,7 @@ #pragma once -#include "../Core/Images/ImageBuffer.h" +#include "../Core/Images/ImageAccessor.h" #include <boost/noncopyable.hpp>
--- a/OrthancServer/ParsedDicomFile.cpp Wed Nov 25 16:00:57 2015 +0100 +++ b/OrthancServer/ParsedDicomFile.cpp Wed Nov 25 16:39:03 2015 +0100 @@ -86,7 +86,6 @@ #include "ToDcmtkBridge.h" #include "Internals/DicomImageDecoder.h" #include "../Core/DicomFormat/DicomIntegerPixelAccessor.h" -#include "../Core/Images/ImageBuffer.h" #include "../Core/Images/JpegWriter.h" #include "../Core/Images/JpegReader.h" #include "../Core/Images/PngReader.h"
--- a/Plugins/Engine/OrthancPlugins.cpp Wed Nov 25 16:00:57 2015 +0100 +++ b/Plugins/Engine/OrthancPlugins.cpp Wed Nov 25 16:39:03 2015 +0100 @@ -430,7 +430,7 @@ sizeof(int32_t) != sizeof(OrthancPluginValueRepresentation) || sizeof(int32_t) != sizeof(OrthancPluginDicomToJsonFlags) || sizeof(int32_t) != sizeof(OrthancPluginDicomToJsonFormat) || - sizeof(int32_t) != sizeof(OrthancPluginDicomFromJsonFlags) || + sizeof(int32_t) != sizeof(OrthancPluginCreateDicomFlags) || sizeof(int32_t) != sizeof(_OrthancPluginDatabaseAnswerType) || sizeof(int32_t) != sizeof(OrthancPluginIdentifierConstraint) || sizeof(int32_t) != sizeof(OrthancPluginInstanceOrigin) || @@ -440,8 +440,8 @@ static_cast<int>(OrthancPluginDicomToJsonFlags_IncludePixelData) != static_cast<int>(DicomToJsonFlags_IncludePixelData) || static_cast<int>(OrthancPluginDicomToJsonFlags_ConvertBinaryToNull) != static_cast<int>(DicomToJsonFlags_ConvertBinaryToNull) || static_cast<int>(OrthancPluginDicomToJsonFlags_ConvertBinaryToAscii) != static_cast<int>(DicomToJsonFlags_ConvertBinaryToAscii) || - static_cast<int>(OrthancPluginDicomFromJsonFlags_DecodeDataUriScheme) != static_cast<int>(DicomFromJsonFlags_DecodeDataUriScheme) || - static_cast<int>(OrthancPluginDicomFromJsonFlags_GenerateIdentifiers) != static_cast<int>(DicomFromJsonFlags_GenerateIdentifiers)) + static_cast<int>(OrthancPluginCreateDicomFlags_DecodeDataUriScheme) != static_cast<int>(DicomFromJsonFlags_DecodeDataUriScheme) || + static_cast<int>(OrthancPluginCreateDicomFlags_GenerateIdentifiers) != static_cast<int>(DicomFromJsonFlags_GenerateIdentifiers)) { throw OrthancException(ErrorCode_Plugin); @@ -1449,11 +1449,11 @@ } - void OrthancPlugins::ApplyDicomFromJson(_OrthancPluginService service, - const void* parameters) + void OrthancPlugins::ApplyCreateDicom(_OrthancPluginService service, + const void* parameters) { - const _OrthancPluginDicomFromJson& p = - *reinterpret_cast<const _OrthancPluginDicomFromJson*>(parameters); + const _OrthancPluginCreateDicom& p = + *reinterpret_cast<const _OrthancPluginCreateDicom*>(parameters); Json::Value json; Json::Reader reader; @@ -1467,11 +1467,39 @@ { std::auto_ptr<ParsedDicomFile> file (ParsedDicomFile::CreateFromJson(json, static_cast<DicomFromJsonFlags>(p.flags))); + + if (p.pixelData) + { + file->EmbedImage(*reinterpret_cast<const ImageAccessor*>(p.pixelData)); + } + file->SaveToMemoryBuffer(dicom); } CopyToMemoryBuffer(*p.target, dicom); } + + + void OrthancPlugins::ApplyCreateImage(_OrthancPluginService service, + const void* parameters) + { + const _OrthancPluginCreateImage& p = + *reinterpret_cast<const _OrthancPluginCreateImage*>(parameters); + + std::auto_ptr<ImageAccessor> result; + + if (service == _OrthancPluginService_CreateImage) + { + result.reset(new Image(Plugins::Convert(p.format), p.width, p.height)); + } + else + { + result.reset(new ImageAccessor); + result->AssignWritable(Plugins::Convert(p.format), p.width, p.height, p.pitch, p.buffer); + } + + *(p.target) = reinterpret_cast<OrthancPluginImage*>(result.release()); + } void OrthancPlugins::DatabaseAnswer(const void* parameters) @@ -2003,8 +2031,8 @@ ApplyDicomToJson(service, parameters); return true; - case _OrthancPluginService_DicomFromJson: - ApplyDicomFromJson(service, parameters); + case _OrthancPluginService_CreateDicom: + ApplyCreateDicom(service, parameters); return true; case _OrthancPluginService_WorklistAddAnswer: @@ -2039,6 +2067,11 @@ return true; } + case _OrthancPluginService_CreateImage: + case _OrthancPluginService_CreateImageAccessor: + ApplyCreateImage(service, parameters); + return true; + default: { // This service is unknown to the Orthanc plugin engine
--- a/Plugins/Engine/OrthancPlugins.h Wed Nov 25 16:00:57 2015 +0100 +++ b/Plugins/Engine/OrthancPlugins.h Wed Nov 25 16:39:03 2015 +0100 @@ -144,8 +144,11 @@ void ApplyDicomToJson(_OrthancPluginService service, const void* parameters); - void ApplyDicomFromJson(_OrthancPluginService service, - const void* parameters); + void ApplyCreateDicom(_OrthancPluginService service, + const void* parameters); + + void ApplyCreateImage(_OrthancPluginService service, + const void* parameters); void SignalChangeInternal(OrthancPluginChangeType changeType, OrthancPluginResourceType resourceType,
--- a/Plugins/Include/orthanc/OrthancCPlugin.h Wed Nov 25 16:00:57 2015 +0100 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Wed Nov 25 16:39:03 2015 +0100 @@ -397,7 +397,7 @@ _OrthancPluginService_RegisterDictionaryTag = 20, _OrthancPluginService_DicomBufferToJson = 21, _OrthancPluginService_DicomInstanceToJson = 22, - _OrthancPluginService_DicomFromJson = 23, + _OrthancPluginService_CreateDicom = 23, /* Registration of callbacks */ _OrthancPluginService_RegisterRestCallback = 1000, @@ -471,6 +471,8 @@ _OrthancPluginService_GetFontsCount = 6009, _OrthancPluginService_GetFontInfo = 6010, _OrthancPluginService_DrawText = 6011, + _OrthancPluginService_CreateImage = 6012, + _OrthancPluginService_CreateImageAccessor = 6013, /* Primitives for handling worklists */ _OrthancPluginService_WorklistAddAnswer = 7000, @@ -670,6 +672,7 @@ /** * The possible output formats for a DICOM-to-JSON conversion. * @ingroup Toolbox + * @see OrthancPluginDicomToJson() **/ typedef enum { @@ -700,16 +703,17 @@ /** - * Flags to customize a JSON-to-DICOM conversion. + * Flags to the creation of a DICOM file. * @ingroup Toolbox + * @see OrthancPluginCreateDicom() **/ typedef enum { - OrthancPluginDicomFromJsonFlags_DecodeDataUriScheme = (1 << 0), /*!< Decode fields encoded using data URI scheme */ - OrthancPluginDicomFromJsonFlags_GenerateIdentifiers = (1 << 1), /*!< Automatically generate DICOM identifiers */ - - _OrthancPluginDicomFromJsonFlags_INTERNAL = 0x7fffffff - } OrthancPluginDicomFromJsonFlags; + OrthancPluginCreateDicomFlags_DecodeDataUriScheme = (1 << 0), /*!< Decode fields encoded using data URI scheme */ + OrthancPluginCreateDicomFlags_GenerateIdentifiers = (1 << 1), /*!< Automatically generate DICOM identifiers */ + + _OrthancPluginCreateDicomFlags_INTERNAL = 0x7fffffff + } OrthancPluginCreateDicomFlags; /** @@ -1005,7 +1009,7 @@ sizeof(int32_t) != sizeof(OrthancPluginValueRepresentation) || sizeof(int32_t) != sizeof(OrthancPluginDicomToJsonFormat) || sizeof(int32_t) != sizeof(OrthancPluginDicomToJsonFlags) || - sizeof(int32_t) != sizeof(OrthancPluginDicomFromJsonFlags) || + sizeof(int32_t) != sizeof(OrthancPluginCreateDicomFlags) || sizeof(int32_t) != sizeof(OrthancPluginIdentifierConstraint) || sizeof(int32_t) != sizeof(OrthancPluginInstanceOrigin)) { @@ -4330,39 +4334,44 @@ typedef struct { - OrthancPluginMemoryBuffer* target; - const char* json; - OrthancPluginDicomFromJsonFlags flags; - } _OrthancPluginDicomFromJson; + OrthancPluginMemoryBuffer* target; + const char* json; + const OrthancPluginImage* pixelData; + OrthancPluginCreateDicomFlags flags; + } _OrthancPluginCreateDicom; /** - * @brief Create a DICOM instance from JSON. + * @brief Create a DICOM instance from a JSON string and an image. * * This function takes as input a string containing a JSON file * describing the content of a DICOM instance. As an output, it * writes the corresponding DICOM instance to a newly allocated - * memory buffer. + * memory buffer. Additionally, an image to be encoded within the + * DICOM instance can also be provided. * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param json The input JSON file. + * @param pixelData The image. Can be NULL, if the pixel data is encoded inside the JSON with the data URI scheme. * @param flags Flags governing the output. * @return 0 if success, other value if error. * @ingroup Toolbox * @see OrthancPluginDicomBufferToJson **/ - ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginDicomFromJson( - OrthancPluginContext* context, - OrthancPluginMemoryBuffer* target, - const char* json, - OrthancPluginDicomFromJsonFlags flags) + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginCreateDicom( + OrthancPluginContext* context, + OrthancPluginMemoryBuffer* target, + const char* json, + const OrthancPluginImage* pixelData, + OrthancPluginCreateDicomFlags flags) { - _OrthancPluginDicomFromJson params; + _OrthancPluginCreateDicom params; params.target = target; params.json = json; + params.pixelData = pixelData; params.flags = flags; - return context->InvokeService(context, _OrthancPluginService_DicomFromJson, ¶ms); + return context->InvokeService(context, _OrthancPluginService_CreateDicom, ¶ms); } @@ -4391,6 +4400,104 @@ context->InvokeService(context, _OrthancPluginService_RegisterDecodeImageCallback, ¶ms); } + + + typedef struct + { + OrthancPluginImage** target; + OrthancPluginPixelFormat format; + uint32_t width; + uint32_t height; + uint32_t pitch; + void* buffer; + } _OrthancPluginCreateImage; + + + /** + * @brief Create an image. + * + * This function creates an image of given size and format. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param format The format of the pixels. + * @param width The width of the image. + * @param height The height of the image. + * @return The newly allocated image. It must be freed with OrthancPluginFreeImage(). + * @ingroup Images + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginImage* OrthancPluginCreateImage( + OrthancPluginContext* context, + OrthancPluginPixelFormat format, + uint32_t width, + uint32_t height) + { + OrthancPluginImage* target = NULL; + + _OrthancPluginCreateImage params; + memset(¶ms, 0, sizeof(params)); + params.target = ⌖ + params.format = format; + params.width = width; + params.height = height; + + if (context->InvokeService(context, _OrthancPluginService_CreateImage, ¶ms) != OrthancPluginErrorCode_Success) + { + return NULL; + } + else + { + return target; + } + } + + + /** + * @brief Create an image pointing to a memory buffer. + * + * This function creates an image whose content points to a memory + * buffer managed by the plugin. Note that the buffer is directly + * accessed, no memory is allocated and no data is copied. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param format The format of the pixels. + * @param width The width of the image. + * @param height The height of the image. + * @param pitch The pitch of the image (i.e. the number of bytes + * between 2 successive lines of the image in the memory buffer). + * @param buffer The memory buffer. + * @return The newly allocated image. It must be freed with OrthancPluginFreeImage(). + * @ingroup Images + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginImage* OrthancPluginCreateImageAccessor( + OrthancPluginContext* context, + OrthancPluginPixelFormat format, + uint32_t width, + uint32_t height, + uint32_t pitch, + void* buffer) + { + OrthancPluginImage* target = NULL; + + _OrthancPluginCreateImage params; + memset(¶ms, 0, sizeof(params)); + params.target = ⌖ + params.format = format; + params.width = width; + params.height = height; + params.pitch = pitch; + params.buffer = buffer; + + if (context->InvokeService(context, _OrthancPluginService_CreateImageAccessor, ¶ms) != OrthancPluginErrorCode_Success) + { + return NULL; + } + else + { + return target; + } + } + + #ifdef __cplusplus } #endif