//----------------------------------------------------------------------- SceneManagerEnumerator::~SceneManagerEnumerator() { // Destroy all remaining instances // Really should have shutdown and unregistered by now, but catch here in case Instances instancesCopy = mInstances; for (Instances::iterator i = instancesCopy.begin(); i != instancesCopy.end(); ++i) { // destroy instances for(Factories::iterator f = mFactories.begin(); f != mFactories.end(); ++f) { if ((*f)->getMetaData().typeName == i->second->getTypeName()) { (*f)->destroyInstance(i->second); mInstances.erase(i->first); break; } } } mInstances.clear(); }
static void AnonymizeOrModifyResource(DicomModification& modification, MetadataType metadataType, ChangeType changeType, ResourceType resourceType, RestApiPostCall& call) { bool isFirst = true; Json::Value result(Json::objectValue); ServerContext& context = OrthancRestApi::GetContext(call); typedef std::list<std::string> Instances; Instances instances; std::string id = call.GetUriComponent("id", ""); context.GetIndex().GetChildInstances(instances, id); if (instances.empty()) { return; } /** * Loop over all the instances of the resource. **/ for (Instances::const_iterator it = instances.begin(); it != instances.end(); ++it) { LOG(INFO) << "Modifying instance " << *it; std::auto_ptr<ServerContext::DicomCacheLocker> locker; try { locker.reset(new ServerContext::DicomCacheLocker(OrthancRestApi::GetContext(call), *it)); } catch (OrthancException&) { // This child instance has been removed in between continue; } ParsedDicomFile& original = locker->GetDicom(); DicomInstanceHasher originalHasher = original.GetHasher(); /** * Compute the resulting DICOM instance. **/ std::auto_ptr<ParsedDicomFile> modified(original.Clone()); modification.Apply(*modified); DicomInstanceToStore toStore; toStore.SetParsedDicomFile(*modified); /** * Prepare the metadata information to associate with the * resulting DICOM instance (AnonymizedFrom/ModifiedFrom). **/ DicomInstanceHasher modifiedHasher = modified->GetHasher(); if (originalHasher.HashSeries() != modifiedHasher.HashSeries()) { toStore.AddMetadata(ResourceType_Series, metadataType, originalHasher.HashSeries()); } if (originalHasher.HashStudy() != modifiedHasher.HashStudy()) { toStore.AddMetadata(ResourceType_Study, metadataType, originalHasher.HashStudy()); } if (originalHasher.HashPatient() != modifiedHasher.HashPatient()) { toStore.AddMetadata(ResourceType_Patient, metadataType, originalHasher.HashPatient()); } assert(*it == originalHasher.HashInstance()); toStore.AddMetadata(ResourceType_Instance, metadataType, *it); /** * Store the resulting DICOM instance into the Orthanc store. **/ std::string modifiedInstance; if (context.Store(modifiedInstance, toStore) != StoreStatus_Success) { LOG(ERROR) << "Error while storing a modified instance " << *it; return; } // Sanity checks in debug mode assert(modifiedInstance == modifiedHasher.HashInstance()); /** * Compute the JSON object that is returned by the REST call. **/ if (isFirst) { std::string newId; switch (resourceType) { case ResourceType_Series: newId = modifiedHasher.HashSeries(); break; case ResourceType_Study: newId = modifiedHasher.HashStudy(); break; case ResourceType_Patient: newId = modifiedHasher.HashPatient(); break; default: throw OrthancException(ErrorCode_InternalError); } result["Type"] = EnumerationToString(resourceType); result["ID"] = newId; result["Path"] = GetBasePath(resourceType, newId); result["PatientID"] = modifiedHasher.HashPatient(); isFirst = false; } } call.GetOutput().AnswerJson(result); }
void Series::Load3DImage(void* target, Orthanc::PixelFormat format, size_t lineStride, size_t stackStride, Orthanc::ThreadedCommandProcessor::IListener* listener) { using namespace Orthanc; // Choose the extraction mode, depending on the format of the // target image. uint8_t bytesPerPixel; ImageExtractionMode mode; switch (format) { case PixelFormat_RGB24: bytesPerPixel = 3; mode = ImageExtractionMode_Preview; break; case PixelFormat_Grayscale8: bytesPerPixel = 1; mode = ImageExtractionMode_UInt8; // Preview ??? break; case PixelFormat_Grayscale16: bytesPerPixel = 2; mode = ImageExtractionMode_UInt16; break; case PixelFormat_SignedGrayscale16: bytesPerPixel = 2; mode = ImageExtractionMode_UInt16; format = PixelFormat_Grayscale16; break; default: throw OrthancException(ErrorCode_NotImplemented); } // Check that the target image is properly sized unsigned int sx = GetWidth(); unsigned int sy = GetHeight(); if (lineStride < sx * bytesPerPixel || stackStride < sx * sy * bytesPerPixel) { throw OrthancException(ErrorCode_BadRequest); } if (sx == 0 || sy == 0 || GetInstanceCount() == 0) { // Empty image, nothing to do if (listener) listener->SignalSuccess(0); return; } /** * Order the stacks according to their distance along the slice * normal (using the "Image Position Patient" tag). This works * even if the "SliceLocation" tag is absent. **/ SliceLocator locator(GetInstance(0)); typedef std::map<float, Instance*> Instances; Instances instances; for (unsigned int i = 0; i < GetInstanceCount(); i++) { float dist = locator.ComputeSliceLocation(GetInstance(i)); instances[dist] = &GetInstance(i); } if (instances.size() != GetInstanceCount()) { // Several instances have the same Z coordinate throw OrthancException(ErrorCode_NotImplemented); } // Submit the download of each stack as a set of commands ThreadedCommandProcessor processor(connection_.GetThreadCount()); if (listener != NULL) { processor.SetListener(*listener); } uint8_t* stackTarget = reinterpret_cast<uint8_t*>(target); for (Instances::iterator it = instances.begin(); it != instances.end(); it++) { processor.Post(new ImageDownloadCommand(*it->second, format, mode, stackTarget, lineStride)); stackTarget += stackStride; } // Wait for all the stacks to be downloaded if (!processor.Join()) { throw OrthancException(ErrorCode_NetworkProtocol); } }