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. // Surface API.
bool Compressor::outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const 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); 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); 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 w = tex.width();
const int h = tex.height(); 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); 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); 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++) { for (int i = 0; i < 6; i++) {
if(!m.compress(cube.face(i), i, mipmap, compressionOptions.m, outputOptions.m)) { 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; 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); 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; return false;
} }
nvtt::TexImage img; nvtt::Surface img;
img.setWrapMode(inputOptions.wrapMode); img.setWrapMode(inputOptions.wrapMode);
img.setAlphaMode(inputOptions.alphaMode); img.setAlphaMode(inputOptions.alphaMode);
img.setNormalMap(inputOptions.isNormalMap); img.setNormalMap(inputOptions.isNormalMap);
@ -269,7 +269,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
// Resize input. // Resize input.
img.resize(w, h, d, ResizeFilter_Box); img.resize(w, h, d, ResizeFilter_Box);
nvtt::TexImage tmp = img; nvtt::Surface tmp = img;
if (!img.isNormalMap()) { if (!img.isNormalMap()) {
tmp.toGamma(inputOptions.outputGamma); tmp.toGamma(inputOptions.outputGamma);
} }
@ -333,7 +333,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
return true; 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)) { if (!compress(tex.alphaMode(), tex.width(), tex.height(), tex.depth(), face, mipmap, tex.data(), compressionOptions, outputOptions)) {
return false; 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.enableColorDithering) {
if (compressionOptions.format >= Format_BC1 && compressionOptions.format <= Format_BC3) { if (compressionOptions.format >= Format_BC1 && compressionOptions.format <= Format_BC3) {

@ -46,10 +46,10 @@ namespace nvtt
Private() {} Private() {}
bool compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; 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; 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; 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 "CubeImage.h"
#include "TexImage.h" #include "TexImage.h"
#include "nvmath/Vector.h"
#include "nvcore/Array.h"
using namespace nv; using namespace nv;
using namespace nvtt; using namespace nvtt;
CubeImage::CubeImage() : m(new CubeImage::Private()) CubeSurface::CubeSurface() : m(new CubeSurface::Private())
{ {
m->addRef(); m->addRef();
} }
CubeImage::CubeImage(const CubeImage & cube) : m(cube.m) CubeSurface::CubeSurface(const CubeSurface & cube) : m(cube.m)
{ {
if (m != NULL) m->addRef(); if (m != NULL) m->addRef();
} }
CubeImage::~CubeImage() CubeSurface::~CubeSurface()
{ {
if (m != NULL) m->release(); if (m != NULL) m->release();
m = NULL; m = NULL;
} }
void CubeImage::operator=(const CubeImage & cube) void CubeSurface::operator=(const CubeSurface & cube)
{ {
if (cube.m != NULL) cube.m->addRef(); if (cube.m != NULL) cube.m->addRef();
if (m != NULL) m->release(); if (m != NULL) m->release();
m = cube.m; m = cube.m;
} }
void CubeImage::detach() void CubeSurface::detach()
{ {
if (m->refCount() > 1) if (m->refCount() > 1)
{ {
m->release(); m->release();
m = new CubeImage::Private(*m); m = new CubeSurface::Private(*m);
m->addRef(); m->addRef();
nvDebugCheck(m->refCount() == 1); nvDebugCheck(m->refCount() == 1);
} }
@ -66,73 +71,301 @@ void CubeImage::detach()
bool CubeImage::isNull() const bool CubeSurface::isNull() const
{ {
return m->size == 0; return m->size == 0;
} }
int CubeImage::size() const int CubeSurface::size() const
{ {
return m->size; return m->size;
} }
int CubeImage::countMipmaps() const int CubeSurface::countMipmaps() const
{ {
return nv::countMipmaps(m->size); return nv::countMipmaps(m->size);
} }
TexImage & CubeImage::face(int f) Surface & CubeSurface::face(int f)
{ {
nvDebugCheck(f >= 0 && f < 6); nvDebugCheck(f >= 0 && f < 6);
return m->face[f]; return m->face[f];
} }
const TexImage & CubeImage::face(int f) const const Surface & CubeSurface::face(int f) const
{ {
nvDebugCheck(f >= 0 && f < 6); nvDebugCheck(f >= 0 && f < 6);
return m->face[f]; return m->face[f];
} }
bool CubeImage::load(const char * fileName) bool CubeSurface::load(const char * fileName)
{ {
// @@ TODO // @@ TODO
return false; return false;
} }
bool CubeImage::save(const char * fileName) const bool CubeSurface::save(const char * fileName) const
{ {
// @@ TODO // @@ TODO
return false; return false;
} }
void CubeImage::fold(const TexImage & tex, CubeLayout layout) void CubeSurface::fold(const Surface & tex, CubeLayout layout)
{ {
// @@ TODO // @@ TODO
} }
TexImage CubeImage::unfold(CubeLayout layout) const Surface CubeSurface::unfold(CubeLayout layout) const
{ {
// @@ TODO // @@ TODO
return TexImage(); return Surface();
} }
CubeImage CubeImage::irradianceFilter(int size) const CubeSurface CubeSurface::irradianceFilter(int size) const
{ {
// @@ TODO // @@ 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 float u = (float(x) + 0.5f) * (2 * ilen) - 1.0f;
return CubeImage(); 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; 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; if (isNull()) return;

@ -25,6 +25,9 @@
#define NVTT_CUBEIMAGE_H #define NVTT_CUBEIMAGE_H
#include "nvtt.h" #include "nvtt.h"
#include "TexImage.h"
#include "nvimage/FloatImage.h"
#include "nvcore/RefCounted.h" #include "nvcore/RefCounted.h"
#include "nvcore/Ptr.h" #include "nvcore/Ptr.h"
@ -33,7 +36,7 @@
namespace nvtt namespace nvtt
{ {
struct CubeImage::Private : public nv::RefCounted struct CubeSurface::Private : public nv::RefCounted
{ {
void operator=(const Private &); void operator=(const Private &);
public: 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; int size;
TexImage face[6]; Surface face[6];
}; };
} // nvtt namespace } // 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(); m->addRef();
} }
TexImage::TexImage(const TexImage & tex) : m(tex.m) Surface::Surface(const Surface & tex) : m(tex.m)
{ {
if (m != NULL) m->addRef(); if (m != NULL) m->addRef();
} }
TexImage::~TexImage() Surface::~Surface()
{ {
if (m != NULL) m->release(); if (m != NULL) m->release();
m = NULL; m = NULL;
} }
void TexImage::operator=(const TexImage & tex) void Surface::operator=(const Surface & tex)
{ {
if (tex.m != NULL) tex.m->addRef(); if (tex.m != NULL) tex.m->addRef();
if (m != NULL) m->release(); if (m != NULL) m->release();
m = tex.m; m = tex.m;
} }
void TexImage::detach() void Surface::detach()
{ {
if (m->refCount() > 1) if (m->refCount() > 1)
{ {
m->release(); m->release();
m = new TexImage::Private(*m); m = new Surface::Private(*m);
m->addRef(); m->addRef();
nvDebugCheck(m->refCount() == 1); nvDebugCheck(m->refCount() == 1);
} }
} }
void TexImage::setWrapMode(WrapMode wrapMode) void Surface::setWrapMode(WrapMode wrapMode)
{ {
if (m->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) 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) 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; return m->image == NULL;
} }
int TexImage::width() const int Surface::width() const
{ {
if (m->image != NULL) return m->image->width(); if (m->image != NULL) return m->image->width();
return 0; return 0;
} }
int TexImage::height() const int Surface::height() const
{ {
if (m->image != NULL) return m->image->height(); if (m->image != NULL) return m->image->height();
return 0; return 0;
} }
int TexImage::depth() const int Surface::depth() const
{ {
if (m->image != NULL) return m->image->depth(); if (m->image != NULL) return m->image->depth();
return 0; return 0;
} }
WrapMode TexImage::wrapMode() const WrapMode Surface::wrapMode() const
{ {
return m->wrapMode; return m->wrapMode;
} }
AlphaMode TexImage::alphaMode() const AlphaMode Surface::alphaMode() const
{ {
return m->alphaMode; return m->alphaMode;
} }
bool TexImage::isNormalMap() const bool Surface::isNormalMap() const
{ {
return m->isNormalMap; return m->isNormalMap;
} }
TextureType TexImage::type() const TextureType Surface::type() const
{ {
return m->type; return m->type;
} }
int TexImage::countMipmaps() const int Surface::countMipmaps() const
{ {
if (m->image == NULL) return 0; if (m->image == NULL) return 0;
return ::countMipmaps(m->image->width(), m->image->height(), 1); 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; if (m->image == NULL) return 0.0f;
return m->image->alphaTestCoverage(alphaRef, 3); 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; 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; return sum / denom;
} }
const float * TexImage::data() const const float * Surface::data() const
{ {
return m->image->channel(0); 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. // We assume it's clear in case we want to accumulate multiple histograms.
//memset(bins, 0, sizeof(int)*count); //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); 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)); AutoPtr<FloatImage> img(ImageIO::loadFloat(fileName));
if (img == NULL) { if (img == NULL) {
@ -406,7 +406,7 @@ bool TexImage::load(const char * fileName, bool * hasAlpha/*= NULL*/)
return true; return true;
} }
bool TexImage::save(const char * fileName) const bool Surface::save(const char * fileName) const
{ {
if (m->image != NULL) if (m->image != NULL)
{ {
@ -416,7 +416,7 @@ bool TexImage::save(const char * fileName) const
return false; 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(); detach();
@ -488,7 +488,7 @@ bool TexImage::setImage(nvtt::InputFormat format, int w, int h, int d, const voi
return true; 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(); 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. // @@ 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) 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 filterWidth;
float params[2]; 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); 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; FloatImage * img = m->image;
if (img == NULL || (w == img->width() && h == img->height() && d == img->depth())) { 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; m->image = img;
} }
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter) void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
{ {
float filterWidth; float filterWidth;
float params[2]; float params[2];
@ -779,7 +779,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
resize(maxExtent, roundMode, filter, filterWidth, params); 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; 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); resize(w, h, d, filter, filterWidth, params);
} }
bool TexImage::buildNextMipmap(MipmapFilter filter) bool Surface::buildNextMipmap(MipmapFilter filter)
{ {
float filterWidth; float filterWidth;
float params[2]; float params[2];
@ -801,7 +801,7 @@ bool TexImage::buildNextMipmap(MipmapFilter filter)
return buildNextMipmap(filter, filterWidth, params); 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; FloatImage * img = m->image;
if (img == NULL || (img->width() == 1 && img->height() == 1 && img->depth() == 1)) { 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; 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); nvDebugCheck(w > 0 && h > 0 && d > 0);
@ -901,7 +901,7 @@ void TexImage::canvasSize(int w, int h, int d)
// Color transforms. // Color transforms.
void TexImage::toLinear(float gamma) void Surface::toLinear(float gamma)
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
if (equal(gamma, 1.0f)) return; if (equal(gamma, 1.0f)) return;
@ -911,7 +911,7 @@ void TexImage::toLinear(float gamma)
m->image->toLinear(0, 3, gamma); m->image->toLinear(0, 3, gamma);
} }
void TexImage::toGamma(float gamma) void Surface::toGamma(float gamma)
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
if (equal(gamma, 1.0f)) return; if (equal(gamma, 1.0f)) return;
@ -930,7 +930,7 @@ static float toSrgb(float f) {
return f; return f;
} }
void TexImage::toSrgb() void Surface::toSrgb()
{ {
FloatImage * img = m->image; FloatImage * img = m->image;
if (img == NULL) return; if (img == NULL) return;
@ -960,7 +960,7 @@ static float toXenonSrgb(float f) {
return f; return f;
} }
void TexImage::toXenonSrgb() void Surface::toXenonSrgb()
{ {
FloatImage * img = m->image; FloatImage * img = m->image;
if (img == NULL) return; 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; 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); 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 (m->image == NULL) return;
if (r == 0 && g == 1 && b == 2 && a == 3) 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 // 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 (m->image == NULL) return;
if (equal(scale, 1.0f) && equal(bias, 0.0f)) 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); 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; 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); m->image->clamp(channel, 1, low, high);
} }
void TexImage::packNormal() void Surface::packNormal()
{ {
scaleBias(0, 0.5f, 0.5f); scaleBias(0, 0.5f, 0.5f);
scaleBias(1, 0.5f, 0.5f); scaleBias(1, 0.5f, 0.5f);
scaleBias(2, 0.5f, 0.5f); scaleBias(2, 0.5f, 0.5f);
} }
void TexImage::expandNormal() void Surface::expandNormal()
{ {
scaleBias(0, 2.0f, -1.0f); scaleBias(0, 2.0f, -1.0f);
scaleBias(1, 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; 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; 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; if (m->image == NULL) return;
@ -1114,7 +1114,7 @@ void TexImage::toGreyScale(float redScale, float greenScale, float blueScale, fl
} }
// Draw colored border. // 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; 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. // 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; 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; if (m->image == NULL) return;
@ -1188,7 +1188,7 @@ void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
m->image->scaleAlphaToCoverage(coverage, alphaRef, 3); 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; 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. // 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. // 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; 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; 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. // 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; if (m->image == NULL) return;
@ -1348,7 +1348,7 @@ void TexImage::toYCoCg()
// @@ Add support for threshold. // @@ Add support for threshold.
// We could do something to prevent scale values from adjacent blocks from being too different to each other // We could do something to prevent scale values from adjacent blocks from being too different to each other
// and minimize bilinear interpolation artifacts. // 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; 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; 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; 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. // Decompression is the same as in RGBM.
fromRGBM(range * sqrtf(3)); fromRGBM(range * sqrtf(3));
} }
void TexImage::abs(int channel) void Surface::abs(int channel)
{ {
if (m->image == NULL) return; 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; 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; 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; if (m->image == NULL) return;
@ -1598,7 +1598,7 @@ void TexImage::toJPEGLS()
} }
} }
void TexImage::fromJPEGLS() void Surface::fromJPEGLS()
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
@ -1624,7 +1624,7 @@ void TexImage::fromJPEGLS()
// If dither is true, this uses Floyd-Steinberg dithering method. // 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; 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. // 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. // 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. // 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; if (m->image == NULL) return;
@ -1758,7 +1758,7 @@ void TexImage::quantize(int channel, int bits, bool exactEndPoints, bool dither)
// Set normal map options. // 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; if (m->image == NULL) return;
@ -1777,7 +1777,7 @@ void TexImage::toNormalMap(float sm, float medium, float big, float large)
m->isNormalMap = true; m->isNormalMap = true;
} }
void TexImage::normalizeNormalMap() void Surface::normalizeNormalMap()
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
if (!m->isNormalMap) return; if (!m->isNormalMap) return;
@ -1787,7 +1787,7 @@ void TexImage::normalizeNormalMap()
nv::normalizeNormalMap(m->image); nv::normalizeNormalMap(m->image);
} }
void TexImage::transformNormals(NormalTransform xform) void Surface::transformNormals(NormalTransform xform)
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
@ -1860,7 +1860,7 @@ void TexImage::transformNormals(NormalTransform xform)
img->packNormals(0); img->packNormals(0);
} }
void TexImage::reconstructNormals(NormalTransform xform) void Surface::reconstructNormals(NormalTransform xform)
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
@ -1909,7 +1909,7 @@ void TexImage::reconstructNormals(NormalTransform xform)
img->packNormals(0); img->packNormals(0);
} }
void TexImage::toCleanNormalMap() void Surface::toCleanNormalMap()
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
@ -1929,21 +1929,21 @@ void TexImage::toCleanNormalMap()
} }
// [-1,1] -> [ 0,1] // [-1,1] -> [ 0,1]
void TexImage::packNormals() { void Surface::packNormals() {
if (m->image == NULL) return; if (m->image == NULL) return;
detach(); detach();
m->image->packNormals(0); m->image->packNormals(0);
} }
// [ 0,1] -> [-1,1] // [ 0,1] -> [-1,1]
void TexImage::expandNormals() { void Surface::expandNormals() {
if (m->image == NULL) return; if (m->image == NULL) return;
detach(); detach();
m->image->expandNormals(0); m->image->expandNormals(0);
} }
void TexImage::flipX() void Surface::flipX()
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
@ -1952,7 +1952,7 @@ void TexImage::flipX()
m->image->flipX(); m->image->flipX();
} }
void TexImage::flipY() void Surface::flipY()
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
@ -1961,7 +1961,7 @@ void TexImage::flipY()
m->image->flipY(); m->image->flipY();
} }
void TexImage::flipZ() void Surface::flipZ()
{ {
if (m->image == NULL) return; if (m->image == NULL) return;
@ -1970,12 +1970,12 @@ void TexImage::flipZ()
m->image->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); 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; 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; 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; 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); 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); 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); 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::averageAngularError(reference.m->image, image.m->image);
return nv::rmsAngularError(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 * ref = reference.m->image;
const FloatImage * img = image.m->image; const FloatImage * img = image.m->image;
if (!sameLayout(img, ref)) { if (!sameLayout(img, ref)) {
return TexImage(); return Surface();
} }
nvDebugCheck(img->componentCount() == 4); nvDebugCheck(img->componentCount() == 4);
nvDebugCheck(ref->componentCount() == 4); nvDebugCheck(ref->componentCount() == 4);
nvtt::TexImage diffImage; nvtt::Surface diffImage;
FloatImage * diff = diffImage.m->image = new FloatImage; FloatImage * diff = diffImage.m->image = new FloatImage;
diff->allocate(4, img->width(), img->height(), img->depth()); diff->allocate(4, img->width(), img->height(), img->depth());

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

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

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

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

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

Loading…
Cancel
Save