Merge recent changes from the witness.
This commit is contained in:
@ -59,7 +59,9 @@ void CompressionOptions::reset()
|
||||
m.gsize = 8;
|
||||
m.bsize = 8;
|
||||
m.asize = 8;
|
||||
m.pixelType = PixelType_UnsignedNorm;
|
||||
|
||||
m.pixelType = PixelType_UnsignedNorm;
|
||||
m.pitchAlignment = 1;
|
||||
|
||||
m.enableColorDithering = false;
|
||||
m.enableAlphaDithering = false;
|
||||
@ -98,10 +100,10 @@ void CompressionOptions::setColorWeights(float red, float green, float blue, flo
|
||||
|
||||
|
||||
/// Set color mask to describe the RGB/RGBA format.
|
||||
void CompressionOptions::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
|
||||
void CompressionOptions::setPixelFormat(uint bitCount, uint rmask, uint gmask, uint bmask, uint amask)
|
||||
{
|
||||
// Validate arguments.
|
||||
nvCheck(bitcount == 8 || bitcount == 16 || bitcount == 24 || bitcount == 32);
|
||||
nvCheck(bitCount <= 32);
|
||||
nvCheck((rmask & gmask) == 0);
|
||||
nvCheck((rmask & bmask) == 0);
|
||||
nvCheck((rmask & amask) == 0);
|
||||
@ -109,16 +111,16 @@ void CompressionOptions::setPixelFormat(uint bitcount, uint rmask, uint gmask, u
|
||||
nvCheck((gmask & amask) == 0);
|
||||
nvCheck((bmask & amask) == 0);
|
||||
|
||||
if (bitcount != 32)
|
||||
if (bitCount != 32)
|
||||
{
|
||||
uint maxMask = (1 << bitcount);
|
||||
uint maxMask = (1 << bitCount);
|
||||
nvCheck(maxMask > rmask);
|
||||
nvCheck(maxMask > gmask);
|
||||
nvCheck(maxMask > bmask);
|
||||
nvCheck(maxMask > amask);
|
||||
}
|
||||
|
||||
m.bitcount = bitcount;
|
||||
m.bitcount = bitCount;
|
||||
m.rmask = rmask;
|
||||
m.gmask = gmask;
|
||||
m.bmask = bmask;
|
||||
@ -153,6 +155,14 @@ void CompressionOptions::setPixelType(PixelType pixelType)
|
||||
}
|
||||
|
||||
|
||||
/// Set pitch alignment in bytes.
|
||||
void CompressionOptions::setPitchAlignment(int pitchAlignment)
|
||||
{
|
||||
nvDebugCheck(pitchAlignment > 0 && isPowerOfTwo(pitchAlignment));
|
||||
m.pitchAlignment = pitchAlignment;
|
||||
}
|
||||
|
||||
|
||||
/// Use external compressor.
|
||||
void CompressionOptions::setExternalCompressor(const char * name)
|
||||
{
|
||||
|
@ -51,7 +51,8 @@ namespace nvtt
|
||||
uint8 asize;
|
||||
|
||||
PixelType pixelType;
|
||||
|
||||
uint pitchAlignment;
|
||||
|
||||
nv::String externalCompressor;
|
||||
|
||||
// Quantization.
|
||||
|
@ -40,12 +40,9 @@ using namespace nvtt;
|
||||
namespace
|
||||
{
|
||||
|
||||
inline uint computePitch(uint w, uint bitsize)
|
||||
inline uint computePitch(uint w, uint bitsize, uint alignment)
|
||||
{
|
||||
uint p = w * ((bitsize + 7) / 8);
|
||||
|
||||
// Align to 32 bits.
|
||||
return ((p + 3) / 4) * 4;
|
||||
return ((w * bitsize + 8 * alignment - 1) / (8 * alignment)) * alignment;
|
||||
}
|
||||
|
||||
inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w)
|
||||
@ -65,6 +62,67 @@ namespace
|
||||
return half_from_float(c.u);
|
||||
}
|
||||
|
||||
struct BitStream
|
||||
{
|
||||
BitStream(uint8 * ptr) : ptr(ptr), buffer(0), bits(0) {
|
||||
}
|
||||
|
||||
void putBits(uint p, int bitCount)
|
||||
{
|
||||
nvDebugCheck(bits < 8);
|
||||
nvDebugCheck(bitCount <= 32);
|
||||
|
||||
uint64 buffer = (this->buffer << bitCount) | p;
|
||||
uint bits = this->bits + bitCount;
|
||||
|
||||
while (bits >= 8)
|
||||
{
|
||||
*ptr++ = (buffer & 0xFF);
|
||||
|
||||
buffer >>= 8;
|
||||
bits -= 8;
|
||||
}
|
||||
|
||||
this->buffer = (uint8)buffer;
|
||||
this->bits = bits;
|
||||
}
|
||||
|
||||
void putFloat(float f)
|
||||
{
|
||||
nvDebugCheck(bits == 0);
|
||||
*((float *)ptr) = f;
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
void putHalf(float f)
|
||||
{
|
||||
nvDebugCheck(bits == 0);
|
||||
*((uint16 *)ptr) = to_half(f);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
nvDebugCheck(bits < 8);
|
||||
if (bits) {
|
||||
*ptr++ = buffer;
|
||||
buffer = 0;
|
||||
bits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void align(int alignment)
|
||||
{
|
||||
nvDebugCheck(alignment >= 1);
|
||||
flush();
|
||||
putBits(0, ((size_t)ptr % alignment) * 8);
|
||||
}
|
||||
|
||||
uint8 * ptr;
|
||||
uint8 buffer;
|
||||
uint8 bits;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@ -96,7 +154,7 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
||||
if (compressionOptions.bitcount != 0)
|
||||
{
|
||||
bitCount = compressionOptions.bitcount;
|
||||
nvCheck(bitCount == 8 || bitCount == 16 || bitCount == 24 || bitCount == 32);
|
||||
nvCheck(bitCount <= 32);
|
||||
|
||||
rmask = compressionOptions.rmask;
|
||||
gmask = compressionOptions.gmask;
|
||||
@ -130,20 +188,16 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
||||
}
|
||||
}
|
||||
|
||||
uint byteCount = (bitCount + 7) / 8;
|
||||
uint pitch = computePitch(w, bitCount);
|
||||
|
||||
uint srcPitch = w;
|
||||
uint srcPlane = w * h;
|
||||
|
||||
const uint pitch = computePitch(w, bitCount, compressionOptions.pitchAlignment);
|
||||
const uint wh = w * h;
|
||||
|
||||
// Allocate output scanline.
|
||||
uint8 * dst = (uint8 *)mem::malloc(pitch + 4);
|
||||
uint8 * const dst = (uint8 *)mem::malloc(pitch);
|
||||
|
||||
for (uint y = 0; y < h; y++)
|
||||
{
|
||||
const uint * src = (const uint *)data + y * srcPitch;
|
||||
const float * fsrc = (const float *)data + y * srcPitch;
|
||||
const uint * src = (const uint *)data + y * w;
|
||||
const float * fsrc = (const float *)data + y * w;
|
||||
|
||||
if (inputFormat == nvtt::InputFormat_BGRA_8UB && compressionOptions.pixelType == nvtt::PixelType_UnsignedNorm && bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000)
|
||||
{
|
||||
@ -151,7 +205,7 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 * ptr = dst;
|
||||
BitStream stream(dst);
|
||||
|
||||
for (uint x = 0; x < w; x++)
|
||||
{
|
||||
@ -171,29 +225,25 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
||||
//g = ((float *)src)[4 * x + 1];
|
||||
//b = ((float *)src)[4 * x + 2];
|
||||
//a = ((float *)src)[4 * x + 3];
|
||||
r = fsrc[x + 0 * srcPlane];
|
||||
g = fsrc[x + 1 * srcPlane];
|
||||
b = fsrc[x + 2 * srcPlane];
|
||||
a = fsrc[x + 3 * srcPlane];
|
||||
r = fsrc[x + 0 * wh];
|
||||
g = fsrc[x + 1 * wh];
|
||||
b = fsrc[x + 2 * wh];
|
||||
a = fsrc[x + 3 * wh];
|
||||
}
|
||||
|
||||
if (compressionOptions.pixelType == nvtt::PixelType_Float)
|
||||
{
|
||||
if (rsize == 32) *((float *)ptr) = r;
|
||||
else if (rsize == 16) *((uint16 *)ptr) = to_half(r);
|
||||
ptr += rsize / 8;
|
||||
if (rsize == 32) stream.putFloat(r);
|
||||
else if (rsize == 16) stream.putHalf(r);
|
||||
|
||||
if (gsize == 32) *((float *)ptr) = g;
|
||||
else if (gsize == 16) *((uint16 *)ptr) = to_half(g);
|
||||
ptr += gsize / 8;
|
||||
if (gsize == 32) stream.putFloat(g);
|
||||
else if (gsize == 16) stream.putHalf(g);
|
||||
|
||||
if (bsize == 32) *((float *)ptr) = b;
|
||||
else if (bsize == 16) *((uint16 *)ptr) = to_half(b);
|
||||
ptr += bsize / 8;
|
||||
if (bsize == 32) stream.putFloat(b);
|
||||
else if (bsize == 16) stream.putHalf(b);
|
||||
|
||||
if (asize == 32) *((float *)ptr) = a;
|
||||
else if (asize == 16) *((uint16 *)ptr) = to_half(a);
|
||||
ptr += asize / 8;
|
||||
if (asize == 32) stream.putFloat(a);
|
||||
else if (asize == 16) stream.putHalf(a);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -212,25 +262,27 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
||||
p |= PixelFormat::convert(c.b, 8, bsize) << bshift;
|
||||
p |= PixelFormat::convert(c.a, 8, asize) << ashift;
|
||||
|
||||
stream.putBits(p, bitCount);
|
||||
|
||||
// Output one byte at a time.
|
||||
for (uint i = 0; i < byteCount; i++)
|
||||
/*for (uint i = 0; i < byteCount; i++)
|
||||
{
|
||||
*(dst + x * byteCount + i) = (p >> (i * 8)) & 0xFF;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
// Zero padding.
|
||||
for (uint x = w * byteCount; x < pitch; x++)
|
||||
stream.align(compressionOptions.pitchAlignment);
|
||||
nvDebugCheck(stream.ptr == dst + pitch);
|
||||
|
||||
/*for (uint x = w * byteCount; x < pitch; x++)
|
||||
{
|
||||
*(dst + x) = 0;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if (outputOptions.outputHandler != NULL)
|
||||
{
|
||||
outputOptions.outputHandler->writeData(dst, pitch);
|
||||
}
|
||||
outputOptions.writeData(dst, pitch);
|
||||
}
|
||||
|
||||
mem::free(dst);
|
||||
|
@ -89,18 +89,15 @@ namespace
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint computePitch(uint w, uint bitsize)
|
||||
{
|
||||
uint p = w * ((bitsize + 7) / 8);
|
||||
inline uint computePitch(uint w, uint bitsize, uint alignment)
|
||||
{
|
||||
return ((w * bitsize + 8 * alignment - 1) / (8 * alignment)) * alignment;
|
||||
}
|
||||
|
||||
// Align to 32 bits.
|
||||
return ((p + 3) / 4) * 4;
|
||||
}
|
||||
|
||||
static int computeImageSize(uint w, uint h, uint d, uint bitCount, Format format)
|
||||
static int computeImageSize(uint w, uint h, uint d, uint bitCount, uint alignment, Format format)
|
||||
{
|
||||
if (format == Format_RGBA) {
|
||||
return d * h * computePitch(w, bitCount);
|
||||
return d * h * computePitch(w, bitCount, alignment);
|
||||
}
|
||||
else {
|
||||
// @@ Handle 3D textures. DXT and VTC have different behaviors.
|
||||
@ -324,7 +321,7 @@ int Compressor::estimateSize(int w, int h, int d, const CompressionOptions & com
|
||||
|
||||
uint bitCount = co.getBitCount();
|
||||
|
||||
return computeImageSize(w, h, d, bitCount, format);
|
||||
return computeImageSize(w, h, d, bitCount, co.pitchAlignment, format);
|
||||
}
|
||||
|
||||
|
||||
@ -413,7 +410,20 @@ bool Compressor::Private::outputHeader(const InputOptions::Private & inputOption
|
||||
if (outputOptions.container == Container_DDS || outputOptions.container == Container_DDS10)
|
||||
{
|
||||
DDSHeader header;
|
||||
|
||||
|
||||
header.setUserVersion(outputOptions.version);
|
||||
|
||||
if (inputOptions.textureType == TextureType_2D) {
|
||||
header.setTexture2D();
|
||||
}
|
||||
else if (inputOptions.textureType == TextureType_Cube) {
|
||||
header.setTextureCube();
|
||||
}
|
||||
/*else if (inputOptions.textureType == TextureType_3D) {
|
||||
header.setTexture3D();
|
||||
header.setDepth(inputOptions.targetDepth);
|
||||
}*/
|
||||
|
||||
header.setWidth(inputOptions.targetWidth);
|
||||
header.setHeight(inputOptions.targetHeight);
|
||||
|
||||
@ -499,7 +509,7 @@ bool Compressor::Private::outputHeader(const InputOptions::Private & inputOption
|
||||
if (compressionOptions.format == Format_RGBA)
|
||||
{
|
||||
// Get output bit count.
|
||||
header.setPitch(computePitch(inputOptions.targetWidth, compressionOptions.getBitCount()));
|
||||
header.setPitch(computePitch(inputOptions.targetWidth, compressionOptions.getBitCount(), compressionOptions.pitchAlignment));
|
||||
|
||||
if (compressionOptions.pixelType == PixelType_Float)
|
||||
{
|
||||
@ -564,7 +574,7 @@ bool Compressor::Private::outputHeader(const InputOptions::Private & inputOption
|
||||
}
|
||||
else
|
||||
{
|
||||
header.setLinearSize(computeImageSize(inputOptions.targetWidth, inputOptions.targetHeight, inputOptions.targetDepth, compressionOptions.bitcount, compressionOptions.format));
|
||||
header.setLinearSize(computeImageSize(inputOptions.targetWidth, inputOptions.targetHeight, inputOptions.targetDepth, compressionOptions.bitcount, compressionOptions.pitchAlignment, compressionOptions.format));
|
||||
|
||||
if (compressionOptions.format == Format_DXT1 || compressionOptions.format == Format_DXT1a || compressionOptions.format == Format_DXT1n) {
|
||||
header.setFourCC('D', 'X', 'T', '1');
|
||||
@ -618,17 +628,6 @@ bool Compressor::Private::outputHeader(const InputOptions::Private & inputOption
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inputOptions.textureType == TextureType_2D) {
|
||||
header.setTexture2D();
|
||||
}
|
||||
else if (inputOptions.textureType == TextureType_Cube) {
|
||||
header.setTextureCube();
|
||||
}
|
||||
/*else if (inputOptions.textureType == TextureType_3D) {
|
||||
header.setTexture3D();
|
||||
header.setDepth(inputOptions.targetDepth);
|
||||
}*/
|
||||
|
||||
// Swap bytes if necessary.
|
||||
header.swapBytes();
|
||||
|
||||
@ -669,6 +668,19 @@ bool Compressor::Private::outputHeader(const TexImage & tex, int mipmapCount, co
|
||||
{
|
||||
DDSHeader header;
|
||||
|
||||
header.setUserVersion(outputOptions.version);
|
||||
|
||||
if (tex.textureType() == TextureType_2D) {
|
||||
header.setTexture2D();
|
||||
}
|
||||
else if (tex.textureType() == TextureType_Cube) {
|
||||
header.setTextureCube();
|
||||
}
|
||||
/*else if (tex.textureType() == TextureType_3D) {
|
||||
header.setTexture3D();
|
||||
header.setDepth(tex.depth());
|
||||
}*/
|
||||
|
||||
header.setWidth(tex.width());
|
||||
header.setHeight(tex.height());
|
||||
header.setMipmapCount(mipmapCount);
|
||||
@ -750,7 +762,7 @@ bool Compressor::Private::outputHeader(const TexImage & tex, int mipmapCount, co
|
||||
if (compressionOptions.format == Format_RGBA)
|
||||
{
|
||||
// Get output bit count.
|
||||
header.setPitch(computePitch(tex.width(), compressionOptions.getBitCount()));
|
||||
header.setPitch(computePitch(tex.width(), compressionOptions.getBitCount(), compressionOptions.pitchAlignment));
|
||||
|
||||
if (compressionOptions.pixelType == PixelType_Float)
|
||||
{
|
||||
@ -815,7 +827,7 @@ bool Compressor::Private::outputHeader(const TexImage & tex, int mipmapCount, co
|
||||
}
|
||||
else
|
||||
{
|
||||
header.setLinearSize(computeImageSize(tex.width(), tex.height(), tex.depth(), compressionOptions.bitcount, compressionOptions.format));
|
||||
header.setLinearSize(computeImageSize(tex.width(), tex.height(), tex.depth(), compressionOptions.bitcount, compressionOptions.pitchAlignment, compressionOptions.format));
|
||||
|
||||
if (compressionOptions.format == Format_DXT1 || compressionOptions.format == Format_DXT1a || compressionOptions.format == Format_DXT1n) {
|
||||
header.setFourCC('D', 'X', 'T', '1');
|
||||
@ -869,17 +881,6 @@ bool Compressor::Private::outputHeader(const TexImage & tex, int mipmapCount, co
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tex.textureType() == TextureType_2D) {
|
||||
header.setTexture2D();
|
||||
}
|
||||
else if (tex.textureType() == TextureType_Cube) {
|
||||
header.setTextureCube();
|
||||
}
|
||||
/*else if (tex.textureType() == TextureType_3D) {
|
||||
header.setTexture3D();
|
||||
header.setDepth(tex.depth());
|
||||
}*/
|
||||
|
||||
// Swap bytes if necessary.
|
||||
header.swapBytes();
|
||||
|
||||
@ -890,7 +891,7 @@ bool Compressor::Private::outputHeader(const TexImage & tex, int mipmapCount, co
|
||||
headerSize = 128 + 20;
|
||||
}
|
||||
|
||||
bool writeSucceed = outputOptions.outputHandler->writeData(&header, headerSize);
|
||||
bool writeSucceed = outputOptions.writeData(&header, headerSize);
|
||||
if (!writeSucceed)
|
||||
{
|
||||
outputOptions.error(Error_FileWrite);
|
||||
@ -916,7 +917,7 @@ bool Compressor::Private::compressMipmaps(uint f, const InputOptions::Private &
|
||||
|
||||
for (uint m = 0; m < mipmapCount; m++)
|
||||
{
|
||||
int size = computeImageSize(w, h, d, compressionOptions.getBitCount(), compressionOptions.format);
|
||||
int size = computeImageSize(w, h, d, compressionOptions.getBitCount(), compressionOptions.pitchAlignment, compressionOptions.format);
|
||||
outputOptions.beginImage(size, w, h, d, f, m);
|
||||
|
||||
if (!initMipmap(mipmap, inputOptions, w, h, d, f, m))
|
||||
@ -1553,12 +1554,12 @@ int Compressor::Private::estimateSize(const InputOptions::Private & inputOptions
|
||||
{
|
||||
const Format format = compressionOptions.format;
|
||||
|
||||
uint bitCount = compressionOptions.bitcount;
|
||||
if (format == Format_RGBA && bitCount == 0) bitCount = compressionOptions.rsize + compressionOptions.gsize + compressionOptions.bsize + compressionOptions.asize;
|
||||
const uint bitCount = compressionOptions.getBitCount();
|
||||
const uint pitchAlignment = compressionOptions.pitchAlignment;
|
||||
|
||||
inputOptions.computeTargetExtents();
|
||||
|
||||
uint mipmapCount = inputOptions.realMipmapCount();
|
||||
const uint mipmapCount = inputOptions.realMipmapCount();
|
||||
|
||||
int size = 0;
|
||||
|
||||
@ -1570,7 +1571,7 @@ int Compressor::Private::estimateSize(const InputOptions::Private & inputOptions
|
||||
|
||||
for (uint m = 0; m < mipmapCount; m++)
|
||||
{
|
||||
size += computeImageSize(w, h, d, bitCount, format);
|
||||
size += computeImageSize(w, h, d, bitCount, pitchAlignment, format);
|
||||
|
||||
// Compute extents of next mipmap:
|
||||
w = max(1U, w / 2);
|
||||
|
@ -49,13 +49,20 @@ void OutputOptions::reset()
|
||||
|
||||
m.outputHeader = true;
|
||||
m.container = Container_DDS;
|
||||
m.version = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Set output file name.
|
||||
void OutputOptions::setFileName(const char * fileName)
|
||||
{
|
||||
m.fileName = fileName; // @@ Do we need to record filename?
|
||||
if (!m.fileName.isNull())
|
||||
{
|
||||
// To close the file and avoid leak.
|
||||
delete m.outputHandler;
|
||||
}
|
||||
|
||||
m.fileName = fileName;
|
||||
m.outputHandler = NULL;
|
||||
|
||||
DefaultOutputHandler * oh = new DefaultOutputHandler(fileName);
|
||||
@ -94,6 +101,11 @@ void OutputOptions::setContainer(Container container)
|
||||
m.container = container;
|
||||
}
|
||||
|
||||
/// Set user version.
|
||||
void OutputOptions::setUserVersion(int version)
|
||||
{
|
||||
m.version = version;
|
||||
}
|
||||
|
||||
bool OutputOptions::Private::hasValidOutputHandler() const
|
||||
{
|
||||
|
@ -35,9 +35,7 @@ namespace nvtt
|
||||
{
|
||||
DefaultOutputHandler(const char * fileName) : stream(fileName) {}
|
||||
|
||||
virtual ~DefaultOutputHandler()
|
||||
{
|
||||
}
|
||||
virtual ~DefaultOutputHandler() {}
|
||||
|
||||
virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel)
|
||||
{
|
||||
@ -66,6 +64,7 @@ namespace nvtt
|
||||
|
||||
bool outputHeader;
|
||||
Container container;
|
||||
int version;
|
||||
|
||||
bool hasValidOutputHandler() const;
|
||||
|
||||
|
@ -271,23 +271,19 @@ float TexImage::alphaTestCoverage(float alphaRef/*= 0.5*/) const
|
||||
|
||||
bool TexImage::load(const char * fileName)
|
||||
{
|
||||
#pragma message(NV_FILE_LINE "TODO: Add support for DDS textures in TexImage::load().")
|
||||
AutoPtr<FloatImage> img(ImageIO::loadFloat(fileName));
|
||||
if (img == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoPtr<FloatImage> img(ImageIO::loadFloat(fileName));
|
||||
detach();
|
||||
|
||||
if (img == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
img->resizeChannelCount(4);
|
||||
|
||||
detach();
|
||||
m->imageArray.resize(1);
|
||||
m->imageArray[0] = img.release();
|
||||
|
||||
img->resizeChannelCount(4);
|
||||
|
||||
m->imageArray.resize(1);
|
||||
m->imageArray[0] = img.release();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TexImage::save(const char * fileName) const
|
||||
@ -560,25 +556,25 @@ void TexImage::resize(int w, int h, ResizeFilter filter)
|
||||
if (filter == ResizeFilter_Box)
|
||||
{
|
||||
BoxFilter filter;
|
||||
m->imageArray[i]->resize(filter, w, h, wrapMode, 3);
|
||||
img = img->resize(filter, w, h, wrapMode, 3);
|
||||
}
|
||||
else if (filter == ResizeFilter_Triangle)
|
||||
{
|
||||
TriangleFilter filter;
|
||||
m->imageArray[i]->resize(filter, w, h, wrapMode, 3);
|
||||
img = img->resize(filter, w, h, wrapMode, 3);
|
||||
}
|
||||
else if (filter == ResizeFilter_Kaiser)
|
||||
{
|
||||
//KaiserFilter filter(inputOptions.kaiserWidth);
|
||||
//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
|
||||
KaiserFilter filter(3);
|
||||
m->imageArray[i]->resize(filter, w, h, wrapMode, 3);
|
||||
img = img->resize(filter, w, h, wrapMode, 3);
|
||||
}
|
||||
else //if (filter == ResizeFilter_Mitchell)
|
||||
{
|
||||
nvDebugCheck(filter == ResizeFilter_Mitchell);
|
||||
MitchellFilter filter;
|
||||
m->imageArray[i]->resize(filter, w, h, wrapMode, 3);
|
||||
img = img->resize(filter, w, h, wrapMode, 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -586,27 +582,30 @@ void TexImage::resize(int w, int h, ResizeFilter filter)
|
||||
if (filter == ResizeFilter_Box)
|
||||
{
|
||||
BoxFilter filter;
|
||||
m->imageArray[i]->resize(filter, w, h, wrapMode);
|
||||
img = img->resize(filter, w, h, wrapMode);
|
||||
}
|
||||
else if (filter == ResizeFilter_Triangle)
|
||||
{
|
||||
TriangleFilter filter;
|
||||
m->imageArray[i]->resize(filter, w, h, wrapMode);
|
||||
img = img->resize(filter, w, h, wrapMode);
|
||||
}
|
||||
else if (filter == ResizeFilter_Kaiser)
|
||||
{
|
||||
//KaiserFilter filter(inputOptions.kaiserWidth);
|
||||
//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
|
||||
KaiserFilter filter(3);
|
||||
m->imageArray[i]->resize(filter, w, h, wrapMode);
|
||||
img = img->resize(filter, w, h, wrapMode);
|
||||
}
|
||||
else //if (filter == ResizeFilter_Mitchell)
|
||||
{
|
||||
nvDebugCheck(filter == ResizeFilter_Mitchell);
|
||||
MitchellFilter filter;
|
||||
m->imageArray[i]->resize(filter, w, h, wrapMode);
|
||||
img = img->resize(filter, w, h, wrapMode);
|
||||
}
|
||||
}
|
||||
|
||||
delete m->imageArray[i];
|
||||
m->imageArray[i] = img;
|
||||
}
|
||||
}
|
||||
|
||||
@ -813,6 +812,18 @@ void TexImage::scaleBias(int channel, float scale, float bias)
|
||||
}
|
||||
}
|
||||
|
||||
void TexImage::clamp(int channel, float low, float high)
|
||||
{
|
||||
detach();
|
||||
|
||||
foreach (i, m->imageArray)
|
||||
{
|
||||
if (m->imageArray[i] == NULL) continue;
|
||||
|
||||
m->imageArray[i]->clamp(channel, 1, low, high);
|
||||
}
|
||||
}
|
||||
|
||||
void TexImage::packNormal()
|
||||
{
|
||||
scaleBias(0, 0.5f, 0.5f);
|
||||
|
@ -48,7 +48,7 @@
|
||||
# define NVTT_API
|
||||
#endif
|
||||
|
||||
#define NVTT_VERSION 020100
|
||||
#define NVTT_VERSION 20100
|
||||
|
||||
#define NVTT_FORBID_COPY(Class) \
|
||||
private: \
|
||||
@ -144,6 +144,8 @@ namespace nvtt
|
||||
|
||||
NVTT_API void setPixelType(PixelType pixelType);
|
||||
|
||||
NVTT_API void setPitchAlignment(int pitchAlignment);
|
||||
|
||||
NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127);
|
||||
};
|
||||
|
||||
@ -345,6 +347,7 @@ namespace nvtt
|
||||
|
||||
NVTT_API void setOutputHeader(bool outputHeader);
|
||||
NVTT_API void setContainer(Container container);
|
||||
NVTT_API void setUserVersion(int version);
|
||||
};
|
||||
|
||||
|
||||
@ -432,6 +435,7 @@ namespace nvtt
|
||||
NVTT_API void transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4]);
|
||||
NVTT_API void swizzle(int r, int g, int b, int a);
|
||||
NVTT_API void scaleBias(int channel, float scale, float bias);
|
||||
NVTT_API void clamp(int channel, float low = 0.0f, float high = 1.0f);
|
||||
NVTT_API void packNormal();
|
||||
NVTT_API void expandNormal();
|
||||
NVTT_API void blend(float r, float g, float b, float a, float t);
|
||||
|
@ -47,7 +47,7 @@
|
||||
# define NVTT_API
|
||||
#endif
|
||||
|
||||
#define NVTT_VERSION 020100
|
||||
#define NVTT_VERSION 20100
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef struct nvtt::InputOptions NvttInputOptions;
|
||||
|
@ -55,7 +55,7 @@ int main(int argc, char *argv[])
|
||||
outputFileName.stripExtension();
|
||||
outputFileName.append(".dds");
|
||||
|
||||
outputOptions.setFileName(outputFileName);
|
||||
outputOptions.setFileName(outputFileName.str());
|
||||
|
||||
// Output compressed image.
|
||||
context.outputHeader(image, image.countMipmaps(), compressionOptions, outputOptions);
|
||||
|
@ -423,7 +423,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
Path csvFileName;
|
||||
csvFileName.format("%s/result.csv", outPath);
|
||||
StdOutputStream csvStream(csvFileName);
|
||||
StdOutputStream csvStream(csvFileName.str());
|
||||
TextWriter csvWriter(&csvStream);
|
||||
|
||||
float totalTime = 0;
|
||||
@ -465,7 +465,7 @@ int main(int argc, char *argv[])
|
||||
outputFileName.format("%s/%s", outPath, fileNames[i]);
|
||||
outputFileName.stripExtension();
|
||||
outputFileName.append(".png");
|
||||
if (!ImageIO::save(outputFileName, img_out.ptr()))
|
||||
if (!ImageIO::save(outputFileName.str(), img_out.ptr()))
|
||||
{
|
||||
printf("Error saving file '%s'.\n", outputFileName.str());
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
for (uint i = 0; i < imageCount; i++)
|
||||
{
|
||||
if (!images[i].load(files[i]))
|
||||
if (!images[i].load(files[i].str()))
|
||||
{
|
||||
printf("*** error loading file\n");
|
||||
return 1;
|
||||
@ -138,7 +138,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
nv::StdOutputStream stream(output);
|
||||
nv::StdOutputStream stream(output.str());
|
||||
if (stream.isError()) {
|
||||
printf("Error opening '%s' for writting\n", output.str());
|
||||
return 1;
|
||||
|
@ -295,11 +295,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
const uint version = nvtt::version();
|
||||
const uint major = version / 100;
|
||||
const uint minor = version % 100;
|
||||
const uint major = version / 100 / 100;
|
||||
const uint minor = (version / 100) % 100;
|
||||
const uint rev = version % 100;
|
||||
|
||||
|
||||
printf("NVIDIA Texture Tools %u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor);
|
||||
printf("NVIDIA Texture Tools %u.%u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor, rev);
|
||||
|
||||
if (input.isNull())
|
||||
{
|
||||
@ -351,7 +352,7 @@ int main(int argc, char *argv[])
|
||||
if (nv::strCaseCmp(input.extension(), ".dds") == 0)
|
||||
{
|
||||
// Load surface.
|
||||
nv::DirectDrawSurface dds(input);
|
||||
nv::DirectDrawSurface dds(input.str());
|
||||
if (!dds.isValid())
|
||||
{
|
||||
fprintf(stderr, "The file '%s' is not a valid DDS file.\n", input.str());
|
||||
@ -400,7 +401,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (loadAsFloat)
|
||||
{
|
||||
nv::AutoPtr<nv::FloatImage> image(nv::ImageIO::loadFloat(input));
|
||||
nv::AutoPtr<nv::FloatImage> image(nv::ImageIO::loadFloat(input.str()));
|
||||
|
||||
if (image == NULL)
|
||||
{
|
||||
@ -420,7 +421,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
// Regular image.
|
||||
nv::Image image;
|
||||
if (!image.load(input))
|
||||
if (!image.load(input.str()))
|
||||
{
|
||||
fprintf(stderr, "The file '%s' is not a supported image type.\n", input.str());
|
||||
return 1;
|
||||
@ -449,6 +450,9 @@ int main(int argc, char *argv[])
|
||||
inputOptions.setAlphaMode(nvtt::AlphaMode_None);
|
||||
}
|
||||
|
||||
inputOptions.setRoundMode(nvtt::RoundMode_ToNearestPowerOfTwo);
|
||||
|
||||
|
||||
if (normal)
|
||||
{
|
||||
setNormalMap(inputOptions);
|
||||
@ -524,7 +528,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
|
||||
MyErrorHandler errorHandler;
|
||||
MyOutputHandler outputHandler(output);
|
||||
MyOutputHandler outputHandler(output.str());
|
||||
if (outputHandler.stream->isError())
|
||||
{
|
||||
fprintf(stderr, "Error opening '%s' for writting\n", output.str());
|
||||
|
@ -112,7 +112,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Load surface.
|
||||
nv::DirectDrawSurface dds(input);
|
||||
nv::DirectDrawSurface dds(input.str());
|
||||
if (!dds.isValid())
|
||||
{
|
||||
fprintf(stderr, "The file '%s' is not a valid DDS file.\n", input.str());
|
||||
@ -179,7 +179,7 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
nv::ImageIO::save(name, stream, &mipmap);
|
||||
nv::ImageIO::save(name.str(), stream, &mipmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
nv::Image image0, image1;
|
||||
if (!loadImage(image0, input0)) return 0;
|
||||
if (!loadImage(image1, input1)) return 0;
|
||||
if (!loadImage(image0, input0.str())) return 0;
|
||||
if (!loadImage(image1, input1.str())) return 0;
|
||||
|
||||
const uint w0 = image0.width();
|
||||
const uint h0 = image0.height();
|
||||
|
@ -164,7 +164,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
nv::Image image;
|
||||
if (!loadImage(image, input)) return 0;
|
||||
if (!loadImage(image, input.str())) return 0;
|
||||
|
||||
nv::FloatImage fimage(&image);
|
||||
fimage.toLinear(0, 3, gamma);
|
||||
|
Reference in New Issue
Block a user