OFCondition Association::SendObject(DcmDataset *dataset) { OFCondition cond; DcmDataset *statusDetail = NULL; T_DIMSE_C_StoreRQ req; T_DIMSE_C_StoreRSP rsp; // check if we SOPClass and SOPInstance in dataset if (!DU_findSOPClassAndInstanceInDataSet(dataset, sopClass, sopInstance)) { return DIMSE_BADDATA; } /* which presentation context should be used */ presId = ASC_findAcceptedPresentationContextID(assoc, sopClass); if (presId == 0) { const char *modalityName = dcmSOPClassUIDToModality(sopClass); if (!modalityName) modalityName = dcmFindNameOfUID(sopClass); if (!modalityName) modalityName = "unknown SOP class"; return DIMSE_BADDATA; } // init store bzero((char*)&req, sizeof(req)); req.MessageID = msgId; strncpy(req.AffectedSOPClassUID, sopClass, sizeof(req.AffectedSOPClassUID)); strncpy(req.AffectedSOPInstanceUID, sopInstance, sizeof(req.AffectedSOPInstanceUID)); req.DataSetType = DIMSE_DATASET_PRESENT; req.Priority = DIMSE_PRIORITY_LOW; // convert to accepted transfer syntax T_ASC_PresentationContext pc; cond = ASC_findAcceptedPresentationContext(assoc->params, presId, &pc); ASC_dumpPresentationContext(&pc, COUT); DJEncoderRegistration::registerCodecs( ECC_lossyYCbCr, EUC_never, // UID generation (never create new UID's) OFFalse, // verbose OFTrue); // optimize huffman table DJDecoderRegistration::registerCodecs(); DcmXfer opt_oxferSyn(pc.acceptedTransferSyntax); E_TransferSyntax ori_oxferSyn = dataset->getOriginalXfer(); DcmXfer original_xfer(dataset->getOriginalXfer()); if(opt_oxferSyn.getXfer() != ori_oxferSyn) { std::cout << "Converting object to accepted transfer-syntax " << opt_oxferSyn.getXferName() << std::endl; OFCondition cond; // create RepresentationParameter DJ_RPLossless rp_lossless(6, 0); DJ_RPLossy rp_lossy(m_CompressionQuality); // NEW const DcmRepresentationParameter *rp = NULL; if(opt_oxferSyn.getXfer() == EXS_JPEGProcess14SV1 || opt_oxferSyn.getXfer() == EXS_JPEGProcess14) { rp = &rp_lossless; } else if(opt_oxferSyn.getXfer() == EXS_JPEGProcess1 || opt_oxferSyn.getXfer() == EXS_JPEGProcess2_4) { rp = &rp_lossy; } // recompress ? if(rp != NULL) { if(original_xfer.isEncapsulated()) { std::cout << "DICOM file is already compressed, convert to uncompressed xfer syntax first\n"; if(EC_Normal != dataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL)) { std::cout << "No conversion from compressed original to uncompressed xfer syntax possible!\n"; } } } cond = dataset->chooseRepresentation(opt_oxferSyn.getXfer(), rp); if(cond.bad()) { DimseCondition::dump(cond); } if (dataset->canWriteXfer(opt_oxferSyn.getXfer())) { std::cout << "Output transfer syntax " << opt_oxferSyn.getXferName() << " can be written" << std::endl; } else { std::cout << "No conversion to transfer syntax " << opt_oxferSyn.getXferName() << " possible!" << std::endl; } } // store it cond = DIMSE_storeUser( assoc, presId, &req, NULL, dataset, NULL, NULL, (m_timeout == 0) ? DIMSE_BLOCKING : DIMSE_NONBLOCKING, m_timeout, &rsp, &statusDetail); // increase message id msgId++; // what happened if(rsp.DataSetType == DIMSE_DATASET_PRESENT) { printf("Response with dataset:\n"); } if (statusDetail != NULL) { printf("Status detail:\n"); statusDetail->print(COUT, false); delete statusDetail; } if (cond != EC_Normal) { return cond; } return (rsp.DimseStatus == STATUS_Success) ? EC_Normal : DIMSE_BADDATA; }
OFCondition Association::SendObject(DcmDataset *dataset) { OFCondition cond = EC_Normal; DcmDataset *statusDetail = NULL; if (Stopped()) { return DUL_NETWORKCLOSED; } T_DIMSE_C_StoreRQ req; T_DIMSE_C_StoreRSP rsp; // check if we SOPClass and SOPInstance in dataset if (!DU_findSOPClassAndInstanceInDataSet(dataset, sopClass, sopInstance)) { return makeOFCondition(OFM_dcmnet, DIMSEC_BADDATA, OF_error, "No SOPClass or SOPInstanceUID found on dataset"); } /* which presentation context should be used */ presId = ASC_findAcceptedPresentationContextID(assoc, sopClass); if (presId == 0) { const char *modalityName = dcmSOPClassUIDToModality(sopClass); if (!modalityName) modalityName = dcmFindNameOfUID(sopClass); if (!modalityName) modalityName = "unknown SOP class"; std::ostringstream os; os << "No valid presentation context found. SOPClass = " << sopClass << " Modality = " << modalityName; return makeOFCondition(OFM_dcmnet, DIMSEC_BADDATA, OF_error, os.str().c_str()); } bzero((char*) & req, sizeof (req)); req.MessageID = msgId; strncpy(req.AffectedSOPClassUID, sopClass, sizeof (req.AffectedSOPClassUID)-1); req.AffectedSOPClassUID[sizeof (req.AffectedSOPClassUID)-1] = 0; strncpy(req.AffectedSOPInstanceUID, sopInstance, sizeof (req.AffectedSOPInstanceUID)-1); req.AffectedSOPInstanceUID[sizeof(req.AffectedSOPInstanceUID)-1] = 0; req.DataSetType = DIMSE_DATASET_PRESENT; req.Priority = DIMSE_PRIORITY_LOW; // convert to accepted transfer syntax T_ASC_PresentationContext pc; cond = ASC_findAcceptedPresentationContext(assoc->params, presId, &pc); ASC_dumpPresentationContext(&pc, COUT); DcmXfer opt_oxferSyn(pc.acceptedTransferSyntax); E_TransferSyntax ori_oxferSyn = dataset->getOriginalXfer(); DcmXfer original_xfer(dataset->getOriginalXfer()); if (opt_oxferSyn.getXfer() != ori_oxferSyn) { LOG_DEBUG(ambitolog, "Converting object into accepted Transfer-Syntax: " << opt_oxferSyn.getXferName()); OFCondition cond; // create RepresentationParameter DJ_RPLossless rp_lossless(6, 0); DJ_RPLossy rp_lossy(70); // NEW const DcmRepresentationParameter *rp = NULL; if (opt_oxferSyn.getXfer() == EXS_JPEGProcess14SV1 || opt_oxferSyn.getXfer() == EXS_JPEGProcess14) { rp = &rp_lossless; } else if (opt_oxferSyn.getXfer() == EXS_JPEGProcess1 || opt_oxferSyn.getXfer() == EXS_JPEGProcess2_4) { rp = &rp_lossy; } // recompress ? if (rp != NULL) { if (original_xfer.isEncapsulated()) { LOG_DEBUG(ambitolog, "The DICOM file is already compressed. It will previously converted to uncompressed Transfer Syntax"); if (EC_Normal != dataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL)) { return makeOFCondition(OFM_dcmnet, DIMSEC_BADDATA, OF_error, "Unable to convert the original format to uncompressed Transfer Syntax"); } } } cond = dataset->chooseRepresentation(opt_oxferSyn.getXfer(), rp); if (cond.bad()) { LOG_ERROR(ambitolog, "Error choosing representation: " << cond.text()); } if (dataset->canWriteXfer(opt_oxferSyn.getXfer())) { LOG_DEBUG(ambitolog, "The output transfer syntax (" << opt_oxferSyn.getXferName() << " can be writen"); } else { std::ostringstream os; os << "Unable to find any possible converson to output Transfer Syntax " << opt_oxferSyn.getXferName(); return makeOFCondition(OFM_dcmnet, DIMSEC_BADDATA, OF_error, os.str().c_str()); } } // store it cond = DIMSE_storeUser( assoc, presId, &req, NULL, dataset, NULL, NULL, (m_timeout == 0) ? DIMSE_BLOCKING : DIMSE_NONBLOCKING, m_timeout, &rsp, &statusDetail); // increase message id msgId++; // what happened if (rsp.DataSetType == DIMSE_DATASET_PRESENT) { LOG_DEBUG(ambitolog, "Response with dataset"); } if (statusDetail != NULL) { LOG_TRACE(ambitolog, "Status: " << DumpDataset(statusDetail)); delete statusDetail; } if (cond != EC_Normal) { return cond; } if (rsp.DimseStatus == STATUS_Success) { return EC_Normal; } else { LOG_ERROR(ambitolog, "DIMSE Status failed: " << rsp.DimseStatus); return DIMSE_BADDATA; } }