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);