Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
    // First make sure we are reading the correct object
    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
        rsc->setError(RS_ERROR_FATAL_DRIVER,
                      "allocation loading failed due to corrupt file. (invalid id)\n");
        return nullptr;
    }

    const char *name = stream->loadString();

    Type *type = Type::createFromStream(rsc, stream);
    if (!type) {
        return nullptr;
    }
    type->compute();

    Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
    type->decUserRef();

    // Number of bytes we wrote out for this allocation
    uint32_t dataSize = stream->loadU32();
    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
    uint32_t packedSize = alloc->getPackedSize();
    if (dataSize != type->getPackedSizeBytes() &&
        dataSize != packedSize) {
        rsc->setError(RS_ERROR_FATAL_DRIVER,
                      "allocation loading failed due to corrupt file. (invalid size)\n");
        ObjectBase::checkDelete(alloc);
        ObjectBase::checkDelete(type);
        return nullptr;
    }

    alloc->assignName(name);
    if (dataSize == type->getPackedSizeBytes()) {
        uint32_t count = dataSize / type->getElementSizeBytes();
        // Read in all of our allocation data
        alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
    } else {
        alloc->unpackVec3Allocation(rsc, stream->getPtr() + stream->getPos(), dataSize);
    }
    stream->reset(stream->getPos() + dataSize);

    return alloc;
}