You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nvidia-texture-tools/src/nvtt/SingleColorLookup.cpp

91 lines
2.0 KiB
C++

#include "SingleColorLookup.h"
#include "nvcore/Debug.h"
#include <stdlib.h> // abs
// Globals
uint8 OMatch5[256][2];
uint8 OMatch6[256][2];
uint8 OMatchAlpha5[256][2];
uint8 OMatchAlpha6[256][2];
static int Mul8Bit(int a, int b)
{
int t = a * b + 128;
return (t + (t >> 8)) >> 8;
}
static inline int Lerp13(int a, int b)
{
#ifdef DXT_USE_ROUNDING_BIAS
// with rounding bias
return a + Mul8Bit(b-a, 0x55);
#else
// without rounding bias
// replace "/ 3" by "* 0xaaab) >> 17" if your compiler sucks or you really need every ounce of speed.
return (a * 2 + b) / 3;
#endif
}
static void PrepareOptTable(uint8 * table, const uint8 * expand, int size, bool alpha_mode)
{
for (int i = 0; i < 256; i++)
{
int bestErr = 256 * 100;
for (int min = 0; min < size; min++)
{
for (int max = 0; max < size; max++)
{
int mine = expand[min];
int maxe = expand[max];
int err;
if (alpha_mode) err = abs((maxe + mine)/2 - i);
else err = abs(Lerp13(maxe, mine) - i);
err *= 100;
// DX10 spec says that interpolation must be within 3% of "correct" result,
// add this as error term. (normally we'd expect a random distribution of
// +-1.5% error, but nowhere in the spec does it say that the error has to be
// unbiased - better safe than sorry).
err += abs(max - min) * 3;
if (err < bestErr)
{
table[i*2+0] = max;
table[i*2+1] = min;
bestErr = err;
}
}
}
}
}
NV_AT_STARTUP(initSingleColorLookup());
void initSingleColorLookup()
{
uint8 expand5[32];
uint8 expand6[64];
for (int i = 0; i < 32; i++) {
expand5[i] = (i<<3) | (i>>2);
}
for (int i = 0; i < 64; i++) {
expand6[i] = (i<<2) | (i>>4);
}
PrepareOptTable(&OMatch5[0][0], expand5, 32, false);
PrepareOptTable(&OMatch6[0][0], expand6, 64, false);
PrepareOptTable(&OMatchAlpha5[0][0], expand5, 32, true);
PrepareOptTable(&OMatchAlpha6[0][0], expand6, 64, true);
}