comparison Core/DicomNetworking/DicomStoreUserConnection.cpp @ 3894:8f7ad4989fec transcoding

transcoding to uncompressed transfer syntaxes over DICOM protocol is implemented
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 07 May 2020 11:13:29 +0200
parents 7a5fa8f307e9
children c62f84c7eda9
comparison
equal deleted inserted replaced
3893:7a5fa8f307e9 3894:8f7ad4989fec
319 319
320 320
321 void DicomStoreUserConnection::Store(std::string& sopClassUid, 321 void DicomStoreUserConnection::Store(std::string& sopClassUid,
322 std::string& sopInstanceUid, 322 std::string& sopInstanceUid,
323 DcmFileFormat& dicom, 323 DcmFileFormat& dicom,
324 bool hasMoveOriginator,
324 const std::string& moveOriginatorAET, 325 const std::string& moveOriginatorAET,
325 uint16_t moveOriginatorID) 326 uint16_t moveOriginatorID)
326 { 327 {
327 DicomTransferSyntax transferSyntax; 328 DicomTransferSyntax transferSyntax;
328 LookupParameters(sopClassUid, sopInstanceUid, transferSyntax, dicom); 329 LookupParameters(sopClassUid, sopInstanceUid, transferSyntax, dicom);
345 strncpy(request.AffectedSOPClassUID, sopClassUid.c_str(), DIC_UI_LEN); 346 strncpy(request.AffectedSOPClassUID, sopClassUid.c_str(), DIC_UI_LEN);
346 request.Priority = DIMSE_PRIORITY_MEDIUM; 347 request.Priority = DIMSE_PRIORITY_MEDIUM;
347 request.DataSetType = DIMSE_DATASET_PRESENT; 348 request.DataSetType = DIMSE_DATASET_PRESENT;
348 strncpy(request.AffectedSOPInstanceUID, sopInstanceUid.c_str(), DIC_UI_LEN); 349 strncpy(request.AffectedSOPInstanceUID, sopInstanceUid.c_str(), DIC_UI_LEN);
349 350
350 if (!moveOriginatorAET.empty()) 351 if (hasMoveOriginator)
351 { 352 {
352 strncpy(request.MoveOriginatorApplicationEntityTitle, 353 strncpy(request.MoveOriginatorApplicationEntityTitle,
353 moveOriginatorAET.c_str(), DIC_AE_LEN); 354 moveOriginatorAET.c_str(), DIC_AE_LEN);
354 request.opts = O_STORE_MOVEORIGINATORAETITLE; 355 request.opts = O_STORE_MOVEORIGINATORAETITLE;
355 356
356 request.MoveOriginatorID = moveOriginatorID; // The type DIC_US is an alias for uint16_t 357 request.MoveOriginatorID = moveOriginatorID; // The type DIC_US is an alias for uint16_t
400 401
401 void DicomStoreUserConnection::Store(std::string& sopClassUid, 402 void DicomStoreUserConnection::Store(std::string& sopClassUid,
402 std::string& sopInstanceUid, 403 std::string& sopInstanceUid,
403 const void* buffer, 404 const void* buffer,
404 size_t size, 405 size_t size,
406 bool hasMoveOriginator,
405 const std::string& moveOriginatorAET, 407 const std::string& moveOriginatorAET,
406 uint16_t moveOriginatorID) 408 uint16_t moveOriginatorID)
407 { 409 {
408 std::unique_ptr<DcmFileFormat> dicom( 410 std::unique_ptr<DcmFileFormat> dicom(
409 FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); 411 FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size));
411 if (dicom.get() == NULL) 413 if (dicom.get() == NULL)
412 { 414 {
413 throw OrthancException(ErrorCode_InternalError); 415 throw OrthancException(ErrorCode_InternalError);
414 } 416 }
415 417
416 Store(sopClassUid, sopInstanceUid, *dicom, moveOriginatorAET, moveOriginatorID); 418 Store(sopClassUid, sopInstanceUid, *dicom, hasMoveOriginator, moveOriginatorAET, moveOriginatorID);
417 } 419 }
418 420
419 421
420 void DicomStoreUserConnection::LookupTranscoding(std::set<DicomTransferSyntax>& acceptedSyntaxes, 422 void DicomStoreUserConnection::LookupTranscoding(std::set<DicomTransferSyntax>& acceptedSyntaxes,
421 const std::string& sopClassUid, 423 const std::string& sopClassUid,
444 void DicomStoreUserConnection::Transcode(std::string& sopClassUid /* out */, 446 void DicomStoreUserConnection::Transcode(std::string& sopClassUid /* out */,
445 std::string& sopInstanceUid /* out */, 447 std::string& sopInstanceUid /* out */,
446 IDicomTranscoder& transcoder, 448 IDicomTranscoder& transcoder,
447 const void* buffer, 449 const void* buffer,
448 size_t size, 450 size_t size,
451 bool hasMoveOriginator,
449 const std::string& moveOriginatorAET, 452 const std::string& moveOriginatorAET,
450 uint16_t moveOriginatorID) 453 uint16_t moveOriginatorID)
451 { 454 {
452 std::unique_ptr<DcmFileFormat> dicom(FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); 455 std::unique_ptr<DcmFileFormat> dicom(FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size));
453 if (dicom.get() == NULL || 456 if (dicom.get() == NULL ||
463 LookupTranscoding(accepted, sopClassUid, inputSyntax); 466 LookupTranscoding(accepted, sopClassUid, inputSyntax);
464 467
465 if (accepted.find(inputSyntax) != accepted.end()) 468 if (accepted.find(inputSyntax) != accepted.end())
466 { 469 {
467 // No need for transcoding 470 // No need for transcoding
468 Store(sopClassUid, sopInstanceUid, *dicom, moveOriginatorAET, moveOriginatorID); 471 Store(sopClassUid, sopInstanceUid, *dicom,
472 hasMoveOriginator, moveOriginatorAET, moveOriginatorID);
469 } 473 }
470 else 474 else
471 { 475 {
472 // Transcoding is needed 476 // Transcoding is needed
473 std::set<DicomTransferSyntax> uncompressedSyntaxes; 477 std::set<DicomTransferSyntax> uncompressedSyntaxes;
487 uncompressedSyntaxes.insert(DicomTransferSyntax_BigEndianExplicit); 491 uncompressedSyntaxes.insert(DicomTransferSyntax_BigEndianExplicit);
488 } 492 }
489 493
490 std::unique_ptr<DcmFileFormat> transcoded; 494 std::unique_ptr<DcmFileFormat> transcoded;
491 495
496 bool hasSopInstanceUidChanged;
497
492 if (transcoder.HasInplaceTranscode()) 498 if (transcoder.HasInplaceTranscode())
493 { 499 {
494 if (transcoder.InplaceTranscode(*dicom, uncompressedSyntaxes, false)) 500 if (transcoder.InplaceTranscode(hasSopInstanceUidChanged, *dicom, uncompressedSyntaxes, false))
495 { 501 {
496 // In-place transcoding is supported and has succeeded 502 // In-place transcoding is supported and has succeeded
497 transcoded.reset(dicom.release()); 503 transcoded.reset(dicom.release());
498 } 504 }
499 } 505 }
500 else 506 else
501 { 507 {
502 transcoded.reset(transcoder.TranscodeToParsed(buffer, size, uncompressedSyntaxes, false)); 508 transcoded.reset(transcoder.TranscodeToParsed(hasSopInstanceUidChanged, buffer, size, uncompressedSyntaxes, false));
509 }
510
511 if (hasSopInstanceUidChanged)
512 {
513 throw OrthancException(ErrorCode_Plugin, "The transcoder has changed the SOP "
514 "instance UID while transcoding to an uncompressed transfer syntax");
503 } 515 }
504 516
505 // WARNING: The "dicom" variable must not be used below this 517 // WARNING: The "dicom" variable must not be used below this
506 // point. The "sopInstanceUid" might also have changed (if 518 // point. The "sopInstanceUid" might also have changed (if
507 // using lossy compression). 519 // using lossy compression).
525 { 537 {
526 throw OrthancException(ErrorCode_InternalError); 538 throw OrthancException(ErrorCode_InternalError);
527 } 539 }
528 else 540 else
529 { 541 {
530 Store(sopClassUid, sopInstanceUid, *transcoded, moveOriginatorAET, moveOriginatorID); 542 Store(sopClassUid, sopInstanceUid, *transcoded,
543 hasMoveOriginator, moveOriginatorAET, moveOriginatorID);
531 } 544 }
532 } 545 }
533 } 546 }
534 } 547 }
535 } 548 }