Sync with perforce repository.

Several bugfixes in nvcore.
Add imgdiff to cmakefiles and fix compilation errors on linux.
This commit is contained in:
castano
2007-07-08 08:08:52 +00:00
parent 9fe9f6cc7a
commit cf1d93ebf4
11 changed files with 3154 additions and 2952 deletions

View File

@ -34,10 +34,10 @@ Do not use memmove in insert & remove, use copy ctors instead.
#define NV_FOREACH(i, container) \ #define NV_FOREACH(i, container) \
typedef typeof(container) NV_STRING_JOIN2(cont,__LINE__); \ typedef typeof(container) NV_STRING_JOIN2(cont,__LINE__); \
for(NV_STRING_JOIN2(cont,__LINE__)::PseudoIndex i((container).start()); (container).isDone(i); (container).advance(i)) for(NV_STRING_JOIN2(cont,__LINE__)::PseudoIndex i((container).start()); !(container).isDone(i); (container).advance(i))
/* /*
#define NV_FOREACH(i, container) \ #define NV_FOREACH(i, container) \
for(typename typeof(container)::PseudoIndex i((container).start()); (container).isDone(i); (container).advance(i)) for(typename typeof(container)::PseudoIndex i((container).start()); !(container).isDone(i); (container).advance(i))
*/ */
#else // If typeof not available: #else // If typeof not available:
@ -61,7 +61,7 @@ struct PseudoIndexWrapper {
}; };
#define NV_FOREACH(i, container) \ #define NV_FOREACH(i, container) \
for(PseudoIndexWrapper i(container); (container).isDone(i(&(container))); (container).advance(i(&(container)))) for(PseudoIndexWrapper i(container); !(container).isDone(i(&(container))); (container).advance(i(&(container))))
#endif #endif
@ -145,7 +145,7 @@ namespace nv
template <typename T> template <typename T>
void deleteAll(T & container) void deleteAll(T & container)
{ {
for(typename T::PseudoIndex i = container.start(); container.isDone(i); container.advance(i)) for(typename T::PseudoIndex i = container.start(); !container.isDone(i); container.advance(i))
{ {
delete container[i]; delete container[i];
} }
@ -272,15 +272,20 @@ namespace nv
/// Push an element at the end of the vector. /// Push an element at the end of the vector.
void push_back( const T & val ) void push_back( const T & val )
{ {
// DO NOT pass elements of your own vector into uint new_size = m_size + 1;
// push_back()! Since we're using references,
// resize() may munge the element storage!
nvDebugCheck( &val < &m_buffer[0] || &val > &m_buffer[m_size] );
int new_size = m_size + 1; if (new_size > m_buffer_size)
resize( new_size ); {
const T copy(val); // create a copy in case value is inside of this array.
resize(new_size);
m_buffer[new_size-1] = copy;
}
else
{
m_size = new_size;
m_buffer[new_size-1] = val; m_buffer[new_size-1] = val;
} }
}
void pushBack( const T & val ) void pushBack( const T & val )
{ {
push_back(val); push_back(val);
@ -364,7 +369,7 @@ namespace nv
/// Remove the first instance of the given element. /// Remove the first instance of the given element.
void remove(const T & element) void remove(const T & element)
{ {
for(PseudoIndex i = start(); isDone(i); advance(i)) { for(PseudoIndex i = start(); !isDone(i); advance(i)) {
removeAt(i); removeAt(i);
break; break;
} }
@ -560,8 +565,8 @@ namespace nv
typedef uint PseudoIndex; typedef uint PseudoIndex;
PseudoIndex start() const { return 0; } PseudoIndex start() const { return 0; }
bool isDone(const PseudoIndex & i) const { return i < this->m_size; }; bool isDone(const PseudoIndex & i) const { nvDebugCheck(i <= this->m_size); return i == this->m_size; };
void advance(PseudoIndex & i) const { i++; } void advance(PseudoIndex & i) const { nvDebugCheck(i <= this->m_size); i++; }
#if NV_CC_MSVC #if NV_CC_MSVC
T & operator[]( const PseudoIndexWrapper & i ) { T & operator[]( const PseudoIndexWrapper & i ) {
@ -642,7 +647,7 @@ namespace nv
~HashMap() { clear(); } ~HashMap() { clear(); }
/** Set a new or existing value under the key, to the value. */ /// Set a new or existing value under the key, to the value.
void set(const T& key, const U& value) void set(const T& key, const U& value)
{ {
int index = findIndex(key); int index = findIndex(key);
@ -657,7 +662,7 @@ namespace nv
} }
/** Add a new value to the hash table, under the specified key. */ /// Add a new value to the hash table, under the specified key.
void add(const T& key, const U& value) void add(const T& key, const U& value)
{ {
nvCheck(findIndex(key) == -1); nvCheck(findIndex(key) == -1);
@ -732,7 +737,7 @@ namespace nv
} }
/** Remove the first value under the specified key. */ /// Remove the first value under the specified key.
bool remove(const T& key) bool remove(const T& key)
{ {
if (table == NULL) if (table == NULL)
@ -767,7 +772,7 @@ namespace nv
} }
/** Remove all entries from the hash table. */ /// Remove all entries from the hash table.
void clear() void clear()
{ {
if (table != NULL) if (table != NULL)
@ -789,15 +794,14 @@ namespace nv
} }
/** Returns true if the hash is empty. */ /// Returns true if the hash is empty.
bool isEmpty() const bool isEmpty() const
{ {
return table == NULL || entry_count == 0; return table == NULL || entry_count == 0;
} }
/** /** Retrieve the value under the given key.
* Retrieve the value under the given key.
* *
* If there's no value under the key, then return false and leave * If there's no value under the key, then return false and leave
* *value alone. * *value alone.
@ -821,6 +825,7 @@ namespace nv
return false; return false;
} }
/// Determine if the given key is contained in the hash.
bool contains(const T & key) const bool contains(const T & key) const
{ {
return get(key); return get(key);
@ -856,7 +861,7 @@ namespace nv
} }
/** Hint the bucket count to >= n. */ /// Hint the bucket count to >= n.
void resize(int n) void resize(int n)
{ {
// Not really sure what this means in relation to // Not really sure what this means in relation to
@ -881,7 +886,7 @@ namespace nv
setRawCapacity(new_raw_size); setRawCapacity(new_raw_size);
} }
/** Behaves much like std::pair. */ /// Behaves much like std::pair.
struct Entry struct Entry
{ {
int next_in_chain; // internal chaining for collisions int next_in_chain; // internal chaining for collisions
@ -910,11 +915,11 @@ namespace nv
}; };
/** HashMap enumerator. */ // HashMap enumerator.
typedef int PseudoIndex; typedef int PseudoIndex;
PseudoIndex start() const { PseudoIndex i = 0; findNext(i); return i; } PseudoIndex start() const { PseudoIndex i = 0; findNext(i); return i; }
bool isDone(const PseudoIndex & i) const { return i <= size_mask; }; bool isDone(const PseudoIndex & i) const { nvDebugCheck(i <= size_mask+1); return i == size_mask+1; };
void advance(PseudoIndex & i) const { i++; findNext(i); } void advance(PseudoIndex & i) const { nvDebugCheck(i <= size_mask+1); i++; findNext(i); }
#if NV_CC_GNUC #if NV_CC_GNUC
Entry & operator[]( const PseudoIndex & i ) { Entry & operator[]( const PseudoIndex & i ) {
@ -936,7 +941,7 @@ namespace nv
private: private:
/** Find the index of the matching entry. If no match, then return -1. */ // Find the index of the matching entry. If no match, then return -1.
int findIndex(const T& key) const int findIndex(const T& key) const
{ {
if (table == NULL) return -1; if (table == NULL) return -1;
@ -1041,7 +1046,7 @@ namespace nv
new_hash.table = NULL; new_hash.table = NULL;
} }
/** Move the enumerator to the next valid element. */ // Move the enumerator to the next valid element.
void findNext(PseudoIndex & i) const { void findNext(PseudoIndex & i) const {
while (i <= size_mask && E(i).isEmpty()) { while (i <= size_mask && E(i).isEmpty()) {
i++; i++;

View File

@ -102,6 +102,18 @@ void nv::strCpy(char * dst, int size, const char * src)
#endif #endif
} }
void nv::strCpy(char * dst, int size, const char * src, int len)
{
nvDebugCheck(dst != NULL);
nvDebugCheck(src != NULL);
#if NV_CC_MSVC && _MSC_VER >= 1400
strncpy_s(dst, size, src, len);
#else
NV_UNUSED(size);
strncpy(dst, src, len);
#endif
}
void nv::strCat(char * dst, int size, const char * src) void nv::strCat(char * dst, int size, const char * src)
{ {
nvDebugCheck(dst != NULL); nvDebugCheck(dst != NULL);

View File

@ -32,6 +32,7 @@ namespace nv
NVCORE_API int strCaseCmp(const char * s1, const char * s2) NV_PURE; NVCORE_API int strCaseCmp(const char * s1, const char * s2) NV_PURE;
NVCORE_API int strCmp(const char * s1, const char * s2) NV_PURE; NVCORE_API int strCmp(const char * s1, const char * s2) NV_PURE;
NVCORE_API void strCpy(char * dst, int size, const char * src); NVCORE_API void strCpy(char * dst, int size, const char * src);
NVCORE_API void strCpy(char * dst, int size, const char * src, int len);
NVCORE_API void strCat(char * dst, int size, const char * src); NVCORE_API void strCat(char * dst, int size, const char * src);
NVCORE_API bool strMatch(const char * str, const char * pat) NV_PURE; NVCORE_API bool strMatch(const char * str, const char * pat) NV_PURE;
@ -327,7 +328,10 @@ namespace nv
setRefCount( 0 ); setRefCount( 0 );
// Copy string. // Copy string.
strCpy(const_cast<char *>(data), len + 1, str); strCpy(const_cast<char *>(data), len+1, str, len);
// Add terminating character.
const_cast<char *>(data)[len] = '\0';
} }
NVCORE_API void setString(const char * str); NVCORE_API void setString(const char * str);

View File

@ -27,12 +27,13 @@ char TextReader::read()
{ {
nvDebugCheck(m_stream != NULL); nvDebugCheck(m_stream != NULL);
char c;
m_stream->serialize(&c, 1);
if( m_stream->isAtEnd() ) { if( m_stream->isAtEnd() ) {
return 0; return 0;
} }
char c;
m_stream->serialize(&c, 1);
return c; return c;
} }

View File

@ -281,6 +281,7 @@ POSH_GetArchString( void )
/** /**
* Byte swaps a 16-bit unsigned value * Byte swaps a 16-bit unsigned value
* *
@ingroup ByteSwapFunctions
@param v [in] unsigned 16-bit input value to swap @param v [in] unsigned 16-bit input value to swap
@returns a byte swapped version of v @returns a byte swapped version of v
*/ */
@ -298,6 +299,7 @@ POSH_SwapU16( posh_u16_t v )
/** /**
* Byte swaps a 16-bit signed value * Byte swaps a 16-bit signed value
* *
@ingroup ByteSwapFunctions
@param v [in] signed 16-bit input value to swap @param v [in] signed 16-bit input value to swap
@returns a byte swapped version of v @returns a byte swapped version of v
@remarks This just calls back to the unsigned version, since byte swapping @remarks This just calls back to the unsigned version, since byte swapping
@ -313,6 +315,7 @@ POSH_SwapI16( posh_i16_t v )
/** /**
* Byte swaps a 32-bit unsigned value * Byte swaps a 32-bit unsigned value
* *
@ingroup ByteSwapFunctions
@param v [in] unsigned 32-bit input value to swap @param v [in] unsigned 32-bit input value to swap
@returns a byte swapped version of v @returns a byte swapped version of v
*/ */
@ -332,6 +335,7 @@ POSH_SwapU32( posh_u32_t v )
/** /**
* Byte swaps a 32-bit signed value * Byte swaps a 32-bit signed value
* *
@ingroup ByteSwapFunctions
@param v [in] signed 32-bit input value to swap @param v [in] signed 32-bit input value to swap
@returns a byte swapped version of v @returns a byte swapped version of v
@remarks This just calls back to the unsigned version, since byte swapping @remarks This just calls back to the unsigned version, since byte swapping
@ -393,7 +397,8 @@ POSH_SwapI64( posh_i64_t v )
/** /**
* Writes an unsigned 16-bit value to a little endian buffer * Writes an unsigned 16-bit value to a little endian buffer
@param dst [out] pointer to the destination buffer, may not be NULL @ingroup MemoryBuffer
@param dst [out] pointer to the destination buffer, may not be NULL. Alignment doesn't matter.
@param value [in] host-endian unsigned 16-bit value @param value [in] host-endian unsigned 16-bit value
@returns a pointer to the location two bytes after dst @returns a pointer to the location two bytes after dst
@remarks does no validation of the inputs @remarks does no validation of the inputs
@ -402,8 +407,10 @@ posh_u16_t *
POSH_WriteU16ToLittle( void *dst, posh_u16_t value ) POSH_WriteU16ToLittle( void *dst, posh_u16_t value )
{ {
posh_u16_t *p16 = ( posh_u16_t * ) dst; posh_u16_t *p16 = ( posh_u16_t * ) dst;
posh_byte_t *p = ( posh_byte_t * ) dst;
*p16 = POSH_LittleU16(value); p[ 0 ] = value & 0xFF;
p[ 1 ] = ( value & 0xFF00) >> 8;
return p16 + 1; return p16 + 1;
} }
@ -411,6 +418,7 @@ POSH_WriteU16ToLittle( void *dst, posh_u16_t value )
/** /**
* Writes a signed 16-bit value to a little endian buffer * Writes a signed 16-bit value to a little endian buffer
@ingroup MemoryBuffer
@param dst [out] pointer to the destination buffer, may not be NULL @param dst [out] pointer to the destination buffer, may not be NULL
@param value [in] host-endian signed 16-bit value @param value [in] host-endian signed 16-bit value
@returns a pointer to the location two bytes after dst @returns a pointer to the location two bytes after dst
@ -426,6 +434,7 @@ POSH_WriteI16ToLittle( void *dst, posh_i16_t value )
/** /**
* Writes an unsigned 32-bit value to a little endian buffer * Writes an unsigned 32-bit value to a little endian buffer
@ingroup MemoryBuffer
@param dst [out] pointer to the destination buffer, may not be NULL @param dst [out] pointer to the destination buffer, may not be NULL
@param value [in] host-endian signed 32-bit value @param value [in] host-endian signed 32-bit value
@returns a pointer to the location four bytes after dst @returns a pointer to the location four bytes after dst
@ -435,8 +444,12 @@ posh_u32_t *
POSH_WriteU32ToLittle( void *dst, posh_u32_t value ) POSH_WriteU32ToLittle( void *dst, posh_u32_t value )
{ {
posh_u32_t *p32 = ( posh_u32_t * ) dst; posh_u32_t *p32 = ( posh_u32_t * ) dst;
posh_byte_t *p = ( posh_byte_t * ) dst;
*p32 = POSH_LittleU32(value); p[ 0 ] = ( value & 0xFF );
p[ 1 ] = ( value & 0xFF00 ) >> 8;
p[ 2 ] = ( value & 0xFF0000 ) >> 16;
p[ 3 ] = ( value & 0xFF000000 ) >> 24;
return p32 + 1; return p32 + 1;
} }
@ -444,6 +457,7 @@ POSH_WriteU32ToLittle( void *dst, posh_u32_t value )
/** /**
* Writes a signed 32-bit value to a little endian buffer * Writes a signed 32-bit value to a little endian buffer
@ingroup MemoryBuffer
@param dst [out] pointer to the destination buffer, may not be NULL @param dst [out] pointer to the destination buffer, may not be NULL
@param value [in] host-endian signed 32-bit value @param value [in] host-endian signed 32-bit value
@returns a pointer to the location four bytes after dst @returns a pointer to the location four bytes after dst
@ -459,6 +473,7 @@ POSH_WriteI32ToLittle( void *dst, posh_i32_t value )
/** /**
* Writes an unsigned 16-bit value to a big endian buffer * Writes an unsigned 16-bit value to a big endian buffer
@ingroup MemoryBuffer
@param dst [out] pointer to the destination buffer, may not be NULL @param dst [out] pointer to the destination buffer, may not be NULL
@param value [in] host-endian unsigned 16-bit value @param value [in] host-endian unsigned 16-bit value
@returns a pointer to the location two bytes after dst @returns a pointer to the location two bytes after dst
@ -468,8 +483,10 @@ posh_u16_t *
POSH_WriteU16ToBig( void *dst, posh_u16_t value ) POSH_WriteU16ToBig( void *dst, posh_u16_t value )
{ {
posh_u16_t *p16 = ( posh_u16_t * ) dst; posh_u16_t *p16 = ( posh_u16_t * ) dst;
posh_byte_t *p = ( posh_byte_t * ) dst;
*p16 = POSH_BigU16(value); p[ 1 ] = ( value & 0xFF );
p[ 0 ] = ( value & 0xFF00 ) >> 8;
return p16 + 1; return p16 + 1;
} }
@ -477,6 +494,7 @@ POSH_WriteU16ToBig( void *dst, posh_u16_t value )
/** /**
* Writes a signed 16-bit value to a big endian buffer * Writes a signed 16-bit value to a big endian buffer
@ingroup MemoryBuffer
@param dst [out] pointer to the destination buffer, may not be NULL @param dst [out] pointer to the destination buffer, may not be NULL
@param value [in] host-endian signed 16-bit value @param value [in] host-endian signed 16-bit value
@returns a pointer to the location two bytes after dst @returns a pointer to the location two bytes after dst
@ -492,6 +510,7 @@ POSH_WriteI16ToBig( void *dst, posh_i16_t value )
/** /**
* Writes an unsigned 32-bit value to a big endian buffer * Writes an unsigned 32-bit value to a big endian buffer
@ingroup MemoryBuffer
@param dst [out] pointer to the destination buffer, may not be NULL @param dst [out] pointer to the destination buffer, may not be NULL
@param value [in] host-endian unsigned 32-bit value @param value [in] host-endian unsigned 32-bit value
@returns a pointer to the location four bytes after dst @returns a pointer to the location four bytes after dst
@ -501,8 +520,12 @@ posh_u32_t *
POSH_WriteU32ToBig( void *dst, posh_u32_t value ) POSH_WriteU32ToBig( void *dst, posh_u32_t value )
{ {
posh_u32_t *p32 = ( posh_u32_t * ) dst; posh_u32_t *p32 = ( posh_u32_t * ) dst;
posh_byte_t *p = ( posh_byte_t * ) dst;
*p32 = POSH_BigU32(value); p[ 3 ] = ( value & 0xFF );
p[ 2 ] = ( value & 0xFF00 ) >> 8;
p[ 1 ] = ( value & 0xFF0000 ) >> 16;
p[ 0 ] = ( value & 0xFF000000 ) >> 24;
return p32 + 1; return p32 + 1;
} }
@ -510,6 +533,7 @@ POSH_WriteU32ToBig( void *dst, posh_u32_t value )
/** /**
* Writes a signed 32-bit value to a big endian buffer * Writes a signed 32-bit value to a big endian buffer
@ingroup MemoryBuffer
@param dst [out] pointer to the destination buffer, may not be NULL @param dst [out] pointer to the destination buffer, may not be NULL
@param value [in] host-endian signed 32-bit value @param value [in] host-endian signed 32-bit value
@returns a pointer to the location four bytes after dst @returns a pointer to the location four bytes after dst
@ -536,8 +560,13 @@ posh_u64_t *
POSH_WriteU64ToLittle( void *dst, posh_u64_t value ) POSH_WriteU64ToLittle( void *dst, posh_u64_t value )
{ {
posh_u64_t *p64 = ( posh_u64_t * ) dst; posh_u64_t *p64 = ( posh_u64_t * ) dst;
posh_byte_t *p = ( posh_byte_t * ) dst;
int i;
*p64 = POSH_LittleU64(value); for ( i = 0; i < 8; i++, value >>= 8 )
{
p[ i ] = ( posh_byte_t ) ( value & 0xFF );
}
return p64 + 1; return p64 + 1;
} }
@ -570,8 +599,13 @@ posh_u64_t *
POSH_WriteU64ToBig( void *dst, posh_u64_t value ) POSH_WriteU64ToBig( void *dst, posh_u64_t value )
{ {
posh_u64_t *p64 = ( posh_u64_t * ) dst; posh_u64_t *p64 = ( posh_u64_t * ) dst;
posh_byte_t *p = ( posh_byte_t * ) dst;
int i;
*p64 = POSH_BigU64(value); for ( i = 0; i < 8; i++, value >>= 8 )
{
p[ 7-i ] = ( posh_byte_t ) ( value & 0xFF );
}
return p64 + 8; return p64 + 8;
} }
@ -599,84 +633,120 @@ POSH_WriteI64ToBig( void *dst, posh_i64_t value )
/** /**
* Reads an unsigned 16-bit value from a little-endian buffer * Reads an unsigned 16-bit value from a little-endian buffer
@ingroup MemoryBuffer
@param src [in] source buffer @param src [in] source buffer
@returns host-endian unsigned 16-bit value @returns host-endian unsigned 16-bit value
*/ */
posh_u16_t posh_u16_t
POSH_ReadU16FromLittle( const void *src ) POSH_ReadU16FromLittle( const void *src )
{ {
return POSH_LittleU16( (*(const posh_u16_t*)src) ); posh_u16_t v = 0;
posh_byte_t *p = ( posh_byte_t * ) src;
v |= p[ 0 ];
v |= ( ( posh_u16_t ) p[ 1 ] ) << 8;
return v;
} }
/** /**
* Reads a signed 16-bit value from a little-endian buffer * Reads a signed 16-bit value from a little-endian buffer
@ingroup MemoryBuffer
@param src [in] source buffer @param src [in] source buffer
@returns host-endian signed 16-bit value @returns host-endian signed 16-bit value
*/ */
posh_i16_t posh_i16_t
POSH_ReadI16FromLittle( const void *src ) POSH_ReadI16FromLittle( const void *src )
{ {
return POSH_LittleI16( (*(const posh_i16_t*)src) ); return ( posh_i16_t ) POSH_ReadU16FromLittle( src );
} }
/** /**
* Reads an unsigned 32-bit value from a little-endian buffer * Reads an unsigned 32-bit value from a little-endian buffer
@ingroup MemoryBuffer
@param src [in] source buffer @param src [in] source buffer
@returns host-endian unsigned 32-bit value @returns host-endian unsigned 32-bit value
*/ */
posh_u32_t posh_u32_t
POSH_ReadU32FromLittle( const void *src ) POSH_ReadU32FromLittle( const void *src )
{ {
return POSH_LittleU32( (*(const posh_u32_t*)src) ); posh_u32_t v = 0;
posh_byte_t *p = ( posh_byte_t * ) src;
v |= p[ 0 ];
v |= ( ( posh_u32_t ) p[ 1 ] ) << 8;
v |= ( ( posh_u32_t ) p[ 2 ] ) << 16;
v |= ( ( posh_u32_t ) p[ 3 ] ) << 24;
return v;
} }
/** /**
* Reads a signed 32-bit value from a little-endian buffer * Reads a signed 32-bit value from a little-endian buffer
@ingroup MemoryBuffer
@param src [in] source buffer @param src [in] source buffer
@returns host-endian signed 32-bit value @returns host-endian signed 32-bit value
*/ */
posh_i32_t posh_i32_t
POSH_ReadI32FromLittle( const void *src ) POSH_ReadI32FromLittle( const void *src )
{ {
return POSH_LittleI32( (*(const posh_i32_t*)src) ); return ( posh_i32_t ) POSH_ReadU32FromLittle( src );
} }
/** /**
* Reads an unsigned 16-bit value from a big-endian buffer * Reads an unsigned 16-bit value from a big-endian buffer
@ingroup MemoryBuffer
@param src [in] source buffer @param src [in] source buffer
@returns host-endian unsigned 16-bit value @returns host-endian unsigned 16-bit value
*/ */
posh_u16_t posh_u16_t
POSH_ReadU16FromBig( const void *src ) POSH_ReadU16FromBig( const void *src )
{ {
return POSH_BigU16( (*(const posh_u16_t*)src) ); posh_u16_t v = 0;
posh_byte_t *p = ( posh_byte_t * ) src;
v |= p[ 1 ];
v |= ( ( posh_u16_t ) p[ 0 ] ) << 8;
return v;
} }
/** /**
* Reads a signed 16-bit value from a big-endian buffer * Reads a signed 16-bit value from a big-endian buffer
@ingroup MemoryBuffer
@param src [in] source buffer @param src [in] source buffer
@returns host-endian signed 16-bit value @returns host-endian signed 16-bit value
*/ */
posh_i16_t posh_i16_t
POSH_ReadI16FromBig( const void *src ) POSH_ReadI16FromBig( const void *src )
{ {
return POSH_BigI16( (*(const posh_i16_t*)src)); return ( posh_i16_t ) POSH_ReadU16FromBig( src );
} }
/** /**
* Reads an unsigned 32-bit value from a big-endian buffer * Reads an unsigned 32-bit value from a big-endian buffer
@ingroup MemoryBuffer
@param src [in] source buffer @param src [in] source buffer
@returns host-endian unsigned 32-bit value @returns host-endian unsigned 32-bit value
*/ */
posh_u32_t posh_u32_t
POSH_ReadU32FromBig( const void *src ) POSH_ReadU32FromBig( const void *src )
{ {
return POSH_BigU32( (*(const posh_u32_t*)src) ); posh_u32_t v = 0;
posh_byte_t *p = ( posh_byte_t * ) src;
v |= p[ 3 ];
v |= ( ( posh_u32_t ) p[ 2 ] ) << 8;
v |= ( ( posh_u32_t ) p[ 1 ] ) << 16;
v |= ( ( posh_u32_t ) p[ 0 ] ) << 24;
return v;
} }
/** /**
* Reads a signed 32-bit value from a big-endian buffer * Reads a signed 32-bit value from a big-endian buffer
@ingroup MemoryBuffer
@param src [in] source buffer @param src [in] source buffer
@returns host-endian signed 32-bit value @returns host-endian signed 32-bit value
*/ */
@ -696,7 +766,16 @@ POSH_ReadI32FromBig( const void *src )
posh_u64_t posh_u64_t
POSH_ReadU64FromLittle( const void *src ) POSH_ReadU64FromLittle( const void *src )
{ {
return POSH_LittleU64( (*(const posh_u64_t*)src) ); posh_u64_t v = 0;
posh_byte_t *p = ( posh_byte_t * ) src;
int i;
for ( i = 0; i < 8; i++ )
{
v |= ( ( posh_u64_t ) p[ i ] ) << (i*8);
}
return v;
} }
/** /**
@ -707,7 +786,7 @@ POSH_ReadU64FromLittle( const void *src )
posh_i64_t posh_i64_t
POSH_ReadI64FromLittle( const void *src ) POSH_ReadI64FromLittle( const void *src )
{ {
return POSH_LittleI64( (*(const posh_i64_t*)src) ); return ( posh_i64_t ) POSH_ReadU64FromLittle( src );
} }
/** /**
@ -718,7 +797,16 @@ POSH_ReadI64FromLittle( const void *src )
posh_u64_t posh_u64_t
POSH_ReadU64FromBig( const void *src ) POSH_ReadU64FromBig( const void *src )
{ {
return POSH_BigU64( (*(const posh_u64_t*)src) ); posh_u64_t v = 0;
posh_byte_t *p = ( posh_byte_t * ) src;
int i;
for ( i = 0; i < 8; i++ )
{
v |= ( ( posh_u64_t ) p[ 7-i ] ) << (i*8);
}
return v;
} }
/** /**
@ -729,7 +817,7 @@ POSH_ReadU64FromBig( const void *src )
posh_i64_t posh_i64_t
POSH_ReadI64FromBig( const void *src ) POSH_ReadI64FromBig( const void *src )
{ {
return POSH_BigI64( (*(const posh_i64_t*)src) ); return ( posh_i64_t ) POSH_ReadU64FromBig( src );
} }
#endif /* POSH_64BIT_INTEGER */ #endif /* POSH_64BIT_INTEGER */
@ -755,11 +843,7 @@ POSH_LittleFloatBits( float f )
u.f32 = f; u.f32 = f;
#if defined POSH_LITTLE_ENDIAN return POSH_LittleU32( u.u32 );
return u.u32;
#else
return POSH_SwapU32( u.u32 );
#endif
} }
/** /**
@ -780,11 +864,7 @@ POSH_BigFloatBits( float f )
u.f32 = f; u.f32 = f;
#if defined POSH_LITTLE_ENDIAN return POSH_BigU32( u.u32 );
return POSH_SwapU32( u.u32 );
#else
return u.u32;
#endif
} }
/** /**

View File

@ -1,6 +1,7 @@
/** /**
@file posh.h @file posh.h
@author Brian Hook @author Brian Hook
@version 1.3.001
Header file for POSH, the Portable Open Source Harness project. Header file for POSH, the Portable Open Source Harness project.
@ -56,6 +57,16 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REVISION:
I've been lax about revision histories, so this starts at, um, 1.3.001.
Sorry for any inconveniences.
1.3.001 - 2/23/2006 - Incorporated fix for bug reported by Bill Cary,
where I was not detecting Visual Studio
compilation on x86-64 systems. Added check for
_M_X64 which should fix that.
*/ */
/* /*
I have yet to find an authoritative reference on preprocessor I have yet to find an authoritative reference on preprocessor
@ -135,6 +146,7 @@ Microsoft Visual Studio predefines the following:
- _MSC_VER - _MSC_VER
- _WIN32: on Win32 - _WIN32: on Win32
- _M_IX6 (on x86 systems) - _M_IX6 (on x86 systems)
- _M_X64: on x86-64 systems
- _M_ALPHA (on DEC AXP systems) - _M_ALPHA (on DEC AXP systems)
- _SH3: WinCE, Hitachi SH-3 - _SH3: WinCE, Hitachi SH-3
- _MIPS: WinCE, MIPS - _MIPS: WinCE, MIPS
@ -193,9 +205,6 @@ Metrowerks:
*/ */
#ifndef HAVE_POSH_H
#define HAVE_POSH_H
/* /*
** ---------------------------------------------------------------------------- ** ----------------------------------------------------------------------------
** Include <limits.h> optionally ** Include <limits.h> optionally
@ -289,6 +298,12 @@ Metrowerks:
# define POSH_OS_STRING "Cygwin" # define POSH_OS_STRING "Cygwin"
#endif #endif
#if defined GEKKO
# define POSH_OS_GAMECUBE
# define __powerpc__
# define POSH_OS_STRING "GameCube"
#endif
#if defined __MINGW32__ #if defined __MINGW32__
# define POSH_OS_MINGW 1 # define POSH_OS_MINGW 1
# define POSH_OS_STRING "MinGW" # define POSH_OS_STRING "MinGW"
@ -369,15 +384,11 @@ Metrowerks:
# define POSH_OS_STRING "Windows CE" # define POSH_OS_STRING "Windows CE"
#endif #endif
#if defined _XBOX_VER == 200 #if defined _XBOX
# define POSH_OS_XBOX360 1
# define POSH_OS_STRING "XBOX-360"
#elif defined _XBOX
# define POSH_OS_XBOX 1 # define POSH_OS_XBOX 1
# define POSH_OS_STRING "XBOX" # define POSH_OS_STRING "XBOX"
#endif #endif
#if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__ #if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__
# define POSH_OS_WIN32 1 # define POSH_OS_WIN32 1
# if !defined POSH_OS_XBOX # if !defined POSH_OS_XBOX
@ -407,6 +418,12 @@ Metrowerks:
** Determine target CPU ** Determine target CPU
** ----------------------------------------------------------------------------- ** -----------------------------------------------------------------------------
*/ */
#if defined GEKKO
# define POSH_CPU_PPC750 1
# define POSH_CPU_STRING "IBM PowerPC 750 (NGC)"
#endif
#if defined mc68000 || defined m68k || defined __MC68K__ || defined m68000 #if defined mc68000 || defined m68k || defined __MC68K__ || defined m68000
# define POSH_CPU_68K 1 # define POSH_CPU_68K 1
# define POSH_CPU_STRING "MC68000" # define POSH_CPU_STRING "MC68000"
@ -414,11 +431,13 @@ Metrowerks:
#if defined __PPC__ || defined __POWERPC__ || defined powerpc || defined _POWER || defined __ppc__ || defined __powerpc__ #if defined __PPC__ || defined __POWERPC__ || defined powerpc || defined _POWER || defined __ppc__ || defined __powerpc__
# define POSH_CPU_PPC 1 # define POSH_CPU_PPC 1
# if !defined POSH_CPU_STRING
# if defined __powerpc64__ # if defined __powerpc64__
# define POSH_CPU_STRING "PowerPC64" # define POSH_CPU_STRING "PowerPC64"
# else # else
# define POSH_CPU_STRING "PowerPC" # define POSH_CPU_STRING "PowerPC"
# endif # endif
# endif
#endif #endif
#if defined _CRAYT3E || defined _CRAYMPP #if defined _CRAYT3E || defined _CRAYMPP
@ -682,12 +701,12 @@ typedef unsigned long long posh_u64_t;
/* hack */ /* hack */
#ifdef __MINGW32__ #ifdef __MINGW32__
# undef POSH_I64 #undef POSH_I64
# undef POSH_U64 #undef POSH_U64
# undef POSH_I64_PRINTF_PREFIX #undef POSH_I64_PRINTF_PREFIX
# define POSH_U64( x ) ((posh_u64_t)(x##LL)) #define POSH_I64( x ) ((posh_i64_t)x)
# define POSH_I64( x ) ((posh_i64_t)(x##LL)) #define POSH_U64( x ) ((posh_u64_t)x)
# define POSH_I64_PRINTF_PREFIX "I64" #define POSH_I64_PRINTF_PREFIX "I64"
#endif #endif
#ifdef FORCE_DOXYGEN #ifdef FORCE_DOXYGEN
@ -893,7 +912,6 @@ double POSH_ReadDoubleFromBig( const void *src );
# undef POSH_NO_FLOAT # undef POSH_NO_FLOAT
#endif #endif
extern posh_u16_t POSH_SwapU16( posh_u16_t u ); extern posh_u16_t POSH_SwapU16( posh_u16_t u );
extern posh_i16_t POSH_SwapI16( posh_i16_t u ); extern posh_i16_t POSH_SwapI16( posh_i16_t u );
extern posh_u32_t POSH_SwapU32( posh_u32_t u ); extern posh_u32_t POSH_SwapU32( posh_u32_t u );
@ -986,4 +1004,4 @@ extern posh_i64_t POSH_ReadI64FromBig( const void *src );
} }
#endif #endif
#endif /* HAVE_POSH_H */

View File

@ -752,44 +752,57 @@ FloatImage * nv::ImageIO::loadFloatTIFF(const char * fileName)
return NULL; return NULL;
} }
::uint16 spp, bpp; ::uint16 spp, bpp, format;
::uint32 width, height; ::uint32 width, height;
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp); TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &format);
if (spp != 1 || (bpp != 8 && bpp != 16 && bpp != 32)) { if (bpp != 8 && bpp != 16 && bpp != 32) {
nvDebug("Can't load '%s', only 1 sample per pixel supported\n", fileName); nvDebug("Can't load '%s', only 1 sample per pixel supported\n", fileName);
TIFFClose(tif); TIFFClose(tif);
return NULL; return NULL;
} }
FloatImage * fimage = new FloatImage(); AutoPtr<FloatImage> fimage(new FloatImage());
fimage->allocate(spp, width, height); fimage->allocate(spp, width, height);
int linesize = TIFFScanlineSize(tif); int linesize = TIFFScanlineSize(tif);
tdata_t buf = (::uint8 *)nv::mem::malloc(linesize); tdata_t buf = (::uint8 *)nv::mem::malloc(linesize);
for (uint y = 0; y < height; y++) { for (uint y = 0; y < height; y++)
{
TIFFReadScanline(tif, buf, y, 0); TIFFReadScanline(tif, buf, y, 0);
float * dst = fimage->scanline(y, 0); for (uint c=0; c<spp; c++ )
{
float * dst = fimage->scanline(y, c);
if (bpp == 8) { for(uint x = 0; x < width; x++)
for(uint x = 0; x < width; x++) { {
dst[x] = float(((::uint8 *)buf)[x]) / float(0xFF); if (bpp == 8)
{
dst[x] = float(((::uint8 *)buf)[x*spp+c]) / float(0xFF);
} }
else if (bpp == 16)
{
dst[x] = float(((::uint16 *)buf)[x*spp+c]) / float(0xFFFF);
} }
else if (bpp == 16) { else if (bpp == 32)
for(uint x = 0; x < width; x++) { {
dst[x] = float(((::uint16 *)buf)[x]) / float(0xFFFF); if (format==SAMPLEFORMAT_IEEEFP)
{
dst[x] = float(((float *)buf)[x*spp+c]);
} }
else
{
dst[x] = float(((::uint32 *)buf)[x*spp+c] >> 8) / float(0xFFFFFF);
} }
else /*if (bpp == 32)*/ {
// Mantissa has only 24 bits, so drop 8 bits. }
for(uint x = 0; x < width; x++) {
dst[x] = float(((::uint32 *)buf)[x] >> 8) / float(0xFFFFFF);
} }
} }
} }
@ -798,9 +811,63 @@ FloatImage * nv::ImageIO::loadFloatTIFF(const char * fileName)
TIFFClose(tif); TIFFClose(tif);
return fimage; return fimage.release();
} }
bool nv::ImageIO::saveFloatTIFF(const char * fileName, FloatImage *fimage)
{
int iW=fimage->width();
int iH=fimage->height();
int iC=fimage->componentNum();
TIFF * image = TIFFOpen(fileName, "w");
// Open the TIFF file
if (image == NULL)
{
nvDebug("Could not open '%s' for writing\n", fileName);
return false;
}
TIFFSetField(image, TIFFTAG_IMAGEWIDTH, iW);
TIFFSetField(image, TIFFTAG_IMAGELENGTH, iH);
TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, iC);
TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 32);
uint32 rowsperstrip = TIFFDefaultStripSize(image, -1);
TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);
TIFFSetField(image, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, -1L);
TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
float *scanline = new float[iW * iC];
for (int y=0; y<iH; y++)
{
for (int c=0; c<iC; c++)
{
float *src = fimage->scanline(y, c);
for (int x=0; x<iW; x++) scanline[x*iC+c]=src[x];
}
if (TIFFWriteScanline(image, scanline, y, 0)==-1)
{
nvDebug("Error writing scanline %d\n", y);
return -1;
}
}
delete [] scanline;
// Close the file
TIFFClose(image);
return true;
}
#endif #endif
#if 0 #if 0

View File

@ -31,8 +31,9 @@ namespace nv
#endif #endif
#if defined(HAVE_TIFF) #if defined(HAVE_TIFF)
// Hack! // Hacks!
NVIMAGE_API FloatImage * loadFloatTIFF(const char * fileName); NVIMAGE_API FloatImage * loadFloatTIFF(const char * fileName);
NVIMAGE_API bool saveFloatTIFF(const char * fileName, FloatImage *fimage);
NVIMAGE_API FloatImage * loadFloatTIFF(Stream & s); NVIMAGE_API FloatImage * loadFloatTIFF(Stream & s);
#endif #endif

View File

@ -52,6 +52,9 @@ TARGET_LINK_LIBRARIES(nvdecompress nvcore nvmath nvimage)
ADD_EXECUTABLE(nvddsinfo tools/ddsinfo.cpp) ADD_EXECUTABLE(nvddsinfo tools/ddsinfo.cpp)
TARGET_LINK_LIBRARIES(nvddsinfo nvcore nvmath nvimage) TARGET_LINK_LIBRARIES(nvddsinfo nvcore nvmath nvimage)
INSTALL(TARGETS nvcompress nvdecompress nvddsinfo DESTINATION bin) ADD_EXECUTABLE(nvimgdiff tools/imgdiff.cpp)
TARGET_LINK_LIBRARIES(nvimgdiff nvcore nvmath nvimage)
INSTALL(TARGETS nvcompress nvdecompress nvddsinfo nvimgdiff DESTINATION bin)

View File

@ -35,7 +35,6 @@
#include "cmdline.h" #include "cmdline.h"
static bool loadImage(nv::Image & image, const char * fileName) static bool loadImage(nv::Image & image, const char * fileName)
{ {
if (nv::strCaseCmp(nv::Path::extension(fileName), ".dds") == 0) if (nv::strCaseCmp(nv::Path::extension(fileName), ".dds") == 0)
@ -77,7 +76,7 @@ struct Error
{ {
samples++; samples++;
mabse += fabs(e); mabse += fabs(e);
maxabse = nv::max(maxabse, fabs(e)); maxabse = nv::max(maxabse, fabsf(e));
mse += e * e; mse += e * e;
} }

View File

@ -25,6 +25,8 @@ public:
Matrix(identity_t); Matrix(identity_t);
Matrix(const Matrix & m); Matrix(const Matrix & m);
scalar data(uint idx) const;
scalar & data(uint idx);
scalar get(uint row, uint col) const; scalar get(uint row, uint col) const;
scalar operator()(uint row, uint col) const; scalar operator()(uint row, uint col) const;
scalar & operator()(uint row, uint col); scalar & operator()(uint row, uint col);
@ -37,8 +39,7 @@ public:
void scale(Vector3::Arg s); void scale(Vector3::Arg s);
void translate(Vector3::Arg t); void translate(Vector3::Arg t);
void rotate(scalar theta, scalar v0, scalar v1, scalar v2); void rotate(scalar theta, scalar v0, scalar v1, scalar v2);
Matrix inverse(); scalar determinant() const;
scalar determinant();
void apply(Matrix::Arg m); void apply(Matrix::Arg m);
@ -76,6 +77,16 @@ inline Matrix::Matrix(const Matrix & m)
// Accessors // Accessors
inline scalar Matrix::data(uint idx) const
{
nvDebugCheck(idx < 16);
return m_data[idx];
}
inline scalar & Matrix::data(uint idx)
{
nvDebugCheck(idx < 16);
return m_data[idx];
}
inline scalar Matrix::get(uint row, uint col) const inline scalar Matrix::get(uint row, uint col) const
{ {
nvDebugCheck(row < 4 && col < 4); nvDebugCheck(row < 4 && col < 4);
@ -305,14 +316,15 @@ inline Matrix perspective(scalar fovy, scalar aspect, scalar zNear)
} }
/// Get matrix determinant. /// Get matrix determinant.
inline scalar Matrix::determinant() inline scalar Matrix::determinant() const
{ {
return m_data[3] * m_data[6] * m_data[9] * m_data[12]-m_data[2] * m_data[7] * m_data[9] * m_data[12]-m_data[3] * m_data[5] * m_data[10] * m_data[12]+m_data[1] * m_data[7] * m_data[10] * m_data[12]+ return
m_data[2] * m_data[5] * m_data[11] * m_data[12]-m_data[1] * m_data[6] * m_data[11] * m_data[12]-m_data[3] * m_data[6] * m_data[8] * m_data[13]+m_data[2] * m_data[7] * m_data[8] * m_data[13]+ m_data[3] * m_data[6] * m_data[ 9] * m_data[12] - m_data[2] * m_data[7] * m_data[ 9] * m_data[12] - m_data[3] * m_data[5] * m_data[10] * m_data[12] + m_data[1] * m_data[7] * m_data[10] * m_data[12] +
m_data[3] * m_data[4] * m_data[10] * m_data[13]-m_data[0] * m_data[7] * m_data[10] * m_data[13]-m_data[2] * m_data[4] * m_data[11] * m_data[13]+m_data[0] * m_data[6] * m_data[11] * m_data[13]+ m_data[2] * m_data[5] * m_data[11] * m_data[12] - m_data[1] * m_data[6] * m_data[11] * m_data[12] - m_data[3] * m_data[6] * m_data[ 8] * m_data[13] + m_data[2] * m_data[7] * m_data[ 8] * m_data[13] +
m_data[3] * m_data[5] * m_data[8] * m_data[14]-m_data[1] * m_data[7] * m_data[8] * m_data[14]-m_data[3] * m_data[4] * m_data[9] * m_data[14]+m_data[0] * m_data[7] * m_data[9] * m_data[14]+ m_data[3] * m_data[4] * m_data[10] * m_data[13] - m_data[0] * m_data[7] * m_data[10] * m_data[13] - m_data[2] * m_data[4] * m_data[11] * m_data[13] + m_data[0] * m_data[6] * m_data[11] * m_data[13] +
m_data[1] * m_data[4] * m_data[11] * m_data[14]-m_data[0] * m_data[5] * m_data[11] * m_data[14]-m_data[2] * m_data[5] * m_data[8] * m_data[15]+m_data[1] * m_data[6] * m_data[8] * m_data[15]+ m_data[3] * m_data[5] * m_data[ 8] * m_data[14] - m_data[1] * m_data[7] * m_data[ 8] * m_data[14] - m_data[3] * m_data[4] * m_data[ 9] * m_data[14] + m_data[0] * m_data[7] * m_data[ 9] * m_data[14] +
m_data[2] * m_data[4] * m_data[9] * m_data[15]-m_data[0] * m_data[6] * m_data[9] * m_data[15]-m_data[1] * m_data[4] * m_data[10] * m_data[15]+m_data[0] * m_data[5] * m_data[10] * m_data[15]; m_data[1] * m_data[4] * m_data[11] * m_data[14] - m_data[0] * m_data[5] * m_data[11] * m_data[14] - m_data[2] * m_data[5] * m_data[ 8] * m_data[15] + m_data[1] * m_data[6] * m_data[ 8] * m_data[15] +
m_data[2] * m_data[4] * m_data[ 9] * m_data[15] - m_data[0] * m_data[6] * m_data[ 9] * m_data[15] - m_data[1] * m_data[4] * m_data[10] * m_data[15] + m_data[0] * m_data[5] * m_data[10] * m_data[15];
} }
inline Matrix transpose(Matrix::Arg m) inline Matrix transpose(Matrix::Arg m)
@ -328,26 +340,26 @@ inline Matrix transpose(Matrix::Arg m)
return r; return r;
} }
inline Matrix Matrix::inverse() inline Matrix inverse(Matrix::Arg m)
{ {
Matrix r; Matrix r;
r.m_data[ 0] = m_data[6]*m_data[11]*m_data[13] - m_data[7]*m_data[10]*m_data[13] + m_data[7]*m_data[9]*m_data[14] - m_data[5]*m_data[11]*m_data[14] - m_data[6]*m_data[9]*m_data[15] + m_data[5]*m_data[10]*m_data[15]; r.data( 0) = m.data(6)*m.data(11)*m.data(13) - m.data(7)*m.data(10)*m.data(13) + m.data(7)*m.data(9)*m.data(14) - m.data(5)*m.data(11)*m.data(14) - m.data(6)*m.data(9)*m.data(15) + m.data(5)*m.data(10)*m.data(15);
r.m_data[ 1] = m_data[3]*m_data[10]*m_data[13] - m_data[2]*m_data[11]*m_data[13] - m_data[3]*m_data[9]*m_data[14] + m_data[1]*m_data[11]*m_data[14] + m_data[2]*m_data[9]*m_data[15] - m_data[1]*m_data[10]*m_data[15]; r.data( 1) = m.data(3)*m.data(10)*m.data(13) - m.data(2)*m.data(11)*m.data(13) - m.data(3)*m.data(9)*m.data(14) + m.data(1)*m.data(11)*m.data(14) + m.data(2)*m.data(9)*m.data(15) - m.data(1)*m.data(10)*m.data(15);
r.m_data[ 2] = m_data[2]*m_data[7]*m_data[13] - m_data[3]*m_data[6]*m_data[13] + m_data[3]*m_data[5]*m_data[14] - m_data[1]*m_data[7]*m_data[14] - m_data[2]*m_data[5]*m_data[15] + m_data[1]*m_data[6]*m_data[15]; r.data( 2) = m.data(2)*m.data( 7)*m.data(13) - m.data(3)*m.data( 6)*m.data(13) + m.data(3)*m.data(5)*m.data(14) - m.data(1)*m.data( 7)*m.data(14) - m.data(2)*m.data(5)*m.data(15) + m.data(1)*m.data( 6)*m.data(15);
r.m_data[ 3] = m_data[3]*m_data[6]*m_data[9] - m_data[2]*m_data[7]*m_data[9] - m_data[3]*m_data[5]*m_data[10] + m_data[1]*m_data[7]*m_data[10] + m_data[2]*m_data[5]*m_data[11] - m_data[1]*m_data[6]*m_data[11]; r.data( 3) = m.data(3)*m.data( 6)*m.data( 9) - m.data(2)*m.data( 7)*m.data( 9) - m.data(3)*m.data(5)*m.data(10) + m.data(1)*m.data( 7)*m.data(10) + m.data(2)*m.data(5)*m.data(11) - m.data(1)*m.data( 6)*m.data(11);
r.m_data[ 4] = m_data[7]*m_data[10]*m_data[12] - m_data[6]*m_data[11]*m_data[12] - m_data[7]*m_data[8]*m_data[14] + m_data[4]*m_data[11]*m_data[14] + m_data[6]*m_data[8]*m_data[15] - m_data[4]*m_data[10]*m_data[15]; r.data( 4) = m.data(7)*m.data(10)*m.data(12) - m.data(6)*m.data(11)*m.data(12) - m.data(7)*m.data(8)*m.data(14) + m.data(4)*m.data(11)*m.data(14) + m.data(6)*m.data(8)*m.data(15) - m.data(4)*m.data(10)*m.data(15);
r.m_data[ 5] = m_data[2]*m_data[11]*m_data[12] - m_data[3]*m_data[10]*m_data[12] + m_data[3]*m_data[8]*m_data[14] - m_data[0]*m_data[11]*m_data[14] - m_data[2]*m_data[8]*m_data[15] + m_data[0]*m_data[10]*m_data[15]; r.data( 5) = m.data(2)*m.data(11)*m.data(12) - m.data(3)*m.data(10)*m.data(12) + m.data(3)*m.data(8)*m.data(14) - m.data(0)*m.data(11)*m.data(14) - m.data(2)*m.data(8)*m.data(15) + m.data(0)*m.data(10)*m.data(15);
r.m_data[ 6] = m_data[3]*m_data[6]*m_data[12] - m_data[2]*m_data[7]*m_data[12] - m_data[3]*m_data[4]*m_data[14] + m_data[0]*m_data[7]*m_data[14] + m_data[2]*m_data[4]*m_data[15] - m_data[0]*m_data[6]*m_data[15]; r.data( 6) = m.data(3)*m.data( 6)*m.data(12) - m.data(2)*m.data( 7)*m.data(12) - m.data(3)*m.data(4)*m.data(14) + m.data(0)*m.data( 7)*m.data(14) + m.data(2)*m.data(4)*m.data(15) - m.data(0)*m.data( 6)*m.data(15);
r.m_data[ 7] = m_data[2]*m_data[7]*m_data[8] - m_data[3]*m_data[6]*m_data[8] + m_data[3]*m_data[4]*m_data[10] - m_data[0]*m_data[7]*m_data[10] - m_data[2]*m_data[4]*m_data[11] + m_data[0]*m_data[6]*m_data[11]; r.data( 7) = m.data(2)*m.data( 7)*m.data( 8) - m.data(3)*m.data( 6)*m.data( 8) + m.data(3)*m.data(4)*m.data(10) - m.data(0)*m.data( 7)*m.data(10) - m.data(2)*m.data(4)*m.data(11) + m.data(0)*m.data( 6)*m.data(11);
r.m_data[ 8] = m_data[5]*m_data[11]*m_data[12] - m_data[7]*m_data[9]*m_data[12] + m_data[7]*m_data[8]*m_data[13] - m_data[4]*m_data[11]*m_data[13] - m_data[5]*m_data[8]*m_data[15] + m_data[4]*m_data[9]*m_data[15]; r.data( 8) = m.data(5)*m.data(11)*m.data(12) - m.data(7)*m.data( 9)*m.data(12) + m.data(7)*m.data(8)*m.data(13) - m.data(4)*m.data(11)*m.data(13) - m.data(5)*m.data(8)*m.data(15) + m.data(4)*m.data( 9)*m.data(15);
r.m_data[ 9] = m_data[3]*m_data[9]*m_data[12] - m_data[1]*m_data[11]*m_data[12] - m_data[3]*m_data[8]*m_data[13] + m_data[0]*m_data[11]*m_data[13] + m_data[1]*m_data[8]*m_data[15] - m_data[0]*m_data[9]*m_data[15]; r.data( 9) = m.data(3)*m.data( 9)*m.data(12) - m.data(1)*m.data(11)*m.data(12) - m.data(3)*m.data(8)*m.data(13) + m.data(0)*m.data(11)*m.data(13) + m.data(1)*m.data(8)*m.data(15) - m.data(0)*m.data( 9)*m.data(15);
r.m_data[10] = m_data[1]*m_data[7]*m_data[12] - m_data[3]*m_data[5]*m_data[12] + m_data[3]*m_data[4]*m_data[13] - m_data[0]*m_data[7]*m_data[13] - m_data[1]*m_data[4]*m_data[15] + m_data[0]*m_data[5]*m_data[15]; r.data(10) = m.data(1)*m.data( 7)*m.data(12) - m.data(3)*m.data( 5)*m.data(12) + m.data(3)*m.data(4)*m.data(13) - m.data(0)*m.data( 7)*m.data(13) - m.data(1)*m.data(4)*m.data(15) + m.data(0)*m.data( 5)*m.data(15);
r.m_data[11] = m_data[3]*m_data[5]*m_data[8] - m_data[1]*m_data[7]*m_data[8] - m_data[3]*m_data[4]*m_data[9] + m_data[0]*m_data[7]*m_data[9] + m_data[1]*m_data[4]*m_data[11] - m_data[0]*m_data[5]*m_data[11]; r.data(11) = m.data(3)*m.data( 5)*m.data( 8) - m.data(1)*m.data( 7)*m.data( 8) - m.data(3)*m.data(4)*m.data( 9) + m.data(0)*m.data( 7)*m.data( 9) + m.data(1)*m.data(4)*m.data(11) - m.data(0)*m.data( 5)*m.data(11);
r.m_data[12] = m_data[6]*m_data[9]*m_data[12] - m_data[5]*m_data[10]*m_data[12] - m_data[6]*m_data[8]*m_data[13] + m_data[4]*m_data[10]*m_data[13] + m_data[5]*m_data[8]*m_data[14] - m_data[4]*m_data[9]*m_data[14]; r.data(12) = m.data(6)*m.data( 9)*m.data(12) - m.data(5)*m.data(10)*m.data(12) - m.data(6)*m.data(8)*m.data(13) + m.data(4)*m.data(10)*m.data(13) + m.data(5)*m.data(8)*m.data(14) - m.data(4)*m.data( 9)*m.data(14);
r.m_data[13] = m_data[1]*m_data[10]*m_data[12] - m_data[2]*m_data[9]*m_data[12] + m_data[2]*m_data[8]*m_data[13] - m_data[0]*m_data[10]*m_data[13] - m_data[1]*m_data[8]*m_data[14] + m_data[0]*m_data[9]*m_data[14]; r.data(13) = m.data(1)*m.data(10)*m.data(12) - m.data(2)*m.data( 9)*m.data(12) + m.data(2)*m.data(8)*m.data(13) - m.data(0)*m.data(10)*m.data(13) - m.data(1)*m.data(8)*m.data(14) + m.data(0)*m.data( 9)*m.data(14);
r.m_data[14] = m_data[2]*m_data[5]*m_data[12] - m_data[1]*m_data[6]*m_data[12] - m_data[2]*m_data[4]*m_data[13] + m_data[0]*m_data[6]*m_data[13] + m_data[1]*m_data[4]*m_data[14] - m_data[0]*m_data[5]*m_data[14]; r.data(14) = m.data(2)*m.data( 5)*m.data(12) - m.data(1)*m.data( 6)*m.data(12) - m.data(2)*m.data(4)*m.data(13) + m.data(0)*m.data( 6)*m.data(13) + m.data(1)*m.data(4)*m.data(14) - m.data(0)*m.data( 5)*m.data(14);
r.m_data[15] = m_data[1]*m_data[6]*m_data[8] - m_data[2]*m_data[5]*m_data[8] + m_data[2]*m_data[4]*m_data[9] - m_data[0]*m_data[6]*m_data[9] - m_data[1]*m_data[4]*m_data[10] + m_data[0]*m_data[5]*m_data[10]; r.data(15) = m.data(1)*m.data( 6)*m.data( 8) - m.data(2)*m.data( 5)*m.data( 8) + m.data(2)*m.data(4)*m.data( 9) - m.data(0)*m.data( 6)*m.data( 9) - m.data(1)*m.data(4)*m.data(10) + m.data(0)*m.data( 5)*m.data(10);
r.scale(1./determinant()); r.scale(1.0f / m.determinant());
return r; return r;
} }