Merge changes from the-witness.

Fix DXT5n compressor.
pull/216/head
castano 14 years ago
parent ac7c017c35
commit 9e881f28d1

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

@ -426,6 +426,21 @@ StringBuilder & StringBuilder::copy( const StringBuilder & s )
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. */
void StringBuilder::reset()
{

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

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

@ -141,9 +141,8 @@ void ColorBlock::swizzle(uint x, uint y, uint z, uint w)
/// 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;
for (int i = 1; i < 16; i++)
@ -184,7 +183,7 @@ bool ColorBlock::isSingleColorNoAlpha() const
*/
/// Count number of unique colors in this color block.
uint ColorBlock::countUniqueColors() const
/*uint ColorBlock::countUniqueColors() const
{
uint count = 0;
@ -204,7 +203,7 @@ uint ColorBlock::countUniqueColors() const
}
return count;
}
}*/
/*/// Get average color of the block.
Color32 ColorBlock::averageColor() const

@ -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
bool isSingleColor() const;
//bool isSingleColorNoAlpha() const;
uint countUniqueColors() const;
bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
//uint countUniqueColors() const;
//Color32 averageColor() const;
bool hasAlpha() const;

@ -221,20 +221,8 @@ void NormalCompressorDXT5::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alph
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;
// Compress X.
if (compressionOptions.quality == Quality_Highest)
{
OptimalCompress::compressDXT5A(rgba, &block->alpha);
}
else
{
QuickCompress::compressDXT5A(rgba, &block->alpha);
}
// Compress Y.
if (compressionOptions.quality == Quality_Highest)
{
@ -242,23 +230,38 @@ void NormalCompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alp
}
else
{
if (rgba.isSingleColor())
if (rgba.isSingleColor(Color32(0, 0xFF, 0, 0))) // Mask all but green channel.
{
OptimalCompress::compressDXT1G(rgba.color(0), &block->color);
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 *)rgba.colors(), flags);
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.
if (compressionOptions.quality == Quality_Highest)
{
OptimalCompress::compressDXT5A(rgba, &block->alpha);
}
else
{
QuickCompress::compressDXT5A(rgba, &block->alpha);
}
}

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

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

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

Loading…
Cancel
Save