Mercurial > hg > orthanc
changeset 1608:adc6a5704cdb
OrthancPluginConvertPixelFormat
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 02 Sep 2015 13:58:08 +0200 |
parents | a1c92fd4d26d |
children | c74495267acf |
files | Core/ImageFormats/Image.h Core/ImageFormats/ImageBuffer.cpp Core/ImageFormats/ImageBuffer.h Core/ImageFormats/ImageProcessing.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h Plugins/Include/orthanc/OrthancCPlugin.h UnitTestsSources/ImageTests.cpp |
diffstat | 8 files changed, 170 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/ImageFormats/Image.h Wed Sep 02 13:58:08 2015 +0200 @@ -0,0 +1,55 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "ImageAccessor.h" +#include "ImageBuffer.h" + +namespace Orthanc +{ + class Image : public ImageAccessor + { + private: + ImageBuffer buffer_; + + public: + Image(PixelFormat format, + unsigned int width, + unsigned int height) : + buffer_(format, width, height) + { + ImageAccessor accessor = buffer_.GetAccessor(); + AssignWritable(format, width, height, accessor.GetPitch(), accessor.GetBuffer()); + } + }; +}
--- a/Core/ImageFormats/ImageBuffer.cpp Tue Sep 01 17:40:45 2015 +0200 +++ b/Core/ImageFormats/ImageBuffer.cpp Wed Sep 02 13:58:08 2015 +0200 @@ -85,9 +85,9 @@ } - ImageBuffer::ImageBuffer(unsigned int width, - unsigned int height, - PixelFormat format) + ImageBuffer::ImageBuffer(PixelFormat format, + unsigned int width, + unsigned int height) { Initialize(); SetWidth(width);
--- a/Core/ImageFormats/ImageBuffer.h Tue Sep 01 17:40:45 2015 +0200 +++ b/Core/ImageFormats/ImageBuffer.h Wed Sep 02 13:58:08 2015 +0200 @@ -59,9 +59,9 @@ void Deallocate(); public: - ImageBuffer(unsigned int width, - unsigned int height, - PixelFormat format); + ImageBuffer(PixelFormat format, + unsigned int width, + unsigned int height); ImageBuffer() {
--- a/Core/ImageFormats/ImageProcessing.cpp Tue Sep 01 17:40:45 2015 +0200 +++ b/Core/ImageFormats/ImageProcessing.cpp Wed Sep 02 13:58:08 2015 +0200 @@ -378,6 +378,47 @@ return; } + if (target.GetFormat() == PixelFormat_RGB24 && + source.GetFormat() == PixelFormat_RGBA32) + { + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); + uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); + for (unsigned int x = 0; x < source.GetWidth(); x++) + { + q[0] = p[0]; + q[1] = p[1]; + q[2] = p[2]; + p += 4; + q += 3; + } + } + + return; + } + + if (target.GetFormat() == PixelFormat_RGBA32 && + source.GetFormat() == PixelFormat_RGB24) + { + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); + uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); + for (unsigned int x = 0; x < source.GetWidth(); x++) + { + q[0] = p[0]; + q[1] = p[1]; + q[2] = p[2]; + q[3] = 255; // Set the alpha channel to full opacity + p += 3; + q += 4; + } + } + + return; + } + throw OrthancException(ErrorCode_NotImplemented); }
--- a/Plugins/Engine/OrthancPlugins.cpp Tue Sep 01 17:40:45 2015 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Wed Sep 02 13:58:08 2015 +0200 @@ -42,10 +42,12 @@ #include "../../OrthancServer/ServerToolbox.h" #include "../../Core/Compression/ZlibCompressor.h" #include "../../Core/Compression/GzipCompressor.h" +#include "../../Core/ImageFormats/Image.h" #include "../../Core/ImageFormats/PngReader.h" #include "../../Core/ImageFormats/PngWriter.h" #include "../../Core/ImageFormats/JpegReader.h" #include "../../Core/ImageFormats/JpegWriter.h" +#include "../../Core/ImageFormats/ImageProcessing.h" #include <boost/regex.hpp> @@ -1168,6 +1170,18 @@ } + void OrthancPlugins::ConvertPixelFormat(const void* parameters) + { + const _OrthancPluginConvertPixelFormat& p = *reinterpret_cast<const _OrthancPluginConvertPixelFormat*>(parameters); + const ImageAccessor& source = *reinterpret_cast<const ImageAccessor*>(p.source); + + std::auto_ptr<ImageAccessor> target(new Image(Convert(p.targetFormat), source.GetWidth(), source.GetHeight())); + ImageProcessing::Convert(*target, source); + + *(p.target) = reinterpret_cast<OrthancPluginImage*>(target.release()); + } + + bool OrthancPlugins::InvokeService(_OrthancPluginService service, const void* parameters) { @@ -1530,6 +1544,10 @@ CallHttpClient(parameters); return true; + case _OrthancPluginService_ConvertPixelFormat: + ConvertPixelFormat(parameters); + return true; + default: { // This service is unknown to the Orthanc plugin engine
--- a/Plugins/Engine/OrthancPlugins.h Tue Sep 01 17:40:45 2015 +0200 +++ b/Plugins/Engine/OrthancPlugins.h Wed Sep 02 13:58:08 2015 +0200 @@ -104,6 +104,8 @@ void CompressImage(const void* parameters); + void ConvertPixelFormat(const void* parameters); + void CallHttpClient(const void* parameters); public:
--- a/Plugins/Include/orthanc/OrthancCPlugin.h Tue Sep 01 17:40:45 2015 +0200 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Wed Sep 02 13:58:08 2015 +0200 @@ -437,6 +437,7 @@ _OrthancPluginService_UncompressImage = 6005, _OrthancPluginService_FreeImage = 6006, _OrthancPluginService_CompressImage = 6007, + _OrthancPluginService_ConvertPixelFormat = 6008, _OrthancPluginService_INTERNAL = 0x7fffffff } _OrthancPluginService; @@ -3272,6 +3273,48 @@ + typedef struct + { + OrthancPluginImage** target; + const OrthancPluginImage* source; + OrthancPluginPixelFormat targetFormat; + } _OrthancPluginConvertPixelFormat; + + + /** + * @brief Change the pixel format of an image. + * + * This function creates a new image, changing the memory layout of the pixels. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param source The source image. + * @param targetFormat The target pixel format. + * @return The resulting image. It must be freed with OrthancPluginFreeImage(). + * @ingroup Compression + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginImage *OrthancPluginConvertPixelFormat( + OrthancPluginContext* context, + const OrthancPluginImage* source, + OrthancPluginPixelFormat targetFormat) + { + OrthancPluginImage* target = NULL; + + _OrthancPluginConvertPixelFormat params; + params.target = ⌖ + params.source = source; + params.targetFormat = targetFormat; + + if (context->InvokeService(context, _OrthancPluginService_ConvertPixelFormat, ¶ms) != OrthancPluginErrorCode_Success) + { + return NULL; + } + else + { + return target; + } + } + + #ifdef __cplusplus } #endif
--- a/UnitTestsSources/ImageTests.cpp Tue Sep 01 17:40:45 2015 +0200 +++ b/UnitTestsSources/ImageTests.cpp Wed Sep 02 13:58:08 2015 +0200 @@ -34,7 +34,7 @@ #include "gtest/gtest.h" #include <stdint.h> -#include "../Core/ImageFormats/ImageBuffer.h" +#include "../Core/ImageFormats/Image.h" #include "../Core/ImageFormats/PngReader.h" #include "../Core/ImageFormats/PngWriter.h" #include "../Core/ImageFormats/JpegReader.h" @@ -196,11 +196,10 @@ std::string s; { - Orthanc::ImageBuffer img(16, 16, Orthanc::PixelFormat_Grayscale8); - Orthanc::ImageAccessor accessor = img.GetAccessor(); + Orthanc::Image img(Orthanc::PixelFormat_Grayscale8, 16, 16); for (unsigned int y = 0, value = 0; y < img.GetHeight(); y++) { - uint8_t* p = reinterpret_cast<uint8_t*>(accessor.GetRow(y)); + uint8_t* p = reinterpret_cast<uint8_t*>(img.GetRow(y)); for (unsigned int x = 0; x < img.GetWidth(); x++, p++) { *p = value++; @@ -208,9 +207,9 @@ } Orthanc::JpegWriter w; - w.WriteToFile("UnitTestsResults/hello.jpg", accessor); + w.WriteToFile("UnitTestsResults/hello.jpg", img); - w.WriteToMemory(s, accessor); + w.WriteToMemory(s, img); Orthanc::Toolbox::WriteFile(s, "UnitTestsResults/hello2.jpg"); std::string t;