Status ConvertDicomToLittleEndian::convert(QString inputFile, QString outputFile)
{
    DcmFileFormat fileformat;
    DcmDataset *dataset = fileformat.getDataset();
    OFCondition error;
    Status state;
    // Transfer Syntax del fitxer d'entrada
    E_TransferSyntax opt_ixfer = EXS_Unknown;
    E_FileReadMode opt_readMode = ERM_autoDetect;
    E_TransferSyntax opt_oxfer = EXS_LittleEndianExplicit;
    QString descriptionError;
    E_EncodingType opt_oenctype = EET_ExplicitLength;
    E_GrpLenEncoding opt_oglenc = EGL_recalcGL;
    E_PaddingEncoding opt_opadenc = EPD_noChange;
    OFCmdUnsignedInt opt_filepad = 0;
    OFCmdUnsignedInt opt_itempad = 0;
    E_FileWriteMode writeMode = EWM_fileformat;

    error = fileformat.loadFile(qPrintable(QDir::toNativeSeparators(inputFile)), opt_ixfer, EGL_noChange, DCM_MaxReadLength, opt_readMode);

    if (error.bad())
    {
        ERROR_LOG(QString("No s'ha pogut obrir el fitxer a convertir LittleEndian %1, descripcio error: %2").arg(inputFile, error.text()));
        return state.setStatus(error);
    }
    dataset->loadAllDataIntoMemory();

    DcmXfer opt_oxferSyn(opt_oxfer);

    dataset->chooseRepresentation(opt_oxfer, NULL);

    if (!dataset->canWriteXfer(opt_oxfer))
    {
        descriptionError = "Error: no conversion to transfer syntax " + QString(opt_oxferSyn.getXferName()) + " possible";
        state.setStatus(qPrintable(descriptionError), false, 1300);
        ERROR_LOG(descriptionError);
        return state;
    }

    error = fileformat.saveFile(qPrintable(QDir::toNativeSeparators(outputFile)), opt_oxfer, opt_oenctype, opt_oglenc, opt_opadenc,
                                OFstatic_cast(Uint32, opt_filepad), OFstatic_cast(Uint32, opt_itempad), writeMode);

    if (!error.good())
    {
        ERROR_LOG(QString("S'ha produit un error al intentar gravar la imatge %1 convertida a LittleEndian al path %2, descripcio error: %3")
                     .arg(inputFile, outputFile, error.text()));
    }

    return state.setStatus(error);
}
Beispiel #2
0
//------------------------------------------------------------------------------
bool ctkDICOMRetrievePrivate::retrieve ( QString UID, RetrieveType retriveType ) {

  if ( !this->RetrieveDatabase )
    {
    logger.error ( "Must have RetrieveDatabase for retrieve transaction" );
    return false;
    }

  // Register the JPEG libraries in case we need them
  //   (registration only happens once, so it's okay to call repeatedly)
  // register global JPEG decompression codecs
  DJDecoderRegistration::registerCodecs();
  // register global JPEG compression codecs
  DJEncoderRegistration::registerCodecs();
  // register RLE compression codec
  DcmRLEEncoderRegistration::registerCodecs();
  // register RLE decompression codec
  DcmRLEDecoderRegistration::registerCodecs();

  // Set the DCMTK log level
  log4cplus::Logger rootLogger = log4cplus::Logger::getRoot();
  rootLogger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL);

  // TODO: use this->SCU instead ?
  DcmSCU scu;
  scu.setAETitle ( OFString(this->CallingAETitle.toStdString().c_str()) );
  scu.setPort ( this->CallingPort );
  scu.setPeerAETitle ( OFString(this->CalledAETitle.toStdString().c_str()) );
  scu.setPeerHostName ( OFString(this->Host.toStdString().c_str()) );
  scu.setPeerPort ( this->CalledPort );
  scu.setMoveDestinationAETitle ( OFString(this->MoveDestinationAETitle.toStdString().c_str()) );

  logger.info ( "Setting Transfer Syntaxes" );
  OFList<OFString> transferSyntaxes;
  transferSyntaxes.push_back ( UID_LittleEndianExplicitTransferSyntax );
  transferSyntaxes.push_back ( UID_BigEndianExplicitTransferSyntax );
  transferSyntaxes.push_back ( UID_LittleEndianImplicitTransferSyntax );
  scu.addPresentationContext ( UID_FINDStudyRootQueryRetrieveInformationModel, transferSyntaxes );
  scu.addPresentationContext ( UID_MOVEStudyRootQueryRetrieveInformationModel, transferSyntaxes );

  if ( !scu.initNetwork().good() ) 
    {
    logger.error ( "Error initializing the network" );
    return false;
    }
  logger.debug ( "Negotiating Association" );
  if ( !scu.negotiateAssociation().good() )
    {
    logger.error ( "Error negotiating association" );
    return false;;
    }

  logger.debug ( "Setting Parameters" );
  // Clear the query
  unsigned long elements = this->parameters->card();
  // Clean it out
  for ( unsigned long i = 0; i < elements; i++ ) 
    {
    this->parameters->remove ( 0ul );
    }
  if ( retriveType == RetrieveSeries )
    {
    this->parameters->putAndInsertString ( DCM_QueryRetrieveLevel, "SERIES" );
    this->parameters->putAndInsertString ( DCM_SeriesInstanceUID, UID.toStdString().c_str() );
    } 
  else
    {
    this->parameters->putAndInsertString ( DCM_QueryRetrieveLevel, "STUDY" );
    this->parameters->putAndInsertString ( DCM_StudyInstanceUID, UID.toStdString().c_str() );  
    }

  logger.debug ( "Sending Move Request" );
  MOVEResponses *responses = new MOVEResponses();
  OFCondition status = scu.sendMOVERequest ( 0, this->parameters, responses );
  if (!status.good())
    {
    logger.error ( "MOVE Request failed: " + QString ( status.text() ) );
    return false;
    }

  logger.debug ( "Find succeded" );

  logger.debug ( "Making Output Directory" );
  QDir directory = QDir( RetrieveDatabase->databaseDirectory() );

  if ( responses->begin() == responses->end() )
    {
    logger.error ( "No responses!" );
    throw std::runtime_error( std::string("No responses!") );
    }

  // Write the responses out to disk
  for ( OFListIterator(FINDResponse*) it = responses->begin(); it != responses->end(); it++ )
    {
    DcmDataset *dataset = (*it)->m_dataset;
    if ( dataset != NULL )
      {
      logger.debug ( "Got a valid dataset" );
      // Save in correct directory
      E_TransferSyntax output_transfersyntax = dataset->getOriginalXfer();
      dataset->chooseRepresentation( output_transfersyntax, NULL );
        
      if ( !dataset->canWriteXfer( output_transfersyntax ) )
        {
        // Pick EXS_LittleEndianExplicit as our default
        output_transfersyntax = EXS_LittleEndianExplicit;
        }
        
      DcmXfer opt_oxferSyn( output_transfersyntax );
      if ( !dataset->chooseRepresentation( opt_oxferSyn.getXfer(), NULL ).bad() )
        {
        DcmFileFormat* fileformat = new DcmFileFormat ( dataset );
          
        // Follow dcmdjpeg example
        fileformat->loadAllDataIntoMemory();
        OFString SOPInstanceUID;
        dataset->findAndGetOFString ( DCM_SOPInstanceUID, SOPInstanceUID );
        QFileInfo fi ( directory, QString ( SOPInstanceUID.c_str() ) );
        logger.debug ( "Saving file: " + fi.absoluteFilePath() );
        status = fileformat->saveFile ( fi.absoluteFilePath().toStdString().c_str(), opt_oxferSyn.getXfer() );
        if ( !status.good() )
          {
          logger.error ( "Error saving file: " + fi.absoluteFilePath() + " Error is " + status.text() );
          }

        RetrieveDatabase->insert( dataset, true );
          
        delete fileformat;
        }
      }
    }


  delete responses;
  //if ( !scu.dropNetwork().good() ) 
    //{
    //logger.error ( "Error dropping the network" );
    //return false;
    //}
  return true;
}
Beispiel #3
0
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;
        }
}