comparison Framework/Oracle/GenericOracleRunner.cpp @ 1151:48befc2bf66d broker

ParseDicomFromWadoCommand
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 15 Nov 2019 17:34:19 +0100
parents 7aad0984d38a
children 113131100638
comparison
equal deleted inserted replaced
1150:7aad0984d38a 1151:48befc2bf66d
28 #include "GetOrthancImageCommand.h" 28 #include "GetOrthancImageCommand.h"
29 #include "GetOrthancWebViewerJpegCommand.h" 29 #include "GetOrthancWebViewerJpegCommand.h"
30 #include "HttpCommand.h" 30 #include "HttpCommand.h"
31 #include "OracleCommandExceptionMessage.h" 31 #include "OracleCommandExceptionMessage.h"
32 #include "OrthancRestApiCommand.h" 32 #include "OrthancRestApiCommand.h"
33 #include "ParseDicomFromFileCommand.h"
34 #include "ParseDicomFromWadoCommand.h"
33 #include "ReadFileCommand.h" 35 #include "ReadFileCommand.h"
34 36
35 #if ORTHANC_ENABLE_DCMTK == 1 37 #if ORTHANC_ENABLE_DCMTK == 1
36 # include "ParseDicomFileCommand.h" 38 # include "ParseDicomSuccessMessage.h"
37 # include <dcmtk/dcmdata/dcdeftag.h> 39 # include <dcmtk/dcmdata/dcdeftag.h>
40 static unsigned int BUCKET_DICOMDIR = 0;
41 static unsigned int BUCKET_SOP = 1;
38 #endif 42 #endif
39 43
40 #include <Core/Compression/GzipCompressor.h> 44 #include <Core/Compression/GzipCompressor.h>
41 #include <Core/HttpClient.h> 45 #include <Core/HttpClient.h>
42 #include <Core/OrthancException.h> 46 #include <Core/OrthancException.h>
43 #include <Core/Toolbox.h> 47 #include <Core/Toolbox.h>
44 #include <Core/SystemToolbox.h> 48 #include <Core/SystemToolbox.h>
45 49
46 #include <boost/filesystem.hpp> 50 #include <boost/filesystem.hpp>
51
52 #include <dcmtk/dcmdata/dcfilefo.h>
47 53
48 54
49 namespace OrthancStone 55 namespace OrthancStone
50 { 56 {
51 static void CopyHttpHeaders(Orthanc::HttpClient& client, 57 static void CopyHttpHeaders(Orthanc::HttpClient& client,
98 << " to " << answer.size() << " bytes"; 104 << " to " << answer.size() << " bytes";
99 } 105 }
100 } 106 }
101 107
102 108
103 static void RunInternal(boost::weak_ptr<IObserver> receiver, 109 static void RunHttpCommand(std::string& answer,
104 IMessageEmitter& emitter, 110 Orthanc::HttpClient::HttpHeaders& answerHeaders,
105 const HttpCommand& command) 111 const HttpCommand& command)
106 { 112 {
107 Orthanc::HttpClient client; 113 Orthanc::HttpClient client;
108 client.SetUrl(command.GetUrl()); 114 client.SetUrl(command.GetUrl());
109 client.SetMethod(command.GetMethod()); 115 client.SetMethod(command.GetMethod());
110 client.SetTimeout(command.GetTimeout()); 116 client.SetTimeout(command.GetTimeout());
120 command.GetMethod() == Orthanc::HttpMethod_Put) 126 command.GetMethod() == Orthanc::HttpMethod_Put)
121 { 127 {
122 client.SetBody(command.GetBody()); 128 client.SetBody(command.GetBody());
123 } 129 }
124 130
131 client.ApplyAndThrowException(answer, answerHeaders);
132 DecodeAnswer(answer, answerHeaders);
133 }
134
135
136 static void RunInternal(boost::weak_ptr<IObserver> receiver,
137 IMessageEmitter& emitter,
138 const HttpCommand& command)
139 {
140 std::string answer;
141 Orthanc::HttpClient::HttpHeaders answerHeaders;
142 RunHttpCommand(answer, answerHeaders, command);
143
144 HttpCommand::SuccessMessage message(command, answerHeaders, answer);
145 emitter.EmitMessage(receiver, message);
146 }
147
148
149 static void RunOrthancRestApiCommand(std::string& answer,
150 Orthanc::HttpClient::HttpHeaders& answerHeaders,
151 const Orthanc::WebServiceParameters& orthanc,
152 const OrthancRestApiCommand& command)
153 {
154 Orthanc::HttpClient client(orthanc, command.GetUri());
155 client.SetMethod(command.GetMethod());
156 client.SetTimeout(command.GetTimeout());
157
158 CopyHttpHeaders(client, command.GetHttpHeaders());
159
160 if (command.GetMethod() == Orthanc::HttpMethod_Post ||
161 command.GetMethod() == Orthanc::HttpMethod_Put)
162 {
163 client.SetBody(command.GetBody());
164 }
165
166 client.ApplyAndThrowException(answer, answerHeaders);
167 DecodeAnswer(answer, answerHeaders);
168 }
169
170
171 static void RunInternal(boost::weak_ptr<IObserver> receiver,
172 IMessageEmitter& emitter,
173 const Orthanc::WebServiceParameters& orthanc,
174 const OrthancRestApiCommand& command)
175 {
176 std::string answer;
177 Orthanc::HttpClient::HttpHeaders answerHeaders;
178 RunOrthancRestApiCommand(answer, answerHeaders, orthanc, command);
179
180 OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer);
181 emitter.EmitMessage(receiver, message);
182 }
183
184
185 static void RunInternal(boost::weak_ptr<IObserver> receiver,
186 IMessageEmitter& emitter,
187 const Orthanc::WebServiceParameters& orthanc,
188 const GetOrthancImageCommand& command)
189 {
190 Orthanc::HttpClient client(orthanc, command.GetUri());
191 client.SetTimeout(command.GetTimeout());
192
193 CopyHttpHeaders(client, command.GetHttpHeaders());
194
125 std::string answer; 195 std::string answer;
126 Orthanc::HttpClient::HttpHeaders answerHeaders; 196 Orthanc::HttpClient::HttpHeaders answerHeaders;
127 client.ApplyAndThrowException(answer, answerHeaders); 197 client.ApplyAndThrowException(answer, answerHeaders);
128 198
129 DecodeAnswer(answer, answerHeaders); 199 DecodeAnswer(answer, answerHeaders);
130 200
131 HttpCommand::SuccessMessage message(command, answerHeaders, answer); 201 command.ProcessHttpAnswer(receiver, emitter, answer, answerHeaders);
132 emitter.EmitMessage(receiver, message);
133 } 202 }
134 203
135 204
136 static void RunInternal(boost::weak_ptr<IObserver> receiver, 205 static void RunInternal(boost::weak_ptr<IObserver> receiver,
137 IMessageEmitter& emitter, 206 IMessageEmitter& emitter,
138 const Orthanc::WebServiceParameters& orthanc, 207 const Orthanc::WebServiceParameters& orthanc,
139 const OrthancRestApiCommand& command) 208 const GetOrthancWebViewerJpegCommand& command)
140 { 209 {
141 Orthanc::HttpClient client(orthanc, command.GetUri()); 210 Orthanc::HttpClient client(orthanc, command.GetUri());
142 client.SetMethod(command.GetMethod());
143 client.SetTimeout(command.GetTimeout()); 211 client.SetTimeout(command.GetTimeout());
144 212
145 CopyHttpHeaders(client, command.GetHttpHeaders()); 213 CopyHttpHeaders(client, command.GetHttpHeaders());
146
147 if (command.GetMethod() == Orthanc::HttpMethod_Post ||
148 command.GetMethod() == Orthanc::HttpMethod_Put)
149 {
150 client.SetBody(command.GetBody());
151 }
152 214
153 std::string answer; 215 std::string answer;
154 Orthanc::HttpClient::HttpHeaders answerHeaders; 216 Orthanc::HttpClient::HttpHeaders answerHeaders;
155 client.ApplyAndThrowException(answer, answerHeaders); 217 client.ApplyAndThrowException(answer, answerHeaders);
156 218
157 DecodeAnswer(answer, answerHeaders); 219 DecodeAnswer(answer, answerHeaders);
158 220
159 OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer); 221 command.ProcessHttpAnswer(receiver, emitter, answer);
222 }
223
224
225 static std::string GetPath(const std::string& root,
226 const std::string& file)
227 {
228 boost::filesystem::path a(root);
229 boost::filesystem::path b(file);
230
231 boost::filesystem::path c;
232 if (b.is_absolute())
233 {
234 c = b;
235 }
236 else
237 {
238 c = a / b;
239 }
240
241 return c.string();
242 }
243
244
245 static void RunInternal(boost::weak_ptr<IObserver> receiver,
246 IMessageEmitter& emitter,
247 const std::string& root,
248 const ReadFileCommand& command)
249 {
250 std::string path = GetPath(root, command.GetPath());
251 LOG(TRACE) << "Oracle reading file: " << path;
252
253 std::string content;
254 Orthanc::SystemToolbox::ReadFile(content, path, true /* log */);
255
256 ReadFileCommand::SuccessMessage message(command, content);
160 emitter.EmitMessage(receiver, message); 257 emitter.EmitMessage(receiver, message);
161 } 258 }
162 259
163 260
164 static void RunInternal(boost::weak_ptr<IObserver> receiver, 261 #if ORTHANC_ENABLE_DCMTK == 1
165 IMessageEmitter& emitter, 262 static Orthanc::ParsedDicomFile* ParseDicom(uint64_t& fileSize, /* OUT */
263 const std::string& path,
264 bool isPixelData)
265 {
266 if (!Orthanc::SystemToolbox::IsRegularFile(path))
267 {
268 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentFile);
269 }
270
271 LOG(TRACE) << "Parsing DICOM file, " << (isPixelData ? "with" : "without")
272 << " pixel data: " << path;
273
274 boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
275
276 fileSize = Orthanc::SystemToolbox::GetFileSize(path);
277
278 // Check for 32bit systems
279 if (fileSize != static_cast<uint64_t>(static_cast<size_t>(fileSize)))
280 {
281 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory);
282 }
283
284 DcmFileFormat dicom;
285 bool ok;
286
287 if (isPixelData)
288 {
289 ok = dicom.loadFile(path.c_str()).good();
290 }
291 else
292 {
293 #if DCMTK_VERSION_NUMBER >= 362
294 /**
295 * NB : We could stop at (0x3007, 0x0000) instead of
296 * DCM_PixelData as the Stone framework does not use further
297 * tags (cf. the Orthanc::DICOM_TAG_* constants), but we still
298 * use "PixelData" as this does not change the runtime much, and
299 * as it is more explicit.
300 **/
301 static const DcmTagKey STOP = DCM_PixelData;
302 //static const DcmTagKey STOP(0x3007, 0x0000);
303
304 ok = dicom.loadFileUntilTag(path.c_str(), EXS_Unknown, EGL_noChange,
305 DCM_MaxReadLength, ERM_autoDetect, STOP).good();
306 #else
307 // The primitive "loadFileUntilTag" was introduced in DCMTK 3.6.2
308 ok = dicom.loadFile(path.c_str()).good();
309 #endif
310 }
311
312 if (ok)
313 {
314 std::auto_ptr<Orthanc::ParsedDicomFile> result(new Orthanc::ParsedDicomFile(dicom));
315
316 boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time();
317 LOG(TRACE) << path << ": parsed in " << (end-start).total_milliseconds() << " ms";
318
319 return result.release();
320 }
321 else
322 {
323 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
324 "Cannot parse file: " + path);
325 }
326 }
327
328
329 static void RunInternal(boost::weak_ptr<IObserver> receiver,
330 IMessageEmitter& emitter,
331 boost::shared_ptr<ParsedDicomCache> cache,
332 const std::string& root,
333 const ParseDicomFromFileCommand& command)
334 {
335 const std::string path = GetPath(root, command.GetPath());
336
337 if (cache)
338 {
339 ParsedDicomCache::Reader reader(*cache, BUCKET_DICOMDIR, path);
340 if (reader.IsValid() &&
341 (!command.IsPixelDataIncluded() ||
342 reader.HasPixelData()))
343 {
344 // Reuse the DICOM file from the cache
345 ParseDicomSuccessMessage message(command, reader.GetDicom(), reader.GetFileSize(), reader.HasPixelData());
346 emitter.EmitMessage(receiver, message);
347 return;
348 }
349 }
350
351 uint64_t fileSize;
352 std::auto_ptr<Orthanc::ParsedDicomFile> parsed(ParseDicom(fileSize, path, command.IsPixelDataIncluded()));
353
354 if (fileSize != static_cast<size_t>(fileSize))
355 {
356 // Cannot load such a large file on 32-bit architecture
357 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory);
358 }
359
360 {
361 ParseDicomSuccessMessage message
362 (command, *parsed, static_cast<size_t>(fileSize), command.IsPixelDataIncluded());
363 emitter.EmitMessage(receiver, message);
364 }
365
366 if (cache)
367 {
368 // Store it into the cache for future use
369
370 // Invalidate to overwrite DICOM instance that would already
371 // be stored without pixel data
372 cache->Invalidate(BUCKET_DICOMDIR, path);
373
374 cache->Acquire(BUCKET_DICOMDIR, path, parsed.release(),
375 static_cast<size_t>(fileSize), command.IsPixelDataIncluded());
376 }
377 }
378
379
380 static void RunInternal(boost::weak_ptr<IObserver> receiver,
381 IMessageEmitter& emitter,
382 boost::shared_ptr<ParsedDicomCache> cache,
166 const Orthanc::WebServiceParameters& orthanc, 383 const Orthanc::WebServiceParameters& orthanc,
167 const GetOrthancImageCommand& command) 384 const ParseDicomFromWadoCommand& command)
168 { 385 {
169 Orthanc::HttpClient client(orthanc, command.GetUri()); 386 if (cache)
170 client.SetTimeout(command.GetTimeout()); 387 {
171 388 ParsedDicomCache::Reader reader(*cache, BUCKET_SOP, command.GetSopInstanceUid());
172 CopyHttpHeaders(client, command.GetHttpHeaders()); 389 if (reader.IsValid() &&
173 390 reader.HasPixelData())
391 {
392 // Reuse the DICOM file from the cache
393 ParseDicomSuccessMessage message(command, reader.GetDicom(), reader.GetFileSize(), reader.HasPixelData());
394 emitter.EmitMessage(receiver, message);
395 return;
396 }
397 }
398
174 std::string answer; 399 std::string answer;
175 Orthanc::HttpClient::HttpHeaders answerHeaders; 400 Orthanc::HttpClient::HttpHeaders answerHeaders;
176 client.ApplyAndThrowException(answer, answerHeaders); 401
177 402 switch (command.GetRestCommand().GetType())
178 DecodeAnswer(answer, answerHeaders); 403 {
179 404 case IOracleCommand::Type_Http:
180 command.ProcessHttpAnswer(receiver, emitter, answer, answerHeaders); 405 RunHttpCommand(answer, answerHeaders, dynamic_cast<const HttpCommand&>(command.GetRestCommand()));
181 } 406 break;
182 407
183 408 case IOracleCommand::Type_OrthancRestApi:
184 static void RunInternal(boost::weak_ptr<IObserver> receiver, 409 RunOrthancRestApiCommand(answer, answerHeaders, orthanc,
185 IMessageEmitter& emitter, 410 dynamic_cast<const OrthancRestApiCommand&>(command.GetRestCommand()));
186 const Orthanc::WebServiceParameters& orthanc, 411 break;
187 const GetOrthancWebViewerJpegCommand& command) 412
188 { 413 default:
189 Orthanc::HttpClient client(orthanc, command.GetUri()); 414 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
190 client.SetTimeout(command.GetTimeout()); 415 }
191 416
192 CopyHttpHeaders(client, command.GetHttpHeaders()); 417 size_t fileSize;
193 418 std::auto_ptr<Orthanc::ParsedDicomFile> parsed(ParseDicomSuccessMessage::ParseWadoAnswer(fileSize, answer, answerHeaders));
194 std::string answer; 419
195 Orthanc::HttpClient::HttpHeaders answerHeaders; 420 {
196 client.ApplyAndThrowException(answer, answerHeaders); 421 ParseDicomSuccessMessage message(command, *parsed, fileSize,
197 422 true /* pixel data always is included in WADO-RS */);
198 DecodeAnswer(answer, answerHeaders); 423 emitter.EmitMessage(receiver, message);
199 424 }
200 command.ProcessHttpAnswer(receiver, emitter, answer); 425
201 } 426 if (cache)
202 427 {
203 428 // Store it into the cache for future use
204 static std::string GetPath(const std::string& root, 429 cache->Acquire(BUCKET_SOP, command.GetSopInstanceUid(), parsed.release(), fileSize, true);
205 const std::string& file) 430 }
206 { 431 }
207 boost::filesystem::path a(root);
208 boost::filesystem::path b(file);
209
210 boost::filesystem::path c;
211 if (b.is_absolute())
212 {
213 c = b;
214 }
215 else
216 {
217 c = a / b;
218 }
219
220 return c.string();
221 }
222
223
224 static void RunInternal(boost::weak_ptr<IObserver> receiver,
225 IMessageEmitter& emitter,
226 const std::string& root,
227 const ReadFileCommand& command)
228 {
229 std::string path = GetPath(root, command.GetPath());
230 LOG(TRACE) << "Oracle reading file: " << path;
231
232 std::string content;
233 Orthanc::SystemToolbox::ReadFile(content, path, true /* log */);
234
235 ReadFileCommand::SuccessMessage message(command, content);
236 emitter.EmitMessage(receiver, message);
237 }
238
239
240 #if ORTHANC_ENABLE_DCMTK == 1
241 namespace
242 {
243 class IDicomHandler : public boost::noncopyable
244 {
245 public:
246 virtual ~IDicomHandler()
247 {
248 }
249
250 virtual void Handle(Orthanc::ParsedDicomFile* dicom,
251 const ParseDicomFileCommand& command,
252 const std::string& path,
253 uint64_t fileSize) = 0;
254
255 static void Apply(IDicomHandler& handler,
256 const std::string& path,
257 const ParseDicomFileCommand& command)
258 {
259 if (!Orthanc::SystemToolbox::IsRegularFile(path))
260 {
261 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentFile);
262 }
263
264 LOG(TRACE) << "Parsing DICOM file, "
265 << (command.IsPixelDataIncluded() ? "with" : "without")
266 << " pixel data: " << path;
267
268 boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
269
270 uint64_t fileSize = Orthanc::SystemToolbox::GetFileSize(path);
271
272 // Check for 32bit systems
273 if (fileSize != static_cast<uint64_t>(static_cast<size_t>(fileSize)))
274 {
275 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory);
276 }
277
278 DcmFileFormat dicom;
279 bool ok;
280
281 if (command.IsPixelDataIncluded())
282 {
283 ok = dicom.loadFile(path.c_str()).good();
284 }
285 else
286 {
287 #if DCMTK_VERSION_NUMBER >= 362
288 /**
289 * NB : We could stop at (0x3007, 0x0000) instead of
290 * DCM_PixelData as the Stone framework does not use further
291 * tags (cf. the Orthanc::DICOM_TAG_* constants), but we
292 * still use "PixelData" as this does not change the runtime
293 * much, and as it is more explicit.
294 **/
295 static const DcmTagKey STOP = DCM_PixelData;
296 //static const DcmTagKey STOP(0x3007, 0x0000);
297
298 ok = dicom.loadFileUntilTag(path.c_str(), EXS_Unknown, EGL_noChange,
299 DCM_MaxReadLength, ERM_autoDetect, STOP).good();
300 #else
301 // The primitive "loadFileUntilTag" was introduced in DCMTK 3.6.2
302 ok = dicom.loadFile(path.c_str()).good();
303 #endif
304 }
305
306 if (ok)
307 {
308 handler.Handle(new Orthanc::ParsedDicomFile(dicom), command, path, fileSize);
309
310 boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time();
311 LOG(TRACE) << path << ": parsed in " << (end-start).total_milliseconds() << " ms";
312 }
313 else
314 {
315 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
316 "Cannot parse file: " + path);
317 }
318 }
319 };
320
321
322 class DicomHandlerWithoutCache : public IDicomHandler
323 {
324 private:
325 boost::weak_ptr<IObserver> receiver_;
326 IMessageEmitter& emitter_;
327
328 public:
329 DicomHandlerWithoutCache(boost::weak_ptr<IObserver> receiver,
330 IMessageEmitter& emitter) :
331 receiver_(receiver),
332 emitter_(emitter)
333 {
334 }
335
336 virtual void Handle(Orthanc::ParsedDicomFile* dicom,
337 const ParseDicomFileCommand& command,
338 const std::string& path,
339 uint64_t fileSize)
340 {
341 std::auto_ptr<Orthanc::ParsedDicomFile> parsed(dicom);
342
343 ParseDicomFileCommand::SuccessMessage message
344 (command, *parsed, static_cast<size_t>(fileSize), command.IsPixelDataIncluded());
345 emitter_.EmitMessage(receiver_, message);
346 }
347 };
348
349
350 class DicomHandlerWithCache : public IDicomHandler
351 {
352 private:
353 boost::weak_ptr<IObserver> receiver_;
354 IMessageEmitter& emitter_;
355 boost::shared_ptr<ParsedDicomCache> cache_;
356
357 public:
358 DicomHandlerWithCache(boost::weak_ptr<IObserver> receiver,
359 IMessageEmitter& emitter,
360 boost::shared_ptr<ParsedDicomCache> cache) :
361 receiver_(receiver),
362 emitter_(emitter),
363 cache_(cache)
364 {
365 if (!cache)
366 {
367 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
368 }
369 }
370
371 virtual void Handle(Orthanc::ParsedDicomFile* dicom,
372 const ParseDicomFileCommand& command,
373 const std::string& path,
374 uint64_t fileSize)
375 {
376 std::auto_ptr<Orthanc::ParsedDicomFile> parsed(dicom);
377
378 {
379 ParseDicomFileCommand::SuccessMessage message
380 (command, *parsed, static_cast<size_t>(fileSize), command.IsPixelDataIncluded());
381 emitter_.EmitMessage(receiver_, message);
382 }
383
384 // Store it into the cache for future use
385 assert(cache_);
386
387 // Invalidate to overwrite DICOM instance that would already
388 // be stored without pixel data
389 cache_->Invalidate(path);
390
391 cache_->Acquire(path, parsed.release(),
392 static_cast<size_t>(fileSize), command.IsPixelDataIncluded());
393 }
394 };
395 }
396
397
398 static void RunInternal(boost::weak_ptr<IObserver> receiver,
399 IMessageEmitter& emitter,
400 boost::shared_ptr<ParsedDicomCache> cache,
401 const std::string& root,
402 const ParseDicomFileCommand& command)
403 {
404 const std::string path = GetPath(root, command.GetPath());
405
406 #if 1
407 if (cache.get())
408 {
409 {
410 ParsedDicomCache::Reader reader(*cache, path);
411 if (reader.IsValid() &&
412 (!command.IsPixelDataIncluded() ||
413 reader.HasPixelData()))
414 {
415 // Reuse the DICOM file from the cache
416 ParseDicomFileCommand::SuccessMessage message(
417 command, reader.GetDicom(), reader.GetFileSize(), reader.HasPixelData());
418 emitter.EmitMessage(receiver, message);
419 return;
420 }
421 }
422
423 DicomHandlerWithCache handler(receiver, emitter, cache);
424 IDicomHandler::Apply(handler, path, command);
425 }
426 else
427 {
428 // No cache available
429 DicomHandlerWithoutCache handler(receiver, emitter);
430 IDicomHandler::Apply(handler, path, command);
431 }
432 #else
433 DicomHandlerWithoutCache handler(receiver, emitter);
434 IDicomHandler::Apply(handler, path, command);
435 #endif
436 }
437
438 #endif 432 #endif
439 433
440 434
441 void GenericOracleRunner::Run(boost::weak_ptr<IObserver> receiver, 435 void GenericOracleRunner::Run(boost::weak_ptr<IObserver> receiver,
442 IMessageEmitter& emitter, 436 IMessageEmitter& emitter,
474 case IOracleCommand::Type_ReadFile: 468 case IOracleCommand::Type_ReadFile:
475 RunInternal(receiver, emitter, rootDirectory_, 469 RunInternal(receiver, emitter, rootDirectory_,
476 dynamic_cast<const ReadFileCommand&>(command)); 470 dynamic_cast<const ReadFileCommand&>(command));
477 break; 471 break;
478 472
479 case IOracleCommand::Type_ParseDicomFile: 473 case IOracleCommand::Type_ParseDicomFromFile:
474 case IOracleCommand::Type_ParseDicomFromWado:
480 #if ORTHANC_ENABLE_DCMTK == 1 475 #if ORTHANC_ENABLE_DCMTK == 1
481 RunInternal(receiver, emitter, dicomCache_, rootDirectory_, 476 switch (command.GetType())
482 dynamic_cast<const ParseDicomFileCommand&>(command)); 477 {
478 case IOracleCommand::Type_ParseDicomFromFile:
479 RunInternal(receiver, emitter, dicomCache_, rootDirectory_,
480 dynamic_cast<const ParseDicomFromFileCommand&>(command));
481 break;
482
483 case IOracleCommand::Type_ParseDicomFromWado:
484 RunInternal(receiver, emitter, dicomCache_, orthanc_,
485 dynamic_cast<const ParseDicomFromWadoCommand&>(command));
486 break;
487
488 default:
489 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
490 }
483 break; 491 break;
484 #else 492 #else
485 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, 493 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented,
486 "DCMTK must be enabled to parse DICOM files"); 494 "DCMTK must be enabled to parse DICOM files");
487 #endif 495 #endif