Mercurial > hg > orthanc-wsi
diff ViewerPlugin/Plugin.cpp @ 73:a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 28 Nov 2016 16:51:19 +0100 |
parents | d529d9ce3c7e |
children | ff0ef01c332c |
line wrap: on
line diff
--- a/ViewerPlugin/Plugin.cpp Mon Nov 28 10:40:48 2016 +0100 +++ b/ViewerPlugin/Plugin.cpp Mon Nov 28 16:51:19 2016 +0100 @@ -19,7 +19,8 @@ #include "../Framework/PrecompiledHeadersWSI.h" -#include "../Framework/Inputs/DicomPyramid.h" + +#include "DicomPyramidCache.h" #include "../Framework/Jpeg2000Reader.h" #include "../Resources/Orthanc/Core/Images/ImageProcessing.h" @@ -33,76 +34,6 @@ #include <cassert> - - -namespace OrthancWSI -{ - // TODO Add LRU recycling policy - class DicomPyramidCache : public boost::noncopyable - { - private: - boost::mutex mutex_; - OrthancPlugins::IOrthancConnection& orthanc_; - std::auto_ptr<DicomPyramid> pyramid_; - - DicomPyramid& GetPyramid(const std::string& seriesId) - { - // Mutex is assumed to be locked - - if (pyramid_.get() == NULL || - pyramid_->GetSeriesId() != seriesId) - { - pyramid_.reset(new DicomPyramid(orthanc_, seriesId, true /* use metadata cache */)); - } - - if (pyramid_.get() == NULL) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - return *pyramid_; - } - - public: - DicomPyramidCache(OrthancPlugins::IOrthancConnection& orthanc) : - orthanc_(orthanc) - { - } - - void Invalidate(const std::string& seriesId) - { - boost::mutex::scoped_lock lock(mutex_); - - if (pyramid_.get() != NULL && - pyramid_->GetSeriesId() == seriesId) - { - pyramid_.reset(NULL); - } - } - - class Locker : public boost::noncopyable - { - private: - boost::mutex::scoped_lock lock_; - DicomPyramid& pyramid_; - - public: - Locker(DicomPyramidCache& cache, - const std::string& seriesId) : - lock_(cache.mutex_), - pyramid_(cache.GetPyramid(seriesId)) - { - } - - DicomPyramid& GetPyramid() const - { - return pyramid_; - } - }; - }; -} - - OrthancPluginContext* context_ = NULL; std::auto_ptr<OrthancPlugins::OrthancPluginConnection> orthanc_; @@ -151,23 +82,41 @@ OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); + unsigned int tileWidth = locker.GetPyramid().GetTileWidth(); + unsigned int tileHeight = locker.GetPyramid().GetTileHeight(); unsigned int totalWidth = locker.GetPyramid().GetLevelWidth(0); unsigned int totalHeight = locker.GetPyramid().GetLevelHeight(0); + Json::Value sizes = Json::arrayValue; Json::Value resolutions = Json::arrayValue; + Json::Value tilesCount = Json::arrayValue; for (unsigned int i = 0; i < locker.GetPyramid().GetLevelCount(); i++) { - resolutions.append(static_cast<float>(totalWidth) / - static_cast<float>(locker.GetPyramid().GetLevelWidth(i))); + unsigned int levelWidth = locker.GetPyramid().GetLevelWidth(i); + unsigned int levelHeight = locker.GetPyramid().GetLevelHeight(i); + + resolutions.append(static_cast<float>(totalWidth) / static_cast<float>(levelWidth)); + + Json::Value s = Json::arrayValue; + s.append(levelWidth); + s.append(levelHeight); + sizes.append(s); + + s = Json::arrayValue; + s.append(OrthancWSI::CeilingDivision(levelWidth, tileWidth)); + s.append(OrthancWSI::CeilingDivision(levelHeight, tileHeight)); + tilesCount.append(s); } Json::Value result; result["ID"] = seriesId; - result["TotalWidth"] = totalWidth; + result["Resolutions"] = resolutions; + result["Sizes"] = sizes; + result["TileHeight"] = tileHeight; + result["TileWidth"] = tileWidth; + result["TilesCount"] = tilesCount; result["TotalHeight"] = totalHeight; - result["TileWidth"] = locker.GetPyramid().GetTileWidth(); - result["TileHeight"] = locker.GetPyramid().GetTileHeight(); - result["Resolutions"] = resolutions; + result["TotalWidth"] = totalWidth; std::string s = result.toStyledString(); OrthancPluginAnswerBuffer(context_, output, s.c_str(), s.size(), "application/json"); @@ -378,7 +327,7 @@ OrthancPluginSetDescription(context, "Provides a Web viewer of whole-slide microscopic images within Orthanc."); orthanc_.reset(new OrthancPlugins::OrthancPluginConnection(context)); - cache_.reset(new OrthancWSI::DicomPyramidCache(*orthanc_)); + cache_.reset(new OrthancWSI::DicomPyramidCache(*orthanc_, 10 /* Number of pyramids to be cached - TODO parameter */)); OrthancPluginRegisterOnChangeCallback(context_, OnChangeCallback);