# fix undefined behaviour in WriteDumb.cpp that would make our dumps include some padding bytes

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@955 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2011-04-22 12:21:49 +00:00
parent 724b562e6f
commit 9491b0c044
2 changed files with 115 additions and 84 deletions

View File

@ -642,9 +642,9 @@ void CompareOnTheFlyNodeAnim(comparer_context& comp) {
comp.cmp<uint32_t>("mPreState");
comp.cmp<uint32_t>("mPostState");
comp.cmp_bounds<aiVector3D>("mPositionKeys");
comp.cmp_bounds<aiVector3D>("mRotationKeys");
comp.cmp_bounds<aiVector3D>("mScalingKeys");
comp.cmp_bounds<aiVectorKey>("mPositionKeys");
comp.cmp_bounds<aiQuatKey>("mRotationKeys");
comp.cmp_bounds<aiVectorKey>("mScalingKeys");
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -105,9 +105,15 @@ inline uint32_t WriteMagic(uint32_t magic)
return ftell(out)-4;
}
// use template specializations rather than regular overloading to be able to
// explicitly select the right 'overload' to leave no doubts on what is called,
// retaining the possibility of letting the compiler select.
template <typename T> uint32_t Write(const T&) {};
// -----------------------------------------------------------------------------------
// Serialize an aiString
inline uint32_t WriteAiString(const aiString& s)
template <>
inline uint32_t Write<aiString>(const aiString& s)
{
const uint32_t s2 = (uint32_t)s.length;
fwrite(&s,4,1,out);
@ -117,7 +123,8 @@ inline uint32_t WriteAiString(const aiString& s)
// -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint32_t
inline uint32_t WriteInteger(unsigned int w)
template <>
inline uint32_t Write<unsigned int>(const unsigned int& w)
{
const uint32_t t = (uint32_t)w;
fwrite(&t,4,1,out);
@ -126,16 +133,17 @@ inline uint32_t WriteInteger(unsigned int w)
// -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint16_t
inline uint32_t WriteShort(unsigned int w)
template <>
inline uint32_t Write<uint16_t>(const uint16_t& w)
{
const uint16_t t = (uint16_t)w;
fwrite(&t,2,1,out);
fwrite(&w,2,1,out);
return 2;
}
// -----------------------------------------------------------------------------------
// Serialize a float
inline uint32_t WriteFloat(float f)
template <>
inline uint32_t Write<float>(const float& f)
{
fwrite(&f,4,1,out);
return 4;
@ -143,7 +151,8 @@ inline uint32_t WriteFloat(float f)
// -----------------------------------------------------------------------------------
// Serialize a double
inline uint32_t WriteDouble(double f)
template <>
inline uint32_t Write<double>(const double& f)
{
fwrite(&f,8,1,out);
return 8;
@ -151,7 +160,8 @@ inline uint32_t WriteDouble(double f)
// -----------------------------------------------------------------------------------
// Serialize a vec3
inline uint32_t WriteVec3(const aiVector3D& v)
template <>
inline uint32_t Write<aiVector3D>(const aiVector3D& v)
{
fwrite(&v,12,1,out);
return 12;
@ -159,16 +169,35 @@ inline uint32_t WriteVec3(const aiVector3D& v)
// -----------------------------------------------------------------------------------
// Serialize a mat4x4
inline uint32_t WriteMat4x4(const aiMatrix4x4& m)
template <>
inline uint32_t Write<aiMatrix4x4>(const aiMatrix4x4& m)
{
for (unsigned int i = 0; i < 4;++i) {
for (unsigned int i2 = 0; i2 < 4;++i2) {
WriteFloat(m[i][i2]);
Write<float>(m[i][i2]);
}
}
return 64;
}
// -----------------------------------------------------------------------------------
// Serialize an aiVectorKey
template <>
inline uint32_t Write<aiVectorKey>(const aiVectorKey& v)
{
const uint32_t t = Write<double>(v.mTime);
return t + Write<aiVector3D>(v.mValue);
}
// -----------------------------------------------------------------------------------
// Serialize an aiQuatKey
template <>
inline uint32_t Write<aiQuatKey>(const aiQuatKey& v)
{
const uint32_t t = Write<double>(v.mTime);
return t + Write<aiQuaternion>(v.mValue);
}
// -----------------------------------------------------------------------------------
// Write the min/max values of an array of Ts to the file
template <typename T>
@ -176,11 +205,13 @@ inline uint32_t WriteBounds(const T* in, unsigned int size)
{
T minc,maxc;
Assimp::ArrayBounds(in,size,minc,maxc);
fwrite(&minc,sizeof(T),1,out);
fwrite(&maxc,sizeof(T),1,out);
return sizeof(T)*2;
const uint32_t t = Write<T>(minc);
return t + Write<T>(maxc);
}
// -----------------------------------------------------------------------------------
void ChangeInteger(uint32_t ofs,uint32_t n)
{
@ -194,13 +225,13 @@ void ChangeInteger(uint32_t ofs,uint32_t n)
uint32_t WriteBinaryNode(const aiNode* node)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODE);
len += WriteAiString(node->mName);
len += WriteMat4x4(node->mTransformation);
len += WriteInteger(node->mNumChildren);
len += WriteInteger(node->mNumMeshes);
len += Write<aiString>(node->mName);
len += Write<aiMatrix4x4>(node->mTransformation);
len += Write<unsigned int>(node->mNumChildren);
len += Write<unsigned int>(node->mNumMeshes);
for (unsigned int i = 0; i < node->mNumMeshes;++i) {
len += WriteInteger(node->mMeshes[i]);
len += Write<unsigned int>(node->mMeshes[i]);
}
for (unsigned int i = 0; i < node->mNumChildren;++i) {
@ -216,8 +247,8 @@ uint32_t WriteBinaryTexture(const aiTexture* tex)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AITEXTURE);
len += WriteInteger(tex->mWidth);
len += WriteInteger(tex->mHeight);
len += Write<unsigned int>(tex->mWidth);
len += Write<unsigned int>(tex->mHeight);
len += fwrite(tex->achFormatHint,1,4,out);
if(!shortened) {
@ -238,9 +269,9 @@ uint32_t WriteBinaryBone(const aiBone* b)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIBONE);
len += WriteAiString(b->mName);
len += WriteInteger(b->mNumWeights);
len += WriteMat4x4(b->mOffsetMatrix);
len += Write<aiString>(b->mName);
len += Write<unsigned int>(b->mNumWeights);
len += Write<aiMatrix4x4>(b->mOffsetMatrix);
// for the moment we write dumb min/max values for the bones, too.
// maybe I'll add a better, hash-like solution later
@ -258,11 +289,11 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMESH);
len += WriteInteger(mesh->mPrimitiveTypes);
len += WriteInteger(mesh->mNumVertices);
len += WriteInteger(mesh->mNumFaces);
len += WriteInteger(mesh->mNumBones);
len += WriteInteger(mesh->mMaterialIndex);
len += Write<unsigned int>(mesh->mPrimitiveTypes);
len += Write<unsigned int>(mesh->mNumVertices);
len += Write<unsigned int>(mesh->mNumFaces);
len += Write<unsigned int>(mesh->mNumBones);
len += Write<unsigned int>(mesh->mMaterialIndex);
// first of all, write bits for all existent vertex components
unsigned int c = 0;
@ -287,7 +318,7 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
}
c |= ASSBIN_MESH_HAS_COLOR(n);
}
len += WriteInteger(c);
len += Write<unsigned int>(c);
aiVector3D minVec, maxVec;
if (mesh->mVertices) {
@ -326,7 +357,7 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
break;
// write number of UV components
len += WriteInteger(mesh->mNumUVComponents[n]);
len += Write<unsigned int>(mesh->mNumUVComponents[n]);
if (shortened) {
len += WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices);
@ -349,7 +380,7 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
hash = SuperFastHash((const char*)&f.mNumIndices,sizeof(unsigned int),hash);
hash = SuperFastHash((const char*) f.mIndices,f.mNumIndices*sizeof(unsigned int),hash);
}
len += WriteInteger(hash);
len += Write<unsigned int>(hash);
}
}
else // else write as usual
@ -363,12 +394,12 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
return -1;
}
len += WriteShort(f.mNumIndices);
len += Write<uint16_t>(f.mNumIndices);
for (unsigned int a = 0; a < f.mNumIndices;++a) {
if (mesh->mNumVertices < (1u<<16)) {
len += WriteShort(f.mIndices[a]);
len += Write<uint16_t>(f.mIndices[a]);
}
else len += WriteInteger(f.mIndices[a]);
else len += Write<unsigned int>(f.mIndices[a]);
}
}
}
@ -390,12 +421,12 @@ uint32_t WriteBinaryMaterialProperty(const aiMaterialProperty* prop)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIALPROPERTY);
len += WriteAiString(prop->mKey);
len += WriteInteger(prop->mSemantic);
len += WriteInteger(prop->mIndex);
len += Write<aiString>(prop->mKey);
len += Write<unsigned int>(prop->mSemantic);
len += Write<unsigned int>(prop->mIndex);
len += WriteInteger(prop->mDataLength);
len += WriteInteger((unsigned int)prop->mType);
len += Write<unsigned int>(prop->mDataLength);
len += Write<unsigned int>((unsigned int)prop->mType);
len += fwrite(prop->mData,1,prop->mDataLength,out);
ChangeInteger(old,len);
@ -407,7 +438,7 @@ uint32_t WriteBinaryMaterial(const aiMaterial* mat)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIAL);
len += WriteInteger(mat->mNumProperties);
len += Write<unsigned int>(mat->mNumProperties);
for (unsigned int i = 0; i < mat->mNumProperties;++i) {
len += WriteBinaryMaterialProperty(mat->mProperties[i])+8;
}
@ -421,12 +452,12 @@ uint32_t WriteBinaryNodeAnim(const aiNodeAnim* nd)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODEANIM);
len += WriteAiString(nd->mNodeName);
len += WriteInteger(nd->mNumPositionKeys);
len += WriteInteger(nd->mNumRotationKeys);
len += WriteInteger(nd->mNumScalingKeys);
len += WriteInteger(nd->mPreState);
len += WriteInteger(nd->mPostState);
len += Write<aiString>(nd->mNodeName);
len += Write<unsigned int>(nd->mNumPositionKeys);
len += Write<unsigned int>(nd->mNumRotationKeys);
len += Write<unsigned int>(nd->mNumScalingKeys);
len += Write<unsigned int>(nd->mPreState);
len += Write<unsigned int>(nd->mPostState);
if (nd->mPositionKeys) {
if (shortened) {
@ -460,10 +491,10 @@ uint32_t WriteBinaryAnim(const aiAnimation* anim)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIANIMATION);
len += WriteAiString (anim->mName);
len += WriteDouble (anim->mDuration);
len += WriteDouble (anim->mTicksPerSecond);
len += WriteInteger(anim->mNumChannels);
len += Write<aiString> (anim->mName);
len += Write<double> (anim->mDuration);
len += Write<double> (anim->mTicksPerSecond);
len += Write<unsigned int>(anim->mNumChannels);
for (unsigned int a = 0; a < anim->mNumChannels;++a) {
const aiNodeAnim* nd = anim->mChannels[a];
@ -479,22 +510,22 @@ uint32_t WriteBinaryLight(const aiLight* l)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AILIGHT);
len += WriteAiString(l->mName);
len += WriteInteger(l->mType);
len += Write<aiString>(l->mName);
len += Write<unsigned int>(l->mType);
if (l->mType != aiLightSource_DIRECTIONAL) {
len += WriteFloat(l->mAttenuationConstant);
len += WriteFloat(l->mAttenuationLinear);
len += WriteFloat(l->mAttenuationQuadratic);
len += Write<float>(l->mAttenuationConstant);
len += Write<float>(l->mAttenuationLinear);
len += Write<float>(l->mAttenuationQuadratic);
}
len += WriteVec3((const aiVector3D&)l->mColorDiffuse);
len += WriteVec3((const aiVector3D&)l->mColorSpecular);
len += WriteVec3((const aiVector3D&)l->mColorAmbient);
len += Write<aiVector3D>((const aiVector3D&)l->mColorDiffuse);
len += Write<aiVector3D>((const aiVector3D&)l->mColorSpecular);
len += Write<aiVector3D>((const aiVector3D&)l->mColorAmbient);
if (l->mType == aiLightSource_SPOT) {
len += WriteFloat(l->mAngleInnerCone);
len += WriteFloat(l->mAngleOuterCone);
len += Write<float>(l->mAngleInnerCone);
len += Write<float>(l->mAngleOuterCone);
}
ChangeInteger(old,len);
@ -506,14 +537,14 @@ uint32_t WriteBinaryCamera(const aiCamera* cam)
{
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AICAMERA);
len += WriteAiString(cam->mName);
len += WriteVec3(cam->mPosition);
len += WriteVec3(cam->mLookAt);
len += WriteVec3(cam->mUp);
len += WriteFloat(cam->mHorizontalFOV);
len += WriteFloat(cam->mClipPlaneNear);
len += WriteFloat(cam->mClipPlaneFar);
len += WriteFloat(cam->mAspect);
len += Write<aiString>(cam->mName);
len += Write<aiVector3D>(cam->mPosition);
len += Write<aiVector3D>(cam->mLookAt);
len += Write<aiVector3D>(cam->mUp);
len += Write<float>(cam->mHorizontalFOV);
len += Write<float>(cam->mClipPlaneNear);
len += Write<float>(cam->mClipPlaneFar);
len += Write<float>(cam->mAspect);
ChangeInteger(old,len);
return len;
@ -525,13 +556,13 @@ uint32_t WriteBinaryScene(const aiScene* scene)
uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AISCENE);
// basic scene information
len += WriteInteger(scene->mFlags);
len += WriteInteger(scene->mNumMeshes);
len += WriteInteger(scene->mNumMaterials);
len += WriteInteger(scene->mNumAnimations);
len += WriteInteger(scene->mNumTextures);
len += WriteInteger(scene->mNumLights);
len += WriteInteger(scene->mNumCameras);
len += Write<unsigned int>(scene->mFlags);
len += Write<unsigned int>(scene->mNumMeshes);
len += Write<unsigned int>(scene->mNumMaterials);
len += Write<unsigned int>(scene->mNumAnimations);
len += Write<unsigned int>(scene->mNumTextures);
len += Write<unsigned int>(scene->mNumLights);
len += Write<unsigned int>(scene->mNumCameras);
// write node graph
len += WriteBinaryNode(scene->mRootNode)+8;
@ -592,12 +623,12 @@ void WriteBinaryDump(const aiScene* scene, FILE* _out, const char* src, const ch
fprintf(out,"ASSIMP.binary-dump.%s",asctime(p));
// == 44 bytes
WriteInteger(ASSBIN_VERSION_MAJOR);
WriteInteger(ASSBIN_VERSION_MINOR);
WriteInteger(aiGetVersionRevision());
WriteInteger(aiGetCompileFlags());
WriteShort(shortened);
WriteShort(compressed);
Write<unsigned int>(ASSBIN_VERSION_MAJOR);
Write<unsigned int>(ASSBIN_VERSION_MINOR);
Write<unsigned int>(aiGetVersionRevision());
Write<unsigned int>(aiGetCompileFlags());
Write<uint16_t>(shortened);
Write<uint16_t>(compressed);
// == 20 bytes
char buff[256];