Merge changes from the witness.

pull/216/head
castano 13 years ago
parent 94401919b8
commit 2ec37026be

@ -453,7 +453,7 @@ namespace
{
MSG msg;
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
if( msg.message == WM_QUIT ) break;
//if( msg.message == WM_QUIT ) break;
TranslateMessage( &msg );
DispatchMessage( &msg );
}
@ -467,12 +467,11 @@ namespace
StringBuilder error_string;
if( func != NULL ) {
error_string.format( "*** Assertion failed: %s\n On file: %s\n On function: %s\n On line: %d\n ", exp, file, func, line );
nvDebug( error_string.str() );
}
else {
error_string.format( "*** Assertion failed: %s\n On file: %s\n On line: %d\n ", exp, file, line );
nvDebug( error_string.str() );
}
nvDebug( error_string.str() );
if (debug::isDebuggerPresent()) {
return NV_ABORT_DEBUG;

@ -70,15 +70,11 @@ namespace nv
b = temp;
}
/// Return the maximum of the two arguments.
/// Return the maximum of the two arguments. For floating point values, it returns the second value if the first is NaN.
template <typename T>
inline const T & max(const T & a, const T & b)
{
//return std::max(a, b);
if( a < b ) {
return b;
}
return a;
return (b < a) ? a : b;
}
/// Return the maximum of the three arguments.
@ -92,11 +88,7 @@ namespace nv
template <typename T>
inline const T & min(const T & a, const T & b)
{
//return std::min(a, b);
if( b < a ) {
return b;
}
return a;
return (a < b) ? a : b;
}
/// Return the maximum of the three arguments.

File diff suppressed because it is too large Load Diff

@ -1,228 +1,228 @@
// 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.
#pragma once
#ifndef NV_IMAGE_BLOCKDXT_H
#define NV_IMAGE_BLOCKDXT_H
#include "nvimage.h"
#include "nvmath/Color.h"
namespace nv
{
struct ColorBlock;
class Stream;
/// DXT1 block.
struct BlockDXT1
{
Color16 col0;
Color16 col1;
union {
uint8 row[4];
uint indices;
};
bool isFourColorMode() const;
uint evaluatePalette(Color32 color_array[4], bool d3d9) const;
uint evaluatePaletteNV5x(Color32 color_array[4]) const;
void evaluatePalette3(Color32 color_array[4], bool d3d9) const;
void evaluatePalette4(Color32 color_array[4], bool d3d9) const;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const;
void setIndices(int * idx);
void flip4();
void flip2();
};
/// Return true if the block uses four color mode, false otherwise.
inline bool BlockDXT1::isFourColorMode() const
{
return col0.u > col1.u;
}
/// DXT3 alpha block with explicit alpha.
struct AlphaBlockDXT3
{
union {
struct {
uint alpha0 : 4;
uint alpha1 : 4;
uint alpha2 : 4;
uint alpha3 : 4;
uint alpha4 : 4;
uint alpha5 : 4;
uint alpha6 : 4;
uint alpha7 : 4;
uint alpha8 : 4;
uint alpha9 : 4;
uint alphaA : 4;
uint alphaB : 4;
uint alphaC : 4;
uint alphaD : 4;
uint alphaE : 4;
uint alphaF : 4;
};
uint16 row[4];
};
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4();
void flip2();
};
/// DXT3 block.
struct BlockDXT3
{
AlphaBlockDXT3 alpha;
BlockDXT1 color;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const;
void flip4();
void flip2();
};
/// DXT5 alpha block.
struct AlphaBlockDXT5
{
union {
struct {
uint64 alpha0 : 8; // 8
uint64 alpha1 : 8; // 16
uint64 bits0 : 3; // 3 - 19
uint64 bits1 : 3; // 6 - 22
uint64 bits2 : 3; // 9 - 25
uint64 bits3 : 3; // 12 - 28
uint64 bits4 : 3; // 15 - 31
uint64 bits5 : 3; // 18 - 34
uint64 bits6 : 3; // 21 - 37
uint64 bits7 : 3; // 24 - 40
uint64 bits8 : 3; // 27 - 43
uint64 bits9 : 3; // 30 - 46
uint64 bitsA : 3; // 33 - 49
uint64 bitsB : 3; // 36 - 52
uint64 bitsC : 3; // 39 - 55
uint64 bitsD : 3; // 42 - 58
uint64 bitsE : 3; // 45 - 61
uint64 bitsF : 3; // 48 - 64
};
uint64 u;
};
void evaluatePalette(uint8 alpha[8], bool d3d9) const;
void evaluatePalette8(uint8 alpha[8], bool d3d9) const;
void evaluatePalette6(uint8 alpha[8], bool d3d9) const;
void indices(uint8 index_array[16]) const;
uint index(uint index) const;
void setIndex(uint index, uint value);
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4();
void flip2();
};
/// DXT5 block.
struct BlockDXT5
{
AlphaBlockDXT5 alpha;
BlockDXT1 color;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const;
void flip4();
void flip2();
};
/// ATI1 block.
struct BlockATI1
{
AlphaBlockDXT5 alpha;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4();
void flip2();
};
/// ATI2 block.
struct BlockATI2
{
AlphaBlockDXT5 x;
AlphaBlockDXT5 y;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4();
void flip2();
};
/// CTX1 block.
struct BlockCTX1
{
uint8 col0[2];
uint8 col1[2];
union {
uint8 row[4];
uint indices;
};
void evaluatePalette(Color32 color_array[4]) const;
void setIndices(int * idx);
void decodeBlock(ColorBlock * block) const;
void flip4();
void flip2();
};
// Serialization functions.
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT1 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT3 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT3 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT5 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT5 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI1 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI2 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockCTX1 & block);
} // nv namespace
#endif // NV_IMAGE_BLOCKDXT_H
// 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.
#pragma once
#ifndef NV_IMAGE_BLOCKDXT_H
#define NV_IMAGE_BLOCKDXT_H
#include "nvimage.h"
#include "nvmath/Color.h"
namespace nv
{
struct ColorBlock;
class Stream;
/// DXT1 block.
struct BlockDXT1
{
Color16 col0;
Color16 col1;
union {
uint8 row[4];
uint indices;
};
bool isFourColorMode() const;
uint evaluatePalette(Color32 color_array[4], bool d3d9) const;
uint evaluatePaletteNV5x(Color32 color_array[4]) const;
void evaluatePalette3(Color32 color_array[4], bool d3d9) const;
void evaluatePalette4(Color32 color_array[4], bool d3d9) const;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const;
void setIndices(int * idx);
void flip4();
void flip2();
};
/// Return true if the block uses four color mode, false otherwise.
inline bool BlockDXT1::isFourColorMode() const
{
return col0.u > col1.u;
}
/// DXT3 alpha block with explicit alpha.
struct AlphaBlockDXT3
{
union {
struct {
uint alpha0 : 4;
uint alpha1 : 4;
uint alpha2 : 4;
uint alpha3 : 4;
uint alpha4 : 4;
uint alpha5 : 4;
uint alpha6 : 4;
uint alpha7 : 4;
uint alpha8 : 4;
uint alpha9 : 4;
uint alphaA : 4;
uint alphaB : 4;
uint alphaC : 4;
uint alphaD : 4;
uint alphaE : 4;
uint alphaF : 4;
};
uint16 row[4];
};
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4();
void flip2();
};
/// DXT3 block.
struct BlockDXT3
{
AlphaBlockDXT3 alpha;
BlockDXT1 color;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const;
void flip4();
void flip2();
};
/// DXT5 alpha block.
struct AlphaBlockDXT5
{
union {
struct {
uint64 alpha0 : 8; // 8
uint64 alpha1 : 8; // 16
uint64 bits0 : 3; // 3 - 19
uint64 bits1 : 3; // 6 - 22
uint64 bits2 : 3; // 9 - 25
uint64 bits3 : 3; // 12 - 28
uint64 bits4 : 3; // 15 - 31
uint64 bits5 : 3; // 18 - 34
uint64 bits6 : 3; // 21 - 37
uint64 bits7 : 3; // 24 - 40
uint64 bits8 : 3; // 27 - 43
uint64 bits9 : 3; // 30 - 46
uint64 bitsA : 3; // 33 - 49
uint64 bitsB : 3; // 36 - 52
uint64 bitsC : 3; // 39 - 55
uint64 bitsD : 3; // 42 - 58
uint64 bitsE : 3; // 45 - 61
uint64 bitsF : 3; // 48 - 64
};
uint64 u;
};
void evaluatePalette(uint8 alpha[8], bool d3d9) const;
void evaluatePalette8(uint8 alpha[8], bool d3d9) const;
void evaluatePalette6(uint8 alpha[8], bool d3d9) const;
void indices(uint8 index_array[16]) const;
uint index(uint index) const;
void setIndex(uint index, uint value);
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4();
void flip2();
};
/// DXT5 block.
struct BlockDXT5
{
AlphaBlockDXT5 alpha;
BlockDXT1 color;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const;
void flip4();
void flip2();
};
/// ATI1 block.
struct BlockATI1
{
AlphaBlockDXT5 alpha;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4();
void flip2();
};
/// ATI2 block.
struct BlockATI2
{
AlphaBlockDXT5 x;
AlphaBlockDXT5 y;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4();
void flip2();
};
/// CTX1 block.
struct BlockCTX1
{
uint8 col0[2];
uint8 col1[2];
union {
uint8 row[4];
uint indices;
};
void evaluatePalette(Color32 color_array[4]) const;
void setIndices(int * idx);
void decodeBlock(ColorBlock * block) const;
void flip4();
void flip2();
};
// Serialization functions.
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT1 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT3 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT3 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT5 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT5 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI1 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI2 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockCTX1 & block);
} // nv namespace
#endif // NV_IMAGE_BLOCKDXT_H

File diff suppressed because it is too large Load Diff

@ -1,117 +1,117 @@
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_COLORBLOCK_H
#define NV_IMAGE_COLORBLOCK_H
#include "nvmath/Color.h"
#include "nvmath/Vector.h"
namespace nv
{
class Image;
class FloatImage;
/// Uncompressed 4x4 color block.
struct ColorBlock
{
ColorBlock();
ColorBlock(const uint * linearImage);
ColorBlock(const ColorBlock & block);
ColorBlock(const Image * img, uint x, uint y);
void init(const Image * img, uint x, uint y);
void init(uint w, uint h, const uint * data, uint x, uint y);
void init(uint w, uint h, const float * data, uint x, uint y);
void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
bool hasAlpha() const;
// Accessors
const Color32 * colors() const;
Color32 color(uint i) const;
Color32 & color(uint i);
Color32 color(uint x, uint y) const;
Color32 & color(uint x, uint y);
private:
Color32 m_color[4*4];
};
/// Get pointer to block colors.
inline const Color32 * ColorBlock::colors() const
{
return m_color;
}
/// Get block color.
inline Color32 ColorBlock::color(uint i) const
{
nvDebugCheck(i < 16);
return m_color[i];
}
/// Get block color.
inline Color32 & ColorBlock::color(uint i)
{
nvDebugCheck(i < 16);
return m_color[i];
}
/// Get block color.
inline Color32 ColorBlock::color(uint x, uint y) const
{
nvDebugCheck(x < 4 && y < 4);
return m_color[y * 4 + x];
}
/// Get block color.
inline Color32 & ColorBlock::color(uint x, uint y)
{
nvDebugCheck(x < 4 && y < 4);
return m_color[y * 4 + x];
}
struct ColorSet
{
void setColors(const float * data, uint img_w, uint img_h, uint img_x, uint img_y);
void setAlphaWeights();
void setUniformWeights();
void createMinimalSet(bool ignoreTransparent);
void wrapIndices();
void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
bool isSingleColor(bool ignoreAlpha) const;
bool hasAlpha() const;
// These methods require indices to be set:
Vector4 color(uint x, uint y) const { nvDebugCheck(x < w && y < h); return colors[remap[y * 4 + x]]; }
Vector4 & color(uint x, uint y) { nvDebugCheck(x < w && y < h); return colors[remap[y * 4 + x]]; }
Vector4 color(uint i) const { nvDebugCheck(i < 16); return colors[remap[i]]; }
Vector4 & color(uint i) { nvDebugCheck(i < 16); return colors[remap[i]]; }
uint count;
uint w, h;
Vector4 colors[16];
float weights[16];
int remap[16];
};
} // nv namespace
#endif // NV_IMAGE_COLORBLOCK_H
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_COLORBLOCK_H
#define NV_IMAGE_COLORBLOCK_H
#include "nvmath/Color.h"
#include "nvmath/Vector.h"
namespace nv
{
class Image;
class FloatImage;
/// Uncompressed 4x4 color block.
struct ColorBlock
{
ColorBlock();
ColorBlock(const uint * linearImage);
ColorBlock(const ColorBlock & block);
ColorBlock(const Image * img, uint x, uint y);
void init(const Image * img, uint x, uint y);
void init(uint w, uint h, const uint * data, uint x, uint y);
void init(uint w, uint h, const float * data, uint x, uint y);
void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
bool hasAlpha() const;
// Accessors
const Color32 * colors() const;
Color32 color(uint i) const;
Color32 & color(uint i);
Color32 color(uint x, uint y) const;
Color32 & color(uint x, uint y);
private:
Color32 m_color[4*4];
};
/// Get pointer to block colors.
inline const Color32 * ColorBlock::colors() const
{
return m_color;
}
/// Get block color.
inline Color32 ColorBlock::color(uint i) const
{
nvDebugCheck(i < 16);
return m_color[i];
}
/// Get block color.
inline Color32 & ColorBlock::color(uint i)
{
nvDebugCheck(i < 16);
return m_color[i];
}
/// Get block color.
inline Color32 ColorBlock::color(uint x, uint y) const
{
nvDebugCheck(x < 4 && y < 4);
return m_color[y * 4 + x];
}
/// Get block color.
inline Color32 & ColorBlock::color(uint x, uint y)
{
nvDebugCheck(x < 4 && y < 4);
return m_color[y * 4 + x];
}
struct ColorSet
{
void setColors(const float * data, uint img_w, uint img_h, uint img_x, uint img_y);
void setAlphaWeights();
void setUniformWeights();
void createMinimalSet(bool ignoreTransparent);
void wrapIndices();
void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
bool isSingleColor(bool ignoreAlpha) const;
bool hasAlpha() const;
// These methods require indices to be set:
Vector4 color(uint x, uint y) const { nvDebugCheck(x < w && y < h); return colors[remap[y * 4 + x]]; }
Vector4 & color(uint x, uint y) { nvDebugCheck(x < w && y < h); return colors[remap[y * 4 + x]]; }
Vector4 color(uint i) const { nvDebugCheck(i < 16); return colors[remap[i]]; }
Vector4 & color(uint i) { nvDebugCheck(i < 16); return colors[remap[i]]; }
uint count;
uint w, h;
Vector4 colors[16];
float weights[16];
int remap[16];
};
} // nv namespace
#endif // NV_IMAGE_COLORBLOCK_H

@ -1,10 +1,10 @@
// This code is in the public domain -- jim@tilander.org
#include <nvcore/nvcore.h>
#include <nvmath/Color.h>
#include <nvimage/Image.h>
#include <nvmath/Color.h>
#include <nvimage/Image.h>
#include "ColorSpace.h"
namespace nv
@ -67,4 +67,4 @@ namespace nv
}
}
}
}
}

File diff suppressed because it is too large Load Diff

@ -1,406 +1,406 @@
// 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.
#pragma once
#ifndef NV_IMAGE_DIRECTDRAWSURFACE_H
#define NV_IMAGE_DIRECTDRAWSURFACE_H
#include "nvimage.h"
#if !defined(MAKEFOURCC)
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
(uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
(uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
#endif
namespace nv
{
class Image;
class Stream;
struct ColorBlock;
extern const uint FOURCC_NVTT;
extern const uint FOURCC_DDS;
extern const uint FOURCC_DXT1;
extern const uint FOURCC_DXT2;
extern const uint FOURCC_DXT3;
extern const uint FOURCC_DXT4;
extern const uint FOURCC_DXT5;
extern const uint FOURCC_RXGB;
extern const uint FOURCC_ATI1;
extern const uint FOURCC_ATI2;
enum DDPF
{
DDPF_ALPHAPIXELS = 0x00000001U,
DDPF_ALPHA = 0x00000002U,
DDPF_FOURCC = 0x00000004U,
DDPF_RGB = 0x00000040U,
DDPF_PALETTEINDEXED1 = 0x00000800U,
DDPF_PALETTEINDEXED2 = 0x00001000U,
DDPF_PALETTEINDEXED4 = 0x00000008U,
DDPF_PALETTEINDEXED8 = 0x00000020U,
DDPF_LUMINANCE = 0x00020000U,
DDPF_ALPHAPREMULT = 0x00008000U,
// Custom NVTT flags.
DDPF_NORMAL = 0x80000000U,
DDPF_SRGB = 0x40000000U,
};
enum D3DFORMAT
{
// 32 bit RGB formats.
D3DFMT_R8G8B8 = 20,
D3DFMT_A8R8G8B8 = 21,
D3DFMT_X8R8G8B8 = 22,
D3DFMT_R5G6B5 = 23,
D3DFMT_X1R5G5B5 = 24,
D3DFMT_A1R5G5B5 = 25,
D3DFMT_A4R4G4B4 = 26,
D3DFMT_R3G3B2 = 27,
D3DFMT_A8 = 28,
D3DFMT_A8R3G3B2 = 29,
D3DFMT_X4R4G4B4 = 30,
D3DFMT_A2B10G10R10 = 31,
D3DFMT_A8B8G8R8 = 32,
D3DFMT_X8B8G8R8 = 33,
D3DFMT_G16R16 = 34,
D3DFMT_A2R10G10B10 = 35,
D3DFMT_A16B16G16R16 = 36,
// Palette formats.
D3DFMT_A8P8 = 40,
D3DFMT_P8 = 41,
// Luminance formats.
D3DFMT_L8 = 50,
D3DFMT_A8L8 = 51,
D3DFMT_A4L4 = 52,
D3DFMT_L16 = 81,
// Floating point formats
D3DFMT_R16F = 111,
D3DFMT_G16R16F = 112,
D3DFMT_A16B16G16R16F = 113,
D3DFMT_R32F = 114,
D3DFMT_G32R32F = 115,
D3DFMT_A32B32G32R32F = 116,
};
// D3D1x resource dimensions.
enum D3D10_RESOURCE_DIMENSION
{
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
};
// DXGI formats.
enum DXGI_FORMAT
{
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
};
extern uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
struct NVIMAGE_CLASS DDSPixelFormat
{
uint size;
uint flags;
uint fourcc;
uint bitcount;
uint rmask;
uint gmask;
uint bmask;
uint amask;
};
struct NVIMAGE_CLASS DDSCaps
{
uint caps1;
uint caps2;
uint caps3;
uint caps4;
};
/// DDS file header for DX10.
struct NVIMAGE_CLASS DDSHeader10
{
uint dxgiFormat;
uint resourceDimension;
uint miscFlag;
uint arraySize;
uint reserved;
};
/// DDS file header.
struct NVIMAGE_CLASS DDSHeader
{
uint fourcc;
uint size;
uint flags;
uint height;
uint width;
uint pitch;
uint depth;
uint mipmapcount;
uint reserved[11];
DDSPixelFormat pf;
DDSCaps caps;
uint notused;
DDSHeader10 header10;
// Helper methods.
DDSHeader();
void setWidth(uint w);
void setHeight(uint h);
void setDepth(uint d);
void setMipmapCount(uint count);
void setTexture2D();
void setTexture3D();
void setTextureCube();
void setLinearSize(uint size);
void setPitch(uint pitch);
void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
void setFormatCode(uint code);
void setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
void setDX10Format(uint format);
void setNormalFlag(bool b);
void setSrgbFlag(bool b);
void setHasAlphaFlag(bool b);
void setUserVersion(int version);
void swapBytes();
bool hasDX10Header() const;
uint signature() const;
uint toolVersion() const;
uint userVersion() const;
bool isNormalMap() const;
bool isSrgb() const;
bool hasAlpha() const;
uint d3d9Format() const;
uint pixelSize() const; // In bits!
uint blockSize() const; // In bytes!
bool isBlockFormat() const;
};
NVIMAGE_API Stream & operator<< (Stream & s, DDSHeader & header);
/// DirectDraw Surface. (DDS)
class NVIMAGE_CLASS DirectDrawSurface
{
public:
DirectDrawSurface();
DirectDrawSurface(const char * file);
DirectDrawSurface(Stream * stream);
~DirectDrawSurface();
bool load(const char * filename);
bool load(Stream * stream);
bool isValid() const;
bool isSupported() const;
bool hasAlpha() const;
uint mipmapCount() const;
uint width() const;
uint height() const;
uint depth() const;
bool isTexture1D() const;
bool isTexture2D() const;
bool isTexture3D() const;
bool isTextureCube() const;
void setNormalFlag(bool b);
void setHasAlphaFlag(bool b);
void setUserVersion(int version);
void mipmap(Image * img, uint f, uint m);
uint surfaceWidth(uint mipmap) const;
uint surfaceHeight(uint mipmap) const;
uint surfaceDepth(uint mipmap) const;
uint surfaceSize(uint mipmap) const;
bool readSurface(uint face, uint mipmap, void * data, uint size);
void printInfo() const;
// Only initialized after loading.
DDSHeader header;
private:
uint faceSize() const;
uint offset(uint face, uint mipmap);
void readLinearImage(Image * img);
void readBlockImage(Image * img);
void readBlock(ColorBlock * rgba);
private:
Stream * stream;
};
} // nv namespace
#endif // NV_IMAGE_DIRECTDRAWSURFACE_H
// 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.
#pragma once
#ifndef NV_IMAGE_DIRECTDRAWSURFACE_H
#define NV_IMAGE_DIRECTDRAWSURFACE_H
#include "nvimage.h"
#if !defined(MAKEFOURCC)
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
(uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
(uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
#endif
namespace nv
{
class Image;
class Stream;
struct ColorBlock;
extern const uint FOURCC_NVTT;
extern const uint FOURCC_DDS;
extern const uint FOURCC_DXT1;
extern const uint FOURCC_DXT2;
extern const uint FOURCC_DXT3;
extern const uint FOURCC_DXT4;
extern const uint FOURCC_DXT5;
extern const uint FOURCC_RXGB;
extern const uint FOURCC_ATI1;
extern const uint FOURCC_ATI2;
enum DDPF
{
DDPF_ALPHAPIXELS = 0x00000001U,
DDPF_ALPHA = 0x00000002U,
DDPF_FOURCC = 0x00000004U,
DDPF_RGB = 0x00000040U,
DDPF_PALETTEINDEXED1 = 0x00000800U,
DDPF_PALETTEINDEXED2 = 0x00001000U,
DDPF_PALETTEINDEXED4 = 0x00000008U,
DDPF_PALETTEINDEXED8 = 0x00000020U,
DDPF_LUMINANCE = 0x00020000U,
DDPF_ALPHAPREMULT = 0x00008000U,
// Custom NVTT flags.
DDPF_NORMAL = 0x80000000U,
DDPF_SRGB = 0x40000000U,
};
enum D3DFORMAT
{
// 32 bit RGB formats.
D3DFMT_R8G8B8 = 20,
D3DFMT_A8R8G8B8 = 21,
D3DFMT_X8R8G8B8 = 22,
D3DFMT_R5G6B5 = 23,
D3DFMT_X1R5G5B5 = 24,
D3DFMT_A1R5G5B5 = 25,
D3DFMT_A4R4G4B4 = 26,
D3DFMT_R3G3B2 = 27,
D3DFMT_A8 = 28,
D3DFMT_A8R3G3B2 = 29,
D3DFMT_X4R4G4B4 = 30,
D3DFMT_A2B10G10R10 = 31,
D3DFMT_A8B8G8R8 = 32,
D3DFMT_X8B8G8R8 = 33,
D3DFMT_G16R16 = 34,
D3DFMT_A2R10G10B10 = 35,
D3DFMT_A16B16G16R16 = 36,
// Palette formats.
D3DFMT_A8P8 = 40,
D3DFMT_P8 = 41,
// Luminance formats.
D3DFMT_L8 = 50,
D3DFMT_A8L8 = 51,
D3DFMT_A4L4 = 52,
D3DFMT_L16 = 81,
// Floating point formats
D3DFMT_R16F = 111,
D3DFMT_G16R16F = 112,
D3DFMT_A16B16G16R16F = 113,
D3DFMT_R32F = 114,
D3DFMT_G32R32F = 115,
D3DFMT_A32B32G32R32F = 116,
};
// D3D1x resource dimensions.
enum D3D10_RESOURCE_DIMENSION
{
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
};
// DXGI formats.
enum DXGI_FORMAT
{
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
};
extern uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
struct NVIMAGE_CLASS DDSPixelFormat
{
uint size;
uint flags;
uint fourcc;
uint bitcount;
uint rmask;
uint gmask;
uint bmask;
uint amask;
};
struct NVIMAGE_CLASS DDSCaps
{
uint caps1;
uint caps2;
uint caps3;
uint caps4;
};
/// DDS file header for DX10.
struct NVIMAGE_CLASS DDSHeader10
{
uint dxgiFormat;
uint resourceDimension;
uint miscFlag;
uint arraySize;
uint reserved;
};
/// DDS file header.
struct NVIMAGE_CLASS DDSHeader
{
uint fourcc;
uint size;
uint flags;
uint height;
uint width;
uint pitch;
uint depth;
uint mipmapcount;
uint reserved[11];
DDSPixelFormat pf;
DDSCaps caps;
uint notused;
DDSHeader10 header10;
// Helper methods.
DDSHeader();
void setWidth(uint w);
void setHeight(uint h);
void setDepth(uint d);
void setMipmapCount(uint count);
void setTexture2D();
void setTexture3D();
void setTextureCube();
void setLinearSize(uint size);
void setPitch(uint pitch);
void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
void setFormatCode(uint code);
void setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
void setDX10Format(uint format);
void setNormalFlag(bool b);
void setSrgbFlag(bool b);
void setHasAlphaFlag(bool b);
void setUserVersion(int version);
void swapBytes();
bool hasDX10Header() const;
uint signature() const;
uint toolVersion() const;
uint userVersion() const;
bool isNormalMap() const;
bool isSrgb() const;
bool hasAlpha() const;
uint d3d9Format() const;
uint pixelSize() const; // In bits!
uint blockSize() const; // In bytes!
bool isBlockFormat() const;
};
NVIMAGE_API Stream & operator<< (Stream & s, DDSHeader & header);
/// DirectDraw Surface. (DDS)
class NVIMAGE_CLASS DirectDrawSurface
{
public:
DirectDrawSurface();
DirectDrawSurface(const char * file);
DirectDrawSurface(Stream * stream);
~DirectDrawSurface();
bool load(const char * filename);
bool load(Stream * stream);
bool isValid() const;
bool isSupported() const;
bool hasAlpha() const;
uint mipmapCount() const;
uint width() const;
uint height() const;
uint depth() const;
bool isTexture1D() const;
bool isTexture2D() const;
bool isTexture3D() const;
bool isTextureCube() const;
void setNormalFlag(bool b);
void setHasAlphaFlag(bool b);
void setUserVersion(int version);
void mipmap(Image * img, uint f, uint m);
uint surfaceWidth(uint mipmap) const;
uint surfaceHeight(uint mipmap) const;
uint surfaceDepth(uint mipmap) const;
uint surfaceSize(uint mipmap) const;
bool readSurface(uint face, uint mipmap, void * data, uint size);
void printInfo() const;
// Only initialized after loading.
DDSHeader header;
private:
uint faceSize() const;
uint offset(uint face, uint mipmap);
void readLinearImage(Image * img);
void readBlockImage(Image * img);
void readBlock(ColorBlock * rgba);
private:
Stream * stream;
};
} // nv namespace
#endif // NV_IMAGE_DIRECTDRAWSURFACE_H

File diff suppressed because it is too large Load Diff

@ -1,234 +1,234 @@
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_FILTER_H
#define NV_IMAGE_FILTER_H
#include "nvimage.h"
#include "nvcore/Debug.h"
namespace nv
{
class Vector4;
/// Base filter class.
class NVIMAGE_CLASS Filter
{
public:
Filter(float width);
virtual ~Filter();
float width() const { return m_width; }
float sampleDelta(float x, float scale) const;
float sampleBox(float x, float scale, int samples) const;
float sampleTriangle(float x, float scale, int samples) const;
virtual float evaluate(float x) const = 0;
protected:
const float m_width;
};
// Box filter.
class NVIMAGE_CLASS BoxFilter : public Filter
{
public:
BoxFilter();
BoxFilter(float width);
virtual float evaluate(float x) const;
};
// Triangle (bilinear/tent) filter.
class NVIMAGE_CLASS TriangleFilter : public Filter
{
public:
TriangleFilter();
TriangleFilter(float width);
virtual float evaluate(float x) const;
};
// Quadratic (bell) filter.
class NVIMAGE_CLASS QuadraticFilter : public Filter
{
public:
QuadraticFilter();
virtual float evaluate(float x) const;
};
// Cubic filter from Thatcher Ulrich.
class NVIMAGE_CLASS CubicFilter : public Filter
{
public:
CubicFilter();
virtual float evaluate(float x) const;
};
// Cubic b-spline filter from Paul Heckbert.
class NVIMAGE_CLASS BSplineFilter : public Filter
{
public:
BSplineFilter();
virtual float evaluate(float x) const;
};
/// Mitchell & Netravali's two-param cubic
/// @see "Reconstruction Filters in Computer Graphics", SIGGRAPH 88
class NVIMAGE_CLASS MitchellFilter : public Filter
{
public:
MitchellFilter();
virtual float evaluate(float x) const;
void setParameters(float b, float c);
private:
float p0, p2, p3;
float q0, q1, q2, q3;
};
// Lanczos3 filter.
class NVIMAGE_CLASS LanczosFilter : public Filter
{
public:
LanczosFilter();
virtual float evaluate(float x) const;
};
// Sinc filter.
class NVIMAGE_CLASS SincFilter : public Filter
{
public:
SincFilter(float w);
virtual float evaluate(float x) const;
};
// Kaiser filter.
class NVIMAGE_CLASS KaiserFilter : public Filter
{
public:
KaiserFilter(float w);
virtual float evaluate(float x) const;
void setParameters(float a, float stretch);
private:
float alpha;
float stretch;
};
// Gaussian filter.
class GaussianFilter : public Filter
{
public:
GaussianFilter(float w);
virtual float evaluate(float x) const;
void setParameters(float variance);
private:
float variance;
};
/// A 1D kernel. Used to precompute filter weights.
class NVIMAGE_CLASS Kernel1
{
NV_FORBID_COPY(Kernel1);
public:
Kernel1(const Filter & f, int iscale, int samples = 32);
~Kernel1();
float valueAt(uint x) const {
nvDebugCheck(x < (uint)m_windowSize);
return m_data[x];
}
int windowSize() const {
return m_windowSize;
}
float width() const {
return m_width;
}
void debugPrint();
private:
int m_windowSize;
float m_width;
float * m_data;
};
/// A 2D kernel.
class NVIMAGE_CLASS Kernel2
{
public:
Kernel2(uint width);
Kernel2(uint width, const float * data);
Kernel2(const Kernel2 & k);
~Kernel2();
void normalize();
void transpose();
float valueAt(uint x, uint y) const {
return m_data[y * m_windowSize + x];
}
uint windowSize() const {
return m_windowSize;
}
void initLaplacian();
void initEdgeDetection();
void initSobel();
void initPrewitt();
void initBlendedSobel(const Vector4 & scale);
private:
const uint m_windowSize;
float * m_data;
};
/// A 1D polyphase kernel
class NVIMAGE_CLASS PolyphaseKernel
{
NV_FORBID_COPY(PolyphaseKernel);
public:
PolyphaseKernel(const Filter & f, uint srcLength, uint dstLength, int samples = 32);
~PolyphaseKernel();
int windowSize() const {
return m_windowSize;
}
uint length() const {
return m_length;
}
float width() const {
return m_width;
}
float valueAt(uint column, uint x) const {
nvDebugCheck(column < m_length);
nvDebugCheck(x < (uint)m_windowSize);
return m_data[column * m_windowSize + x];
}
void debugPrint() const;
private:
int m_windowSize;
uint m_length;
float m_width;
float * m_data;
};
} // nv namespace
#endif // NV_IMAGE_FILTER_H
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_FILTER_H
#define NV_IMAGE_FILTER_H
#include "nvimage.h"
#include "nvcore/Debug.h"
namespace nv
{
class Vector4;
/// Base filter class.
class NVIMAGE_CLASS Filter
{
public:
Filter(float width);
virtual ~Filter();
float width() const { return m_width; }
float sampleDelta(float x, float scale) const;
float sampleBox(float x, float scale, int samples) const;
float sampleTriangle(float x, float scale, int samples) const;
virtual float evaluate(float x) const = 0;
protected:
const float m_width;
};
// Box filter.
class NVIMAGE_CLASS BoxFilter : public Filter
{
public:
BoxFilter();
BoxFilter(float width);
virtual float evaluate(float x) const;
};
// Triangle (bilinear/tent) filter.
class NVIMAGE_CLASS TriangleFilter : public Filter
{
public:
TriangleFilter();
TriangleFilter(float width);
virtual float evaluate(float x) const;
};
// Quadratic (bell) filter.
class NVIMAGE_CLASS QuadraticFilter : public Filter
{
public:
QuadraticFilter();
virtual float evaluate(float x) const;
};
// Cubic filter from Thatcher Ulrich.
class NVIMAGE_CLASS CubicFilter : public Filter
{
public:
CubicFilter();
virtual float evaluate(float x) const;
};
// Cubic b-spline filter from Paul Heckbert.
class NVIMAGE_CLASS BSplineFilter : public Filter
{
public:
BSplineFilter();
virtual float evaluate(float x) const;
};
/// Mitchell & Netravali's two-param cubic
/// @see "Reconstruction Filters in Computer Graphics", SIGGRAPH 88
class NVIMAGE_CLASS MitchellFilter : public Filter
{
public:
MitchellFilter();
virtual float evaluate(float x) const;
void setParameters(float b, float c);
private:
float p0, p2, p3;
float q0, q1, q2, q3;
};
// Lanczos3 filter.
class NVIMAGE_CLASS LanczosFilter : public Filter
{
public:
LanczosFilter();
virtual float evaluate(float x) const;
};
// Sinc filter.
class NVIMAGE_CLASS SincFilter : public Filter
{
public:
SincFilter(float w);
virtual float evaluate(float x) const;
};
// Kaiser filter.
class NVIMAGE_CLASS KaiserFilter : public Filter
{
public:
KaiserFilter(float w);
virtual float evaluate(float x) const;
void setParameters(float a, float stretch);
private:
float alpha;
float stretch;
};
// Gaussian filter.
class GaussianFilter : public Filter
{
public:
GaussianFilter(float w);
virtual float evaluate(float x) const;
void setParameters(float variance);
private:
float variance;
};
/// A 1D kernel. Used to precompute filter weights.
class NVIMAGE_CLASS Kernel1
{
NV_FORBID_COPY(Kernel1);
public:
Kernel1(const Filter & f, int iscale, int samples = 32);
~Kernel1();
float valueAt(uint x) const {
nvDebugCheck(x < (uint)m_windowSize);
return m_data[x];
}
int windowSize() const {
return m_windowSize;
}
float width() const {
return m_width;
}
void debugPrint();
private:
int m_windowSize;
float m_width;
float * m_data;
};
/// A 2D kernel.
class NVIMAGE_CLASS Kernel2
{
public:
Kernel2(uint width);
Kernel2(uint width, const float * data);
Kernel2(const Kernel2 & k);
~Kernel2();
void normalize();
void transpose();
float valueAt(uint x, uint y) const {
return m_data[y * m_windowSize + x];
}
uint windowSize() const {
return m_windowSize;
}
void initLaplacian();
void initEdgeDetection();
void initSobel();
void initPrewitt();
void initBlendedSobel(const Vector4 & scale);
private:
const uint m_windowSize;
float * m_data;
};
/// A 1D polyphase kernel
class NVIMAGE_CLASS PolyphaseKernel
{
NV_FORBID_COPY(PolyphaseKernel);
public:
PolyphaseKernel(const Filter & f, uint srcLength, uint dstLength, int samples = 32);
~PolyphaseKernel();
int windowSize() const {
return m_windowSize;
}
uint length() const {
return m_length;
}
float width() const {
return m_width;
}
float valueAt(uint column, uint x) const {
nvDebugCheck(column < m_length);
nvDebugCheck(x < (uint)m_windowSize);
return m_data[column * m_windowSize + x];
}
void debugPrint() const;
private:
int m_windowSize;
uint m_length;
float m_width;
float * m_data;
};
} // nv namespace
#endif // NV_IMAGE_FILTER_H

@ -235,7 +235,7 @@ namespace nv
nvDebugCheck(x < m_width);
nvDebugCheck(y < m_height);
nvDebugCheck(z < m_depth);
return m_mem[((c * m_depth + z) * m_height + y) * m_width + x];
return m_mem[c * m_pixelCount + index(x, y, z)];
}
/// Get pixel component.
@ -246,7 +246,7 @@ namespace nv
nvDebugCheck(x < m_width);
nvDebugCheck(y < m_height);
nvDebugCheck(z < m_depth);
return m_mem[((c * m_depth + z) * m_height + y) * m_width + x];
return m_mem[c * m_pixelCount + index(x, y, z)];
}
/// Get pixel component.
@ -255,7 +255,7 @@ namespace nv
nvDebugCheck(m_mem != NULL);
nvDebugCheck(c < m_componentCount);
nvDebugCheck(idx < m_pixelCount);
return m_mem[c * m_height * m_width + idx];
return m_mem[c * m_pixelCount + idx];
}
/// Get pixel component.
@ -264,7 +264,7 @@ namespace nv
nvDebugCheck(m_mem != NULL);
nvDebugCheck(c < m_componentCount);
nvDebugCheck(idx < m_pixelCount);
return m_mem[c * m_height * m_width + idx];
return m_mem[c * m_pixelCount + idx];
}
/// Get pixel component.
@ -288,7 +288,9 @@ namespace nv
nvDebugCheck(x < m_width);
nvDebugCheck(y < m_height);
nvDebugCheck(z < m_depth);
return (z * m_height + y) * m_width + x;
uint idx = (z * m_height + y) * m_width + x;
nvDebugCheck(idx < m_pixelCount);
return idx;
}

@ -1,160 +1,160 @@
// This code is in the public domain -- castanyo@yahoo.es
#include "Image.h"
#include "ImageIO.h"
#include "nvmath/Color.h"
#include "nvcore/Debug.h"
#include "nvcore/Ptr.h"
#include "nvcore/Utils.h" // swap
using namespace nv;
Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL)
{
}
Image::Image(const Image & img) : m_data(NULL)
{
allocate(img.m_width, img.m_height, img.m_depth);
m_format = img.m_format;
memcpy(m_data, img.m_data, sizeof(Color32) * m_width * m_height * m_depth);
}
Image::~Image()
{
free();
}
const Image & Image::operator=(const Image & img)
{
allocate(img.m_width, img.m_height, m_depth);
m_format = img.m_format;
memcpy(m_data, img.m_data, sizeof(Color32) * m_width * m_height * m_depth);
return *this;
}
void Image::allocate(uint w, uint h, uint d)
{
free();
m_width = w;
m_height = h;
m_depth = d;
m_data = realloc<Color32>(m_data, w * h * d);
}
bool Image::load(const char * name)
{
free();
AutoPtr<Image> img(ImageIO::load(name));
if (img == NULL) {
return false;
}
swap(m_width, img->m_width);
swap(m_height, img->m_height);
swap(m_depth, img->m_depth);
swap(m_format, img->m_format);
swap(m_data, img->m_data);
return true;
}
void Image::wrap(void * data, uint w, uint h, uint d)
{
free();
m_data = (Color32 *)data;
m_width = w;
m_height = h;
m_depth = d;
}
void Image::unwrap()
{
m_data = NULL;
m_width = 0;
m_height = 0;
m_depth = 0;
}
void Image::free()
{
::free(m_data);
m_data = NULL;
}
uint Image::width() const
{
return m_width;
}
uint Image::height() const
{
return m_height;
}
uint Image::depth() const
{
return m_depth;
}
const Color32 * Image::scanline(uint h) const
{
nvDebugCheck(h < m_height);
return m_data + h * m_width;
}
Color32 * Image::scanline(uint h)
{
nvDebugCheck(h < m_height);
return m_data + h * m_width;
}
const Color32 * Image::pixels() const
{
return m_data;
}
Color32 * Image::pixels()
{
return m_data;
}
const Color32 & Image::pixel(uint idx) const
{
nvDebugCheck(idx < m_width * m_height * m_depth);
return m_data[idx];
}
Color32 & Image::pixel(uint idx)
{
nvDebugCheck(idx < m_width * m_height * m_depth);
return m_data[idx];
}
Image::Format Image::format() const
{
return m_format;
}
void Image::setFormat(Image::Format f)
{
m_format = f;
}
void Image::fill(Color32 c)
{
const uint size = m_width * m_height * m_depth;
for (uint i = 0; i < size; ++i)
{
m_data[i] = c;
}
}
// This code is in the public domain -- castanyo@yahoo.es
#include "Image.h"
#include "ImageIO.h"
#include "nvmath/Color.h"
#include "nvcore/Debug.h"
#include "nvcore/Ptr.h"
#include "nvcore/Utils.h" // swap
using namespace nv;
Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL)
{
}
Image::Image(const Image & img) : m_data(NULL)
{
allocate(img.m_width, img.m_height, img.m_depth);
m_format = img.m_format;
memcpy(m_data, img.m_data, sizeof(Color32) * m_width * m_height * m_depth);
}
Image::~Image()
{
free();
}
const Image & Image::operator=(const Image & img)
{
allocate(img.m_width, img.m_height, m_depth);
m_format = img.m_format;
memcpy(m_data, img.m_data, sizeof(Color32) * m_width * m_height * m_depth);
return *this;
}
void Image::allocate(uint w, uint h, uint d)
{
free();
m_width = w;
m_height = h;
m_depth = d;
m_data = realloc<Color32>(m_data, w * h * d);
}
bool Image::load(const char * name)
{
free();
AutoPtr<Image> img(ImageIO::load(name));
if (img == NULL) {
return false;
}
swap(m_width, img->m_width);
swap(m_height, img->m_height);
swap(m_depth, img->m_depth);
swap(m_format, img->m_format);
swap(m_data, img->m_data);
return true;
}
void Image::wrap(void * data, uint w, uint h, uint d)
{
free();
m_data = (Color32 *)data;
m_width = w;
m_height = h;
m_depth = d;
}
void Image::unwrap()
{
m_data = NULL;
m_width = 0;
m_height = 0;
m_depth = 0;
}
void Image::free()
{
::free(m_data);
m_data = NULL;
}
uint Image::width() const
{
return m_width;
}
uint Image::height() const
{
return m_height;
}
uint Image::depth() const
{
return m_depth;
}
const Color32 * Image::scanline(uint h) const
{
nvDebugCheck(h < m_height);
return m_data + h * m_width;
}
Color32 * Image::scanline(uint h)
{
nvDebugCheck(h < m_height);
return m_data + h * m_width;
}
const Color32 * Image::pixels() const
{
return m_data;
}
Color32 * Image::pixels()
{
return m_data;
}
const Color32 & Image::pixel(uint idx) const
{
nvDebugCheck(idx < m_width * m_height * m_depth);
return m_data[idx];
}
Color32 & Image::pixel(uint idx)
{
nvDebugCheck(idx < m_width * m_height * m_depth);
return m_data[idx];
}
Image::Format Image::format() const
{
return m_format;
}
void Image::setFormat(Image::Format f)
{
m_format = f;
}
void Image::fill(Color32 c)
{
const uint size = m_width * m_height * m_depth;
for (uint i = 0; i < size; ++i)
{
m_data[i] = c;
}
}

@ -1,86 +1,86 @@
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_IMAGE_H
#define NV_IMAGE_IMAGE_H
#include "nvimage.h"
#include "nvcore/Debug.h"
namespace nv
{
class Color32;
/// 32 bit RGBA image.
class NVIMAGE_CLASS Image
{
public:
enum Format
{
Format_RGB,
Format_ARGB,
};
Image();
Image(const Image & img);
~Image();
const Image & operator=(const Image & img);
void allocate(uint w, uint h, uint d = 1);
bool load(const char * name);
void wrap(void * data, uint w, uint h, uint d = 1);
void unwrap();
uint width() const;
uint height() const;
uint depth() const;
const Color32 * scanline(uint h) const;
Color32 * scanline(uint h);
const Color32 * pixels() const;
Color32 * pixels();
const Color32 & pixel(uint idx) const;
Color32 & pixel(uint idx);
const Color32 & pixel(uint x, uint y) const;
Color32 & pixel(uint x, uint y);
Format format() const;
void setFormat(Format f);
void fill(Color32 c);
private:
void free();
private:
uint m_width;
uint m_height;
uint m_depth;
Format m_format;
Color32 * m_data;
};
inline const Color32 & Image::pixel(uint x, uint y) const
{
nvDebugCheck(x < m_width && y < m_height);
return pixel(y * m_width + x);
}
inline Color32 & Image::pixel(uint x, uint y)
{
nvDebugCheck(x < m_width && y < m_height);
return pixel(y * m_width + x);
}
} // nv namespace
#endif // NV_IMAGE_IMAGE_H
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_IMAGE_H
#define NV_IMAGE_IMAGE_H
#include "nvimage.h"
#include "nvcore/Debug.h"
namespace nv
{
class Color32;
/// 32 bit RGBA image.
class NVIMAGE_CLASS Image
{
public:
enum Format
{
Format_RGB,
Format_ARGB,
};
Image();
Image(const Image & img);
~Image();
const Image & operator=(const Image & img);
void allocate(uint w, uint h, uint d = 1);
bool load(const char * name);
void wrap(void * data, uint w, uint h, uint d = 1);
void unwrap();
uint width() const;
uint height() const;
uint depth() const;
const Color32 * scanline(uint h) const;
Color32 * scanline(uint h);
const Color32 * pixels() const;
Color32 * pixels();
const Color32 & pixel(uint idx) const;
Color32 & pixel(uint idx);
const Color32 & pixel(uint x, uint y) const;
Color32 & pixel(uint x, uint y);
Format format() const;
void setFormat(Format f);
void fill(Color32 c);
private:
void free();
private:
uint m_width;
uint m_height;
uint m_depth;
Format m_format;
Color32 * m_data;
};
inline const Color32 & Image::pixel(uint x, uint y) const
{
nvDebugCheck(x < m_width && y < m_height);
return pixel(y * m_width + x);
}
inline Color32 & Image::pixel(uint x, uint y)
{
nvDebugCheck(x < m_width && y < m_height);
return pixel(y * m_width + x);
}
} // nv namespace
#endif // NV_IMAGE_IMAGE_H

File diff suppressed because it is too large Load Diff

@ -1,37 +1,37 @@
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_IMAGEIO_H
#define NV_IMAGE_IMAGEIO_H
#include "nvimage.h"
#include "nvcore/StrLib.h"
namespace nv
{
class Image;
class FloatImage;
class Stream;
namespace ImageIO
{
NVIMAGE_API Image * load(const char * fileName);
NVIMAGE_API Image * load(const char * fileName, Stream & s);
NVIMAGE_API FloatImage * loadFloat(const char * fileName);
NVIMAGE_API FloatImage * loadFloat(const char * fileName, Stream & s);
NVIMAGE_API bool save(const char * fileName, const Image * img, const char ** tags=NULL); // NULL terminated list.
NVIMAGE_API bool save(const char * fileName, Stream & s, const Image * img, const char ** tags=NULL);
NVIMAGE_API bool saveFloat(const char * fileName, const FloatImage * fimage, uint baseComponent, uint componentCount);
NVIMAGE_API bool saveFloat(const char * fileName, Stream & s, const FloatImage * fimage, uint baseComponent, uint componentCount);
} // ImageIO namespace
} // nv namespace
#endif // NV_IMAGE_IMAGEIO_H
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_IMAGEIO_H
#define NV_IMAGE_IMAGEIO_H
#include "nvimage.h"
#include "nvcore/StrLib.h"
namespace nv
{
class Image;
class FloatImage;
class Stream;
namespace ImageIO
{
NVIMAGE_API Image * load(const char * fileName);
NVIMAGE_API Image * load(const char * fileName, Stream & s);
NVIMAGE_API FloatImage * loadFloat(const char * fileName);
NVIMAGE_API FloatImage * loadFloat(const char * fileName, Stream & s);
NVIMAGE_API bool save(const char * fileName, const Image * img, const char ** tags=NULL); // NULL terminated list.
NVIMAGE_API bool save(const char * fileName, Stream & s, const Image * img, const char ** tags=NULL);
NVIMAGE_API bool saveFloat(const char * fileName, const FloatImage * fimage, uint baseComponent, uint componentCount);
NVIMAGE_API bool saveFloat(const char * fileName, Stream & s, const FloatImage * fimage, uint baseComponent, uint componentCount);
} // ImageIO namespace
} // nv namespace
#endif // NV_IMAGE_IMAGEIO_H

@ -27,6 +27,7 @@
#include "Image.h"
#include "nvmath/Color.inl"
#include "nvmath/Vector.h"
#include "nvcore/Ptr.h"

@ -1,59 +1,59 @@
// 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.
#pragma once
#ifndef NV_IMAGE_NORMALMAP_H
#define NV_IMAGE_NORMALMAP_H
#include "nvimage.h"
#include "FloatImage.h"
#include "nvmath/Vector.h"
namespace nv
{
class Image;
enum NormalMapFilter
{
NormalMapFilter_Sobel3x3, // fine detail
NormalMapFilter_Sobel5x5, // medium detail
NormalMapFilter_Sobel7x7, // large detail
NormalMapFilter_Sobel9x9, // very large
};
// @@ These two functions should be deprecated:
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, NormalMapFilter filter = NormalMapFilter_Sobel3x3);
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights);
FloatImage * createNormalMap(const FloatImage * img, FloatImage::WrapMode wm, Vector4::Arg filterWeights);
void normalizeNormalMap(FloatImage * img);
// @@ Add generation of DU/DV maps.
} // nv namespace
#endif // NV_IMAGE_NORMALMAP_H
// 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.
#pragma once
#ifndef NV_IMAGE_NORMALMAP_H
#define NV_IMAGE_NORMALMAP_H
#include "nvimage.h"
#include "FloatImage.h"
#include "nvmath/Vector.h"
namespace nv
{
class Image;
enum NormalMapFilter
{
NormalMapFilter_Sobel3x3, // fine detail
NormalMapFilter_Sobel5x5, // medium detail
NormalMapFilter_Sobel7x7, // large detail
NormalMapFilter_Sobel9x9, // very large
};
// @@ These two functions should be deprecated:
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, NormalMapFilter filter = NormalMapFilter_Sobel3x3);
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights);
FloatImage * createNormalMap(const FloatImage * img, FloatImage::WrapMode wm, Vector4::Arg filterWeights);
void normalizeNormalMap(FloatImage * img);
// @@ Add generation of DU/DV maps.
} // nv namespace
#endif // NV_IMAGE_NORMALMAP_H

@ -1,118 +1,118 @@
// 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.
#pragma once
#ifndef NV_IMAGE_PIXELFORMAT_H
#define NV_IMAGE_PIXELFORMAT_H
#include "nvimage.h"
namespace nv
{
namespace PixelFormat
{
// Convert component @a c having @a inbits to the returned value having @a outbits.
inline uint convert(uint c, uint inbits, uint outbits)
{
if (inbits == 0)
{
return 0;
}
else if (inbits >= outbits)
{
// truncate
return c >> (inbits - outbits);
}
else
{
// bitexpand
return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
}
}
// Get pixel component shift and size given its mask.
inline void maskShiftAndSize(uint mask, uint * shift, uint * size)
{
if (!mask)
{
*shift = 0;
*size = 0;
return;
}
*shift = 0;
while((mask & 1) == 0) {
++(*shift);
mask >>= 1;
}
*size = 0;
while((mask & 1) == 1) {
++(*size);
mask >>= 1;
}
}
inline float quantizeCeil(float f, int inbits, int outbits)
{
nvDebugCheck(f >= 0.0f && f <= 1.0f);
//uint i = f * (float(1 << inbits) - 1);
//i = convert(i, inbits, outbits);
//float result = float(i) / (float(1 << outbits) - 1);
//nvCheck(result >= f);
float result;
int offset = 0;
do {
uint i = offset + uint(f * (float(1 << inbits) - 1));
i = convert(i, inbits, outbits);
result = float(i) / (float(1 << outbits) - 1);
offset++;
} while (result < f);
return result;
}
/*
inline float quantizeRound(float f, int bits)
{
nvDebugCheck(f >= 0.0f && f <= 1.0f);
float scale = float(1 << bits);
return fround(f * scale) / scale;
}
inline float quantizeFloor(float f, int bits)
{
nvDebugCheck(f >= 0.0f && f <= 1.0f);
float scale = float(1 << bits);
return floor(f * scale) / scale;
}
*/
} // PixelFormat namespace
} // nv namespace
#endif // NV_IMAGE_PIXELFORMAT_H
// 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.
#pragma once
#ifndef NV_IMAGE_PIXELFORMAT_H
#define NV_IMAGE_PIXELFORMAT_H
#include "nvimage.h"
namespace nv
{
namespace PixelFormat
{
// Convert component @a c having @a inbits to the returned value having @a outbits.
inline uint convert(uint c, uint inbits, uint outbits)
{
if (inbits == 0)
{
return 0;
}
else if (inbits >= outbits)
{
// truncate
return c >> (inbits - outbits);
}
else
{
// bitexpand
return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
}
}
// Get pixel component shift and size given its mask.
inline void maskShiftAndSize(uint mask, uint * shift, uint * size)
{
if (!mask)
{
*shift = 0;
*size = 0;
return;
}
*shift = 0;
while((mask & 1) == 0) {
++(*shift);
mask >>= 1;
}
*size = 0;
while((mask & 1) == 1) {
++(*size);
mask >>= 1;
}
}
inline float quantizeCeil(float f, int inbits, int outbits)
{
nvDebugCheck(f >= 0.0f && f <= 1.0f);
//uint i = f * (float(1 << inbits) - 1);
//i = convert(i, inbits, outbits);
//float result = float(i) / (float(1 << outbits) - 1);
//nvCheck(result >= f);
float result;
int offset = 0;
do {
uint i = offset + uint(f * (float(1 << inbits) - 1));
i = convert(i, inbits, outbits);
result = float(i) / (float(1 << outbits) - 1);
offset++;
} while (result < f);
return result;
}
/*
inline float quantizeRound(float f, int bits)
{
nvDebugCheck(f >= 0.0f && f <= 1.0f);
float scale = float(1 << bits);
return fround(f * scale) / scale;
}
inline float quantizeFloor(float f, int bits)
{
nvDebugCheck(f >= 0.0f && f <= 1.0f);
float scale = float(1 << bits);
return floor(f * scale) / scale;
}
*/
} // PixelFormat namespace
} // nv namespace
#endif // NV_IMAGE_PIXELFORMAT_H

@ -1,71 +1,71 @@
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_PSDFILE_H
#define NV_IMAGE_PSDFILE_H
#include "nvcore/Stream.h"
namespace nv
{
enum PsdColorMode
{
PsdColorMode_Bitmap = 0,
PsdColorMode_GrayScale = 1,
PsdColorMode_Indexed = 2,
PsdColorMode_RGB = 3,
PsdColorMode_CMYK = 4,
PsdColorMode_MultiChannel = 7,
PsdColorMode_DuoTone = 8,
PsdColorMode_LabColor = 9
};
/// PSD header.
struct PsdHeader
{
uint32 signature;
uint16 version;
uint8 reserved[6];
uint16 channel_count;
uint32 height;
uint32 width;
uint16 depth;
uint16 color_mode;
bool isValid() const
{
return signature == 0x38425053; // '8BPS'
}
bool isSupported() const
{
if (version != 1) {
nvDebug("*** bad version number %u\n", version);
return false;
}
if (channel_count > 4) {
return false;
}
if (depth != 8) { // @@ Add support for 16 bit depths.
return false;
}
if (color_mode != PsdColorMode_RGB) {
return false;
}
return true;
}
};
inline Stream & operator<< (Stream & s, PsdHeader & head)
{
s << head.signature << head.version;
for (int i = 0; i < 6; i++) {
s << head.reserved[i];
}
return s << head.channel_count << head.height << head.width << head.depth << head.color_mode;
}
} // nv namespace
#endif // NV_IMAGE_PSDFILE_H
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_PSDFILE_H
#define NV_IMAGE_PSDFILE_H
#include "nvcore/Stream.h"
namespace nv
{
enum PsdColorMode
{
PsdColorMode_Bitmap = 0,
PsdColorMode_GrayScale = 1,
PsdColorMode_Indexed = 2,
PsdColorMode_RGB = 3,
PsdColorMode_CMYK = 4,
PsdColorMode_MultiChannel = 7,
PsdColorMode_DuoTone = 8,
PsdColorMode_LabColor = 9
};
/// PSD header.
struct PsdHeader
{
uint32 signature;
uint16 version;
uint8 reserved[6];
uint16 channel_count;
uint32 height;
uint32 width;
uint16 depth;
uint16 color_mode;
bool isValid() const
{
return signature == 0x38425053; // '8BPS'
}
bool isSupported() const
{
if (version != 1) {
nvDebug("*** bad version number %u\n", version);
return false;
}
if (channel_count > 4) {
return false;
}
if (depth != 8) { // @@ Add support for 16 bit depths.
return false;
}
if (color_mode != PsdColorMode_RGB) {
return false;
}
return true;
}
};
inline Stream & operator<< (Stream & s, PsdHeader & head)
{
s << head.signature << head.version;
for (int i = 0; i < 6; i++) {
s << head.reserved[i];
}
return s << head.channel_count << head.height << head.width << head.depth << head.color_mode;
}
} // nv namespace
#endif // NV_IMAGE_PSDFILE_H

@ -1,222 +1,222 @@
// This code is in the public domain -- castanyo@yahoo.es
/*
http://www.visgraf.impa.br/Courses/ip00/proj/Dithering1/floyd_steinberg_dithering.html
http://www.gamedev.net/reference/articles/article341.asp
@@ Look at LPS: http://www.cs.rit.edu/~pga/pics2000/i.html
This is a really nice guide to dithering algorithms:
http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT
@@ This code needs to be reviewed, I'm not sure it's correct.
*/
#include "Quantize.h"
#include "Image.h"
#include "PixelFormat.h"
#include "nvmath/Color.h"
#include "nvmath/Vector.inl"
#include "nvcore/Utils.h" // swap
#include <string.h> // memset
using namespace nv;
// Simple quantization.
void nv::Quantize::BinaryAlpha( Image * image, int alpha_threshold /*= 127*/ )
{
nvCheck(image != NULL);
const uint w = image->width();
const uint h = image->height();
for(uint y = 0; y < h; y++) {
for(uint x = 0; x < w; x++) {
Color32 pixel = image->pixel(x, y);
// Convert color.
if( pixel.a > alpha_threshold ) pixel.a = 255;
else pixel.a = 0;
// Store color.
image->pixel(x, y) = pixel;
}
}
}
// Simple quantization.
void nv::Quantize::RGB16( Image * image )
{
Truncate(image, 5, 6, 5, 8);
}
// Alpha quantization.
void nv::Quantize::Alpha4( Image * image )
{
Truncate(image, 8, 8, 8, 4);
}
// Error diffusion. Floyd Steinberg.
void nv::Quantize::FloydSteinberg_RGB16( Image * image )
{
FloydSteinberg(image, 5, 6, 5, 8);
}
// Error diffusion. Floyd Steinberg.
void nv::Quantize::FloydSteinberg_BinaryAlpha( Image * image, int alpha_threshold /*= 127*/ )
{
nvCheck(image != NULL);
const uint w = image->width();
const uint h = image->height();
// @@ Use fixed point?
float * row0 = new float[(w+2)];
float * row1 = new float[(w+2)];
memset(row0, 0, sizeof(float)*(w+2));
memset(row1, 0, sizeof(float)*(w+2));
for(uint y = 0; y < h; y++) {
for(uint x = 0; x < w; x++) {
Color32 pixel = image->pixel(x, y);
// Add error.
int alpha = int(pixel.a) + int(row0[1+x]);
// Convert color.
if( alpha > alpha_threshold ) pixel.a = 255;
else pixel.a = 0;
// Store color.
image->pixel(x, y) = pixel;
// Compute new error.
float diff = float(alpha - pixel.a);
// Propagate new error.
row0[1+x+1] += 7.0f / 16.0f * diff;
row1[1+x-1] += 3.0f / 16.0f * diff;
row1[1+x+0] += 5.0f / 16.0f * diff;
row1[1+x+1] += 1.0f / 16.0f * diff;
}
swap(row0, row1);
memset(row1, 0, sizeof(float)*(w+2));
}
delete [] row0;
delete [] row1;
}
// Error diffusion. Floyd Steinberg.
void nv::Quantize::FloydSteinberg_Alpha4( Image * image )
{
FloydSteinberg(image, 8, 8, 8, 4);
}
void nv::Quantize::Truncate(Image * image, uint rsize, uint gsize, uint bsize, uint asize)
{
nvCheck(image != NULL);
const uint w = image->width();
const uint h = image->height();
for(uint y = 0; y < h; y++) {
for(uint x = 0; x < w; x++) {
Color32 pixel = image->pixel(x, y);
// Convert to our desired size, and reconstruct.
pixel.r = PixelFormat::convert(pixel.r, 8, rsize);
pixel.r = PixelFormat::convert(pixel.r, rsize, 8);
pixel.g = PixelFormat::convert(pixel.g, 8, gsize);
pixel.g = PixelFormat::convert(pixel.g, gsize, 8);
pixel.b = PixelFormat::convert(pixel.b, 8, bsize);
pixel.b = PixelFormat::convert(pixel.b, bsize, 8);
pixel.a = PixelFormat::convert(pixel.a, 8, asize);
pixel.a = PixelFormat::convert(pixel.a, asize, 8);
// Store color.
image->pixel(x, y) = pixel;
}
}
}
// Error diffusion. Floyd Steinberg.
void nv::Quantize::FloydSteinberg(Image * image, uint rsize, uint gsize, uint bsize, uint asize)
{
nvCheck(image != NULL);
const uint w = image->width();
const uint h = image->height();
Vector4 * row0 = new Vector4[w+2];
Vector4 * row1 = new Vector4[w+2];
memset(row0, 0, sizeof(Vector4)*(w+2));
memset(row1, 0, sizeof(Vector4)*(w+2));
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
Color32 pixel = image->pixel(x, y);
// Add error.
pixel.r = clamp(int(pixel.r) + int(row0[1+x].x), 0, 255);
pixel.g = clamp(int(pixel.g) + int(row0[1+x].y), 0, 255);
pixel.b = clamp(int(pixel.b) + int(row0[1+x].z), 0, 255);
pixel.a = clamp(int(pixel.a) + int(row0[1+x].w), 0, 255);
int r = pixel.r;
int g = pixel.g;
int b = pixel.b;
int a = pixel.a;
// Convert to our desired size, and reconstruct.
r = PixelFormat::convert(r, 8, rsize);
r = PixelFormat::convert(r, rsize, 8);
g = PixelFormat::convert(g, 8, gsize);
g = PixelFormat::convert(g, gsize, 8);
b = PixelFormat::convert(b, 8, bsize);
b = PixelFormat::convert(b, bsize, 8);
a = PixelFormat::convert(a, 8, asize);
a = PixelFormat::convert(a, asize, 8);
// Store color.
image->pixel(x, y) = Color32(r, g, b, a);
// Compute new error.
Vector4 diff(float(int(pixel.r) - r), float(int(pixel.g) - g), float(int(pixel.b) - b), float(int(pixel.a) - a));
// Propagate new error.
row0[1+x+1] += 7.0f / 16.0f * diff;
row1[1+x-1] += 3.0f / 16.0f * diff;
row1[1+x+0] += 5.0f / 16.0f * diff;
row1[1+x+1] += 1.0f / 16.0f * diff;
}
swap(row0, row1);
memset(row1, 0, sizeof(Vector4)*(w+2));
}
delete [] row0;
delete [] row1;
}
// This code is in the public domain -- castanyo@yahoo.es
/*
http://www.visgraf.impa.br/Courses/ip00/proj/Dithering1/floyd_steinberg_dithering.html
http://www.gamedev.net/reference/articles/article341.asp
@@ Look at LPS: http://www.cs.rit.edu/~pga/pics2000/i.html
This is a really nice guide to dithering algorithms:
http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT
@@ This code needs to be reviewed, I'm not sure it's correct.
*/
#include "Quantize.h"
#include "Image.h"
#include "PixelFormat.h"
#include "nvmath/Color.h"
#include "nvmath/Vector.inl"
#include "nvcore/Utils.h" // swap
#include <string.h> // memset
using namespace nv;
// Simple quantization.
void nv::Quantize::BinaryAlpha( Image * image, int alpha_threshold /*= 127*/ )
{
nvCheck(image != NULL);
const uint w = image->width();
const uint h = image->height();
for(uint y = 0; y < h; y++) {
for(uint x = 0; x < w; x++) {
Color32 pixel = image->pixel(x, y);
// Convert color.
if( pixel.a > alpha_threshold ) pixel.a = 255;
else pixel.a = 0;
// Store color.
image->pixel(x, y) = pixel;
}
}
}
// Simple quantization.
void nv::Quantize::RGB16( Image * image )
{
Truncate(image, 5, 6, 5, 8);
}
// Alpha quantization.
void nv::Quantize::Alpha4( Image * image )
{
Truncate(image, 8, 8, 8, 4);
}
// Error diffusion. Floyd Steinberg.
void nv::Quantize::FloydSteinberg_RGB16( Image * image )
{
FloydSteinberg(image, 5, 6, 5, 8);
}
// Error diffusion. Floyd Steinberg.
void nv::Quantize::FloydSteinberg_BinaryAlpha( Image * image, int alpha_threshold /*= 127*/ )
{
nvCheck(image != NULL);
const uint w = image->width();
const uint h = image->height();
// @@ Use fixed point?
float * row0 = new float[(w+2)];
float * row1 = new float[(w+2)];
memset(row0, 0, sizeof(float)*(w+2));
memset(row1, 0, sizeof(float)*(w+2));
for(uint y = 0; y < h; y++) {
for(uint x = 0; x < w; x++) {
Color32 pixel = image->pixel(x, y);
// Add error.
int alpha = int(pixel.a) + int(row0[1+x]);
// Convert color.
if( alpha > alpha_threshold ) pixel.a = 255;
else pixel.a = 0;
// Store color.
image->pixel(x, y) = pixel;
// Compute new error.
float diff = float(alpha - pixel.a);
// Propagate new error.
row0[1+x+1] += 7.0f / 16.0f * diff;
row1[1+x-1] += 3.0f / 16.0f * diff;
row1[1+x+0] += 5.0f / 16.0f * diff;
row1[1+x+1] += 1.0f / 16.0f * diff;
}
swap(row0, row1);
memset(row1, 0, sizeof(float)*(w+2));
}
delete [] row0;
delete [] row1;
}
// Error diffusion. Floyd Steinberg.
void nv::Quantize::FloydSteinberg_Alpha4( Image * image )
{
FloydSteinberg(image, 8, 8, 8, 4);
}
void nv::Quantize::Truncate(Image * image, uint rsize, uint gsize, uint bsize, uint asize)
{
nvCheck(image != NULL);
const uint w = image->width();
const uint h = image->height();
for(uint y = 0; y < h; y++) {
for(uint x = 0; x < w; x++) {
Color32 pixel = image->pixel(x, y);
// Convert to our desired size, and reconstruct.
pixel.r = PixelFormat::convert(pixel.r, 8, rsize);
pixel.r = PixelFormat::convert(pixel.r, rsize, 8);
pixel.g = PixelFormat::convert(pixel.g, 8, gsize);
pixel.g = PixelFormat::convert(pixel.g, gsize, 8);
pixel.b = PixelFormat::convert(pixel.b, 8, bsize);
pixel.b = PixelFormat::convert(pixel.b, bsize, 8);
pixel.a = PixelFormat::convert(pixel.a, 8, asize);
pixel.a = PixelFormat::convert(pixel.a, asize, 8);
// Store color.
image->pixel(x, y) = pixel;
}
}
}
// Error diffusion. Floyd Steinberg.
void nv::Quantize::FloydSteinberg(Image * image, uint rsize, uint gsize, uint bsize, uint asize)
{
nvCheck(image != NULL);
const uint w = image->width();
const uint h = image->height();
Vector4 * row0 = new Vector4[w+2];
Vector4 * row1 = new Vector4[w+2];
memset(row0, 0, sizeof(Vector4)*(w+2));
memset(row1, 0, sizeof(Vector4)*(w+2));
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
Color32 pixel = image->pixel(x, y);
// Add error.
pixel.r = clamp(int(pixel.r) + int(row0[1+x].x), 0, 255);
pixel.g = clamp(int(pixel.g) + int(row0[1+x].y), 0, 255);
pixel.b = clamp(int(pixel.b) + int(row0[1+x].z), 0, 255);
pixel.a = clamp(int(pixel.a) + int(row0[1+x].w), 0, 255);
int r = pixel.r;
int g = pixel.g;
int b = pixel.b;
int a = pixel.a;
// Convert to our desired size, and reconstruct.
r = PixelFormat::convert(r, 8, rsize);
r = PixelFormat::convert(r, rsize, 8);
g = PixelFormat::convert(g, 8, gsize);
g = PixelFormat::convert(g, gsize, 8);
b = PixelFormat::convert(b, 8, bsize);
b = PixelFormat::convert(b, bsize, 8);
a = PixelFormat::convert(a, 8, asize);
a = PixelFormat::convert(a, asize, 8);
// Store color.
image->pixel(x, y) = Color32(r, g, b, a);
// Compute new error.
Vector4 diff(float(int(pixel.r) - r), float(int(pixel.g) - g), float(int(pixel.b) - b), float(int(pixel.a) - a));
// Propagate new error.
row0[1+x+1] += 7.0f / 16.0f * diff;
row1[1+x-1] += 3.0f / 16.0f * diff;
row1[1+x+0] += 5.0f / 16.0f * diff;
row1[1+x+1] += 1.0f / 16.0f * diff;
}
swap(row0, row1);
memset(row1, 0, sizeof(Vector4)*(w+2));
}
delete [] row0;
delete [] row1;
}

@ -1,32 +1,32 @@
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_QUANTIZE_H
#define NV_IMAGE_QUANTIZE_H
#include "nvimage.h"
namespace nv
{
class Image;
namespace Quantize
{
void RGB16(Image * img);
void BinaryAlpha(Image * img, int alpha_threshold = 127);
void Alpha4(Image * img);
void FloydSteinberg_RGB16(Image * img);
void FloydSteinberg_BinaryAlpha(Image * img, int alpha_threshold = 127);
void FloydSteinberg_Alpha4(Image * img);
void Truncate(Image * image, uint rsize, uint gsize, uint bsize, uint asize);
void FloydSteinberg(Image * image, uint rsize, uint gsize, uint bsize, uint asize);
// @@ Add palette quantization algorithms!
}
}
#endif // NV_IMAGE_QUANTIZE_H
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_QUANTIZE_H
#define NV_IMAGE_QUANTIZE_H
#include "nvimage.h"
namespace nv
{
class Image;
namespace Quantize
{
void RGB16(Image * img);
void BinaryAlpha(Image * img, int alpha_threshold = 127);
void Alpha4(Image * img);
void FloydSteinberg_RGB16(Image * img);
void FloydSteinberg_BinaryAlpha(Image * img, int alpha_threshold = 127);
void FloydSteinberg_Alpha4(Image * img);
void Truncate(Image * image, uint rsize, uint gsize, uint bsize, uint asize);
void FloydSteinberg(Image * image, uint rsize, uint gsize, uint bsize, uint asize);
// @@ Add palette quantization algorithms!
}
}
#endif // NV_IMAGE_QUANTIZE_H

@ -1,106 +1,106 @@
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_TGAFILE_H
#define NV_IMAGE_TGAFILE_H
#include "nvcore/Stream.h"
namespace nv
{
// TGA types
enum TGAType {
TGA_TYPE_INDEXED = 1,
TGA_TYPE_RGB = 2,
TGA_TYPE_GREY = 3,
TGA_TYPE_RLE_INDEXED = 9,
TGA_TYPE_RLE_RGB = 10,
TGA_TYPE_RLE_GREY = 11
};
#define TGA_INTERLEAVE_MASK 0xc0
#define TGA_INTERLEAVE_NONE 0x00
#define TGA_INTERLEAVE_2WAY 0x40
#define TGA_INTERLEAVE_4WAY 0x80
#define TGA_ORIGIN_MASK 0x30
#define TGA_ORIGIN_LEFT 0x00
#define TGA_ORIGIN_RIGHT 0x10
#define TGA_ORIGIN_LOWER 0x00
#define TGA_ORIGIN_UPPER 0x20
#define TGA_HAS_ALPHA 0x0F
/// Tga Header.
struct TgaHeader {
uint8 id_length;
uint8 colormap_type;
uint8 image_type;
uint16 colormap_index;
uint16 colormap_length;
uint8 colormap_size;
uint16 x_origin;
uint16 y_origin;
uint16 width;
uint16 height;
uint8 pixel_size;
uint8 flags;
enum { Size = 18 }; //const static int SIZE = 18;
};
/// Tga File.
struct TgaFile {
TgaFile() {
mem = NULL;
}
~TgaFile() {
free();
}
uint size() const {
return head.width * head.height * (head.pixel_size / 8);
}
void allocate() {
nvCheck( mem == NULL );
mem = new uint8[size()];
}
void free() {
delete [] mem;
mem = NULL;
}
TgaHeader head;
uint8 * mem;
};
inline Stream & operator<< (Stream & s, TgaHeader & head)
{
s << head.id_length << head.colormap_type << head.image_type;
s << head.colormap_index << head.colormap_length << head.colormap_size;
s << head.x_origin << head.y_origin << head.width << head.height;
s << head.pixel_size << head.flags;
return s;
}
inline Stream & operator<< (Stream & s, TgaFile & tga)
{
s << tga.head;
if( s.isLoading() ) {
tga.allocate();
}
s.serialize( tga.mem, tga.size() );
return s;
}
} // nv namespace
#endif // NV_IMAGE_TGAFILE_H
// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef NV_IMAGE_TGAFILE_H
#define NV_IMAGE_TGAFILE_H
#include "nvcore/Stream.h"
namespace nv
{
// TGA types
enum TGAType {
TGA_TYPE_INDEXED = 1,
TGA_TYPE_RGB = 2,
TGA_TYPE_GREY = 3,
TGA_TYPE_RLE_INDEXED = 9,
TGA_TYPE_RLE_RGB = 10,
TGA_TYPE_RLE_GREY = 11
};
#define TGA_INTERLEAVE_MASK 0xc0
#define TGA_INTERLEAVE_NONE 0x00
#define TGA_INTERLEAVE_2WAY 0x40
#define TGA_INTERLEAVE_4WAY 0x80
#define TGA_ORIGIN_MASK 0x30
#define TGA_ORIGIN_LEFT 0x00
#define TGA_ORIGIN_RIGHT 0x10
#define TGA_ORIGIN_LOWER 0x00
#define TGA_ORIGIN_UPPER 0x20
#define TGA_HAS_ALPHA 0x0F
/// Tga Header.
struct TgaHeader {
uint8 id_length;
uint8 colormap_type;
uint8 image_type;
uint16 colormap_index;
uint16 colormap_length;
uint8 colormap_size;
uint16 x_origin;
uint16 y_origin;
uint16 width;
uint16 height;
uint8 pixel_size;
uint8 flags;
enum { Size = 18 }; //const static int SIZE = 18;
};
/// Tga File.
struct TgaFile {
TgaFile() {
mem = NULL;
}
~TgaFile() {
free();
}
uint size() const {
return head.width * head.height * (head.pixel_size / 8);
}
void allocate() {
nvCheck( mem == NULL );
mem = new uint8[size()];
}
void free() {
delete [] mem;
mem = NULL;
}
TgaHeader head;
uint8 * mem;
};
inline Stream & operator<< (Stream & s, TgaHeader & head)
{
s << head.id_length << head.colormap_type << head.image_type;
s << head.colormap_index << head.colormap_length << head.colormap_size;
s << head.x_origin << head.y_origin << head.width << head.height;
s << head.pixel_size << head.flags;
return s;
}
inline Stream & operator<< (Stream & s, TgaFile & tga)
{
s << tga.head;
if( s.isLoading() ) {
tga.allocate();
}
s.serialize( tga.mem, tga.size() );
return s;
}
} // nv namespace
#endif // NV_IMAGE_TGAFILE_H

File diff suppressed because it is too large Load Diff

@ -1,30 +1,30 @@
#pragma once
#ifndef NV_MATH_HALF_H
#define NV_MATH_HALF_H
#include "nvmath.h"
namespace nv {
uint32 half_to_float( uint16 h );
uint16 half_from_float( uint32 f );
void half_init_tables();
uint32 fast_half_to_float(uint16 h);
inline uint16 to_half(float c) {
union { float f; uint32 u; } f;
f.f = c;
return nv::half_from_float( f.u );
}
inline float to_float(uint16 c) {
union { float f; uint32 u; } f;
f.u = nv::fast_half_to_float( c );
return f.f;
}
} // nv namespace
#endif // NV_MATH_HALF_H
#pragma once
#ifndef NV_MATH_HALF_H
#define NV_MATH_HALF_H
#include "nvmath.h"
namespace nv {
uint32 half_to_float( uint16 h );
uint16 half_from_float( uint32 f );
void half_init_tables();
uint32 fast_half_to_float(uint16 h);
inline uint16 to_half(float c) {
union { float f; uint32 u; } f;
f.f = c;
return nv::half_from_float( f.u );
}
inline float to_float(uint16 c) {
union { float f; uint32 u; } f;
f.u = nv::fast_half_to_float( c );
return f.f;
}
} // nv namespace
#endif // NV_MATH_HALF_H

File diff suppressed because it is too large Load Diff

@ -381,14 +381,14 @@ namespace nv
return Vector2(max(a.x, b.x), max(a.y, b.y));
}
inline bool isValid(Vector2::Arg v)
inline bool isFinite(Vector2::Arg v)
{
return isFinite(v.x) && isFinite(v.y);
}
inline Vector2 validate(Vector2::Arg v, Vector2::Arg fallback = Vector2(0.0f))
{
if (!isValid(v)) return fallback;
if (!isFinite(v)) return fallback;
Vector2 vf = v;
nv::floatCleanup(vf.component, 2);
return vf;
@ -567,14 +567,14 @@ namespace nv
return Vector3(ceilf(v.x), ceilf(v.y), ceilf(v.z));
}
inline bool isValid(Vector3::Arg v)
inline bool isFinite(Vector3::Arg v)
{
return isFinite(v.x) && isFinite(v.y) && isFinite(v.z);
}
inline Vector3 validate(Vector3::Arg v, Vector3::Arg fallback = Vector3(0.0f))
{
if (!isValid(v)) return fallback;
if (!isFinite(v)) return fallback;
Vector3 vf = v;
nv::floatCleanup(vf.component, 3);
return vf;
@ -699,14 +699,14 @@ namespace nv
return Vector4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
}
inline bool isValid(Vector4::Arg v)
inline bool isFinite(Vector4::Arg v)
{
return isFinite(v.x) && isFinite(v.y) && isFinite(v.z) && isFinite(v.w);
}
inline Vector4 validate(Vector4::Arg v, Vector4::Arg fallback = Vector4(0.0f))
{
if (!isValid(v)) return fallback;
if (!isFinite(v)) return fallback;
Vector4 vf = v;
nv::floatCleanup(vf.component, 4);
return vf;

@ -5,14 +5,13 @@
#define NV_MATH_H
#include "nvcore/nvcore.h"
#include "nvcore/Debug.h"
#include "nvcore/Utils.h" // clamp
#include "nvcore/Debug.h" // nvDebugCheck
#include "nvcore/Utils.h" // clamp
#include <math.h>
#include <limits.h> // INT_MAX
#if NV_OS_WIN32 || NV_OS_XBOX
#include <float.h>
#include <float.h> // finite, isnan
#endif
// Function linkage
@ -105,9 +104,12 @@ namespace nv
inline float toRadian(float degree) { return degree * (PI / 180.0f); }
inline float toDegree(float radian) { return radian * (180.0f / PI); }
// Robust floating point comparisons:
// http://realtimecollisiondetection.net/blog/?p=89
inline bool equal(const float f0, const float f1, const float epsilon = NV_EPSILON)
{
return fabs(f0-f1) <= epsilon;
//return fabs(f0-f1) <= epsilon;
return fabs(f0-f1) <= epsilon * max(1.0f, fabs(f0), fabs(f1));
}
inline bool isZero(const float f, const float epsilon = NV_EPSILON)

@ -1,8 +1,8 @@
// This code is in the public domain -- castano@gmail.com
#pragma once
#ifndef NV_THREAD_THREADPOOL_H
#define NV_THREAD_THREADPOOL_H
// This code is in the public domain -- castano@gmail.com
#pragma once
#ifndef NV_THREAD_THREADPOOL_H
#define NV_THREAD_THREADPOOL_H
#include "nvthread.h"

@ -183,6 +183,35 @@ Surface CubeSurface::unfold(CubeLayout layout) const
}
float CubeSurface::average(int channel) const
{
const uint edgeLength = m->edgeLength;
// These tables along with the surface so that we only compute them once.
if (m->solidAngleTable == NULL) {
m->solidAngleTable = new SolidAngleTable(edgeLength);
}
float total = 0.0f;
float sum = 0.0f;
for (int f = 0; f < 6; f++) {
float * c = m->face[f].m->image->channel(channel);
for (uint y = 0; y < edgeLength; y++) {
for (uint x = 0; x < edgeLength; x++) {
float solidAngle = m->solidAngleTable->lookup(x, y);
total += solidAngle;
sum += c[y * edgeLength + x] * solidAngle;
}
}
}
return sum / total;
}
CubeSurface CubeSurface::irradianceFilter(int size) const
{
// @@ TODO
@ -237,7 +266,7 @@ SolidAngleTable::SolidAngleTable(uint edgeLength) : size(edgeLength/2) {
for (uint y = 0; y < size; y++) {
for (uint x = 0; x < size; x++) {
data[y * size + x] = solidAngleTerm(128+x, 128+y, inverseEdgeLength);
data[y * size + x] = solidAngleTerm(size+x, size+y, inverseEdgeLength);
}
}
}
@ -631,7 +660,7 @@ CubeSurface CubeSurface::cosinePowerFilter(int size, float cosinePower) const
CubeSurface filteredCube;
filteredCube.m->allocate(size);
// Store these tables along with the surface. Compute them only once!
// These tables along with the surface so that we only compute them once.
if (m->solidAngleTable == NULL) {
m->solidAngleTable = new SolidAngleTable(edgeLength);
}

@ -74,7 +74,7 @@ namespace nvtt
edgeLength = p.edgeLength;
for (uint i = 0; i < 6; i++) {
face[i] = p.face[6];
face[i] = p.face[i];
}
solidAngleTable = NULL; // @@ Transfer tables. Needs refcounting?
vectorTable = NULL;

@ -44,6 +44,7 @@ OutputOptions::~OutputOptions()
void OutputOptions::reset()
{
m.fileName.reset();
m.fileHandle = NULL;
m.outputHandler = NULL;
m.errorHandler = NULL;
@ -52,37 +53,67 @@ void OutputOptions::reset()
m.container = Container_DDS;
m.version = 0;
m.srgb = false;
m.deleteOutputHandler = false;
}
/// Set output file name.
void OutputOptions::setFileName(const char * fileName)
{
if (!m.fileName.isNull())
if (m.deleteOutputHandler)
{
// To close the file and avoid leak.
delete m.outputHandler;
}
m.fileName = fileName;
m.fileHandle = NULL;
m.outputHandler = NULL;
m.deleteOutputHandler = false;
DefaultOutputHandler * oh = new DefaultOutputHandler(fileName);
if (!oh->stream.isError())
{
if (oh->stream.isError()) {
delete oh;
}
else {
m.deleteOutputHandler = true;
m.outputHandler = oh;
}
}
/// Set output file handle.
void OutputOptions::setFileHandle(void * fp)
{
if (m.deleteOutputHandler) {
delete m.outputHandler;
}
m.fileName.reset();
m.fileHandle = (FILE *)fp;
m.outputHandler = NULL;
m.deleteOutputHandler = false;
DefaultOutputHandler * oh = new DefaultOutputHandler(m.fileHandle);
if (oh->stream.isError()) {
delete oh;
}
else {
m.deleteOutputHandler = true;
m.outputHandler = oh;
}
}
/// Set output handler.
void OutputOptions::setOutputHandler(OutputHandler * outputHandler)
{
if (!m.fileName.isNull())
{
if (m.deleteOutputHandler) {
delete m.outputHandler;
m.fileName.reset();
}
m.fileName.reset();
m.fileHandle = NULL;
m.outputHandler = outputHandler;
m.deleteOutputHandler = false;
}
/// Set error handler.
@ -117,7 +148,7 @@ void OutputOptions::setSrgbFlag(bool b)
bool OutputOptions::Private::hasValidOutputHandler() const
{
if (!fileName.isNull())
if (!fileName.isNull() || fileHandle != NULL)
{
return outputHandler != NULL;
}

@ -25,16 +25,19 @@
#ifndef NV_TT_OUTPUTOPTIONS_H
#define NV_TT_OUTPUTOPTIONS_H
#include <nvcore/StrLib.h> // Path
#include <nvcore/StdStream.h>
#include "nvtt.h"
#include "nvcore/StrLib.h" // Path
#include "nvcore/StdStream.h"
namespace nvtt
{
struct DefaultOutputHandler : public nvtt::OutputHandler
{
DefaultOutputHandler(const char * fileName) : stream(fileName) {}
DefaultOutputHandler(FILE * fp) : stream(fp, false) {}
virtual ~DefaultOutputHandler() {}
@ -64,6 +67,7 @@ namespace nvtt
struct OutputOptions::Private
{
nv::Path fileName;
FILE * fileHandle;
OutputHandler * outputHandler;
ErrorHandler * errorHandler;
@ -72,6 +76,7 @@ namespace nvtt
Container container;
int version;
bool srgb;
bool deleteOutputHandler;
bool hasValidOutputHandler() const;

@ -704,13 +704,14 @@ void Surface::resize(int w, int h, int d, ResizeFilter filter)
void Surface::resize(int w, int h, int d, ResizeFilter filter, float filterWidth, const float * params)
{
FloatImage * img = m->image;
if (img == NULL || (w == img->width() && h == img->height() && d == img->depth())) {
if (isNull() || (w == width() && h == height() && d == depth())) {
return;
}
detach();
FloatImage * img = m->image;
FloatImage::WrapMode wrapMode = (FloatImage::WrapMode)m->wrapMode;
if (m->alphaMode == AlphaMode_Transparency)
@ -781,7 +782,7 @@ void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, float filterWidth, const float * params)
{
if (m->image == NULL) return;
if (isNull()) return;
int w = m->image->width();
int h = m->image->height();
@ -803,13 +804,14 @@ bool Surface::buildNextMipmap(MipmapFilter filter)
bool Surface::buildNextMipmap(MipmapFilter filter, float filterWidth, const float * params)
{
FloatImage * img = m->image;
if (img == NULL || (img->width() == 1 && img->height() == 1 && img->depth() == 1)) {
if (isNull() || (width() == 1 && height() == 1 && depth() == 1)) {
return false;
}
detach();
FloatImage * img = m->image;
FloatImage::WrapMode wrapMode = (FloatImage::WrapMode)m->wrapMode;
if (m->alphaMode == AlphaMode_Transparency)
@ -868,13 +870,14 @@ void Surface::canvasSize(int w, int h, int d)
{
nvDebugCheck(w > 0 && h > 0 && d > 0);
FloatImage * img = m->image;
if (img == NULL || (w == img->width() && h == img->height() && d == img->depth())) {
if (isNull() || (w == width() && h == height() && d == depth())) {
return;
}
detach();
FloatImage * img = m->image;
FloatImage * new_img = new FloatImage;
new_img->allocate(4, w, h, d);
new_img->clear();
@ -903,7 +906,7 @@ void Surface::canvasSize(int w, int h, int d)
// Color transforms.
void Surface::toLinear(float gamma)
{
if (m->image == NULL) return;
if (isNull()) return;
if (equal(gamma, 1.0f)) return;
detach();
@ -913,7 +916,7 @@ void Surface::toLinear(float gamma)
void Surface::toGamma(float gamma)
{
if (m->image == NULL) return;
if (isNull()) return;
if (equal(gamma, 1.0f)) return;
detach();
@ -923,7 +926,8 @@ void Surface::toGamma(float gamma)
static float toSrgb(float f) {
if (f <= 0.0) f = 0.0f;
if (isNan(f)) f = 0.0f;
else if (f <= 0.0f) f = 0.0f;
else if (f <= 0.0031308f) f = 12.92f * f;
else if (f <= 1.0f) f = (powf(f, 0.41666f) * 1.055f) - 0.055f;
else f = 1.0f;
@ -932,21 +936,43 @@ static float toSrgb(float f) {
void Surface::toSrgb()
{
FloatImage * img = m->image;
if (img == NULL) return;
if (isNull()) return;
detach();
FloatImage * img = m->image;
const uint count = img->pixelCount();
for (uint j = 0; j < count; j++)
{
float & r = img->pixel(0, j);
float & g = img->pixel(1, j);
float & b = img->pixel(2, j);
for (uint c = 0; c < 3; c++) {
float * channel = img->channel(c);
for (uint i = 0; i < count; i++) {
channel[i] = ::toSrgb(channel[i]);
}
}
}
static float fromSrgb(float f) {
if (f < 0.0f) f = 0.0f;
else if (f < 0.04045f) f = f / 12.92f;
else if (f <= 1.0f) f = powf((f + 0.055f) / 1.055f, 2.4f);
else f = 1.0f;
return f;
}
void Surface::toLinearFromSrgb()
{
if (isNull()) return;
detach();
r = ::toSrgb(r);
g = ::toSrgb(g);
b = ::toSrgb(b);
FloatImage * img = m->image;
const uint count = img->pixelCount();
for (uint c = 0; c < 3; c++) {
float * channel = img->channel(c);
for (uint i = 0; i < count; i++) {
channel[i] = ::fromSrgb(channel[i]);
}
}
}
@ -962,28 +988,25 @@ static float toXenonSrgb(float f) {
void Surface::toXenonSrgb()
{
FloatImage * img = m->image;
if (img == NULL) return;
if (isNull()) return;
detach();
const uint count = img->pixelCount();
for (uint j = 0; j < count; j++)
{
float & r = img->pixel(0, j);
float & g = img->pixel(1, j);
float & b = img->pixel(2, j);
FloatImage * img = m->image;
r = ::toXenonSrgb(r);
g = ::toXenonSrgb(g);
b = ::toXenonSrgb(b);
const uint count = img->pixelCount();
for (uint c = 0; c < 3; c++) {
float * channel = img->channel(c);
for (uint i = 0; i < count; i++) {
channel[i] = ::toXenonSrgb(channel[i]);
}
}
}
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 (isNull()) return;
detach();
@ -1000,7 +1023,7 @@ void Surface::transform(const float w0[4], const float w1[4], const float w2[4],
void Surface::swizzle(int r, int g, int b, int a)
{
if (m->image == NULL) return;
if (isNull()) return;
if (r == 0 && g == 1 && b == 2 && a == 3) return;
detach();
@ -1011,7 +1034,7 @@ void Surface::swizzle(int r, int g, int b, int a)
// color * scale + bias
void Surface::scaleBias(int channel, float scale, float bias)
{
if (m->image == NULL) return;
if (isNull()) return;
if (equal(scale, 1.0f) && equal(bias, 0.0f)) return;
detach();
@ -1021,7 +1044,7 @@ void Surface::scaleBias(int channel, float scale, float bias)
void Surface::clamp(int channel, float low, float high)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1045,7 +1068,7 @@ void Surface::expandNormal()
void Surface::blend(float red, float green, float blue, float alpha, float t)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1067,7 +1090,7 @@ void Surface::blend(float red, float green, float blue, float alpha, float t)
void Surface::premultiplyAlpha()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1089,7 +1112,7 @@ void Surface::premultiplyAlpha()
void Surface::toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1116,7 +1139,7 @@ void Surface::toGreyScale(float redScale, float greenScale, float blueScale, flo
// Draw colored border.
void Surface::setBorder(float r, float g, float b, float a)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1158,7 +1181,7 @@ void Surface::setBorder(float r, float g, float b, float a)
// Fill image with the given color.
void Surface::fill(float red, float green, float blue, float alpha)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1181,7 +1204,7 @@ void Surface::fill(float red, float green, float blue, float alpha)
void Surface::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1220,7 +1243,7 @@ void Surface::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
// Once you have M quantized, you would compute the corresponding RGB and quantize that.
void Surface::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1288,7 +1311,7 @@ void Surface::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
void Surface::fromRGBM(float range/*= 1*/)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1557,7 +1580,7 @@ void Surface::fromRGBE(int mantissaBits, int exponentBits)
// Y is in the [0, 1] range, while CoCg are in the [-1, 1] range.
void Surface::toYCoCg()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1594,7 +1617,7 @@ void Surface::toYCoCg()
// and minimize bilinear interpolation artifacts.
void Surface::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
{
if (m->image == NULL || m->image->depth() != 1) return;
if (isNull() || depth() != 1) return;
detach();
@ -1652,7 +1675,7 @@ void Surface::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
void Surface::fromYCoCg()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1685,7 +1708,7 @@ void Surface::fromYCoCg()
void Surface::toLUVW(float range/*= 1.0f*/)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1720,7 +1743,7 @@ void Surface::fromLUVW(float range/*= 1.0f*/)
void Surface::abs(int channel)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1735,7 +1758,7 @@ void Surface::abs(int channel)
void Surface::convolve(int channel, int kernelSize, float * kernelData)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1746,7 +1769,7 @@ void Surface::convolve(int channel, int kernelSize, float * kernelData)
/*
void Surface::blockLuminanceScale(float scale)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1821,7 +1844,7 @@ void Surface::blockLuminanceScale(float scale)
/*
void Surface::toJPEGLS()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1844,7 +1867,7 @@ void Surface::toJPEGLS()
void Surface::fromJPEGLS()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1870,7 +1893,7 @@ void Surface::fromJPEGLS()
// If dither is true, this uses Floyd-Steinberg dithering method.
void Surface::binarize(int channel, float threshold, bool dither)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1933,7 +1956,7 @@ void Surface::binarize(int channel, float threshold, bool dither)
// When dither is true, this uses Floyd-Steinberg dithering.
void Surface::quantize(int channel, int bits, bool exactEndPoints, bool dither)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2004,7 +2027,7 @@ void Surface::quantize(int channel, int bits, bool exactEndPoints, bool dither)
// Set normal map options.
void Surface::toNormalMap(float sm, float medium, float big, float large)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2023,7 +2046,7 @@ void Surface::toNormalMap(float sm, float medium, float big, float large)
void Surface::normalizeNormalMap()
{
if (m->image == NULL) return;
if (isNull()) return;
if (!m->isNormalMap) return;
detach();
@ -2033,7 +2056,7 @@ void Surface::normalizeNormalMap()
void Surface::transformNormals(NormalTransform xform)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2106,7 +2129,7 @@ void Surface::transformNormals(NormalTransform xform)
void Surface::reconstructNormals(NormalTransform xform)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2155,7 +2178,7 @@ void Surface::reconstructNormals(NormalTransform xform)
void Surface::toCleanNormalMap()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2174,14 +2197,14 @@ void Surface::toCleanNormalMap()
// [-1,1] -> [ 0,1]
void Surface::packNormals() {
if (m->image == NULL) return;
if (isNull()) return;
detach();
m->image->packNormals(0);
}
// [ 0,1] -> [-1,1]
void Surface::expandNormals() {
if (m->image == NULL) return;
if (isNull()) return;
detach();
m->image->expandNormals(0);
}
@ -2189,7 +2212,7 @@ void Surface::expandNormals() {
void Surface::flipX()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2198,7 +2221,7 @@ void Surface::flipX()
void Surface::flipY()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2207,7 +2230,7 @@ void Surface::flipY()
void Surface::flipZ()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2233,6 +2256,8 @@ bool Surface::copyChannel(const Surface & srcImage, int srcChannel, int dstChann
detach();
dst = m->image;
memcpy(dst->channel(dstChannel), src->channel(srcChannel), dst->pixelCount()*sizeof(float));
return true;
@ -2252,6 +2277,8 @@ bool Surface::addChannel(const Surface & srcImage, int srcChannel, int dstChanne
detach();
dst = m->image;
const uint w = src->width();
const uint h = src->height();

@ -350,6 +350,7 @@ namespace nvtt
NVTT_API void reset();
NVTT_API void setFileName(const char * fileName);
NVTT_API void setFileHandle(void * fp);
NVTT_API void setOutputHandler(OutputHandler * outputHandler);
NVTT_API void setErrorHandler(ErrorHandler * errorHandler);
@ -464,6 +465,7 @@ namespace nvtt
NVTT_API void toLinear(float gamma);
NVTT_API void toGamma(float gamma);
NVTT_API void toSrgb();
NVTT_API void toLinearFromSrgb();
NVTT_API void toXenonSrgb();
NVTT_API void transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4]);
NVTT_API void swizzle(int r, int g, int b, int a);
@ -564,6 +566,8 @@ namespace nvtt
// @@ Add edge fixup methods.
NVTT_API float average(int channel) const;
// Filtering.
NVTT_API CubeSurface irradianceFilter(int size) const;
NVTT_API CubeSurface cosinePowerFilter(int size, float cosinePower) const;

Loading…
Cancel
Save