HalfFloatGridSource::HalfFloatGridSource(const String &serializedVolumeFile, const bool trilinearValue, const bool trilinearGradient, const bool sobelGradient) :
    GridSource(trilinearValue, trilinearGradient, sobelGradient)
{

    Timer t;
    DataStreamPtr streamRead = Root::getSingleton().openFileStream(serializedVolumeFile);
#if OGRE_NO_ZIP_ARCHIVE == 0
    DataStreamPtr uncompressStream(OGRE_NEW DeflateStream(serializedVolumeFile, streamRead));
    StreamSerialiser ser(uncompressStream);
#else
    StreamSerialiser ser(streamRead);
#endif
    if (!ser.readChunkBegin(VOLUME_CHUNK_ID, VOLUME_CHUNK_VERSION))
    {
        OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
                    "Invalid volume file given!",
                    __FUNCTION__);
    }

    // Read header
    Vector3 readFrom, readTo;
    ser.read(&readFrom);
    ser.read(&readTo);
    float voxelWidth;
    ser.read<float>(&voxelWidth);
    size_t width, height, depth;
    ser.read<size_t>(&width);
    ser.read<size_t>(&height);
    ser.read<size_t>(&depth);
    mWidth = static_cast<int>(width);
    mHeight = static_cast<int>(height);
    mDepth = static_cast<int>(depth);
    mDepthTimesHeight = static_cast<int>(mDepth * mHeight);

    Vector3 worldDimension = readTo - readFrom;
    mPosXScale = (Real)1.0 / (Real)worldDimension.x * (Real)mWidth;
    mPosYScale = (Real)1.0 / (Real)worldDimension.y * (Real)mHeight;
    mPosZScale = (Real)1.0 / (Real)worldDimension.z * (Real)mDepth;

    mVolumeSpaceToWorldSpaceFactor = (Real)worldDimension.x * (Real)mWidth;
    mMaxClampedAbsoluteDensity = 0;

    // Read data
    size_t elementCount = mWidth * mHeight * mDepth;
    mData = OGRE_ALLOC_T(uint16, elementCount, MEMCATEGORY_GENERAL);
    ser.read(mData, elementCount);

    ser.readChunkEnd(VOLUME_CHUNK_ID);

    LogManager::getSingleton().stream() << "Processed serialization in " << t.getMilliseconds() << "ms.";
}
void spec_uncompress(int in, int out, int lev) {
    blockSize100k           = 0;
    uncompressStream( in, out );
}