std::vector<ImportDescriptor*> DicomImporter::getImportDescriptors(const std::string &filename) { mErrors.clear(); mWarnings.clear(); std::vector<ImportDescriptor*> descriptors; DcmFileFormat fileformat; OFCondition status; if((status = fileformat.loadFile(filename.c_str())).bad()) { return descriptors; } ImportDescriptorResource pImportDescriptor(filename, TypeConverter::toString<RasterElement>()); VERIFYRV(pImportDescriptor.get() != NULL, descriptors); descriptors.push_back(pImportDescriptor.release()); DicomImage img(fileformat.getDataset(), fileformat.getDataset()->getOriginalXfer()); if(img.getStatus() != EIS_Normal) { mErrors.push_back(std::string("Unable to decode image: ") + DicomImage::getString(img.getStatus())); pImportDescriptor->setDataDescriptor(RasterUtilities::generateRasterDataDescriptor(filename, NULL, 0, 0, INT1UBYTE, IN_MEMORY)); return descriptors; } InterleaveFormatType interleave(BSQ); EncodingType encoding(INT4UBYTES); bool rgb = false; unsigned long rows = img.getHeight(), columns = img.getWidth(), frames = img.getFrameCount(); int imgDepth = img.getDepth(); switch(img.getPhotometricInterpretation()) { case EPI_Monochrome1: case EPI_Monochrome2: // do nothing special....this is single or multi-frame grayscale, 1 or 2 byte break; case EPI_RGB: case EPI_PaletteColor: // supported if there's only 1 frame if(frames == 1) { frames = 3; rgb = true; } else { mWarnings.push_back("RGB and palette color not supported when multiple frames are present. Converting to grayscale."); } break; default: mWarnings.push_back(std::string(DicomImage::getString(img.getPhotometricInterpretation())) + " not supported. Attempting to convert to grayscale."); } if(imgDepth <= 8) { encoding = INT1UBYTE; } else if(imgDepth <= 16) { encoding = INT2UBYTES; } else if(imgDepth <= 32) { encoding = INT4UBYTES; } else { mWarnings.push_back("Bit depth " + StringUtilities::toDisplayString(imgDepth) + " not supported. Downgrading to 32 bits."); encoding = INT4UBYTES; } RasterDataDescriptor *pDescriptor = RasterUtilities::generateRasterDataDescriptor( filename, NULL, rows, columns, frames, interleave, encoding, IN_MEMORY); if(pDescriptor != NULL) { if(rgb) { pDescriptor->setDisplayBand(RED, pDescriptor->getBands()[0]); pDescriptor->setDisplayBand(GREEN, pDescriptor->getBands()[1]); pDescriptor->setDisplayBand(BLUE, pDescriptor->getBands()[2]); pDescriptor->setDisplayMode(RGB_MODE); } pImportDescriptor->setDataDescriptor(pDescriptor); FactoryResource<DynamicObject> pMeta; int idx = 0; DcmElement *pElmnt; while((pElmnt = fileformat.getDataset()->getElement(idx++)) != NULL) { if(pElmnt->error().bad()) { continue; } const DcmTag &tag = pElmnt->getTag(); std::string name = const_cast<DcmTag&>(tag).getTagName(); if(name.empty()) { name = QString("(%1,%2)").arg(pElmnt->getGTag(), 4, 16, QChar('0')).arg(pElmnt->getETag(), 4, 16, QChar('0')).toStdString(); } pMeta->setAttributeByPath(std::string("DICOM/") + name, dcmElementToDataVariant(*pElmnt)); } pImportDescriptor->getDataDescriptor()->setMetadata(pMeta.release()); } RasterUtilities::generateAndSetFileDescriptor(pImportDescriptor->getDataDescriptor(), filename, std::string(), LITTLE_ENDIAN_ORDER); return descriptors; }
void query_from_net( const std::string& patientid, const std::string& name, const std::string& modality, const std::string& date_from, const std::string& date_to, const std::string& studydescription, const std::string& accessionnumber, const std::string& local_aet, const std::set<std::string>& groups, const sigc::slot< void, const Glib::RefPtr< ImagePool::Study >& >& resultslot ) { // get encodings std::string dicom_enc = ImagePool::get_encoding(); std::string system_enc = ImagePool::get_system_encoding(dicom_enc); // create patientsname querystring std::string patientsname; if(name.empty()) { patientsname = "*"; } else { patientsname = convert_string_to(name.c_str(), system_enc); } std::string description; if(!studydescription.empty()) { description = convert_string_to(studydescription.c_str(), system_enc); } // create date querystring std::string date; if(date_from.empty() && date_to.empty()) { date = ""; } else if(date_to.empty()) { date = date_from + "-"; } else if(date_from.empty()) { date = "-" + date_to; } else { date = date_from + "-" + date_to; } if(date_from == date_to) { date = date_from; } /*std::string station; if(!stationname.empty()) { station = "*" + convert_string_to(stationname.c_str(), system_enc) + "*"; }*/ DcmDataset query; DcmElement* e = NULL; e = newDicomElement(DCM_QueryRetrieveLevel); e->putString("STUDY"); query.insert(e); e = newDicomElement(DCM_SpecificCharacterSet); e->putString(dicom_enc.c_str()); query.insert(e); e = newDicomElement(DCM_PatientsName); e->putString(patientsname.c_str()); query.insert(e); e = newDicomElement(DCM_PatientID); e->putString(convert_string_to(patientid.c_str(), system_enc).c_str()); query.insert(e); e = newDicomElement(DCM_SOPClassesInStudy); query.insert(e); e = newDicomElement(DCM_ModalitiesInStudy); e->putString(modality.c_str()); query.insert(e); e = newDicomElement(DCM_PatientsBirthDate); query.insert(e); e = newDicomElement(DCM_PatientsSex); query.insert(e); e = newDicomElement(DCM_StudyDate); e->putString(date.c_str()); query.insert(e); e = newDicomElement(DCM_StudyTime); query.insert(e); e = newDicomElement(DCM_NumberOfStudyRelatedSeries); query.insert(e); e = newDicomElement(DCM_NumberOfStudyRelatedInstances); query.insert(e); e = newDicomElement(DCM_AccessionNumber); e->putString(accessionnumber.c_str()); query.insert(e); e = newDicomElement(DCM_StudyID); query.insert(e); e = newDicomElement(DCM_StudyInstanceUID); query.insert(e); e = newDicomElement(DCM_StudyDescription); e->putString(description.c_str()); query.insert(e); // StationName not allowed in StudyRoot /*e = newDicomElement(DCM_StationName); e->putString(station.c_str()); query.insert(e);*/ std::cout << "NEW QUERY:" << std::endl; query.print(COUT); NetClient<FindAssociation> a; a.signal_server_result.connect(sigc::bind(sigc::ptr_fun(on_query_from_net_result), resultslot)); //std::set<std::string> groups = get_servergroups(); std::set<std::string>::iterator i = groups.begin(); // do we have groups defined ? if(groups.size() > 0) { while(i != groups.end()) { a.QueryServerGroup(&query, *i, local_aet, UID_FINDStudyRootQueryRetrieveInformationModel); i++; } } // no query all servers else { a.QueryServerGroup(&query, "", local_aet, UID_FINDStudyRootQueryRetrieveInformationModel); } }
tissuestack::imaging::DicomFileWrapper::DicomFileWrapper(const std::string filename, const bool isTempFile) : _file_name(filename), _isTemp(isTempFile) { if (!tissuestack::utils::System::fileExists(filename)) THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException, "Supposed Dicom File does not exist in that location!"); // load file to read header tags DcmFileFormat dicomFormat; OFCondition status = dicomFormat.loadFile(filename.c_str()); if (!status.good()) THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException, "Given dicom file is no good!"); OFString value; if (dicomFormat.getDataset()->findAndGetOFString(DCM_TransferSyntaxUID, value).good()) { std::string transferSyntaxUID = value.c_str(); std::transform(transferSyntaxUID.begin(), transferSyntaxUID.end(), transferSyntaxUID.begin(), toupper); if (transferSyntaxUID.find("JPEG2000") != std::string::npos) THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException, "We don't support JPEG2000!"); } if (!dicomFormat.getDataset()->findAndGetOFString(DCM_SeriesInstanceUID, value).good()) if (!dicomFormat.getDataset()->findAndGetOFString(DCM_SeriesNumber, value).good()) this->_series_number = "0"; else this->_series_number = std::string(value.c_str()); else this->_series_number = std::string(value.c_str()); if (!dicomFormat.getDataset()->findAndGetOFString(DCM_InstanceNumber, value).good()) THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException, "Could not read dicom instance number!"); this->_instance_number = strtoul(value.c_str(), NULL, 10); if (!dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ImagePositionPatient, value).good()) this->_image_position_patient = "0\\0\\0"; else this->_image_position_patient = std::string(value.c_str()); if (dicomFormat.getDataset()->findAndGetOFString(DCM_MRAcquisitionType, value).good()) // are we 3D this->_acquisitionType = std::string(value.c_str()); if (dicomFormat.getDataset()->findAndGetOFString(DCM_PatientPosition, value).good()) this->_patient_position = std::string(value.c_str()); if (dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ImageType, value).good()) // are we a mosaic { std::string v = std::string(value.c_str()); std::transform(v.begin(), v.end(), v.begin(), toupper); if (v.find("MOSAIC") != std::string::npos) // have a look for numbers of images in mosaic { if (dicomFormat.getDataset()->findAndGetOFString(CSA_NumberOfImagesInMosaic, value).good()) this->_number_of_images_in_mosaic = strtoul(value.c_str(), NULL, 10); DcmElement * csaImageHeaderInfo = const_cast<DcmElement *>( this->findDcmElement(dicomFormat.getDataset(), CSA_ImageSeriesHeaderInfo)); if (csaImageHeaderInfo != nullptr) { Uint8 * csaImageHeaderContent = nullptr; unsigned long int length = csaImageHeaderInfo->getLength(); status = csaImageHeaderInfo->getUint8Array(csaImageHeaderContent); if (status.good()) { std::string tmp = std::string((const char *) csaImageHeaderContent, length); size_t ascconf_start = tmp.find(ASCCONV_BEGIN); if (ascconf_start == std::string::npos) // plan B: try other header { csaImageHeaderInfo = const_cast<DcmElement *>( this->findDcmElement(dicomFormat.getDataset(), CSA_ImageHeaderInfo)); if (csaImageHeaderInfo != nullptr) { csaImageHeaderContent = nullptr; length = csaImageHeaderInfo->getLength(); status = csaImageHeaderInfo->getUint8Array(csaImageHeaderContent); tmp = std::string((const char *) csaImageHeaderContent, length); ascconf_start = tmp.find(ASCCONV_BEGIN); // try again with backup header } } if (ascconf_start != std::string::npos) { ascconf_start += strlen(ASCCONV_BEGIN) + 1; size_t ascconf_end = tmp.find(ASCCONV_END) - 1; if (ascconf_end != std::string::npos) this->_ascconv = tmp.substr(ascconf_start, ascconf_end-ascconf_start); } } } if (this->_number_of_images_in_mosaic == 0 && !this->_ascconv.empty()) // plan B for number of images in mosaic { size_t lSize_start = this->_ascconv.find(LSIZE); if (lSize_start != std::string::npos) { lSize_start = this->_ascconv.find("=", lSize_start); if (lSize_start != std::string::npos) { lSize_start++; size_t lSize_end = this->_ascconv.find("\n", lSize_start); if (lSize_end != std::string::npos) { std::string lSizeString = this->_ascconv.substr(lSize_start, lSize_start-lSize_end); this->_number_of_images_in_mosaic = strtoul(lSizeString.c_str(), NULL, 10); } } } } } } if (dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ImagesInAcquisition, value).good()) this->_number_of_images_in_series_or_acquisition = strtoul(value.c_str(), NULL, 10); if (this->_number_of_images_in_series_or_acquisition == 0 && dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ACR_NEMA_ImagesInSeries, value).good()) this->_number_of_images_in_series_or_acquisition = strtoul(value.c_str(), NULL, 10); if (!dicomFormat.getDataset()->findAndGetOFStringArray(DCM_PixelSpacing, value).good()) this->_pixel_spacing = "1\\1"; else this->_pixel_spacing = std::string(value.c_str()); if (!dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ImageOrientationPatient, value).good()) this->_image_orientation = "1\\0\\0\\0\\1\\0"; else this->_image_orientation = std::string(value.c_str()); if (!dicomFormat.getDataset()->findAndGetOFString(DCM_Rows, value).good()) THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException, "Could not extract number of rows for given dicom!"); this->_rows = strtoull(value.c_str(), NULL, 10); if (!dicomFormat.getDataset()->findAndGetOFString(DCM_Columns, value).good()) THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException, "Could not extract number of columns for given dicom!"); this->_columns = strtoull(value.c_str(), NULL, 10); if (!dicomFormat.getDataset()->findAndGetOFString(DCM_BitsAllocated, value).good()) THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException, "Could not extract number of allocated bits for given dicom!"); this->_allocated_bits = strtoul(value.c_str(), NULL, 10); if (!dicomFormat.getDataset()->findAndGetOFString(DCM_PixelRepresentation, value).good()) this->_is_signed_data = 0; else this->_is_signed_data = static_cast<unsigned short>(strtoul(value.c_str(), NULL, 10)); if (!dicomFormat.getDataset()->findAndGetOFString(DCM_PhotometricInterpretation, value).good()) this->_photometric_interpretation = "MONOCHROME2"; else this->_photometric_interpretation = std::string(value.c_str()); if (this->isColor()) { if (!dicomFormat.getDataset()->findAndGetOFString(DCM_PlanarConfiguration, value).good()) this->_planar_configuration = 0; else this->_planar_configuration = static_cast<unsigned short>(strtoul(value.c_str(), NULL, 10)); } }