comparison Framework/Oracle/GenericOracleRunner.cpp @ 1110:b82b74d13830 broker

ParseDicomFileCommand
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 31 Oct 2019 15:05:46 +0100
parents 98cdfe5768a4
children 3730956f41a5
comparison
equal deleted inserted replaced
1109:79b1b541fe15 1110:b82b74d13830
19 **/ 19 **/
20 20
21 21
22 #include "GenericOracleRunner.h" 22 #include "GenericOracleRunner.h"
23 23
24 #if !defined(ORTHANC_ENABLE_DCMTK)
25 # error The macro ORTHANC_ENABLE_DCMTK must be defined
26 #endif
27
24 #include "CustomOracleCommand.h" 28 #include "CustomOracleCommand.h"
25 #include "GetOrthancImageCommand.h" 29 #include "GetOrthancImageCommand.h"
26 #include "GetOrthancWebViewerJpegCommand.h" 30 #include "GetOrthancWebViewerJpegCommand.h"
27 #include "HttpCommand.h" 31 #include "HttpCommand.h"
28 #include "OracleCommandExceptionMessage.h" 32 #include "OracleCommandExceptionMessage.h"
29 #include "OrthancRestApiCommand.h" 33 #include "OrthancRestApiCommand.h"
30 #include "ReadFileCommand.h" 34 #include "ReadFileCommand.h"
31 35
36 #if ORTHANC_ENABLE_DCMTK == 1
37 # include "ParseDicomFileCommand.h"
38 # include <dcmtk/dcmdata/dcdeftag.h>
39 #endif
40
32 #include <Core/Compression/GzipCompressor.h> 41 #include <Core/Compression/GzipCompressor.h>
33 #include <Core/HttpClient.h> 42 #include <Core/HttpClient.h>
34 #include <Core/OrthancException.h> 43 #include <Core/OrthancException.h>
35 #include <Core/Toolbox.h> 44 #include <Core/Toolbox.h>
36 #include <Core/SystemToolbox.h> 45 #include <Core/SystemToolbox.h>
37 46
38 #include <boost/filesystem.hpp> 47 #include <boost/filesystem.hpp>
48
39 49
40 namespace OrthancStone 50 namespace OrthancStone
41 { 51 {
42 static void CopyHttpHeaders(Orthanc::HttpClient& client, 52 static void CopyHttpHeaders(Orthanc::HttpClient& client,
43 const Orthanc::HttpClient::HttpHeaders& headers) 53 const Orthanc::HttpClient::HttpHeaders& headers)
180 190
181 return command.ProcessHttpAnswer(answer); 191 return command.ProcessHttpAnswer(answer);
182 } 192 }
183 193
184 194
195 static std::string GetPath(const std::string& root,
196 const std::string& file)
197 {
198 boost::filesystem::path a(root);
199 boost::filesystem::path b(file);
200
201 boost::filesystem::path c;
202 if (b.is_absolute())
203 {
204 c = b;
205 }
206 else
207 {
208 c = a / b;
209 }
210
211 LOG(INFO) << "Oracle reading file: " << c.string();
212 return c.string();
213 }
214
215
185 static IMessage* Execute(const std::string& root, 216 static IMessage* Execute(const std::string& root,
186 const ReadFileCommand& command) 217 const ReadFileCommand& command)
187 { 218 {
188 boost::filesystem::path a(root); 219 std::string path = GetPath(root, command.GetPath());
189 boost::filesystem::path b(command.GetPath()); 220
190 221 std::string content;
191 boost::filesystem::path path; 222 Orthanc::SystemToolbox::ReadFile(content, path, true /* log */);
192 if (b.is_absolute()) 223
193 { 224 return new ReadFileCommand::SuccessMessage(command, content);
194 path = b; 225 }
226
227
228 #if ORTHANC_ENABLE_DCMTK == 1
229 static IMessage* Execute(const std::string& root,
230 const ParseDicomFileCommand& command)
231 {
232 std::string path = GetPath(root, command.GetPath());
233
234 DcmFileFormat f;
235 bool ok;
236
237 if (command.IsPixelDataIncluded())
238 {
239 ok = f.loadFile(path.c_str()).good();
195 } 240 }
196 else 241 else
197 { 242 {
198 path = a / b; 243 #if DCMTK_VERSION_NUMBER >= 362
199 } 244 // NB : We could stop at (0x3007, 0x0000) instead of
200 245 // DCM_PixelData, cf. the Orthanc::DICOM_TAG_* constants
201 std::string content; 246
202 Orthanc::SystemToolbox::ReadFile(content, path.string(), true /* log */); 247 static const DcmTagKey STOP = DCM_PixelData;
203 248 //static const DcmTagKey STOP(0x3007, 0x0000);
204 return new ReadFileCommand::SuccessMessage(command, content); 249
205 } 250 ok = f.loadFileUntilTag(path.c_str(), EXS_Unknown, EGL_noChange,
251 DCM_MaxReadLength, ERM_autoDetect, STOP).good();
252 #else
253 // The primitive "loadFileUntilTag" was introduced in DCMTK 3.6.2
254 ok = f.loadFile(path.c_str()).good();
255 #endif
256 }
257
258 if (ok)
259 {
260 return new ParseDicomFileCommand::SuccessMessage(command, f);
261 }
262 else
263 {
264 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
265 "Cannot parse file: " + path);
266 }
267 }
268 #endif
206 269
207 270
208 IMessage* GenericOracleRunner::Run(IOracleCommand& command) 271 IMessage* GenericOracleRunner::Run(IOracleCommand& command)
209 { 272 {
210 try 273 try
231 return dynamic_cast<CustomOracleCommand&>(command).Execute(*this); 294 return dynamic_cast<CustomOracleCommand&>(command).Execute(*this);
232 295
233 case IOracleCommand::Type_ReadFile: 296 case IOracleCommand::Type_ReadFile:
234 return Execute(rootDirectory_, dynamic_cast<const ReadFileCommand&>(command)); 297 return Execute(rootDirectory_, dynamic_cast<const ReadFileCommand&>(command));
235 298
299 case IOracleCommand::Type_ParseDicomFile:
300 #if ORTHANC_ENABLE_DCMTK == 1
301 return Execute(rootDirectory_, dynamic_cast<const ParseDicomFileCommand&>(command));
302 #else
303 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented,
304 "DCMTK must be enabled to parse DICOM files");
305 #endif
306
236 default: 307 default:
237 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 308 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
238 } 309 }
239 } 310 }
240 catch (Orthanc::OrthancException& e) 311 catch (Orthanc::OrthancException& e)