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();
}