std::vector<ImportDescriptor*> DiHdfImporter::getImportDescriptors(const std::string &filename) { mErrors.clear(); mWarnings.clear(); std::vector<ImportDescriptor*> descriptors; ImportDescriptorResource pImportDescriptor(filename, TypeConverter::toString<RasterElement>()); VERIFYRV(pImportDescriptor.get(), descriptors); descriptors.push_back(pImportDescriptor.release()); HdfContext hdf(filename); if (hdf.grid() == FAIL) { mErrors.push_back("Invalid DI HDF file."); return descriptors; } int32 frames = 0; int32 attrs = 0; GRfileinfo(hdf.grid(), &frames, &attrs); if (frames <= 0) { mErrors.push_back("Dataset does not contain and frames."); return descriptors; } if (hdf.toFrame(0) == FAIL) { mErrors.push_back("Unable to access image data."); return descriptors; } char pName[256]; int32 comps = 0; int32 data_type = 0; int32 interlace_mode = 0; int32 pDims[2] = {0,0}; EncodingType encoding; GRgetiminfo(hdf.riid(), pName, &comps, &data_type, &interlace_mode, pDims, &attrs); switch(data_type) { case DFNT_FLOAT32: encoding = FLT4BYTES; break; case DFNT_FLOAT64: encoding = FLT8BYTES; break; case DFNT_CHAR8: case DFNT_INT8: encoding = INT1SBYTE; break; case DFNT_UCHAR8: case DFNT_UINT8: encoding = INT1UBYTE; break; case DFNT_INT16: encoding = INT2SBYTES; break; case DFNT_UINT16: encoding = INT2UBYTES; break; case DFNT_INT32: encoding = INT4SBYTES; break; case DFNT_UINT32: encoding = INT4UBYTES; break; case DFNT_INT64: case DFNT_UINT64: default: mErrors.push_back("Unknown data encoding."); break; } pImportDescriptor->setDataDescriptor(RasterUtilities::generateRasterDataDescriptor( filename, NULL, pDims[1], pDims[0], frames, BSQ, encoding, IN_MEMORY)); RasterUtilities::generateAndSetFileDescriptor(pImportDescriptor->getDataDescriptor(), filename, std::string(), LITTLE_ENDIAN_ORDER); return descriptors; }
std::vector<ImportDescriptor*> FitsImporter::getImportDescriptors(const std::string& fname) { std::string filename = fname; std::vector<std::vector<std::string> >& errors = mErrors[fname]; std::vector<std::vector<std::string> >& warnings = mWarnings[fname]; errors.clear(); warnings.clear(); int status=0; std::vector<ImportDescriptor*> descriptors; FitsFileResource pFile(filename); if (!pFile.isValid()) { errors.resize(1); errors[0].push_back(pFile.getStatus()); RETURN_DESCRIPTORS; } int hduCnt = 0; int specificHdu = 0; int hdu = 1; if (!splitFilename(filename, hduCnt, specificHdu, hdu, pFile, errors, warnings)) { RETURN_DESCRIPTORS; } errors.resize(hduCnt+1); warnings.resize(hduCnt+1); for(; hdu <= hduCnt; ++hdu) { std::string datasetName = filename + "[" + StringUtilities::toDisplayString(hdu) + "]"; int hduType; CHECK_FITS(fits_movabs_hdu(pFile, hdu, &hduType, &status), hdu, false, continue); ImportDescriptorResource pImportDescriptor(static_cast<ImportDescriptor*>(NULL)); FactoryResource<DynamicObject> pMetadata; VERIFYRV(pMetadata.get() != NULL, descriptors); { // scope std::vector<std::string> comments; char pCard[81]; char pValue[81]; char pComment[81]; int nkeys = 0; CHECK_FITS(fits_get_hdrspace(pFile, &nkeys, NULL, &status), hdu, true, ;); for(int keyidx = 1; keyidx <= nkeys; ++keyidx) { CHECK_FITS(fits_read_keyn(pFile, keyidx, pCard, pValue, pComment, &status), hdu, true, continue); std::string name = StringUtilities::stripWhitespace(std::string(pCard)); std::string val = StringUtilities::stripWhitespace(std::string(pValue)); std::string comment = StringUtilities::stripWhitespace(std::string(pComment)); if (!val.empty()) { pMetadata->setAttributeByPath("FITS/" + name, val); } else if (!comment.empty()) { comments.push_back(comment); } } if (!comments.empty()) { // ideally, this would add a multi-line string but Opticks doesn't display this properly // pMetadata->setAttributeByPath("FITS/COMMENT", StringUtilities::join(comments, "\n")); for(unsigned int idx = 0; idx < comments.size(); ++idx) { pMetadata->setAttributeByPath("FITS/COMMENT/" + StringUtilities::toDisplayString(idx), comments[idx]); } } } switch(hduType) { case IMAGE_HDU: { pImportDescriptor = ImportDescriptorResource(datasetName, TypeConverter::toString<RasterElement>()); VERIFYRV(pImportDescriptor.get() != NULL, descriptors); EncodingType fileEncoding; InterleaveFormatType interleave(BSQ); unsigned int rows=0; unsigned int cols=0; unsigned int bands=1; int bitpix; int naxis; long axes[3]; CHECK_FITS(fits_get_img_param(pFile, 3, &bitpix, &naxis, axes, &status), hdu, false, continue); switch(bitpix) { case BYTE_IMG: fileEncoding = INT1UBYTE; break; case SHORT_IMG: fileEncoding = INT2SBYTES; break; case LONG_IMG: fileEncoding = INT4SBYTES; break; case FLOAT_IMG: fileEncoding = FLT4BYTES; break; case DOUBLE_IMG: fileEncoding = FLT8BYTES; break; default: warnings[hdu].push_back("Unsupported BITPIX value " + StringUtilities::toDisplayString(bitpix) + "."); continue; } EncodingType dataEncoding = checkForOverflow(fileEncoding, pMetadata.get(), hdu, errors, warnings); if (naxis == 1) { // 1-D data is a signature pImportDescriptor = ImportDescriptorResource(datasetName, TypeConverter::toString<Signature>()); pMetadata->setAttributeByPath(METADATA_SIG_ENCODING, dataEncoding); pMetadata->setAttributeByPath(METADATA_SIG_LENGTH, axes[0]); RasterUtilities::generateAndSetFileDescriptor(pImportDescriptor->getDataDescriptor(), filename, StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER); // add units SignatureDataDescriptor* pSigDd = dynamic_cast<SignatureDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pSigDd != NULL) { FactoryResource<Units> pUnits; pUnits->setUnitName("Custom"); pUnits->setUnitType(CUSTOM_UNIT); pSigDd->setUnits("Reflectance", pUnits.get()); } break; // leave switch() } else if (naxis == 2) { cols = axes[0]; rows = axes[1]; } else if (naxis == 3) { cols = axes[0]; rows = axes[1]; bands = axes[2]; } else { errors[hdu].push_back(StringUtilities::toDisplayString(naxis) + " axis data not supported."); } RasterDataDescriptor* pDataDesc = RasterUtilities::generateRasterDataDescriptor( datasetName, NULL, rows, cols, bands, interleave, dataEncoding, IN_MEMORY); pImportDescriptor->setDataDescriptor(pDataDesc); if (specificHdu == 0 && hdu == 1 && naxis == 2 && (axes[0] <= 5 || axes[1] <= 5)) { // use 5 as this is a good top end for the number of astronomical band pass filters // in general usage. this is not in a spec anywhere and is derived from various sample // FITS files for different astronomical instruments. // // There's a good chance this is really a spectrum. (0th HDU) // We'll create an import descriptor for the spectrum version of this // And disable the raster descriptor by default pImportDescriptor->setImported(false); ImportDescriptorResource pSigDesc(datasetName, TypeConverter::toString<SignatureLibrary>()); DynamicObject* pSigMetadata = pSigDesc->getDataDescriptor()->getMetadata(); pSigMetadata->merge(pMetadata.get()); std::vector<double> centerWavelengths; unsigned int cnt = (axes[0] <= 5) ? axes[1] : axes[0]; double startVal = StringUtilities::fromDisplayString<double>( dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/MINWAVE"), "0.0")); double endVal = StringUtilities::fromDisplayString<double>( dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/MAXWAVE"), "0.0")); double incr = (endVal == 0.0) ? 1.0 : ((endVal - startVal) / static_cast<double>(cnt)); centerWavelengths.reserve(cnt); for (unsigned int idx = 0; idx < cnt; idx++) { centerWavelengths.push_back(startVal + (idx * incr)); } pSigMetadata->setAttributeByPath(CENTER_WAVELENGTHS_METADATA_PATH, centerWavelengths); // Units std::string unitsName = dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/BUNIT"), std::string()); if (!unitsName.empty()) { FactoryResource<Units> units; units->setUnitName(unitsName); units->setUnitType(RADIANCE); SignatureDataDescriptor* pSigDd = dynamic_cast<SignatureDataDescriptor*>(pSigDesc->getDataDescriptor()); if (pSigDd != NULL) { pSigDd->setUnits("Reflectance", units.get()); } } RasterUtilities::generateAndSetFileDescriptor(pSigDesc->getDataDescriptor(), filename, StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER); // If units are not available, set custom units into the data descriptor so that the user can // modify them - this must occur after the call to RasterUtilities::generateAndSetFileDescriptor() // so that the file descriptor will still display no defined units if (unitsName.empty()) { FactoryResource<Units> units; units->setUnitName("Custom"); units->setUnitType(CUSTOM_UNIT); SignatureDataDescriptor* pSigDd = dynamic_cast<SignatureDataDescriptor*>(pSigDesc->getDataDescriptor()); if (pSigDd != NULL) { pSigDd->setUnits("Reflectance", units.get()); } } descriptors.push_back(pSigDesc.release()); } RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>( RasterUtilities::generateAndSetFileDescriptor(pDataDesc, filename, StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER)); if (pFileDescriptor != NULL) { unsigned int bitsPerElement = RasterUtilities::bytesInEncoding(fileEncoding) * 8; pFileDescriptor->setBitsPerElement(bitsPerElement); } break; // leave switch() } case ASCII_TBL: case BINARY_TBL: warnings[hdu].push_back("Tables not supported. [HDU " + StringUtilities::toDisplayString(hdu) + "]"); continue; default: warnings[hdu].push_back("HDU " + StringUtilities::toDisplayString(hdu) + " is an unknown type."); continue; } pImportDescriptor->getDataDescriptor()->setMetadata(pMetadata.release()); pImportDescriptor->setImported(errors[hdu].empty()); descriptors.push_back(pImportDescriptor.release()); }
std::vector<ImportDescriptor*> NefImporter::getImportDescriptors(const std::string &filename) { std::vector<ImportDescriptor*> descriptors; try { ImportDescriptorResource pImportDescriptor(filename, TypeConverter::toString<RasterElement>()); VERIFYRV(pImportDescriptor.get() != NULL, descriptors); descriptors.push_back(pImportDescriptor.release()); InterleaveFormatType interleave(BSQ); EncodingType encoding(INT4UBYTES); //bool rgb = false; LibRaw iProcessor; const char *fn=filename.c_str(); iProcessor.open_file(fn); unsigned long rows = iProcessor.imgdata.sizes.iheight, columns = iProcessor.imgdata.sizes.iwidth,frames=3; RasterDataDescriptor *pDescriptor = RasterUtilities::generateRasterDataDescriptor( filename, NULL, rows, columns, frames, interleave, encoding, IN_MEMORY); if(pDescriptor != NULL) { 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); RasterUtilities::generateAndSetFileDescriptor(pImportDescriptor->getDataDescriptor(), filename, std::string(), LITTLE_ENDIAN_ORDER); descriptors.push_back(pImportDescriptor.release()); //return descriptors; /* Endian e; DynamicObject* pMeta = NULL; { // scope the geotiff importer ImporterResource geotiff("GeoTIFF Importer", filename); if (geotiff.get() == NULL) { return descriptors; } std::vector<ImportDescriptor*> tiffDescriptors = geotiff->getImportDescriptors(); if (tiffDescriptors.size() != 1) { return descriptors; } e = Endian(tiffDescriptors.front()->getDataDescriptor()->getFileDescriptor()->getEndian()); pMeta = tiffDescriptors.front()->getDataDescriptor()->getMetadata(); } if (dv_cast<std::string>(pMeta->getAttributeByPath("TIFF/Make")) != "NIKON CORPORATION") { return descriptors; } // Reload the file and parse the RAW IFD FileResource pNef(filename.c_str(), "rb"); if (pNef.get() == NULL) { return descriptors; } // JpegImageOffset, RawOffset std::vector<unsigned int> ifds = dv_cast<std::vector<unsigned int> >(pMeta->getAttributeByPath("TIFF/SubIFD")); if (ifds.size() != 2) { return descriptors; } fseek(pNef, ifds[1], SEEK_SET); unsigned int rows = 0; unsigned int cols = 0; unsigned int bpp = 0; // parse the entries size_t entryCount = getVal<uint16_t>(pNef, e); while (--entryCount >= 0) { uint16_t tag = getVal<uint16_t>(pNef, e); uint16_t type = getVal<uint16_t>(pNef, e); uint16_t count = getVal<uint32_t>(pNef, e); bool compressed = false; switch(tag) { case 254: // SubfileType == 0 (full resolution) if (type != 4 && count != 1 && getVal<uint32_t>(pNef, e) != 0) { return descriptors; } break; case 256: // ImageWidth if (type != 4 && count != 1) { return descriptors; } cols = getVal<uint32_t>(pNef, e); break; case 257: // ImageHight if (type != 4 && count != 1) { return descriptors; } rows = getVal<uint32_t>(pNef, e); break; case 258: // BitsPerSample if (type != 1 && count != 1) { return descriptors; } bpp = getVal<unsigned char>(pNef, e); fseek(pNef, 3, SEEK_CUR); break; case 259: // Compression if (type != 3 && count != 1) { return descriptors; } { uint16_t comp = getVal<uint16_t>(pNef, e); fseek(pNef, 2, SEEK_CUR); if (comp == 1) { compressed = false; } else if (comp == 34713) { compressed = true; } else { return descriptors; } } break; default: fseek(pNef, 4, SEEK_CUR); break; } } */ } catch (const std::bad_cast&) { // metadata not present, wrong kind of file } return descriptors; }
std::vector<ImportDescriptor*> LandsatGeotiffImporter::createImportDescriptors(const std::string& filename, const DynamicObject* pImageMetadata, Landsat::LandsatImageType type) { std::string suffix; if (type == Landsat::LANDSAT_VNIR) { suffix = "vnir"; } else if (type == Landsat::LANDSAT_PAN) { suffix = "pan"; } else if (type == Landsat::LANDSAT_TIR) { suffix = "tir"; } std::vector<ImportDescriptor*> descriptors; std::string spacecraft = dv_cast<std::string>( pImageMetadata->getAttributeByPath("LANDSAT_MTL/L1_METADATA_FILE/PRODUCT_METADATA/SPACECRAFT_ID"), ""); std::vector<std::string> bandNames = Landsat::getSensorBandNames(spacecraft, type); if (bandNames.empty()) { //this spacecraft and iamge type //isn't meant to have any bands, so terminate early //e.g. spacecraft == "Landsat5" && type == Landsat::LANDSAT_PAN return descriptors; } std::vector<unsigned int> validBands; std::vector<std::string> bandFiles = Landsat::getGeotiffBandFilenames( pImageMetadata, filename, type, validBands); if (bandFiles.empty()) { mWarnings.push_back("Unable to locate band files for " + suffix + " product."); return descriptors; } ImportDescriptorResource pImportDescriptor(filename + "-" + suffix, TypeConverter::toString<RasterElement>(), NULL, false); if (pImportDescriptor.get() == NULL) { return descriptors; } RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pDescriptor == NULL) { return descriptors; } pDescriptor->setProcessingLocation(ON_DISK); DynamicObject* pMetadata = pDescriptor->getMetadata(); pMetadata->merge(pImageMetadata); FactoryResource<RasterFileDescriptor> pFileDescriptorRes; pDescriptor->setFileDescriptor(pFileDescriptorRes.get()); RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); pFileDescriptor->setFilename(filename); std::string tiffFile = bandFiles[0]; if (!Landsat::parseBasicsFromTiff(tiffFile, pDescriptor)) { mWarnings.push_back("Unable to parse basic information about image from tiff file for " + suffix + " product."); return descriptors; } if (pDescriptor->getBandCount() != 1 || pDescriptor->getDataType() != INT1UBYTE) { mWarnings.push_back("Improperly formatted tiff file for " + suffix + " product."); return descriptors; } pDescriptor->setInterleaveFormat(BSQ); //one tiff file per band. pFileDescriptor->setInterleaveFormat(BSQ); std::vector<DimensionDescriptor> bands = RasterUtilities::generateDimensionVector( bandFiles.size(), true, false, true); pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); pDescriptor->setBadValues(std::vector<int>(1, 0)); pFileDescriptor->setDatasetLocation(suffix); //special metadata here Landsat::fixMtlMetadata(pMetadata, type, validBands); std::vector<std::string> defaultImport = OptionsLandsatImport::getSettingDefaultImport(); bool fallbackToDn = false; descriptors.push_back(pImportDescriptor.release()); if (type == Landsat::LANDSAT_VNIR) { //attempt to display true-color DimensionDescriptor redBand = RasterUtilities::findBandWavelengthMatch(0.630, 0.690, pDescriptor); DimensionDescriptor greenBand = RasterUtilities::findBandWavelengthMatch(0.510, 0.590, pDescriptor); DimensionDescriptor blueBand = RasterUtilities::findBandWavelengthMatch(0.410, 0.490, pDescriptor); if (redBand.isValid() && greenBand.isValid() && blueBand.isValid()) { pDescriptor->setDisplayMode(RGB_MODE); pDescriptor->setDisplayBand(RED, redBand); pDescriptor->setDisplayBand(GREEN, greenBand); pDescriptor->setDisplayBand(BLUE, blueBand); } } std::vector<std::pair<double, double> > radianceFactors = Landsat::determineRadianceConversionFactors( pMetadata, type, validBands); bool shouldDefaultImportRadiance = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Radiance") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size()) { //we have enough to create radiance import descriptor RasterDataDescriptor* pRadianceDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-radiance", NULL)); if (pRadianceDescriptor != NULL) { pRadianceDescriptor->setDataType(FLT4BYTES); pRadianceDescriptor->setValidDataTypes(std::vector<EncodingType>(1, pRadianceDescriptor->getDataType())); pRadianceDescriptor->setBadValues(std::vector<int>(1, -100)); FactoryResource<Units> pUnits; pUnits->setUnitType(RADIANCE); pUnits->setUnitName("w/(m^2*sr*um)"); pUnits->setScaleFromStandard(1.0); pRadianceDescriptor->setUnits(pUnits.get()); FileDescriptor* pRadianceFileDescriptor = pRadianceDescriptor->getFileDescriptor(); if (pRadianceFileDescriptor != NULL) { pRadianceFileDescriptor->setDatasetLocation(suffix + "-radiance"); ImportDescriptorResource pRadianceImportDescriptor(pRadianceDescriptor, shouldDefaultImportRadiance); descriptors.push_back(pRadianceImportDescriptor.release()); } } } else if (shouldDefaultImportRadiance) { fallbackToDn = true; } std::vector<double> reflectanceFactors = Landsat::determineReflectanceConversionFactors( pMetadata, type, validBands); bool shouldDefaultImportReflectance = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Reflectance") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size() && reflectanceFactors.size() == bandFiles.size()) { //we have enough to create reflectance import descriptor RasterDataDescriptor* pReflectanceDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-reflectance", NULL)); if (pReflectanceDescriptor != NULL) { pReflectanceDescriptor->setDataType(INT2SBYTES); pReflectanceDescriptor->setValidDataTypes( std::vector<EncodingType>(1, pReflectanceDescriptor->getDataType())); pReflectanceDescriptor->setBadValues(std::vector<int>(1, std::numeric_limits<short>::max())); FactoryResource<Units> pUnits; pUnits->setUnitType(REFLECTANCE); pUnits->setUnitName("Reflectance"); pUnits->setScaleFromStandard(1/10000.0); pReflectanceDescriptor->setUnits(pUnits.get()); FileDescriptor* pReflectanceFileDescriptor = pReflectanceDescriptor->getFileDescriptor(); if (pReflectanceFileDescriptor != NULL) { pReflectanceFileDescriptor->setDatasetLocation(suffix + "-reflectance"); ImportDescriptorResource pReflectanceImportDescriptor(pReflectanceDescriptor, shouldDefaultImportReflectance); descriptors.push_back(pReflectanceImportDescriptor.release()); } } } else if (shouldDefaultImportReflectance) { fallbackToDn = true; } double K1 = 0.0; double K2 = 0.0; bool haveTemperatureFactors = Landsat::getTemperatureConstants(pMetadata, type, K1, K2); bool shouldDefaultImportTemperature = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Temperature") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size() && haveTemperatureFactors) { //we have enough to create temperature import descriptor RasterDataDescriptor* pTemperatureDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-temperature", NULL)); if (pTemperatureDescriptor != NULL) { pTemperatureDescriptor->setDataType(FLT4BYTES); pTemperatureDescriptor->setValidDataTypes( std::vector<EncodingType>(1, pTemperatureDescriptor->getDataType())); pTemperatureDescriptor->setBadValues(std::vector<int>(1, -1)); FactoryResource<Units> pUnits; pUnits->setUnitType(EMISSIVITY); pUnits->setUnitName("K"); pUnits->setScaleFromStandard(1.0); pTemperatureDescriptor->setUnits(pUnits.get()); FileDescriptor* pTemperatureFileDescriptor = pTemperatureDescriptor->getFileDescriptor(); if (pTemperatureFileDescriptor != NULL) { pTemperatureFileDescriptor->setDatasetLocation(suffix + "-temperature"); ImportDescriptorResource pTemperatureImportDescriptor(pTemperatureDescriptor, shouldDefaultImportTemperature); descriptors.push_back(pTemperatureImportDescriptor.release()); } } } else if (shouldDefaultImportTemperature) { fallbackToDn = true; } if (fallbackToDn || std::find(defaultImport.begin(), defaultImport.end(), suffix + "-DN") != defaultImport.end()) { pImportDescriptor->setImported(true); } return descriptors; }
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; }