Mercurial > hg > orthanc
comparison OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp @ 5647:f048683aa619
added "?whole" option to "/instances/{id}/tags" to access tags stored after pixel data
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 04 Jun 2024 17:50:45 +0200 |
parents | f7adfb22e20e |
children | 65a509cac161 |
comparison
equal
deleted
inserted
replaced
5646:9d27024a431f | 5647:f048683aa619 |
---|---|
58 static const std::string CHECK_REVISIONS = "CheckRevisions"; | 58 static const std::string CHECK_REVISIONS = "CheckRevisions"; |
59 | 59 |
60 static const char* const IGNORE_LENGTH = "ignore-length"; | 60 static const char* const IGNORE_LENGTH = "ignore-length"; |
61 static const char* const RECONSTRUCT_FILES = "ReconstructFiles"; | 61 static const char* const RECONSTRUCT_FILES = "ReconstructFiles"; |
62 static const char* const LIMIT_TO_THIS_LEVEL_MAIN_DICOM_TAGS = "LimitToThisLevelMainDicomTags"; | 62 static const char* const LIMIT_TO_THIS_LEVEL_MAIN_DICOM_TAGS = "LimitToThisLevelMainDicomTags"; |
63 static const char* const ARG_WHOLE = "whole"; | |
63 | 64 |
64 | 65 |
65 namespace Orthanc | 66 namespace Orthanc |
66 { | 67 { |
67 static std::string GetDocumentationSampleResource(ResourceType type) | 68 static std::string GetDocumentationSampleResource(ResourceType type) |
484 call.GetOutput().AnswerBuffer("{}", MimeType_Json); | 485 call.GetOutput().AnswerBuffer("{}", MimeType_Json); |
485 } | 486 } |
486 | 487 |
487 | 488 |
488 template <DicomToJsonFormat format> | 489 template <DicomToJsonFormat format> |
489 static void GetInstanceTagsInternal(RestApiGetCall& call) | 490 static void GetInstanceTagsInternal(RestApiGetCall& call, |
491 bool whole) | |
490 { | 492 { |
491 ServerContext& context = OrthancRestApi::GetContext(call); | 493 ServerContext& context = OrthancRestApi::GetContext(call); |
492 | 494 |
493 std::string publicId = call.GetUriComponent("id", ""); | 495 std::string publicId = call.GetUriComponent("id", ""); |
494 | 496 |
495 std::set<DicomTag> ignoreTagLength; | 497 std::set<DicomTag> ignoreTagLength; |
496 ParseSetOfTags(ignoreTagLength, call, IGNORE_LENGTH); | 498 ParseSetOfTags(ignoreTagLength, call, IGNORE_LENGTH); |
497 | 499 |
498 if (format != DicomToJsonFormat_Full || | 500 if (whole) |
499 !ignoreTagLength.empty()) | 501 { |
500 { | 502 // This is new in Orthanc 1.12.4. Reference: |
501 Json::Value full; | 503 // https://discourse.orthanc-server.org/t/private-tags-with-group-7fe0-are-not-provided-via-rest-api/4744 |
502 context.ReadDicomAsJson(full, publicId, ignoreTagLength); | 504 const DicomToJsonFlags flags = static_cast<DicomToJsonFlags>(DicomToJsonFlags_Default & ~DicomToJsonFlags_StopAfterPixelData); |
503 AnswerDicomAsJson(call, full, format); | 505 |
506 Json::Value answer; | |
507 | |
508 { | |
509 ServerContext::DicomCacheLocker locker(OrthancRestApi::GetContext(call), publicId); | |
510 locker.GetDicom().DatasetToJson(answer, format, flags, | |
511 ORTHANC_MAXIMUM_TAG_LENGTH, ignoreTagLength); | |
512 } | |
513 | |
514 call.GetOutput().AnswerJson(answer); | |
504 } | 515 } |
505 else | 516 else |
506 { | 517 { |
507 // This path allows one to avoid the JSON decoding if no | 518 if (format != DicomToJsonFormat_Full || |
508 // simplification is asked, and if no "ignore-length" argument | 519 !ignoreTagLength.empty()) |
509 // is present | 520 { |
510 Json::Value full; | 521 Json::Value full; |
511 context.ReadDicomAsJson(full, publicId); | 522 context.ReadDicomAsJson(full, publicId, ignoreTagLength); |
512 call.GetOutput().AnswerJson(full); | 523 AnswerDicomAsJson(call, full, format); |
513 } | 524 } |
525 else | |
526 { | |
527 // This path allows one to avoid the JSON decoding if no | |
528 // simplification is asked, and if no "ignore-length" argument | |
529 // is present | |
530 Json::Value full; | |
531 context.ReadDicomAsJson(full, publicId); | |
532 call.GetOutput().AnswerJson(full); | |
533 } | |
534 } | |
535 } | |
536 | |
537 | |
538 static void DocumentGetInstanceTags(RestApiGetCall& call) | |
539 { | |
540 call.GetDocumentation() | |
541 .SetTag("Instances") | |
542 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") | |
543 .SetHttpGetArgument( | |
544 IGNORE_LENGTH, RestApiCallDocumentation::Type_JsonListOfStrings, | |
545 "Also include the DICOM tags that are provided in this list, even if their associated value is long", false) | |
546 .SetHttpGetArgument( | |
547 ARG_WHOLE, RestApiCallDocumentation::Type_Boolean, "Whether to read the whole DICOM file from the " | |
548 "storage area (new in Orthanc 1.12.4). If set to \"false\" (default value), the DICOM file is read " | |
549 "until the pixel data tag (7fe0,0010) to optimize access to storage. Setting the option " | |
550 "to \"true\" provides access to the DICOM tags stored after the pixel data tag.", false) | |
551 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value"); | |
514 } | 552 } |
515 | 553 |
516 | 554 |
517 static void GetInstanceTags(RestApiGetCall& call) | 555 static void GetInstanceTags(RestApiGetCall& call) |
518 { | 556 { |
519 if (call.IsDocumentation()) | 557 if (call.IsDocumentation()) |
520 { | 558 { |
521 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); | 559 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); |
522 call.GetDocumentation() | 560 DocumentGetInstanceTags(call); |
523 .SetTag("Instances") | 561 call.GetDocumentation() |
524 .SetSummary("Get DICOM tags") | 562 .SetSummary("Get DICOM tags") |
525 .SetDescription("Get the DICOM tags in the specified format. By default, the `full` format is used, which " | 563 .SetDescription("Get the DICOM tags in the specified format. By default, the `full` format is used, which " |
526 "combines hexadecimal tags with human-readable description.") | 564 "combines hexadecimal tags with human-readable description.") |
527 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") | |
528 .SetHttpGetArgument(IGNORE_LENGTH, RestApiCallDocumentation::Type_JsonListOfStrings, | |
529 "Also include the DICOM tags that are provided in this list, even if their associated value is long", false) | |
530 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value") | |
531 .SetTruncatedJsonHttpGetSample("https://orthanc.uclouvain.be/demo/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/tags", 10); | 565 .SetTruncatedJsonHttpGetSample("https://orthanc.uclouvain.be/demo/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/tags", 10); |
532 return; | 566 return; |
533 } | 567 } |
534 | 568 |
569 const bool whole = call.GetBooleanArgument(ARG_WHOLE, false); | |
570 | |
535 switch (OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full)) | 571 switch (OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full)) |
536 { | 572 { |
537 case DicomToJsonFormat_Human: | 573 case DicomToJsonFormat_Human: |
538 GetInstanceTagsInternal<DicomToJsonFormat_Human>(call); | 574 GetInstanceTagsInternal<DicomToJsonFormat_Human>(call, whole); |
539 break; | 575 break; |
540 | 576 |
541 case DicomToJsonFormat_Short: | 577 case DicomToJsonFormat_Short: |
542 GetInstanceTagsInternal<DicomToJsonFormat_Short>(call); | 578 GetInstanceTagsInternal<DicomToJsonFormat_Short>(call, whole); |
543 break; | 579 break; |
544 | 580 |
545 case DicomToJsonFormat_Full: | 581 case DicomToJsonFormat_Full: |
546 GetInstanceTagsInternal<DicomToJsonFormat_Full>(call); | 582 GetInstanceTagsInternal<DicomToJsonFormat_Full>(call, whole); |
547 break; | 583 break; |
548 | 584 |
549 default: | 585 default: |
550 throw OrthancException(ErrorCode_InternalError); | 586 throw OrthancException(ErrorCode_InternalError); |
551 } | 587 } |
554 | 590 |
555 static void GetInstanceSimplifiedTags(RestApiGetCall& call) | 591 static void GetInstanceSimplifiedTags(RestApiGetCall& call) |
556 { | 592 { |
557 if (call.IsDocumentation()) | 593 if (call.IsDocumentation()) |
558 { | 594 { |
559 call.GetDocumentation() | 595 DocumentGetInstanceTags(call); |
560 .SetTag("Instances") | 596 call.GetDocumentation() |
561 .SetSummary("Get human-readable tags") | 597 .SetSummary("Get human-readable tags") |
562 .SetDescription("Get the DICOM tags in human-readable format (same as the `/instances/{id}/tags?simplify` route)") | 598 .SetDescription("Get the DICOM tags in human-readable format (same as the `/instances/{id}/tags?simplify` route)") |
563 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") | |
564 .SetHttpGetArgument(IGNORE_LENGTH, RestApiCallDocumentation::Type_JsonListOfStrings, | |
565 "Also include the DICOM tags that are provided in this list, even if their associated value is long", false) | |
566 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value") | |
567 .SetTruncatedJsonHttpGetSample("https://orthanc.uclouvain.be/demo/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/simplified-tags", 10); | 599 .SetTruncatedJsonHttpGetSample("https://orthanc.uclouvain.be/demo/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/simplified-tags", 10); |
568 return; | 600 return; |
569 } | 601 } |
570 else | 602 else |
571 { | 603 { |
572 GetInstanceTagsInternal<DicomToJsonFormat_Human>(call); | 604 GetInstanceTagsInternal<DicomToJsonFormat_Human>(call, call.GetBooleanArgument(ARG_WHOLE, false)); |
573 } | 605 } |
574 } | 606 } |
575 | 607 |
576 | 608 |
577 static void ListFrames(RestApiGetCall& call) | 609 static void ListFrames(RestApiGetCall& call) |