VolumeCollection* RawVoxVolumeReader::read(const std::string &url) throw (tgt::CorruptedFileException, tgt::IOException, std::bad_alloc) { VolumeURL origin(url); std::string fileName = origin.getPath(); LINFO("Reading file " << fileName); std::fstream fin(fileName.c_str(), std::ios::in | std::ios::binary); if (!fin.good()) throw tgt::IOException(); RawVoxHeader header; fin.read(reinterpret_cast<char*>(&header), sizeof(header)); svec3 dimensions = svec3(header.sizeX_, header.sizeY_, header.sizeZ_); if(header.magic_ != 1381388120) { throw tgt::CorruptedFileException("Wrong magic number."); } VolumeRAM* dataset; switch(header.bitsPerVoxel_) { case 8: LINFO("Reading 8 bit dataset"); dataset = new VolumeRAM_UInt8(dimensions); break; case 16: LINFO("Reading 16 bit dataset"); dataset = new VolumeRAM_UInt16(dimensions); break; case 32: LINFO("Reading 32 bit (float) dataset"); dataset = new VolumeRAM_Float(dimensions); break; default: LERROR("Unknown bpp!"); throw tgt::UnsupportedFormatException("Unexpected bpp."); } fin.read(reinterpret_cast<char*>(dataset->getData()), dataset->getNumBytes()); if ( fin.eof() ) { delete dataset; throw tgt::CorruptedFileException(); } fin.close(); VolumeCollection* volumeCollection = new VolumeCollection(); Volume* volumeHandle = new Volume(dataset, vec3(1.0f), vec3(0.0f)); oldVolumePosition(volumeHandle); volumeHandle->setOrigin(fileName); volumeCollection->add(volumeHandle); return volumeCollection; }
void VolumeSeriesSource::loadStep() { if(!volume_) return; VolumeRAM* v = volume_->getWritableRepresentation<VolumeRAM>(); if (!v) return; int step = step_.get(); std::string filename; if (files_.size() > 0 && step < static_cast<int>(files_.size())) filename = files_[step]; else return; std::ifstream f(filename.c_str(), std::ios_base::binary); if (!f) { LERROR("Could not open file: " << filename); return; } // read the volume as a raw blob, should be fast LINFO("Loading raw file " << filename); f.read(reinterpret_cast<char*>(v->getData()), v->getNumBytes()); if (!f.good()) { LERROR("Reading from file failed: " << filename); return; } // Special handling for float volumes: normalize values to [0.0; 1.0] VolumeRAM_Float* vf = dynamic_cast<VolumeRAM_Float*>(v); if (vf && spreadMin_ != spreadMax_) { const size_t n = vf->getNumVoxels(); // use spread values if available if (spreadMin_ != spreadMax_) { const float d = spreadMax_ - spreadMin_; float* voxel = vf->voxel(); for (size_t i = 0; i < n; ++i) voxel[i] = (voxel[i] - spreadMin_) / d; } else { LINFO("Normalizing float data to [0.0; 1.0]. " << "This might not be what you want, better define 'Spread: <min> <max>' in the .sdat file."); const float d = vf->max() - vf->min(); const float p = vf->min(); float* voxel = vf->voxel(); for (size_t i = 0; i < n; ++i) voxel[i] = (voxel[i] - p) / d; } vf->invalidate(); } needUpload_ = true; invalidate(); }
void VolumeGL2RAMConverter::update(const DataRepresentation* source, DataRepresentation* destination) { const VolumeGL* volumeSrc = static_cast<const VolumeGL*>(source); VolumeRAM* volumeDst = static_cast<VolumeRAM*>(destination); if (volumeSrc->getDimensions() != volumeDst->getDimensions()) { volumeDst->setDimensions(volumeSrc->getDimensions()); } volumeSrc->getTexture()->download(volumeDst->getData()); if (volumeDst->hasHistograms()) volumeDst->getHistograms()->setValid(false); }
DataRepresentation* VolumeGL2RAMConverter::createFrom(const DataRepresentation* source) { const VolumeGL* volumeGL = static_cast<const VolumeGL*>(source); VolumeRAM* volume = createVolumeRAM(volumeGL->getDimensions(), volumeGL->getDataFormat()); if (volume) { volumeGL->getTexture()->download(volume->getData()); return volume; } else { LogError("Cannot convert format from GL to RAM:" << volumeGL->getDataFormat()->getString()); } return nullptr; }
DataRepresentation* VolumeCL2RAMConverter::createFrom(const DataRepresentation* source) { DataRepresentation* destination = 0; const VolumeCL* volumeCL = static_cast<const VolumeCL*>(source); size3_t dimensions = volumeCL->getDimensions(); destination = createVolumeRAM(dimensions, volumeCL->getDataFormat()); if (destination) { VolumeRAM* volumeRAM = static_cast<VolumeRAM*>(destination); volumeCL->download(volumeRAM->getData()); //const cl::CommandQueue& queue = OpenCL::getInstance()->getQueue(); //queue.enqueueReadImage(volumeCL->getVolume(), true, glm::size3_t(0), glm::size3_t(dimension), 0, 0, volumeRAM->getData()); } return destination; }
Volume* MPVMVolumeReader::readMetaData(std::string filePath) { if (!filesystem::fileExists(filePath)) { std::string newPath = filesystem::addBasePath(filePath); if (filesystem::fileExists(newPath)) { filePath = newPath; } else { throw DataReaderException("Error could not find input file: " + filePath, IvwContext); } } std::string fileDirectory = filesystem::getFileDirectory(filePath); // Read the mpvm file content std::istream* f = new std::ifstream(filePath.c_str()); std::string textLine; std::vector<std::string> files; while (!f->eof()) { getline(*f, textLine); textLine = trim(textLine); files.push_back(textLine); }; delete f; if (files.empty()) throw DataReaderException("Error: No PVM files found in " + filePath, IvwContext); if (files.size() > 4) throw DataReaderException("Error: Maximum 4 pvm files are supported, file: " + filePath, IvwContext); // Read all pvm volumes std::vector<Volume*> volumes; for (size_t i = 0; i < files.size(); i++) { Volume* newVol = PVMVolumeReader::readPVMData(fileDirectory + files[i]); if (newVol) volumes.push_back(newVol); else LogWarn("Could not load " << fileDirectory << files[i]); } if (volumes.empty()) throw DataReaderException("No PVM volumes could be read from file: " + filePath, IvwContext); if (volumes.size() == 1) { printPVMMeta(volumes[0], fileDirectory + files[0]); return volumes[0]; } // Make sure dimension and format match const DataFormatBase* format = volumes[0]->getDataFormat(); size3_t mdim = volumes[0]->getDimensions(); for (size_t i = 1; i < volumes.size(); i++) { if (format != volumes[i]->getDataFormat() || mdim != volumes[i]->getDimensions()) { LogWarn("PVM volumes did not have the same format or dimensions, using first volume."); printPVMMeta(volumes[0], fileDirectory + files[0]); return volumes[0]; } } // Create new format const DataFormatBase* mformat = DataFormatBase::get(format->getNumericType(), volumes.size(), format->getSize()*8); // Create new volume Volume* volume = new Volume(); glm::mat3 basis = volumes[0]->getBasis(); volume->setBasis(basis); volume->setOffset(-0.5f * (basis[0] + basis[1] + basis[2])); volume->setDimensions(mdim); volume->dataMap_.initWithFormat(mformat); volume->setDataFormat(mformat); volume->copyMetaDataFrom(*volumes[0]); // Merge descriptions but ignore the rest StringMetaData* metaData = volume->getMetaData<StringMetaData>("description"); if (metaData) { std::string descStr = metaData->get(); for (size_t i = 1; i < volumes.size(); i++) { metaData = volumes[0]->getMetaData<StringMetaData>("description"); if (metaData) descStr = descStr + ", " + metaData->get(); } volume->setMetaData<StringMetaData>("description", descStr); } // Create RAM volume VolumeRAM* mvolRAM = createVolumeRAM(mdim, mformat); unsigned char* dataPtr = static_cast<unsigned char*>(mvolRAM->getData()); std::vector<const unsigned char*> volumesDataPtr; for (size_t i = 0; i < volumes.size(); i++) { volumesDataPtr.push_back(static_cast<const unsigned char*>( volumes[i]->getRepresentation<VolumeRAM>()->getData())); } // Copy the data from the other volumes to the new multichannel volume size_t mbytes = mformat->getSize(); size_t bytes = format->getSize(); size_t dims = mdim.x * mdim.y * mdim.z; size_t vsize = volumesDataPtr.size(); for (size_t i = 0; i < dims; i++) { for (size_t j = 0; j < vsize; j++) { for (size_t b = 0; b < bytes; b++) { dataPtr[i * mbytes + (j * bytes) + b] = volumesDataPtr[j][i * bytes + b]; } } } // Delete the single channel volumes for (size_t i = 0; i < volumes.size(); i++) { delete volumes[i]; } volume->addRepresentation(mvolRAM); printPVMMeta(volume, filePath); return volume; }
VolumeRAM* VolumeDiskRaw::loadBrick(const tgt::svec3& pOffset, const tgt::svec3& pDimensions) const throw (tgt::Exception) { //check for wrong parameter if(tgt::hmul(pDimensions) == 0) throw std::invalid_argument("requested brick dimensions are zero!"); if(!tgt::hand(tgt::lessThanEqual(pOffset+pDimensions,getDimensions()))) throw std::invalid_argument("requested brick outside volume date!"); //create new VolumeRam VolumeFactory vf; VolumeRAM* vr = vf.create(getFormat(), pDimensions); if (!vr) throw VoreenException("Failed to create VolumeRAM"); //open file FILE* fin; fin = fopen(getFileName().c_str(),"rb"); if (!fin) throw tgt::FileException("Failed to open file for reading: " + getFileName()); size_t bytesPerVoxel = static_cast<size_t>(vr->getBitsAllocated() / 8); size_t numVoxels = pDimensions.x; size_t numBytes = numVoxels * bytesPerVoxel; int64_t offset = getOffset(); if(offset < 0) { //Assume data is aligned to end of file. // get file size: fseek(fin, 0, SEEK_END); int64_t fileSize = ftell(fin); rewind(fin); //calculate real offset: offset = fileSize - hmul(getDimensions())*bytesPerVoxel; } //modify offset to start at first slice offset += getDimensions().x*getDimensions().y*pOffset.z*bytesPerVoxel; fseek(fin, static_cast<long>(offset), SEEK_SET); //read into ram size_t pointerOffset = 0; for(size_t z = 0; z < pDimensions.z; z++){ for(size_t y = 0; y < pDimensions.y; y++) { //read into ram if(fread(reinterpret_cast<char*>(vr->getData())+pointerOffset, numBytes, 1, fin) != 1) { fclose(fin); delete vr; throw tgt::FileException("Failed to read from file: " + getFileName()); } //move offset pointerOffset += numBytes; //move to next read if(y < pDimensions.y) fseek(fin, static_cast<long>(getDimensions().x-pDimensions.x),SEEK_SET); } //move to next read if(z < pDimensions.z) fseek(fin,static_cast<long>((getDimensions().x*getDimensions().y)-(pDimensions.x*pDimensions.y)),SEEK_SET); } fclose(fin); //swap endian if(getSwapEndian()) { Volume* tempHandle = new Volume(vr, vec3(1.0f), vec3(0.0f)); VolumeOperatorSwapEndianness::APPLY_OP(tempHandle); tempHandle->releaseAllRepresentations(); delete tempHandle; } return vr; }
VolumeRAM* VolumeDiskRaw::loadSlices(const size_t firstSlice, const size_t lastSlice) const throw (tgt::Exception) { //check for wrong parameter if(getDimensions().z <= lastSlice) throw std::invalid_argument("lastSlice is out of volume dimension!!!"); if(firstSlice > lastSlice) throw std::invalid_argument("firstSlice has to be less or equal lastSlice!!!"); //create new VolumeRam VolumeFactory vf; VolumeRAM* vr = vf.create(getFormat(), tgt::svec3(getDimensions().x,getDimensions().y, lastSlice-firstSlice+1)); if (!vr) throw VoreenException("Failed to create VolumeRAM"); //open file std::ifstream infile(getFileName().c_str(), std::ios::in | std::ios::binary); if (infile.fail()) throw tgt::FileException("Failed to open file for reading: " + getFileName()); size_t bytesPerVoxel = static_cast<size_t>(vr->getBitsAllocated() / 8); size_t numVoxels = getDimensions().x*getDimensions().y*(lastSlice-firstSlice+1); size_t numBytes = numVoxels * bytesPerVoxel; int64_t offset = getOffset(); if(offset < 0) { //Assume data is aligned to end of file. // get file size: infile.seekg( 0, infile.end); std::streampos fileSize = infile.tellg(); infile.seekg( 0, infile.beg); //calculate real offset: offset = static_cast<std::string::size_type>(fileSize) - hmul(getDimensions())*bytesPerVoxel; } //modify offset to start at first slice offset += getDimensions().x*getDimensions().y*firstSlice*bytesPerVoxel; infile.seekg(offset); //read into ram infile.read(reinterpret_cast<char*>(vr->getData()),numBytes); if (infile.fail()) { //LERRORC("voreen.RepresentationConverterLoadFromDisk", "read() failed"); infile.close(); delete vr; throw tgt::FileException("Failed to read from file: " + getFileName()); } infile.close(); //swap endian if(getSwapEndian()) { Volume* tempHandle = new Volume(vr, vec3(1.0f), vec3(0.0f)); VolumeOperatorSwapEndianness::APPLY_OP(tempHandle); tempHandle->releaseAllRepresentations(); delete tempHandle; } return vr; }
VolumeRAM* VolumeDiskRaw::loadVolume() const throw (tgt::Exception) { VolumeRAM* volume = 0; LDEBUG("Creating volume from diskrepr. " << getFileName() << " format: " << getFormat()); VolumeFactory vf; try { volume = vf.create(getFormat(), getDimensions()); } catch (std::bad_alloc&) { throw tgt::Exception("bad allocation"); } if (!volume) throw VoreenException("Failed to create VolumeRAM"); FILE* fin; fin = fopen(getFileName().c_str(),"rb"); if (fin == 0) { throw tgt::IOException("Unable to open raw file for reading", getFileName()); } size_t bytesPerVoxel = static_cast<size_t>(volume->getBitsAllocated() / 8); size_t numVoxels = hmul(getDimensions()); size_t numBytes = numVoxels * bytesPerVoxel; int64_t offset = getOffset(); if(offset < 0) { //Assume data is aligned to end of file. // get file size: fseek(fin, 0, SEEK_END); int64_t fileSize = ftell(fin); rewind(fin); //calculate real offset: offset = fileSize - numBytes; } #ifdef _MSC_VER _fseeki64(fin, offset, SEEK_SET); #else fseek(fin, offset, SEEK_SET); #endif if(fread(reinterpret_cast<char*>(volume->getData()), numBytes, 1, fin) != 1) { //LERRORC("voreen.RepresentationConverterLoadFromDisk", "fread() failed"); fclose(fin); delete volume; throw tgt::FileException("Failed to read from file: " + getFileName()); } fclose(fin); if (getSwapEndian()) { Volume* tempHandle = new Volume(volume, vec3(1.0f), vec3(0.0f)); VolumeOperatorSwapEndianness::APPLY_OP(tempHandle); tempHandle->releaseAllRepresentations(); delete tempHandle; } return volume; }
VolumeRepresentation* RepresentationConverterLoadFromDisk::convert(const VolumeRepresentation* source) const { const VolumeDisk* dr = dynamic_cast<const VolumeDisk*>(source); if(dr) { VolumeRAM* volume = 0; LDEBUGC("voreen.RepresentationConverterLoadFromDisk", "creating volume from diskrepr. " << dr->getFileName() << " format: " << dr->getFormat()); VolumeFactory vf; volume = vf.create(dr->getFormat(), dr->getDimensions()); if(!volume) return 0; FILE* fin; fin = fopen(dr->getFileName().c_str(),"rb"); if (fin == 0) throw tgt::IOException("Unable to open raw file for reading", dr->getFileName()); size_t bytesPerVoxel = static_cast<size_t>(volume->getBitsAllocated() / 8); size_t numVoxels = hmul(dr->getDimensions()); size_t numBytes = numVoxels * bytesPerVoxel; int64_t offset = dr->getOffset(); if(offset < 0) { //Assume data is aligned to end of file. // get file size: fseek(fin, 0, SEEK_END); int64_t fileSize = ftell(fin); rewind(fin); //calculate real offset: offset = fileSize - numBytes; } #ifdef _MSC_VER _fseeki64(fin, offset, SEEK_SET); #else fseek(fin, offset, SEEK_SET); #endif if(fread(reinterpret_cast<char*>(volume->getData()), numBytes, 1, fin) != 1) { LERRORC("voreen.RepresentationConverterLoadFromDisk", "fread() failed"); fclose(fin); delete volume; return 0; } fclose(fin); if(dr->getSwapEndian()) { Volume* tempHandle = new Volume(volume, vec3(1.0f), vec3(0.0f)); VolumeOperatorSwapEndianness::APPLY_OP(tempHandle); tempHandle->releaseAllRepresentations(); } return volume; } else { //should have checked before... //LERROR("Failed to convert!"); return 0; } }