Merge changes from the-witness.
Fix DXT5n compressor.
This commit is contained in:
@ -37,14 +37,13 @@ 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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,22 +54,22 @@ namespace nv
|
|||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,8 +109,7 @@ 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)
|
||||||
@ -125,7 +123,7 @@ namespace nv
|
|||||||
{
|
{
|
||||||
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
|
||||||
@ -149,8 +147,7 @@ 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)
|
||||||
@ -164,7 +161,7 @@ namespace nv
|
|||||||
{
|
{
|
||||||
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
|
||||||
@ -188,8 +185,7 @@ 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. */
|
||||||
//@{
|
//@{
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
|
@ -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; }
|
||||||
|
|
||||||
|
@ -10,9 +10,11 @@
|
|||||||
|
|
||||||
#include <time.h> //clock
|
#include <time.h> //clock
|
||||||
|
|
||||||
class NVCORE_CLASS Timer
|
namespace nv {
|
||||||
{
|
|
||||||
public:
|
class NVCORE_CLASS Timer
|
||||||
|
{
|
||||||
|
public:
|
||||||
Timer() {}
|
Timer() {}
|
||||||
|
|
||||||
void start() { m_start = clock(); }
|
void start() { m_start = clock(); }
|
||||||
@ -20,10 +22,12 @@ public:
|
|||||||
|
|
||||||
float elapsed() const { return float(m_stop - m_start) / CLOCKS_PER_SEC; }
|
float elapsed() const { return float(m_stop - m_start) / CLOCKS_PER_SEC; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
clock_t m_start;
|
clock_t m_start;
|
||||||
clock_t m_stop;
|
clock_t m_stop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // nv namespace
|
||||||
|
|
||||||
#else
|
#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.
|
/// 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
|
||||||
|
@ -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
0
src/nvmath/Box.cpp
Executable file → Normal 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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(...) {
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
|
Reference in New Issue
Block a user