Mercurial > hg > orthanc-stone
comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 2169:fe5406abd43f
added separate class Windowing
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 21 Oct 2024 15:40:34 +0200 |
parents | acc9c70bc25a |
children | 7e8b918b0482 |
comparison
equal
deleted
inserted
replaced
2168:14d6080660e7 | 2169:fe5406abd43f |
---|---|
1773 static_cast<double>(params.GetWidth())); | 1773 static_cast<double>(params.GetWidth())); |
1774 GetViewport().centralPhysicalHeight_ = (params.GetPixelSpacingY() * | 1774 GetViewport().centralPhysicalHeight_ = (params.GetPixelSpacingY() * |
1775 static_cast<double>(params.GetHeight())); | 1775 static_cast<double>(params.GetHeight())); |
1776 } | 1776 } |
1777 | 1777 |
1778 GetViewport().windowingPresetCenters_.resize(params.GetWindowingPresetsCount()); | 1778 GetViewport().windowingPresets_.resize(params.GetWindowingPresetsCount()); |
1779 GetViewport().windowingPresetWidths_.resize(params.GetWindowingPresetsCount()); | |
1780 | 1779 |
1781 for (size_t i = 0; i < params.GetWindowingPresetsCount(); i++) | 1780 for (size_t i = 0; i < params.GetWindowingPresetsCount(); i++) |
1782 { | 1781 { |
1783 LOG(INFO) << "Preset windowing " << (i + 1) << "/" << params.GetWindowingPresetsCount() | 1782 LOG(INFO) << "Preset windowing " << (i + 1) << "/" << params.GetWindowingPresetsCount() |
1784 << ": " << params.GetWindowingPresetCenter(i) | 1783 << ": " << params.GetWindowingPreset(i).GetCenter() |
1785 << "," << params.GetWindowingPresetWidth(i); | 1784 << "," << params.GetWindowingPreset(i).GetWidth(); |
1786 | 1785 |
1787 GetViewport().windowingPresetCenters_[i] = params.GetWindowingPresetCenter(i); | 1786 GetViewport().windowingPresets_[i] = params.GetWindowingPreset(i); |
1788 GetViewport().windowingPresetWidths_[i] = params.GetWindowingPresetWidth(i); | |
1789 } | 1787 } |
1790 | 1788 |
1791 if (params.GetWindowingPresetsCount() == 0) | 1789 if (params.GetWindowingPresetsCount() == 0) |
1792 { | 1790 { |
1793 LOG(INFO) << "No preset windowing"; | 1791 LOG(INFO) << "No preset windowing"; |
1794 } | 1792 } |
1795 | 1793 |
1796 uint32_t bitsStored, pixelRepresentation; | 1794 GetViewport().fallbackWindowing_ = params.GetFallbackWindowing(); |
1797 if (dicom.ParseUnsignedInteger32(bitsStored, Orthanc::DICOM_TAG_BITS_STORED) && | |
1798 dicom.ParseUnsignedInteger32(pixelRepresentation, Orthanc::DICOM_TAG_PIXEL_REPRESENTATION)) | |
1799 { | |
1800 // Added in Stone Web viewer > 2.5 | |
1801 const bool isSigned = (pixelRepresentation != 0); | |
1802 const float maximum = powf(2.0, bitsStored); | |
1803 GetViewport().windowingDefaultCenter_ = (isSigned ? 0.0f : maximum / 2.0f); | |
1804 GetViewport().windowingDefaultWidth_ = maximum; | |
1805 } | |
1806 else | |
1807 { | |
1808 GetViewport().windowingDefaultCenter_ = 128; | |
1809 GetViewport().windowingDefaultWidth_ = 256; | |
1810 } | |
1811 | 1795 |
1812 GetViewport().SetWindowingPreset(); | 1796 GetViewport().SetWindowingPreset(); |
1813 } | 1797 } |
1814 | 1798 |
1815 uint32_t cineRate; | 1799 uint32_t cineRate; |
1992 { | 1976 { |
1993 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | 1977 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
1994 } | 1978 } |
1995 else | 1979 else |
1996 { | 1980 { |
1997 if (GetViewport().windowingPresetCenters_.empty()) | 1981 if (GetViewport().windowingPresets_.empty()) |
1998 { | 1982 { |
1999 // New in Stone Web viewer 2.2: Deal with Philips multiframe | 1983 // New in Stone Web viewer 2.2: Deal with Philips multiframe |
2000 // (cf. mail from Tomas Kenda on 2021-08-17) | 1984 // (cf. mail from Tomas Kenda on 2021-08-17) |
2001 double windowingCenter, windowingWidth; | 1985 double windowingCenter, windowingWidth; |
2002 message.GetDicom().GetDefaultWindowing(windowingCenter, windowingWidth, frameNumber_); | 1986 message.GetDicom().GetDefaultWindowing(windowingCenter, windowingWidth, frameNumber_); |
2003 GetViewport().windowingPresetCenters_.push_back(windowingCenter); | 1987 GetViewport().windowingPresets_.push_back(OrthancStone::Windowing(windowingCenter, windowingWidth)); |
2004 GetViewport().windowingPresetWidths_.push_back(windowingWidth); | |
2005 GetViewport().SetWindowingPreset(); | 1988 GetViewport().SetWindowingPreset(); |
2006 } | 1989 } |
2007 | 1990 |
2008 Apply(GetViewport(), message.GetDicom(), frame.release(), sopInstanceUid_, frameNumber_); | 1991 Apply(GetViewport(), message.GetDicom(), frame.release(), sopInstanceUid_, frameNumber_); |
2009 | 1992 |
2098 boost::shared_ptr<FramesCache> framesCache_; | 2081 boost::shared_ptr<FramesCache> framesCache_; |
2099 std::unique_ptr<IFramesCollection> frames_; | 2082 std::unique_ptr<IFramesCollection> frames_; |
2100 std::unique_ptr<SeriesCursor> cursor_; | 2083 std::unique_ptr<SeriesCursor> cursor_; |
2101 float windowingCenter_; | 2084 float windowingCenter_; |
2102 float windowingWidth_; | 2085 float windowingWidth_; |
2103 std::vector<float> windowingPresetCenters_; | 2086 std::vector<OrthancStone::Windowing> windowingPresets_; |
2104 std::vector<float> windowingPresetWidths_; | 2087 OrthancStone::Windowing fallbackWindowing_; |
2105 float windowingDefaultCenter_; | |
2106 float windowingDefaultWidth_; | |
2107 unsigned int cineRate_; | 2088 unsigned int cineRate_; |
2108 bool inverted_; | 2089 bool inverted_; |
2109 bool fitNextContent_; | 2090 bool fitNextContent_; |
2110 std::list<PrefetchItem> prefetchQueue_; | 2091 std::list<PrefetchItem> prefetchQueue_; |
2111 bool serverSideTranscoding_; | 2092 bool serverSideTranscoding_; |
2622 bool softwareRendering, | 2603 bool softwareRendering, |
2623 bool linearInterpolation) : | 2604 bool linearInterpolation) : |
2624 context_(context), | 2605 context_(context), |
2625 source_(source), | 2606 source_(source), |
2626 framesCache_(cache), | 2607 framesCache_(cache), |
2627 windowingDefaultCenter_(128), | |
2628 windowingDefaultWidth_(256), | |
2629 fitNextContent_(true), | 2608 fitNextContent_(true), |
2630 hasFocusOnInstance_(false), | 2609 hasFocusOnInstance_(false), |
2631 focusFrameNumber_(0), | 2610 focusFrameNumber_(0), |
2632 synchronizationOffset_(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0)), | 2611 synchronizationOffset_(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0)), |
2633 synchronizationEnabled_(false), | 2612 synchronizationEnabled_(false), |
3172 } | 3151 } |
3173 | 3152 |
3174 | 3153 |
3175 void SetWindowingPreset() | 3154 void SetWindowingPreset() |
3176 { | 3155 { |
3177 assert(windowingPresetCenters_.size() == windowingPresetWidths_.size()); | 3156 if (windowingPresets_.empty()) |
3178 | 3157 { |
3179 if (windowingPresetCenters_.empty()) | 3158 SetWindowing(fallbackWindowing_); |
3180 { | |
3181 SetWindowing(windowingDefaultCenter_, windowingDefaultWidth_); | |
3182 } | 3159 } |
3183 else | 3160 else |
3184 { | 3161 { |
3185 SetWindowing(windowingPresetCenters_[0], windowingPresetWidths_[0]); | 3162 SetWindowing(windowingPresets_[0]); |
3186 } | 3163 } |
3187 } | 3164 } |
3188 | 3165 |
3189 void SetWindowing(float windowingCenter, | 3166 void SetWindowing(const OrthancStone::Windowing& windowing) |
3190 float windowingWidth) | 3167 { |
3191 { | 3168 windowingCenter_ = windowing.GetCenter(); |
3192 windowingCenter_ = windowingCenter; | 3169 windowingWidth_ = windowing.GetWidth(); |
3193 windowingWidth_ = windowingWidth; | |
3194 UpdateCurrentTextureParameters(); | 3170 UpdateCurrentTextureParameters(); |
3195 | 3171 |
3196 if (observer_.get() != NULL) | 3172 if (observer_.get() != NULL) |
3197 { | 3173 { |
3198 observer_->SignalWindowingUpdated(*this, windowingCenter, windowingWidth); | 3174 observer_->SignalWindowingUpdated(*this, windowingCenter_, windowingWidth_); |
3199 } | 3175 } |
3200 } | 3176 } |
3201 | 3177 |
3202 void StretchWindowing() | 3178 void StretchWindowing() |
3203 { | 3179 { |
3222 } | 3198 } |
3223 | 3199 |
3224 Orthanc::ImageProcessing::GetMinMaxFloatValue(minValue, maxValue, texture); | 3200 Orthanc::ImageProcessing::GetMinMaxFloatValue(minValue, maxValue, texture); |
3225 } | 3201 } |
3226 | 3202 |
3227 SetWindowing((minValue + maxValue) / 2.0f, maxValue - minValue); | 3203 const float center = (minValue + maxValue) / 2.0f; |
3204 const float width = maxValue - minValue; | |
3205 SetWindowing(OrthancStone::Windowing(center, width)); | |
3228 } | 3206 } |
3229 | 3207 |
3230 void FlipX() | 3208 void FlipX() |
3231 { | 3209 { |
3232 { | 3210 { |
3518 { | 3496 { |
3519 assert(windowingPresetCenters_.size() == windowingPresetWidths_.size()); | 3497 assert(windowingPresetCenters_.size() == windowingPresetWidths_.size()); |
3520 | 3498 |
3521 target = Json::arrayValue; | 3499 target = Json::arrayValue; |
3522 | 3500 |
3523 for (size_t i = 0; i < windowingPresetCenters_.size(); i++) | 3501 for (size_t i = 0; i < windowingPresets_.size(); i++) |
3524 { | 3502 { |
3525 const float c = windowingPresetCenters_[i]; | 3503 const double c = windowingPresets_[i].GetCenter(); |
3526 const float w = windowingPresetWidths_[i]; | 3504 const double w = windowingPresets_[i].GetWidth(); |
3527 | 3505 |
3528 std::string name = "Preset"; | 3506 std::string name = "Preset"; |
3529 if (windowingPresetCenters_.size() > 1) | 3507 if (windowingPresets_.size() > 1) |
3530 { | 3508 { |
3531 name += " " + boost::lexical_cast<std::string>(i + 1); | 3509 name += " " + boost::lexical_cast<std::string>(i + 1); |
3532 } | 3510 } |
3533 | 3511 |
3534 Json::Value preset = Json::objectValue; | 3512 Json::Value preset = Json::objectValue; |
4394 int center, | 4372 int center, |
4395 int width) | 4373 int width) |
4396 { | 4374 { |
4397 try | 4375 try |
4398 { | 4376 { |
4399 GetViewport(canvas)->SetWindowing(center, width); | 4377 GetViewport(canvas)->SetWindowing(OrthancStone::Windowing(center, width)); |
4400 } | 4378 } |
4401 EXTERN_CATCH_EXCEPTIONS; | 4379 EXTERN_CATCH_EXCEPTIONS; |
4402 } | 4380 } |
4403 | 4381 |
4404 | 4382 |