Mercurial > hg > orthanc-wsi
changeset 130:4f3945a2b725
sync
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 22 Mar 2018 17:32:05 +0100 |
parents | 806d1bb56918 |
children | 3112e5edb8b6 |
files | Applications/CMakeLists.txt Applications/Dicomizer.cpp Resources/Orthanc/Core/Enumerations.cpp Resources/Orthanc/Core/Enumerations.h Resources/Orthanc/Core/HttpClient.cpp Resources/Orthanc/Core/Images/ImageAccessor.h Resources/Orthanc/Core/Images/ImageProcessing.cpp Resources/Orthanc/Core/Images/ImageProcessing.h Resources/Orthanc/Core/Images/PixelTraits.h Resources/Orthanc/Core/Logging.cpp Resources/Orthanc/Core/Logging.h Resources/Orthanc/Core/SystemToolbox.cpp Resources/Orthanc/Core/SystemToolbox.h Resources/Orthanc/NEWS Resources/Orthanc/Resources/CMake/JsonCppConfiguration.cmake Resources/SyncOrthancFolder.py ViewerPlugin/CMakeLists.txt |
diffstat | 17 files changed, 1893 insertions(+), 134 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/CMakeLists.txt Fri Feb 02 18:11:32 2018 +0100 +++ b/Applications/CMakeLists.txt Thu Mar 22 17:32:05 2018 +0100 @@ -100,6 +100,7 @@ -DORTHANC_ENABLE_JPEG=1 -DORTHANC_ENABLE_LOCALE=1 -DORTHANC_ENABLE_LOGGING=1 + -DORTHANC_ENABLE_LOGGING_STDIO=0 -DORTHANC_ENABLE_LOGGING_PLUGIN=0 -DORTHANC_ENABLE_LUA=0 # For FromDcmtkBridge -DORTHANC_ENABLE_MD5=0
--- a/Applications/Dicomizer.cpp Fri Feb 02 18:11:32 2018 +0100 +++ b/Applications/Dicomizer.cpp Thu Mar 22 17:32:05 2018 +0100 @@ -275,7 +275,7 @@ OrthancWSI::DicomToolbox::SetStringTag(*dataset, DCM_ImageOrientationSlide, "0\\-1\\0\\-1\\0\\0"); std::string date, time; - Orthanc::SystemToolbox::GetNowDicom(date, time); + Orthanc::SystemToolbox::GetNowDicom(date, time, true /* use UTC time (not local time) */); OrthancWSI::DicomToolbox::SetStringTag(*dataset, DCM_StudyDate, date); OrthancWSI::DicomToolbox::SetStringTag(*dataset, DCM_StudyTime, time); OrthancWSI::DicomToolbox::SetStringTag(*dataset, DCM_SeriesDate, date);
--- a/Resources/Orthanc/Core/Enumerations.cpp Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/Enumerations.cpp Thu Mar 22 17:32:05 2018 +0100 @@ -161,6 +161,9 @@ case ErrorCode_NullPointer: return "Cannot handle a NULL pointer"; + case ErrorCode_DatabaseUnavailable: + return "The database is currently not available (probably a transient situation)"; + case ErrorCode_SQLiteNotOpened: return "SQLite: The database is not opened"; @@ -1617,6 +1620,9 @@ case ErrorCode_NotAcceptable: return HttpStatus_406_NotAcceptable; + case ErrorCode_DatabaseUnavailable: + return HttpStatus_503_ServiceUnavailable; + default: return HttpStatus_500_InternalServerError; }
--- a/Resources/Orthanc/Core/Enumerations.h Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/Enumerations.h Thu Mar 22 17:32:05 2018 +0100 @@ -35,6 +35,16 @@ #include <string> + +#if defined(_MSC_VER) +# define ORTHANC_FORCE_INLINE __forceinline +#elif defined(__GNUC__) || defined(__clang__) || defined(__EMSCRIPTEN__) +# define ORTHANC_FORCE_INLINE inline __attribute((always_inline)) +#else +# error Please support your compiler here +#endif + + namespace Orthanc { enum Endianness @@ -85,6 +95,7 @@ ErrorCode_EmptyRequest = 33 /*!< The request is empty */, ErrorCode_NotAcceptable = 34 /*!< Cannot send a response which is acceptable according to the Accept HTTP header */, ErrorCode_NullPointer = 35 /*!< Cannot handle a NULL pointer */, + ErrorCode_DatabaseUnavailable = 36 /*!< The database is currently not available (probably a transient situation) */, ErrorCode_SQLiteNotOpened = 1000 /*!< SQLite: The database is not opened */, ErrorCode_SQLiteAlreadyOpened = 1001 /*!< SQLite: Connection is already open */, ErrorCode_SQLiteCannotOpen = 1002 /*!< SQLite: Unable to open the database */,
--- a/Resources/Orthanc/Core/HttpClient.cpp Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/HttpClient.cpp Thu Mar 22 17:32:05 2018 +0100 @@ -88,7 +88,7 @@ return GetHttpStatus(curl_easy_perform(curl), curl, status); #else LOG(ERROR) << "Orthanc was compiled without SSL support, cannot make HTTPS request"; - throw OrthancException(ErrorCode_InternalError); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); #endif } }
--- a/Resources/Orthanc/Core/Images/ImageAccessor.h Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/Images/ImageAccessor.h Thu Mar 22 17:32:05 2018 +0100 @@ -43,6 +43,9 @@ class ImageAccessor { private: + template <Orthanc::PixelFormat Format> + friend struct ImageTraits; + bool readOnly_; PixelFormat format_; unsigned int width_; @@ -50,6 +53,23 @@ unsigned int pitch_; uint8_t *buffer_; + template <typename T> + const T& GetPixelUnchecked(unsigned int x, + unsigned int y) const + { + const uint8_t* row = reinterpret_cast<const uint8_t*>(buffer_) + y * pitch_; + return reinterpret_cast<const T*>(row) [x]; + } + + + template <typename T> + T& GetPixelUnchecked(unsigned int x, + unsigned int y) + { + uint8_t* row = reinterpret_cast<uint8_t*>(buffer_) + y * pitch_; + return reinterpret_cast<T*>(row) [x]; + } + public: ImageAccessor() {
--- a/Resources/Orthanc/Core/Images/ImageProcessing.cpp Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/Images/ImageProcessing.cpp Thu Mar 22 17:32:05 2018 +0100 @@ -34,7 +34,7 @@ #include "../PrecompiledHeaders.h" #include "ImageProcessing.h" -#include "../OrthancException.h" +#include "PixelTraits.h" #include <boost/math/special_functions/round.hpp> @@ -114,7 +114,7 @@ // Y = 0.2126 R + 0.7152 G + 0.0722 B int32_t v = (2126 * static_cast<int32_t>(s[0]) + 7152 * static_cast<int32_t>(s[1]) + - 0722 * static_cast<int32_t>(s[2])) / 1000; + 0722 * static_cast<int32_t>(s[2])) / 10000; if (static_cast<int32_t>(v) < static_cast<int32_t>(minValue)) { @@ -166,11 +166,13 @@ minValue = std::numeric_limits<PixelType>::max(); maxValue = std::numeric_limits<PixelType>::min(); + const unsigned int width = source.GetWidth(); + for (unsigned int y = 0; y < source.GetHeight(); y++) { const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, p++) + for (unsigned int x = 0; x < width; x++, p++) { if (*p < minValue) { @@ -225,9 +227,10 @@ - template <typename PixelType> - void MultiplyConstantInternal(ImageAccessor& image, - float factor) + template <typename PixelType, + bool UseRound> + static void MultiplyConstantInternal(ImageAccessor& image, + float factor) { if (std::abs(factor - 1.0f) <= std::numeric_limits<float>::epsilon()) { @@ -236,14 +239,24 @@ const int64_t minValue = std::numeric_limits<PixelType>::min(); const int64_t maxValue = std::numeric_limits<PixelType>::max(); + const unsigned int width = image.GetWidth(); for (unsigned int y = 0; y < image.GetHeight(); y++) { PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); - for (unsigned int x = 0; x < image.GetWidth(); x++, p++) + for (unsigned int x = 0; x < width; x++, p++) { - int64_t v = boost::math::llround(static_cast<float>(*p) * factor); + int64_t v; + if (UseRound) + { + // The "round" operation is very costly + v = boost::math::llround(static_cast<float>(*p) * factor); + } + else + { + v = static_cast<int64_t>(static_cast<float>(*p) * factor); + } if (v > maxValue) { @@ -262,33 +275,44 @@ } - template <typename PixelType> - void ShiftScaleInternal(ImageAccessor& image, - float offset, - float scaling) + template <typename PixelType, + bool UseRound> + static void ShiftScaleInternal(ImageAccessor& image, + float offset, + float scaling) { - const float minValue = static_cast<float>(std::numeric_limits<PixelType>::min()); - const float maxValue = static_cast<float>(std::numeric_limits<PixelType>::max()); + const float minFloatValue = static_cast<float>(std::numeric_limits<PixelType>::min()); + const float maxFloatValue = static_cast<float>(std::numeric_limits<PixelType>::max()); + const PixelType minPixelValue = std::numeric_limits<PixelType>::min(); + const PixelType maxPixelValue = std::numeric_limits<PixelType>::max(); - for (unsigned int y = 0; y < image.GetHeight(); y++) + const unsigned int height = image.GetHeight(); + const unsigned int width = image.GetWidth(); + + for (unsigned int y = 0; y < height; y++) { PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); - for (unsigned int x = 0; x < image.GetWidth(); x++, p++) + for (unsigned int x = 0; x < width; x++, p++) { float v = (static_cast<float>(*p) + offset) * scaling; - if (v > maxValue) + if (v > maxFloatValue) { - *p = std::numeric_limits<PixelType>::max(); + *p = maxPixelValue; } - else if (v < minValue) + else if (v < minFloatValue) { - *p = std::numeric_limits<PixelType>::min(); + *p = minPixelValue; + } + else if (UseRound) + { + // The "round" operation is very costly + *p = static_cast<PixelType>(boost::math::iround(v)); } else { - *p = static_cast<PixelType>(boost::math::iround(v)); + *p = static_cast<PixelType>(v); } } } @@ -548,6 +572,63 @@ } if (target.GetFormat() == PixelFormat_BGRA32 && + source.GetFormat() == PixelFormat_Grayscale16) + { + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y)); + uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); + for (unsigned int x = 0; x < source.GetWidth(); x++) + { + uint8_t value = (*p < 256 ? *p : 255); + q[0] = value; + q[1] = value; + q[2] = value; + q[3] = 255; + p += 1; + q += 4; + } + } + + return; + } + + if (target.GetFormat() == PixelFormat_BGRA32 && + source.GetFormat() == PixelFormat_SignedGrayscale16) + { + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + const int16_t* p = reinterpret_cast<const int16_t*>(source.GetConstRow(y)); + uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); + for (unsigned int x = 0; x < source.GetWidth(); x++) + { + uint8_t value; + if (*p < 0) + { + value = 0; + } + else if (*p > 255) + { + value = 255; + } + else + { + value = static_cast<uint8_t>(*p); + } + + q[0] = value; + q[1] = value; + q[2] = value; + q[3] = 255; + p += 1; + q += 4; + } + } + + return; + } + + if (target.GetFormat() == PixelFormat_BGRA32 && source.GetFormat() == PixelFormat_RGB24) { for (unsigned int y = 0; y < source.GetHeight(); y++) @@ -599,19 +680,40 @@ switch (image.GetFormat()) { case PixelFormat_Grayscale8: - SetInternal<uint8_t>(image, value); + memset(image.GetBuffer(), static_cast<uint8_t>(value), image.GetPitch() * image.GetHeight()); return; case PixelFormat_Grayscale16: - SetInternal<uint16_t>(image, value); + if (value == 0) + { + memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight()); + } + else + { + SetInternal<uint16_t>(image, value); + } return; case PixelFormat_Grayscale32: - SetInternal<uint32_t>(image, value); + if (value == 0) + { + memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight()); + } + else + { + SetInternal<uint32_t>(image, value); + } return; case PixelFormat_SignedGrayscale16: - SetInternal<int16_t>(image, value); + if (value == 0) + { + memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight()); + } + else + { + SetInternal<int16_t>(image, value); + } return; case PixelFormat_Float32: @@ -790,20 +892,42 @@ void ImageProcessing::MultiplyConstant(ImageAccessor& image, - float factor) + float factor, + bool useRound) { switch (image.GetFormat()) { case PixelFormat_Grayscale8: - MultiplyConstantInternal<uint8_t>(image, factor); + if (useRound) + { + MultiplyConstantInternal<uint8_t, true>(image, factor); + } + else + { + MultiplyConstantInternal<uint8_t, false>(image, factor); + } return; case PixelFormat_Grayscale16: - MultiplyConstantInternal<uint16_t>(image, factor); + if (useRound) + { + MultiplyConstantInternal<uint16_t, true>(image, factor); + } + else + { + MultiplyConstantInternal<uint16_t, false>(image, factor); + } return; case PixelFormat_SignedGrayscale16: - MultiplyConstantInternal<int16_t>(image, factor); + if (useRound) + { + MultiplyConstantInternal<int16_t, true>(image, factor); + } + else + { + MultiplyConstantInternal<int16_t, false>(image, factor); + } return; default: @@ -814,20 +938,42 @@ void ImageProcessing::ShiftScale(ImageAccessor& image, float offset, - float scaling) + float scaling, + bool useRound) { switch (image.GetFormat()) { case PixelFormat_Grayscale8: - ShiftScaleInternal<uint8_t>(image, offset, scaling); + if (useRound) + { + ShiftScaleInternal<uint8_t, true>(image, offset, scaling); + } + else + { + ShiftScaleInternal<uint8_t, false>(image, offset, scaling); + } return; case PixelFormat_Grayscale16: - ShiftScaleInternal<uint16_t>(image, offset, scaling); + if (useRound) + { + ShiftScaleInternal<uint16_t, true>(image, offset, scaling); + } + else + { + ShiftScaleInternal<uint16_t, false>(image, offset, scaling); + } return; case PixelFormat_SignedGrayscale16: - ShiftScaleInternal<int16_t>(image, offset, scaling); + if (useRound) + { + ShiftScaleInternal<int16_t, true>(image, offset, scaling); + } + else + { + ShiftScaleInternal<int16_t, false>(image, offset, scaling); + } return; default: @@ -859,4 +1005,222 @@ throw OrthancException(ErrorCode_NotImplemented); } } + + + + namespace + { + template <Orthanc::PixelFormat Format> + class BresenhamPixelWriter + { + private: + typedef typename PixelTraits<Format>::PixelType PixelType; + + Orthanc::ImageAccessor& image_; + PixelType value_; + + void PlotLineLow(int x0, + int y0, + int x1, + int y1) + { + int dx = x1 - x0; + int dy = y1 - y0; + int yi = 1; + + if (dy < 0) + { + yi = -1; + dy = -dy; + } + + int d = 2 * dy - dx; + int y = y0; + + for (int x = x0; x <= x1; x++) + { + Write(x, y); + + if (d > 0) + { + y = y + yi; + d = d - 2 * dx; + } + + d = d + 2*dy; + } + } + + void PlotLineHigh(int x0, + int y0, + int x1, + int y1) + { + int dx = x1 - x0; + int dy = y1 - y0; + int xi = 1; + + if (dx < 0) + { + xi = -1; + dx = -dx; + } + + int d = 2 * dx - dy; + int x = x0; + + for (int y = y0; y <= y1; y++) + { + Write(x, y); + + if (d > 0) + { + x = x + xi; + d = d - 2 * dy; + } + + d = d + 2 * dx; + } + } + + public: + BresenhamPixelWriter(Orthanc::ImageAccessor& image, + int64_t value) : + image_(image), + value_(PixelTraits<Format>::IntegerToPixel(value)) + { + } + + BresenhamPixelWriter(Orthanc::ImageAccessor& image, + const PixelType& value) : + image_(image), + value_(value) + { + } + + void Write(int x, + int y) + { + if (x >= 0 && + y >= 0 && + static_cast<unsigned int>(x) < image_.GetWidth() && + static_cast<unsigned int>(y) < image_.GetHeight()) + { + PixelType* p = reinterpret_cast<PixelType*>(image_.GetRow(y)); + p[x] = value_; + } + } + + void DrawSegment(int x0, + int y0, + int x1, + int y1) + { + // This is an implementation of Bresenham's line algorithm + // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#All_cases + + if (abs(y1 - y0) < abs(x1 - x0)) + { + if (x0 > x1) + { + PlotLineLow(x1, y1, x0, y0); + } + else + { + PlotLineLow(x0, y0, x1, y1); + } + } + else + { + if (y0 > y1) + { + PlotLineHigh(x1, y1, x0, y0); + } + else + { + PlotLineHigh(x0, y0, x1, y1); + } + } + } + }; + } + + + void ImageProcessing::DrawLineSegment(ImageAccessor& image, + int x0, + int y0, + int x1, + int y1, + int64_t value) + { + switch (image.GetFormat()) + { + case Orthanc::PixelFormat_Grayscale8: + { + BresenhamPixelWriter<Orthanc::PixelFormat_Grayscale8> writer(image, value); + writer.DrawSegment(x0, y0, x1, y1); + break; + } + + case Orthanc::PixelFormat_Grayscale16: + { + BresenhamPixelWriter<Orthanc::PixelFormat_Grayscale16> writer(image, value); + writer.DrawSegment(x0, y0, x1, y1); + break; + } + + case Orthanc::PixelFormat_SignedGrayscale16: + { + BresenhamPixelWriter<Orthanc::PixelFormat_SignedGrayscale16> writer(image, value); + writer.DrawSegment(x0, y0, x1, y1); + break; + } + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + } + } + + + void ImageProcessing::DrawLineSegment(ImageAccessor& image, + int x0, + int y0, + int x1, + int y1, + uint8_t red, + uint8_t green, + uint8_t blue, + uint8_t alpha) + { + switch (image.GetFormat()) + { + case Orthanc::PixelFormat_BGRA32: + { + PixelTraits<Orthanc::PixelFormat_BGRA32>::PixelType pixel; + pixel.red_ = red; + pixel.green_ = green; + pixel.blue_ = blue; + pixel.alpha_ = alpha; + + BresenhamPixelWriter<Orthanc::PixelFormat_BGRA32> writer(image, pixel); + writer.DrawSegment(x0, y0, x1, y1); + break; + } + + case Orthanc::PixelFormat_RGB24: + { + PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel; + pixel.red_ = red; + pixel.green_ = green; + pixel.blue_ = blue; + + BresenhamPixelWriter<Orthanc::PixelFormat_RGB24> writer(image, pixel); + writer.DrawSegment(x0, y0, x1, y1); + break; + } + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + } + } }
--- a/Resources/Orthanc/Core/Images/ImageProcessing.h Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/Images/ImageProcessing.h Thu Mar 22 17:32:05 2018 +0100 @@ -39,45 +39,65 @@ namespace Orthanc { - class ImageProcessing + namespace ImageProcessing { - public: - static void Copy(ImageAccessor& target, - const ImageAccessor& source); + void Copy(ImageAccessor& target, + const ImageAccessor& source); - static void Convert(ImageAccessor& target, - const ImageAccessor& source); + void Convert(ImageAccessor& target, + const ImageAccessor& source); + + void Set(ImageAccessor& image, + int64_t value); - static void Set(ImageAccessor& image, - int64_t value); + void Set(ImageAccessor& image, + uint8_t red, + uint8_t green, + uint8_t blue, + uint8_t alpha); - static void Set(ImageAccessor& image, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha); + void ShiftRight(ImageAccessor& target, + unsigned int shift); + + void GetMinMaxIntegerValue(int64_t& minValue, + int64_t& maxValue, + const ImageAccessor& image); + + void GetMinMaxFloatValue(float& minValue, + float& maxValue, + const ImageAccessor& image); - static void ShiftRight(ImageAccessor& target, - unsigned int shift); + void AddConstant(ImageAccessor& image, + int64_t value); + + // "useRound" is expensive + void MultiplyConstant(ImageAccessor& image, + float factor, + bool useRound); - static void GetMinMaxIntegerValue(int64_t& minValue, - int64_t& maxValue, - const ImageAccessor& image); + // "useRound" is expensive + void ShiftScale(ImageAccessor& image, + float offset, + float scaling, + bool useRound); - static void GetMinMaxFloatValue(float& minValue, - float& maxValue, - const ImageAccessor& image); + void Invert(ImageAccessor& image); - static void AddConstant(ImageAccessor& image, - int64_t value); - - static void MultiplyConstant(ImageAccessor& image, - float factor); + void DrawLineSegment(ImageAccessor& image, + int x0, + int y0, + int x1, + int y1, + int64_t value); - static void ShiftScale(ImageAccessor& image, - float offset, - float scaling); - - static void Invert(ImageAccessor& image); + void DrawLineSegment(ImageAccessor& image, + int x0, + int y0, + int x1, + int y1, + uint8_t red, + uint8_t green, + uint8_t blue, + uint8_t alpha); }; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/Core/Images/PixelTraits.h Thu Mar 22 17:32:05 2018 +0100 @@ -0,0 +1,267 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 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 + * 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 "../Enumerations.h" +#include "../OrthancException.h" + +#include <limits> + +namespace Orthanc +{ + template <PixelFormat format, + typename _PixelType> + struct IntegerPixelTraits + { + typedef _PixelType PixelType; + + ORTHANC_FORCE_INLINE + static PixelFormat GetPixelFormat() + { + return format; + } + + ORTHANC_FORCE_INLINE + static PixelType IntegerToPixel(int64_t value) + { + if (value < static_cast<int64_t>(std::numeric_limits<PixelType>::min()) || + value > static_cast<int64_t>(std::numeric_limits<PixelType>::max())) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + else + { + return static_cast<PixelType>(value); + } + } + + ORTHANC_FORCE_INLINE + static void SetZero(PixelType& target) + { + target = 0; + } + + ORTHANC_FORCE_INLINE + static void SetMinValue(PixelType& target) + { + target = std::numeric_limits<PixelType>::min(); + } + + ORTHANC_FORCE_INLINE + static void SetMaxValue(PixelType& target) + { + target = std::numeric_limits<PixelType>::max(); + } + + ORTHANC_FORCE_INLINE + static void Copy(PixelType& target, + const PixelType& source) + { + target = source; + } + + ORTHANC_FORCE_INLINE + static float PixelToFloat(const PixelType& source) + { + return static_cast<float>(source); + } + + ORTHANC_FORCE_INLINE + static void FloatToPixel(PixelType& target, + float value) + { + if (value < static_cast<float>(std::numeric_limits<PixelType>::min())) + { + target = std::numeric_limits<PixelType>::min(); + } + else if (value > static_cast<float>(std::numeric_limits<PixelType>::max())) + { + target = std::numeric_limits<PixelType>::max(); + } + else + { + target = static_cast<PixelType>(value); + } + } + + ORTHANC_FORCE_INLINE + static bool IsEqual(const PixelType& a, + const PixelType& b) + { + return a == b; + } + }; + + + template <PixelFormat Format> + struct PixelTraits; + + + template <> + struct PixelTraits<PixelFormat_Grayscale8> : + public IntegerPixelTraits<PixelFormat_Grayscale8, uint8_t> + { + }; + + + template <> + struct PixelTraits<PixelFormat_Grayscale16> : + public IntegerPixelTraits<PixelFormat_Grayscale16, uint16_t> + { + }; + + + template <> + struct PixelTraits<PixelFormat_SignedGrayscale16> : + public IntegerPixelTraits<PixelFormat_SignedGrayscale16, int16_t> + { + }; + + + template <> + struct PixelTraits<PixelFormat_RGB24> + { + struct PixelType + { + uint8_t red_; + uint8_t green_; + uint8_t blue_; + }; + + ORTHANC_FORCE_INLINE + static PixelFormat GetPixelFormat() + { + return PixelFormat_RGB24; + } + + ORTHANC_FORCE_INLINE + static void SetZero(PixelType& target) + { + target.red_ = 0; + target.green_ = 0; + target.blue_ = 0; + } + + ORTHANC_FORCE_INLINE + static void Copy(PixelType& target, + const PixelType& source) + { + target.red_ = source.red_; + target.green_ = source.green_; + target.blue_ = source.blue_; + } + + ORTHANC_FORCE_INLINE + static bool IsEqual(const PixelType& a, + const PixelType& b) + { + return (a.red_ == b.red_ && + a.green_ == b.green_ && + a.blue_ == b.blue_); + } + + ORTHANC_FORCE_INLINE + static void FloatToPixel(PixelType& target, + float value) + { + uint8_t v; + PixelTraits<PixelFormat_Grayscale8>::FloatToPixel(v, value); + + target.red_ = v; + target.green_ = v; + target.blue_ = v; + } + }; + + + template <> + struct PixelTraits<PixelFormat_BGRA32> + { + struct PixelType + { + uint8_t blue_; + uint8_t green_; + uint8_t red_; + uint8_t alpha_; + }; + + ORTHANC_FORCE_INLINE + static PixelFormat GetPixelFormat() + { + return PixelFormat_BGRA32; + } + + ORTHANC_FORCE_INLINE + static void SetZero(PixelType& target) + { + target.blue_ = 0; + target.green_ = 0; + target.red_ = 0; + target.alpha_ = 0; + } + + ORTHANC_FORCE_INLINE + static void Copy(PixelType& target, + const PixelType& source) + { + target.blue_ = source.blue_; + target.green_ = source.green_; + target.red_ = source.red_; + target.alpha_ = source.alpha_; + } + + ORTHANC_FORCE_INLINE + static bool IsEqual(const PixelType& a, + const PixelType& b) + { + return (a.blue_ == b.blue_ && + a.green_ == b.green_ && + a.red_ == b.red_ && + a.alpha_ == b.alpha_); + } + + ORTHANC_FORCE_INLINE + static void FloatToPixel(PixelType& target, + float value) + { + uint8_t v; + PixelTraits<PixelFormat_Grayscale8>::FloatToPixel(v, value); + + target.blue_ = v; + target.green_ = v; + target.red_ = v; + target.alpha_ = 255; + } + }; +}
--- a/Resources/Orthanc/Core/Logging.cpp Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/Logging.cpp Thu Mar 22 17:32:05 2018 +0100 @@ -94,7 +94,7 @@ context_ = context; } - InternalLogger::InternalLogger(const char* level, + InternalLogger::InternalLogger(Level level, const char* file /* ignored */, int line /* ignored */) : level_(level) @@ -105,48 +105,108 @@ { if (context_ != NULL) { - if (level_ == "ERROR") - { - OrthancPluginLogError(context_, message_.c_str()); - } - else if (level_ == "WARNING") + switch (level_) { - OrthancPluginLogWarning(context_, message_.c_str()); - } - else if (level_ == "INFO") - { - OrthancPluginLogInfo(context_, message_.c_str()); - } - else - { - std::string s = "Unknown log level (" + level_ + ") for message: " + message_; - OrthancPluginLogError(context_, s.c_str()); + case ERROR: + OrthancPluginLogError(context_, message_.c_str()); + break; + + case WARNING: + OrthancPluginLogWarning(context_, message_.c_str()); + break; + + case INFO: + OrthancPluginLogInfo(context_, message_.c_str()); + break; + + case TRACE: + // Not used by plugins + break; + + default: + { + std::string s = ("Unknown log level (" + boost::lexical_cast<std::string>(level_) + + ") for message: " + message_); + OrthancPluginLogError(context_, s.c_str()); + break; + } } } } - - InternalLogger& InternalLogger::operator<< (const std::string& message) - { - message_ += message; - return *this; - } - - InternalLogger& InternalLogger::operator<< (const char* message) - { - message_ += std::string(message); - return *this; - } - - InternalLogger& InternalLogger::operator<< (int message) - { - message_ += boost::lexical_cast<std::string>(message); - return *this; - } } } -#else /* ORTHANC_ENABLE_LOGGING_PLUGIN == 0 && ORTHANC_ENABLE_LOGGING == 1 */ +#elif ORTHANC_ENABLE_LOGGING_STDIO == 1 + +/********************************************************* + * Logger compatible with <stdio.h> + *********************************************************/ + +#include <stdio.h> +#include <boost/lexical_cast.hpp> + +namespace Orthanc +{ + namespace Logging + { + static bool globalVerbose_ = false; + static bool globalTrace_ = false; + + InternalLogger::InternalLogger(Level level, + const char* file /* ignored */, + int line /* ignored */) : + level_(level) + { + } + + InternalLogger::~InternalLogger() + { + switch (level_) + { + case ERROR: + fprintf(stderr, "E: %s\n", message_.c_str()); + break; + + case WARNING: + fprintf(stdout, "W: %s\n", message_.c_str()); + break; + + case INFO: + if (globalVerbose_) + { + fprintf(stdout, "I: %s\n", message_.c_str()); + } + break; + + case TRACE: + if (globalTrace_) + { + fprintf(stdout, "T: %s\n", message_.c_str()); + } + break; + + default: + fprintf(stderr, "Unknown log level (%d) for message: %s\n", level_, message_.c_str()); + } + } + + void EnableInfoLevel(bool enabled) + { + globalVerbose_ = enabled; + } + + void EnableTraceLevel(bool enabled) + { + globalTrace_ = enabled; + } + } +} + + +#else /* ORTHANC_ENABLE_LOGGING_PLUGIN == 0 && + ORTHANC_ENABLE_LOGGING_STDIO == 0 && + ORTHANC_ENABLE_LOGGING == 1 */ /********************************************************* * Internal logger of Orthanc, that mimics some @@ -156,7 +216,12 @@ #include "OrthancException.h" #include "Enumerations.h" #include "Toolbox.h" -#include "SystemToolbox.h" + +#if ORTHANC_SANDBOXED == 1 +# include <stdio.h> +#else +# include "SystemToolbox.h" +#endif #include <fstream> #include <boost/filesystem.hpp> @@ -232,9 +297,9 @@ static_cast<int>(now.date().year()), now.date().month().as_number(), now.date().day().as_number(), - now.time_of_day().hours(), - now.time_of_day().minutes(), - now.time_of_day().seconds(), + static_cast<int>(now.time_of_day().hours()), + static_cast<int>(now.time_of_day().minutes()), + static_cast<int>(now.time_of_day().seconds()), SystemToolbox::GetProcessId()); std::string programName = exe.filename().replace_extension("").string(); @@ -436,9 +501,9 @@ level[0], now.date().month().as_number(), now.date().day().as_number(), - duration.hours(), - duration.minutes(), - duration.seconds(), + static_cast<int>(duration.hours()), + static_cast<int>(duration.minutes()), + static_cast<int>(duration.seconds()), static_cast<int>(duration.fractional_seconds())); header = std::string(date) + path.filename().string() + ":" + boost::lexical_cast<std::string>(line) + "] ";
--- a/Resources/Orthanc/Core/Logging.h Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/Logging.h Thu Mar 22 17:32:05 2018 +0100 @@ -47,6 +47,14 @@ # endif #endif +#if !defined(ORTHANC_ENABLE_LOGGING_STDIO) +# if ORTHANC_ENABLE_LOGGING == 1 +# error The macro ORTHANC_ENABLE_LOGGING_STDIO must be defined +# else +# define ORTHANC_ENABLE_LOGGING_STDIO 0 +# endif +#endif + #if ORTHANC_ENABLE_LOGGING_PLUGIN == 1 # include <orthanc/OrthancCPlugin.h> #endif @@ -104,40 +112,57 @@ # define VLOG(level) ::Orthanc::Logging::NullStream() -#elif ORTHANC_ENABLE_LOGGING_PLUGIN == 1 +#elif (ORTHANC_ENABLE_LOGGING_PLUGIN == 1 || \ + ORTHANC_ENABLE_LOGGING_STDIO == 1) # include <boost/noncopyable.hpp> -# define LOG(level) ::Orthanc::Logging::InternalLogger(#level, __FILE__, __LINE__) -# define VLOG(level) ::Orthanc::Logging::InternalLogger("TRACE", __FILE__, __LINE__) +# include <boost/lexical_cast.hpp> +# define LOG(level) ::Orthanc::Logging::InternalLogger \ + (::Orthanc::Logging::level, __FILE__, __LINE__) +# define VLOG(level) ::Orthanc::Logging::InternalLogger \ + (::Orthanc::Logging::TRACE, __FILE__, __LINE__) namespace Orthanc { namespace Logging { + enum Level + { + ERROR, + WARNING, + INFO, + TRACE + }; + class InternalLogger : public boost::noncopyable { private: - std::string level_; + Level level_; std::string message_; public: - InternalLogger(const char* level, + InternalLogger(Level level, const char* file, int line); ~InternalLogger(); - InternalLogger& operator<< (const std::string& message); - - InternalLogger& operator<< (const char* message); - - InternalLogger& operator<< (int message); + template <typename T> + InternalLogger& operator<< (T message) + { + message_ += boost::lexical_cast<std::string>(message); + return *this; + } }; } } -#else /* ORTHANC_ENABLE_LOGGING_PLUGIN == 0 && ORTHANC_ENABLE_LOGGING == 1 */ + + +#else /* ORTHANC_ENABLE_LOGGING_PLUGIN == 0 && + ORTHANC_ENABLE_LOGGING_STDIO == 0 && + ORTHANC_ENABLE_LOGGING == 1 */ # include <boost/thread/mutex.hpp> # define LOG(level) ::Orthanc::Logging::InternalLogger(#level, __FILE__, __LINE__)
--- a/Resources/Orthanc/Core/SystemToolbox.cpp Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/SystemToolbox.cpp Thu Mar 22 17:32:05 2018 +0100 @@ -561,17 +561,30 @@ } - std::string SystemToolbox::GetNowIsoString() + static boost::posix_time::ptime GetNow(bool utc) { - boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); - return boost::posix_time::to_iso_string(now); + if (utc) + { + return boost::posix_time::second_clock::universal_time(); + } + else + { + return boost::posix_time::second_clock::local_time(); + } + } + + + std::string SystemToolbox::GetNowIsoString(bool utc) + { + return boost::posix_time::to_iso_string(GetNow(utc)); } void SystemToolbox::GetNowDicom(std::string& date, - std::string& time) + std::string& time, + bool utc) { - boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); + boost::posix_time::ptime now = GetNow(utc); tm tm = boost::posix_time::to_tm(now); char s[32];
--- a/Resources/Orthanc/Core/SystemToolbox.h Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Core/SystemToolbox.h Thu Mar 22 17:32:05 2018 +0100 @@ -95,9 +95,10 @@ std::string GenerateUuid(); - std::string GetNowIsoString(); + std::string GetNowIsoString(bool utc); void GetNowDicom(std::string& date, - std::string& time); + std::string& time, + bool utc); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Orthanc/NEWS Thu Mar 22 17:32:05 2018 +0100 @@ -0,0 +1,942 @@ +Pending changes in the mainline +=============================== + +REST API +-------- + +* "/system" URI returns the version of the Orthanc REST API +* "/tools/now" returns the current UTC (universal) time +* "/tools/now-local" returns the curent local time. + This was the behavior of "/tools/now" until release 1.3.1. +* Added "?expand" GET argument to "/peers" and "/modalities" routes +* New URI: "/tools/create-media-extended" to generate a DICOMDIR + archive from several resources, including additional type-3 tags + +Lua +--- + +* New CMake option: "-DENABLE_LUA_MODULES=ON" to enable support for + loading external Lua modules if the Lua engine is statically linked + +Plugins +------- + +* New error code: DatabaseUnavailable + +Maintenance +----------- + +* Orthanc now uses UTC (universal time) instead of local time in its database +* Fix to allow creating DICOM instances with empty Specific Character Set (0008,0005) +* Upgrade to curl 7.57.0 for static and Windows builds +* Support of Linux Standard Base +* Static linking against libuuid (from e2fsprogs) +* Fix static build on CentOS 6 +* Upgrade to JsonCpp 1.8.4 for static builds +* Possibility of using JsonCpp 0.10.6 if the compiler does not support C++11 + with the "-DUSE_LEGACY_JSONCPP=ON" CMake option + + +Version 1.3.1 (2017-11-29) +========================== + +General +------- + +* Built-in decoding of palette images + +REST API +-------- + +* New URI: "/instances/.../frames/.../raw.gz" to compress raw frames using gzip +* New argument "ignore-length" to force the inclusion of too long tags in JSON +* New argument "/.../media?extended" to include additional type-3 tags in DICOMDIR + +Plugins +------- + +* New pixel formats exposed in SDK: BGRA32, Float32, Grayscale32, RGB48 + +Maintenance +----------- + +* Creation of ./Resources/CMake/OrthancFramework*.cmake to reuse the Orthanc + C++ framework in other projects +* New security-related options: "DicomAlwaysAllowEcho" +* Use "GBK" (frequently used in China) as an alias for "GB18030" +* Experimental support of actively maintained Civetweb to replace Mongoose 3.8 +* Fix issue 31 for good (create new modality types for Philips ADW, GE Xeleris, GE AWServer) +* Fix issue 64 (OpenBSD support) +* Fix static compilation of DCMTK 3.6.2 on Fedora +* Upgrade to Boost 1.65.1 in static builds +* Upgrade to SQLite amalgamation 3.21.0 in static builds + + +Version 1.3.0 (2017-07-19) +========================== + +General +------- + +* Orthanc now anonymizes according to Basic Profile of PS 3.15-2017c Table E.1-1 +* In the "DicomModalities" configuration: + - Manufacturer type MedInria is now obsolete + - Manufacturer types AgfaImpax and SyngoVia are obsolete too + (use GenericNoWildcardInDates instead) + - Obsolete manufacturers are still accepted but might disappear in the future + - Added new manufacturer: GenericNoUniversalWildcard to replace all '*' by '' in + outgoing C-Find requests +* New security-related options: "DicomAlwaysAllowStore" and "DicomCheckModalityHost" + +REST API +-------- + +* Argument "Since" in URI "/tools/find" (related to issue 53) +* Argument "DicomVersion" in URIs "/{...}/{...}/anonymization" + +Plugins +------- + +* New function: "OrthancPluginRegisterIncomingHttpRequestFilter2()" + +Lua +--- + +* Added HTTP headers support for Lua HttpPost/HttpGet/HttpPut/HttpDelete + +Orthanc Explorer +---------------- + +* Query/retrieve: Added button for "DR" modality + +Maintenance +----------- + +* Ability to retrieve raw frames encoded as unsigned 32-bits integers +* Fix issue 29 (more consistent handling of the "--upgrade" argument) +* Fix issue 31 (create new modality types for Philips ADW, GE Xeleris, GE AWServer) +* Fix issue 35 (AET name is not transferred to Orthanc using DCMTK 3.6.0) +* Fix issue 44 (bad interpretation of photometric interpretation MONOCHROME1) +* Fix issue 45 (crash when providing a folder to "--config" command-line option) +* Fix issue 46 (PHI remaining after anonymization) +* Fix issue 49 (worklists: accentuated characters are removed from C-Find responses) +* Fix issue 52 (DICOM level security association problems) +* Fix issue 55 (modification/anonymization of tags that might break the database + model now requires the "Force" parameter to be set to "true" in the query) +* Fix issue 56 (case-insensitive matching over accents) +* Fix Debian #865606 (orthanc FTBFS with libdcmtk-dev 3.6.1~20170228-2) +* Fix XSS inside DICOM in Orthanc Explorer (as reported by Victor Pasnkel, Morphus Labs) +* Upgrade to DCMTK 3.6.2 in static builds (released on 2017-07-17) +* Upgrade to Boost 1.64.0 in static builds +* New advanced "Locale" configuration option +* Removed configuration option "USE_DCMTK_361_PRIVATE_DIC" + + +Version 1.2.0 (2016/12/13) +========================== + +General +------- + +* Handling of private tags/creators in the "Dictionary" configuration option +* New configuration options: "LoadPrivateDictionary", "DicomScuTimeout" and "DicomScpTimeout" +* New metadata automatically computed at the instance level: "TransferSyntax" and "SopClassUid" + +REST API +-------- + +* "/tools/invalidate-tags" to invalidate the JSON summary of all the DICOM files + (useful if private tags are registered, or if changing the default encoding) +* "Permissive" flag for URI "/modalities/{...}/store" to ignore C-STORE transfer errors +* "Asynchronous" flag for URIs "/modalities/{...}/store" and "/peers/{...}/store" + to avoid waiting for the completion of image transfers +* Possibility to DELETE "dicom-as-json" attachments to reconstruct the JSON summaries + (useful if "Dictionary" has changed) +* "Keep" option for modifications to keep original DICOM identifiers (advanced feature) +* "/tools/default-encoding" to get or temporarily change the default encoding +* "/{resource}/{id}/reconstruct" to reconstruct the main DICOM tags, the JSON summary and + the metadata of a resource (useful to compute new metadata, or if using "Keep" above) + +Plugins +------- + +* New function: "OrthancPluginRegisterPrivateDictionaryTag()" to register private tags +* More control over client cache in the ServeFolders plugin +* New C++ help wrappers in "Plugins/Samples/Common/" to read DICOM datasets from REST API +* New data structure: "OrthancPluginFindMatcher" to match DICOM against C-FIND queries + +Maintenance +----------- + +* Fix handling of encodings in C-FIND requests (including for worklists) +* Use of DCMTK 3.6.1 dictionary of private tags in standalone builds +* Avoid hard crash if not enough memory (handling of std::bad_alloc) +* Improved robustness of Orthanc Explorer wrt. query/retrieve (maybe fix issue 24) +* Fix serious performance issue with C-FIND +* Fix extraction of the symbolic name of the private tags +* Performance warning if runtime debug assertions are turned on +* Improved robustness against files with no PatientID +* Upgrade to curl 7.50.3 for static and Windows builds +* Content-Type for JSON documents is now "application/json; charset=utf-8" +* Ignore "Group Length" tags in C-FIND queries +* Fix handling of worklist SCP with ReferencedStudySequence and ReferencedPatientSequence +* Fix handling of Move Originator AET and ID in C-MOVE SCP +* Fix vulnerability ZSL-2016-5379 "Unquoted Service Path Privilege Escalation" in the + Windows service +* Fix vulnerability ZSL-2016-5380 "Remote Memory Corruption Vulnerability" in DCMTK 3.6.0 + + +Version 1.1.0 (2016/06/27) +========================== + +General +------- + +* HTTPS client certificates can be associated with Orthanc peers to enhance security over Internet +* Possibility to use PKCS#11 authentication for hardware security modules with Orthanc peers +* New command-line option "--logfile" to output the Orthanc log to the given file +* Support of SIGHUP signal (restart Orthanc only if the configuration files have changed) + +REST API +-------- + +* New URI: "/instances/.../frames/.../raw" to access the raw frames (bypass image decoding) +* New URI "/modalities/.../move" to issue C-MOVE SCU requests +* "MoveOriginatorID" can be specified for "/modalities/.../store" + +Dicom protocol +-------------- + +* Support of optional tags for counting resources in C-FIND: + 0008-0061, 0008-0062, 0020-1200, 0020-1202, 0020-1204, 0020-1206, 0020-1208, 0020-1209 +* Support of Move Originator Message ID (0000,1031) in C-STORE responses driven by C-MOVE + +Plugins +------- + +* Speedup in plugins by removing unnecessary locks +* New callback to filter incoming HTTP requests: OrthancPluginRegisterIncomingHttpRequestFilter() +* New callback to handle non-worklists C-FIND requests: OrthancPluginRegisterFindCallback() +* New callback to handle C-MOVE requests: OrthancPluginRegisterMoveCallback() +* New function: "OrthancPluginHttpClient()" to do HTTP requests with full control +* New function: "OrthancPluginGenerateUuid()" to generate a UUID +* More than one custom image decoder can be installed (e.g. to handle different transfer syntaxes) + +Lua +--- + +* Possibility to dynamically fix outgoing C-FIND requests using "OutgoingFindRequestFilter()" +* Access to the HTTP headers in the "IncomingHttpRequestFilter()" callback + +Image decoding +-------------- + +* Huge speedup if decoding the family of JPEG transfer syntaxes +* Refactoring leading to speedups with custom image decoders (including Web viewer plugin) +* Support decoding of RLE Lossless transfer syntax +* Support of signed 16bpp images in ParsedDicomFile + +Maintenance +----------- + +* New logo of Orthanc +* Fix issue 11 (is_regular_file() fails for FILE_ATTRIBUTE_REPARSE_POINT) +* Fix issue 16 ("Limit" parameter error in REST API /tools/find method) +* Fix of Debian bug #818512 ("FTBFS: Please install libdcmtk*-dev") +* Fix of Debian bug #823139 ("orthanc: Please provide RecoverCompressedFile.cpp") +* Replaced "localhost" by "127.0.0.1", as it might impact performance on Windows +* Compatibility with CMake >= 3.5.0 +* Possibility to use forthcoming DCMTK 3.6.1 in static builds (instead of 3.6.0) +* Upgrade to Boost 1.60.0 for static builds +* Use of HTTP status 403 Forbidden (instead of 401) if access to a REST resource is disallowed +* Option "HttpsVerifyPeers" can be used to connect against self-signed HTTPS certificates +* New configuration option "AllowFindSopClassesInStudy" +* Macro "__linux" (now obsolete) replaced by macro "__linux__" (maybe solves Debian bug #821011) +* Modification of instances can now replace PixelData (resp. EncapsulatedDocument) with + provided a PNG/JPEG image (resp. PDF file) if it is encoded using Data URI Scheme +* Dropped support of Google Log + + +Version 1.0.0 (2015/12/15) +========================== + +* Lua: "IncomingFindRequestFilter()" to apply filters to incoming C-FIND requests +* New function in plugin SDK: "OrthancPluginSendMultipartItem2()" +* Fix of DICOMDIR generation with DCMTK 3.6.1, support of encodings +* Fix range search if the lower or upper limit is absent +* Fix modality worklists lookups if tags with UN (unknown) VR are present +* Warn about badly formatted modality/peer definitions in configuration file at startup + + +Version 0.9.6 (2015/12/08) +========================== + +* Promiscuous mode (accept unknown SOP class UID) is now turned off by default +* Fix serialization of DICOM buffers that might contain garbage trailing +* Fix modality worklists server if some fields are null +* More tolerant "/series/.../ordered-slices" with broken series +* Improved logging information if upgrade fails +* Fix formatting of multipart HTTP answers (bis) + + +Version 0.9.5 (2015/12/02) +========================== + +Major +----- + +* Experimental support of DICOM C-FIND SCP for modality worklists through plugins +* Support of DICOM C-FIND SCU for modality worklists ("/modalities/{dicom}/find-worklist") + +REST API +-------- + +* New URIs: + - "/series/.../ordered-slices" to order the slices of a 2D+t or 3D series + - "/tools/shutdown" to stop Orthanc from the REST API + - ".../compress", ".../uncompress" and ".../is-compressed" for attachments + - "/tools/create-archive" to create ZIP from a set of resources + - "/tools/create-media" to create ZIP+DICOMDIR from a set of resources + - "/instances/.../header" to get the meta information (header) of the DICOM instance +* "/tools/create-dicom": + - Support of binary tags encoded using data URI scheme + - Support of hierarchical structures (creation of sequences) + - Create tags with unknown VR +* "/modify" can insert/modify sequences +* ".../preview" and ".../image-uint8" can return JPEG images if the HTTP Accept Header asks so +* "Origin" metadata for the instances + +Minor +----- + +* New configuration options: + - "UnknownSopClassAccepted" to disable promiscuous mode (accept unknown SOP class UID) + - New configuration option: "Dictionary" to declare custom DICOM tags +* Add ".dcm" suffix to files in ZIP archives (cf. URI ".../archive") +* MIME content type can be associated to custom attachments (cf. "UserContentType") + +Plugins +------- + +* New functions: + - "OrthancPluginRegisterDecodeImageCallback()" to replace the built-in image decoder + - "OrthancPluginDicomInstanceToJson()" to convert DICOM to JSON + - "OrthancPluginDicomBufferToJson()" to convert DICOM to JSON + - "OrthancPluginRegisterErrorCode()" to declare custom error codes + - "OrthancPluginRegisterDictionaryTag()" to declare custom DICOM tags + - "OrthancPluginLookupDictionary()" to get information about some DICOM tag + - "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 + - "OrthancPluginDecodeDicomImage()" to decode DICOM images + - "OrthancPluginComputeMd5()" and "OrthancPluginComputeSha1()" to compute MD5/SHA-1 hash +* New events in change callbacks: + - "OrthancStarted" + - "OrthancStopped" + - "UpdatedAttachment" + - "UpdatedMetadata" +* "/system" URI gives information about the plugins used for storage area and DB back-end +* Plugin callbacks must now return explicit "OrthancPluginErrorCode" (instead of integers) + +Lua +--- + +* Optional argument "keepStrings" in "DumpJson()" + +Maintenance +----------- + +* Full indexation of the patient/study tags to speed up searches and C-FIND +* Many refactorings, notably of the searching features and of the image decoding +* C-MOVE SCP for studies using AccessionNumber tag +* Fix issue 4 (C-STORE Association not renegotiated on Specific-to-specific transfer syntax change) +* Fix formatting of multipart HTTP answers +* "--logdir" flag creates a single log file instead of 3 separate files for errors/warnings/infos +* "--errors" flag lists the error codes that could be returned by Orthanc +* Under Windows, the exit status of Orthanc corresponds to the encountered error code +* New "AgfaImpax", "EFilm2" and "Vitrea" modality manufacturers +* C-FIND SCP will return tags with sequence value representation +* Upgrade to Boost 1.59.0 for static builds + + +Version 0.9.4 (2015/09/16) +========================== + +* Preview of PDF files encapsulated in DICOM from Orthanc Explorer +* Creation of DICOM files with encapsulated PDF through "/tools/create-dicom" +* "limit" and "since" arguments while retrieving DICOM resources in the REST API +* Support of "deflate" and "gzip" content-types in HTTP requests +* Options to validate peers against CA certificates in HTTPS requests +* New configuration option: "HttpTimeout" to set the default timeout for HTTP requests + +Lua +--- + +* More information about the origin request in the "OnStoredInstance()" and + "ReceivedInstanceFilter()" callbacks. WARNING: This can result in + incompatibilities wrt. previous versions of Orthanc. +* New function "GetOrthancConfiguration()" to get the Orthanc configuration + +Plugins +------- + +* New functions to compress/uncompress images using PNG and JPEG +* New functions to issue HTTP requests from plugins +* New function "OrthancPluginBufferCompression()" to (un)compress memory buffers +* New function "OrthancPluginReadFile()" to read files from the filesystem +* New function "OrthancPluginWriteFile()" to write files to the filesystem +* New function "OrthancPluginGetErrorDescription()" to convert error codes to strings +* New function "OrthancPluginSendHttpStatus()" to send HTTP status with a body +* New function "OrthancPluginRegisterRestCallbackNoLock()" for high-performance plugins +* Plugins have access to explicit error codes +* Improvements to the sample "ServeFolders" plugin +* Primitives to upgrade the database version in plugins + +Maintenance +----------- + +* Many code refactorings +* Improved error codes (no more custom descriptions in exceptions) +* If error while calling the REST API, the answer body contains description of the error + (this feature can be disabled with the "HttpDescribeErrors" option) +* Upgrade to curl 7.44.0 for static and Windows builds +* Upgrade to libcurl 1.0.2d for static and Windows builds +* Depends on libjpeg 9a +* Bypass zlib uncompression if "StorageCompression" is enabled and HTTP client supports deflate + + +Version 0.9.3 (2015/08/07) +========================== + +* C-Echo testing can be triggered from Orthanc Explorer (in the query/retrieve page) +* Removal of the dependency upon Google Log, Orthanc now uses its internal logger + (use -DENABLE_GOOGLE_LOG=ON to re-enable Google Log) +* Upgrade to JsonCpp 0.10.5 for static and Windows builds + + +Version 0.9.2 (2015/08/02) +========================== + +* Upgrade to Boost 1.58.0 for static and Windows builds +* Source code repository moved from Google Code to BitBucket +* Inject version information into Windows binaries +* Fix access to binary data in HTTP/REST requests by Lua scripts +* Fix potential deadlock in the callbacks of plugins + + +Version 0.9.1 (2015/07/02) +========================== + +General +------- + +* The configuration can be splitted into several files stored inside the same folder +* Custom setting of the local AET during C-STORE SCU (both in Lua and in the REST API) +* Many code refactorings + +Lua +--- + +* Access to the REST API of Orthanc (RestApiGet, RestApiPost, RestApiPut, RestApiDelete) +* Functions to convert between Lua values and JSON strings: "ParseJson" and "DumpJson" +* New events: "OnStablePatient", "OnStableStudy", "OnStableSeries", "Initialize", "Finalize" + +Plugins +------- + +* Plugins can retrieve the configuration file directly as a JSON string +* Plugins can send answers as multipart messages + +Fixes +----- + +* Fix compatibility issues for C-FIND SCU to Siemens Syngo.Via modalities SCP +* Fix issue 15 (Lua scripts making HTTP requests) +* Fix issue 35 (Characters in PatientID string are not protected for C-FIND) +* Fix issue 37 (Hyphens trigger range query even if datatype does not support ranges) + + +Version 0.9.0 (2015/06/03) +========================== + +Major +----- + +* DICOM Query/Retrieve available from Orthanc Explorer +* C-MOVE SCU and C-FIND SCU are accessible through the REST API +* "?expand" flag for URIs "/patients", "/studies" and "/series" +* "/tools/find" URI to search for DICOM resources from REST +* Support of FreeBSD +* The "Orthanc Client" SDK is now a separate project + +Minor +----- + +* Speed-up in Orthanc Explorer for large amount of images +* Speed-up of the C-FIND SCP server of Orthanc +* Allow replacing PatientID/StudyInstanceUID/SeriesInstanceUID from Lua scripts +* Option "CaseSensitivePN" to enable case-insensitive C-FIND SCP + +Fixes +----- + +* Prevent freeze on C-FIND if no DICOM tag is to be returned +* Fix slow C-STORE SCP on recent versions of GNU/Linux, if + USE_SYSTEM_DCMTK is set to OFF (http://forum.dcmtk.org/viewtopic.php?f=1&t=4009) +* Fix issue 30 (QR response missing "Query/Retrieve Level" (008,0052)) +* Fix issue 32 (Cyrillic symbols): Introduction of the "Windows1251" encoding +* Plugins now receive duplicated GET arguments in their REST callbacks + + +Version 0.8.6 (2015/02/12) +========================== + +Major +----- + +* URIs to get all the parents of a given resource in a single REST call +* Instances without PatientID are now allowed +* Support of HTTP proxy to access Orthanc peers + +Minor +----- + +* Support of Tudor DICOM in Query/Retrieve +* More flexible "/modify" and "/anonymize" for single instance +* Access to called AET and remote AET from Lua scripts ("OnStoredInstance") +* Option "DicomAssociationCloseDelay" to set delay before closing DICOM association +* ZIP archives now display the accession number of the studies + +Plugins +------- + +* Introspection of plugins (cf. the "/plugins" URI) +* Plugins can access the command-line arguments used to launch Orthanc +* Plugins can extend Orthanc Explorer with custom JavaScript +* Plugins can get/set global properties to save their configuration +* Plugins can do REST calls to other plugins (cf. "xxxAfterPlugins()") +* Scan of folders for plugins + +Fixes +----- + +* Code refactorings +* Fix issue 25 (AET with underscore not allowed) +* Fix replacement and insertion of private DICOM tags +* Fix anonymization generating non-portable DICOM files + + +Version 0.8.5 (2014/11/04) +========================== + +General +------- + +* Major speed-up thanks to a new database schema +* Plugins can monitor changes through callbacks +* Download ZIP + DICOMDIR from Orthanc Explorer +* Sample plugin framework to serve static resources (./Plugins/Samples/WebSkeleton/) + +Fixes +----- + +* Fix issue 19 (YBR_FULL are decoded incorrectly) +* Fix issue 21 (Microsoft Visual Studio precompiled headers) +* Fix issue 22 (Error decoding multi-frame instances) +* Fix issue 24 (Build fails on OSX when directory has .DS_Store files) +* Fix crash when bad HTTP credentials are provided + + +Version 0.8.4 (2014/09/19) +========================== + +* "/instances-tags" to get the tags of all the child instances of a + patient/study/series with a single REST call (bulk tags retrieval) +* Configuration/Lua to select the accepted C-STORE SCP transfer syntaxes +* Fix reporting of errors in Orthanc Explorer when sending images to peers/modalities +* Installation of plugin SDK in CMake + + +Version 0.8.3 (2014/09/11) +========================== + +Major +----- + +* Creation of ZIP archives for media storage, with DICOMDIR +* URIs to get all the children of a given resource in a single REST call +* "/tools/lookup" URI to map DICOM UIDs to Orthanc identifiers +* Support of index-only mode (using the "StoreDicom" option) +* Plugins can implement a custom storage area + +Minor +----- + +* Configuration option to enable HTTP Keep-Alive +* Configuration option to disable the logging of exported resources in "/exports" +* Plugins can retrieve the path to Orthanc and to its configuration file +* "/tools/create-dicom" now accepts the "PatientID" DICOM tag (+ updated sample) +* Possibility to set HTTP headers from plugins +* "LastUpdate" metadata is now always returned for patients, studies and series + +Maintenance +----------- + +* Refactoring of HttpOutput ("Content-Length" header is now always sent) +* Upgrade to Mongoose 3.8 +* Fixes for Visual Studio 2013 and Windows 64bit +* Fix issue 16: Handling of "AT" value representations in JSON +* Fix issue 17 + + +Version 0.8.2 (2014/08/07) +========================== + +* Support of the standard text encodings +* Hot restart of Orthanc by posting to "/tools/reset" +* More fault-tolerant commands in Lua scripts +* Parameter to set the default encoding for DICOM files without SpecificCharacterSet +* Fix of issue #14 (support of XCode 5.1) +* Upgrade to Google Test 1.7.0 + + +Version 0.8.1 (2014/07/29) +========================== + +General +------- + +* Access patient module at the study level to cope with PatientID collisions +* On-the-fly conversion of JSON to XML according to the HTTP Accept header +* C-Echo SCU in the REST API +* DICOM conformance statement available at URI "/tools/dicom-conformance" + +Lua scripts +----------- + +* Lua scripts can do HTTP requests, and thus can call Web services +* Lua scripts can invoke system commands, with CallSystem() + +Plugins +------- + +* Lookup for DICOM UIDs in the plugin SDK +* Plugins have access to the HTTP headers and can answer with HTTP status codes +* Callback to react to the incoming of DICOM instances + +Fixes +----- + +* Fix build of Google Log with Visual Studio >= 11.0 +* Fix automated generation of the list of resource children in the REST API + + +Version 0.8.0 (2014/07/10) +========================== + +Major changes +------------- + +* Routing images with Lua scripts +* Introduction of the Orthanc Plugin SDK +* Official support of OS X (Darwin) 10.8 + +Minor changes +------------- + +* Extraction of tags for the patient/study/series/instance DICOM modules +* Extraction of the tags shared by all the instances of a patient/study/series +* Options to limit the number of results for an incoming C-FIND query +* Support of kFreeBSD +* Several code refactorings +* Fix OrthancCppClient::GetVoxelSizeZ() + + +Version 0.7.6 (2014/06/11) +========================== + +* Support of JPEG and JPEG-LS decompression +* Download DICOM images as Matlab/Octave arrays +* Precompiled headers for Microsoft Visual Studio + + +Version 0.7.5 (2014/05/08) +========================== + +* Dynamic negotiation of SOP classes for C-STORE SCU +* Creation of DICOM instances using the REST API +* Embedding of images within DICOM instances +* Adding/removal/modification of remote modalities/peers through REST +* Reuse of the previous SCU connection to avoid unnecessary handshakes +* Fix problems with anonymization and modification +* Fix missing licensing terms about reuse of some code from DCMTK +* Various code refactorings + + +Version 0.7.4 (2014/04/16) +========================== + +* Switch to openssl-1.0.1g in static builds (cf. Heartbleed exploit) +* Switch to boost 1.55.0 in static builds (to solve compiling errors) +* Better logging about nonexistent tags +* Dcm4Chee manufacturer +* Automatic discovering of the path to the DICOM dictionaries +* In the "DicomModalities" config, the port number can be a string + + +Version 0.7.3 (2014/02/14) +========================== + +Major changes +------------- + +* Fixes in the implementation of the C-FIND handler for Query/Retrieve +* Custom attachment of files to patients, studies, series or instances +* Access to lowlevel info about the attached files through the REST API +* Recover pixel data for more transfer syntaxes (notably JPEG) + +Minor changes +------------- + +* AET comparison is now case-insensitive by default +* Possibility to disable the HTTP server or the DICOM server +* Automatic computation of MD5 hashes for the stored DICOM files +* Maintenance tool to recover DICOM files compressed by Orthanc +* The newline characters in the configuration file are fixed for GNU/Linux +* Capture of the SIGTERM signal in GNU/Linux + + +Version 0.7.2 (2013/11/08) +========================== + +* Support of Query/Retrieve from medInria +* Accept more transfer syntaxes for C-STORE SCP and SCU (notably JPEG) +* Create the meta-header when receiving files through C-STORE SCP +* Fixes and improvements thanks to the static analyzer cppcheck + + +Version 0.7.1 (2013/10/30) +========================== + +* Use ZIP64 only when required to improve compatibility (cf. issue #7) +* Refactoring of the CMake options +* Fix for big-endian architectures (RedHat bug #985748) +* Use filenames with 8 characters in ZIP files for maximum compatibility +* Possibility to build Orthanc inplace (in the source directory) + + +Version 0.7.0 (2013/10/25) +========================== + +Major changes +------------- + +* DICOM Query/Retrieve is supported + +Minor changes +------------- + +* Possibility to keep the PatientID during an anonymization +* Check whether "unzip", "tar" and/or "7-zip" are installed from CMake + + +Version 0.6.2 (2013/10/04) +========================== + +* Build of the C++ client as a shared library +* Improvements and documentation of the C++ client API +* Fix of Debian bug #724947 (licensing issue with the SHA-1 library) +* Switch to Boost 1.54.0 (cf. issue #9) +* "make uninstall" is now possible + + +Version 0.6.1 (2013/09/16) +========================== + +* Detection of stable patients/studies/series +* C-FIND SCU at the instance level +* Link from modified to original resource in Orthanc Explorer +* Fix of issue #8 +* Anonymization of the medical alerts tag (0010,2000) + + +Version 0.6.0 (2013/07/16) +========================== + +Major changes +------------- + +* Introduction of the C++ client +* Send DICOM resources to other Orthanc instances through HTTP +* Access to signed images (instances/.../image-int16) + (Closes: Debian #716958) + +Minor changes +------------- + +* Export of DICOM files to the host filesystem (instances/.../export) +* Statistics about patients, studies, series and instances +* Link from anonymized to original resource in Orthanc Explorer +* Fixes for Red Hat and Debian packaging +* Fixes for history in Orthanc Explorer +* Fixes for boost::thread, as reported by Cyril Paulus +* Fix licensing (Closes: Debian #712038) + +Metadata +-------- + +* Access to the metadata through the REST API (.../metadata) +* Support of user-defined metadata +* "LastUpdate" metadata for patients, studies and series +* "/tools/now" to be used in combination with "LastUpdate" +* Improved support of series with temporal positions + + +Version 0.5.2 (2013/05/07) +========================== + +* "Bulk" Store-SCU (send several DICOM instances with the same + DICOM connection) +* Store-SCU for patients and studies in Orthanc Explorer +* Filtering of incoming DICOM instances (through Lua scripting) +* Filtering of incoming HTTP requests (through Lua scripting) +* Clearing of "/exports" and "/changes" +* Check MD5 of third party downloads +* Faking of the HTTP methods PUT and DELETE + + +Version 0.5.1 (2013/04/17) +========================== + +* Support of RGB images +* Fix of store SCU in release builds +* Possibility to store the SQLite index at another place than the + DICOM instances (for performance) + + +Version 0.5.0 (2013/01/31) +========================== + +Major changes +------------- + +* Download of modified or anonymized DICOM instances +* Inplace modification and anonymization of DICOM series, studies and patients + +Minor changes +------------- + +* Support of private tags +* Implementation of the PMSCT_RLE1 image decoding for Philips modalities +* Generation of random DICOM UID through the REST API (/tools/generate-uid) + + +Version 0.4.0 (2012/12/14) +========================== + +Major changes +------------- + +* Recycling of disk space +* Raw access to the value of the DICOM tags in the REST API + +Minor changes +------------- + +* Protection of patients against recycling (also in Orthanc Explorer) +* The DICOM dictionaries are embedded in Windows builds + + +Version 0.3.1 (2012/12/05) +========================== + +* Download archives of patients, studies and series as ZIP files +* Orthanc now checks the version of its database schema before starting + + +Version 0.3.0 (2012/11/30) +========================== + +Major changes +------------- + +* Transparent compression of the DICOM instances on the disk +* The patient/study/series/instances are now indexed by SHA-1 digests + of their DICOM Instance IDs (and not by UUIDs anymore): The same + DICOM objects are thus always identified by the same Orthanc IDs +* Log of exported instances through DICOM C-STORE SCU ("/exported" URI) +* Full refactoring of the DB schema and of the REST API +* Introduction of generic classes for REST APIs (in Core/RestApi) + +Minor changes +------------- + +* "/statistics" URI +* "last" flag to retrieve the last change from the "/changes" URI +* Generate a sample configuration file from command line +* "CompletedSeries" event in the changes API +* Thread to continuously flush DB to disk (SQLite checkpoints for + improved robustness) + + +Version 0.2.3 (2012/10/26) +========================== + +* Use HTTP Content-Disposition to set a filename when downloading JSON/DCM +* URI "/system" for general information about Orthanc +* Versioning info and help on the command line +* Improved logging +* Possibility of dynamic linking against jsoncpp, sqlite, boost and dmctk + for Debian packaging +* Fix some bugs +* Switch to default 8042 port for HTTP + + +Version 0.2.2 (2012/10/04) +========================== + +* Switch to Google Log +* Fixes to Debian packaging + + +Version 0.2.1 (2012/09/28) +========================== + +* Status of series +* Continuous Integration Server is up and running +* Ready for Debian packaging + + +Version 0.2.0 (2012/09/16) +========================== + +Major changes +------------- + +* Renaming to "Orthanc" +* Focus on security: Support of SSL, HTTP Basic Authentication and + interdiction of remote access +* Access to multi-frame images (for nuclear medicine) +* Access to the raw PNG images (in 8bpp and 16bpp) + +Minor changes +------------- + +* Change of the licensing of the "Core/SQLite" folder to BSD (to + reflect the original licensing terms of Chromium, from which the + code derives) +* Standalone build for cross-compilation + + +Version 0.1.1 (2012/07/20) +========================== + +* Fix Windows version +* Native Windows build with Microsoft Visual Studio 2005 +* Add path to storage in Configuration.json + + +Version 0.1.0 (2012/07/19) +========================== + +* Initial release
--- a/Resources/Orthanc/Resources/CMake/JsonCppConfiguration.cmake Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/Orthanc/Resources/CMake/JsonCppConfiguration.cmake Thu Mar 22 17:32:05 2018 +0100 @@ -1,7 +1,18 @@ +set(JSONCPP_CXX11 OFF) + if (STATIC_BUILD OR NOT USE_SYSTEM_JSONCPP) - set(JSONCPP_SOURCES_DIR ${CMAKE_BINARY_DIR}/jsoncpp-0.10.5) - set(JSONCPP_URL "http://www.orthanc-server.com/downloads/third-party/jsoncpp-0.10.5.tar.gz") - set(JSONCPP_MD5 "db146bac5a126ded9bd728ab7b61ed6b") + if (USE_LEGACY_JSONCPP) + set(JSONCPP_SOURCES_DIR ${CMAKE_BINARY_DIR}/jsoncpp-0.10.6) + set(JSONCPP_URL "http://www.orthanc-server.com/downloads/third-party/jsoncpp-0.10.6.tar.gz") + set(JSONCPP_MD5 "13d1991d79697df8cadbc25c93e37c83") + add_definitions(-DORTHANC_LEGACY_JSONCPP=1) + else() + set(JSONCPP_SOURCES_DIR ${CMAKE_BINARY_DIR}/jsoncpp-1.8.4) + set(JSONCPP_URL "http://www.orthanc-server.com/downloads/third-party/jsoncpp-1.8.4.tar.gz") + set(JSONCPP_MD5 "fa47a3ab6b381869b6a5f20811198662") + add_definitions(-DORTHANC_LEGACY_JSONCPP=0) + set(JSONCPP_CXX11 ON) + endif() DownloadPackage(${JSONCPP_MD5} ${JSONCPP_URL} "${JSONCPP_SOURCES_DIR}") @@ -48,14 +59,24 @@ JSONCPP_VERSION_MAJOR ${JSONCPP_VERSION_MAJOR1}) message("JsonCpp major version: ${JSONCPP_VERSION_MAJOR}") - if ((CMAKE_COMPILER_IS_GNUCXX OR - "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") AND - JSONCPP_VERSION_MAJOR GREATER 0) - message("Switching to C++11 standard in gcc/clang, as version of JsonCpp is >= 1.0.0") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-deprecated-declarations") + if (JSONCPP_VERSION_MAJOR GREATER 0) + set(JSONCPP_CXX11 ON) endif() else() message("Unable to detect the major version of JsonCpp, assuming < 1.0.0") endif() +endif() + +if (JSONCPP_CXX11) + # Osimis has encountered problems when this macro is left at its + # default value (1000), so we increase this limit + # https://gitlab.kitware.com/third-party/jsoncpp/commit/56df2068470241f9043b676bfae415ed62a0c172 + add_definitions(-DJSONCPP_DEPRECATED_STACK_LIMIT=5000) + + if (CMAKE_COMPILER_IS_GNUCXX OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + message("Switching to C++11 standard in gcc/clang, as version of JsonCpp is >= 1.0.0") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-deprecated-declarations") + endif() endif()
--- a/Resources/SyncOrthancFolder.py Fri Feb 02 18:11:32 2018 +0100 +++ b/Resources/SyncOrthancFolder.py Thu Mar 22 17:32:05 2018 +0100 @@ -15,6 +15,7 @@ REPOSITORY = 'http://bitbucket.org/sjodogne/orthanc/raw' FILES = [ + 'NEWS', 'Core/Cache/LeastRecentlyUsedIndex.h', 'Core/ChunkedBuffer.cpp', 'Core/ChunkedBuffer.h', @@ -55,6 +56,7 @@ 'Core/Images/JpegReader.h', 'Core/Images/JpegWriter.cpp', 'Core/Images/JpegWriter.h', + 'Core/Images/PixelTraits.h', 'Core/Images/PngReader.cpp', 'Core/Images/PngReader.h', 'Core/Images/PngWriter.cpp',
--- a/ViewerPlugin/CMakeLists.txt Fri Feb 02 18:11:32 2018 +0100 +++ b/ViewerPlugin/CMakeLists.txt Thu Mar 22 17:32:05 2018 +0100 @@ -71,6 +71,7 @@ -DORTHANC_ENABLE_LOCALE=0 -DORTHANC_ENABLE_LOGGING=1 -DORTHANC_ENABLE_LOGGING_PLUGIN=1 + -DORTHANC_ENABLE_LOGGING_STDIO=0 -DORTHANC_ENABLE_MD5=0 -DORTHANC_ENABLE_PNG=1 -DORTHANC_ENABLE_PUGIXML=0