Mercurial > hg > orthanc-wsi
comparison ViewerPlugin/Plugin.cpp @ 217:20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 12 Jan 2021 14:24:18 +0100 |
parents | 1e864138f0da |
children | 49f647ed1b4c |
comparison
equal
deleted
inserted
replaced
216:c35a3a0627b9 | 217:20bc074ec19a |
---|---|
19 **/ | 19 **/ |
20 | 20 |
21 | 21 |
22 #include "../Framework/PrecompiledHeadersWSI.h" | 22 #include "../Framework/PrecompiledHeadersWSI.h" |
23 | 23 |
24 #include "../Framework/ImageToolbox.h" | |
24 #include "../Framework/Jpeg2000Reader.h" | 25 #include "../Framework/Jpeg2000Reader.h" |
25 #include "DicomPyramidCache.h" | 26 #include "DicomPyramidCache.h" |
26 #include "OrthancPluginConnection.h" | 27 #include "OrthancPluginConnection.h" |
27 | 28 |
28 #include <Compatibility.h> // For std::unique_ptr | 29 #include <Compatibility.h> // For std::unique_ptr |
84 OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); | 85 OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); |
85 | 86 |
86 | 87 |
87 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); | 88 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
88 | 89 |
89 unsigned int tileWidth = locker.GetPyramid().GetTileWidth(); | |
90 unsigned int tileHeight = locker.GetPyramid().GetTileHeight(); | |
91 unsigned int totalWidth = locker.GetPyramid().GetLevelWidth(0); | 90 unsigned int totalWidth = locker.GetPyramid().GetLevelWidth(0); |
92 unsigned int totalHeight = locker.GetPyramid().GetLevelHeight(0); | 91 unsigned int totalHeight = locker.GetPyramid().GetLevelHeight(0); |
93 | 92 |
94 Json::Value sizes = Json::arrayValue; | 93 Json::Value sizes = Json::arrayValue; |
95 Json::Value resolutions = Json::arrayValue; | 94 Json::Value resolutions = Json::arrayValue; |
96 Json::Value tilesCount = Json::arrayValue; | 95 Json::Value tilesCount = Json::arrayValue; |
96 Json::Value tilesSizes = Json::arrayValue; | |
97 for (unsigned int i = 0; i < locker.GetPyramid().GetLevelCount(); i++) | 97 for (unsigned int i = 0; i < locker.GetPyramid().GetLevelCount(); i++) |
98 { | 98 { |
99 unsigned int levelWidth = locker.GetPyramid().GetLevelWidth(i); | 99 const unsigned int levelWidth = locker.GetPyramid().GetLevelWidth(i); |
100 unsigned int levelHeight = locker.GetPyramid().GetLevelHeight(i); | 100 const unsigned int levelHeight = locker.GetPyramid().GetLevelHeight(i); |
101 | 101 const unsigned int tileWidth = locker.GetPyramid().GetTileWidth(i); |
102 const unsigned int tileHeight = locker.GetPyramid().GetTileHeight(i); | |
103 | |
102 resolutions.append(static_cast<float>(totalWidth) / static_cast<float>(levelWidth)); | 104 resolutions.append(static_cast<float>(totalWidth) / static_cast<float>(levelWidth)); |
103 | 105 |
104 Json::Value s = Json::arrayValue; | 106 Json::Value s = Json::arrayValue; |
105 s.append(levelWidth); | 107 s.append(levelWidth); |
106 s.append(levelHeight); | 108 s.append(levelHeight); |
108 | 110 |
109 s = Json::arrayValue; | 111 s = Json::arrayValue; |
110 s.append(OrthancWSI::CeilingDivision(levelWidth, tileWidth)); | 112 s.append(OrthancWSI::CeilingDivision(levelWidth, tileWidth)); |
111 s.append(OrthancWSI::CeilingDivision(levelHeight, tileHeight)); | 113 s.append(OrthancWSI::CeilingDivision(levelHeight, tileHeight)); |
112 tilesCount.append(s); | 114 tilesCount.append(s); |
115 | |
116 s = Json::arrayValue; | |
117 s.append(tileWidth); | |
118 s.append(tileHeight); | |
119 tilesSizes.append(s); | |
113 } | 120 } |
114 | 121 |
115 Json::Value result; | 122 Json::Value result; |
116 result["ID"] = seriesId; | 123 result["ID"] = seriesId; |
117 result["Resolutions"] = resolutions; | 124 result["Resolutions"] = resolutions; |
118 result["Sizes"] = sizes; | 125 result["Sizes"] = sizes; |
119 result["TileHeight"] = tileHeight; | |
120 result["TileWidth"] = tileWidth; | |
121 result["TilesCount"] = tilesCount; | 126 result["TilesCount"] = tilesCount; |
127 result["TilesSizes"] = tilesSizes; | |
122 result["TotalHeight"] = totalHeight; | 128 result["TotalHeight"] = totalHeight; |
123 result["TotalWidth"] = totalWidth; | 129 result["TotalWidth"] = totalWidth; |
124 | 130 |
125 std::string s = result.toStyledString(); | 131 std::string s = result.toStyledString(); |
126 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); | 132 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); |
147 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 153 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
148 } | 154 } |
149 | 155 |
150 // Retrieve the raw tile from the WSI pyramid | 156 // Retrieve the raw tile from the WSI pyramid |
151 OrthancWSI::ImageCompression compression; | 157 OrthancWSI::ImageCompression compression; |
158 Orthanc::PhotometricInterpretation photometric; | |
152 Orthanc::PixelFormat format; | 159 Orthanc::PixelFormat format; |
153 std::string tile; | 160 std::string tile; |
154 unsigned int tileWidth, tileHeight; | 161 unsigned int tileWidth, tileHeight; |
155 | 162 |
156 { | 163 { |
157 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); | 164 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
158 | 165 |
159 format = locker.GetPyramid().GetPixelFormat(); | 166 format = locker.GetPyramid().GetPixelFormat(); |
160 tileWidth = locker.GetPyramid().GetTileWidth(); | 167 tileWidth = locker.GetPyramid().GetTileWidth(level); |
161 tileHeight = locker.GetPyramid().GetTileHeight(); | 168 tileHeight = locker.GetPyramid().GetTileHeight(level); |
169 photometric = locker.GetPyramid().GetPhotometricInterpretation(); | |
162 | 170 |
163 if (!locker.GetPyramid().ReadRawTile(tile, compression, | 171 if (!locker.GetPyramid().ReadRawTile(tile, compression, |
164 static_cast<unsigned int>(level), | 172 static_cast<unsigned int>(level), |
165 static_cast<unsigned int>(tileX), | 173 static_cast<unsigned int>(tileX), |
166 static_cast<unsigned int>(tileY))) | 174 static_cast<unsigned int>(tileY))) |
191 switch (compression) | 199 switch (compression) |
192 { | 200 { |
193 case OrthancWSI::ImageCompression_Jpeg2000: | 201 case OrthancWSI::ImageCompression_Jpeg2000: |
194 decoded.reset(new OrthancWSI::Jpeg2000Reader); | 202 decoded.reset(new OrthancWSI::Jpeg2000Reader); |
195 dynamic_cast<OrthancWSI::Jpeg2000Reader&>(*decoded).ReadFromMemory(tile); | 203 dynamic_cast<OrthancWSI::Jpeg2000Reader&>(*decoded).ReadFromMemory(tile); |
204 | |
205 if (photometric == Orthanc::PhotometricInterpretation_YBR_ICT) | |
206 { | |
207 OrthancWSI::ImageToolbox::ConvertJpegYCbCrToRgb(*decoded); | |
208 } | |
209 | |
196 break; | 210 break; |
197 | 211 |
198 case OrthancWSI::ImageCompression_None: | 212 case OrthancWSI::ImageCompression_None: |
199 { | 213 { |
200 unsigned int bpp = Orthanc::GetBytesPerPixel(format); | 214 unsigned int bpp = Orthanc::GetBytesPerPixel(format); |