# 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>("mPreState");
comp.cmp<uint32_t>("mPostState"); comp.cmp<uint32_t>("mPostState");
comp.cmp_bounds<aiVector3D>("mPositionKeys"); comp.cmp_bounds<aiVectorKey>("mPositionKeys");
comp.cmp_bounds<aiVector3D>("mRotationKeys"); comp.cmp_bounds<aiQuatKey>("mRotationKeys");
comp.cmp_bounds<aiVector3D>("mScalingKeys"); comp.cmp_bounds<aiVectorKey>("mScalingKeys");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

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