From 5225f4810f1db9025504cb0707c606558946da4b Mon Sep 17 00:00:00 2001 From: castano Date: Wed, 3 Nov 2010 18:53:51 +0000 Subject: [PATCH] Add stubs for quantization methods. --- src/nvtt/CompressionOptions.cpp | 140 +++++++++++----------- src/nvtt/Context.cpp | 204 +++++++++----------------------- src/nvtt/Context.h | 14 +-- src/nvtt/TexImage.cpp | 11 ++ src/nvtt/nvtt.h | 6 +- 5 files changed, 142 insertions(+), 233 deletions(-) diff --git a/src/nvtt/CompressionOptions.cpp b/src/nvtt/CompressionOptions.cpp index e59a95d..53e41a5 100644 --- a/src/nvtt/CompressionOptions.cpp +++ b/src/nvtt/CompressionOptions.cpp @@ -31,56 +31,56 @@ using namespace nvtt; /// Constructor. Sets compression options to the default values. CompressionOptions::CompressionOptions() : m(*new CompressionOptions::Private()) { - reset(); + reset(); } /// Destructor. CompressionOptions::~CompressionOptions() { - delete &m; + delete &m; } /// Set default compression options. void CompressionOptions::reset() { - m.format = Format_DXT1; - m.quality = Quality_Normal; - m.colorWeight.set(1.0f, 1.0f, 1.0f, 1.0f); - - m.bitcount = 32; - m.bmask = 0x000000FF; - m.gmask = 0x0000FF00; - m.rmask = 0x00FF0000; - m.amask = 0xFF000000; - - m.rsize = 8; - m.gsize = 8; - m.bsize = 8; - m.asize = 8; + m.format = Format_DXT1; + m.quality = Quality_Normal; + m.colorWeight.set(1.0f, 1.0f, 1.0f, 1.0f); + + m.bitcount = 32; + m.bmask = 0x000000FF; + m.gmask = 0x0000FF00; + m.rmask = 0x00FF0000; + m.amask = 0xFF000000; + + m.rsize = 8; + m.gsize = 8; + m.bsize = 8; + m.asize = 8; m.pixelType = PixelType_UnsignedNorm; m.pitchAlignment = 1; - m.enableColorDithering = false; - m.enableAlphaDithering = false; - m.binaryAlpha = false; - m.alphaThreshold = 127; + m.enableColorDithering = false; + m.enableAlphaDithering = false; + m.binaryAlpha = false; + m.alphaThreshold = 127; } /// Set desired compression format. void CompressionOptions::setFormat(Format format) { - m.format = format; + m.format = format; } /// Set compression quality settings. void CompressionOptions::setQuality(Quality quality) { - m.quality = quality; + m.quality = quality; } @@ -95,63 +95,63 @@ void CompressionOptions::setColorWeights(float red, float green, float blue, flo // float x = red / total; // float y = green / total; // m.colorWeight.set(x, y, 1.0f - x - y); - m.colorWeight.set(red, green, blue, alpha); + m.colorWeight.set(red, green, blue, alpha); } /// Set color mask to describe the RGB/RGBA format. void CompressionOptions::setPixelFormat(uint bitCount, uint rmask, uint gmask, uint bmask, uint amask) { - // Validate arguments. + // Validate arguments. nvCheck(bitCount <= 32); - nvCheck((rmask & gmask) == 0); - nvCheck((rmask & bmask) == 0); - nvCheck((rmask & amask) == 0); - nvCheck((gmask & bmask) == 0); - nvCheck((gmask & amask) == 0); - nvCheck((bmask & amask) == 0); - - if (bitCount != 32) - { - uint maxMask = (1 << bitCount); - nvCheck(maxMask > rmask); - nvCheck(maxMask > gmask); - nvCheck(maxMask > bmask); - nvCheck(maxMask > amask); - } - - m.bitcount = bitCount; - m.rmask = rmask; - m.gmask = gmask; - m.bmask = bmask; - m.amask = amask; - - m.rsize = 0; - m.gsize = 0; - m.bsize = 0; - m.asize = 0; + nvCheck((rmask & gmask) == 0); + nvCheck((rmask & bmask) == 0); + nvCheck((rmask & amask) == 0); + nvCheck((gmask & bmask) == 0); + nvCheck((gmask & amask) == 0); + nvCheck((bmask & amask) == 0); + + if (bitCount != 32) + { + uint maxMask = (1 << bitCount); + nvCheck(maxMask > rmask); + nvCheck(maxMask > gmask); + nvCheck(maxMask > bmask); + nvCheck(maxMask > amask); + } + + m.bitcount = bitCount; + m.rmask = rmask; + m.gmask = gmask; + m.bmask = bmask; + m.amask = amask; + + m.rsize = 0; + m.gsize = 0; + m.bsize = 0; + m.asize = 0; } void CompressionOptions::setPixelFormat(uint8 rsize, uint8 gsize, uint8 bsize, uint8 asize) { - nvCheck(rsize <= 32 || gsize <= 32 || bsize <= 32 || asize <= 32); - - m.bitcount = 0; - m.rmask = 0; - m.gmask = 0; - m.bmask = 0; - m.amask = 0; - - m.rsize = rsize; - m.gsize = gsize; - m.bsize = bsize; - m.asize = asize; + nvCheck(rsize <= 32 || gsize <= 32 || bsize <= 32 || asize <= 32); + + m.bitcount = 0; + m.rmask = 0; + m.gmask = 0; + m.bmask = 0; + m.amask = 0; + + m.rsize = rsize; + m.gsize = gsize; + m.bsize = bsize; + m.asize = asize; } /// Set pixel type. void CompressionOptions::setPixelType(PixelType pixelType) { - m.pixelType = pixelType; + m.pixelType = pixelType; } @@ -159,14 +159,14 @@ void CompressionOptions::setPixelType(PixelType pixelType) void CompressionOptions::setPitchAlignment(int pitchAlignment) { nvDebugCheck(pitchAlignment > 0 && isPowerOfTwo(pitchAlignment)); - m.pitchAlignment = pitchAlignment; + m.pitchAlignment = pitchAlignment; } /// Use external compressor. void CompressionOptions::setExternalCompressor(const char * name) { - m.externalCompressor = name; + m.externalCompressor = name; } /// Set quantization options. @@ -176,11 +176,11 @@ void CompressionOptions::setExternalCompressor(const char * name) /// the compressor. void CompressionOptions::setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold/*= 127*/) { - nvCheck(alphaThreshold >= 0 && alphaThreshold < 256); - m.enableColorDithering = colorDithering; - m.enableAlphaDithering = alphaDithering; - m.binaryAlpha = binaryAlpha; - m.alphaThreshold = alphaThreshold; + nvCheck(alphaThreshold >= 0 && alphaThreshold < 256); + m.enableColorDithering = colorDithering; + m.enableAlphaDithering = alphaDithering; + m.binaryAlpha = binaryAlpha; + m.alphaThreshold = alphaThreshold; } diff --git a/src/nvtt/Context.cpp b/src/nvtt/Context.cpp index cc63750..e270b21 100644 --- a/src/nvtt/Context.cpp +++ b/src/nvtt/Context.cpp @@ -104,118 +104,6 @@ namespace } // namespace -namespace nvtt -{ - // Mipmap could be: - // - a pointer to an input image. - // - a fixed point image. - // - a floating point image. - /*struct Mipmap - { - Mipmap() : m_inputImage(NULL) {} - ~Mipmap() {} - - // Reference input image. - void setFromInput(const InputOptions::Private & inputOptions, uint idx) - { - m_inputImage = inputOptions.image(idx); - m_fixedImage = NULL; - m_floatImage = NULL; - - if (const FloatImage * floatImage = inputOptions.floatImage(idx)) - { - m_floatImage = floatImage->clone(); - } - } - - // Assign and take ownership of given image. - void setImage(FloatImage * image) - { - m_inputImage = NULL; - m_fixedImage = NULL; - m_floatImage = image; - } - - - // Convert linear float image to fixed image ready for compression. - void toFixedImage(const InputOptions::Private & inputOptions) - { - if (this->asFixedImage() == NULL) - { - nvDebugCheck(m_floatImage != NULL); - - if (inputOptions.isNormalMap || inputOptions.outputGamma == 1.0f) - { - m_fixedImage = m_floatImage->createImage(); - } - else - { - m_fixedImage = m_floatImage->createImageGammaCorrect(inputOptions.outputGamma); - } - } - } - - // Convert input image to linear float image. - void toFloatImage(const InputOptions::Private & inputOptions) - { - if (m_floatImage == NULL) - { - nvDebugCheck(this->asFixedImage() != NULL); - - m_floatImage = new FloatImage(this->asFixedImage()); - - if (inputOptions.isNormalMap) - { - // Expand normals to [-1, 1] range. - // floatImage->expandNormals(0); - } - else if (inputOptions.inputGamma != 1.0f) - { - // Convert to linear space. - m_floatImage->toLinear(0, 3, inputOptions.inputGamma); - } - } - } - - const FloatImage * asFloatImage() const - { - return m_floatImage.ptr(); - } - - FloatImage * asMutableFloatImage() - { - m_inputImage = NULL; - return m_floatImage.ptr(); - } - - const Image * asFixedImage() const - { - if (m_inputImage != NULL) - { - return m_inputImage; - } - return m_fixedImage.ptr(); - } - - Image * asMutableFixedImage() - { - if (m_inputImage != NULL) - { - // Do not modify input image, create a copy. - m_fixedImage = new Image(*m_inputImage); - m_inputImage = NULL; - } - return m_fixedImage.ptr(); - } - - - private: - const Image * m_inputImage; - AutoPtr m_fixedImage; - AutoPtr m_floatImage; - };*/ - -} // nvtt namespace Compressor::Compressor() : m(*new Compressor::Private()) @@ -400,11 +288,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c // @@ Fix order of cubemap faces! - // @@ Apply quantization options. - - int size = computeImageSize(w, h, d, compressionOptions.bitcount, compressionOptions.pitchAlignment, compressionOptions.format); - outputOptions.beginImage(size, w, h, d, 0, 0); - + quantize(tmp, compressionOptions); compress(tmp, compressionOptions, outputOptions); for (int m = 1; m < mipmapCount; m++) { @@ -457,15 +341,13 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c tmp.toGamma(inputOptions.outputGamma); } - // @@ Apply quantization options. - + quantize(tmp, compressionOptions); compress(tmp, compressionOptions, outputOptions); }; return true; } - bool Compressor::Private::compress(const TexImage & tex, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const { foreach(i, tex.m->imageArray) { @@ -477,6 +359,60 @@ bool Compressor::Private::compress(const TexImage & tex, const CompressionOption return true; } +bool Compressor::Private::compress(AlphaMode alphaMode, int w, int h, int d, const float * rgba, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const +{ + // Decide what compressor to use. + AutoPtr compressor; +#if defined HAVE_CUDA + if (cudaEnabled && w * h >= 512) + { + compressor = chooseGpuCompressor(compressionOptions); + } +#endif + if (compressor == NULL) + { + compressor = chooseCpuCompressor(compressionOptions); + } + + if (compressor == NULL) + { + outputOptions.error(Error_UnsupportedFeature); + } + else + { + compressor->compress(alphaMode, w, h, rgba, compressionOptions, outputOptions); + } + + return true; +} + + +bool Compressor::Private::quantize(TexImage & img, const CompressionOptions::Private & compressionOptions) const +{ + if (compressionOptions.enableColorDithering) { + if (compressionOptions.format >= Format_BC1 && compressionOptions.format <= Format_BC3) { + img.quantize(0, 5, true); + img.quantize(1, 6, true); + img.quantize(2, 5, true); + } + else if (compressionOptions.format == Format_RGB) { + img.quantize(0, compressionOptions.rsize, true); + img.quantize(1, compressionOptions.gsize, true); + img.quantize(2, compressionOptions.bsize, true); + } + } + if (compressionOptions.enableAlphaDithering) { + if (compressionOptions.format == Format_RGB) { + img.quantize(0, compressionOptions.rsize, true); + img.quantize(1, compressionOptions.gsize, true); + img.quantize(2, compressionOptions.bsize, true); + } + } + else if (compressionOptions.binaryAlpha) { + img.binarize(3, compressionOptions.alphaThreshold, compressionOptions.enableAlphaDithering); + } +} + bool Compressor::Private::outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const { @@ -911,34 +847,6 @@ CompressorInterface * Compressor::Private::chooseGpuCompressor(const Compression return NULL; } - -bool Compressor::Private::compress(AlphaMode alphaMode, int w, int h, int d, const float * rgba, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const -{ - // Decide what compressor to use. - AutoPtr compressor; -#if defined HAVE_CUDA - if (cudaEnabled && w * h >= 512) - { - compressor = chooseGpuCompressor(compressionOptions); - } -#endif - if (compressor == NULL) - { - compressor = chooseCpuCompressor(compressionOptions); - } - - if (compressor == NULL) - { - outputOptions.error(Error_UnsupportedFeature); - } - else - { - compressor->compress(alphaMode, w, h, rgba, compressionOptions, outputOptions); - } - - return true; -} - /* int Compressor::Private::estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const { diff --git a/src/nvtt/Context.h b/src/nvtt/Context.h index c777439..a751ebc 100644 --- a/src/nvtt/Context.h +++ b/src/nvtt/Context.h @@ -47,7 +47,7 @@ namespace nvtt bool compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; bool compress(AlphaMode alphaMode, int w, int h, int d, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; - //int estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const; + bool quantize(TexImage & tex, const CompressionOptions::Private & compressionOptions) const; bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; bool outputHeader(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; @@ -55,18 +55,6 @@ namespace nvtt nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const; nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const; - //bool compressMipmaps(uint f, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; - - //bool initMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f, uint m) const; - - //int findExactMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const; - //int findClosestMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const; - - //void downsampleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const; - //void scaleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d) const; - //void premultiplyAlphaMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const; - //void processInputImage(Mipmap & mipmap, const InputOptions::Private & inputOptions) const; - //void quantizeMipmap(Mipmap & mipmap, const CompressionOptions::Private & compressionOptions) const; bool cudaSupported; diff --git a/src/nvtt/TexImage.cpp b/src/nvtt/TexImage.cpp index e439636..56ea814 100644 --- a/src/nvtt/TexImage.cpp +++ b/src/nvtt/TexImage.cpp @@ -1268,6 +1268,17 @@ void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/) } +void TexImage::binarize(int channel, float threshold, bool dither) +{ +#pragma NV_MESSAGE("binarize not implemented") +} + +void TexImage::quantize(int channel, int bits, bool dither) +{ +#pragma NV_MESSAGE("quantize not implemented") +} + + // Set normal map options. void TexImage::toNormalMap(float sm, float medium, float big, float large) diff --git a/src/nvtt/nvtt.h b/src/nvtt/nvtt.h index 4293b2f..9216570 100644 --- a/src/nvtt/nvtt.h +++ b/src/nvtt/nvtt.h @@ -431,9 +431,11 @@ namespace nvtt NVTT_API void toYCoCg(); NVTT_API void blockScaleCoCg(int bits = 5, float threshold = 0.0f); - // @@ Add quantization methods. + // Color quantization. + NVTT_API void binarize(int channel, float threshold, bool dither); + NVTT_API void quantize(int channel, int bits, bool dither); - // Set normal map options. + // Normal map transforms. NVTT_API void toNormalMap(float sm, float medium, float big, float large); NVTT_API void normalizeNormalMap();