# HG changeset patch # User Sebastien Jodogne # Date 1415031110 -3600 # Node ID 25260fe03dd6a23acc50c615a3dede1d093449e1 # Parent e85e668d2147494b2f832b27739ca34bf7e56733# Parent 6502517fd4af14ff2f88895334104da331c895ee integration mainline->db-changes diff -r e85e668d2147 -r 25260fe03dd6 Core/DicomFormat/DicomImageInformation.cpp --- a/Core/DicomFormat/DicomImageInformation.cpp Mon Oct 27 13:46:03 2014 +0100 +++ b/Core/DicomFormat/DicomImageInformation.cpp Mon Nov 03 17:11:50 2014 +0100 @@ -39,6 +39,7 @@ #include "DicomImageInformation.h" #include "../OrthancException.h" +#include "../Toolbox.h" #include #include #include @@ -53,6 +54,66 @@ try { + std::string p = values.GetValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION).AsString(); + Toolbox::ToUpperCase(p); + + if (p == "RGB") + { + photometric_ = PhotometricInterpretation_RGB; + } + else if (p == "MONOCHROME1") + { + photometric_ = PhotometricInterpretation_Monochrome1; + } + else if (p == "MONOCHROME2") + { + photometric_ = PhotometricInterpretation_Monochrome2; + } + else if (p == "PALETTE COLOR") + { + photometric_ = PhotometricInterpretation_Palette; + } + else if (p == "HSV") + { + photometric_ = PhotometricInterpretation_HSV; + } + else if (p == "ARGB") + { + photometric_ = PhotometricInterpretation_ARGB; + } + else if (p == "CMYK") + { + photometric_ = PhotometricInterpretation_CMYK; + } + else if (p == "YBR_FULL") + { + photometric_ = PhotometricInterpretation_YBRFull; + } + else if (p == "YBR_FULL_422") + { + photometric_ = PhotometricInterpretation_YBRFull422; + } + else if (p == "YBR_PARTIAL_420") + { + photometric_ = PhotometricInterpretation_YBRPartial420; + } + else if (p == "YBR_PARTIAL_422") + { + photometric_ = PhotometricInterpretation_YBRPartial422; + } + else if (p == "YBR_ICT") + { + photometric_ = PhotometricInterpretation_YBR_ICT; + } + else if (p == "YBR_RCT") + { + photometric_ = PhotometricInterpretation_YBR_RCT; + } + else + { + photometric_ = PhotometricInterpretation_Unknown; + } + width_ = boost::lexical_cast(values.GetValue(DICOM_TAG_COLUMNS).AsString()); height_ = boost::lexical_cast(values.GetValue(DICOM_TAG_ROWS).AsString()); bitsAllocated_ = boost::lexical_cast(values.GetValue(DICOM_TAG_BITS_ALLOCATED).AsString()); @@ -159,30 +220,37 @@ bool DicomImageInformation::ExtractPixelFormat(PixelFormat& format) const { - if (GetBitsStored() == 8 && GetChannelCount() == 1 && !IsSigned()) + if (photometric_ == PhotometricInterpretation_Monochrome1 || + photometric_ == PhotometricInterpretation_Monochrome2) { - format = PixelFormat_Grayscale8; - return true; + if (GetBitsStored() == 8 && GetChannelCount() == 1 && !IsSigned()) + { + format = PixelFormat_Grayscale8; + return true; + } + + if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && !IsSigned()) + { + format = PixelFormat_Grayscale16; + return true; + } + + if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && IsSigned()) + { + format = PixelFormat_SignedGrayscale16; + return true; + } } - if (GetBitsStored() == 8 && GetChannelCount() == 3 && !IsSigned()) + if (GetBitsStored() == 8 && + GetChannelCount() == 3 && + !IsSigned() && + photometric_ == PhotometricInterpretation_RGB) { format = PixelFormat_RGB24; return true; } - if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && !IsSigned()) - { - format = PixelFormat_Grayscale16; - return true; - } - - if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && IsSigned()) - { - format = PixelFormat_SignedGrayscale16; - return true; - } - return false; } } diff -r e85e668d2147 -r 25260fe03dd6 Core/DicomFormat/DicomImageInformation.h --- a/Core/DicomFormat/DicomImageInformation.h Mon Oct 27 13:46:03 2014 +0100 +++ b/Core/DicomFormat/DicomImageInformation.h Mon Nov 03 17:11:50 2014 +0100 @@ -54,6 +54,8 @@ unsigned int bitsStored_; unsigned int highBit_; + PhotometricInterpretation photometric_; + public: DicomImageInformation(const DicomMap& values); @@ -112,6 +114,11 @@ return highBit_ + 1 - bitsStored_; } + PhotometricInterpretation GetPhotometricInterpretation() const + { + return photometric_; + } + bool ExtractPixelFormat(PixelFormat& format) const; }; } diff -r e85e668d2147 -r 25260fe03dd6 Core/DicomFormat/DicomMap.cpp --- a/Core/DicomFormat/DicomMap.cpp Mon Oct 27 13:46:03 2014 +0100 +++ b/Core/DicomFormat/DicomMap.cpp Mon Nov 03 17:11:50 2014 +0100 @@ -36,6 +36,7 @@ #include #include #include "DicomString.h" +#include "DicomArray.h" #include "../OrthancException.h" @@ -387,4 +388,11 @@ GetMainDicomTagsInternal(result, ResourceType_Series); GetMainDicomTagsInternal(result, ResourceType_Instance); } + + + void DicomMap::Print(FILE* fp) const + { + DicomArray a(*this); + a.Print(fp); + } } diff -r e85e668d2147 -r 25260fe03dd6 Core/DicomFormat/DicomMap.h --- a/Core/DicomFormat/DicomMap.h Mon Oct 27 13:46:03 2014 +0100 +++ b/Core/DicomFormat/DicomMap.h Mon Nov 03 17:11:50 2014 +0100 @@ -160,5 +160,7 @@ static void GetMainDicomTags(std::set& result, ResourceType level); static void GetMainDicomTags(std::set& result); + + void Print(FILE* fp) const; }; } diff -r e85e668d2147 -r 25260fe03dd6 Core/Enumerations.cpp --- a/Core/Enumerations.cpp Mon Oct 27 13:46:03 2014 +0100 +++ b/Core/Enumerations.cpp Mon Nov 03 17:11:50 2014 +0100 @@ -313,6 +313,58 @@ } + const char* EnumerationToString(PhotometricInterpretation photometric) + { + switch (photometric) + { + case PhotometricInterpretation_RGB: + return "RGB"; + + case PhotometricInterpretation_Monochrome1: + return "Monochrome1"; + + case PhotometricInterpretation_Monochrome2: + return "Monochrome2"; + + case PhotometricInterpretation_ARGB: + return "ARGB"; + + case PhotometricInterpretation_CMYK: + return "CMYK"; + + case PhotometricInterpretation_HSV: + return "HSV"; + + case PhotometricInterpretation_Palette: + return "Palette color"; + + case PhotometricInterpretation_YBRFull: + return "YBR full"; + + case PhotometricInterpretation_YBRFull422: + return "YBR full 422"; + + case PhotometricInterpretation_YBRPartial420: + return "YBR partial 420"; + + case PhotometricInterpretation_YBRPartial422: + return "YBR partial 422"; + + case PhotometricInterpretation_YBR_ICT: + return "YBR ICT"; + + case PhotometricInterpretation_YBR_RCT: + return "YBR RCT"; + + case PhotometricInterpretation_Unknown: + return "Unknown"; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } + + Encoding StringToEncoding(const char* encoding) { std::string s(encoding); diff -r e85e668d2147 -r 25260fe03dd6 Core/Enumerations.h --- a/Core/Enumerations.h Mon Oct 27 13:46:03 2014 +0100 +++ b/Core/Enumerations.h Mon Nov 03 17:11:50 2014 +0100 @@ -254,6 +254,26 @@ }; + // https://www.dabsoft.ch/dicom/3/C.7.6.3.1.2/ + enum PhotometricInterpretation + { + PhotometricInterpretation_ARGB, // Retired + PhotometricInterpretation_CMYK, // Retired + PhotometricInterpretation_HSV, // Retired + PhotometricInterpretation_Monochrome1, + PhotometricInterpretation_Monochrome2, + PhotometricInterpretation_Palette, + PhotometricInterpretation_RGB, + PhotometricInterpretation_YBRFull, + PhotometricInterpretation_YBRFull422, + PhotometricInterpretation_YBRPartial420, + PhotometricInterpretation_YBRPartial422, + PhotometricInterpretation_YBR_ICT, + PhotometricInterpretation_YBR_RCT, + PhotometricInterpretation_Unknown + }; + + /** * WARNING: Do not change the explicit values in the enumerations * below this point. This would result in incompatible databases @@ -298,6 +318,8 @@ const char* EnumerationToString(Encoding encoding); + const char* EnumerationToString(PhotometricInterpretation photometric); + Encoding StringToEncoding(const char* encoding); ResourceType StringToResourceType(const char* type); diff -r e85e668d2147 -r 25260fe03dd6 LinuxCompilation.txt --- a/LinuxCompilation.txt Mon Oct 27 13:46:03 2014 +0100 +++ b/LinuxCompilation.txt Mon Nov 03 17:11:50 2014 +0100 @@ -9,15 +9,17 @@ statically linking against all the third-party dependencies. In this case, the system-wide libraries will not be used. The build tool (CMake) will download the sources of all the required packages and -automatically compile them. This process should work on all the Linux -distributions. +automatically compile them. -We make the assumption that Orthanc source code is placed in the -folder "~/Orthanc" and that the binaries will be compiled to -"~/OrthancBuild". +This process should work on any Linux distribution, provided that a +C/C++ compiler ("build-essential" in Debian-based systems), the Python +interpreter, CMake, the "unzip" system tool, and the development +package for libuuid ("uuid-dev" in Debian) are installed. -To build binaries with debug information: +We now make the assumption that Orthanc source code is placed in the +folder "~/Orthanc" and that the binaries will be compiled to +"~/OrthancBuild". To build binaries with debug information: # cd ~/OrthancBuild # cmake -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug ~/Orthanc @@ -33,10 +35,15 @@ # make doc -Note: When the "STATIC_BUILD" option is set to "ON", the build tool +Note 1- When the "STATIC_BUILD" option is set to "ON", the build tool will not ask you the permission to download packages from the Internet. +Note 2- If the development package of libuuid was not installed when +first invoking cmake, you will have to manually remove the build +directory ("rm -rf ~/OrthancBuild") after installing this package, +then run cmake again. + Use system-wide libraries under Linux ===================================== diff -r e85e668d2147 -r 25260fe03dd6 NEWS --- a/NEWS Mon Oct 27 13:46:03 2014 +0100 +++ b/NEWS Mon Nov 03 17:11:50 2014 +0100 @@ -5,8 +5,10 @@ * Download ZIP + DICOMDIR from Orthanc Explorer * Plugins can monitor changes through callbacks * Sample plugin framework to serve static resources +* 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 diff -r e85e668d2147 -r 25260fe03dd6 OrthancServer/Internals/DicomImageDecoder.cpp --- a/OrthancServer/Internals/DicomImageDecoder.cpp Mon Oct 27 13:46:03 2014 +0100 +++ b/OrthancServer/Internals/DicomImageDecoder.cpp Mon Nov 03 17:11:50 2014 +0100 @@ -318,7 +318,9 @@ LOG(WARNING) << "Unsupported DICOM image: " << info.GetBitsStored() << "bpp, " << info.GetChannelCount() << " channels, " << (info.IsSigned() ? "signed" : "unsigned") - << (info.IsPlanar() ? ", planar" : ", non-planar"); + << (info.IsPlanar() ? ", planar, " : ", non-planar, ") + << EnumerationToString(info.GetPhotometricInterpretation()) + << " photometric interpretation"; throw OrthancException(ErrorCode_NotImplemented); } diff -r e85e668d2147 -r 25260fe03dd6 Resources/EmbedResources.py --- a/Resources/EmbedResources.py Mon Oct 27 13:46:03 2014 +0100 +++ b/Resources/EmbedResources.py Mon Nov 03 17:11:50 2014 +0100 @@ -86,6 +86,13 @@ content = {} for root, dirs, files in os.walk(pathName): base = os.path.relpath(root, pathName) + + # Fix issue #24 (Build fails on OSX when directory has .DS_Store files): + # Ignore folders whose name starts with a dot (".") + if base.find('/.') != -1: + print('Ignoring folder: %s' % root) + continue + for f in files: if f.find('~') == -1: # Ignore Emacs backup files if base == '.': diff -r e85e668d2147 -r 25260fe03dd6 UnitTestsSources/ImageProcessingTests.cpp --- a/UnitTestsSources/ImageProcessingTests.cpp Mon Oct 27 13:46:03 2014 +0100 +++ b/UnitTestsSources/ImageProcessingTests.cpp Mon Nov 03 17:11:50 2014 +0100 @@ -51,6 +51,7 @@ m.SetValue(DICOM_TAG_BITS_STORED, "12"); m.SetValue(DICOM_TAG_HIGH_BIT, "11"); m.SetValue(DICOM_TAG_PIXEL_REPRESENTATION, "0"); + m.SetValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION, "MONOCHROME2"); DicomImageInformation info(m); PixelFormat format; @@ -70,6 +71,7 @@ m.SetValue(DICOM_TAG_BITS_STORED, "16"); m.SetValue(DICOM_TAG_HIGH_BIT, "15"); m.SetValue(DICOM_TAG_PIXEL_REPRESENTATION, "1"); + m.SetValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION, "MONOCHROME2"); DicomImageInformation info(m); PixelFormat format;