Merge changes from the-witness.

Fix DXT5n compressor.
This commit is contained in:
castano
2010-07-22 10:25:14 +00:00
parent ac7c017c35
commit 9e881f28d1
24 changed files with 3357 additions and 3332 deletions

View File

@ -37,63 +37,62 @@ namespace nv
public: public:
/// Ctor. /// Ctor.
StdStream( FILE * fp, bool autoclose=true ) : StdStream( FILE * fp, bool autoclose=true ) : m_fp(fp), m_autoclose(autoclose) { }
m_fp(fp), m_autoclose(autoclose) { }
/// Dtor. /// Dtor.
virtual ~StdStream() virtual ~StdStream()
{ {
if( m_fp != NULL && m_autoclose ) { if( m_fp != NULL && m_autoclose ) {
fclose( m_fp ); _fclose_nolock( m_fp );
} }
} }
/** @name Stream implementation. */ /** @name Stream implementation. */
//@{ //@{
virtual void seek( uint pos ) virtual void seek( uint pos )
{ {
nvDebugCheck(m_fp != NULL); nvDebugCheck(m_fp != NULL);
nvDebugCheck(pos < size()); nvDebugCheck(pos < size());
fseek(m_fp, pos, SEEK_SET); _fseek_nolock(m_fp, pos, SEEK_SET);
} }
virtual uint tell() const virtual uint tell() const
{ {
nvDebugCheck(m_fp != NULL); nvDebugCheck(m_fp != NULL);
return ftell(m_fp); return _ftell_nolock(m_fp);
} }
virtual uint size() const virtual uint size() const
{ {
nvDebugCheck(m_fp != NULL); nvDebugCheck(m_fp != NULL);
uint pos = ftell(m_fp); uint pos = ftell(m_fp);
fseek(m_fp, 0, SEEK_END); _fseek_nolock(m_fp, 0, SEEK_END);
uint end = ftell(m_fp); uint end = ftell(m_fp);
fseek(m_fp, pos, SEEK_SET); _fseek_nolock(m_fp, pos, SEEK_SET);
return end; return end;
} }
virtual bool isError() const virtual bool isError() const
{ {
return m_fp == NULL || ferror( m_fp ) != 0; return m_fp == NULL || ferror( m_fp ) != 0;
} }
virtual void clearError() virtual void clearError()
{ {
nvDebugCheck(m_fp != NULL); nvDebugCheck(m_fp != NULL);
clearerr(m_fp); clearerr(m_fp);
} }
virtual bool isAtEnd() const virtual bool isAtEnd() const
{ {
nvDebugCheck(m_fp != NULL); nvDebugCheck(m_fp != NULL);
return feof( m_fp ) != 0; return feof( m_fp ) != 0;
} }
/// Always true. /// Always true.
virtual bool isSeekable() const { return true; } virtual bool isSeekable() const { return true; }
//@} //@}
protected: protected:
@ -110,34 +109,33 @@ namespace nv
public: public:
/// Construct stream by file name. /// Construct stream by file name.
StdOutputStream( const char * name ) : StdOutputStream( const char * name ) : StdStream(fileOpen(name, "wb")) { }
StdStream(fileOpen(name, "wb")) { }
/// Construct stream by file handle. /// Construct stream by file handle.
StdOutputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose) StdOutputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose)
{ {
} }
/** @name Stream implementation. */ /** @name Stream implementation. */
//@{ //@{
/// Write data. /// Write data.
virtual uint serialize( void * data, uint len ) virtual uint serialize( void * data, uint len )
{ {
nvDebugCheck(data != NULL); nvDebugCheck(data != NULL);
nvDebugCheck(m_fp != NULL); nvDebugCheck(m_fp != NULL);
return (uint)fwrite(data, 1, len, m_fp); return (uint)_fwrite_nolock(data, 1, len, m_fp);
} }
virtual bool isLoading() const virtual bool isLoading() const
{ {
return false; return false;
} }
virtual bool isSaving() const virtual bool isSaving() const
{ {
return true; return true;
} }
//@} //@}
}; };
@ -149,34 +147,33 @@ namespace nv
public: public:
/// Construct stream by file name. /// Construct stream by file name.
StdInputStream( const char * name ) : StdInputStream( const char * name ) : StdStream(fileOpen(name, "rb")) { }
StdStream(fileOpen(name, "rb")) { }
/// Construct stream by file handle. /// Construct stream by file handle.
StdInputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose) StdInputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose)
{ {
} }
/** @name Stream implementation. */ /** @name Stream implementation. */
//@{ //@{
/// Read data. /// Read data.
virtual uint serialize( void * data, uint len ) virtual uint serialize( void * data, uint len )
{ {
nvDebugCheck(data != NULL); nvDebugCheck(data != NULL);
nvDebugCheck(m_fp != NULL); nvDebugCheck(m_fp != NULL);
return (uint)fread(data, 1, len, m_fp); return (uint)_fread_nolock(data, 1, len, m_fp);
} }
virtual bool isLoading() const virtual bool isLoading() const
{ {
return true; return true;
} }
virtual bool isSaving() const virtual bool isSaving() const
{ {
return false; return false;
} }
//@} //@}
}; };
@ -188,75 +185,74 @@ namespace nv
public: public:
/// Ctor. /// Ctor.
MemoryInputStream( const uint8 * mem, uint size ) : MemoryInputStream( const uint8 * mem, uint size ) : m_mem(mem), m_ptr(mem), m_size(size) { }
m_mem(mem), m_ptr(mem), m_size(size) { }
/** @name Stream implementation. */ /** @name Stream implementation. */
//@{ //@{
/// Read data. /// Read data.
virtual uint serialize( void * data, uint len ) virtual uint serialize( void * data, uint len )
{ {
nvDebugCheck(data != NULL); nvDebugCheck(data != NULL);
nvDebugCheck(!isError()); nvDebugCheck(!isError());
uint left = m_size - tell(); uint left = m_size - tell();
if (len > left) len = left; if (len > left) len = left;
memcpy( data, m_ptr, len ); memcpy( data, m_ptr, len );
m_ptr += len; m_ptr += len;
return len; return len;
} }
virtual void seek( uint pos ) virtual void seek( uint pos )
{ {
nvDebugCheck(!isError()); nvDebugCheck(!isError());
m_ptr = m_mem + pos; m_ptr = m_mem + pos;
nvDebugCheck(!isError()); nvDebugCheck(!isError());
} }
virtual uint tell() const virtual uint tell() const
{ {
nvDebugCheck(m_ptr >= m_mem); nvDebugCheck(m_ptr >= m_mem);
return uint(m_ptr - m_mem); return uint(m_ptr - m_mem);
} }
virtual uint size() const virtual uint size() const
{ {
return m_size; return m_size;
} }
virtual bool isError() const virtual bool isError() const
{ {
return m_mem == NULL || m_ptr > m_mem + m_size || m_ptr < m_mem; return m_mem == NULL || m_ptr > m_mem + m_size || m_ptr < m_mem;
} }
virtual void clearError() virtual void clearError()
{ {
// Nothing to do. // Nothing to do.
} }
virtual bool isAtEnd() const virtual bool isAtEnd() const
{ {
return m_ptr == m_mem + m_size; return m_ptr == m_mem + m_size;
} }
/// Always true. /// Always true.
virtual bool isSeekable() const virtual bool isSeekable() const
{ {
return true; return true;
} }
virtual bool isLoading() const virtual bool isLoading() const
{ {
return true; return true;
} }
virtual bool isSaving() const virtual bool isSaving() const
{ {
return false; return false;
} }
//@} //@}
private: private:

View File

@ -426,6 +426,21 @@ StringBuilder & StringBuilder::copy( const StringBuilder & s )
return *this; return *this;
} }
bool StringBuilder::endsWith(const char * str) const
{
size_t l = strlen(str);
size_t ml = strlen(m_str);
if (ml < l) return false;
return strncmp(m_str + ml - l, str, l) == 0;
}
bool StringBuilder::beginsWith(const char * str) const
{
size_t l = strlen(str);
return strncmp(m_str, str, l) == 0;
}
/** Reset the string. */ /** Reset the string. */
void StringBuilder::reset() void StringBuilder::reset()
{ {

View File

@ -82,6 +82,9 @@ namespace nv
StringBuilder & toLower(); StringBuilder & toLower();
StringBuilder & toUpper(); StringBuilder & toUpper();
bool endsWith(const char * str) const;
bool beginsWith(const char * str) const;
void reset(); void reset();
bool isNull() const { return m_size == 0; } bool isNull() const { return m_size == 0; }

View File

@ -10,20 +10,24 @@
#include <time.h> //clock #include <time.h> //clock
class NVCORE_CLASS Timer namespace nv {
{
public:
Timer() {}
void start() { m_start = clock(); } class NVCORE_CLASS Timer
void stop() { m_stop = clock(); } {
public:
Timer() {}
float elapsed() const { return float(m_stop - m_start) / CLOCKS_PER_SEC; } void start() { m_start = clock(); }
void stop() { m_stop = clock(); }
private: float elapsed() const { return float(m_stop - m_start) / CLOCKS_PER_SEC; }
clock_t m_start;
clock_t m_stop; private:
}; clock_t m_start;
clock_t m_stop;
};
} // nv namespace
#else #else

View File

@ -141,9 +141,8 @@ void ColorBlock::swizzle(uint x, uint y, uint z, uint w)
/// Returns true if the block has a single color. /// Returns true if the block has a single color.
bool ColorBlock::isSingleColor() const bool ColorBlock::isSingleColor(Color32 mask/*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const
{ {
Color32 mask(0xFF, 0xFF, 0xFF, 0x00);
uint u = m_color[0].u & mask.u; uint u = m_color[0].u & mask.u;
for (int i = 1; i < 16; i++) for (int i = 1; i < 16; i++)
@ -184,7 +183,7 @@ bool ColorBlock::isSingleColorNoAlpha() const
*/ */
/// Count number of unique colors in this color block. /// Count number of unique colors in this color block.
uint ColorBlock::countUniqueColors() const /*uint ColorBlock::countUniqueColors() const
{ {
uint count = 0; uint count = 0;
@ -204,7 +203,7 @@ uint ColorBlock::countUniqueColors() const
} }
return count; return count;
} }*/
/*/// Get average color of the block. /*/// Get average color of the block.
Color32 ColorBlock::averageColor() const Color32 ColorBlock::averageColor() const

View File

@ -25,9 +25,8 @@ namespace nv
void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0 void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
bool isSingleColor() const; bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
//bool isSingleColorNoAlpha() const; //uint countUniqueColors() const;
uint countUniqueColors() const;
//Color32 averageColor() const; //Color32 averageColor() const;
bool hasAlpha() const; bool hasAlpha() const;

0
src/nvmath/Box.cpp Executable file → Normal file
View File

View File

@ -221,10 +221,38 @@ void NormalCompressorDXT5::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alph
void NormalCompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) void NormalCompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
{ {
rgba.swizzle(4, 1, 5, 0); // 0xFF, G, 0, R
BlockDXT5 * block = new(output) BlockDXT5; BlockDXT5 * block = new(output) BlockDXT5;
// Compress Y.
if (compressionOptions.quality == Quality_Highest)
{
OptimalCompress::compressDXT1G(rgba, &block->color);
}
else
{
if (rgba.isSingleColor(Color32(0, 0xFF, 0, 0))) // Mask all but green channel.
{
OptimalCompress::compressDXT1G(rgba.color(0).g, &block->color);
}
else
{
ColorBlock tile = rgba;
tile.swizzle(4, 1, 5, 3); // leave alpha in alpha channel.
nvsquish::WeightedClusterFit fit;
fit.SetMetric(0, 1, 0);
int flags = 0;
if (alphaMode == nvtt::AlphaMode_Transparency) flags |= nvsquish::kWeightColourByAlpha;
nvsquish::ColourSet colours((uint8 *)tile.colors(), flags);
fit.SetColourSet(&colours, 0);
fit.Compress(&block->color);
}
}
rgba.swizzle(4, 1, 5, 0); // 1, G, 0, R
// Compress X. // Compress X.
if (compressionOptions.quality == Quality_Highest) if (compressionOptions.quality == Quality_Highest)
{ {
@ -234,31 +262,6 @@ void NormalCompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alp
{ {
QuickCompress::compressDXT5A(rgba, &block->alpha); QuickCompress::compressDXT5A(rgba, &block->alpha);
} }
// Compress Y.
if (compressionOptions.quality == Quality_Highest)
{
OptimalCompress::compressDXT1G(rgba, &block->color);
}
else
{
if (rgba.isSingleColor())
{
OptimalCompress::compressDXT1G(rgba.color(0), &block->color);
}
else
{
nvsquish::WeightedClusterFit fit;
fit.SetMetric(0, 1, 0);
int flags = 0;
if (alphaMode == nvtt::AlphaMode_Transparency) flags |= nvsquish::kWeightColourByAlpha;
nvsquish::ColourSet colours((uint8 *)rgba.colors(), flags);
fit.SetColourSet(&colours, 0);
fit.Compress(&block->color);
}
}
} }

View File

@ -312,13 +312,19 @@ bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const
} }
FloatImage * img = m->imageArray[idx]; FloatImage * img = m->imageArray[idx];
if (img->width() != w || img->height() != h) if (img != NULL) {
{ if (img->width() != w || img->height() != h) {
return false; return false;
}
} }
detach(); detach();
if (img == NULL) {
img = m->imageArray[idx] = new FloatImage();
img->allocate(4, w, h);
}
const int count = w * h; const int count = w * h;
float * restrict rdst = img->channel(0); float * restrict rdst = img->channel(0);
@ -333,10 +339,10 @@ bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const
try { try {
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
rdst[i] = src[i].r; rdst[i] = float(src[i].r) / 255.0f;
gdst[i] = src[i].g; gdst[i] = float(src[i].g) / 255.0f;
bdst[i] = src[i].b; bdst[i] = float(src[i].b) / 255.0f;
adst[i] = src[i].a; adst[i] = float(src[i].a) / 255.0f;
} }
} }
catch(...) { catch(...) {

View File

@ -391,7 +391,6 @@ namespace nvtt
/// A texture mipmap. /// A texture mipmap.
struct TexImage struct TexImage
{ {
NVTT_API TexImage();
NVTT_API TexImage(const TexImage & tex); NVTT_API TexImage(const TexImage & tex);
NVTT_API ~TexImage(); NVTT_API ~TexImage();
@ -459,6 +458,7 @@ namespace nvtt
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel); NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
private: private:
TexImage();
void detach(); void detach();
friend struct Compressor; friend struct Compressor;

View File

@ -558,7 +558,7 @@ int main(int argc, char *argv[])
// fflush(stdout); // fflush(stdout);
// getchar(); // getchar();
Timer timer; nv::Timer timer;
timer.start(); timer.start();
if (!context.process(inputOptions, compressionOptions, outputOptions)) if (!context.process(inputOptions, compressionOptions, outputOptions))