Mercurial > hg > orthanc
diff OrthancServer/OrthancRestApi/OrthancRestResources.cpp @ 3600:4066998150ef
/instances/{id}/preview route now takes the windowing into account
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Thu, 09 Jan 2020 18:54:40 +0100 |
parents | 810772486249 |
children | a77e7839012a |
line wrap: on
line diff
--- a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp Tue Jan 07 10:53:32 2020 +0100 +++ b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp Thu Jan 09 18:54:40 2020 +0100 @@ -39,6 +39,7 @@ #include "../../Core/DicomParsing/FromDcmtkBridge.h" #include "../../Core/DicomParsing/Internals/DicomImageDecoder.h" #include "../../Core/HttpServer/HttpContentNegociation.h" +#include "../../Core/Images/ImageProcessing.h" #include "../../Core/Logging.h" #include "../DefaultDicomImageDecoder.h" #include "../OrthancConfiguration.h" @@ -502,6 +503,38 @@ } + void LookupWindowingTags(const ParsedDicomFile& dicom, float& windowCenter, float& windowWidth, float& rescaleSlope, float& rescaleIntercept, bool& invert) + { + DicomMap dicomTags; + dicom.ExtractDicomSummary(dicomTags); + + + unsigned int bitsStored = boost::lexical_cast<unsigned int>(dicomTags.GetStringValue(Orthanc::DICOM_TAG_BITS_STORED, "8", false)); + windowWidth = static_cast<float>(2 << (bitsStored - 1)); + windowCenter = windowWidth / 2; + rescaleSlope = 1.0f; + rescaleIntercept = 0.0f; + invert = false; + + if (dicomTags.HasTag(Orthanc::DICOM_TAG_WINDOW_CENTER) && dicomTags.HasTag(Orthanc::DICOM_TAG_WINDOW_WIDTH)) + { + windowCenter = boost::lexical_cast<float>(dicomTags.GetStringValue(Orthanc::DICOM_TAG_WINDOW_CENTER, "", false)); + windowWidth = boost::lexical_cast<float>(dicomTags.GetStringValue(Orthanc::DICOM_TAG_WINDOW_WIDTH, "", false)); + } + + if (dicomTags.HasTag(Orthanc::DICOM_TAG_RESCALE_SLOPE) && dicomTags.HasTag(Orthanc::DICOM_TAG_RESCALE_INTERCEPT)) + { + rescaleSlope = boost::lexical_cast<float>(dicomTags.GetStringValue(Orthanc::DICOM_TAG_RESCALE_SLOPE, "", false)); + rescaleIntercept = boost::lexical_cast<float>(dicomTags.GetStringValue(Orthanc::DICOM_TAG_RESCALE_INTERCEPT, "", false)); + } + + PhotometricInterpretation photometric; + if (dicom.LookupPhotometricInterpretation(photometric)) + { + invert = (photometric == PhotometricInterpretation_Monochrome1); + } + } + template <enum ImageExtractionMode mode> static void GetImage(RestApiGetCall& call) { @@ -520,6 +553,11 @@ } bool invert = false; + float windowCenter = 128.0f; + float windowWidth = 256.0f; + float rescaleSlope = 1.0f; + float rescaleIntercept = 0.0f; + std::auto_ptr<ImageAccessor> decoded; try @@ -549,11 +587,7 @@ // twice the DICOM file ParsedDicomFile parsed(dicomContent); - PhotometricInterpretation photometric; - if (parsed.LookupPhotometricInterpretation(photometric)) - { - invert = (photometric == PhotometricInterpretation_Monochrome1); - } + LookupWindowingTags(dicomContent, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); } } #endif @@ -564,12 +598,11 @@ // things on multi-frame images ServerContext::DicomCacheLocker locker(context, publicId); decoded.reset(DicomImageDecoder::Decode(locker.GetDicom(), frame)); + LookupWindowingTags(locker.GetDicom(), windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); - PhotometricInterpretation photometric; - if (mode == ImageExtractionMode_Preview && - locker.GetDicom().LookupPhotometricInterpretation(photometric)) + if (mode != ImageExtractionMode_Preview) { - invert = (photometric == PhotometricInterpretation_Monochrome1); + invert = false; } } } @@ -593,6 +626,13 @@ return; } + if (mode == ImageExtractionMode_Preview + && (decoded->GetFormat() == Orthanc::PixelFormat_Grayscale8 || decoded->GetFormat() == Orthanc::PixelFormat_Grayscale16)) + { + ImageProcessing::ApplyWindowing(*decoded, *decoded, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); + invert = false; // don't invert it later on when encoding it, it has been inverted in the ApplyWindowing function + } + ImageToEncode image(decoded, mode, invert); HttpContentNegociation negociation;