Mercurial > hg > orthanc-stone
diff OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp @ 1679:5b8b88e5bfd6
successfully running unit tests in WebAssembly
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 24 Nov 2020 12:59:10 +0100 |
parents | 51bab5188a13 |
children | 9ac2a65d4172 |
line wrap: on
line diff
--- a/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp Tue Nov 24 07:40:19 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp Tue Nov 24 12:59:10 2020 +0100 @@ -182,10 +182,10 @@ bool ok = false; - if (LinearAlgebra::ParseVector(presetWindowingCenters_, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) && - LinearAlgebra::ParseVector(presetWindowingWidths_, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH)) + if (LinearAlgebra::ParseVector(windowingPresetCenters_, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) && + LinearAlgebra::ParseVector(windowingPresetWidths_, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH)) { - if (presetWindowingCenters_.size() == presetWindowingWidths_.size()) + if (windowingPresetCenters_.size() == windowingPresetWidths_.size()) { ok = true; } @@ -199,8 +199,8 @@ if (!ok) { // Don't use "Vector::clear()", as it has not the same meaning as "std::vector::clear()" - presetWindowingCenters_.resize(0); - presetWindowingWidths_.resize(0); + windowingPresetCenters_.resize(0); + windowingPresetWidths_.resize(0); } // This computes the "IndexInSeries" metadata from Orthanc (check @@ -397,18 +397,31 @@ } - size_t DicomInstanceParameters::GetPresetWindowingsCount() const + size_t DicomInstanceParameters::GetWindowingPresetsCount() const { - assert(data_.presetWindowingCenters_.size() == data_.presetWindowingWidths_.size()); - return data_.presetWindowingCenters_.size(); + assert(data_.windowingPresetCenters_.size() == data_.windowingPresetWidths_.size()); + return data_.windowingPresetCenters_.size(); } - float DicomInstanceParameters::GetPresetWindowingCenter(size_t i) const + float DicomInstanceParameters::GetWindowingPresetCenter(size_t i) const { - if (i < GetPresetWindowingsCount()) + if (i < GetWindowingPresetsCount()) + { + return static_cast<float>(data_.windowingPresetCenters_[i]); + } + else { - return static_cast<float>(data_.presetWindowingCenters_[i]); + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + + float DicomInstanceParameters::GetWindowingPresetWidth(size_t i) const + { + if (i < GetWindowingPresetsCount()) + { + return static_cast<float>(data_.windowingPresetWidths_[i]); } else { @@ -417,19 +430,71 @@ } - float DicomInstanceParameters::GetPresetWindowingWidth(size_t i) const + static void GetWindowingBounds(float& low, + float& high, + double center, // in + double width) // in + { + low = static_cast<float>(center - width / 2.0); + high = static_cast<float>(center + width / 2.0); + } + + + void DicomInstanceParameters::GetWindowingPresetsUnion(float& center, + float& width) const { - if (i < GetPresetWindowingsCount()) + assert(tags_.get() != NULL); + size_t s = GetWindowingPresetsCount(); + + if (s > 0) { - return static_cast<float>(data_.presetWindowingWidths_[i]); + // Use the largest windowing given all the preset windowings + // that are available in the DICOM tags + float low, high; + GetWindowingBounds(low, high, GetWindowingPresetCenter(0), GetWindowingPresetWidth(0)); + + for (size_t i = 1; i < s; i++) + { + float a, b; + GetWindowingBounds(a, b, GetWindowingPresetCenter(i), GetWindowingPresetWidth(i)); + low = std::min(low, a); + high = std::max(high, b); + } + + assert(low <= high); + + if (LinearAlgebra::IsNear(low, high)) + { + // Cannot infer a suitable windowing from the available tags + center = 128.0f; + width = 256.0f; + } + else + { + center = (low + high) / 2.0f; + width = (high - low); + } } else { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + float a, b; + if (tags_->ParseFloat(a, Orthanc::DICOM_TAG_SMALLEST_IMAGE_PIXEL_VALUE) && + tags_->ParseFloat(b, Orthanc::DICOM_TAG_LARGEST_IMAGE_PIXEL_VALUE) && + a < b) + { + center = (a + b) / 2.0f; + width = (b - a); + } + else + { + // Cannot infer a suitable windowing from the available tags + center = 128.0f; + width = 256.0f; + } } } - + Orthanc::ImageAccessor* DicomInstanceParameters::ConvertToFloat(const Orthanc::ImageAccessor& pixelData) const { std::unique_ptr<Orthanc::Image> converted(new Orthanc::Image(Orthanc::PixelFormat_Float32, @@ -494,9 +559,9 @@ texture.reset(new FloatTextureSceneLayer(*converted)); } - if (GetPresetWindowingsCount() > 0) + if (GetWindowingPresetsCount() > 0) { - texture->SetCustomWindowing(GetPresetWindowingCenter(0), GetPresetWindowingWidth(0)); + texture->SetCustomWindowing(GetWindowingPresetCenter(0), GetWindowingPresetWidth(0)); } switch (GetImageInformation().GetPhotometricInterpretation())