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