void MPVMVolumeReader::printMetaInfo(MetaDataOwner* metaDataOwner, std::string key) { StringMetaData* metaData = metaDataOwner->getMetaData<StringMetaData>(key); if (metaData) { std::string metaStr = metaData->get(); replaceInString(metaStr, "\n", ", "); key[0] = static_cast<char>(toupper(key[0])); LogInfo(key << ": " << metaStr); } }
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; }
void PVMVolumeWriter::writeData(const Volume *data, const std::string filePath) const { if (filesystem::fileExists(filePath) && !overwrite_) throw DataWriterException("Error: Output file: " + filePath + " already exists", IvwContext); const DataFormatBase *format = data->getDataFormat(); int components = 0; #include <warn/push> #include <warn/ignore/switch-enum> switch (format->getId()) { case inviwo::DataFormatId::UInt8: components = 1; break; case inviwo::DataFormatId::UInt16: components = 2; break; default: break; } #include <warn/pop> if (components == 0) throw DataWriterException("Error: Output format " + std::string(format->getString()) + " not support by PVM writer", IvwContext); const VolumeRAM *vr = data->getRepresentation<VolumeRAM>(); const unsigned char *dataPtr = (const unsigned char *)vr->getData(); size3_t dim = vr->getDimensions(); vec3 spacing(1.f); mat3 basis = data->getBasis(); spacing.x = basis[0][0] / dim.x; spacing.y = basis[1][1] / dim.y; spacing.z = basis[2][2] / dim.z; unsigned char *data2Ptr = nullptr; if (components == 2) { size_t size = dim.x * dim.y * dim.z; data2Ptr = new unsigned char[size * components]; size_t bytes = format->getSize(); memcpy(data2Ptr, dataPtr, size * bytes); swapbytes(data2Ptr, static_cast<unsigned int>(size * bytes)); dataPtr = (const unsigned char *)data2Ptr; } unsigned char *description = nullptr; StringMetaData *descMetaData = data->getMetaData<StringMetaData>("description"); if (descMetaData) { description = new unsigned char[descMetaData->get().size() + 1]; strncpy((char *)description, descMetaData->get().c_str(), descMetaData->get().size()); description[descMetaData->get().size()] = '\0'; } unsigned char *courtesy = nullptr; StringMetaData *courMetaData = data->getMetaData<StringMetaData>("courtesy"); if (courMetaData) { courtesy = new unsigned char[courMetaData->get().size() + 1]; strncpy((char *)courtesy, courMetaData->get().c_str(), courMetaData->get().size()); courtesy[courMetaData->get().size()] = '\0'; } unsigned char *parameter = nullptr; StringMetaData *paraMetaData = data->getMetaData<StringMetaData>("parameter"); if (paraMetaData) { parameter = new unsigned char[paraMetaData->get().size() + 1]; strncpy((char *)parameter, paraMetaData->get().c_str(), paraMetaData->get().size()); parameter[paraMetaData->get().size()] = '\0'; } unsigned char *comment = nullptr; StringMetaData *commMetaData = data->getMetaData<StringMetaData>("comment"); if (commMetaData) { comment = new unsigned char[commMetaData->get().size() + 1]; strncpy((char *)comment, commMetaData->get().c_str(), commMetaData->get().size()); comment[commMetaData->get().size()] = '\0'; } writePVMvolume(filePath.c_str(), dataPtr, static_cast<unsigned int>(dim.x), static_cast<unsigned int>(dim.y), static_cast<unsigned int>(dim.z), components, spacing.x, spacing.y, spacing.z, description, courtesy, parameter, comment); delete[] data2Ptr; delete[] description; delete[] courtesy; delete[] parameter; delete[] comment; }