当前位置: 首页 > 工具软件 > Orthanc > 使用案例 >

orthanc 源码 获取dicom json

越源
2023-12-01
 ServerContext::StoreResult ServerContext::StoreAfterTranscoding(std::string& resultPublicId,
                                                                  DicomInstanceToStore& dicom,
                                                                  StoreInstanceMode mode,
                                                                  bool isReconstruct)
  {
    bool overwrite;
    switch (mode)
    {
      case StoreInstanceMode_Default:
        overwrite = overwriteInstances_;
        break;
        
      case StoreInstanceMode_OverwriteDuplicate:
        overwrite = true;
        break;
        
      case StoreInstanceMode_IgnoreDuplicate:
        overwrite = false;
        break;

      default:
        throw OrthancException(ErrorCode_ParameterOutOfRange);
    }

    bool hasPixelDataOffset;
    uint64_t pixelDataOffset;
    hasPixelDataOffset = DicomStreamReader::LookupPixelDataOffset(
      pixelDataOffset, dicom.GetBufferData(), dicom.GetBufferSize());

    DicomTransferSyntax transferSyntax;
    bool hasTransferSyntax = dicom.LookupTransferSyntax(transferSyntax);
    
    DicomMap summary;
    dicom.GetSummary(summary);   // -> from Orthanc 1.11.1, this includes the leaf nodes and sequences

    std::set<DicomTag> allMainDicomTags = DicomMap::GetAllMainDicomTags();

    try
    {
      MetricsRegistry::Timer timer(GetMetricsRegistry(), "orthanc_store_dicom_duration_ms");
      StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry());

      DicomInstanceHasher hasher(summary);
      resultPublicId = hasher.HashInstance();

      Json::Value dicomAsJson;
      dicom.GetDicomAsJson(dicomAsJson, allMainDicomTags);  // don't crop any main dicom tags

      Json::Value simplifiedTags;
      Toolbox::SimplifyDicomAsJson(simplifiedTags, dicomAsJson, DicomToJsonFormat_Human);

      // Test if the instance must be filtered out
      StoreResult result;

      if (!isReconstruct) // skip all filters if this is a reconstruction
      {
        boost::shared_lock<boost::shared_mutex> lock(listenersMutex_);

        for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
        {
          try
          {
            if (!it->GetListener().FilterIncomingInstance(dicom, simplifiedTags))
            {
              result.SetStatus(StoreStatus_FilteredOut);
              result.SetCStoreStatusCode(STATUS_Success); // to keep backward compatibility, we still return 'success'
              break;
            }

            if (dicom.GetOrigin().GetRequestOrigin() == Orthanc::RequestOrigin_DicomProtocol)
            {
              uint16_t filterResult = STATUS_Success;
              if (!it->GetListener().FilterIncomingCStoreInstance(filterResult, dicom, simplifiedTags))
              {
                // The instance is to be discarded
                result.SetStatus(StoreStatus_FilteredOut);
                result.SetCStoreStatusCode(filterResult);
                break;
              }
            }
            
          }
          catch (OrthancException& e)
          {
            LOG(ERROR) << "Error in the " << it->GetDescription() 
                       << " callback while receiving an instance: " << e.What()
                       << " (code " << e.GetErrorCode() << ")";
            throw;
          }
        }
      }

      if (result.GetStatus() == StoreStatus_FilteredOut)
      {
        LOG(INFO) << "An incoming instance has been discarded by the filter";
        return result;
      }

      // Remove the file from the DicomCache (useful if
      // "OverwriteInstances" is set to "true")
      dicomCache_.Invalidate(resultPublicId);
      PublishDicomCacheMetrics();

      // TODO Should we use "gzip" instead?
      CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None);

      FileInfo dicomInfo = accessor.Write(dicom.GetBufferData(), dicom.GetBufferSize(), 
                                          FileContentType_Dicom, compression, storeMD5_);

      ServerIndex::Attachments attachments;
      attachments.push_back(dicomInfo);

      FileInfo dicomUntilPixelData;

      ParsedDicomFile pdf(dicom.GetBufferData(), dicom.GetBufferSize());
      DicomWebJsonVisitor visitor;
      pdf.Apply(visitor);
      Json::Value v = visitor.GetResult();

      v["00431028"]["BulkDataURI"] = "http://localhost/dicom-web/studies/1.2.840.113619.2.417.3.2831214628.419.1651705382.616/series/1.2.840.113619.2.417.3.2831214628.419.1651705382.622.3/instances/1.2.840.113619.2.417.3.2831214628.419.1651705382.667.1/bulk/00431028";
      v["00431028"].removeMember("InlineBinary");


      v["7FE00010"]["BulkDataURI"] = "http://localhost/dicom-web/studies/1.2.840.113619.2.417.3.2831214628.419.1651705382.616/series/1.2.840.113619.2.417.3.2831214628.419.1651705382.622.3/instances/1.2.840.113619.2.417.3.2831214628.419.1651705382.667.1/bulk/7fe00010";
      v["7FE00010"].removeMember("InlineBinary");
     
     
      Json::StreamWriterBuilder wbuilder;

      wbuilder["indentation"] = "";       // Optional
     Json::String str = Json::writeString(wbuilder, v);
    

     
   

      if (hasPixelDataOffset &&
          (!area_.HasReadRange() ||
           compressionEnabled_))
      {
        dicomUntilPixelData = accessor.Write(dicom.GetBufferData(), pixelDataOffset, 
                                             FileContentType_DicomUntilPixelData, compression, storeMD5_);
        attachments.push_back(dicomUntilPixelData);
      }

      typedef std::map<MetadataType, std::string>  InstanceMetadata;
      InstanceMetadata  instanceMetadata;
      result.SetStatus(index_.Store(
        instanceMetadata, summary, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwrite,
        hasTransferSyntax, transferSyntax, hasPixelDataOffset, pixelDataOffset, isReconstruct));

      // Only keep the metadata for the "instance" level
      dicom.ClearMetadata();

      for (InstanceMetadata::const_iterator it = instanceMetadata.begin();
           it != instanceMetadata.end(); ++it)
      {
        dicom.AddMetadata(ResourceType_Instance, it->first, it->second);
      }
            
      if (result.GetStatus() != StoreStatus_Success)
      {
        accessor.Remove(dicomInfo);

        if (dicomUntilPixelData.IsValid())
        {
          accessor.Remove(dicomUntilPixelData);
        }
      }

      if (!isReconstruct) 
      {
        // skip logs in case of reconstruction
        switch (result.GetStatus())
        {
          case StoreStatus_Success:
            LOG(INFO) << "New instance stored";
            break;

          case StoreStatus_AlreadyStored:
            LOG(INFO) << "Already stored";
            break;

          case StoreStatus_Failure:
            LOG(ERROR) << "Store failure";
            break;

          default:
            // This should never happen
            break;
        }

        // skip all signals if this is a reconstruction
        if (result.GetStatus() == StoreStatus_Success ||
            result.GetStatus() == StoreStatus_AlreadyStored)
        {
          boost::shared_lock<boost::shared_mutex> lock(listenersMutex_);

          for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
          {
            try
            {
              it->GetListener().SignalStoredInstance(resultPublicId, dicom, simplifiedTags);
            }
            catch (OrthancException& e)
            {
              LOG(ERROR) << "Error in the " << it->GetDescription() 
                        << " callback while receiving an instance: " << e.What()
                        << " (code " << e.GetErrorCode() << ")";
            }
          }
        }
      }

      return result;
    }
    catch (OrthancException& e)
    {
      if (e.GetErrorCode() == ErrorCode_InexistentTag)
      {
        summary.LogMissingTagsForStore();
      }
      
      throw;
    }
  }
 类似资料: