Cosine power filter. A bit of renaming.

pull/216/head
castano 13 years ago
parent dbdf9b6398
commit 03c3fa42a8

@ -132,18 +132,18 @@ int Compressor::estimateSize(const InputOptions & inputOptions, const Compressio
}
// TexImage API.
bool Compressor::outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
// Surface API.
bool Compressor::outputHeader(const Surface & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
{
return m.outputHeader(tex.type(), tex.width(), tex.height(), tex.depth(), mipmapCount, tex.isNormalMap(), compressionOptions.m, outputOptions.m);
}
bool Compressor::compress(const TexImage & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
bool Compressor::compress(const Surface & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
{
return m.compress(tex, face, mipmap, compressionOptions.m, outputOptions.m);
}
int Compressor::estimateSize(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions) const
int Compressor::estimateSize(const Surface & tex, int mipmapCount, const CompressionOptions & compressionOptions) const
{
const int w = tex.width();
const int h = tex.height();
@ -152,12 +152,12 @@ int Compressor::estimateSize(const TexImage & tex, int mipmapCount, const Compre
return estimateSize(w, h, d, mipmapCount, compressionOptions);
}
bool Compressor::outputHeader(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
bool Compressor::outputHeader(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
{
return m.outputHeader(TextureType_Cube, cube.size(), cube.size(), 1, mipmapCount, false, compressionOptions.m, outputOptions.m);
}
bool Compressor::compress(const CubeImage & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
bool Compressor::compress(const CubeSurface & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
{
for (int i = 0; i < 6; i++) {
if(!m.compress(cube.face(i), i, mipmap, compressionOptions.m, outputOptions.m)) {
@ -167,7 +167,7 @@ bool Compressor::compress(const CubeImage & cube, int mipmap, const CompressionO
return true;
}
int Compressor::estimateSize(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions) const
int Compressor::estimateSize(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions) const
{
return 6 * estimateSize(cube.size(), cube.size(), 1, mipmapCount, compressionOptions);
}
@ -223,7 +223,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
return false;
}
nvtt::TexImage img;
nvtt::Surface img;
img.setWrapMode(inputOptions.wrapMode);
img.setAlphaMode(inputOptions.alphaMode);
img.setNormalMap(inputOptions.isNormalMap);
@ -269,7 +269,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
// Resize input.
img.resize(w, h, d, ResizeFilter_Box);
nvtt::TexImage tmp = img;
nvtt::Surface tmp = img;
if (!img.isNormalMap()) {
tmp.toGamma(inputOptions.outputGamma);
}
@ -333,7 +333,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
return true;
}
bool Compressor::Private::compress(const TexImage & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
bool Compressor::Private::compress(const Surface & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
{
if (!compress(tex.alphaMode(), tex.width(), tex.height(), tex.depth(), face, mipmap, tex.data(), compressionOptions, outputOptions)) {
return false;
@ -375,7 +375,7 @@ bool Compressor::Private::compress(AlphaMode alphaMode, int w, int h, int d, int
}
void Compressor::Private::quantize(TexImage & img, const CompressionOptions::Private & compressionOptions) const
void Compressor::Private::quantize(Surface & img, const CompressionOptions::Private & compressionOptions) const
{
if (compressionOptions.enableColorDithering) {
if (compressionOptions.format >= Format_BC1 && compressionOptions.format <= Format_BC3) {

@ -46,10 +46,10 @@ namespace nvtt
Private() {}
bool compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool compress(const TexImage & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool compress(const Surface & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool compress(AlphaMode alphaMode, int w, int h, int d, int face, int mipmap, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
void quantize(TexImage & tex, const CompressionOptions::Private & compressionOptions) const;
void quantize(Surface & tex, const CompressionOptions::Private & compressionOptions) const;
bool outputHeader(nvtt::TextureType textureType, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;

@ -24,41 +24,46 @@
#include "CubeImage.h"
#include "TexImage.h"
#include "nvmath/Vector.h"
#include "nvcore/Array.h"
using namespace nv;
using namespace nvtt;
CubeImage::CubeImage() : m(new CubeImage::Private())
CubeSurface::CubeSurface() : m(new CubeSurface::Private())
{
m->addRef();
}
CubeImage::CubeImage(const CubeImage & cube) : m(cube.m)
CubeSurface::CubeSurface(const CubeSurface & cube) : m(cube.m)
{
if (m != NULL) m->addRef();
}
CubeImage::~CubeImage()
CubeSurface::~CubeSurface()
{
if (m != NULL) m->release();
m = NULL;
}
void CubeImage::operator=(const CubeImage & cube)
void CubeSurface::operator=(const CubeSurface & cube)
{
if (cube.m != NULL) cube.m->addRef();
if (m != NULL) m->release();
m = cube.m;
}
void CubeImage::detach()
void CubeSurface::detach()
{
if (m->refCount() > 1)
{
m->release();
m = new CubeImage::Private(*m);
m = new CubeSurface::Private(*m);
m->addRef();
nvDebugCheck(m->refCount() == 1);
}
@ -66,73 +71,301 @@ void CubeImage::detach()
bool CubeImage::isNull() const
bool CubeSurface::isNull() const
{
return m->size == 0;
}
int CubeImage::size() const
int CubeSurface::size() const
{
return m->size;
}
int CubeImage::countMipmaps() const
int CubeSurface::countMipmaps() const
{
return nv::countMipmaps(m->size);
}
TexImage & CubeImage::face(int f)
Surface & CubeSurface::face(int f)
{
nvDebugCheck(f >= 0 && f < 6);
return m->face[f];
}
const TexImage & CubeImage::face(int f) const
const Surface & CubeSurface::face(int f) const
{
nvDebugCheck(f >= 0 && f < 6);
return m->face[f];
}
bool CubeImage::load(const char * fileName)
bool CubeSurface::load(const char * fileName)
{
// @@ TODO
return false;
}
bool CubeImage::save(const char * fileName) const
bool CubeSurface::save(const char * fileName) const
{
// @@ TODO
return false;
}
void CubeImage::fold(const TexImage & tex, CubeLayout layout)
void CubeSurface::fold(const Surface & tex, CubeLayout layout)
{
// @@ TODO
}
TexImage CubeImage::unfold(CubeLayout layout) const
Surface CubeSurface::unfold(CubeLayout layout) const
{
// @@ TODO
return TexImage();
return Surface();
}
CubeImage CubeImage::irradianceFilter(int size) const
CubeSurface CubeSurface::irradianceFilter(int size) const
{
// @@ TODO
return CubeImage();
return CubeSurface();
}
CubeImage CubeImage::cosinePowerFilter(int size, float cosinePower) const
// Small solid angle table that takes into account cube map symmetry.
struct SolidAngleTable {
SolidAngleTable(int edgeLength) : size(edgeLength/2) {
// Allocate table.
data.resize(size * size);
// @@ Init table.
}
//
float lookup(int x, int y) const {
if (x >= size) x -= size;
else if (x < size) x = size - x - 1;
if (y >= size) y -= size;
else if (y < size) y = size - y - 1;
return data[y * size + x];
}
int size;
nv::Array<float> data;
};
// ilen = inverse edge length.
Vector3 texelDirection(uint face, uint x, uint y, float ilen)
{
// @@ TODO
return CubeImage();
float u = (float(x) + 0.5f) * (2 * ilen) - 1.0f;
float v = (float(y) + 0.5f) * (2 * ilen) - 1.0f;
nvDebugCheck(u >= 0.0f && u <= 1.0f);
nvDebugCheck(v >= 0.0f && v <= 1.0f);
Vector3 n;
if (face == 0) {
n.x = 1;
n.y = -v;
n.z = -u;
}
if (face == 1) {
n.x = -1;
n.y = -v;
n.z = u;
}
if (face == 2) {
n.x = u;
n.y = 1;
n.z = v;
}
if (face == 3) {
n.x = u;
n.y = -1;
n.z = -v;
}
if (face == 4) {
n.x = u;
n.y = -v;
n.z = 1;
}
if (face == 5) {
n.x = -u;
n.y = -v;
n.z = -1;
}
return normalizeFast(n);
}
struct VectorTable {
VectorTable(int edgeLength) : size(edgeLength) {
float invEdgeLength = 1.0f / edgeLength;
for (uint f = 0; f < 6; f++) {
for (uint y = 0; y < size; y++) {
for (uint x = 0; x < size; x++) {
data[(f * size + y) * size + x] = texelDirection(f, x, y, invEdgeLength);
}
}
}
}
const Vector3 & lookup(uint f, uint x, uint y) {
nvDebugCheck(f < 6 && x < size && y < size);
return data[(f * size + y) * size + x];
}
int size;
nv::Array<Vector3> data;
};
CubeSurface CubeSurface::cosinePowerFilter(int size, float cosinePower) const
{
const uint edgeLength = m->size;
// Allocate output cube.
CubeSurface filteredCube;
filteredCube.m->allocate(size);
SolidAngleTable solidAngleTable(edgeLength);
VectorTable vectorTable(edgeLength);
#if 1
// Scatter approach.
// For each texel of the input cube.
// - Lookup our solid angle.
// - Determine to what texels of the output cube we contribute.
// - Add our contribution to the texels whose power is above threshold.
for (uint f = 0; f < 6; f++) {
const Surface & face = m->face[f];
for (uint y = 0; y < edgeLength; y++) {
for (uint x = 0; x < edgeLength; x++) {
float solidAngle = solidAngleTable.lookup(x, y);
float r = face.m->image->pixel(0, x, y, 0) * solidAngle;;
float g = face.m->image->pixel(1, x, y, 0) * solidAngle;;
float b = face.m->image->pixel(2, x, y, 0) * solidAngle;;
Vector3 texelDir = texelDirection(f, x, y, edgeLength);
for (uint ff = 0; ff < 6; ff++) {
FloatImage * filteredFace = filteredCube.m->face[ff].m->image;
for (uint yy = 0; yy < size; yy++) {
for (uint xx = 0; xx < size; xx++) {
Vector3 filterDir = texelDirection(ff, xx, yy, size);
float power = powf(saturate(dot(texelDir, filterDir)), cosinePower);
if (power > 0.01) {
filteredFace->pixel(0, xx, yy, 0) += r * power;
filteredFace->pixel(1, xx, yy, 0) += g * power;
filteredFace->pixel(2, xx, yy, 0) += b * power;
filteredFace->pixel(3, xx, yy, 0) += solidAngle * power;
}
}
}
}
}
}
}
// Normalize contributions.
for (uint f = 0; f < 6; f++) {
FloatImage * filteredFace = filteredCube.m->face[f].m->image;
for (int i = 0; i < size*size; i++) {
float & r = filteredFace->pixel(0, i);
float & g = filteredFace->pixel(1, i);
float & b = filteredFace->pixel(2, i);
float & sum = filteredFace->pixel(3, i);
float isum = 1.0f / sum;
r *= isum;
g *= isum;
b *= isum;
sum = 1;
}
}
#else
// Gather approach. This should be easier to parallelize, because there's no contention in the filtered output.
// For each texel of the output cube.
// - Determine what texels of the input cube contribute to it.
// - Add weighted contributions. Normalize.
// For each texel of the output cube. @@ Parallelize this loop.
for (uint f = 0; f < 6; f++) {
nvtt::Surface filteredFace = filteredCube.m->face[f];
FloatImage * filteredImage = filteredFace.m->image;
for (uint y = 0; y < size; y++) {
for (uint x = 0; x < size; x++) {
const Vector3 filterDir = texelDirection(f, x, y, size);
Vector3 color(0);
float sum = 0;
// For each texel of the input cube.
for (uint ff = 0; ff < 6; ff++) {
const Surface & inputFace = m->face[ff];
const FloatImage * inputImage = inputFace.m->image;
for (uint yy = 0; yy < edgeLength; yy++) {
for (uint xx = 0; xx < edgeLength; xx++) {
// @@ We should probably store solid angle and direction together.
Vector3 inputDir = vectorTable.lookup(ff, xx, yy);
float power = powf(saturate(dot(inputDir, filterDir)), cosinePower);
if (power > 0.01f) { // @@ Adjustable threshold.
float solidAngle = solidAngleTable.lookup(xx, yy);
float contribution = solidAngle * power;
sum += contribution;
float r = inputImage->pixel(0, xx, yy, 0);
float g = inputImage->pixel(1, xx, yy, 0);
float b = inputImage->pixel(2, xx, yy, 0);
color.r += r * contribution;
color.g += g * contribution;
color.b += b * contribution;
}
}
}
}
color *= (1.0f / sum);
filteredImage->pixel(0, x, y, 0) = color.x;
filteredImage->pixel(1, x, y, 0) = color.y;
filteredImage->pixel(2, x, y, 0) = color.z;
}
}
}
#endif
return filteredCube;
}
void CubeImage::toLinear(float gamma)
void CubeSurface::toLinear(float gamma)
{
if (isNull()) return;
@ -143,7 +376,7 @@ void CubeImage::toLinear(float gamma)
}
}
void CubeImage::toGamma(float gamma)
void CubeSurface::toGamma(float gamma)
{
if (isNull()) return;

@ -25,6 +25,9 @@
#define NVTT_CUBEIMAGE_H
#include "nvtt.h"
#include "TexImage.h"
#include "nvimage/FloatImage.h"
#include "nvcore/RefCounted.h"
#include "nvcore/Ptr.h"
@ -33,7 +36,7 @@
namespace nvtt
{
struct CubeImage::Private : public nv::RefCounted
struct CubeSurface::Private : public nv::RefCounted
{
void operator=(const Private &);
public:
@ -56,8 +59,18 @@ namespace nvtt
{
}
void allocate(int size)
{
this->size = size;
for (uint i = 0; i < 6; i++) {
face[i].detach();
face[i].m->image = new nv::FloatImage;
face[i].m->image->allocate(size, size, 1);
}
}
int size;
TexImage face[6];
Surface face[6];
};
} // nvtt namespace

@ -184,41 +184,41 @@ void nv::getTargetExtent(int & w, int & h, int & d, int maxExtent, RoundMode rou
TexImage::TexImage() : m(new TexImage::Private())
Surface::Surface() : m(new Surface::Private())
{
m->addRef();
}
TexImage::TexImage(const TexImage & tex) : m(tex.m)
Surface::Surface(const Surface & tex) : m(tex.m)
{
if (m != NULL) m->addRef();
}
TexImage::~TexImage()
Surface::~Surface()
{
if (m != NULL) m->release();
m = NULL;
}
void TexImage::operator=(const TexImage & tex)
void Surface::operator=(const Surface & tex)
{
if (tex.m != NULL) tex.m->addRef();
if (m != NULL) m->release();
m = tex.m;
}
void TexImage::detach()
void Surface::detach()
{
if (m->refCount() > 1)
{
m->release();
m = new TexImage::Private(*m);
m = new Surface::Private(*m);
m->addRef();
nvDebugCheck(m->refCount() == 1);
}
}
void TexImage::setWrapMode(WrapMode wrapMode)
void Surface::setWrapMode(WrapMode wrapMode)
{
if (m->wrapMode != wrapMode)
{
@ -227,7 +227,7 @@ void TexImage::setWrapMode(WrapMode wrapMode)
}
}
void TexImage::setAlphaMode(AlphaMode alphaMode)
void Surface::setAlphaMode(AlphaMode alphaMode)
{
if (m->alphaMode != alphaMode)
{
@ -236,7 +236,7 @@ void TexImage::setAlphaMode(AlphaMode alphaMode)
}
}
void TexImage::setNormalMap(bool isNormalMap)
void Surface::setNormalMap(bool isNormalMap)
{
if (m->isNormalMap != isNormalMap)
{
@ -245,63 +245,63 @@ void TexImage::setNormalMap(bool isNormalMap)
}
}
bool TexImage::isNull() const
bool Surface::isNull() const
{
return m->image == NULL;
}
int TexImage::width() const
int Surface::width() const
{
if (m->image != NULL) return m->image->width();
return 0;
}
int TexImage::height() const
int Surface::height() const
{
if (m->image != NULL) return m->image->height();
return 0;
}
int TexImage::depth() const
int Surface::depth() const
{
if (m->image != NULL) return m->image->depth();
return 0;
}
WrapMode TexImage::wrapMode() const
WrapMode Surface::wrapMode() const
{
return m->wrapMode;
}
AlphaMode TexImage::alphaMode() const
AlphaMode Surface::alphaMode() const
{
return m->alphaMode;
}
bool TexImage::isNormalMap() const
bool Surface::isNormalMap() const
{
return m->isNormalMap;
}
TextureType TexImage::type() const
TextureType Surface::type() const
{
return m->type;
}
int TexImage::countMipmaps() const
int Surface::countMipmaps() const
{
if (m->image == NULL) return 0;
return ::countMipmaps(m->image->width(), m->image->height(), 1);
}
float TexImage::alphaTestCoverage(float alphaRef/*= 0.5*/) const
float Surface::alphaTestCoverage(float alphaRef/*= 0.5*/) const
{
if (m->image == NULL) return 0.0f;
return m->image->alphaTestCoverage(alphaRef, 3);
}
float TexImage::average(int channel, int alpha_channel/*= -1*/, float gamma /*= 2.2f*/) const
float Surface::average(int channel, int alpha_channel/*= -1*/, float gamma /*= 2.2f*/) const
{
if (m->image == NULL) return 0.0f;
@ -337,12 +337,12 @@ float TexImage::average(int channel, int alpha_channel/*= -1*/, float gamma /*=
return sum / denom;
}
const float * TexImage::data() const
const float * Surface::data() const
{
return m->image->channel(0);
}
void TexImage::histogram(int channel, float rangeMin, float rangeMax, int binCount, int * binPtr) const
void Surface::histogram(int channel, float rangeMin, float rangeMax, int binCount, int * binPtr) const
{
// We assume it's clear in case we want to accumulate multiple histograms.
//memset(bins, 0, sizeof(int)*count);
@ -364,7 +364,7 @@ void TexImage::histogram(int channel, float rangeMin, float rangeMax, int binCou
}
}
void TexImage::range(int channel, float * rangeMin, float * rangeMax)
void Surface::range(int channel, float * rangeMin, float * rangeMax)
{
Vector2 range(FLT_MAX, -FLT_MAX);
@ -384,7 +384,7 @@ void TexImage::range(int channel, float * rangeMin, float * rangeMax)
}
bool TexImage::load(const char * fileName, bool * hasAlpha/*= NULL*/)
bool Surface::load(const char * fileName, bool * hasAlpha/*= NULL*/)
{
AutoPtr<FloatImage> img(ImageIO::loadFloat(fileName));
if (img == NULL) {
@ -406,7 +406,7 @@ bool TexImage::load(const char * fileName, bool * hasAlpha/*= NULL*/)
return true;
}
bool TexImage::save(const char * fileName) const
bool Surface::save(const char * fileName) const
{
if (m->image != NULL)
{
@ -416,7 +416,7 @@ bool TexImage::save(const char * fileName) const
return false;
}
bool TexImage::setImage(nvtt::InputFormat format, int w, int h, int d, const void * data)
bool Surface::setImage(nvtt::InputFormat format, int w, int h, int d, const void * data)
{
detach();
@ -488,7 +488,7 @@ bool TexImage::setImage(nvtt::InputFormat format, int w, int h, int d, const voi
return true;
}
bool TexImage::setImage(InputFormat format, int w, int h, int d, const void * r, const void * g, const void * b, const void * a)
bool Surface::setImage(InputFormat format, int w, int h, int d, const void * r, const void * g, const void * b, const void * a)
{
detach();
@ -561,7 +561,7 @@ bool TexImage::setImage(InputFormat format, int w, int h, int d, const void * r,
}
// @@ Add support for compressed 3D textures.
bool TexImage::setImage2D(Format format, Decoder decoder, int w, int h, const void * data)
bool Surface::setImage2D(Format format, Decoder decoder, int w, int h, const void * data)
{
if (format != nvtt::Format_BC1 && format != nvtt::Format_BC2 && format != nvtt::Format_BC3 && format != nvtt::Format_BC4 && format != nvtt::Format_BC5)
{
@ -693,7 +693,7 @@ static void getDefaultFilterWidthAndParams(int filter, float * filterWidth, floa
}
}
void TexImage::resize(int w, int h, int d, ResizeFilter filter)
void Surface::resize(int w, int h, int d, ResizeFilter filter)
{
float filterWidth;
float params[2];
@ -702,7 +702,7 @@ void TexImage::resize(int w, int h, int d, ResizeFilter filter)
resize(w, h, d, filter, filterWidth, params);
}
void TexImage::resize(int w, int h, int d, ResizeFilter filter, float filterWidth, const float * params)
void Surface::resize(int w, int h, int d, ResizeFilter filter, float filterWidth, const float * params)
{
FloatImage * img = m->image;
if (img == NULL || (w == img->width() && h == img->height() && d == img->depth())) {
@ -770,7 +770,7 @@ void TexImage::resize(int w, int h, int d, ResizeFilter filter, float filterWidt
m->image = img;
}
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
{
float filterWidth;
float params[2];
@ -779,7 +779,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
resize(maxExtent, roundMode, filter, filterWidth, params);
}
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, float filterWidth, const float * params)
void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, float filterWidth, const float * params)
{
if (m->image == NULL) return;
@ -792,7 +792,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, f
resize(w, h, d, filter, filterWidth, params);
}
bool TexImage::buildNextMipmap(MipmapFilter filter)
bool Surface::buildNextMipmap(MipmapFilter filter)
{
float filterWidth;
float params[2];
@ -801,7 +801,7 @@ bool TexImage::buildNextMipmap(MipmapFilter filter)
return buildNextMipmap(filter, filterWidth, params);
}
bool TexImage::buildNextMipmap(MipmapFilter filter, float filterWidth, const float * params)
bool Surface::buildNextMipmap(MipmapFilter filter, float filterWidth, const float * params)
{
FloatImage * img = m->image;
if (img == NULL || (img->width() == 1 && img->height() == 1 && img->depth() == 1)) {
@ -864,7 +864,7 @@ bool TexImage::buildNextMipmap(MipmapFilter filter, float filterWidth, const flo
return true;
}
void TexImage::canvasSize(int w, int h, int d)
void Surface::canvasSize(int w, int h, int d)
{
nvDebugCheck(w > 0 && h > 0 && d > 0);
@ -901,7 +901,7 @@ void TexImage::canvasSize(int w, int h, int d)
// Color transforms.
void TexImage::toLinear(float gamma)
void Surface::toLinear(float gamma)
{
if (m->image == NULL) return;
if (equal(gamma, 1.0f)) return;
@ -911,7 +911,7 @@ void TexImage::toLinear(float gamma)
m->image->toLinear(0, 3, gamma);
}
void TexImage::toGamma(float gamma)
void Surface::toGamma(float gamma)
{
if (m->image == NULL) return;
if (equal(gamma, 1.0f)) return;
@ -930,7 +930,7 @@ static float toSrgb(float f) {
return f;
}
void TexImage::toSrgb()
void Surface::toSrgb()
{
FloatImage * img = m->image;
if (img == NULL) return;
@ -960,7 +960,7 @@ static float toXenonSrgb(float f) {
return f;
}
void TexImage::toXenonSrgb()
void Surface::toXenonSrgb()
{
FloatImage * img = m->image;
if (img == NULL) return;
@ -981,7 +981,7 @@ void TexImage::toXenonSrgb()
}
void TexImage::transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4])
void Surface::transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4])
{
if (m->image == NULL) return;
@ -998,7 +998,7 @@ void TexImage::transform(const float w0[4], const float w1[4], const float w2[4]
m->image->transform(0, xform, voffset);
}
void TexImage::swizzle(int r, int g, int b, int a)
void Surface::swizzle(int r, int g, int b, int a)
{
if (m->image == NULL) return;
if (r == 0 && g == 1 && b == 2 && a == 3) return;
@ -1009,7 +1009,7 @@ void TexImage::swizzle(int r, int g, int b, int a)
}
// color * scale + bias
void TexImage::scaleBias(int channel, float scale, float bias)
void Surface::scaleBias(int channel, float scale, float bias)
{
if (m->image == NULL) return;
if (equal(scale, 1.0f) && equal(bias, 0.0f)) return;
@ -1019,7 +1019,7 @@ void TexImage::scaleBias(int channel, float scale, float bias)
m->image->scaleBias(channel, 1, scale, bias);
}
void TexImage::clamp(int channel, float low, float high)
void Surface::clamp(int channel, float low, float high)
{
if (m->image == NULL) return;
@ -1028,14 +1028,14 @@ void TexImage::clamp(int channel, float low, float high)
m->image->clamp(channel, 1, low, high);
}
void TexImage::packNormal()
void Surface::packNormal()
{
scaleBias(0, 0.5f, 0.5f);
scaleBias(1, 0.5f, 0.5f);
scaleBias(2, 0.5f, 0.5f);
}
void TexImage::expandNormal()
void Surface::expandNormal()
{
scaleBias(0, 2.0f, -1.0f);
scaleBias(1, 2.0f, -1.0f);
@ -1043,7 +1043,7 @@ void TexImage::expandNormal()
}
void TexImage::blend(float red, float green, float blue, float alpha, float t)
void Surface::blend(float red, float green, float blue, float alpha, float t)
{
if (m->image == NULL) return;
@ -1065,7 +1065,7 @@ void TexImage::blend(float red, float green, float blue, float alpha, float t)
}
}
void TexImage::premultiplyAlpha()
void Surface::premultiplyAlpha()
{
if (m->image == NULL) return;
@ -1087,7 +1087,7 @@ void TexImage::premultiplyAlpha()
}
void TexImage::toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale)
void Surface::toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale)
{
if (m->image == NULL) return;
@ -1114,7 +1114,7 @@ void TexImage::toGreyScale(float redScale, float greenScale, float blueScale, fl
}
// Draw colored border.
void TexImage::setBorder(float r, float g, float b, float a)
void Surface::setBorder(float r, float g, float b, float a)
{
if (m->image == NULL) return;
@ -1156,7 +1156,7 @@ void TexImage::setBorder(float r, float g, float b, float a)
}
// Fill image with the given color.
void TexImage::fill(float red, float green, float blue, float alpha)
void Surface::fill(float red, float green, float blue, float alpha)
{
if (m->image == NULL) return;
@ -1179,7 +1179,7 @@ void TexImage::fill(float red, float green, float blue, float alpha)
}
void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
void Surface::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
{
if (m->image == NULL) return;
@ -1188,7 +1188,7 @@ void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
m->image->scaleAlphaToCoverage(coverage, alphaRef, 3);
}
/*bool TexImage::normalizeRange(float * rangeMin, float * rangeMax)
/*bool Surface::normalizeRange(float * rangeMin, float * rangeMax)
{
if (m->image == NULL) return false;
@ -1218,7 +1218,7 @@ void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
// Ideally you should compress/quantize the RGB and M portions independently.
// Once you have M quantized, you would compute the corresponding RGB and quantize that.
void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
void Surface::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
{
if (m->image == NULL) return;
@ -1286,7 +1286,7 @@ void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
}
}
void TexImage::fromRGBM(float range/*= 1*/)
void Surface::fromRGBM(float range/*= 1*/)
{
if (m->image == NULL) return;
@ -1311,7 +1311,7 @@ void TexImage::fromRGBM(float range/*= 1*/)
// Y is in the [0, 1] range, while CoCg are in the [-1, 1] range.
void TexImage::toYCoCg()
void Surface::toYCoCg()
{
if (m->image == NULL) return;
@ -1348,7 +1348,7 @@ void TexImage::toYCoCg()
// @@ Add support for threshold.
// We could do something to prevent scale values from adjacent blocks from being too different to each other
// and minimize bilinear interpolation artifacts.
void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
void Surface::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
{
if (m->image == NULL || m->image->depth() != 1) return;
@ -1406,7 +1406,7 @@ void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
}
}
void TexImage::fromYCoCg()
void Surface::fromYCoCg()
{
if (m->image == NULL) return;
@ -1439,7 +1439,7 @@ void TexImage::fromYCoCg()
}
}
void TexImage::toLUVW(float range/*= 1.0f*/)
void Surface::toLUVW(float range/*= 1.0f*/)
{
if (m->image == NULL) return;
@ -1468,13 +1468,13 @@ void TexImage::toLUVW(float range/*= 1.0f*/)
}
}
void TexImage::fromLUVW(float range/*= 1.0f*/)
void Surface::fromLUVW(float range/*= 1.0f*/)
{
// Decompression is the same as in RGBM.
fromRGBM(range * sqrtf(3));
}
void TexImage::abs(int channel)
void Surface::abs(int channel)
{
if (m->image == NULL) return;
@ -1489,7 +1489,7 @@ void TexImage::abs(int channel)
}
}
void TexImage::convolve(int channel, int kernelSize, float * kernelData)
void Surface::convolve(int channel, int kernelSize, float * kernelData)
{
if (m->image == NULL) return;
@ -1500,7 +1500,7 @@ void TexImage::convolve(int channel, int kernelSize, float * kernelData)
}
/*
void TexImage::blockLuminanceScale(float scale)
void Surface::blockLuminanceScale(float scale)
{
if (m->image == NULL) return;
@ -1575,7 +1575,7 @@ void TexImage::blockLuminanceScale(float scale)
*/
/*
void TexImage::toJPEGLS()
void Surface::toJPEGLS()
{
if (m->image == NULL) return;
@ -1598,7 +1598,7 @@ void TexImage::toJPEGLS()
}
}
void TexImage::fromJPEGLS()
void Surface::fromJPEGLS()
{
if (m->image == NULL) return;
@ -1624,7 +1624,7 @@ void TexImage::fromJPEGLS()
// If dither is true, this uses Floyd-Steinberg dithering method.
void TexImage::binarize(int channel, float threshold, bool dither)
void Surface::binarize(int channel, float threshold, bool dither)
{
if (m->image == NULL) return;
@ -1687,7 +1687,7 @@ void TexImage::binarize(int channel, float threshold, bool dither)
// Assumes input is in [0, 1] range. Output is in the [0, 1] range, but rounded to the middle of each bin.
// If exactEndPoints is true, [0, 1] are represented exactly, and the correponding bins are half the size, so quantization is not truly uniform.
// When dither is true, this uses Floyd-Steinberg dithering.
void TexImage::quantize(int channel, int bits, bool exactEndPoints, bool dither)
void Surface::quantize(int channel, int bits, bool exactEndPoints, bool dither)
{
if (m->image == NULL) return;
@ -1758,7 +1758,7 @@ void TexImage::quantize(int channel, int bits, bool exactEndPoints, bool dither)
// Set normal map options.
void TexImage::toNormalMap(float sm, float medium, float big, float large)
void Surface::toNormalMap(float sm, float medium, float big, float large)
{
if (m->image == NULL) return;
@ -1777,7 +1777,7 @@ void TexImage::toNormalMap(float sm, float medium, float big, float large)
m->isNormalMap = true;
}
void TexImage::normalizeNormalMap()
void Surface::normalizeNormalMap()
{
if (m->image == NULL) return;
if (!m->isNormalMap) return;
@ -1787,7 +1787,7 @@ void TexImage::normalizeNormalMap()
nv::normalizeNormalMap(m->image);
}
void TexImage::transformNormals(NormalTransform xform)
void Surface::transformNormals(NormalTransform xform)
{
if (m->image == NULL) return;
@ -1860,7 +1860,7 @@ void TexImage::transformNormals(NormalTransform xform)
img->packNormals(0);
}
void TexImage::reconstructNormals(NormalTransform xform)
void Surface::reconstructNormals(NormalTransform xform)
{
if (m->image == NULL) return;
@ -1909,7 +1909,7 @@ void TexImage::reconstructNormals(NormalTransform xform)
img->packNormals(0);
}
void TexImage::toCleanNormalMap()
void Surface::toCleanNormalMap()
{
if (m->image == NULL) return;
@ -1929,21 +1929,21 @@ void TexImage::toCleanNormalMap()
}
// [-1,1] -> [ 0,1]
void TexImage::packNormals() {
void Surface::packNormals() {
if (m->image == NULL) return;
detach();
m->image->packNormals(0);
}
// [ 0,1] -> [-1,1]
void TexImage::expandNormals() {
void Surface::expandNormals() {
if (m->image == NULL) return;
detach();
m->image->expandNormals(0);
}
void TexImage::flipX()
void Surface::flipX()
{
if (m->image == NULL) return;
@ -1952,7 +1952,7 @@ void TexImage::flipX()
m->image->flipX();
}
void TexImage::flipY()
void Surface::flipY()
{
if (m->image == NULL) return;
@ -1961,7 +1961,7 @@ void TexImage::flipY()
m->image->flipY();
}
void TexImage::flipZ()
void Surface::flipZ()
{
if (m->image == NULL) return;
@ -1970,12 +1970,12 @@ void TexImage::flipZ()
m->image->flipZ();
}
bool TexImage::copyChannel(const TexImage & srcImage, int srcChannel)
bool Surface::copyChannel(const Surface & srcImage, int srcChannel)
{
return copyChannel(srcImage, srcChannel, srcChannel);
}
bool TexImage::copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel)
bool Surface::copyChannel(const Surface & srcImage, int srcChannel, int dstChannel)
{
if (srcChannel < 0 || srcChannel > 3 || dstChannel < 0 || dstChannel > 3) return false;
@ -1994,7 +1994,7 @@ bool TexImage::copyChannel(const TexImage & srcImage, int srcChannel, int dstCha
return true;
}
bool TexImage::addChannel(const TexImage & srcImage, int srcChannel, int dstChannel, float scale)
bool Surface::addChannel(const Surface & srcImage, int srcChannel, int dstChannel, float scale)
{
if (srcChannel < 0 || srcChannel > 3 || dstChannel < 0 || dstChannel > 3) return false;
@ -2024,43 +2024,43 @@ bool TexImage::addChannel(const TexImage & srcImage, int srcChannel, int dstChan
float nvtt::rmsError(const TexImage & reference, const TexImage & image)
float nvtt::rmsError(const Surface & reference, const Surface & image)
{
return nv::rmsColorError(reference.m->image, image.m->image, reference.alphaMode() == nvtt::AlphaMode_Transparency);
}
float nvtt::rmsAlphaError(const TexImage & reference, const TexImage & image)
float nvtt::rmsAlphaError(const Surface & reference, const Surface & image)
{
return nv::rmsAlphaError(reference.m->image, image.m->image);
}
float nvtt::cieLabError(const TexImage & reference, const TexImage & image)
float nvtt::cieLabError(const Surface & reference, const Surface & image)
{
return nv::cieLabError(reference.m->image, image.m->image);
}
float nvtt::angularError(const TexImage & reference, const TexImage & image)
float nvtt::angularError(const Surface & reference, const Surface & image)
{
//return nv::averageAngularError(reference.m->image, image.m->image);
return nv::rmsAngularError(reference.m->image, image.m->image);
}
TexImage nvtt::diff(const TexImage & reference, const TexImage & image, float scale)
Surface nvtt::diff(const Surface & reference, const Surface & image, float scale)
{
const FloatImage * ref = reference.m->image;
const FloatImage * img = image.m->image;
if (!sameLayout(img, ref)) {
return TexImage();
return Surface();
}
nvDebugCheck(img->componentCount() == 4);
nvDebugCheck(ref->componentCount() == 4);
nvtt::TexImage diffImage;
nvtt::Surface diffImage;
FloatImage * diff = diffImage.m->image = new FloatImage;
diff->allocate(4, img->width(), img->height(), img->depth());

@ -36,7 +36,7 @@
namespace nvtt
{
struct TexImage::Private : public nv::RefCounted
struct Surface::Private : public nv::RefCounted
{
void operator=(const Private &);
public:

@ -67,8 +67,8 @@
namespace nvtt
{
// Forward declarations.
struct TexImage;
struct CubeImage;
struct Surface;
struct CubeSurface;
/// Supported compression formats.
enum Format
@ -378,15 +378,15 @@ namespace nvtt
NVTT_API bool process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API int estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions) const;
// TexImage API.
NVTT_API bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API bool compress(const TexImage & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API int estimateSize(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions) const;
// Surface API.
NVTT_API bool outputHeader(const Surface & img, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API bool compress(const Surface & img, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API int estimateSize(const Surface & img, int mipmapCount, const CompressionOptions & compressionOptions) const;
// CubeImage API.
NVTT_API bool outputHeader(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API bool compress(const CubeImage & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API int estimateSize(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions) const;
// CubeSurface API.
NVTT_API bool outputHeader(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API bool compress(const CubeSurface & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API int estimateSize(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions) const;
// Raw API.
NVTT_API bool outputHeader(TextureType type, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
@ -405,14 +405,15 @@ namespace nvtt
//NormalTransform_DualParaboloid,
};
/// A texture mipmap.
struct TexImage
/// A surface is a texture mipmap. Can be 2D or 3D.
struct Surface
{
NVTT_API TexImage();
NVTT_API TexImage(const TexImage & tex);
NVTT_API ~TexImage();
NVTT_API Surface();
NVTT_API Surface(const Surface & img);
NVTT_API ~Surface();
NVTT_API void operator=(const TexImage & tex);
NVTT_API void operator=(const Surface & img);
// Texture parameters.
NVTT_API void setWrapMode(WrapMode mode);
@ -500,19 +501,12 @@ namespace nvtt
NVTT_API void flipZ();
// Copy image data.
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel);
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
NVTT_API bool addChannel(const TexImage & img, int srcChannel, int dstChannel, float scale);
NVTT_API bool copyChannel(const Surface & srcImage, int srcChannel);
NVTT_API bool copyChannel(const Surface & srcImage, int srcChannel, int dstChannel);
// Error compare.
NVTT_API friend float rmsError(const TexImage & reference, const TexImage & img);
NVTT_API friend float rmsAlphaError(const TexImage & reference, const TexImage & img);
NVTT_API friend float cieLabError(const TexImage & reference, const TexImage & img);
NVTT_API friend float angularError(const TexImage & reference, const TexImage & img);
NVTT_API friend TexImage diff(const TexImage & reference, const TexImage & img, float scale);
NVTT_API bool addChannel(const Surface & img, int srcChannel, int dstChannel, float scale);
private:
//private:
void detach();
struct Private;
@ -528,14 +522,14 @@ namespace nvtt
CubeLayout_LatitudeLongitude,
};
/// A cubemap mipmap.
struct CubeImage
/// A cubemap mipmap. CubeSurface?
struct CubeSurface
{
NVTT_API CubeImage();
NVTT_API CubeImage(const CubeImage & tex);
NVTT_API ~CubeImage();
NVTT_API CubeSurface();
NVTT_API CubeSurface(const CubeSurface & img);
NVTT_API ~CubeSurface();
NVTT_API void operator=(const CubeImage & tex);
NVTT_API void operator=(const CubeSurface & img);
// Queries.
NVTT_API bool isNull() const;
@ -546,20 +540,20 @@ namespace nvtt
NVTT_API bool load(const char * fileName);
NVTT_API bool save(const char * fileName) const;
TexImage & face(int face);
const TexImage & face(int face) const;
Surface & face(int face);
const Surface & face(int face) const;
// Layout conversion.
void fold(const TexImage & img, CubeLayout layout);
TexImage unfold(CubeLayout layout) const;
void fold(const Surface & img, CubeLayout layout);
Surface unfold(CubeLayout layout) const;
// @@ Angular extent filtering.
// @@ Add resizing methods.
// Filtering.
CubeImage irradianceFilter(int size) const;
CubeImage cosinePowerFilter(int size, float cosinePower) const;
CubeSurface irradianceFilter(int size) const;
CubeSurface cosinePowerFilter(int size, float cosinePower) const;
/*
@ -575,7 +569,7 @@ namespace nvtt
NVTT_API void toLinear(float gamma);
NVTT_API void toGamma(float gamma);
private:
//private:
void detach();
struct Private;
@ -589,11 +583,11 @@ namespace nvtt
// Return NVTT version.
NVTT_API unsigned int version();
NVTT_API float rmsError(const TexImage & reference, const TexImage & img);
NVTT_API float rmsAlphaError(const TexImage & reference, const TexImage & img);
NVTT_API float cieLabError(const TexImage & reference, const TexImage & img);
NVTT_API float angularError(const TexImage & reference, const TexImage & img);
NVTT_API TexImage diff(const TexImage & reference, const TexImage & img, float scale);
NVTT_API float rmsError(const Surface & reference, const Surface & img);
NVTT_API float rmsAlphaError(const Surface & reference, const Surface & img);
NVTT_API float cieLabError(const Surface & reference, const Surface & img);
NVTT_API float angularError(const Surface & reference, const Surface & img);
NVTT_API Surface diff(const Surface & reference, const Surface & img, float scale);
} // nvtt namespace

@ -38,7 +38,7 @@ int main(int argc, char *argv[])
context.enableCudaAcceleration(false);
// Load input image.
nvtt::TexImage image;
nvtt::Surface image;
if (!image.load(inputFileName)) {
return EXIT_FAILURE;
}
@ -76,7 +76,7 @@ int main(int argc, char *argv[])
int m = 1;
while (image.buildNextMipmap(nvtt::MipmapFilter_Kaiser))
{
nvtt::TexImage tmpImage = image;
nvtt::Surface tmpImage = image;
tmpImage.toGamma(gamma);
tmpImage.scaleAlphaToCoverage(coverage, alphaRef);

@ -43,7 +43,7 @@ int main(int argc, char *argv[])
context.enableCudaAcceleration(false);
// Load color map.
nvtt::TexImage colorMap;
nvtt::Surface colorMap;
if (!colorMap.load(inputFileNameColor)) {
printf("Image '%s' could not be loaded.\n", inputFileNameColor);
return EXIT_FAILURE;
@ -63,7 +63,7 @@ int main(int argc, char *argv[])
colorOutputOptions.setFileName(outputFileNameColor.str());
// Load normal map.
nvtt::TexImage normalMap;
nvtt::Surface normalMap;
if (inputFileNameNormal != NULL) {
if (!normalMap.load(inputFileNameColor)) {
printf("Image '%s' could not be loaded.\n", inputFileNameNormal);
@ -123,7 +123,7 @@ int main(int argc, char *argv[])
{
colorMap.scaleAlphaToCoverage(coverage, alphaRef);
nvtt::TexImage tmpColorMap = colorMap;
nvtt::Surface tmpColorMap = colorMap;
tmpColorMap.toGamma(gamma);
context.compress(tmpColorMap, 0, m, colorCompressionOptions, colorOutputOptions);

@ -280,9 +280,9 @@ struct MyOutputHandler : public nvtt::OutputHandler
return true;
}
nvtt::TexImage decompress(Mode mode, nvtt::Format format, nvtt::Decoder decoder)
nvtt::Surface decompress(Mode mode, nvtt::Format format, nvtt::Decoder decoder)
{
nvtt::TexImage img;
nvtt::Surface img;
img.setImage2D(format, decoder, m_width, m_height, m_data);
return img;
}
@ -576,7 +576,7 @@ int main(int argc, char *argv[])
//int failedTests = 0;
//float totalDiff = 0;
nvtt::TexImage img;
nvtt::Surface img;
printf("Running Test: %s\n", set.name);
@ -640,7 +640,7 @@ int main(int argc, char *argv[])
img.toGamma(2);
}
nvtt::TexImage tmp = img;
nvtt::Surface tmp = img;
if (mode == Mode_BC1) {
if (set.type == ImageType_HDR) {
/*for (int i = 0; i < 3; i++) {
@ -727,7 +727,7 @@ int main(int argc, char *argv[])
printf(" Time: \t%.3f sec\n", timer.elapsed());
totalTime += timer.elapsed();
nvtt::TexImage img_out = outputHandler.decompress(mode, format, decoder);
nvtt::Surface img_out = outputHandler.decompress(mode, format, decoder);
img_out.setAlphaMode(img.alphaMode());
img_out.setNormalMap(img.isNormalMap());
@ -796,14 +796,14 @@ int main(int argc, char *argv[])
tmp.transformNormals(nvtt::NormalTransform_DualParaboloid);
}*/
nvtt::TexImage diff = nvtt::diff(img, img_out, 1.0f);
nvtt::Surface diff = nvtt::diff(img, img_out, 1.0f);
//bool residualCompression = (set.type == ImageType_HDR);
bool residualCompression = (mode == Mode_BC3_RGBS);
if (residualCompression)
{
float residualScale = 8.0f;
nvtt::TexImage residual = diff;
nvtt::Surface residual = diff;
for (int j = 0; j < 3; j++) {
residual.scaleBias(j, residualScale, 0.5); // @@ The residual scale is fairly arbitrary.
residual.clamp(j);
@ -821,7 +821,7 @@ int main(int argc, char *argv[])
context.compress(residual, 0, 0, compressionOptions, outputOptions);
nvtt::TexImage residual_out = outputHandler.decompress(mode, format, decoder);
nvtt::Surface residual_out = outputHandler.decompress(mode, format, decoder);
/*outputFileName.format("%s/%s", outputFilePath.str(), set.fileNames[i]);
outputFileName.stripExtension();
@ -904,7 +904,7 @@ int main(int argc, char *argv[])
regressFileName.stripExtension();
regressFileName.append(".png");
nvtt::TexImage img_reg;
nvtt::Surface img_reg;
if (!img_reg.load(regressFileName.str()))
{
printf("Regression image '%s' not found.\n", regressFileName.str());

Loading…
Cancel
Save