Пример #1
0
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);
    }
}
Пример #2
0
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;
}
Пример #3
0
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;
}