void LocalService::SolveFile( const boost::filesystem::path & fileName, const boost::filesystem::path & path, ResultSet &result) { OFString ofStr; DcmFileFormat dfile; OFCondition cond = dfile.loadFile( fileName.string().data()); if (! cond.good()) { LOG( "Loading of " << fileName << " failed. (" << cond.text() << ")" ); return; } DcmDataset *dataSet = dfile.getDataset(); TableRow row; SerieInfo serInfo; // load data and check if it is already in tree CheckDataSet( dataSet, serInfo, row, path.string()); // look if this row is already in resultSet FoundStudiesSet::iterator found = m_alreadyFoundInRun.find(row.studyID); // if not, add it if( found == m_alreadyFoundInRun.end() ) { m_alreadyFoundInRun.insert( FoundStudiesSet::value_type( row.studyID) ); result.push_back( row); } }
bool ParserDicom::isValidFile(string filename) { DcmFileFormat dcm; OFCondition cond = dcm.loadFile(filename.c_str()); return cond.good(); }
//------------------------------------------------------------------------------ void ctkDICOMDatabase::loadFileHeader (QString fileName) { Q_D(ctkDICOMDatabase); DcmFileFormat fileFormat; OFCondition status = fileFormat.loadFile(fileName.toLatin1().data()); if (status.good()) { DcmDataset *dataset = fileFormat.getDataset(); DcmStack stack; while (dataset->nextObject(stack, true) == EC_Normal) { DcmObject *dO = stack.top(); if (dO->isaString()) { QString tag = QString("%1,%2").arg( dO->getGTag(),4,16,QLatin1Char('0')).arg( dO->getETag(),4,16,QLatin1Char('0')); std::ostringstream s; dO->print(s); d->LoadedHeader[tag] = QString(s.str().c_str()); } } } return; }
bool DicomImporter::IsFileValid(const String& _file) { try { // // create the dicom fileformat and check if this is possible // DcmFileFormat ff; OFCondition cond = ff.loadFile(_file.c_str()); if (cond.bad()) return false; // // ist it in part 10 format (does meta-header exist)? // DcmMetaInfo *m = ff.getMetaInfo(); if (m == NULL || m->card() == 0) return false; // // does the file contain data (does the dataset exist)? // DcmDataset *d = ff.getDataset(); if (d == NULL) return false; // // yes, it is a valid dicom file! // return true; } catch (...) { throw; } }
bool DCMTKImageIO::CanReadFile(const char* filename) { DcmFileFormat dicomFile; OFCondition condition = dicomFile.loadFile( filename ); if ( !condition.good() ) { return false; } E_TransferSyntax xfer = dicomFile.getDataset()->getOriginalXfer(); if( xfer == EXS_JPEG2000LosslessOnly || xfer == EXS_JPEG2000 || xfer == EXS_JPEG2000MulticomponentLosslessOnly || xfer == EXS_JPEG2000Multicomponent ) { return false; } // search for mandatory tags DcmStack stack; DcmTagKey searchKey; unsigned int group = 0x0028; // samples per pixel unsigned int elem = 0x0002; // samples per pixel searchKey.set(group, elem); if (dicomFile.search(searchKey, stack, ESM_fromHere, OFTrue) != EC_Normal) return false; group = 0x0028; // pixel type elem = 0x0100; // pixel type searchKey.set(group, elem); if (dicomFile.search(searchKey, stack, ESM_fromHere, OFTrue) != EC_Normal) return false; return true; }
void DicomImporter::DetermineSopClass(const String& _file) { try { DcmFileFormat ff; ff.loadFile(_file.c_str()); DcmMetaInfo *m = ff.getMetaInfo(); DcmElement* elem = NULL; elem = DcmtkHelper::searchElement(m, 0002, 0002); std::string sopClass; if (elem != NULL) { sopClass = DcmtkConvert::DcmElementValueToString(elem); } else { return; } if (sopClass == "1.2.840.10008.1.3.10") { dicomdirFiles.push_back(_file); } else { nonDicomdirFiles.push_back(_file); } } catch (...) { throw; } }
// Load our vtkImageData object from a list of DICOM image filenames... // http://www.vtk.org/pipermail/vtkusers/2007-August/042635.html void vtkDicom::load_dcmFiles(QStringList dcm_fileList) { DcmFileFormat dcm; std::string imgFname; std::cout << "vtkdicom: Files/Images(?): " << dcm_fileList.size() << "\n"; for (int sei = 0; sei < dcm_fileList.size(); ++sei) { imgFname = dcm_fileList.at(sei).toLocal8Bit().constData(); OFCondition status = dcm.loadFile(imgFname.c_str()); if (!status.good()) { std::cout << " vtkdicom: Error: cannot read file (" << status.text() << ")" << "\n"; return; } if (sei == 0) { OFString acquisitionNumber, instanceNumber, imagePositionPatient, patientsName; DcmDataset *dcmDs = dcm.getDataset(); dcmDs->findAndGetOFStringArray(DCM_ImagePositionPatient, imagePositionPatient); dcmDs->findAndGetOFString(DCM_AcquisitionNumber, acquisitionNumber); dcmDs->findAndGetOFString(DCM_InstanceNumber, instanceNumber); dcmDs->findAndGetOFString(DCM_PatientName, patientsName); std::cout << "vtkdicom: I#, IPP: " << instanceNumber << " - " << imagePositionPatient << "\n"; } dcm.loadAllDataIntoMemory(); const unsigned short* p = NULL; dcm.getDataset()->findAndGetUint16Array(DCM_PixelData, p); } }
Examen* ParserDicom::loadFile(string dirName) { // Open directory DIR* dir = opendir(dirName.c_str()); if (dir == NULL) { return NULL; } // Get examen informations ExamenParams* params = getInfos(dir, dirName); if (params == NULL) { return NULL; } // Create struct examen Volume* img = new Volume(params->width, params->height, params->depth); Examen* exam = new Examen(img, params); // Read data int index = 0; struct dirent* file; rewinddir(dir); string pathDirectory = dirName + PATH_SEPARATOR; int tabSize = params->width * params->height; float tab[tabSize]; while ((file = readdir(dir)) != NULL) { if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0) { string fullpath = pathDirectory + file->d_name; DcmFileFormat dcm; OFCondition cond = dcm.loadFile(fullpath.c_str()); if (cond.bad()) { delete img; delete params; return NULL; } DiDocument* didoc = new DiDocument(fullpath.c_str()); DiMono2Image* dimg = new DiMono2Image(didoc, EIS_Normal); OFString s; dcm.getDataset()->findAndGetOFString(DCM_BitsStored, s); int bitsStored = atoi(s.c_str()); short* slice = (short*) dimg->getOutputData(0, bitsStored, 0); for(int i=0; i<tabSize; ++i) { tab[i] = (float) slice[i]; } img->setSlice(tab, index++); delete dimg; delete didoc; } } closedir(dir); return exam; }
mitk::DataNode::Pointer RTDoseReader:: LoadRTDose(const char* filename) { DcmFileFormat fileformat; OFCondition outp = fileformat.loadFile(filename, EXS_Unknown); if(outp.bad()) { MITK_ERROR << "Cant read the file" << std::endl; } DcmDataset *dataset = fileformat.getDataset(); std::string name = filename; itk::FilenamesContainer file; file.push_back(name); mitk::DicomSeriesReader* reader = new mitk::DicomSeriesReader; mitk::DataNode::Pointer originalNode = reader->LoadDicomSeries(file,false); if(originalNode.IsNull()) { MITK_ERROR << "Error reading the dcm file" << std::endl; return 0; } mitk::Image::Pointer originalImage = dynamic_cast<mitk::Image*>(originalNode->GetData()); DRTDoseIOD doseObject; OFCondition result = doseObject.read(*dataset); if(result.bad()) { MITK_ERROR << "Error reading the Dataset" << std::endl; return 0; } OFString gridScaling; Float32 gridscale; doseObject.getDoseGridScaling(gridScaling); gridscale = OFStandard::atof(gridScaling.c_str()); AccessByItk_1(originalImage, MultiplayGridScaling, gridscale); double prescripeDose = this->GetMaxDoseValue(dataset); originalNode->SetName("RT Dose"); originalNode->SetFloatProperty(mitk::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),prescripeDose); originalNode->SetFloatProperty(mitk::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), 40); originalNode->SetBoolProperty(mitk::Constants::DOSE_PROPERTY_NAME.c_str(),true); return originalNode; }
int main(void) { DcmFileFormat fileformat; OFCondition oc = fileformat.loadFile("D:\\021A3C1C.dcm"); if(oc.good()) { OFString patientName; if(fileformat.getDataset()->findAndGetOFString(DCM_PatientName, patientName).good()) { std::cout<<"Patient Name:"<<patientName<<std::endl; } } return 0; }
int Opendcm::loadDcmFile() { // OFCondition status; DcmFileFormat fileformat; fileformat.loadFile("/home/jeannypan/Documents/dcmtk_image/real_dicom.dcm"); QString sopClass,; fileformat.getMetaInfo()->findAndGetString(DCM_MediaStorageSOPClassUID),sopClass // QString out; // string sopClass; // status= fileformat.loadFile("/home/jeannypan/Documents/dcmtk_image/real_dicom.dcm"); // if (status.good()) // { // OFString sopClassUID, xferUID; // //if(fileformat.getMetaInfo()->findAndGetString(DCM_MediaStorageSOPClassUID),sopClassUID).good()) // if(fileformat.getMetaInfo()->findAndGetOFString(DCM_MediaStorageSOPClassUID,sopClassUID).good()) // //COUT << "SOP Class UID:" << sopClassUID << OFendl; // sopClass =sopClassUID; // sopClass = QString ::fromStdString(sopClass); // //sopClass = QsopClassUID; // //out="SOP Class UID:"; // //out += sopClass; // ui->textEdit->setPlainText(sopClass); // //ui->textBrowser->out(); // if(fileformat.getMetaInfo() ->findAndGetOFString(DCM_TransferSyntaxUID,xferUID).good()) // //COUT << "Transfer Syntax UID:" << xferUID << OFendl; // out="SOP Class UID:";//+sopClassUID; // ui->textEdit->setText(out); // //ui->textBrowser->out(); // //fileformat.print(out); // } else // //cerr << "Error: cannot read DICOM file"<<status.text()<<endl; // out="Error: cannot read DICOM file";//+sopClassUID; // ui->textEdit->setPlainText(out); // //ui->textBrowser->out(); return 0; }
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); }
std::string ImageMatrix::get_patientname(const std::string & dirpath){ std::string filepath = dirpath + "\\ADC\\ADC_1"; DcmFileFormat *pDicomFile = new DcmFileFormat(); OFCondition oc = pDicomFile->loadFile(filepath.c_str()); if(oc.good()){ DcmDataset *pDataset = pDicomFile->getDataset(); const char * name; pDataset -> findAndGetString(DCM_PatientName, name); std::string res(name); delete pDataset; return res; } else return "f**k"; }
void vtkDicom::dumpDicomFile(std::string imgFname) { DcmFileFormat dfile; OFCondition status = dfile.loadFile(imgFname.c_str()); if (status.good()) { OFString acquisitionNumber, instanceNumber, imagePositionPatient, patientsName; dfile.loadAllDataIntoMemory(); DcmDataset *dcmDs = dfile.getDataset(); dcmDs->findAndGetOFStringArray(DCM_ImagePositionPatient, imagePositionPatient); dcmDs->findAndGetOFString(DCM_AcquisitionNumber, acquisitionNumber); dcmDs->findAndGetOFString(DCM_InstanceNumber, instanceNumber); dcmDs->findAndGetOFString(DCM_PatientName, patientsName); std::cout << " " << instanceNumber << " - " << imagePositionPatient << "\n"; } else { std::cout << " Error: cannot read file (" << status.text() << ")" << "\n"; } }
void LocalService::SolveFileGET( const boost::filesystem::path & fileName, const std::string &patientID, const std::string &studyID, const std::string &serieID, DicomObjSet &result, const std::string &path) { OFString ofStr; DcmFileFormat dfile; OFCondition cond = dfile.loadFile( fileName.string().data()); if (! cond.good()) { LOG( "Loading of " << fileName << " failed. (" << cond.text() << ")" ); return; } DcmDataset *dataSet = dfile.getDataset(); TableRow row; SerieInfo serInfo; // load data and check if it is already in tree CheckDataSet( dataSet, serInfo, row, path); // compare with wantend ones if( row.patientID == patientID && row.studyID == studyID && serInfo.id == serieID) { // if it mathes, insert new image into result DicomObj buddy; result.push_back( buddy); // copy dataset reference & init DicomObj *newOne = &result.back(); newOne->Load( fileName.string() ); newOne->Init(); } }
void ctkDICOMDataset::InitializeFromFile(const QString& filename, const E_TransferSyntax readXfer, const E_GrpLenEncoding groupLength, const Uint32 maxReadLength, const E_FileReadMode readMode) { DcmDataset *dataset; DcmFileFormat fileformat; OFCondition status = fileformat.loadFile(filename.toAscii().data(), readXfer, groupLength, maxReadLength, readMode); dataset = fileformat.getAndRemoveDataset(); if (!status.good()) { qDebug() << "Could not load " << filename << "\nDCMTK says: " << status.text(); delete dataset; return; } InitializeFromDataset(dataset, true); }
StoreStatus ServerContext::Store(std::string& resultPublicId, DcmFileFormat& dicomInstance, const char* dicomBuffer, size_t dicomSize) { DicomMap dicomSummary; FromDcmtkBridge::Convert(dicomSummary, *dicomInstance.getDataset()); DicomInstanceHasher hasher(dicomSummary); resultPublicId = hasher.HashInstance(); Json::Value dicomJson; FromDcmtkBridge::ToJson(dicomJson, *dicomInstance.getDataset()); StoreStatus status = StoreStatus_Failure; if (dicomSize > 0) { status = Store(dicomBuffer, dicomSize, dicomSummary, dicomJson, ""); } return status; }
StoreStatus ServerContext::Store(std::string& resultPublicId, DcmFileFormat& dicomInstance) { std::string buffer; if (!FromDcmtkBridge::SaveToMemoryBuffer(buffer, dicomInstance.getDataset())) { throw OrthancException(ErrorCode_InternalError); } if (buffer.size() == 0) return Store(resultPublicId, dicomInstance, NULL, 0); else return Store(resultPublicId, dicomInstance, &buffer[0], buffer.size()); }
bool DicomImageLoader::supportsFileType( const string &url ) { // DicomImageLoader try to load some DDS image, then it hangs, so stop // using DicomImageLoader to load it when DDSImageLoader can do it if( DDSImageLoader::supportsFileType(url) ) { return false; } // set the dcmtk console to write to the H3D console ofConsole.setCerr( &H3DUtil::Console ); ofConsole.setCout( &H3DUtil::Console ); // temporarily shut down console to avoid warning messages from // dcmtk while checking if supported. H3DUtil::Console.disable(); DcmFileFormat fileformat; OFCondition status = fileformat.loadFile( url.c_str(), EXS_Unknown, EGL_noChange, 0 ); // restore console output level. H3DUtil::Console.enable(); return status.good(); }
IFileIO::ConfidenceLevel DICOMSegmentationIO::GetReaderConfidenceLevel() const { if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; const std::string fileName = this->GetLocalFileName(); DcmFileFormat dcmFileFormat; OFCondition status = dcmFileFormat.loadFile(fileName.c_str()); if (status.bad()) return Unsupported; OFString modality; if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good()) { if (modality.compare("SEG") == 0) return Supported; else return Unsupported; } return Unsupported; }
OFCondition RetrieveDICOMFilesFromPACS::storeSCP(T_ASC_Association *association, T_DIMSE_Message *msg, T_ASC_PresentationContextID presentationContextID) { T_DIMSE_C_StoreRQ *storeRequest = &msg->msg.CStoreRQ; OFBool useMetaheader = OFTrue; StoreSCPCallbackData storeSCPCallbackData; DcmFileFormat retrievedFile; DcmDataset *retrievedDataset = retrievedFile.getDataset(); storeSCPCallbackData.dcmFileFormat = &retrievedFile; storeSCPCallbackData.retrieveDICOMFilesFromPACS = this; storeSCPCallbackData.fileName = storeRequest->AffectedSOPInstanceUID; OFCondition condition = DIMSE_storeProvider(association, presentationContextID, storeRequest, NULL, useMetaheader, &retrievedDataset, storeSCPCallback, (void*) &storeSCPCallbackData, DIMSE_BLOCKING, 0); if (condition.bad()) { // Remove file ERROR_LOG("S'ha produit al processar una peticio de descarregar d'un fitxer, descripcio error " + QString(condition.text())); unlink(qPrintable(storeSCPCallbackData.fileName)); } return condition; }
ExamenParams* ParserDicom::getInfos(DIR* dir, string dirName) { struct dirent* file = getOneFile(dir); if (file == NULL) { return NULL; } string fullpath = dirName + PATH_SEPARATOR + file->d_name; DcmFileFormat dcm; OFCondition cond = dcm.loadFile(fullpath.c_str()); if (cond.bad()) { return NULL; } Information* generalInfos = new Information(); OFString s; dcm.getDataset()->findAndGetOFString(DCM_PatientName, s); generalInfos->addInformation("Patient name", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientID, s); generalInfos->addInformation("Patient ID", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientBirthDate, s); generalInfos->addInformation("Patient birthday", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientAge, s); generalInfos->addInformation("Patient age", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientSex, s); generalInfos->addInformation("Patient sex", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientSize, s); generalInfos->addInformation("Patient size", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientWeight, s); generalInfos->addInformation("Patient weight", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_ImagePositionPatient, s); generalInfos->addInformation("Image position patient", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_ImageOrientationPatient, s); generalInfos->addInformation("Image orientation patient", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_StudyID, s); generalInfos->addInformation("Study data", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_StudyDate, s); generalInfos->addInformation("Study date", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_StudyTime, s); generalInfos->addInformation("Study time", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_StudyDescription, s); generalInfos->addInformation("Study description", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_BitsAllocated, s); generalInfos->addInformation("Bits allocated", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_BitsStored, s); generalInfos->addInformation("Bits stored", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_HighBit, s); generalInfos->addInformation("High bit", s.c_str()); generalInfos->addInformation("Intercept", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_RescaleIntercept, s); int intercept = atoi(s.c_str()); generalInfos->addInformation("Slope", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_RescaleSlope, s); int slope = atoi(s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_WindowCenter, s); generalInfos->addInformation("Window center", s.c_str()); int Wcenter=atoi(s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_WindowWidth, s); generalInfos->addInformation("Window width", s.c_str()); int Wwidth=atoi(s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_SliceThickness, s); generalInfos->addInformation("Slice thickness", s.c_str()); float Sthickness = atof(s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_WindowCenterWidthExplanation, s); generalInfos->addInformation("WindowCenterWidthExplanation", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_Manufacturer, s); generalInfos->addInformation("Manufacturer", s.c_str()); //--------------------------------------------- // Affectation des parametres de l'examen //--------------------------------------------- GrayTranslationFunction gtf(slope, intercept); ExamenParams* params = new ExamenParams(gtf, fullpath, generalInfos); params->getGrayViewWindow().setLuminosity(Wcenter); params->getGrayViewWindow().setContrast(Wwidth); //params->getGrayViewWindow().setMin(HundsfieldValue::min()); // Must choose ! //params->getGrayViewWindow().setMax(HundsfieldValue::max()); //params->setParametersSI(Sthickness); //--------------------------------------------- // Examen size informations //--------------------------------------------- DiDocument* didoc = new DiDocument(fullpath.c_str()); DiMono2Image* dimg = new DiMono2Image(didoc, EIS_Normal); params->width = dimg->getColumns(); params->height = dimg->getRows(); params->depth = nbFiles(dir); params->resolutionX = dimg->getPixelWidth();; params->resolutionY = dimg->getPixelHeight();; params->resolutionZ = Sthickness; // check ostringstream sNbSlice, sSize, sResX, sResY; sResX << params->resolutionX; sResY << params->resolutionY; sNbSlice << params->depth + 1; sSize << params->width << " " << params->height; generalInfos->addInformation("Slice number", sNbSlice.str()); generalInfos->addInformation("Scan resolution (x, y)", sSize.str()); generalInfos->addInformation("Pixel resolution X", sResX.str()); generalInfos->addInformation("Pixel resolution Y", sResY.str()); delete dimg; delete didoc; return params; }
/* Helper function to write a DICOM file using C++ */ static int write_dcm_cpp(const char *path, const Image *const im, const Dcm_meta *const meta, const float max_val) { #define BUF_LEN 1024 char buf[BUF_LEN]; // Ensure the image is monochromatic if (im->nc != 1) { SIFT3D_ERR("write_dcm_cpp: image %s has %d channels. " "Currently only signle-channel images are supported.\n", path, im->nc); return SIFT3D_FAILURE; } // If no metadata was provided, initialize default metadata Dcm_meta meta_new; set_meta_defaults(meta, &meta_new); // Create a new fileformat object DcmFileFormat fileFormat; // Set the file type to derived DcmDataset *const dataset = fileFormat.getDataset(); OFCondition status = dataset->putAndInsertString(DCM_ImageType, "DERIVED"); if (status.bad()) { std::cerr << "write_dcm_cpp: Failed to set the image type" << std::endl; return SIFT3D_FAILURE; } // Set the class UID dataset->putAndInsertString(DCM_SOPClassUID, UID_CTImageStorage); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the SOPClassUID\n"); return SIFT3D_FAILURE; } // Set the photometric interpretation const char *photoInterp; if (im->nc == 1) { photoInterp = "MONOCHROME2"; } else if (im->nc == 3) { photoInterp = "RGB"; } else { SIFT3D_ERR("write_dcm_cpp: failed to determine the " "photometric representation for %d channels \n", im->nc); return SIFT3D_FAILURE; } dataset->putAndInsertString(DCM_PhotometricInterpretation, photoInterp); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the photometric " "interpretation \n"); return SIFT3D_FAILURE; } // Set the pixel representation to unsigned dataset->putAndInsertUint16(DCM_PixelRepresentation, 0); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the pixel " "representation \n"); return SIFT3D_FAILURE; } // Set the number of channels (Samples Per Pixel) and set the planar // configuration to interlaced pixels assert(SIFT3D_IM_GET_IDX(im, 0, 0, 0, 1) == SIFT3D_IM_GET_IDX(im, 0, 0, 0, 0) + 1); snprintf(buf, BUF_LEN, "%d", im->nc); dataset->putAndInsertString(DCM_SamplesPerPixel, buf); dataset->putAndInsertString(DCM_PlanarConfiguration, "0"); // Set the bits allocated and stored, in big endian format const unsigned int dcm_high_bit = dcm_bit_width - 1; dataset->putAndInsertUint16(DCM_BitsAllocated, dcm_bit_width); dataset->putAndInsertUint16(DCM_BitsStored, dcm_bit_width); dataset->putAndInsertUint16(DCM_HighBit, dcm_high_bit); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the bit widths \n"); return SIFT3D_FAILURE; } // Set the patient name status = dataset->putAndInsertString(DCM_PatientName, meta_new.patient_name); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the patient name\n"); return SIFT3D_FAILURE; } // Set the patient ID status = dataset->putAndInsertString(DCM_PatientID, meta_new.patient_id); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the patient ID \n"); return SIFT3D_FAILURE; } // Set the study UID status = dataset->putAndInsertString(DCM_StudyInstanceUID, meta_new.study_uid); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the " "StudyInstanceUID \n"); return SIFT3D_FAILURE; } // Set the series UID status = dataset->putAndInsertString(DCM_SeriesInstanceUID, meta_new.series_uid); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the " "SeriesInstanceUID \n"); return SIFT3D_FAILURE; } // Set the series description status = dataset->putAndInsertString(DCM_SeriesDescription, meta_new.series_descrip); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the series " "description \n"); return SIFT3D_FAILURE; } // Set the instance UID status = dataset->putAndInsertString(DCM_SOPInstanceUID, meta_new.instance_uid); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: failed to set the " "SOPInstanceUID \n"); return SIFT3D_FAILURE; } // Set the dimensions OFCondition xstatus = dataset->putAndInsertUint16(DCM_Rows, im->ny); OFCondition ystatus = dataset->putAndInsertUint16(DCM_Columns, im->nx); snprintf(buf, BUF_LEN, "%d", im->nz); OFCondition zstatus = dataset->putAndInsertString(DCM_NumberOfFrames, buf); if (xstatus.bad() || ystatus.bad() || zstatus.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the dimensions \n"); return SIFT3D_FAILURE; } // Set the instance number snprintf(buf, BUF_LEN, "%u", meta_new.instance_num); status = dataset->putAndInsertString(DCM_InstanceNumber, buf); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the instance " "number \n"); return SIFT3D_FAILURE; } // Set the ImagePositionPatient vector const double imPosX = static_cast<double>(im->nx - 1) * im->ux; const double imPosY = static_cast<double>(im->ny - 1) * im->uy; const double imPosZ = static_cast<double>(meta_new.instance_num) * im->uz; snprintf(buf, BUF_LEN, "%f\\%f\\%f", imPosX, imPosY, imPosZ); status = dataset->putAndInsertString(DCM_ImagePositionPatient, buf); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the " "ImagePositionPatient vector \n"); return SIFT3D_FAILURE; } // Set the slice location snprintf(buf, BUF_LEN, "%f", imPosZ); status = dataset->putAndInsertString(DCM_SliceLocation, buf); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the slice " "location \n"); return SIFT3D_FAILURE; } // Set the pixel spacing snprintf(buf, BUF_LEN, "%f\\%f", im->ux, im->uy); status = dataset->putAndInsertString(DCM_PixelSpacing, buf); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the pixel " "spacing \n"); return SIFT3D_FAILURE; } // Set the aspect ratio snprintf(buf, BUF_LEN, "%f\\%f", im->ux, im->uy); status = dataset->putAndInsertString(DCM_PixelAspectRatio, buf); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the pixel aspect " "aspect ratio \n"); return SIFT3D_FAILURE; } // Set the slice thickness snprintf(buf, BUF_LEN, "%f", im->uz); status = dataset->putAndInsertString(DCM_SliceThickness, buf); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: Failed to set the slice " "thickness \n"); return SIFT3D_FAILURE; } // Count the number of pixels in the image unsigned long numPixels = im->dims[0]; for (int i = 1; i < IM_NDIMS; i++) { numPixels *= im->dims[i]; } // Get the image scaling factor const float dcm_max_val = static_cast<float>(1 << dcm_bit_width) - 1.0f; const float im_max = max_val < 0.0f ? im_max_abs(im) : max_val; const float scale = im_max == 0.0f ? 1.0f : dcm_max_val / im_max; // Render the data to an 8-bit unsigned integer array assert(dcm_bit_width == 8); assert(fabsf(dcm_max_val - 255.0f) < FLT_EPSILON); uint8_t *pixelData = new uint8_t[numPixels]; int x, y, z, c; SIFT3D_IM_LOOP_START_C(im, x, y, z, c) const float vox = SIFT3D_IM_GET_VOX(im, x, y, z, c); if (vox < 0.0f) { SIFT3D_ERR("write_dcm_cpp: Image cannot be " "negative \n"); return SIFT3D_FAILURE; } pixelData[c + x + y * im->nx + z * im->nx * im->ny] = static_cast<uint8_t>(vox * scale); SIFT3D_IM_LOOP_END_C // Write the data status = dataset->putAndInsertUint8Array(DCM_PixelData, pixelData, numPixels); delete[] pixelData; if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: failed to set the pixel data \n"); return SIFT3D_FAILURE; } // Choose the encoding format #if 0 DJEncoderRegistration::registerCodecs(); const E_TransferSyntax xfer = EXS_JPEGProcess14SV1TransferSyntax; DJ_RPLossless rp_lossless; status = dataset->chooseRepresentation(xfer, &rp_lossless); #else const E_TransferSyntax xfer = EXS_LittleEndianExplicit; dataset->chooseRepresentation(xfer, NULL); #endif if (!dataset->canWriteXfer(xfer)) { SIFT3D_ERR("write_dcm_cpp: Failed to choose the encoding " "format \n"); return SIFT3D_FAILURE; } // Force the media storage UIDs to be re-generated by removing them dataset->remove(DCM_MediaStorageSOPClassUID); dataset->remove(DCM_MediaStorageSOPInstanceUID); // Save the file status = fileFormat.saveFile(path, xfer); if (status.bad()) { SIFT3D_ERR("write_dcm_cpp: failed to write file %s (%s) \n", path, status.text()); return SIFT3D_FAILURE; } return SIFT3D_SUCCESS; #undef BUF_LEN }
//------------------------------------------------------------------------------ void ctkDICOMDatabase::insert ( DcmDataset *dataset, bool storeFile, bool generateThumbnail) { Q_D(ctkDICOMDatabase); if (!dataset) { return; } // Check to see if the file has already been loaded OFString sopInstanceUID ; dataset->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID); QSqlQuery fileExists ( d->Database ); fileExists.prepare("SELECT InsertTimestamp,Filename FROM Images WHERE SOPInstanceUID == ?"); fileExists.bindValue(0,QString(sopInstanceUID.c_str())); fileExists.exec(); if ( fileExists.next() && QFileInfo(fileExists.value(1).toString()).lastModified() < QDateTime::fromString(fileExists.value(0).toString(),Qt::ISODate) ) { logger.debug ( "File " + fileExists.value(1).toString() + " already added" ); return; } OFString patientsName, patientID, patientsBirthDate, patientsBirthTime, patientsSex, patientComments, patientsAge; OFString studyInstanceUID, studyID, studyDate, studyTime, accessionNumber, modalitiesInStudy, institutionName, performingPhysiciansName, referringPhysician, studyDescription; OFString seriesInstanceUID, seriesDate, seriesTime, seriesDescription, bodyPartExamined, frameOfReferenceUID, contrastAgent, scanningSequence; OFString instanceNumber; Sint32 seriesNumber = 0, acquisitionNumber = 0, echoNumber = 0, temporalPosition = 0; //If the following fields can not be evaluated, cancel evaluation of the DICOM file dataset->findAndGetOFString(DCM_PatientName, patientsName); dataset->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID); dataset->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID); dataset->findAndGetOFString(DCM_PatientID, patientID); dataset->findAndGetOFString(DCM_PatientBirthDate, patientsBirthDate); dataset->findAndGetOFString(DCM_PatientBirthTime, patientsBirthTime); dataset->findAndGetOFString(DCM_PatientSex, patientsSex); dataset->findAndGetOFString(DCM_PatientAge, patientsAge); dataset->findAndGetOFString(DCM_PatientComments, patientComments); dataset->findAndGetOFString(DCM_StudyID, studyID); dataset->findAndGetOFString(DCM_StudyDate, studyDate); dataset->findAndGetOFString(DCM_StudyTime, studyTime); dataset->findAndGetOFString(DCM_AccessionNumber, accessionNumber); dataset->findAndGetOFString(DCM_ModalitiesInStudy, modalitiesInStudy); dataset->findAndGetOFString(DCM_InstitutionName, institutionName); dataset->findAndGetOFString(DCM_PerformingPhysicianName, performingPhysiciansName); dataset->findAndGetOFString(DCM_ReferringPhysicianName, referringPhysician); dataset->findAndGetOFString(DCM_StudyDescription, studyDescription); dataset->findAndGetOFString(DCM_SeriesDate, seriesDate); dataset->findAndGetOFString(DCM_SeriesTime, seriesTime); dataset->findAndGetOFString(DCM_SeriesDescription, seriesDescription); dataset->findAndGetOFString(DCM_BodyPartExamined, bodyPartExamined); dataset->findAndGetOFString(DCM_FrameOfReferenceUID, frameOfReferenceUID); dataset->findAndGetOFString(DCM_ContrastBolusAgent, contrastAgent); dataset->findAndGetOFString(DCM_ScanningSequence, scanningSequence); dataset->findAndGetSint32(DCM_SeriesNumber, seriesNumber); dataset->findAndGetSint32(DCM_AcquisitionNumber, acquisitionNumber); dataset->findAndGetSint32(DCM_EchoNumbers, echoNumber); dataset->findAndGetSint32(DCM_TemporalPositionIdentifier, temporalPosition); // store the file if the database is not in memomry QString filename; if ( storeFile && !this->isInMemory() ) { DcmFileFormat* fileformat = new DcmFileFormat ( dataset ); QString destinationDirectoryName = databaseDirectory() + "/dicom/"; QDir destinationDir(destinationDirectoryName); QString studySeriesDirectory = QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str(); destinationDir.mkpath(studySeriesDirectory); filename = databaseDirectory() + "/dicom/" + pathForDataset(dataset); logger.debug ( "Saving file: " + filename ); OFCondition status = fileformat->saveFile ( filename.toAscii() ); if ( !status.good() ) { logger.error ( "Error saving file: " + filename + "\nError is " + status.text() ); delete fileformat; return; } delete fileformat; } QSqlQuery check_exists_query(d->Database); //The patient UID is a unique number within the database, generated by the sqlite autoincrement int patientUID = -1; if ( patientID != "" && patientsName != "" ) { //Check if patient is already present in the db check_exists_query.prepare ( "SELECT * FROM Patients WHERE PatientID = ? AND PatientsName = ?" ); check_exists_query.bindValue ( 0, QString ( patientID.c_str() ) ); check_exists_query.bindValue ( 1, QString ( patientsName.c_str() ) ); check_exists_query.exec(); if (check_exists_query.next()) { patientUID = check_exists_query.value(check_exists_query.record().indexOf("UID")).toInt(); } else { // Insert it QSqlQuery statement ( d->Database ); statement.prepare ( "INSERT INTO Patients ('UID', 'PatientsName', 'PatientID', 'PatientsBirthDate', 'PatientsBirthTime', 'PatientsSex', 'PatientsAge', 'PatientsComments' ) values ( NULL, ?, ?, ?, ?, ?, ?, ? )" ); statement.bindValue ( 0, QString ( patientsName.c_str() ) ); statement.bindValue ( 1, QString ( patientID.c_str() ) ); statement.bindValue ( 2, QString ( patientsBirthDate.c_str() ) ); statement.bindValue ( 3, QString ( patientsBirthTime.c_str() ) ); statement.bindValue ( 4, QString ( patientsSex.c_str() ) ); // TODO: shift patient's age to study, since this is not a patient level attribute in images // statement.bindValue ( 5, QString ( patientsAge.c_str() ) ); statement.bindValue ( 6, QString ( patientComments.c_str() ) ); statement.exec (); patientUID = statement.lastInsertId().toInt(); logger.debug ( "New patient inserted: " + QString().setNum ( patientUID ) ); } } if ( studyInstanceUID != "" ) { check_exists_query.prepare ( "SELECT * FROM Studies WHERE StudyInstanceUID = ?" ); check_exists_query.bindValue ( 0, QString ( studyInstanceUID.c_str() ) ); check_exists_query.exec(); if(!check_exists_query.next()) { QSqlQuery statement ( d->Database ); statement.prepare ( "INSERT INTO Studies ( 'StudyInstanceUID', 'PatientsUID', 'StudyID', 'StudyDate', 'StudyTime', 'AccessionNumber', 'ModalitiesInStudy', 'InstitutionName', 'ReferringPhysician', 'PerformingPhysiciansName', 'StudyDescription' ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ); statement.bindValue ( 0, QString ( studyInstanceUID.c_str() ) ); statement.bindValue ( 1, patientUID ); statement.bindValue ( 2, QString ( studyID.c_str() ) ); statement.bindValue ( 3, QDate::fromString ( studyDate.c_str(), "yyyyMMdd" ) ); statement.bindValue ( 4, QString ( studyTime.c_str() ) ); statement.bindValue ( 5, QString ( accessionNumber.c_str() ) ); statement.bindValue ( 6, QString ( modalitiesInStudy.c_str() ) ); statement.bindValue ( 7, QString ( institutionName.c_str() ) ); statement.bindValue ( 8, QString ( referringPhysician.c_str() ) ); statement.bindValue ( 9, QString ( performingPhysiciansName.c_str() ) ); statement.bindValue ( 10, QString ( studyDescription.c_str() ) ); if ( !statement.exec() ) { logger.error ( "Error executing statament: " + statement.lastQuery() + " Error: " + statement.lastError().text() ); } } } if ( seriesInstanceUID != "" ) { check_exists_query.prepare ( "SELECT * FROM Series WHERE SeriesInstanceUID = ?" ); check_exists_query.bindValue ( 0, QString ( seriesInstanceUID.c_str() ) ); logger.warn ( "Statement: " + check_exists_query.lastQuery() ); check_exists_query.exec(); if(!check_exists_query.next()) { QSqlQuery statement ( d->Database ); statement.prepare ( "INSERT INTO Series ( 'SeriesInstanceUID', 'StudyInstanceUID', 'SeriesNumber', 'SeriesDate', 'SeriesTime', 'SeriesDescription', 'BodyPartExamined', 'FrameOfReferenceUID', 'AcquisitionNumber', 'ContrastAgent', 'ScanningSequence', 'EchoNumber', 'TemporalPosition' ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ); statement.bindValue ( 0, QString ( seriesInstanceUID.c_str() ) ); statement.bindValue ( 1, QString ( studyInstanceUID.c_str() ) ); statement.bindValue ( 2, static_cast<int>(seriesNumber) ); statement.bindValue ( 3, QString ( seriesDate.c_str() ) ); statement.bindValue ( 4, QDate::fromString ( seriesTime.c_str(), "yyyyMMdd" ) ); statement.bindValue ( 5, QString ( seriesDescription.c_str() ) ); statement.bindValue ( 6, QString ( bodyPartExamined.c_str() ) ); statement.bindValue ( 7, QString ( frameOfReferenceUID.c_str() ) ); statement.bindValue ( 8, static_cast<int>(acquisitionNumber) ); statement.bindValue ( 9, QString ( contrastAgent.c_str() ) ); statement.bindValue ( 10, QString ( scanningSequence.c_str() ) ); statement.bindValue ( 11, static_cast<int>(echoNumber) ); statement.bindValue ( 12, static_cast<int>(temporalPosition) ); if ( !statement.exec() ) { logger.error ( "Error executing statament: " + statement.lastQuery() + " Error: " + statement.lastError().text() ); } } } if ( !filename.isEmpty() ) { check_exists_query.prepare ( "SELECT * FROM Images WHERE Filename = ?" ); check_exists_query.bindValue ( 0, filename ); check_exists_query.exec(); if(!check_exists_query.next()) { QSqlQuery statement ( d->Database ); statement.prepare ( "INSERT INTO Images ( 'SOPInstanceUID', 'Filename', 'SeriesInstanceUID', 'InsertTimestamp' ) VALUES ( ?, ?, ?, ? )" ); statement.bindValue ( 0, QString ( sopInstanceUID.c_str() ) ); statement.bindValue ( 1, filename ); statement.bindValue ( 2, QString ( seriesInstanceUID.c_str() ) ); statement.bindValue ( 3, QDateTime::currentDateTime() ); statement.exec(); } } if(generateThumbnail){ if(d->thumbnailGenerator){ QString studySeriesDirectory = QString(studyInstanceUID.c_str()) + "/" + QString(seriesInstanceUID.c_str()); //Create thumbnail here QString thumbnailPath = databaseDirectory() + "/thumbs/" + this->pathForDataset(dataset) + ".png"; //QString(studyInstanceUID.c_str()) + "/" + //QString(seriesInstanceUID.c_str()) + "/" + //QString(sopInstanceUID.c_str()) + ".png"; QFileInfo thumbnailInfo(thumbnailPath); if(!(thumbnailInfo.exists() && (thumbnailInfo.lastModified() > QFileInfo(filename).lastModified()))){ QDir(databaseDirectory() + "/thumbs/").mkpath(studySeriesDirectory); DicomImage dcmImage(QDir::toNativeSeparators(filename).toAscii()); d->thumbnailGenerator->generateThumbnail(&dcmImage, thumbnailPath); } } } if (isInMemory()) { emit databaseChanged(); } }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { notice()<<"Reading DICOM file "<<file<<" using DCMTK"<<std::endl; std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = file; if (ext=="dicom") { fileName = osgDB::getNameLessExtension(file); } fileName = osgDB::findDataFile( fileName, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; Files files; osgDB::FileType fileType = osgDB::fileType(fileName); if (fileType==osgDB::DIRECTORY) { getDicomFilesInDirectory(fileName, files); } else { #if 1 files.push_back(fileName); #else if (!getDicomFilesInDirectory(osgDB::getFilePath(fileName), files)) { files.push_back(fileName); } #endif } if (files.empty()) { return ReadResult::FILE_NOT_FOUND; } osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix; osg::ref_ptr<osg::Image> image; unsigned int imageNum = 0; EP_Representation pixelRep = EPR_Uint8; int numPlanes = 0; GLenum pixelFormat = 0; GLenum dataType = 0; unsigned int pixelSize = 0; typedef std::list<FileInfo> FileInfoList; FileInfoList fileInfoList; typedef std::map<double, FileInfo> DistanceFileInfoMap; typedef std::map<osg::Vec3d, DistanceFileInfoMap> OrientationFileInfoMap; OrientationFileInfoMap orientationFileInfoMap; unsigned int totalNumSlices = 0; for(Files::iterator itr = files.begin(); itr != files.end(); ++itr) { DcmFileFormat fileformat; OFCondition status = fileformat.loadFile((*itr).c_str()); if(!status.good()) return ReadResult::ERROR_IN_READING_FILE; FileInfo fileInfo; fileInfo.filename = *itr; double pixelSize_y = 1.0; double pixelSize_x = 1.0; double sliceThickness = 1.0; double imagePositionPatient[3] = {0, 0, 0}; double imageOrientationPatient[6] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0 }; Uint16 numOfSlices = 1; double value = 0.0; if (fileformat.getDataset()->findAndGetFloat64(DCM_PixelSpacing, value,0).good()) { pixelSize_y = value; fileInfo.matrix(1,1) = pixelSize_y; } if (fileformat.getDataset()->findAndGetFloat64(DCM_PixelSpacing, value,1).good()) { pixelSize_x = value; fileInfo.matrix(0,0) = pixelSize_x; } // Get slice thickness if (fileformat.getDataset()->findAndGetFloat64(DCM_SliceThickness, value).good()) { sliceThickness = value; notice()<<"sliceThickness = "<<sliceThickness<<std::endl; fileInfo.sliceThickness = sliceThickness; } notice()<<"tagExistsWithValue(DCM_NumberOfFrames)="<<fileformat.getDataset()->tagExistsWithValue(DCM_NumberOfFrames)<<std::endl; notice()<<"tagExistsWithValue(DCM_NumberOfSlices)="<<fileformat.getDataset()->tagExistsWithValue(DCM_NumberOfSlices)<<std::endl; Uint32 numFrames; if (fileformat.getDataset()->findAndGetUint32(DCM_NumberOfFrames, numFrames).good()) { fileInfo.numSlices = numFrames; notice()<<"Read number of frames = "<<numFrames<<std::endl; } OFString numFramesStr; if (fileformat.getDataset()->findAndGetOFString(DCM_NumberOfFrames, numFramesStr).good()) { fileInfo.numSlices = atoi(numFramesStr.c_str()); notice()<<"Read number of frames = "<<numFramesStr<<std::endl; } if (fileformat.getDataset()->findAndGetUint16(DCM_NumberOfFrames, numOfSlices).good()) { fileInfo.numSlices = numOfSlices; notice()<<"Read number of frames = "<<numOfSlices<<std::endl; } if (fileformat.getDataset()->findAndGetUint16(DCM_NumberOfSlices, numOfSlices).good()) { fileInfo.numSlices = numOfSlices; notice()<<"Read number of slices = "<<numOfSlices<<std::endl; } // patient position for(int i=0; i<3; ++i) { if (fileformat.getDataset()->findAndGetFloat64(DCM_ImagePositionPatient, imagePositionPatient[i],i).good()) { notice()<<"Read DCM_ImagePositionPatient["<<i<<"], "<<imagePositionPatient[i]<<std::endl; } else { notice()<<"Have not read DCM_ImagePositionPatient["<<i<<"]"<<std::endl; } } //notice()<<"imagePositionPatient[2]="<<imagePositionPatient[2]<<std::endl; fileInfo.matrix.setTrans(imagePositionPatient[0],imagePositionPatient[1],imagePositionPatient[2]); for(int i=0; i<6; ++i) { double value = 0.0; if (fileformat.getDataset()->findAndGetFloat64(DCM_ImageOrientationPatient, value,i).good()) { imageOrientationPatient[i] = value; notice()<<"Read imageOrientationPatient["<<i<<"], "<<imageOrientationPatient[i]<<std::endl; } else { notice()<<"Have not read imageOrientationPatient["<<i<<"]"<<std::endl; } } osg::Vec3d dirX(imageOrientationPatient[0],imageOrientationPatient[1],imageOrientationPatient[2]); osg::Vec3d dirY(imageOrientationPatient[3],imageOrientationPatient[4],imageOrientationPatient[5]); osg::Vec3d dirZ = dirX ^ dirY; dirZ.normalize(); dirX *= pixelSize_x; dirY *= pixelSize_y; fileInfo.matrix(0,0) = dirX[0]; fileInfo.matrix(1,0) = dirX[1]; fileInfo.matrix(2,0) = dirX[2]; fileInfo.matrix(0,1) = dirY[0]; fileInfo.matrix(1,1) = dirY[1]; fileInfo.matrix(2,1) = dirY[2]; fileInfo.matrix(0,2) = dirZ[0]; fileInfo.matrix(1,2) = dirZ[1]; fileInfo.matrix(2,2) = dirZ[2]; fileInfo.distance = dirZ * (osg::Vec3d(0.0,0.0,0.0)*fileInfo.matrix); notice()<<"dirX = "<<dirX<<std::endl; notice()<<"dirY = "<<dirY<<std::endl; notice()<<"dirZ = "<<dirZ<<std::endl; notice()<<"matrix = "<<fileInfo.matrix<<std::endl; notice()<<"pos = "<<osg::Vec3d(0.0,0.0,0.0)*fileInfo.matrix<<std::endl; notice()<<"dist = "<<fileInfo.distance<<std::endl; notice()<<std::endl; (orientationFileInfoMap[dirZ])[fileInfo.distance] = fileInfo; totalNumSlices += fileInfo.numSlices; } if (orientationFileInfoMap.empty()) return 0; typedef std::map<double, FileInfo> DistanceFileInfoMap; typedef std::map<osg::Vec3d, DistanceFileInfoMap> OrientationFileInfoMap; for(OrientationFileInfoMap::iterator itr = orientationFileInfoMap.begin(); itr != orientationFileInfoMap.end(); ++itr) { notice()<<"Orientation = "<<itr->first<<std::endl; DistanceFileInfoMap& dfim = itr->second; for(DistanceFileInfoMap::iterator ditr = dfim.begin(); ditr != dfim.end(); ++ditr) { FileInfo& fileInfo = ditr->second; notice()<<" d = "<<fileInfo.distance<<" "<<fileInfo.filename<<std::endl; } } DistanceFileInfoMap& dfim = orientationFileInfoMap.begin()->second; if (dfim.empty()) return 0; double totalDistance = 0.0; if (dfim.size()>1) { totalDistance = fabs(dfim.rbegin()->first - dfim.begin()->first); } else { totalDistance = dfim.begin()->second.sliceThickness * double(dfim.begin()->second.numSlices); } notice()<<"Total Distance including ends "<<totalDistance<<std::endl; double averageThickness = totalNumSlices<=1 ? 1.0 : totalDistance / double(totalNumSlices-1); notice()<<"Average thickness "<<averageThickness<<std::endl; for(DistanceFileInfoMap::iterator ditr = dfim.begin(); ditr != dfim.end(); ++ditr) { FileInfo& fileInfo = ditr->second; std::auto_ptr<DicomImage> dcmImage(new DicomImage(fileInfo.filename.c_str())); if (dcmImage.get()) { if (dcmImage->getStatus()==EIS_Normal) { // get the pixel data const DiPixel* pixelData = dcmImage->getInterData(); if(!pixelData) { warning()<<"Error: no data in DicomImage object."<<std::endl; return ReadResult::ERROR_IN_READING_FILE; } osg::ref_ptr<osg::Image> imageAdapter = new osg::Image; EP_Representation curr_pixelRep; int curr_numPlanes; GLenum curr_pixelFormat; GLenum curr_dataType; unsigned int curr_pixelSize; // create the new image convertPixelTypes(pixelData, curr_pixelRep, curr_numPlanes, curr_dataType, curr_pixelFormat, curr_pixelSize); imageAdapter->setImage(dcmImage->getWidth(), dcmImage->getHeight(), dcmImage->getFrameCount(), curr_pixelFormat, curr_pixelFormat, curr_dataType, (unsigned char*)(pixelData->getData()), osg::Image::NO_DELETE); if (!image) { pixelRep = curr_pixelRep; numPlanes = curr_numPlanes; dataType = curr_dataType; pixelFormat = curr_pixelFormat; pixelSize = curr_pixelSize; (*matrix)(0,0) = fileInfo.matrix(0,0); (*matrix)(1,0) = fileInfo.matrix(1,0); (*matrix)(2,0) = fileInfo.matrix(2,0); (*matrix)(0,1) = fileInfo.matrix(0,1); (*matrix)(1,1) = fileInfo.matrix(1,1); (*matrix)(2,1) = fileInfo.matrix(2,1); (*matrix)(0,2) = fileInfo.matrix(0,2) * averageThickness; (*matrix)(1,2) = fileInfo.matrix(1,2) * averageThickness; (*matrix)(2,2) = fileInfo.matrix(2,2) * averageThickness; image = new osg::Image; image->setUserData(matrix.get()); image->setFileName(fileName.c_str()); image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices, pixelFormat, dataType); matrix->preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r()))); notice()<<"Image dimensions = "<<image->s()<<", "<<image->t()<<", "<<image->r()<<" pixelFormat=0x"<<std::hex<<pixelFormat<<" dataType=0x"<<std::hex<<dataType<<std::dec<<std::endl; } else if (pixelData->getPlanes()>numPlanes || pixelData->getRepresentation()>pixelRep) { notice()<<"Need to reallocated "<<image->s()<<", "<<image->t()<<", "<<image->r()<<std::endl; // record the previous image settings to use when we copy back the content. osg::ref_ptr<osg::Image> previous_image = image; // create the new image convertPixelTypes(pixelData, pixelRep, numPlanes, dataType, pixelFormat, pixelSize); image = new osg::Image; image->setUserData(previous_image->getUserData()); image->setFileName(fileName.c_str()); image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices, pixelFormat, dataType); osg::copyImage(previous_image.get(), 0,0,0, previous_image->s(), previous_image->t(), imageNum, image.get(), 0, 0, 0, false); } osg::copyImage(imageAdapter.get(), 0,0,0, imageAdapter->s(), imageAdapter->t(), imageAdapter->r(), image.get(), 0, 0, imageNum, false); imageNum += dcmImage->getFrameCount(); } else { warning()<<"Error in reading dicom file "<<fileName.c_str()<<", error = "<<DicomImage::getString(dcmImage->getStatus())<<std::endl; } } } if (!image) { return ReadResult::ERROR_IN_READING_FILE; } notice()<<"Spacing = "<<*matrix<<std::endl; return image.get(); }
void ImageInstance::initImage(const QString &file) { DcmFileFormat dcmFile; OFCondition result; result = dcmFile.loadFile(file.toLocal8Bit()); DcmDataset *dset = dcmFile.getDataset(); if (result.good()) { //patient information const char *value = NULL; result = dset->findAndGetString(DCM_PatientID, value); patientID = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_PatientName, value); patientName = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_PatientAge, value); patientAge = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_PatientBirthDate, value); patientBirth = QDate::fromString(QString::fromLocal8Bit(value), DATE_DICOM_FORMAT); result = dset->findAndGetString(DCM_PatientSex, value); patientSex = QString::fromLocal8Bit(value); //study information result = dset->findAndGetString(DCM_StudyInstanceUID, value); studyUid = QString::fromLatin1(value); result = dset->findAndGetString(DCM_StudyDate, value); studyTime.setDate(QDate::fromString(QString::fromLocal8Bit(value), DATE_DICOM_FORMAT)); result = dset->findAndGetString(DCM_StudyTime, value); studyTime.setTime(formatDicomTime(QString::fromLatin1(value))); result = dset->findAndGetString(DCM_StudyDescription, value); studyDes = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_ProtocolName, value); procId = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_BodyPartExamined, value); bodyPart = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_Manufacturer, value); manufacturer = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_Modality, value); modality = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_StationName, value); stationName = QString::fromLocal8Bit(value); //series information result = dset->findAndGetString(DCM_SeriesInstanceUID, value); seriesUid = QString::fromLatin1(value); result = dset->findAndGetString(DCM_SeriesNumber, value); seriesNumber = QString::fromLatin1(value); result = dset->findAndGetString(DCM_SeriesDescription, value); seriesDes = QString::fromLocal8Bit(value); //instance information result = dset->findAndGetString(DCM_SOPClassUID, value); sopClassUid = QString::fromLatin1(value); result = dset->findAndGetString(DCM_SOPInstanceUID, value); instanceUid = QString::fromLatin1(value); result = dset->findAndGetString(DCM_InstanceNumber, value); instanceNumber = QString::fromLatin1(value); result = dset->findAndGetString(DCM_InstitutionName, value); institution = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_AcquisitionDate, value); if (value==NULL) result = dset->findAndGetString(DCM_ContentDate, value); acquisitionTime.setDate(QDate::fromString(QString::fromLatin1(value), DATE_DICOM_FORMAT)); result = dset->findAndGetString(DCM_AcquisitionTime, value); if (value==NULL) result = dset->findAndGetString(DCM_ContentTime, value); acquisitionTime.setTime(formatDicomTime(QString::fromLatin1(value))); result = dset->findAndGetString(DCM_PatientPosition, value); patientPostion = QString::fromLatin1(value); result = dset->findAndGetString(DCM_RequestingPhysician, value); reqPhysician = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_PerformingPhysicianName, value); perPhysician = QString::fromLocal8Bit(value); result = dset->findAndGetString(DCM_AccessionNumber, value); accessionNumber = QString::fromLatin1(value); result = dset->findAndGetFloat64(DCM_PixelSpacing, pixelSpacingY, 0); result = dset->findAndGetFloat64(DCM_PixelSpacing, pixelSpacingX, 1); result = dset->findAndGetString(DCM_KVP, value); kvp = QString::fromLatin1(value).toDouble(); result = dset->findAndGetString(DCM_Exposure, value); mAs = QString::fromLatin1(value).toInt(); result = dset->findAndGetFloat64(DCM_WindowWidth, winWidth); result = dset->findAndGetFloat64(DCM_WindowCenter, winCenter); defCenter = winCenter; defWidth = winWidth; if (UID_DigitalXRayImageStorageForPresentation == sopClassUid) { DcmItem *refItem; const char *refImageUid; dset->findAndGetSequenceItem(DCM_ReferencedImageSequence, refItem); if (refItem && refItem->findAndGetString(DCM_ReferencedSOPInstanceUID, refImageUid).good()) { QString dirName = file.left(file.lastIndexOf('/')); rawFile = QString("%1/%2_%3.dcm").arg(dirName, RAW_IMAGE_PREFIX, refImageUid); rawCenter = winCenter; rawWidth = winWidth; } } } dcmImage = new DicomImage(dset, dset->getOriginalXfer()); if (dcmImage->getStatus() == EIS_Normal) { //dcmImage->getWindow(winCenter, winWidth); getPixmap(cachedPixmap); } }
bool CreateResource(DcmDirectoryRecord*& target, ResourceType level, DcmFileFormat& dicom, const char* filename, const char* path) { DcmDataset& dataset = *dicom.getDataset(); OFCondition result; OFString id; E_DirRecType type; switch (level) { case ResourceType_Patient: result = dataset.findAndGetOFString(DCM_PatientID, id); type = ERT_Patient; break; case ResourceType_Study: result = dataset.findAndGetOFString(DCM_StudyInstanceUID, id); type = ERT_Study; break; case ResourceType_Series: result = dataset.findAndGetOFString(DCM_SeriesInstanceUID, id); type = ERT_Series; break; case ResourceType_Instance: result = dataset.findAndGetOFString(DCM_SOPInstanceUID, id); type = ERT_Image; break; default: throw OrthancException(ErrorCode_InternalError); } if (!result.good()) { throw OrthancException(ErrorCode_InternalError); } IndexKey key = std::make_pair(level, std::string(id.c_str())); Index::iterator it = index_.find(key); if (it != index_.end()) { target = it->second; return false; // Already existing } std::auto_ptr<DcmDirectoryRecord> record(new DcmDirectoryRecord(type, NULL, filename)); switch (level) { case ResourceType_Patient: FillPatient(*record, dataset); break; case ResourceType_Study: FillStudy(*record, dataset); break; case ResourceType_Series: FillSeries(*record, dataset); break; case ResourceType_Instance: FillInstance(*record, dataset, *dicom.getMetaInfo(), path); break; default: throw OrthancException(ErrorCode_InternalError); } if (record->isAffectedBySpecificCharacterSet()) { copyElementType1C(dataset, DCM_SpecificCharacterSet, *record); } target = record.get(); GetRoot().insertSub(record.release()); index_[key] = target; return true; // Newly created }
//------------------------------------------------------------------------------ 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; }
void QtDcmManager::makePreview ( const QString &filename ) { DcmRLEDecoderRegistration::registerCodecs ( OFFalse, OFFalse ); DJDecoderRegistration::registerCodecs ( EDC_photometricInterpretation, EUC_default, EPC_default, OFFalse ); DcmFileFormat file; file.loadFile ( filename.toLatin1().data() ); DcmDataset * dset = file.getDataset(); DicomImage* dcimage = new DicomImage ( dset, file.getDataset()->getOriginalXfer(), CIF_MayDetachPixelData ); if ( dcimage != NULL ) { dcimage->setNoDisplayFunction(); dcimage->hideAllOverlays(); dcimage->setNoVoiTransformation(); if ( dcimage->getStatus() == EIS_Normal ) { Uint32 *pixelData = ( Uint32 * ) ( dcimage->getOutputData ( 32 /* bits per sample */ ) ); if ( pixelData != NULL ) { Uint8 *colored = new Uint8[dcimage->getWidth() * dcimage->getHeight() * 4]; //4 * dcimage->getWidth() * dcimage->getHeight() matrix Uint8 *col = colored; Uint32 *p = pixelData; //get the highest values for RGBA, then use them to scale the pixel luminosity Uint32 p_max = 0; #ifdef WIN32 Uint32 p_min = UINT_LEAST32_MAX; #else Uint32 p_min = std::numeric_limits<Uint32>::max(); #endif for ( unsigned i = 0; i < dcimage->getWidth(); ++i ) { for ( unsigned j = 0; j < dcimage->getHeight(); ++j, ++p ) { if ( *p > p_max ) { p_max = *p; } if ( *p < p_min ) { p_min = *p; } } } double a = 4294967295.f / ( ( double ) p_max - ( double ) p_min ); //re-initialize 'col' p = pixelData; //copy the pixels in our QImage for ( unsigned i = 0; i < dcimage->getWidth(); ++i ) { for ( unsigned j = 0; j < dcimage->getHeight(); ++j, ++p ) { *col = ( Uint8 ) ( ( 255.f / 4294967295.f ) * ( a * ( ( double ) ( *p ) - ( double ) p_min ) ) ); ++col; *col = ( Uint8 ) ( ( 255.f / 4294967295.f ) * ( a * ( ( double ) ( *p ) - ( double ) p_min ) ) ); ++col; *col = ( Uint8 ) ( ( 255.f / 4294967295.f ) * ( a * ( ( double ) ( *p ) - ( double ) p_min ) ) ); ++col; *col = 255; ++col; } } QImage image ( colored, dcimage->getWidth(), dcimage->getHeight(), QImage::Format_ARGB32 ); if ( d->previewWidget ) { d->previewWidget->imageLabel->setPixmap ( QPixmap::fromImage ( image.scaled ( 130,130 ), Qt::AutoColor ) ); } delete[] colored; } } delete dcimage; } DcmRLEDecoderRegistration::cleanup(); DJDecoderRegistration::cleanup(); }
//************************************ // Method: Open // FullName: CDcmMerger::Open // Access: public // Returns: int // Qualifier: // Parameter: CStringList * in_pFileList // Purpose: //************************************ int CDcmMerger::Open(CStringList* in_pFileList) { int retcode = SV_NORMAL; for (INT i = 0; i< in_pFileList->GetCount(); i++) { POSITION pos = NULL; pos = in_pFileList->FindIndex(i); if(pos != NULL) { CString sFileName = in_pFileList->GetAt(pos); char* pzTempName; //Convert to ANSI code if(CUtility::UnicodeToAnsi(sFileName,&pzTempName) != ERROR_SUCCESS) retcode = SV_SYSTEM_ERR; //Create DICOM file access object DcmFileFormat* pDcmFile = NULL; DicomImage* pDcmImage = NULL; //*********Create file object pDcmFile = new DcmFileFormat(); if (pDcmFile == NULL) retcode = SV_MEMORY_ERR; //Load file E_TransferSyntax xfer; if(retcode == SV_NORMAL) { OFCondition cond = pDcmFile->loadFile(pzTempName, EXS_Unknown, EGL_withoutGL, DCM_MaxReadLength, ERM_autoDetect); if (cond.bad()) retcode = SV_FILEIO_ERROR; else xfer = pDcmFile->getDataset()->getOriginalXfer(); } OFCmdUnsignedInt opt_frame = 0; //default: start from first frame OFCmdUnsignedInt opt_frameCount = 0; //default: process all frame if(retcode == SV_NORMAL) { //*********Create image object pDcmImage = new DicomImage(pDcmFile, xfer, CIF_AcrNemaCompatibility, opt_frame, opt_frameCount); if (pDcmImage == NULL) retcode = SV_MEMORY_ERR; else if (pDcmImage->getStatus() != EIS_Normal) retcode = SV_UNSUPPORT_FORMAT; } if(retcode == SV_NORMAL) { // VOI LUT processing [1/31/2009 QUYPS] pDcmImage->setMinMaxWindow(); //Add to list m_FileList.AddTail(pDcmFile); m_ImageList.AddTail(pDcmImage); } else { delete pDcmFile; delete pDcmImage; } //Release memory delete[] pzTempName; } else { retcode = SV_SYSTEM_ERR; } //if error occur, escape from loop if (retcode != SV_NORMAL) break; } return retcode; }