comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1667:9584df157a9e

clarifying variable names
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 19 Nov 2020 17:57:44 +0100
parents 1e6d3289b1ad
children ab1bc8de1798
comparison
equal deleted inserted replaced
1666:1e6d3289b1ad 1667:9584df157a9e
897 { 897 {
898 assert(prefetch_.size() == framesCount_); 898 assert(prefetch_.size() == framesCount_);
899 return prefetch_.size(); 899 return prefetch_.size();
900 } 900 }
901 901
902 size_t GetPrefetchFrameIndex(size_t i) const 902 size_t GetPrefetchIndex(size_t i) const
903 { 903 {
904 if (i >= prefetch_.size()) 904 if (i >= prefetch_.size())
905 { 905 {
906 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 906 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
907 } 907 }
1271 1271
1272 1272
1273 class PrefetchItem 1273 class PrefetchItem
1274 { 1274 {
1275 private: 1275 private:
1276 size_t frameIndex_; 1276 size_t cursorIndex_;
1277 bool isFull_; 1277 bool isFull_;
1278 1278
1279 public: 1279 public:
1280 PrefetchItem(size_t frameIndex, 1280 PrefetchItem(size_t cursorIndex,
1281 bool isFull) : 1281 bool isFull) :
1282 frameIndex_(frameIndex), 1282 cursorIndex_(cursorIndex),
1283 isFull_(isFull) 1283 isFull_(isFull)
1284 { 1284 {
1285 } 1285 }
1286 1286
1287 size_t GetFrameIndex() const 1287 size_t GetCursorIndex() const
1288 { 1288 {
1289 return frameIndex_; 1289 return cursorIndex_;
1290 } 1290 }
1291 1291
1292 bool IsFull() const 1292 bool IsFull() const
1293 { 1293 {
1294 return isFull_; 1294 return isFull_;
1324 1324
1325 void ScheduleNextPrefetch() 1325 void ScheduleNextPrefetch()
1326 { 1326 {
1327 while (!prefetchQueue_.empty()) 1327 while (!prefetchQueue_.empty())
1328 { 1328 {
1329 size_t index = prefetchQueue_.front().GetFrameIndex(); 1329 size_t cursorIndex = prefetchQueue_.front().GetCursorIndex();
1330 bool isFull = prefetchQueue_.front().IsFull(); 1330 bool isFull = prefetchQueue_.front().IsFull();
1331 prefetchQueue_.pop_front(); 1331 prefetchQueue_.pop_front();
1332 1332
1333 const std::string sopInstanceUid = frames_->GetInstanceOfFrame(index).GetSopInstanceUid(); 1333 const std::string sopInstanceUid = frames_->GetInstanceOfFrame(cursorIndex).GetSopInstanceUid();
1334 unsigned int frameNumber = frames_->GetFrameNumberInInstance(index); 1334 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1335 1335
1336 { 1336 {
1337 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frameNumber); 1337 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frameNumber);
1338 if (!accessor.IsValid() || 1338 if (!accessor.IsValid() ||
1339 (isFull && accessor.GetQuality() == 0)) 1339 (isFull && accessor.GetQuality() == 0))
1340 { 1340 {
1341 if (isFull) 1341 if (isFull)
1342 { 1342 {
1343 ScheduleLoadFullDicomFrame(index, PRIORITY_NORMAL, true); 1343 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_NORMAL, true);
1344 } 1344 }
1345 else 1345 else
1346 { 1346 {
1347 ScheduleLoadRenderedFrame(index, PRIORITY_NORMAL, true); 1347 ScheduleLoadRenderedFrame(cursorIndex, PRIORITY_NORMAL, true);
1348 } 1348 }
1349 return; 1349 return;
1350 } 1350 }
1351 } 1351 }
1352 } 1352 }
1368 unsigned int frameNumber) 1368 unsigned int frameNumber)
1369 { 1369 {
1370 if (cursor_.get() != NULL && 1370 if (cursor_.get() != NULL &&
1371 frames_.get() != NULL) 1371 frames_.get() != NULL)
1372 { 1372 {
1373 size_t index = cursor_->GetCurrentIndex(); 1373 size_t cursorIndex = cursor_->GetCurrentIndex();
1374 1374
1375 if (frames_->GetInstanceOfFrame(index).GetSopInstanceUid() == sopInstanceUid && 1375 if (frames_->GetInstanceOfFrame(cursorIndex).GetSopInstanceUid() == sopInstanceUid &&
1376 frames_->GetFrameNumberInInstance(index) == frameNumber) 1376 frames_->GetFrameNumberInInstance(cursorIndex) == frameNumber)
1377 { 1377 {
1378 DisplayCurrentFrame(); 1378 DisplayCurrentFrame();
1379 } 1379 }
1380 } 1380 }
1381 } 1381 }
1386 DisplayedFrameQuality quality = DisplayedFrameQuality_None; 1386 DisplayedFrameQuality quality = DisplayedFrameQuality_None;
1387 1387
1388 if (cursor_.get() != NULL && 1388 if (cursor_.get() != NULL &&
1389 frames_.get() != NULL) 1389 frames_.get() != NULL)
1390 { 1390 {
1391 const size_t index = cursor_->GetCurrentIndex(); 1391 const size_t cursorIndex = cursor_->GetCurrentIndex();
1392 1392
1393 unsigned int cachedQuality; 1393 unsigned int cachedQuality;
1394 if (!DisplayFrame(cachedQuality, index)) 1394 if (!DisplayFrame(cachedQuality, cursorIndex))
1395 { 1395 {
1396 // This frame is not cached yet: Load it 1396 // This frame is not cached yet: Load it
1397 if (source_.HasDicomWebRendered()) 1397 if (source_.HasDicomWebRendered())
1398 { 1398 {
1399 ScheduleLoadRenderedFrame(index, PRIORITY_HIGH, false /* not a prefetch */); 1399 ScheduleLoadRenderedFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */);
1400 } 1400 }
1401 else 1401 else
1402 { 1402 {
1403 ScheduleLoadFullDicomFrame(index, PRIORITY_HIGH, false /* not a prefetch */); 1403 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */);
1404 } 1404 }
1405 } 1405 }
1406 else if (cachedQuality < QUALITY_FULL) 1406 else if (cachedQuality < QUALITY_FULL)
1407 { 1407 {
1408 // This frame is only available in low-res: Download the full DICOM 1408 // This frame is only available in low-res: Download the full DICOM
1409 ScheduleLoadFullDicomFrame(index, PRIORITY_HIGH, false /* not a prefetch */); 1409 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */);
1410 quality = DisplayedFrameQuality_Low; 1410 quality = DisplayedFrameQuality_Low;
1411 } 1411 }
1412 else 1412 else
1413 { 1413 {
1414 quality = DisplayedFrameQuality_High; 1414 quality = DisplayedFrameQuality_High;
1417 { 1417 {
1418 // Prepare prefetching 1418 // Prepare prefetching
1419 prefetchQueue_.clear(); 1419 prefetchQueue_.clear();
1420 for (size_t i = 0; i < cursor_->GetPrefetchSize() && i < 16; i++) 1420 for (size_t i = 0; i < cursor_->GetPrefetchSize() && i < 16; i++)
1421 { 1421 {
1422 size_t a = cursor_->GetPrefetchFrameIndex(i); 1422 size_t a = cursor_->GetPrefetchIndex(i);
1423 if (a != index) 1423 if (a != cursorIndex)
1424 { 1424 {
1425 prefetchQueue_.push_back(PrefetchItem(a, i < 2)); 1425 prefetchQueue_.push_back(PrefetchItem(a, i < 2));
1426 } 1426 }
1427 } 1427 }
1428 1428
1467 layer.GetWindowing(windowingCenter_, windowingWidth_); 1467 layer.GetWindowing(windowingCenter_, windowingWidth_);
1468 } 1468 }
1469 } 1469 }
1470 1470
1471 1471
1472 static bool IsFrameMonochrome1(const OrthancStone::SortedFrames& frames,
1473 size_t frameIndex)
1474 {
1475 const OrthancStone::DicomInstanceParameters& instance = frames.GetInstanceOfFrame(frameIndex);
1476 return (instance.GetImageInformation().GetPhotometricInterpretation() ==
1477 Orthanc::PhotometricInterpretation_Monochrome1);
1478 }
1479
1480
1481 bool DisplayFrame(unsigned int& quality, 1472 bool DisplayFrame(unsigned int& quality,
1482 size_t index) 1473 size_t cursorIndex)
1483 { 1474 {
1484 if (frames_.get() == NULL) 1475 if (frames_.get() == NULL)
1485 { 1476 {
1486 return false; 1477 return false;
1487 } 1478 }
1488 1479
1489 const std::string sopInstanceUid = frames_->GetInstanceOfFrame(index).GetSopInstanceUid(); 1480 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex);
1490 size_t frameNumber = frames_->GetFrameNumberInInstance(index); 1481 const std::string sopInstanceUid = instance.GetSopInstanceUid();
1482 size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1491 1483
1492 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frameNumber); 1484 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frameNumber);
1493 if (accessor.IsValid()) 1485 if (accessor.IsValid())
1494 { 1486 {
1495 SaveCurrentWindowing(); 1487 SaveCurrentWindowing();
1496 1488
1497 quality = accessor.GetQuality(); 1489 quality = accessor.GetQuality();
1498 1490
1491 bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() ==
1492 Orthanc::PhotometricInterpretation_Monochrome1);
1493
1499 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer; 1494 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer;
1500 1495
1501 switch (accessor.GetImage().GetFormat()) 1496 switch (accessor.GetImage().GetFormat())
1502 { 1497 {
1503 case Orthanc::PixelFormat_RGB24: 1498 case Orthanc::PixelFormat_RGB24:
1507 case Orthanc::PixelFormat_Float32: 1502 case Orthanc::PixelFormat_Float32:
1508 { 1503 {
1509 std::unique_ptr<OrthancStone::FloatTextureSceneLayer> tmp( 1504 std::unique_ptr<OrthancStone::FloatTextureSceneLayer> tmp(
1510 new OrthancStone::FloatTextureSceneLayer(accessor.GetImage())); 1505 new OrthancStone::FloatTextureSceneLayer(accessor.GetImage()));
1511 tmp->SetCustomWindowing(windowingCenter_, windowingWidth_); 1506 tmp->SetCustomWindowing(windowingCenter_, windowingWidth_);
1512 tmp->SetInverted(inverted_ ^ IsFrameMonochrome1(*frames_, index)); 1507 tmp->SetInverted(inverted_ ^ isMonochrome1);
1513 layer.reset(tmp.release()); 1508 layer.reset(tmp.release());
1514 break; 1509 break;
1515 } 1510 }
1516 1511
1517 default: 1512 default:
1521 layer->SetLinearInterpolation(true); 1516 layer->SetLinearInterpolation(true);
1522 layer->SetFlipX(flipX_); 1517 layer->SetFlipX(flipX_);
1523 layer->SetFlipY(flipY_); 1518 layer->SetFlipY(flipY_);
1524 1519
1525 double pixelSpacingX, pixelSpacingY; 1520 double pixelSpacingX, pixelSpacingY;
1526 OrthancStone::GeometryToolbox::GetPixelSpacing( 1521 OrthancStone::GeometryToolbox::GetPixelSpacing(pixelSpacingX, pixelSpacingY, instance.GetTags());
1527 pixelSpacingX, pixelSpacingY, frames_->GetInstanceOfFrame(index).GetTags());
1528 layer->SetPixelSpacing(pixelSpacingX, pixelSpacingY); 1522 layer->SetPixelSpacing(pixelSpacingX, pixelSpacingY);
1529
1530 1523
1531 std::unique_ptr<OrthancStone::MacroSceneLayer> annotationsLayer; 1524 std::unique_ptr<OrthancStone::MacroSceneLayer> annotationsLayer;
1532 1525
1533 if (annotations_ && 1526 if (annotations_ &&
1534 cursor_.get() != NULL) 1527 cursor_.get() != NULL)
1592 { 1585 {
1593 return false; 1586 return false;
1594 } 1587 }
1595 } 1588 }
1596 1589
1597 void ScheduleLoadFullDicomFrame(size_t index, 1590 void ScheduleLoadFullDicomFrame(size_t cursorIndex,
1598 int priority, 1591 int priority,
1599 bool isPrefetch) 1592 bool isPrefetch)
1600 { 1593 {
1601 if (frames_.get() != NULL) 1594 if (frames_.get() != NULL)
1602 { 1595 {
1603 std::string sopInstanceUid = frames_->GetInstanceOfFrame(index).GetSopInstanceUid(); 1596 std::string sopInstanceUid = frames_->GetInstanceOfFrame(cursorIndex).GetSopInstanceUid();
1604 unsigned int frameNumber = frames_->GetFrameNumberInInstance(index); 1597 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1605 1598
1606 { 1599 {
1607 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); 1600 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock());
1608 lock->Schedule( 1601 lock->Schedule(
1609 GetSharedObserver(), priority, OrthancStone::ParseDicomFromWadoCommand::Create( 1602 GetSharedObserver(), priority, OrthancStone::ParseDicomFromWadoCommand::Create(
1613 new SetFullDicomFrame(GetSharedObserver(), sopInstanceUid, frameNumber, isPrefetch))); 1606 new SetFullDicomFrame(GetSharedObserver(), sopInstanceUid, frameNumber, isPrefetch)));
1614 } 1607 }
1615 } 1608 }
1616 } 1609 }
1617 1610
1618 void ScheduleLoadRenderedFrame(size_t index, 1611 void ScheduleLoadRenderedFrame(size_t cursorIndex,
1619 int priority, 1612 int priority,
1620 bool isPrefetch) 1613 bool isPrefetch)
1621 { 1614 {
1622 if (!source_.HasDicomWebRendered()) 1615 if (!source_.HasDicomWebRendered())
1623 { 1616 {
1624 ScheduleLoadFullDicomFrame(index, priority, isPrefetch); 1617 ScheduleLoadFullDicomFrame(cursorIndex, priority, isPrefetch);
1625 } 1618 }
1626 else if (frames_.get() != NULL) 1619 else if (frames_.get() != NULL)
1627 { 1620 {
1628 std::string sopInstanceUid = frames_->GetInstanceOfFrame(index).GetSopInstanceUid(); 1621 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex);
1629 unsigned int frameNumber = frames_->GetFrameNumberInInstance(index); 1622 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1630 bool isMonochrome1 = IsFrameMonochrome1(*frames_, index); 1623
1624 bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() ==
1625 Orthanc::PhotometricInterpretation_Monochrome1);
1631 1626
1632 const std::string uri = ("studies/" + frames_->GetStudyInstanceUid() + 1627 const std::string uri = ("studies/" + frames_->GetStudyInstanceUid() +
1633 "/series/" + frames_->GetSeriesInstanceUid() + 1628 "/series/" + frames_->GetSeriesInstanceUid() +
1634 "/instances/" + sopInstanceUid + 1629 "/instances/" + instance.GetSopInstanceUid() +
1635 "/frames/" + boost::lexical_cast<std::string>(frameNumber + 1) + "/rendered"); 1630 "/frames/" + boost::lexical_cast<std::string>(frameNumber + 1) + "/rendered");
1636 1631
1637 std::map<std::string, std::string> headers, arguments; 1632 std::map<std::string, std::string> headers, arguments;
1638 arguments["window"] = ( 1633 arguments["window"] = (
1639 boost::lexical_cast<std::string>(windowingCenter_) + "," + 1634 boost::lexical_cast<std::string>(windowingCenter_) + "," +
1640 boost::lexical_cast<std::string>(windowingWidth_) + ",linear"); 1635 boost::lexical_cast<std::string>(windowingWidth_) + ",linear");
1641 1636
1642 std::unique_ptr<OrthancStone::IOracleCommand> command( 1637 std::unique_ptr<OrthancStone::IOracleCommand> command(
1643 source_.CreateDicomWebCommand( 1638 source_.CreateDicomWebCommand(
1644 uri, arguments, headers, new SetLowQualityFrame( 1639 uri, arguments, headers, new SetLowQualityFrame(
1645 GetSharedObserver(), sopInstanceUid, frameNumber, 1640 GetSharedObserver(), instance.GetSopInstanceUid(), frameNumber,
1646 windowingCenter_, windowingWidth_, isMonochrome1, isPrefetch))); 1641 windowingCenter_, windowingWidth_, isMonochrome1, isPrefetch)));
1647 1642
1648 { 1643 {
1649 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); 1644 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock());
1650 lock->Schedule(GetSharedObserver(), priority, command.release()); 1645 lock->Schedule(GetSharedObserver(), priority, command.release());
1952 std::unique_ptr<OrthancStone::PolylineSceneLayer> layer(new OrthancStone::PolylineSceneLayer); 1947 std::unique_ptr<OrthancStone::PolylineSceneLayer> layer(new OrthancStone::PolylineSceneLayer);
1953 1948
1954 if (cursor_.get() != NULL && 1949 if (cursor_.get() != NULL &&
1955 frames_.get() != NULL) 1950 frames_.get() != NULL)
1956 { 1951 {
1957 const size_t index = cursor_->GetCurrentIndex(); 1952 const size_t cursorIndex = cursor_->GetCurrentIndex();
1958 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(index); 1953 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex);
1959 const unsigned int frame = frames_->GetFrameNumberInInstance(index); 1954 const unsigned int frame = frames_->GetFrameNumberInInstance(cursorIndex);
1960 1955
1961 for (std::list<const ViewerViewport*>::const_iterator 1956 for (std::list<const ViewerViewport*>::const_iterator
1962 it = viewports.begin(); it != viewports.end(); ++it) 1957 it = viewports.begin(); it != viewports.end(); ++it)
1963 { 1958 {
1964 assert(*it != NULL); 1959 assert(*it != NULL);
2170 ApplyScheduledFocus(); 2165 ApplyScheduledFocus();
2171 } 2166 }
2172 2167
2173 void ApplyScheduledFocus() 2168 void ApplyScheduledFocus()
2174 { 2169 {
2175 size_t frameIndex; 2170 size_t cursorIndex;
2176 2171
2177 if (hasFocusOnInstance_ && 2172 if (hasFocusOnInstance_ &&
2178 cursor_.get() != NULL && 2173 cursor_.get() != NULL &&
2179 frames_.get() != NULL && 2174 frames_.get() != NULL &&
2180 frames_->LookupFrame(frameIndex, focusSopInstanceUid_, focusFrameNumber_)) 2175 frames_->LookupFrame(cursorIndex, focusSopInstanceUid_, focusFrameNumber_))
2181 { 2176 {
2182 size_t current = cursor_->GetCurrentIndex(); 2177 size_t current = cursor_->GetCurrentIndex();
2183 2178
2184 if (current != frameIndex) 2179 if (current != cursorIndex)
2185 { 2180 {
2186 cursor_->SetCurrentIndex(frameIndex); 2181 cursor_->SetCurrentIndex(cursorIndex);
2187 DisplayCurrentFrame(); 2182 DisplayCurrentFrame();
2188 } 2183 }
2189 2184
2190 hasFocusOnInstance_ = false; 2185 hasFocusOnInstance_ = false;
2191 } 2186 }
2194 void FocusOnPoint(const OrthancStone::Vector& p) 2189 void FocusOnPoint(const OrthancStone::Vector& p)
2195 { 2190 {
2196 //static const double MAX_DISTANCE = 0.5; // 0.5 cm => TODO parameter? 2191 //static const double MAX_DISTANCE = 0.5; // 0.5 cm => TODO parameter?
2197 static const double MAX_DISTANCE = std::numeric_limits<double>::infinity(); 2192 static const double MAX_DISTANCE = std::numeric_limits<double>::infinity();
2198 2193
2199 size_t frameIndex; 2194 size_t cursorIndex;
2200 if (cursor_.get() != NULL && 2195 if (cursor_.get() != NULL &&
2201 frames_.get() != NULL && 2196 frames_.get() != NULL &&
2202 frames_->FindClosestFrame(frameIndex, p, MAX_DISTANCE)) 2197 frames_->FindClosestFrame(cursorIndex, p, MAX_DISTANCE))
2203 { 2198 {
2204 cursor_->SetCurrentIndex(frameIndex); 2199 cursor_->SetCurrentIndex(cursorIndex);
2205 DisplayCurrentFrame(); 2200 DisplayCurrentFrame();
2206 } 2201 }
2207 } 2202 }
2208 }; 2203 };
2209 2204