void ctkDICOMDataset::Deserialize() { Q_D(ctkDICOMDataset); // read attribute m_ctkDICOMDataset // construct a DcmDataset from it // calls InitializeData(DcmDataset*) // this method can be called both from sub-classes when they get the InitializeData signal from the persistence framework // and from EnsureDcmDataSetIsInitialized() when a GetElement.. or SetElement.. method is called. if (d->m_DICOMDataSetInitialized) return; // only need to do this once QString stringbuffer = this->GetStoredSerialization(); if ( stringbuffer.isEmpty() ) { d->m_DICOMDataSetInitialized = true; return; // TODO nicer: hold three states: newly created / loaded but not initialized / restored from DB } //std::cerr << "** " << (void*)this << " ctkDICOMDataset: Deserialize Dataset from string of size " << stringbuffer.size() << "\n" << stringbuffer.toStdString() << std::endl; QByteArray qtArray = QByteArray::fromBase64( stringbuffer.toAscii() ); //std::cerr << "** " << (void*)this << " ctkDICOMDataset: Deserialize Dataset from byte array of size " << qtArray.size() << std::endl; DcmInputBufferStream dcmbuffer; dcmbuffer.setBuffer( qtArray.data(), qtArray.size() ); //std::cerr << "** Buffer state: " << dcmbuffer.status().code() << " " << dcmbuffer.good() << " " << dcmbuffer.eos() << " tell " << dcmbuffer.tell() << " avail " << dcmbuffer.avail() << std::endl; DcmDataset dataset; dataset.transferInit(); //std::cerr << "** Dataset state: " << dataset.transferState() << std::endl << std::endl; OFCondition condition = dataset.read( dcmbuffer, EXS_LittleEndianImplicit ); dataset.transferEnd(); // do this in all cases, even when reading reported an error this->InitializeFromDataset(&dataset); if ( condition.bad() ) { std::cerr << "** Condition code of Dataset::read() is " << condition.code() << std::endl; std::cerr << "** Buffer state: " << dcmbuffer.status().code() << " " << dcmbuffer.good() << " " << dcmbuffer.eos() << " tell " << dcmbuffer.tell() << " avail " << dcmbuffer.avail() << std::endl; std::cerr << "** Dataset state: " << static_cast<int>(dataset.transferState()) << std::endl; std::cerr << "Could not DcmDataset::read(..): " << condition.text() << std::endl; //throw std::invalid_argument( std::string("Could not DcmDataset::read(..): ") + condition.text() ); } }
PACSRequestStatus::RetrieveRequestStatus RetrieveDICOMFilesFromPACS::retrieve(const QString &studyInstanceUID, const QString &seriesInstanceUID, const QString &sopInstanceUID) { T_ASC_PresentationContextID presentationContextID; T_DIMSE_C_MoveRSP moveResponse; DcmDataset *statusDetail = NULL; m_pacsConnection = new PACSConnection(m_pacs); PACSRequestStatus::RetrieveRequestStatus retrieveRequestStatus; MoveSCPCallbackData moveSCPCallbackData; DcmDataset *dcmDatasetToRetrieve = getDcmDatasetOfImagesToRetrieve(studyInstanceUID, seriesInstanceUID, sopInstanceUID); m_numberOfImagesRetrieved = 0; // TODO S'hauria de comprovar que es tracti d'un PACS amb el servei de retrieve configurat if (!m_pacsConnection->connectToPACS(PACSConnection::RetrieveDICOMFiles)) { ERROR_LOG("S'ha produit un error al intentar connectar al PACS per fer un retrieve. AE Title: " + m_pacs.getAETitle()); return PACSRequestStatus::RetrieveCanNotConnectToPACS; } // Which presentation context should be used, It's important that the connection has MoveStudyRoot level T_ASC_Association *association = m_pacsConnection->getConnection(); presentationContextID = ASC_findAcceptedPresentationContextID(association, MoveAbstractSyntax); if (presentationContextID == 0) { ERROR_LOG("No s'ha trobat cap presentation context valid"); return PACSRequestStatus::RetrieveFailureOrRefused; } moveSCPCallbackData.association = association; moveSCPCallbackData.presentationContextId = presentationContextID; moveSCPCallbackData.retrieveDICOMFilesFromPACS = this; // Set the destination of the images to us T_DIMSE_C_MoveRQ moveRequest = getConfiguredMoveRequest(association); ASC_getAPTitles(association->params, moveRequest.MoveDestination, NULL, NULL); OFCondition condition = DIMSE_moveUser(association, presentationContextID, &moveRequest, dcmDatasetToRetrieve, moveCallback, &moveSCPCallbackData, DIMSE_BLOCKING, 0, m_pacsConnection->getNetwork(), subOperationCallback, this, &moveResponse, &statusDetail, NULL /*responseIdentifiers*/); if (condition.bad()) { ERROR_LOG(QString("El metode descarrega no ha finalitzat correctament. Codi error: %1, descripcio error: %2").arg(condition.code()) .arg(condition.text())); } m_pacsConnection->disconnect(); retrieveRequestStatus = getDIMSEStatusCodeAsRetrieveRequestStatus(moveResponse.DimseStatus); processServiceClassProviderResponseStatus(moveResponse.DimseStatus, statusDetail); // Dump status detail information if there is some if (statusDetail != NULL) { delete statusDetail; } delete dcmDatasetToRetrieve; return retrieveRequestStatus; }