comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1682:84fe7089ccaa

switch to server-side transcoding on failed decoding (for jpeg2k)
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 24 Nov 2020 20:54:33 +0100
parents f2e8b3ac1dcd
children eafb10992e73
comparison
equal deleted inserted replaced
1681:f2e8b3ac1dcd 1682:84fe7089ccaa
1245 class SetFullDicomFrame : public ICommand 1245 class SetFullDicomFrame : public ICommand
1246 { 1246 {
1247 private: 1247 private:
1248 std::string sopInstanceUid_; 1248 std::string sopInstanceUid_;
1249 unsigned int frameNumber_; 1249 unsigned int frameNumber_;
1250 int priority_;
1250 bool isPrefetch_; 1251 bool isPrefetch_;
1251 1252
1252 public: 1253 public:
1253 SetFullDicomFrame(boost::shared_ptr<ViewerViewport> viewport, 1254 SetFullDicomFrame(boost::shared_ptr<ViewerViewport> viewport,
1254 const std::string& sopInstanceUid, 1255 const std::string& sopInstanceUid,
1255 unsigned int frameNumber, 1256 unsigned int frameNumber,
1257 int priority,
1256 bool isPrefetch) : 1258 bool isPrefetch) :
1257 ICommand(viewport), 1259 ICommand(viewport),
1258 sopInstanceUid_(sopInstanceUid), 1260 sopInstanceUid_(sopInstanceUid),
1259 frameNumber_(frameNumber), 1261 frameNumber_(frameNumber),
1262 priority_(priority),
1260 isPrefetch_(isPrefetch) 1263 isPrefetch_(isPrefetch)
1261 { 1264 {
1262 } 1265 }
1263 1266
1264 virtual void Handle(const OrthancStone::ParseDicomSuccessMessage& message) const ORTHANC_OVERRIDE 1267 virtual void Handle(const OrthancStone::ParseDicomSuccessMessage& message) const ORTHANC_OVERRIDE
1265 { 1268 {
1266 Apply(GetViewport(), message.GetDicom(), sopInstanceUid_, frameNumber_); 1269 Apply(GetViewport(), message.GetDicom(), sopInstanceUid_, frameNumber_, priority_, isPrefetch_);
1267 1270
1268 if (isPrefetch_) 1271 if (isPrefetch_)
1269 { 1272 {
1270 GetViewport().ScheduleNextPrefetch(); 1273 GetViewport().ScheduleNextPrefetch();
1271 } 1274 }
1272 } 1275 }
1273 1276
1274 static void Apply(ViewerViewport& viewport, 1277 static void Apply(ViewerViewport& viewport,
1275 const Orthanc::ParsedDicomFile& dicom, 1278 const Orthanc::ParsedDicomFile& dicom,
1276 const std::string& sopInstanceUid, 1279 const std::string& sopInstanceUid,
1277 unsigned int frameNumber) 1280 unsigned int frameNumber,
1281 int priority,
1282 bool isPrefetch)
1278 { 1283 {
1279 Orthanc::DicomMap tags; 1284 Orthanc::DicomMap tags;
1280 dicom.ExtractDicomSummary(tags, ORTHANC_STONE_MAX_TAG_LENGTH); 1285 dicom.ExtractDicomSummary(tags, ORTHANC_STONE_MAX_TAG_LENGTH);
1281 1286
1282 std::string s; 1287 std::string s;
1283 if (!tags.LookupStringValue(s, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false)) 1288 if (!tags.LookupStringValue(s, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false))
1284 { 1289 {
1285 // Safety check 1290 // Safety check
1286 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 1291 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
1287 } 1292 }
1293
1294 std::unique_ptr<Orthanc::ImageAccessor> frame;
1288 1295
1289 std::unique_ptr<Orthanc::ImageAccessor> frame(dicom.DecodeFrame(frameNumber)); 1296 try
1297 {
1298 frame.reset(dicom.DecodeFrame(frameNumber));
1299 }
1300 catch (Orthanc::OrthancException& e)
1301 {
1302 if (e.GetErrorCode() == Orthanc::ErrorCode_NotImplemented)
1303 {
1304 viewport.serverSideTranscoding_ = true;
1305 LOG(INFO) << "Switching to server-side transcoding";
1306 viewport.ScheduleLoadFullDicomFrame(sopInstanceUid, frameNumber, priority, isPrefetch);
1307 return;
1308 }
1309 else
1310 {
1311 throw;
1312 }
1313 }
1290 1314
1291 if (frame.get() == NULL) 1315 if (frame.get() == NULL)
1292 { 1316 {
1293 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 1317 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
1294 } 1318 }
1373 bool flipX_; 1397 bool flipX_;
1374 bool flipY_; 1398 bool flipY_;
1375 bool fitNextContent_; 1399 bool fitNextContent_;
1376 bool isCtrlDown_; 1400 bool isCtrlDown_;
1377 std::list<PrefetchItem> prefetchQueue_; 1401 std::list<PrefetchItem> prefetchQueue_;
1402 bool serverSideTranscoding_;
1378 1403
1379 1404
1380 bool hasFocusOnInstance_; 1405 bool hasFocusOnInstance_;
1381 std::string focusSopInstanceUid_; 1406 std::string focusSopInstanceUid_;
1382 size_t focusFrameNumber_; 1407 size_t focusFrameNumber_;
1628 } 1653 }
1629 } 1654 }
1630 } 1655 }
1631 } 1656 }
1632 1657
1658 void ScheduleLoadFullDicomFrame(const std::string& sopInstanceUid,
1659 unsigned int frameNumber,
1660 int priority,
1661 bool isPrefetch)
1662 {
1663 if (frames_.get() != NULL)
1664 {
1665 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock());
1666 lock->Schedule(
1667 GetSharedObserver(), priority, OrthancStone::ParseDicomFromWadoCommand::Create(
1668 source_, frames_->GetStudyInstanceUid(), frames_->GetSeriesInstanceUid(),
1669 sopInstanceUid, serverSideTranscoding_,
1670 Orthanc::DicomTransferSyntax_LittleEndianExplicit,
1671 new SetFullDicomFrame(GetSharedObserver(), sopInstanceUid, frameNumber, priority, isPrefetch)));
1672 }
1673 }
1674
1633 void ScheduleLoadFullDicomFrame(size_t cursorIndex, 1675 void ScheduleLoadFullDicomFrame(size_t cursorIndex,
1634 int priority, 1676 int priority,
1635 bool isPrefetch) 1677 bool isPrefetch)
1636 { 1678 {
1637 if (frames_.get() != NULL) 1679 if (frames_.get() != NULL)
1638 { 1680 {
1639 std::string sopInstanceUid = frames_->GetInstanceOfFrame(cursorIndex).GetSopInstanceUid(); 1681 std::string sopInstanceUid = frames_->GetInstanceOfFrame(cursorIndex).GetSopInstanceUid();
1640 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); 1682 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1641 1683 ScheduleLoadFullDicomFrame(sopInstanceUid, frameNumber, priority, isPrefetch);
1642 {
1643 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock());
1644 lock->Schedule(
1645 GetSharedObserver(), priority, OrthancStone::ParseDicomFromWadoCommand::Create(
1646 source_, frames_->GetStudyInstanceUid(), frames_->GetSeriesInstanceUid(),
1647 sopInstanceUid, false /* transcoding (TODO) */,
1648 Orthanc::DicomTransferSyntax_LittleEndianExplicit /* TODO */,
1649 new SetFullDicomFrame(GetSharedObserver(), sopInstanceUid, frameNumber, isPrefetch)));
1650 }
1651 } 1684 }
1652 } 1685 }
1653 1686
1654 void ScheduleLoadRenderedFrame(size_t cursorIndex, 1687 void ScheduleLoadRenderedFrame(size_t cursorIndex,
1655 int priority, 1688 int priority,
1674 if (accessor.get() != NULL && 1707 if (accessor.get() != NULL &&
1675 accessor->IsValid()) 1708 accessor->IsValid())
1676 { 1709 {
1677 try 1710 try
1678 { 1711 {
1679 SetFullDicomFrame::Apply(*this, accessor->GetDicom(), instance.GetSopInstanceUid(), frameNumber); 1712 SetFullDicomFrame::Apply(*this, accessor->GetDicom(), instance.GetSopInstanceUid(),
1713 frameNumber, priority, isPrefetch);
1680 return; 1714 return;
1681 } 1715 }
1682 catch (Orthanc::OrthancException&) 1716 catch (Orthanc::OrthancException&)
1683 { 1717 {
1684 // This happens in the case of a JPEG2k image unsupported by DCMTK 1718 // This happens in the case of a JPEG2k image unsupported by DCMTK
1882 flipX_ = false; 1916 flipX_ = false;
1883 flipY_ = false; 1917 flipY_ = false;
1884 fitNextContent_ = true; 1918 fitNextContent_ = true;
1885 cineRate_ = DEFAULT_CINE_RATE; 1919 cineRate_ = DEFAULT_CINE_RATE;
1886 inverted_ = false; 1920 inverted_ = false;
1921 serverSideTranscoding_ = false;
1887 1922
1888 frames_.reset(frames); 1923 frames_.reset(frames);
1889 cursor_.reset(new SeriesCursor(frames_->GetFramesCount())); 1924 cursor_.reset(new SeriesCursor(frames_->GetFramesCount()));
1890 1925
1891 LOG(INFO) << "Number of frames in series: " << frames_->GetFramesCount(); 1926 LOG(INFO) << "Number of frames in series: " << frames_->GetFramesCount();