# HG changeset patch # User Sebastien Jodogne # Date 1464689518 -7200 # Node ID f6c88aa6efe0712ef3b6ce0c4632ddf581a5a102 # Parent e8cfda4c8a2f9e92da3f4c7515fefdece8fc3403 sync diff -r e8cfda4c8a2f -r f6c88aa6efe0 Orthanc/Core/Enumerations.cpp --- a/Orthanc/Core/Enumerations.cpp Fri Apr 15 21:44:03 2016 +0200 +++ b/Orthanc/Core/Enumerations.cpp Tue May 31 12:11:58 2016 +0200 @@ -37,6 +37,7 @@ #include "Toolbox.h" #include +#include namespace Orthanc { @@ -328,6 +329,9 @@ case ErrorCode_NoWorklistHandler: return "No request handler factory for DICOM C-Find Modality SCP"; + case ErrorCode_AlreadyExistingTag: + return "Cannot override the value of a tag that already exists"; + default: if (error >= ErrorCode_START_PLUGINS) { @@ -737,6 +741,9 @@ case PixelFormat_SignedGrayscale16: return "Grayscale (signed 16bpp)"; + case PixelFormat_Float32: + return "Grayscale (float 32bpp)"; + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -910,6 +917,10 @@ case PixelFormat_RGBA32: return 4; + case PixelFormat_Float32: + assert(sizeof(float) == 4); + return 4; + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } diff -r e8cfda4c8a2f -r f6c88aa6efe0 Orthanc/Core/Enumerations.h --- a/Orthanc/Core/Enumerations.h Fri Apr 15 21:44:03 2016 +0200 +++ b/Orthanc/Core/Enumerations.h Tue May 31 12:11:58 2016 +0200 @@ -139,6 +139,7 @@ ErrorCode_SslDisabled = 2039 /*!< Orthanc has been built without SSL support */, ErrorCode_CannotOrderSlices = 2040 /*!< Unable to order the slices of the series */, ErrorCode_NoWorklistHandler = 2041 /*!< No request handler factory for DICOM C-Find Modality SCP */, + ErrorCode_AlreadyExistingTag = 2042 /*!< Cannot override the value of a tag that already exists */, ErrorCode_START_PLUGINS = 1000000 }; @@ -186,7 +187,13 @@ * {summary}{Graylevel, signed 16bpp image.} * {description}{The image is graylevel. Each pixel is signed and stored in two bytes.} **/ - PixelFormat_SignedGrayscale16 = 5 + PixelFormat_SignedGrayscale16 = 5, + + /** + * {summary}{Graylevel, floating-point image.} + * {description}{The image is graylevel. Each pixel is floating-point and stored in 4 bytes.} + **/ + PixelFormat_Float32 = 6 }; diff -r e8cfda4c8a2f -r f6c88aa6efe0 Orthanc/Core/Images/ImageAccessor.cpp --- a/Orthanc/Core/Images/ImageAccessor.cpp Fri Apr 15 21:44:03 2016 +0200 +++ b/Orthanc/Core/Images/ImageAccessor.cpp Tue May 31 12:11:58 2016 +0200 @@ -65,7 +65,7 @@ for (unsigned int x = 0; x < source.GetWidth(); x++, p++) { - s += boost::lexical_cast(static_cast(*p)) + " "; + s += boost::lexical_cast(static_cast(*p)) + " "; } target.AddChunk(s); @@ -221,6 +221,10 @@ ToMatlabStringInternal(buffer, *this); break; + case PixelFormat_Float32: + ToMatlabStringInternal(buffer, *this); + break; + case PixelFormat_RGB24: RGB24ToMatlabString(buffer, *this); break; diff -r e8cfda4c8a2f -r f6c88aa6efe0 Orthanc/Core/Images/ImageProcessing.cpp --- a/Orthanc/Core/Images/ImageProcessing.cpp Fri Apr 15 21:44:03 2016 +0200 +++ b/Orthanc/Core/Images/ImageProcessing.cpp Tue May 31 12:11:58 2016 +0200 @@ -75,9 +75,28 @@ } + template + static void ConvertGrayscaleToFloat(ImageAccessor& target, + const ImageAccessor& source) + { + assert(sizeof(float) == 4); + + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + float* t = reinterpret_cast(target.GetRow(y)); + const SourceType* s = reinterpret_cast(source.GetConstRow(y)); + + for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++) + { + *t = static_cast(*s); + } + } + } + + template static void ConvertColorToGrayscale(ImageAccessor& target, - const ImageAccessor& source) + const ImageAccessor& source) { assert(source.GetFormat() == PixelFormat_RGB24); @@ -378,6 +397,27 @@ return; } + if (target.GetFormat() == PixelFormat_Float32 && + source.GetFormat() == PixelFormat_Grayscale8) + { + ConvertGrayscaleToFloat(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Float32 && + source.GetFormat() == PixelFormat_Grayscale16) + { + ConvertGrayscaleToFloat(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Float32 && + source.GetFormat() == PixelFormat_SignedGrayscale16) + { + ConvertGrayscaleToFloat(target, source); + return; + } + if (target.GetFormat() == PixelFormat_Grayscale8 && source.GetFormat() == PixelFormat_RGBA32) { @@ -438,6 +478,47 @@ return; } + if (target.GetFormat() == PixelFormat_RGB24 && + source.GetFormat() == PixelFormat_Grayscale8) + { + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + const uint8_t* p = reinterpret_cast(source.GetConstRow(y)); + uint8_t* q = reinterpret_cast(target.GetRow(y)); + for (unsigned int x = 0; x < source.GetWidth(); x++) + { + q[0] = *p; + q[1] = *p; + q[2] = *p; + p += 1; + q += 3; + } + } + + return; + } + + if (target.GetFormat() == PixelFormat_RGBA32 && + source.GetFormat() == PixelFormat_Grayscale8) + { + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + const uint8_t* p = reinterpret_cast(source.GetConstRow(y)); + uint8_t* q = reinterpret_cast(target.GetRow(y)); + for (unsigned int x = 0; x < source.GetWidth(); x++) + { + q[0] = *p; + q[1] = *p; + q[2] = *p; + q[3] = 255; + p += 1; + q += 4; + } + } + + return; + } + throw OrthancException(ErrorCode_NotImplemented); } @@ -460,6 +541,11 @@ SetInternal(image, value); return; + case PixelFormat_Float32: + assert(sizeof(float) == 4); + SetInternal(image, value); + return; + default: throw OrthancException(ErrorCode_NotImplemented); } diff -r e8cfda4c8a2f -r f6c88aa6efe0 Orthanc/Core/Toolbox.cpp --- a/Orthanc/Core/Toolbox.cpp Fri Apr 15 21:44:03 2016 +0200 +++ b/Orthanc/Core/Toolbox.cpp Tue May 31 12:11:58 2016 +0200 @@ -582,12 +582,24 @@ void Toolbox::DecodeBase64(std::string& result, const std::string& data) { + for (size_t i = 0; i < data.length(); i++) + { + if (!isalnum(data[i]) && + data[i] != '+' && + data[i] != '/' && + data[i] != '=') + { + // This is not a valid character for a Base64 string + throw OrthancException(ErrorCode_BadFileFormat); + } + } + result = base64_decode(data); } # if BOOST_HAS_REGEX == 1 - void Toolbox::DecodeDataUriScheme(std::string& mime, + bool Toolbox::DecodeDataUriScheme(std::string& mime, std::string& content, const std::string& source) { @@ -599,10 +611,11 @@ { mime = what[1]; DecodeBase64(content, what[2]); + return true; } else { - throw OrthancException(ErrorCode_BadFileFormat); + return false; } } # endif diff -r e8cfda4c8a2f -r f6c88aa6efe0 Orthanc/Core/Toolbox.h --- a/Orthanc/Core/Toolbox.h Fri Apr 15 21:44:03 2016 +0200 +++ b/Orthanc/Core/Toolbox.h Tue May 31 12:11:58 2016 +0200 @@ -127,7 +127,7 @@ const std::string& data); # if BOOST_HAS_REGEX == 1 - void DecodeDataUriScheme(std::string& mime, + bool DecodeDataUriScheme(std::string& mime, std::string& content, const std::string& source); # endif diff -r e8cfda4c8a2f -r f6c88aa6efe0 Orthanc/Resources/CMake/BoostConfiguration.cmake --- a/Orthanc/Resources/CMake/BoostConfiguration.cmake Fri Apr 15 21:44:03 2016 +0200 +++ b/Orthanc/Resources/CMake/BoostConfiguration.cmake Tue May 31 12:11:58 2016 +0200 @@ -42,7 +42,7 @@ # Parameters for Boost 1.60.0 set(BOOST_NAME boost_1_60_0) set(BOOST_BCP_SUFFIX bcpdigest-1.0.1) - set(BOOST_MD5 "0646971514a1e012fbe382c5662a8605") + set(BOOST_MD5 "a789f8ec2056ad1c2d5f0cb64687cc7b") set(BOOST_URL "http://www.montefiore.ulg.ac.be/~jodogne/Orthanc/ThirdPartyDownloads/${BOOST_NAME}_${BOOST_BCP_SUFFIX}.tar.gz") set(BOOST_FILESYSTEM_SOURCES_DIR "${BOOST_NAME}/libs/filesystem/src") set(BOOST_SOURCES_DIR ${CMAKE_BINARY_DIR}/${BOOST_NAME})