From 9491b0c044288f523b1cc28ef76259c942b84e40 Mon Sep 17 00:00:00 2001 From: aramis_acg Date: Fri, 22 Apr 2011 12:21:49 +0000 Subject: [PATCH] # 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 --- tools/assimp_cmd/CompareDump.cpp | 6 +- tools/assimp_cmd/WriteDumb.cpp | 193 ++++++++++++++++++------------- 2 files changed, 115 insertions(+), 84 deletions(-) diff --git a/tools/assimp_cmd/CompareDump.cpp b/tools/assimp_cmd/CompareDump.cpp index bf3b1cea9..9c997ca5f 100644 --- a/tools/assimp_cmd/CompareDump.cpp +++ b/tools/assimp_cmd/CompareDump.cpp @@ -642,9 +642,9 @@ void CompareOnTheFlyNodeAnim(comparer_context& comp) { comp.cmp("mPreState"); comp.cmp("mPostState"); - comp.cmp_bounds("mPositionKeys"); - comp.cmp_bounds("mRotationKeys"); - comp.cmp_bounds("mScalingKeys"); + comp.cmp_bounds("mPositionKeys"); + comp.cmp_bounds("mRotationKeys"); + comp.cmp_bounds("mScalingKeys"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tools/assimp_cmd/WriteDumb.cpp b/tools/assimp_cmd/WriteDumb.cpp index b87220939..aa5b321dc 100644 --- a/tools/assimp_cmd/WriteDumb.cpp +++ b/tools/assimp_cmd/WriteDumb.cpp @@ -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 uint32_t Write(const T&) {}; + // ----------------------------------------------------------------------------------- // Serialize an aiString -inline uint32_t WriteAiString(const aiString& s) +template <> +inline uint32_t Write(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(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(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(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(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(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(const aiMatrix4x4& m) { for (unsigned int i = 0; i < 4;++i) { for (unsigned int i2 = 0; i2 < 4;++i2) { - WriteFloat(m[i][i2]); + Write(m[i][i2]); } } return 64; } +// ----------------------------------------------------------------------------------- +// Serialize an aiVectorKey +template <> +inline uint32_t Write(const aiVectorKey& v) +{ + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiQuatKey +template <> +inline uint32_t Write(const aiQuatKey& v) +{ + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); +} + // ----------------------------------------------------------------------------------- // Write the min/max values of an array of Ts to the file template @@ -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(minc); + return t + Write(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(node->mName); + len += Write(node->mTransformation); + len += Write(node->mNumChildren); + len += Write(node->mNumMeshes); for (unsigned int i = 0; i < node->mNumMeshes;++i) { - len += WriteInteger(node->mMeshes[i]); + len += Write(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(tex->mWidth); + len += Write(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(b->mName); + len += Write(b->mNumWeights); + len += Write(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(mesh->mPrimitiveTypes); + len += Write(mesh->mNumVertices); + len += Write(mesh->mNumFaces); + len += Write(mesh->mNumBones); + len += Write(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(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(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(hash); } } else // else write as usual @@ -363,12 +394,12 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh) return -1; } - len += WriteShort(f.mNumIndices); + len += Write(f.mNumIndices); for (unsigned int a = 0; a < f.mNumIndices;++a) { if (mesh->mNumVertices < (1u<<16)) { - len += WriteShort(f.mIndices[a]); + len += Write(f.mIndices[a]); } - else len += WriteInteger(f.mIndices[a]); + else len += Write(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(prop->mKey); + len += Write(prop->mSemantic); + len += Write(prop->mIndex); - len += WriteInteger(prop->mDataLength); - len += WriteInteger((unsigned int)prop->mType); + len += Write(prop->mDataLength); + len += Write((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(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(nd->mNodeName); + len += Write(nd->mNumPositionKeys); + len += Write(nd->mNumRotationKeys); + len += Write(nd->mNumScalingKeys); + len += Write(nd->mPreState); + len += Write(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 (anim->mName); + len += Write (anim->mDuration); + len += Write (anim->mTicksPerSecond); + len += Write(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(l->mName); + len += Write(l->mType); if (l->mType != aiLightSource_DIRECTIONAL) { - len += WriteFloat(l->mAttenuationConstant); - len += WriteFloat(l->mAttenuationLinear); - len += WriteFloat(l->mAttenuationQuadratic); + len += Write(l->mAttenuationConstant); + len += Write(l->mAttenuationLinear); + len += Write(l->mAttenuationQuadratic); } - len += WriteVec3((const aiVector3D&)l->mColorDiffuse); - len += WriteVec3((const aiVector3D&)l->mColorSpecular); - len += WriteVec3((const aiVector3D&)l->mColorAmbient); + len += Write((const aiVector3D&)l->mColorDiffuse); + len += Write((const aiVector3D&)l->mColorSpecular); + len += Write((const aiVector3D&)l->mColorAmbient); if (l->mType == aiLightSource_SPOT) { - len += WriteFloat(l->mAngleInnerCone); - len += WriteFloat(l->mAngleOuterCone); + len += Write(l->mAngleInnerCone); + len += Write(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(cam->mName); + len += Write(cam->mPosition); + len += Write(cam->mLookAt); + len += Write(cam->mUp); + len += Write(cam->mHorizontalFOV); + len += Write(cam->mClipPlaneNear); + len += Write(cam->mClipPlaneFar); + len += Write(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(scene->mFlags); + len += Write(scene->mNumMeshes); + len += Write(scene->mNumMaterials); + len += Write(scene->mNumAnimations); + len += Write(scene->mNumTextures); + len += Write(scene->mNumLights); + len += Write(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(ASSBIN_VERSION_MAJOR); + Write(ASSBIN_VERSION_MINOR); + Write(aiGetVersionRevision()); + Write(aiGetCompileFlags()); + Write(shortened); + Write(compressed); // == 20 bytes char buff[256];