Fix msvc warnings and errors.
Test TexImage stuff more througly. Test YCoCg and RGBM.
This commit is contained in:
parent
c1204bfb66
commit
5f845513ee
@ -6,6 +6,7 @@
|
||||
#include "TgaFile.h"
|
||||
#include "PsdFile.h"
|
||||
#include "DirectDrawSurface.h"
|
||||
#include "PixelFormat.h"
|
||||
|
||||
#include "nvmath/Color.h"
|
||||
#include "nvmath/Half.h"
|
||||
@ -290,7 +291,7 @@ bool nv::ImageIO::saveFloat(const char * fileName, Stream & s, const FloatImage
|
||||
image->setFormat(Image::Format_ARGB);
|
||||
}
|
||||
|
||||
return ImageIO::save(fileName, image.ptr());
|
||||
return ImageIO::save(fileName, s, image.ptr());
|
||||
}
|
||||
#endif // defined(HAVE_FREEIMAGE)
|
||||
|
||||
@ -299,9 +300,9 @@ bool nv::ImageIO::saveFloat(const char * fileName, Stream & s, const FloatImage
|
||||
|
||||
bool nv::ImageIO::saveFloat(const char * fileName, const FloatImage * fimage, uint baseComponent, uint componentCount)
|
||||
{
|
||||
#if !defined(HAVE_FREEIMAGE)
|
||||
const char * extension = Path::extension(fileName);
|
||||
|
||||
#if !defined(HAVE_FREEIMAGE)
|
||||
#if defined(HAVE_OPENEXR)
|
||||
if (strCaseCmp(extension, ".exr") == 0) {
|
||||
return saveFloatEXR(fileName, fimage, baseComponent, componentCount);
|
||||
@ -312,16 +313,15 @@ bool nv::ImageIO::saveFloat(const char * fileName, const FloatImage * fimage, ui
|
||||
return saveFloatTIFF(fileName, fimage, baseComponent, componentCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !defined(HAVE_FREEIMAGE)
|
||||
|
||||
StdInputStream stream(fileName);
|
||||
StdOutputStream stream(fileName);
|
||||
|
||||
if (stream.isError()) {
|
||||
return false;
|
||||
}
|
||||
if (stream.isError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return saveFloat(fileName, stream, fimage, baseComponent, componentCount);
|
||||
return saveFloat(fileName, stream, fimage, baseComponent, componentCount);
|
||||
}
|
||||
|
||||
#if defined(HAVE_FREEIMAGE)
|
||||
@ -448,6 +448,38 @@ FloatImage * nv::ImageIO::loadFloatFreeImage(FREE_IMAGE_FORMAT fif, Stream & s)
|
||||
|
||||
switch (fit)
|
||||
{
|
||||
case FIT_BITMAP:
|
||||
{
|
||||
floatImage->allocate(4, w, h);
|
||||
FIBITMAP * tmp = FreeImage_ConvertTo32Bits(bitmap);
|
||||
|
||||
uint bitcount = FreeImage_GetBPP(bitmap);
|
||||
uint byteCount = bitcount / 8;
|
||||
|
||||
for (int y=0; y < h; y++)
|
||||
{
|
||||
const Color32 * src = (const Color32 *)FreeImage_GetScanLine(bitmap, h - y - 1 );
|
||||
|
||||
float * r = floatImage->scanline(y, 0);
|
||||
float * g = floatImage->scanline(y, 1);
|
||||
float * b = floatImage->scanline(y, 2);
|
||||
float * a = floatImage->scanline(y, 3);
|
||||
|
||||
for (int x=0; x < w; x++)
|
||||
{
|
||||
r[x] = float(src[x].r) / 255.0f;
|
||||
g[x] = float(src[x].g) / 255.0f;
|
||||
b[x] = float(src[x].b) / 255.0f;
|
||||
a[x] = float(src[x].a) / 255.0f;
|
||||
}
|
||||
|
||||
src += byteCount;
|
||||
}
|
||||
|
||||
FreeImage_Unload(tmp);
|
||||
}
|
||||
|
||||
break;
|
||||
case FIT_FLOAT:
|
||||
floatImage->allocate(1, w, h);
|
||||
|
||||
@ -1216,7 +1248,7 @@ bool nv::ImageIO::savePNG(Stream & s, const Image * img, const ImageMetaData * t
|
||||
png_set_write_fn(png_ptr, (void*)&s, user_write_data, user_write_flush);
|
||||
|
||||
// Set image header information
|
||||
int color_type = PNG_COLOR_TYPE_RGB;
|
||||
int color_type = PNG_COLOR_TYPE_RGBA;
|
||||
switch(img->format())
|
||||
{
|
||||
case Image::Format_RGB: color_type = PNG_COLOR_TYPE_RGB; break;
|
||||
@ -1231,6 +1263,7 @@ bool nv::ImageIO::savePNG(Stream & s, const Image * img, const ImageMetaData * t
|
||||
png_bytep * row_data = new png_bytep[sizeof(png_byte) * img->height()];
|
||||
for (uint i = 0; i < img->height(); i++) {
|
||||
row_data[i] = (png_byte*)img->scanline (i);
|
||||
if (img->format() == Image::Format_RGB) row_data[i]--; // This is a bit of a hack, libpng expects images in ARGB format not BGRA, it supports BGR swapping, but not alpha swapping.
|
||||
}
|
||||
png_set_rows(png_ptr, info_ptr, row_data);
|
||||
|
||||
@ -1252,9 +1285,10 @@ bool nv::ImageIO::savePNG(Stream & s, const Image * img, const ImageMetaData * t
|
||||
|
||||
png_write_png(png_ptr, info_ptr,
|
||||
// component order is BGR(A)
|
||||
PNG_TRANSFORM_BGR
|
||||
PNG_TRANSFORM_BGR |
|
||||
// Strip alpha byte for RGB images
|
||||
| (img->format() == Image::Format_RGB ? PNG_TRANSFORM_STRIP_FILLER : 0),
|
||||
(img->format() == Image::Format_RGB ? PNG_TRANSFORM_STRIP_FILLER : 0)
|
||||
,
|
||||
NULL);
|
||||
|
||||
// Finish things up
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright Ignacio Castano <icastano@nvidia.com> 2009
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2008 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2008-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@ -133,9 +134,9 @@ bool Compressor::outputHeader(const TexImage & tex, int mipmapCount, const Compr
|
||||
return m.outputHeader(TextureType_2D, tex.width(), tex.height(), tex.depth(), mipmapCount, tex.isNormalMap(), compressionOptions.m, outputOptions.m);
|
||||
}
|
||||
|
||||
bool Compressor::compress(const TexImage & tex, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||
bool Compressor::compress(const TexImage & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||
{
|
||||
return m.compress(tex, 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
|
||||
@ -149,9 +150,9 @@ int Compressor::estimateSize(const TexImage & tex, int mipmapCount, const Compre
|
||||
|
||||
|
||||
// Raw API.
|
||||
bool Compressor::compress(int w, int h, int d, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||
bool Compressor::compress(int w, int h, int d, int face, int mipmap, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||
{
|
||||
return m.compress(AlphaMode_None, w, h, d, rgba, compressionOptions.m, outputOptions.m);
|
||||
return m.compress(AlphaMode_None, w, h, d, face, mipmap, rgba, compressionOptions.m, outputOptions.m);
|
||||
}
|
||||
|
||||
int Compressor::estimateSize(int w, int h, int d, int mipmapCount, const CompressionOptions & compressionOptions) const
|
||||
@ -244,20 +245,14 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
||||
tmp.toGamma(inputOptions.outputGamma);
|
||||
}
|
||||
|
||||
int size = computeImageSize(w, h, d, compressionOptions.bitcount, compressionOptions.pitchAlignment, compressionOptions.format);
|
||||
outputOptions.beginImage(size, w, h, d, f, 0);
|
||||
|
||||
quantize(tmp, compressionOptions);
|
||||
compress(tmp, compressionOptions, outputOptions);
|
||||
compress(tmp, f, 0, compressionOptions, outputOptions);
|
||||
|
||||
for (int m = 1; m < mipmapCount; m++) {
|
||||
w = max(1, w/2);
|
||||
h = max(1, h/2);
|
||||
d = max(1, d/2);
|
||||
|
||||
int size = computeImageSize(w, h, d, compressionOptions.bitcount, compressionOptions.pitchAlignment, compressionOptions.format);
|
||||
outputOptions.beginImage(size, w, h, d, f, m);
|
||||
|
||||
int idx = m * faceCount + f;
|
||||
|
||||
bool useSourceImages = false;
|
||||
@ -296,24 +291,27 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
||||
}
|
||||
|
||||
quantize(tmp, compressionOptions);
|
||||
compress(tmp, compressionOptions, outputOptions);
|
||||
compress(tmp, f, m, compressionOptions, outputOptions);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compressor::Private::compress(const TexImage & tex, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
|
||||
bool Compressor::Private::compress(const TexImage & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
|
||||
{
|
||||
if (!compress(tex.alphaMode(), tex.width(), tex.height(), tex.depth(), tex.data(), compressionOptions, outputOptions)) {
|
||||
if (!compress(tex.alphaMode(), tex.width(), tex.height(), tex.depth(), face, mipmap, tex.data(), compressionOptions, outputOptions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compressor::Private::compress(AlphaMode alphaMode, int w, int h, int d, const float * rgba, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
|
||||
bool Compressor::Private::compress(AlphaMode alphaMode, int w, int h, int d, int face, int mipmap, const float * rgba, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
|
||||
{
|
||||
int size = computeImageSize(w, h, d, compressionOptions.bitcount, compressionOptions.pitchAlignment, compressionOptions.format);
|
||||
outputOptions.beginImage(size, w, h, d, face, mipmap);
|
||||
|
||||
// Decide what compressor to use.
|
||||
AutoPtr<CompressorInterface> compressor;
|
||||
#if defined HAVE_CUDA
|
||||
@ -340,7 +338,7 @@ bool Compressor::Private::compress(AlphaMode alphaMode, int w, int h, int d, con
|
||||
}
|
||||
|
||||
|
||||
bool Compressor::Private::quantize(TexImage & img, const CompressionOptions::Private & compressionOptions) const
|
||||
void Compressor::Private::quantize(TexImage & img, const CompressionOptions::Private & compressionOptions) const
|
||||
{
|
||||
if (compressionOptions.enableColorDithering) {
|
||||
if (compressionOptions.format >= Format_BC1 && compressionOptions.format <= Format_BC3) {
|
||||
@ -362,7 +360,7 @@ bool Compressor::Private::quantize(TexImage & img, const CompressionOptions::Pri
|
||||
}
|
||||
}
|
||||
else if (compressionOptions.binaryAlpha) {
|
||||
img.binarize(3, compressionOptions.alphaThreshold, compressionOptions.enableAlphaDithering);
|
||||
img.binarize(3, float(compressionOptions.alphaThreshold)/255.0f, compressionOptions.enableAlphaDithering);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2008 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@ -43,11 +44,11 @@ namespace nvtt
|
||||
{
|
||||
Private() {}
|
||||
|
||||
bool compress(const TexImage & tex, 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(AlphaMode alphaMode, int w, int h, int d, const float * data, 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(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 quantize(TexImage & tex, const CompressionOptions::Private & compressionOptions) const;
|
||||
void quantize(TexImage & 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(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@ -157,7 +158,7 @@ void InputOptions::resetTextureLayout()
|
||||
if (m.images != NULL)
|
||||
{
|
||||
// Delete images.
|
||||
for (int i = 0; i < m.imageCount; i++) {
|
||||
for (uint i = 0; i < m.imageCount; i++) {
|
||||
free(m.images[i]);
|
||||
}
|
||||
|
||||
@ -178,14 +179,14 @@ bool InputOptions::setMipmapData(const void * data, int width, int height, int d
|
||||
if (depth != 1) {
|
||||
return false;
|
||||
}
|
||||
if (face >= m.faceCount) {
|
||||
if (uint(face) >= m.faceCount) {
|
||||
return false;
|
||||
}
|
||||
if (mipLevel >= m.mipmapCount) {
|
||||
if (uint(mipLevel) >= m.mipmapCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int idx = mipLevel * m.faceCount + face;
|
||||
const uint idx = mipLevel * m.faceCount + face;
|
||||
if (idx >= m.imageCount) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2008 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@ -472,9 +473,7 @@ bool TexImage::setImage2D(InputFormat format, int w, int h, const void * r, cons
|
||||
|
||||
bool TexImage::setImage2D(Format format, Decoder decoder, int w, int h, const void * data)
|
||||
{
|
||||
#pragma NV_MESSAGE("TODO: Add support for all compressed formats in TexImage::setImage2D.")
|
||||
|
||||
if (format != nvtt::Format_BC1 && format != nvtt::Format_BC2 && format != nvtt::Format_BC3)
|
||||
if (format != nvtt::Format_BC1 && format != nvtt::Format_BC2 && format != nvtt::Format_BC3 && format != nvtt::Format_BC4 && format != nvtt::Format_BC5)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -500,59 +499,69 @@ bool TexImage::setImage2D(Format format, Decoder decoder, int w, int h, const vo
|
||||
{
|
||||
ColorBlock colors;
|
||||
|
||||
if (format == nvtt::Format_BC1)
|
||||
{
|
||||
const BlockDXT1 * block = (const BlockDXT1 *)ptr;
|
||||
if (format == nvtt::Format_BC1)
|
||||
{
|
||||
const BlockDXT1 * block = (const BlockDXT1 *)ptr;
|
||||
|
||||
if (decoder == Decoder_Reference) {
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (decoder == Decoder_NV5x) {
|
||||
block->decodeBlockNV5x(&colors);
|
||||
}
|
||||
}
|
||||
else if (format == nvtt::Format_BC2)
|
||||
{
|
||||
const BlockDXT3 * block = (const BlockDXT3 *)ptr;
|
||||
if (decoder == Decoder_Reference) {
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (decoder == Decoder_NV5x) {
|
||||
block->decodeBlockNV5x(&colors);
|
||||
}
|
||||
}
|
||||
else if (format == nvtt::Format_BC2)
|
||||
{
|
||||
const BlockDXT3 * block = (const BlockDXT3 *)ptr;
|
||||
|
||||
if (decoder == Decoder_Reference) {
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (decoder == Decoder_NV5x) {
|
||||
block->decodeBlockNV5x(&colors);
|
||||
}
|
||||
}
|
||||
else if (format == nvtt::Format_BC3)
|
||||
{
|
||||
const BlockDXT5 * block = (const BlockDXT5 *)ptr;
|
||||
if (decoder == Decoder_Reference) {
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (decoder == Decoder_NV5x) {
|
||||
block->decodeBlockNV5x(&colors);
|
||||
}
|
||||
}
|
||||
else if (format == nvtt::Format_BC3)
|
||||
{
|
||||
const BlockDXT5 * block = (const BlockDXT5 *)ptr;
|
||||
|
||||
if (decoder == Decoder_Reference) {
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (decoder == Decoder_NV5x) {
|
||||
block->decodeBlockNV5x(&colors);
|
||||
}
|
||||
}
|
||||
if (decoder == Decoder_Reference) {
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (decoder == Decoder_NV5x) {
|
||||
block->decodeBlockNV5x(&colors);
|
||||
}
|
||||
}
|
||||
else if (format == nvtt::Format_BC4)
|
||||
{
|
||||
const BlockATI1 * block = (const BlockATI1 *)ptr;
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (format == nvtt::Format_BC5)
|
||||
{
|
||||
const BlockATI2 * block = (const BlockATI2 *)ptr;
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
|
||||
for (int yy = 0; yy < 4; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < 4; xx++)
|
||||
{
|
||||
Color32 c = colors.color(xx, yy);
|
||||
for (int yy = 0; yy < 4; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < 4; xx++)
|
||||
{
|
||||
Color32 c = colors.color(xx, yy);
|
||||
|
||||
if (x * 4 + xx < w && y * 4 + yy < h)
|
||||
{
|
||||
m->image->pixel(x*4 + xx, y*4 + yy, 0) = float(c.r) * 1.0f/255.0f;
|
||||
m->image->pixel(x*4 + xx, y*4 + yy, 1) = float(c.g) * 1.0f/255.0f;
|
||||
m->image->pixel(x*4 + xx, y*4 + yy, 2) = float(c.b) * 1.0f/255.0f;
|
||||
m->image->pixel(x*4 + xx, y*4 + yy, 3) = float(c.a) * 1.0f/255.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (x * 4 + xx < w && y * 4 + yy < h)
|
||||
{
|
||||
m->image->pixel(x*4 + xx, y*4 + yy, 0) = float(c.r) * 1.0f/255.0f;
|
||||
m->image->pixel(x*4 + xx, y*4 + yy, 1) = float(c.g) * 1.0f/255.0f;
|
||||
m->image->pixel(x*4 + xx, y*4 + yy, 2) = float(c.b) * 1.0f/255.0f;
|
||||
m->image->pixel(x*4 + xx, y*4 + yy, 3) = float(c.a) * 1.0f/255.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ptr += bs;
|
||||
ptr += bs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...) {
|
||||
return false;
|
||||
@ -803,6 +812,7 @@ void TexImage::swizzle(int r, int g, int b, int a)
|
||||
m->image->swizzle(0, r, g, b, a);
|
||||
}
|
||||
|
||||
// color * scale + bias
|
||||
void TexImage::scaleBias(int channel, float scale, float bias)
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
@ -1038,21 +1048,44 @@ void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
|
||||
|
||||
const uint count = img->width() * img->height();
|
||||
for (uint i = 0; i < count; i++) {
|
||||
float ri = nv::clamp(r[i] * irange, 0.0f, 1.0f);
|
||||
float gi = nv::clamp(g[i] * irange, 0.0f, 1.0f);
|
||||
float bi = nv::clamp(b[i] * irange, 0.0f, 1.0f);
|
||||
float R = nv::clamp(r[i] * irange, 0.0f, 1.0f);
|
||||
float G = nv::clamp(g[i] * irange, 0.0f, 1.0f);
|
||||
float B = nv::clamp(b[i] * irange, 0.0f, 1.0f);
|
||||
|
||||
float m = max(max(ri, gi), max(bi, 1e-6f)); // Avoid division by zero.
|
||||
float M = max(max(R, G), max(B, 1e-6f)); // Avoid division by zero.
|
||||
//m = quantizeCeil(m, 8);
|
||||
float im = 1.0f / m;
|
||||
|
||||
r[i] = ri * im;
|
||||
g[i] = gi * im;
|
||||
b[i] = bi * im;
|
||||
a[i] = m;
|
||||
r[i] = R / M;
|
||||
g[i] = G / M;
|
||||
b[i] = B / M;
|
||||
a[i] = M;
|
||||
}
|
||||
}
|
||||
|
||||
void TexImage::fromRGBM(float range/*= 1*/)
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
detach();
|
||||
|
||||
FloatImage * img = m->image;
|
||||
float * r = img->channel(0);
|
||||
float * g = img->channel(1);
|
||||
float * b = img->channel(2);
|
||||
float * a = img->channel(3);
|
||||
|
||||
const uint count = img->width() * img->height();
|
||||
for (uint i = 0; i < count; i++) {
|
||||
float M = a[i] * range;
|
||||
|
||||
r[i] *= M;
|
||||
g[i] *= M;
|
||||
b[i] *= M;
|
||||
a[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Y is in the [0, 1] range, while CoCg are in the [-1, 1] range.
|
||||
void TexImage::toYCoCg()
|
||||
{
|
||||
@ -1068,13 +1101,13 @@ void TexImage::toYCoCg()
|
||||
|
||||
const uint count = img->width() * img->height();
|
||||
for (uint i = 0; i < count; i++) {
|
||||
float ri = r[i];
|
||||
float gi = g[i];
|
||||
float bi = b[i];
|
||||
float R = r[i];
|
||||
float G = g[i];
|
||||
float B = b[i];
|
||||
|
||||
float Y = (2*gi + ri + bi) * 0.25f;
|
||||
float Co = (ri - bi);
|
||||
float Cg = (2*gi - ri - bi) * 0.5f;
|
||||
float Y = (2*G + R + B) * 0.25f;
|
||||
float Co = (R - B);
|
||||
float Cg = (2*G - R - B) * 0.5f;
|
||||
|
||||
r[i] = Co;
|
||||
g[i] = Cg;
|
||||
@ -1146,6 +1179,40 @@ void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
|
||||
}
|
||||
}
|
||||
|
||||
void TexImage::fromYCoCg()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
detach();
|
||||
|
||||
FloatImage * img = m->image;
|
||||
float * r = img->channel(0);
|
||||
float * g = img->channel(1);
|
||||
float * b = img->channel(2);
|
||||
float * a = img->channel(3);
|
||||
|
||||
const uint count = img->width() * img->height();
|
||||
for (uint i = 0; i < count; i++) {
|
||||
float Co = r[i];
|
||||
float Cg = g[i];
|
||||
float scale = b[i];
|
||||
float Y = a[i];
|
||||
|
||||
Co *= scale;
|
||||
Cg *= scale;
|
||||
|
||||
float R = Y + Co - Cg;
|
||||
float G = Y + Cg;
|
||||
float B = Y - Co - Cg;
|
||||
|
||||
r[i] = R;
|
||||
g[i] = G;
|
||||
b[i] = B;
|
||||
a[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TexImage::binarize(int channel, float threshold, bool dither)
|
||||
{
|
||||
@ -1189,79 +1256,6 @@ void TexImage::normalizeNormalMap()
|
||||
nv::normalizeNormalMap(m->image);
|
||||
}
|
||||
|
||||
float TexImage::rootMeanSquaredError_rgb(const TexImage & reference) const
|
||||
{
|
||||
double mse = 0;
|
||||
|
||||
const FloatImage * img = m->image;
|
||||
const FloatImage * ref = reference.m->image;
|
||||
|
||||
if (img == NULL || ref == NULL || img->width() != ref->width() || img->height() != ref->height()) {
|
||||
return FLT_MAX;
|
||||
}
|
||||
nvDebugCheck(img->componentNum() == 4);
|
||||
nvDebugCheck(ref->componentNum() == 4);
|
||||
|
||||
const uint count = img->width() * img->height();
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
float r0 = img->pixel(4 * i + count * 0);
|
||||
float g0 = img->pixel(4 * i + count * 1);
|
||||
float b0 = img->pixel(4 * i + count * 2);
|
||||
//float a0 = img->pixel(4 * i + count * 3);
|
||||
float r1 = ref->pixel(4 * i + count * 0);
|
||||
float g1 = ref->pixel(4 * i + count * 1);
|
||||
float b1 = ref->pixel(4 * i + count * 2);
|
||||
float a1 = ref->pixel(4 * i + count * 3);
|
||||
|
||||
float r = r0 - r1;
|
||||
float g = g0 - g1;
|
||||
float b = b0 - b1;
|
||||
//float a = a0 - a1;
|
||||
|
||||
if (reference.alphaMode() == nvtt::AlphaMode_Transparency)
|
||||
{
|
||||
mse += double(r * r) * a1 / 255.0;
|
||||
mse += double(g * g) * a1 / 255.0;
|
||||
mse += double(b * b) * a1 / 255.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mse += r * r;
|
||||
mse += g * g;
|
||||
mse += b * b;
|
||||
}
|
||||
}
|
||||
|
||||
return float(sqrt(mse / count));
|
||||
}
|
||||
|
||||
float TexImage::rootMeanSquaredError_alpha(const TexImage & reference) const
|
||||
{
|
||||
double mse = 0;
|
||||
|
||||
const FloatImage * img = m->image;
|
||||
const FloatImage * ref = reference.m->image;
|
||||
|
||||
if (img == NULL || ref == NULL || img->width() != ref->width() || img->height() != ref->height()) {
|
||||
return FLT_MAX;
|
||||
}
|
||||
nvDebugCheck(img->componentNum() == 4 && ref->componentNum() == 4);
|
||||
|
||||
const uint count = img->width() * img->height();
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
float a0 = img->pixel(4 * i + count * 3);
|
||||
float a1 = ref->pixel(4 * i + count * 3);
|
||||
|
||||
float a = a0 - a1;
|
||||
|
||||
mse += double(a * a);
|
||||
}
|
||||
|
||||
return float(sqrt(mse / count));
|
||||
}
|
||||
|
||||
void TexImage::flipVertically()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
@ -1299,3 +1293,117 @@ bool TexImage::copyChannel(const TexImage & srcImage, int srcChannel, int dstCha
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
float nvtt::rmsError(const TexImage & reference, const TexImage & image)
|
||||
{
|
||||
double mse = 0;
|
||||
|
||||
const FloatImage * ref = reference.m->image;
|
||||
const FloatImage * img = image.m->image;
|
||||
|
||||
if (img == NULL || ref == NULL || img->width() != ref->width() || img->height() != ref->height()) {
|
||||
return FLT_MAX;
|
||||
}
|
||||
nvDebugCheck(img->componentNum() == 4);
|
||||
nvDebugCheck(ref->componentNum() == 4);
|
||||
|
||||
const uint count = img->width() * img->height();
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
float r0 = img->pixel(i + count * 0);
|
||||
float g0 = img->pixel(i + count * 1);
|
||||
float b0 = img->pixel(i + count * 2);
|
||||
//float a0 = img->pixel(i + count * 3);
|
||||
float r1 = ref->pixel(i + count * 0);
|
||||
float g1 = ref->pixel(i + count * 1);
|
||||
float b1 = ref->pixel(i + count * 2);
|
||||
float a1 = ref->pixel(i + count * 3);
|
||||
|
||||
float r = r0 - r1;
|
||||
float g = g0 - g1;
|
||||
float b = b0 - b1;
|
||||
//float a = a0 - a1;
|
||||
|
||||
if (reference.alphaMode() == nvtt::AlphaMode_Transparency)
|
||||
{
|
||||
mse += double(r * r) * a1;
|
||||
mse += double(g * g) * a1;
|
||||
mse += double(b * b) * a1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mse += r * r;
|
||||
mse += g * g;
|
||||
mse += b * b;
|
||||
}
|
||||
}
|
||||
|
||||
return float(sqrt(mse / count));
|
||||
}
|
||||
|
||||
|
||||
/*float rmsError(const Image * a, const Image * b)
|
||||
{
|
||||
nvCheck(a != NULL);
|
||||
nvCheck(b != NULL);
|
||||
nvCheck(a->width() == b->width());
|
||||
nvCheck(a->height() == b->height());
|
||||
|
||||
double mse = 0;
|
||||
|
||||
const uint count = a->width() * a->height();
|
||||
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
Color32 c0 = a->pixel(i);
|
||||
Color32 c1 = b->pixel(i);
|
||||
|
||||
int r = c0.r - c1.r;
|
||||
int g = c0.g - c1.g;
|
||||
int b = c0.b - c1.b;
|
||||
int a = c0.a - c1.a;
|
||||
|
||||
mse += double(r * r * c0.a) / 255;
|
||||
mse += double(g * g * c0.a) / 255;
|
||||
mse += double(b * b * c0.a) / 255;
|
||||
}
|
||||
|
||||
return float(sqrt(mse / count));
|
||||
}*/
|
||||
|
||||
|
||||
float nvtt::rmsAlphaError(const TexImage & reference, const TexImage & image)
|
||||
{
|
||||
double mse = 0;
|
||||
|
||||
const FloatImage * img = image.m->image;
|
||||
const FloatImage * ref = reference.m->image;
|
||||
|
||||
if (img == NULL || ref == NULL || img->width() != ref->width() || img->height() != ref->height()) {
|
||||
return FLT_MAX;
|
||||
}
|
||||
nvDebugCheck(img->componentNum() == 4 && ref->componentNum() == 4);
|
||||
|
||||
const uint count = img->width() * img->height();
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
float a0 = img->pixel(i + count * 3);
|
||||
float a1 = ref->pixel(i + count * 3);
|
||||
|
||||
float a = a0 - a1;
|
||||
|
||||
mse += double(a * a);
|
||||
}
|
||||
|
||||
return float(sqrt(mse / count));
|
||||
}
|
||||
|
||||
TexImage nvtt::diff(const TexImage & reference, const TexImage & image)
|
||||
{
|
||||
// @@ TODO.
|
||||
return TexImage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@ -133,11 +134,11 @@ void CudaCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const f
|
||||
// Allocate image as a cuda array.
|
||||
const uint count = w * h;
|
||||
Color32 * tmp = malloc<Color32>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
tmp[i].r = clamp(data[i + count*0], 0.0f, 1.0f) * 255;
|
||||
tmp[i].g = clamp(data[i + count*1], 0.0f, 1.0f) * 255;
|
||||
tmp[i].b = clamp(data[i + count*2], 0.0f, 1.0f) * 255;
|
||||
tmp[i].a = clamp(data[i + count*3], 0.0f, 1.0f) * 255;
|
||||
for (uint i = 0; i < count; i++) {
|
||||
tmp[i].r = uint8(clamp(data[i + count*0], 0.0f, 1.0f) * 255);
|
||||
tmp[i].g = uint8(clamp(data[i + count*1], 0.0f, 1.0f) * 255);
|
||||
tmp[i].b = uint8(clamp(data[i + count*2], 0.0f, 1.0f) * 255);
|
||||
tmp[i].a = uint8(clamp(data[i + count*3], 0.0f, 1.0f) * 255);
|
||||
}
|
||||
|
||||
cudaArray * d_image;
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,239 +1,240 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "nvcore/Debug.h"
|
||||
#include "nvcore/Library.h"
|
||||
#include "CudaUtils.h"
|
||||
|
||||
#if defined HAVE_CUDA
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#endif
|
||||
|
||||
using namespace nv;
|
||||
using namespace cuda;
|
||||
|
||||
/* @@ Move this to win32 utils or somewhere else.
|
||||
#if NV_OS_WIN32
|
||||
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
static bool isWindowsVista()
|
||||
{
|
||||
OSVERSIONINFO osvi;
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
::GetVersionEx(&osvi);
|
||||
return osvi.dwMajorVersion >= 6;
|
||||
}
|
||||
|
||||
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||||
|
||||
static bool isWow32()
|
||||
{
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
|
||||
|
||||
BOOL bIsWow64 = FALSE;
|
||||
|
||||
if (NULL != fnIsWow64Process)
|
||||
{
|
||||
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
|
||||
{
|
||||
// Assume 32 bits.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return !bIsWow64;
|
||||
}
|
||||
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
static bool isCudaDriverAvailable(int version)
|
||||
{
|
||||
#if defined HAVE_CUDA
|
||||
#if NV_OS_WIN32
|
||||
Library nvcuda("nvcuda.dll");
|
||||
#else
|
||||
Library nvcuda(NV_LIBRARY_NAME(cuda));
|
||||
#endif
|
||||
|
||||
if (!nvcuda.isValid())
|
||||
{
|
||||
nvDebug("*** CUDA driver not found.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version >= 2000)
|
||||
{
|
||||
void * address = nvcuda.bindSymbol("cuStreamCreate");
|
||||
if (address == NULL) {
|
||||
nvDebug("*** CUDA driver version < 2.0.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= 2010)
|
||||
{
|
||||
void * address = nvcuda.bindSymbol("cuModuleLoadDataEx");
|
||||
if (address == NULL) {
|
||||
nvDebug("*** CUDA driver version < 2.1.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= 2020)
|
||||
{
|
||||
typedef CUresult (CUDAAPI * PFCU_DRIVERGETVERSION)(int * version);
|
||||
|
||||
PFCU_DRIVERGETVERSION driverGetVersion = (PFCU_DRIVERGETVERSION)nvcuda.bindSymbol("cuDriverGetVersion");
|
||||
if (driverGetVersion == NULL) {
|
||||
nvDebug("*** CUDA driver version < 2.2.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
int driverVersion;
|
||||
CUresult err = driverGetVersion(&driverVersion);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
nvDebug("*** Error querying driver version: '%s'.\n", cudaGetErrorString((cudaError_t)err));
|
||||
return false;
|
||||
}
|
||||
|
||||
return driverVersion >= version;
|
||||
}
|
||||
#endif // HAVE_CUDA
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Determine if CUDA is available.
|
||||
bool nv::cuda::isHardwarePresent()
|
||||
{
|
||||
#if defined HAVE_CUDA
|
||||
// Make sure that CUDA driver matches CUDA runtime.
|
||||
if (!isCudaDriverAvailable(CUDART_VERSION))
|
||||
{
|
||||
nvDebug("CUDA driver not available for CUDA runtime %d\n", CUDART_VERSION);
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = deviceCount();
|
||||
if (count == 1)
|
||||
{
|
||||
// Make sure it's not an emulation device.
|
||||
cudaDeviceProp deviceProp;
|
||||
cudaGetDeviceProperties(&deviceProp, 0);
|
||||
|
||||
// deviceProp.name != Device Emulation (CPU)
|
||||
if (deviceProp.major == -1 || deviceProp.minor == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// @@ Make sure that warp size == 32
|
||||
|
||||
return count > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Get number of CUDA enabled devices.
|
||||
int nv::cuda::deviceCount()
|
||||
{
|
||||
#if defined HAVE_CUDA
|
||||
int gpuCount = 0;
|
||||
|
||||
cudaError_t result = cudaGetDeviceCount(&gpuCount);
|
||||
|
||||
if (result == cudaSuccess)
|
||||
{
|
||||
return gpuCount;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nv::cuda::getFastestDevice()
|
||||
{
|
||||
int max_gflops_device = 0;
|
||||
#if defined HAVE_CUDA
|
||||
int max_gflops = 0;
|
||||
|
||||
const int device_count = deviceCount();
|
||||
int current_device = 0;
|
||||
while (current_device < device_count)
|
||||
{
|
||||
cudaDeviceProp device_properties;
|
||||
cudaGetDeviceProperties(&device_properties, current_device);
|
||||
int gflops = device_properties.multiProcessorCount * device_properties.clockRate;
|
||||
|
||||
if (device_properties.major != -1 && device_properties.minor != -1)
|
||||
{
|
||||
if( gflops > max_gflops )
|
||||
{
|
||||
max_gflops = gflops;
|
||||
max_gflops_device = current_device;
|
||||
}
|
||||
}
|
||||
|
||||
current_device++;
|
||||
}
|
||||
#endif
|
||||
return max_gflops_device;
|
||||
}
|
||||
|
||||
|
||||
/// Activate the given devices.
|
||||
bool nv::cuda::setDevice(int i)
|
||||
{
|
||||
nvCheck(i < deviceCount());
|
||||
#if defined HAVE_CUDA
|
||||
cudaError_t result = cudaSetDevice(i);
|
||||
|
||||
if (result != cudaSuccess) {
|
||||
nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(result));
|
||||
}
|
||||
|
||||
return result == cudaSuccess;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void nv::cuda::exit()
|
||||
{
|
||||
#if defined HAVE_CUDA
|
||||
cudaError_t result = cudaThreadExit();
|
||||
|
||||
if (result != cudaSuccess) {
|
||||
nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(result));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "nvcore/Debug.h"
|
||||
#include "nvcore/Library.h"
|
||||
#include "CudaUtils.h"
|
||||
|
||||
#if defined HAVE_CUDA
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#endif
|
||||
|
||||
using namespace nv;
|
||||
using namespace cuda;
|
||||
|
||||
/* @@ Move this to win32 utils or somewhere else.
|
||||
#if NV_OS_WIN32
|
||||
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
static bool isWindowsVista()
|
||||
{
|
||||
OSVERSIONINFO osvi;
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
::GetVersionEx(&osvi);
|
||||
return osvi.dwMajorVersion >= 6;
|
||||
}
|
||||
|
||||
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||||
|
||||
static bool isWow32()
|
||||
{
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
|
||||
|
||||
BOOL bIsWow64 = FALSE;
|
||||
|
||||
if (NULL != fnIsWow64Process)
|
||||
{
|
||||
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
|
||||
{
|
||||
// Assume 32 bits.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return !bIsWow64;
|
||||
}
|
||||
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
static bool isCudaDriverAvailable(int version)
|
||||
{
|
||||
#if defined HAVE_CUDA
|
||||
#if NV_OS_WIN32
|
||||
Library nvcuda("nvcuda.dll");
|
||||
#else
|
||||
Library nvcuda(NV_LIBRARY_NAME(cuda));
|
||||
#endif
|
||||
|
||||
if (!nvcuda.isValid())
|
||||
{
|
||||
nvDebug("*** CUDA driver not found.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version >= 2000)
|
||||
{
|
||||
void * address = nvcuda.bindSymbol("cuStreamCreate");
|
||||
if (address == NULL) {
|
||||
nvDebug("*** CUDA driver version < 2.0.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= 2010)
|
||||
{
|
||||
void * address = nvcuda.bindSymbol("cuModuleLoadDataEx");
|
||||
if (address == NULL) {
|
||||
nvDebug("*** CUDA driver version < 2.1.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= 2020)
|
||||
{
|
||||
typedef CUresult (CUDAAPI * PFCU_DRIVERGETVERSION)(int * version);
|
||||
|
||||
PFCU_DRIVERGETVERSION driverGetVersion = (PFCU_DRIVERGETVERSION)nvcuda.bindSymbol("cuDriverGetVersion");
|
||||
if (driverGetVersion == NULL) {
|
||||
nvDebug("*** CUDA driver version < 2.2.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
int driverVersion;
|
||||
CUresult err = driverGetVersion(&driverVersion);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
nvDebug("*** Error querying driver version: '%s'.\n", cudaGetErrorString((cudaError_t)err));
|
||||
return false;
|
||||
}
|
||||
|
||||
return driverVersion >= version;
|
||||
}
|
||||
#endif // HAVE_CUDA
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Determine if CUDA is available.
|
||||
bool nv::cuda::isHardwarePresent()
|
||||
{
|
||||
#if defined HAVE_CUDA
|
||||
// Make sure that CUDA driver matches CUDA runtime.
|
||||
if (!isCudaDriverAvailable(CUDART_VERSION))
|
||||
{
|
||||
nvDebug("CUDA driver not available for CUDA runtime %d\n", CUDART_VERSION);
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = deviceCount();
|
||||
if (count == 1)
|
||||
{
|
||||
// Make sure it's not an emulation device.
|
||||
cudaDeviceProp deviceProp;
|
||||
cudaGetDeviceProperties(&deviceProp, 0);
|
||||
|
||||
// deviceProp.name != Device Emulation (CPU)
|
||||
if (deviceProp.major == -1 || deviceProp.minor == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// @@ Make sure that warp size == 32
|
||||
|
||||
return count > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Get number of CUDA enabled devices.
|
||||
int nv::cuda::deviceCount()
|
||||
{
|
||||
#if defined HAVE_CUDA
|
||||
int gpuCount = 0;
|
||||
|
||||
cudaError_t result = cudaGetDeviceCount(&gpuCount);
|
||||
|
||||
if (result == cudaSuccess)
|
||||
{
|
||||
return gpuCount;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nv::cuda::getFastestDevice()
|
||||
{
|
||||
int max_gflops_device = 0;
|
||||
#if defined HAVE_CUDA
|
||||
int max_gflops = 0;
|
||||
|
||||
const int device_count = deviceCount();
|
||||
int current_device = 0;
|
||||
while (current_device < device_count)
|
||||
{
|
||||
cudaDeviceProp device_properties;
|
||||
cudaGetDeviceProperties(&device_properties, current_device);
|
||||
int gflops = device_properties.multiProcessorCount * device_properties.clockRate;
|
||||
|
||||
if (device_properties.major != -1 && device_properties.minor != -1)
|
||||
{
|
||||
if( gflops > max_gflops )
|
||||
{
|
||||
max_gflops = gflops;
|
||||
max_gflops_device = current_device;
|
||||
}
|
||||
}
|
||||
|
||||
current_device++;
|
||||
}
|
||||
#endif
|
||||
return max_gflops_device;
|
||||
}
|
||||
|
||||
|
||||
/// Activate the given devices.
|
||||
bool nv::cuda::setDevice(int i)
|
||||
{
|
||||
nvCheck(i < deviceCount());
|
||||
#if defined HAVE_CUDA
|
||||
cudaError_t result = cudaSetDevice(i);
|
||||
|
||||
if (result != cudaSuccess) {
|
||||
nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(result));
|
||||
}
|
||||
|
||||
return result == cudaSuccess;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void nv::cuda::exit()
|
||||
{
|
||||
#if defined HAVE_CUDA
|
||||
cudaError_t result = cudaThreadExit();
|
||||
|
||||
if (result != cudaSuccess) {
|
||||
nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(result));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@ -350,11 +351,11 @@ namespace nvtt
|
||||
|
||||
// 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, 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;
|
||||
|
||||
// Raw API.
|
||||
NVTT_API bool compress(int w, int h, int d, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||
NVTT_API bool compress(int w, int h, int d, int face, int mipmap, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||
NVTT_API int estimateSize(int w, int h, int d, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||
};
|
||||
|
||||
@ -427,8 +428,10 @@ namespace nvtt
|
||||
NVTT_API void scaleAlphaToCoverage(float coverage, float alphaRef = 0.5f);
|
||||
NVTT_API bool normalizeRange(float * rangeMin, float * rangeMax);
|
||||
NVTT_API void toRGBM(float range = 1.0f, float threshold = 0.0f);
|
||||
NVTT_API void fromRGBM(float range = 1.0f);
|
||||
NVTT_API void toYCoCg();
|
||||
NVTT_API void blockScaleCoCg(int bits = 5, float threshold = 0.0f);
|
||||
NVTT_API void fromYCoCg();
|
||||
|
||||
// Color quantization.
|
||||
NVTT_API void binarize(int channel, float threshold, bool dither);
|
||||
@ -438,10 +441,6 @@ namespace nvtt
|
||||
NVTT_API void toNormalMap(float sm, float medium, float big, float large);
|
||||
NVTT_API void normalizeNormalMap();
|
||||
|
||||
// Error compare.
|
||||
NVTT_API float rootMeanSquaredError_rgb(const TexImage & reference) const;
|
||||
NVTT_API float rootMeanSquaredError_alpha(const TexImage & reference) const;
|
||||
|
||||
// Geometric transforms.
|
||||
NVTT_API void flipVertically();
|
||||
|
||||
@ -449,6 +448,11 @@ namespace nvtt
|
||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel);
|
||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
|
||||
|
||||
// Error compare.
|
||||
friend NVTT_API float rmsError(const TexImage & reference, const TexImage & img);
|
||||
friend NVTT_API float rmsAlphaError(const TexImage & reference, const TexImage & img);
|
||||
friend NVTT_API TexImage diff(const TexImage & reference, const TexImage & img);
|
||||
|
||||
private:
|
||||
void detach();
|
||||
|
||||
|
@ -1,3 +1,26 @@
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "nvtt.h"
|
||||
#include "nvtt_wrapper.h"
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
@ -64,7 +64,7 @@ int main(int argc, char *argv[])
|
||||
image.setAlphaMode(nvtt::AlphaMode_Transparency);
|
||||
|
||||
// Output first mipmap.
|
||||
context.compress(image, compressionOptions, outputOptions);
|
||||
context.compress(image, 0, 0, compressionOptions, outputOptions);
|
||||
|
||||
float gamma = 2.2f;
|
||||
image.toLinear(gamma);
|
||||
@ -73,6 +73,7 @@ int main(int argc, char *argv[])
|
||||
float coverage = image.alphaTestCoverage(alphaRef);
|
||||
|
||||
// Build mimaps.
|
||||
int m = 1;
|
||||
while (image.buildNextMipmap(nvtt::MipmapFilter_Kaiser))
|
||||
{
|
||||
nvtt::TexImage tmpImage = image;
|
||||
@ -80,7 +81,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
tmpImage.scaleAlphaToCoverage(coverage, alphaRef);
|
||||
|
||||
context.compress(tmpImage, compressionOptions, outputOptions);
|
||||
context.compress(tmpImage, 0, m, compressionOptions, outputOptions);
|
||||
m++;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
|
||||
// Copyright (c) 2007-2009 NVIDIA Corporation -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@ -127,30 +128,39 @@ static const char * s_quake3ImageSet[] = {
|
||||
"q3-wires02.tga",
|
||||
};
|
||||
|
||||
|
||||
enum Mode {
|
||||
Mode_BC1,
|
||||
Mode_BC3_Alpha,
|
||||
Mode_BC3_YCoCg,
|
||||
Mode_BC3_RGBM,
|
||||
Mode_BC3_Normal,
|
||||
Mode_BC5_Normal,
|
||||
};
|
||||
struct ImageSet
|
||||
{
|
||||
const char * name;
|
||||
const char ** fileNames;
|
||||
int fileCount;
|
||||
nvtt::Format format;
|
||||
Mode mode;
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
|
||||
|
||||
static ImageSet s_imageSets[] = {
|
||||
{s_kodakImageSet, sizeof(s_kodakImageSet)/sizeof(s_kodakImageSet[0]), nvtt::Format_DXT1},
|
||||
{s_waterlooImageSet, sizeof(s_waterlooImageSet)/sizeof(s_waterlooImageSet[0]), nvtt::Format_DXT1},
|
||||
{s_epicImageSet, sizeof(s_epicImageSet)/sizeof(s_epicImageSet[0]), nvtt::Format_DXT1},
|
||||
{s_farbrauschImageSet, sizeof(s_farbrauschImageSet)/sizeof(s_farbrauschImageSet[0]), nvtt::Format_DXT1},
|
||||
{s_lugaruImageSet, sizeof(s_lugaruImageSet)/sizeof(s_lugaruImageSet[0]), nvtt::Format_DXT5},
|
||||
{s_quake3ImageSet, sizeof(s_quake3ImageSet)/sizeof(s_quake3ImageSet[0]), nvtt::Format_DXT5},
|
||||
{"Kodak - BC1", s_kodakImageSet, ARRAY_SIZE(s_kodakImageSet), Mode_BC1},
|
||||
{"Kodak - BC3-YCoCg", s_kodakImageSet, ARRAY_SIZE(s_kodakImageSet), Mode_BC3_YCoCg},
|
||||
{"Kodak - BC3-RGBM", s_kodakImageSet, ARRAY_SIZE(s_kodakImageSet), Mode_BC3_RGBM},
|
||||
{"Waterloo - BC1", s_waterlooImageSet, ARRAY_SIZE(s_waterlooImageSet), Mode_BC1},
|
||||
{"Waterloo - BC3-YCoCg", s_waterlooImageSet, ARRAY_SIZE(s_waterlooImageSet), Mode_BC3_YCoCg},
|
||||
{"Epic - BC1", s_epicImageSet, ARRAY_SIZE(s_epicImageSet), Mode_BC1},
|
||||
{"Epic - BC1-YCoCg", s_epicImageSet, ARRAY_SIZE(s_epicImageSet), Mode_BC3_YCoCg},
|
||||
{"Farbraush - BC1", s_farbrauschImageSet, ARRAY_SIZE(s_farbrauschImageSet), Mode_BC1},
|
||||
{"Farbraush - BC1-YCoCg", s_farbrauschImageSet, ARRAY_SIZE(s_farbrauschImageSet), Mode_BC3_YCoCg},
|
||||
{"Lugaru - BC3", s_lugaruImageSet, ARRAY_SIZE(s_lugaruImageSet), Mode_BC3_Alpha},
|
||||
{"Quake3 - BC3", s_quake3ImageSet, ARRAY_SIZE(s_quake3ImageSet), Mode_BC3_Alpha},
|
||||
};
|
||||
const int s_imageSetCount = sizeof(s_imageSets)/sizeof(s_imageSets[0]);
|
||||
|
||||
enum Decoder
|
||||
{
|
||||
Decoder_Reference,
|
||||
Decoder_NVIDIA,
|
||||
};
|
||||
|
||||
struct MyOutputHandler : public nvtt::OutputHandler
|
||||
{
|
||||
MyOutputHandler() : m_data(NULL), m_ptr(NULL) {}
|
||||
@ -176,83 +186,17 @@ struct MyOutputHandler : public nvtt::OutputHandler
|
||||
return true;
|
||||
}
|
||||
|
||||
Image * decompress(nvtt::Format format, Decoder decoder)
|
||||
nvtt::TexImage decompress(Mode mode, nvtt::Decoder decoder)
|
||||
{
|
||||
int bw = (m_width + 3) / 4;
|
||||
int bh = (m_height + 3) / 4;
|
||||
nvtt::Format format;
|
||||
if (mode == Mode_BC1) format = nvtt::Format_BC1;
|
||||
else if (mode == Mode_BC5_Normal) format = nvtt::Format_BC5;
|
||||
else format = nvtt::Format_BC3;
|
||||
|
||||
AutoPtr<Image> img( new Image() );
|
||||
img->allocate(m_width, m_height);
|
||||
nvtt::TexImage img;
|
||||
img.setImage2D(format, decoder, m_width, m_height, m_data);
|
||||
|
||||
if (format == nvtt::Format_BC1)
|
||||
{
|
||||
BlockDXT1 * block = (BlockDXT1 *)m_data;
|
||||
|
||||
for (int y = 0; y < bh; y++)
|
||||
{
|
||||
for (int x = 0; x < bw; x++)
|
||||
{
|
||||
ColorBlock colors;
|
||||
if (decoder == Decoder_Reference) {
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (decoder == Decoder_NVIDIA) {
|
||||
block->decodeBlockNV5x(&colors);
|
||||
}
|
||||
|
||||
for (int yy = 0; yy < 4; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < 4; xx++)
|
||||
{
|
||||
Color32 c = colors.color(xx, yy);
|
||||
|
||||
if (x * 4 + xx < m_width && y * 4 + yy < m_height)
|
||||
{
|
||||
img->pixel(x * 4 + xx, y * 4 + yy) = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
block++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (format == nvtt::Format_BC3)
|
||||
{
|
||||
BlockDXT5 * block = (BlockDXT5 *)m_data;
|
||||
|
||||
for (int y = 0; y < bh; y++)
|
||||
{
|
||||
for (int x = 0; x < bw; x++)
|
||||
{
|
||||
ColorBlock colors;
|
||||
if (decoder == Decoder_Reference) {
|
||||
block->decodeBlock(&colors);
|
||||
}
|
||||
else if (decoder == Decoder_NVIDIA) {
|
||||
block->decodeBlockNV5x(&colors);
|
||||
}
|
||||
|
||||
for (int yy = 0; yy < 4; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < 4; xx++)
|
||||
{
|
||||
Color32 c = colors.color(xx, yy);
|
||||
|
||||
if (x * 4 + xx < m_width && y * 4 + yy < m_height)
|
||||
{
|
||||
img->pixel(x * 4 + xx, y * 4 + yy) = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
block++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return img.release();
|
||||
return img;
|
||||
}
|
||||
|
||||
int m_size;
|
||||
@ -263,36 +207,6 @@ struct MyOutputHandler : public nvtt::OutputHandler
|
||||
};
|
||||
|
||||
|
||||
float rmsError(const Image * a, const Image * b)
|
||||
{
|
||||
nvCheck(a != NULL);
|
||||
nvCheck(b != NULL);
|
||||
nvCheck(a->width() == b->width());
|
||||
nvCheck(a->height() == b->height());
|
||||
|
||||
double mse = 0;
|
||||
|
||||
const uint count = a->width() * a->height();
|
||||
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
Color32 c0 = a->pixel(i);
|
||||
Color32 c1 = b->pixel(i);
|
||||
|
||||
int r = c0.r - c1.r;
|
||||
int g = c0.g - c1.g;
|
||||
int b = c0.b - c1.b;
|
||||
int a = c0.a - c1.a;
|
||||
|
||||
mse += double(r * r * c0.a) / 255;
|
||||
mse += double(g * g * c0.a) / 255;
|
||||
mse += double(b * b * c0.a) / 255;
|
||||
}
|
||||
|
||||
return float(sqrt(mse / count));
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MyAssertHandler assertHandler;
|
||||
@ -305,11 +219,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
printf("NVIDIA Texture Tools %u.%u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor, rev);
|
||||
|
||||
int set = 0;
|
||||
int setIndex = 0;
|
||||
bool fast = false;
|
||||
bool nocuda = false;
|
||||
bool showHelp = false;
|
||||
Decoder decoder = Decoder_Reference;
|
||||
nvtt::Decoder decoder = nvtt::Decoder_Reference;
|
||||
const char * basePath = "";
|
||||
const char * outPath = "output";
|
||||
const char * regressPath = NULL;
|
||||
@ -320,14 +234,14 @@ int main(int argc, char *argv[])
|
||||
if (strcmp("-set", argv[i]) == 0)
|
||||
{
|
||||
if (i+1 < argc && argv[i+1][0] != '-') {
|
||||
set = atoi(argv[i+1]);
|
||||
setIndex = atoi(argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if (strcmp("-dec", argv[i]) == 0)
|
||||
{
|
||||
if (i+1 < argc && argv[i+1][0] != '-') {
|
||||
decoder = (Decoder)atoi(argv[i+1]);
|
||||
decoder = (nvtt::Decoder)atoi(argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -394,10 +308,6 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
nvtt::InputOptions inputOptions;
|
||||
inputOptions.setMipmapGeneration(false);
|
||||
inputOptions.setAlphaMode(nvtt::AlphaMode_Transparency);
|
||||
|
||||
nvtt::CompressionOptions compressionOptions;
|
||||
compressionOptions.setFormat(nvtt::Format_BC1);
|
||||
if (fast)
|
||||
@ -413,7 +323,22 @@ int main(int argc, char *argv[])
|
||||
//compressionOptions.setExternalCompressor("d3dx");
|
||||
//compressionOptions.setExternalCompressor("stb");
|
||||
|
||||
compressionOptions.setFormat(s_imageSets[set].format);
|
||||
|
||||
const ImageSet & set = s_imageSets[setIndex];
|
||||
|
||||
if (set.mode == Mode_BC1) {
|
||||
compressionOptions.setFormat(nvtt::Format_BC1);
|
||||
}
|
||||
else if (set.mode == Mode_BC3_Alpha || set.mode == Mode_BC3_YCoCg || set.mode == Mode_BC3_RGBM) {
|
||||
compressionOptions.setFormat(nvtt::Format_BC3);
|
||||
}
|
||||
else if (set.mode == Mode_BC3_Normal) {
|
||||
compressionOptions.setFormat(nvtt::Format_BC3n);
|
||||
}
|
||||
else if (set.mode == Mode_BC5_Normal) {
|
||||
compressionOptions.setFormat(nvtt::Format_BC5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nvtt::OutputOptions outputOptions;
|
||||
@ -429,7 +354,7 @@ int main(int argc, char *argv[])
|
||||
FileSystem::createDirectory(outPath);
|
||||
|
||||
Path csvFileName;
|
||||
csvFileName.format("%s/result-%d.csv", outPath, set);
|
||||
csvFileName.format("%s/result-%d.csv", outPath, setIndex);
|
||||
StdOutputStream csvStream(csvFileName.str());
|
||||
TextWriter csvWriter(&csvStream);
|
||||
|
||||
@ -438,46 +363,85 @@ int main(int argc, char *argv[])
|
||||
int failedTests = 0;
|
||||
float totalDiff = 0;
|
||||
|
||||
const char ** fileNames = s_imageSets[set].fileNames;
|
||||
int fileCount = s_imageSets[set].fileCount;
|
||||
const char ** fileNames = set.fileNames;
|
||||
int fileCount = set.fileCount;
|
||||
|
||||
Timer timer;
|
||||
|
||||
nvtt::TexImage img;
|
||||
if (set.mode == Mode_BC3_Alpha) {
|
||||
img.setAlphaMode(nvtt::AlphaMode_Transparency);
|
||||
}
|
||||
if (set.mode == Mode_BC3_Normal || set.mode == Mode_BC5_Normal) {
|
||||
img.setNormalMap(true);
|
||||
}
|
||||
|
||||
printf("Processing Set: %s\n", set.name);
|
||||
|
||||
for (int i = 0; i < fileCount; i++)
|
||||
{
|
||||
AutoPtr<Image> img( new Image() );
|
||||
|
||||
if (!img->load(fileNames[i]))
|
||||
if (!img.load(fileNames[i]))
|
||||
{
|
||||
printf("Input image '%s' not found.\n", fileNames[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
inputOptions.setTextureLayout(nvtt::TextureType_2D, img->width(), img->height());
|
||||
inputOptions.setMipmapData(img->pixels(), img->width(), img->height());
|
||||
if (img.isNormalMap()) {
|
||||
img.normalizeNormalMap();
|
||||
}
|
||||
|
||||
if (set.mode == Mode_BC3_YCoCg) {
|
||||
img.toYCoCg();
|
||||
img.blockScaleCoCg();
|
||||
img.scaleBias(0, 0.5, 0.5);
|
||||
img.scaleBias(1, 0.5, 0.5);
|
||||
}
|
||||
else if (set.mode == Mode_BC3_RGBM) {
|
||||
img.toRGBM();
|
||||
}
|
||||
|
||||
printf("Compressing: \t'%s'\n", fileNames[i]);
|
||||
|
||||
timer.start();
|
||||
|
||||
context.process(inputOptions, compressionOptions, outputOptions);
|
||||
context.compress(img, 0, 0, compressionOptions, outputOptions);
|
||||
|
||||
timer.stop();
|
||||
printf(" Time: \t%.3f sec\n", timer.elapsed());
|
||||
totalTime += timer.elapsed();
|
||||
|
||||
AutoPtr<Image> img_out( outputHandler.decompress(s_imageSets[set].format, decoder) );
|
||||
nvtt::TexImage img_out = outputHandler.decompress(set.mode, decoder);
|
||||
if (set.mode == Mode_BC3_Alpha) {
|
||||
img_out.setAlphaMode(nvtt::AlphaMode_Transparency);
|
||||
}
|
||||
if (set.mode == Mode_BC3_Normal || set.mode == Mode_BC5_Normal) {
|
||||
img_out.setNormalMap(true);
|
||||
}
|
||||
|
||||
if (set.mode == Mode_BC3_YCoCg) {
|
||||
img_out.scaleBias(0, 1.0, -0.5);
|
||||
img_out.scaleBias(1, 1.0, -0.5);
|
||||
img_out.fromYCoCg();
|
||||
|
||||
img.scaleBias(0, 1.0, -0.5);
|
||||
img.scaleBias(1, 1.0, -0.5);
|
||||
img.fromYCoCg();
|
||||
}
|
||||
else if (set.mode == Mode_BC3_RGBM) {
|
||||
img_out.fromRGBM();
|
||||
img.fromRGBM();
|
||||
}
|
||||
|
||||
Path outputFileName;
|
||||
outputFileName.format("%s/%s", outPath, fileNames[i]);
|
||||
outputFileName.stripExtension();
|
||||
outputFileName.append(".png");
|
||||
if (!ImageIO::save(outputFileName.str(), img_out.ptr()))
|
||||
if (!img_out.save(outputFileName.str()))
|
||||
{
|
||||
printf("Error saving file '%s'.\n", outputFileName.str());
|
||||
}
|
||||
|
||||
float rmse = rmsError(img.ptr(), img_out.ptr());
|
||||
float rmse = nvtt::rmsError(img, img_out);
|
||||
totalRMSE += rmse;
|
||||
|
||||
printf(" RMSE: \t%.4f\n", rmse);
|
||||
@ -492,14 +456,14 @@ int main(int argc, char *argv[])
|
||||
regressFileName.stripExtension();
|
||||
regressFileName.append(".png");
|
||||
|
||||
AutoPtr<Image> img_reg( new Image() );
|
||||
if (!img_reg->load(regressFileName.str()))
|
||||
nvtt::TexImage img_reg;
|
||||
if (!img_reg.load(regressFileName.str()))
|
||||
{
|
||||
printf("Regression image '%s' not found.\n", regressFileName.str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
float rmse_reg = rmsError(img.ptr(), img_reg.ptr());
|
||||
float rmse_reg = rmsError(img, img_reg);
|
||||
|
||||
float diff = rmse_reg - rmse;
|
||||
totalDiff += diff;
|
||||
|
Loading…
Reference in New Issue
Block a user