From Paul Martz:

"These two files fix the alignment bug in the flt plugin header
parsing, which I posted about on Saturday. They go in the flt plugin
directory.

The fix is to memcpy the data read from the flt file into individual fields
in our Header struct, then replace the raw (packed) data block with our
header struct. This avoids the alignment problem entirely, and all fields
now contain valid data."
This commit is contained in:
Robert Osfield
2004-03-02 15:37:41 +00:00
parent 1b7b65389e
commit adcb6665d4
2 changed files with 112 additions and 7 deletions

View File

@@ -87,8 +87,100 @@ HeaderRecord::~HeaderRecord()
void HeaderRecord::endian()
{
SHeader *pHeader = (SHeader*)getData();
// OpenFlight spec dictates values that arepacked and not do not necessarily
// adhere to alignment rules. Copy values out of the OpenFlight packed header
// and into the SHeader struct and let the compiler worry about alignment
// issues within the struct.
SHeader *pHeader = (SHeader*) malloc( sizeof(SHeader) );
char* src = (char*)getData();
// Numeric constant data sizes taken from OpenFlight spec
memcpy( &(pHeader->RecHeader), src, 4 ); src += 4;
memcpy( &(pHeader->szIdent), src, 8 ); src += 8;
memcpy( &(pHeader->diFormatRevLev), src, 4 ); src += 4;
memcpy( &(pHeader->diDatabaseRevLev), src, 4 ); src += 4;
memcpy( &(pHeader->szDaTimLastRev), src, 32 ); src += 32;
memcpy( &(pHeader->iNextGroup), src, 2 ); src += 2;
memcpy( &(pHeader->iNextLOD), src, 2 ); src += 2;
memcpy( &(pHeader->iNextObject), src, 2 ); src += 2;
memcpy( &(pHeader->iNextPolygon), src, 2 ); src += 2;
memcpy( &(pHeader->iMultDivUnit), src, 2 ); src += 2;
memcpy( &(pHeader->swVertexCoordUnit), src, 1 ); src += 1;
memcpy( &(pHeader->swTexWhite), src, 1 ); src += 1;
memcpy( &(pHeader->dwFlags), src, 4 ); src += 4;
src += 4*6; // Reserved
memcpy( &(pHeader->diProjection), src, 4 ); src += 4;
src += 4*7; // Reserved
memcpy( &(pHeader->iNextDegOfFreedom), src, 2 ); src += 2;
memcpy( &(pHeader->iVertexStorage), src, 2 ); src += 2;
memcpy( &(pHeader->diDatabaseSource), src, 4 ); src += 4;
memcpy( &(pHeader->dfSWDatabaseCoordX), src, 8 ); src += 8;
memcpy( &(pHeader->dfSWDatabaseCoordY), src, 8 ); src += 8;
memcpy( &(pHeader->dfDatabaseOffsetX), src, 8 ); src += 8;
memcpy( &(pHeader->dfDatabaseOffsetY), src, 8 ); src += 8;
memcpy( &(pHeader->iNextSound), src, 2 ); src += 2;
memcpy( &(pHeader->iNextPath), src, 2 ); src += 2;
src += 4*2; // Reserved
memcpy( &(pHeader->iNextClippingRegion), src, 2 ); src += 2;
memcpy( &(pHeader->iNextText), src, 2 ); src += 2;
memcpy( &(pHeader->iNextBSP), src, 2 ); src += 2;
memcpy( &(pHeader->iNextSwitch), src, 2 ); src += 2;
src += 4; // reserved
memcpy( &(pHeader->SWCorner), src, 8*2 ); src += 8*2;
memcpy( &(pHeader->NECorner), src, 8*2 ); src += 8*2;
memcpy( &(pHeader->Origin), src, 8*2 ); src += 8*2;
memcpy( &(pHeader->dfLambertUpperLat), src, 8 ); src += 8;
memcpy( &(pHeader->dfLambertLowerLat), src, 8 ); src += 8;
memcpy( &(pHeader->iNextLightSource), src, 2 ); src += 2;
memcpy( &(pHeader->iNextLightPoint), src, 2 ); src += 2;
memcpy( &(pHeader->iNextRoad), src, 2 ); src += 2;
memcpy( &(pHeader->iNextCat), src, 2 ); src += 2;
src += 2*4; // Reserved;
memcpy( &(pHeader->diEllipsoid), src, 4 ); src += 4;
if ( pHeader->diFormatRevLev >= 1570 )
{
memcpy( &(pHeader->iNextAdaptiveNodeID), src, 2 ); src += 2;
memcpy( &(pHeader->iNextCurveNodeID), src, 2 ); src += 2;
if ( pHeader->diFormatRevLev >= 1580 )
{
// As of 2004/2/23, only adding 15.8 support to header parsing.
// Delete this comment when full support for 15.8 (1580) is added.
memcpy( &(pHeader->iUTMZone), src, 2 ); src += 2;
src += 6; // Reserved
}
else
// Must be v15.7
src += 2; // Reserved
memcpy( &(pHeader->dfDatabaseDeltaZ), src, 8 ); src += 8;
memcpy( &(pHeader->dfRadius), src, 8 ); src += 8;
memcpy( &(pHeader->iNextMeshNodeID), src, 2 ); src += 2;
if ( pHeader->diFormatRevLev >= 1580 )
{
// As of 2004/2/23, only adding 15.8 support to header parsing.
// Delete this comment when full support for 15.8 (1580) is added.
memcpy( &(pHeader->iNextLightPointSysID), src, 2 ); src += 2;
src += 4; // Reserved
memcpy( &(pHeader->dfEarthMajorAxis), src, 8 ); src += 8;
memcpy( &(pHeader->dfEarthMinorAxis), src, 8 ); src += 8;
}
else
// Must be v15.7
src += 2; // Reserved
}
// Now that we've copied the data into SHeader, we're done with the original packed
// data as read out of the OpenFlight file. Free it, and replace it with the
// SHeader struct, so that subsequent typecasts of _pData work as expected.
free( _pData );
_pData = (SRecHeader*)pHeader;
// Proceed with byteswapping
ENDIAN( pHeader->diFormatRevLev );
ENDIAN( pHeader->diDatabaseRevLev );
ENDIAN( pHeader->iNextGroup );
@@ -127,6 +219,16 @@ void HeaderRecord::endian()
ENDIAN( pHeader->dfDatabaseDeltaZ );
ENDIAN( pHeader->dfRadius );
ENDIAN( pHeader->iNextMeshNodeID );
if ( pHeader->diFormatRevLev >= 1580 )
{
// As of 2004/2/23, only adding 15.8 support to header parsing.
// Delete this comment when full support for 15.8 (1580) is added.
ENDIAN( pHeader->iUTMZone );
ENDIAN( pHeader->iNextLightPointSysID );
ENDIAN( pHeader->dfEarthMajorAxis );
ENDIAN( pHeader->dfEarthMinorAxis );
}
}
}

View File

@@ -59,22 +59,19 @@ struct SHeader
float64 dfDatabaseOffsetY;
int16 iNextSound; // Next Sound Bead Id
int16 iNextPath; // Next Path Bead ID
int32 diReserved_1[2]; // Reserved for MultiGen
int16 iNextClippingRegion;// Next Clipping Region Bead ID
int16 iNextText; // Next Text Bead ID
int16 iNextBSP; // Next BSP ID
int16 iNextSwitch; // Next Switch Bead ID
int32 diReserved_2; // Reserved
float64x2 SWCorner; // South West Corner Lat/Lon (NB: dec. degrees)
float64x2 NECorner; // North East Corner Lat/Lon (NB: dec. degrees)
float64x2 Origin; // Origin Lat/Lon (NB: dec. degrees, not radians)
float64 dfLambertUpperLat; // Lambert Upper Latitude
float64 dfLambertLowerLat; // Lambert Lower Latitude
int16 iNextLightSource; // Next Light Source ID Number
int16 iReserved_3; // Reserved
int16 iNextLightPoint; // Next Light Point ID number
int16 iNextRoad; // Next road bead ID number
int16 iNextCat; // Next CAT bead ID number
int16 iReserved_4[4]; // Reserved
int32 diEllipsoid; // Earth ellipsoid model
// 0 - WGS 1984
// 1 - WGS 1972
@@ -85,14 +82,20 @@ struct SHeader
// New with 15.7.0 ...
int16 iNextAdaptiveNodeID; // Next Adaptive node ID number
int16 iNextCurveNodeID; // Next Curve node ID number
int16 iReserved_5; // Reserved
float64 dfDatabaseDeltaZ; // Delta z to place database (used in
// conjunction with existing Delta x and
// Delta y values)
float64 dfRadius; // Radius (distance from database origin to
// farthest corner)
uint16 iNextMeshNodeID; // Next Mesh node ID number
uint16 iReserved_6; // Reserved
// New with 15.8
// As of 2004/2/23, only adding 15.8 support to header parsing.
// Delete this comment when full support for 15.8 (1580) is added.
int16 iUTMZone; // UTM zone 1-60, negative indicates southern hemisphere
uint16 iNextLightPointSysID; // Light point system ID
float64 dfEarthMajorAxis; // Custom ellipsoid Earth major axis
float64 dfEarthMinorAxis; // Custom ellipsoid Earth minor axis
};