Mercurial > hg > orthanc-wsi
comparison Applications/Dicomizer.cpp @ 167:605247fc8758
Fix issue #144 (OrthancWSIDicomizer PhotometricInterpretation)
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 12 Jul 2019 12:00:31 +0200 |
parents | f0dac1e8f736 |
children | d3aea0af03e1 |
comparison
equal
deleted
inserted
replaced
166:f0dac1e8f736 | 167:605247fc8758 |
---|---|
82 | 82 |
83 static void TranscodePyramid(OrthancWSI::PyramidWriterBase& target, | 83 static void TranscodePyramid(OrthancWSI::PyramidWriterBase& target, |
84 OrthancWSI::ITiledPyramid& source, | 84 OrthancWSI::ITiledPyramid& source, |
85 const OrthancWSI::DicomizerParameters& parameters) | 85 const OrthancWSI::DicomizerParameters& parameters) |
86 { | 86 { |
87 LOG(WARNING) << "Transcoding the source pyramid (not re-encoding)"; | |
88 | |
87 Orthanc::BagOfTasks tasks; | 89 Orthanc::BagOfTasks tasks; |
88 | 90 |
89 for (unsigned int i = 0; i < source.GetLevelCount(); i++) | 91 for (unsigned int i = 0; i < source.GetLevelCount(); i++) |
90 { | 92 { |
91 LOG(WARNING) << "Creating level " << i << " of size " | 93 LOG(WARNING) << "Creating level " << i << " of size " |
92 << source.GetLevelWidth(i) << "x" << source.GetLevelHeight(i); | 94 << source.GetLevelWidth(i) << "x" << source.GetLevelHeight(i); |
93 target.AddLevel(source.GetLevelWidth(i), source.GetLevelHeight(i)); | 95 target.AddLevel(source.GetLevelWidth(i), source.GetLevelHeight(i)); |
94 } | 96 } |
95 | |
96 LOG(WARNING) << "Transcoding the source pyramid"; | |
97 | 97 |
98 OrthancWSI::TranscodeTileCommand::PrepareBagOfTasks(tasks, target, source, parameters); | 98 OrthancWSI::TranscodeTileCommand::PrepareBagOfTasks(tasks, target, source, parameters); |
99 OrthancWSI::ApplicationToolbox::Execute(tasks, parameters.GetThreadsCount()); | 99 OrthancWSI::ApplicationToolbox::Execute(tasks, parameters.GetThreadsCount()); |
100 } | 100 } |
101 | 101 |
102 | 102 |
103 static void ReconstructPyramid(OrthancWSI::PyramidWriterBase& target, | 103 static void ReconstructPyramid(OrthancWSI::PyramidWriterBase& target, |
104 OrthancWSI::ITiledPyramid& source, | 104 OrthancWSI::ITiledPyramid& source, |
105 const OrthancWSI::DicomizerParameters& parameters) | 105 const OrthancWSI::DicomizerParameters& parameters) |
106 { | 106 { |
107 LOG(WARNING) << "Re-encoding the source pyramid (not transcoding, slower process)"; | |
108 | |
107 Orthanc::BagOfTasks tasks; | 109 Orthanc::BagOfTasks tasks; |
108 | 110 |
109 unsigned int levelsCount = parameters.GetPyramidLevelsCount(target, source); | 111 unsigned int levelsCount = parameters.GetPyramidLevelsCount(target, source); |
110 LOG(WARNING) << "The target pyramid will have " << levelsCount << " levels"; | 112 LOG(WARNING) << "The target pyramid will have " << levelsCount << " levels"; |
111 assert(levelsCount >= 1); | 113 assert(levelsCount >= 1); |
158 | 160 |
159 static void Recompress(OrthancWSI::IFileTarget& output, | 161 static void Recompress(OrthancWSI::IFileTarget& output, |
160 OrthancWSI::ITiledPyramid& source, | 162 OrthancWSI::ITiledPyramid& source, |
161 const DcmDataset& dataset, | 163 const DcmDataset& dataset, |
162 const OrthancWSI::DicomizerParameters& parameters, | 164 const OrthancWSI::DicomizerParameters& parameters, |
163 const OrthancWSI::ImagedVolumeParameters& volume) | 165 const OrthancWSI::ImagedVolumeParameters& volume, |
166 OrthancWSI::ImageCompression sourceCompression) | |
164 { | 167 { |
165 OrthancWSI::TiledPyramidStatistics stats(source); | 168 OrthancWSI::TiledPyramidStatistics stats(source); |
166 | 169 |
167 LOG(WARNING) << "Size of source tiles: " << stats.GetTileWidth() << "x" << stats.GetTileHeight(); | 170 LOG(WARNING) << "Size of source tiles: " << stats.GetTileWidth() << "x" << stats.GetTileHeight(); |
168 LOG(WARNING) << "Pixel format: " << Orthanc::EnumerationToString(stats.GetPixelFormat()); | 171 LOG(WARNING) << "Pixel format: " << Orthanc::EnumerationToString(source.GetPixelFormat()); |
172 LOG(WARNING) << "Source photometric interpretation: " << Orthanc::EnumerationToString(source.GetPhotometricInterpretation()); | |
173 LOG(WARNING) << "Source compression: " << EnumerationToString(sourceCompression); | |
169 LOG(WARNING) << "Smoothing is " << (parameters.IsSmoothEnabled() ? "enabled" : "disabled"); | 174 LOG(WARNING) << "Smoothing is " << (parameters.IsSmoothEnabled() ? "enabled" : "disabled"); |
170 | 175 |
171 if (parameters.IsRepaintBackground()) | 176 if (parameters.IsRepaintBackground()) |
172 { | 177 { |
173 LOG(WARNING) << "Repainting the background with color: (" | 178 LOG(WARNING) << "Repainting the background with color: (" |
178 else | 183 else |
179 { | 184 { |
180 LOG(WARNING) << "No repainting of the background"; | 185 LOG(WARNING) << "No repainting of the background"; |
181 } | 186 } |
182 | 187 |
188 Orthanc::PhotometricInterpretation targetPhotometric; | |
189 bool transcoding; | |
190 | |
191 if (parameters.IsForceReencode() || | |
192 parameters.IsReconstructPyramid() || | |
193 sourceCompression != parameters.GetTargetCompression()) | |
194 { | |
195 // The tiles of the source image will be re-encoded | |
196 transcoding = false; | |
197 | |
198 switch (parameters.GetTargetCompression()) | |
199 { | |
200 case OrthancWSI::ImageCompression_Jpeg: | |
201 case OrthancWSI::ImageCompression_Jpeg2000: | |
202 targetPhotometric = Orthanc::PhotometricInterpretation_YBRFull422; | |
203 break; | |
204 | |
205 case OrthancWSI::ImageCompression_None: | |
206 targetPhotometric = Orthanc::PhotometricInterpretation_RGB; | |
207 break; | |
208 | |
209 default: | |
210 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
211 } | |
212 } | |
213 else | |
214 { | |
215 // Transcoding: The tiles are copied (no re-encoding) | |
216 transcoding = true; | |
217 targetPhotometric = source.GetPhotometricInterpretation(); | |
218 } | |
219 | |
183 OrthancWSI::DicomPyramidWriter target(output, dataset, | 220 OrthancWSI::DicomPyramidWriter target(output, dataset, |
184 source.GetPixelFormat(), | 221 source.GetPixelFormat(), |
185 parameters.GetTargetCompression(), | 222 parameters.GetTargetCompression(), |
186 parameters.GetTargetTileWidth(source), | 223 parameters.GetTargetTileWidth(source), |
187 parameters.GetTargetTileHeight(source), | 224 parameters.GetTargetTileHeight(source), |
188 parameters.GetDicomMaxFileSize(), | 225 parameters.GetDicomMaxFileSize(), |
189 volume); | 226 volume, targetPhotometric); |
190 target.SetJpegQuality(parameters.GetJpegQuality()); | 227 target.SetJpegQuality(parameters.GetJpegQuality()); |
191 | 228 |
192 LOG(WARNING) << "Size of target tiles: " << target.GetTileWidth() << "x" << target.GetTileHeight(); | 229 LOG(WARNING) << "Size of target tiles: " << target.GetTileWidth() << "x" << target.GetTileHeight(); |
193 | 230 LOG(WARNING) << "Target photometric interpretation: " << Orthanc::EnumerationToString(targetPhotometric); |
194 if (target.GetImageCompression() == OrthancWSI::ImageCompression_Jpeg) | 231 |
195 { | 232 if (!transcoding && |
196 LOG(WARNING) << "Target image compression: Jpeg with quality " | 233 target.GetImageCompression() == OrthancWSI::ImageCompression_Jpeg) |
234 { | |
235 LOG(WARNING) << "Target compression: Jpeg with quality " | |
197 << static_cast<int>(target.GetJpegQuality()); | 236 << static_cast<int>(target.GetJpegQuality()); |
198 target.SetJpegQuality(target.GetJpegQuality()); | 237 target.SetJpegQuality(target.GetJpegQuality()); |
199 } | 238 } |
200 else | 239 else |
201 { | 240 { |
202 LOG(WARNING) << "Target image compression: " | 241 LOG(WARNING) << "Target compression: " |
203 << OrthancWSI::EnumerationToString(target.GetImageCompression()); | 242 << OrthancWSI::EnumerationToString(target.GetImageCompression()); |
204 } | 243 } |
205 | 244 |
206 if (stats.GetTileWidth() % target.GetTileWidth() != 0 || | 245 if (stats.GetTileWidth() % target.GetTileWidth() != 0 || |
207 stats.GetTileHeight() % target.GetTileHeight() != 0) | 246 stats.GetTileHeight() % target.GetTileHeight() != 0) |
217 LOG(ERROR) << "Tiles are too small (16 pixels minimum): " | 256 LOG(ERROR) << "Tiles are too small (16 pixels minimum): " |
218 << target.GetTileWidth() << "x" << target.GetTileHeight(); | 257 << target.GetTileWidth() << "x" << target.GetTileHeight(); |
219 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); | 258 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
220 } | 259 } |
221 | 260 |
222 if (parameters.IsReconstructPyramid()) | 261 if (transcoding) |
262 { | |
263 TranscodePyramid(target, stats, parameters); | |
264 } | |
265 else | |
223 { | 266 { |
224 ReconstructPyramid(target, stats, parameters); | 267 ReconstructPyramid(target, stats, parameters); |
225 } | |
226 else | |
227 { | |
228 TranscodePyramid(target, stats, parameters); | |
229 } | 268 } |
230 | 269 |
231 target.Flush(); | 270 target.Flush(); |
232 } | 271 } |
233 | 272 |
861 | 900 |
862 return true; | 901 return true; |
863 } | 902 } |
864 | 903 |
865 | 904 |
905 | |
866 OrthancWSI::ITiledPyramid* OpenInputPyramid(OrthancWSI::ImageCompression& sourceCompression, | 906 OrthancWSI::ITiledPyramid* OpenInputPyramid(OrthancWSI::ImageCompression& sourceCompression, |
867 const std::string& path, | 907 const std::string& path, |
868 const OrthancWSI::DicomizerParameters& parameters) | 908 const OrthancWSI::DicomizerParameters& parameters) |
869 { | 909 { |
870 LOG(WARNING) << "The input image is: " << path; | 910 LOG(WARNING) << "The input image is: " << path; |
952 // Create the shared DICOM tags | 992 // Create the shared DICOM tags |
953 std::auto_ptr<DcmDataset> dataset(ParseDataset(parameters.GetDatasetPath())); | 993 std::auto_ptr<DcmDataset> dataset(ParseDataset(parameters.GetDatasetPath())); |
954 EnrichDataset(*dataset, *source, sourceCompression, parameters, volume); | 994 EnrichDataset(*dataset, *source, sourceCompression, parameters, volume); |
955 | 995 |
956 std::auto_ptr<OrthancWSI::IFileTarget> output(parameters.CreateTarget()); | 996 std::auto_ptr<OrthancWSI::IFileTarget> output(parameters.CreateTarget()); |
957 Recompress(*output, *source, *dataset, parameters, volume); | 997 Recompress(*output, *source, *dataset, parameters, volume, sourceCompression); |
958 } | 998 } |
959 } | 999 } |
960 catch (Orthanc::OrthancException& e) | 1000 catch (Orthanc::OrthancException& e) |
961 { | 1001 { |
962 LOG(ERROR) << "Terminating on exception: " << e.What(); | 1002 LOG(ERROR) << "Terminating on exception: " << e.What(); |