Merge changes from the witness.

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

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

@ -70,15 +70,11 @@ namespace nv
b = temp; 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> template <typename T>
inline const T & max(const T & a, const T & b) inline const T & max(const T & a, const T & b)
{ {
//return std::max(a, b); return (b < a) ? a : b;
if( a < b ) {
return b;
}
return a;
} }
/// Return the maximum of the three arguments. /// Return the maximum of the three arguments.
@ -92,11 +88,7 @@ namespace nv
template <typename T> template <typename T>
inline const T & min(const T & a, const T & b) inline const T & min(const T & a, const T & b)
{ {
//return std::min(a, b); return (a < b) ? a : b;
if( b < a ) {
return b;
}
return a;
} }
/// Return the maximum of the three arguments. /// 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> // Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, // restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell // copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
// //
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
#ifndef NV_IMAGE_BLOCKDXT_H #ifndef NV_IMAGE_BLOCKDXT_H
#define NV_IMAGE_BLOCKDXT_H #define NV_IMAGE_BLOCKDXT_H
#include "nvimage.h" #include "nvimage.h"
#include "nvmath/Color.h" #include "nvmath/Color.h"
namespace nv namespace nv
{ {
struct ColorBlock; struct ColorBlock;
class Stream; class Stream;
/// DXT1 block. /// DXT1 block.
struct BlockDXT1 struct BlockDXT1
{ {
Color16 col0; Color16 col0;
Color16 col1; Color16 col1;
union { union {
uint8 row[4]; uint8 row[4];
uint indices; uint indices;
}; };
bool isFourColorMode() const; bool isFourColorMode() const;
uint evaluatePalette(Color32 color_array[4], bool d3d9) const; uint evaluatePalette(Color32 color_array[4], bool d3d9) const;
uint evaluatePaletteNV5x(Color32 color_array[4]) const; uint evaluatePaletteNV5x(Color32 color_array[4]) const;
void evaluatePalette3(Color32 color_array[4], bool d3d9) const; void evaluatePalette3(Color32 color_array[4], bool d3d9) const;
void evaluatePalette4(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 decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const; void decodeBlockNV5x(ColorBlock * block) const;
void setIndices(int * idx); void setIndices(int * idx);
void flip4(); void flip4();
void flip2(); void flip2();
}; };
/// Return true if the block uses four color mode, false otherwise. /// Return true if the block uses four color mode, false otherwise.
inline bool BlockDXT1::isFourColorMode() const inline bool BlockDXT1::isFourColorMode() const
{ {
return col0.u > col1.u; return col0.u > col1.u;
} }
/// DXT3 alpha block with explicit alpha. /// DXT3 alpha block with explicit alpha.
struct AlphaBlockDXT3 struct AlphaBlockDXT3
{ {
union { union {
struct { struct {
uint alpha0 : 4; uint alpha0 : 4;
uint alpha1 : 4; uint alpha1 : 4;
uint alpha2 : 4; uint alpha2 : 4;
uint alpha3 : 4; uint alpha3 : 4;
uint alpha4 : 4; uint alpha4 : 4;
uint alpha5 : 4; uint alpha5 : 4;
uint alpha6 : 4; uint alpha6 : 4;
uint alpha7 : 4; uint alpha7 : 4;
uint alpha8 : 4; uint alpha8 : 4;
uint alpha9 : 4; uint alpha9 : 4;
uint alphaA : 4; uint alphaA : 4;
uint alphaB : 4; uint alphaB : 4;
uint alphaC : 4; uint alphaC : 4;
uint alphaD : 4; uint alphaD : 4;
uint alphaE : 4; uint alphaE : 4;
uint alphaF : 4; uint alphaF : 4;
}; };
uint16 row[4]; uint16 row[4];
}; };
void decodeBlock(ColorBlock * block, bool d3d9 = false) const; void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4(); void flip4();
void flip2(); void flip2();
}; };
/// DXT3 block. /// DXT3 block.
struct BlockDXT3 struct BlockDXT3
{ {
AlphaBlockDXT3 alpha; AlphaBlockDXT3 alpha;
BlockDXT1 color; BlockDXT1 color;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const; void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const; void decodeBlockNV5x(ColorBlock * block) const;
void flip4(); void flip4();
void flip2(); void flip2();
}; };
/// DXT5 alpha block. /// DXT5 alpha block.
struct AlphaBlockDXT5 struct AlphaBlockDXT5
{ {
union { union {
struct { struct {
uint64 alpha0 : 8; // 8 uint64 alpha0 : 8; // 8
uint64 alpha1 : 8; // 16 uint64 alpha1 : 8; // 16
uint64 bits0 : 3; // 3 - 19 uint64 bits0 : 3; // 3 - 19
uint64 bits1 : 3; // 6 - 22 uint64 bits1 : 3; // 6 - 22
uint64 bits2 : 3; // 9 - 25 uint64 bits2 : 3; // 9 - 25
uint64 bits3 : 3; // 12 - 28 uint64 bits3 : 3; // 12 - 28
uint64 bits4 : 3; // 15 - 31 uint64 bits4 : 3; // 15 - 31
uint64 bits5 : 3; // 18 - 34 uint64 bits5 : 3; // 18 - 34
uint64 bits6 : 3; // 21 - 37 uint64 bits6 : 3; // 21 - 37
uint64 bits7 : 3; // 24 - 40 uint64 bits7 : 3; // 24 - 40
uint64 bits8 : 3; // 27 - 43 uint64 bits8 : 3; // 27 - 43
uint64 bits9 : 3; // 30 - 46 uint64 bits9 : 3; // 30 - 46
uint64 bitsA : 3; // 33 - 49 uint64 bitsA : 3; // 33 - 49
uint64 bitsB : 3; // 36 - 52 uint64 bitsB : 3; // 36 - 52
uint64 bitsC : 3; // 39 - 55 uint64 bitsC : 3; // 39 - 55
uint64 bitsD : 3; // 42 - 58 uint64 bitsD : 3; // 42 - 58
uint64 bitsE : 3; // 45 - 61 uint64 bitsE : 3; // 45 - 61
uint64 bitsF : 3; // 48 - 64 uint64 bitsF : 3; // 48 - 64
}; };
uint64 u; uint64 u;
}; };
void evaluatePalette(uint8 alpha[8], bool d3d9) const; void evaluatePalette(uint8 alpha[8], bool d3d9) const;
void evaluatePalette8(uint8 alpha[8], bool d3d9) const; void evaluatePalette8(uint8 alpha[8], bool d3d9) const;
void evaluatePalette6(uint8 alpha[8], bool d3d9) const; void evaluatePalette6(uint8 alpha[8], bool d3d9) const;
void indices(uint8 index_array[16]) const; void indices(uint8 index_array[16]) const;
uint index(uint index) const; uint index(uint index) const;
void setIndex(uint index, uint value); void setIndex(uint index, uint value);
void decodeBlock(ColorBlock * block, bool d3d9 = false) const; void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4(); void flip4();
void flip2(); void flip2();
}; };
/// DXT5 block. /// DXT5 block.
struct BlockDXT5 struct BlockDXT5
{ {
AlphaBlockDXT5 alpha; AlphaBlockDXT5 alpha;
BlockDXT1 color; BlockDXT1 color;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const; void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void decodeBlockNV5x(ColorBlock * block) const; void decodeBlockNV5x(ColorBlock * block) const;
void flip4(); void flip4();
void flip2(); void flip2();
}; };
/// ATI1 block. /// ATI1 block.
struct BlockATI1 struct BlockATI1
{ {
AlphaBlockDXT5 alpha; AlphaBlockDXT5 alpha;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const; void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4(); void flip4();
void flip2(); void flip2();
}; };
/// ATI2 block. /// ATI2 block.
struct BlockATI2 struct BlockATI2
{ {
AlphaBlockDXT5 x; AlphaBlockDXT5 x;
AlphaBlockDXT5 y; AlphaBlockDXT5 y;
void decodeBlock(ColorBlock * block, bool d3d9 = false) const; void decodeBlock(ColorBlock * block, bool d3d9 = false) const;
void flip4(); void flip4();
void flip2(); void flip2();
}; };
/// CTX1 block. /// CTX1 block.
struct BlockCTX1 struct BlockCTX1
{ {
uint8 col0[2]; uint8 col0[2];
uint8 col1[2]; uint8 col1[2];
union { union {
uint8 row[4]; uint8 row[4];
uint indices; uint indices;
}; };
void evaluatePalette(Color32 color_array[4]) const; void evaluatePalette(Color32 color_array[4]) const;
void setIndices(int * idx); void setIndices(int * idx);
void decodeBlock(ColorBlock * block) const; void decodeBlock(ColorBlock * block) const;
void flip4(); void flip4();
void flip2(); void flip2();
}; };
// Serialization functions. // Serialization functions.
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT1 & block); NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT1 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT3 & block); NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT3 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT3 & block); NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT3 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT5 & block); NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT5 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT5 & block); NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT5 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI1 & block); NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI1 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI2 & block); NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI2 & block);
NVIMAGE_API Stream & operator<<(Stream & stream, BlockCTX1 & block); NVIMAGE_API Stream & operator<<(Stream & stream, BlockCTX1 & block);
} // nv namespace } // nv namespace
#endif // NV_IMAGE_BLOCKDXT_H #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 // This code is in the public domain -- castanyo@yahoo.es
#pragma once #pragma once
#ifndef NV_IMAGE_COLORBLOCK_H #ifndef NV_IMAGE_COLORBLOCK_H
#define NV_IMAGE_COLORBLOCK_H #define NV_IMAGE_COLORBLOCK_H
#include "nvmath/Color.h" #include "nvmath/Color.h"
#include "nvmath/Vector.h" #include "nvmath/Vector.h"
namespace nv namespace nv
{ {
class Image; class Image;
class FloatImage; class FloatImage;
/// Uncompressed 4x4 color block. /// Uncompressed 4x4 color block.
struct ColorBlock struct ColorBlock
{ {
ColorBlock(); ColorBlock();
ColorBlock(const uint * linearImage); ColorBlock(const uint * linearImage);
ColorBlock(const ColorBlock & block); ColorBlock(const ColorBlock & block);
ColorBlock(const Image * img, uint x, uint y); ColorBlock(const Image * img, uint x, uint y);
void init(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 uint * data, uint x, uint y);
void init(uint w, uint h, const float * 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 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 isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
bool hasAlpha() const; bool hasAlpha() const;
// Accessors // Accessors
const Color32 * colors() const; const Color32 * colors() const;
Color32 color(uint i) const; Color32 color(uint i) const;
Color32 & color(uint i); Color32 & color(uint i);
Color32 color(uint x, uint y) const; Color32 color(uint x, uint y) const;
Color32 & color(uint x, uint y); Color32 & color(uint x, uint y);
private: private:
Color32 m_color[4*4]; Color32 m_color[4*4];
}; };
/// Get pointer to block colors. /// Get pointer to block colors.
inline const Color32 * ColorBlock::colors() const inline const Color32 * ColorBlock::colors() const
{ {
return m_color; return m_color;
} }
/// Get block color. /// Get block color.
inline Color32 ColorBlock::color(uint i) const inline Color32 ColorBlock::color(uint i) const
{ {
nvDebugCheck(i < 16); nvDebugCheck(i < 16);
return m_color[i]; return m_color[i];
} }
/// Get block color. /// Get block color.
inline Color32 & ColorBlock::color(uint i) inline Color32 & ColorBlock::color(uint i)
{ {
nvDebugCheck(i < 16); nvDebugCheck(i < 16);
return m_color[i]; return m_color[i];
} }
/// Get block color. /// Get block color.
inline Color32 ColorBlock::color(uint x, uint y) const inline Color32 ColorBlock::color(uint x, uint y) const
{ {
nvDebugCheck(x < 4 && y < 4); nvDebugCheck(x < 4 && y < 4);
return m_color[y * 4 + x]; return m_color[y * 4 + x];
} }
/// Get block color. /// Get block color.
inline Color32 & ColorBlock::color(uint x, uint y) inline Color32 & ColorBlock::color(uint x, uint y)
{ {
nvDebugCheck(x < 4 && y < 4); nvDebugCheck(x < 4 && y < 4);
return m_color[y * 4 + x]; return m_color[y * 4 + x];
} }
struct ColorSet struct ColorSet
{ {
void setColors(const float * data, uint img_w, uint img_h, uint img_x, uint img_y); void setColors(const float * data, uint img_w, uint img_h, uint img_x, uint img_y);
void setAlphaWeights(); void setAlphaWeights();
void setUniformWeights(); void setUniformWeights();
void createMinimalSet(bool ignoreTransparent); void createMinimalSet(bool ignoreTransparent);
void wrapIndices(); void wrapIndices();
void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0 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 isSingleColor(bool ignoreAlpha) const;
bool hasAlpha() const; bool hasAlpha() const;
// These methods require indices to be set: // 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) 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 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) const { nvDebugCheck(i < 16); return colors[remap[i]]; }
Vector4 & color(uint i) { nvDebugCheck(i < 16); return colors[remap[i]]; } Vector4 & color(uint i) { nvDebugCheck(i < 16); return colors[remap[i]]; }
uint count; uint count;
uint w, h; uint w, h;
Vector4 colors[16]; Vector4 colors[16];
float weights[16]; float weights[16];
int remap[16]; int remap[16];
}; };
} // nv namespace } // nv namespace
#endif // NV_IMAGE_COLORBLOCK_H #endif // NV_IMAGE_COLORBLOCK_H

@ -1,10 +1,10 @@
// This code is in the public domain -- jim@tilander.org // This code is in the public domain -- jim@tilander.org
#include <nvcore/nvcore.h> #include <nvcore/nvcore.h>
#include <nvmath/Color.h> #include <nvmath/Color.h>
#include <nvimage/Image.h> #include <nvimage/Image.h>
#include "ColorSpace.h" #include "ColorSpace.h"
namespace nv 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> // Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, // restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell // copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
// //
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
#ifndef NV_IMAGE_DIRECTDRAWSURFACE_H #ifndef NV_IMAGE_DIRECTDRAWSURFACE_H
#define NV_IMAGE_DIRECTDRAWSURFACE_H #define NV_IMAGE_DIRECTDRAWSURFACE_H
#include "nvimage.h" #include "nvimage.h"
#if !defined(MAKEFOURCC) #if !defined(MAKEFOURCC)
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ #define MAKEFOURCC(ch0, ch1, ch2, ch3) \
(uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \ (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
(uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 )) (uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
#endif #endif
namespace nv namespace nv
{ {
class Image; class Image;
class Stream; class Stream;
struct ColorBlock; struct ColorBlock;
extern const uint FOURCC_NVTT; extern const uint FOURCC_NVTT;
extern const uint FOURCC_DDS; extern const uint FOURCC_DDS;
extern const uint FOURCC_DXT1; extern const uint FOURCC_DXT1;
extern const uint FOURCC_DXT2; extern const uint FOURCC_DXT2;
extern const uint FOURCC_DXT3; extern const uint FOURCC_DXT3;
extern const uint FOURCC_DXT4; extern const uint FOURCC_DXT4;
extern const uint FOURCC_DXT5; extern const uint FOURCC_DXT5;
extern const uint FOURCC_RXGB; extern const uint FOURCC_RXGB;
extern const uint FOURCC_ATI1; extern const uint FOURCC_ATI1;
extern const uint FOURCC_ATI2; extern const uint FOURCC_ATI2;
enum DDPF enum DDPF
{ {
DDPF_ALPHAPIXELS = 0x00000001U, DDPF_ALPHAPIXELS = 0x00000001U,
DDPF_ALPHA = 0x00000002U, DDPF_ALPHA = 0x00000002U,
DDPF_FOURCC = 0x00000004U, DDPF_FOURCC = 0x00000004U,
DDPF_RGB = 0x00000040U, DDPF_RGB = 0x00000040U,
DDPF_PALETTEINDEXED1 = 0x00000800U, DDPF_PALETTEINDEXED1 = 0x00000800U,
DDPF_PALETTEINDEXED2 = 0x00001000U, DDPF_PALETTEINDEXED2 = 0x00001000U,
DDPF_PALETTEINDEXED4 = 0x00000008U, DDPF_PALETTEINDEXED4 = 0x00000008U,
DDPF_PALETTEINDEXED8 = 0x00000020U, DDPF_PALETTEINDEXED8 = 0x00000020U,
DDPF_LUMINANCE = 0x00020000U, DDPF_LUMINANCE = 0x00020000U,
DDPF_ALPHAPREMULT = 0x00008000U, DDPF_ALPHAPREMULT = 0x00008000U,
// Custom NVTT flags. // Custom NVTT flags.
DDPF_NORMAL = 0x80000000U, DDPF_NORMAL = 0x80000000U,
DDPF_SRGB = 0x40000000U, DDPF_SRGB = 0x40000000U,
}; };
enum D3DFORMAT enum D3DFORMAT
{ {
// 32 bit RGB formats. // 32 bit RGB formats.
D3DFMT_R8G8B8 = 20, D3DFMT_R8G8B8 = 20,
D3DFMT_A8R8G8B8 = 21, D3DFMT_A8R8G8B8 = 21,
D3DFMT_X8R8G8B8 = 22, D3DFMT_X8R8G8B8 = 22,
D3DFMT_R5G6B5 = 23, D3DFMT_R5G6B5 = 23,
D3DFMT_X1R5G5B5 = 24, D3DFMT_X1R5G5B5 = 24,
D3DFMT_A1R5G5B5 = 25, D3DFMT_A1R5G5B5 = 25,
D3DFMT_A4R4G4B4 = 26, D3DFMT_A4R4G4B4 = 26,
D3DFMT_R3G3B2 = 27, D3DFMT_R3G3B2 = 27,
D3DFMT_A8 = 28, D3DFMT_A8 = 28,
D3DFMT_A8R3G3B2 = 29, D3DFMT_A8R3G3B2 = 29,
D3DFMT_X4R4G4B4 = 30, D3DFMT_X4R4G4B4 = 30,
D3DFMT_A2B10G10R10 = 31, D3DFMT_A2B10G10R10 = 31,
D3DFMT_A8B8G8R8 = 32, D3DFMT_A8B8G8R8 = 32,
D3DFMT_X8B8G8R8 = 33, D3DFMT_X8B8G8R8 = 33,
D3DFMT_G16R16 = 34, D3DFMT_G16R16 = 34,
D3DFMT_A2R10G10B10 = 35, D3DFMT_A2R10G10B10 = 35,
D3DFMT_A16B16G16R16 = 36, D3DFMT_A16B16G16R16 = 36,
// Palette formats. // Palette formats.
D3DFMT_A8P8 = 40, D3DFMT_A8P8 = 40,
D3DFMT_P8 = 41, D3DFMT_P8 = 41,
// Luminance formats. // Luminance formats.
D3DFMT_L8 = 50, D3DFMT_L8 = 50,
D3DFMT_A8L8 = 51, D3DFMT_A8L8 = 51,
D3DFMT_A4L4 = 52, D3DFMT_A4L4 = 52,
D3DFMT_L16 = 81, D3DFMT_L16 = 81,
// Floating point formats // Floating point formats
D3DFMT_R16F = 111, D3DFMT_R16F = 111,
D3DFMT_G16R16F = 112, D3DFMT_G16R16F = 112,
D3DFMT_A16B16G16R16F = 113, D3DFMT_A16B16G16R16F = 113,
D3DFMT_R32F = 114, D3DFMT_R32F = 114,
D3DFMT_G32R32F = 115, D3DFMT_G32R32F = 115,
D3DFMT_A32B32G32R32F = 116, D3DFMT_A32B32G32R32F = 116,
}; };
// D3D1x resource dimensions. // D3D1x resource dimensions.
enum D3D10_RESOURCE_DIMENSION enum D3D10_RESOURCE_DIMENSION
{ {
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1, D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2, D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3, D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4, D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
}; };
// DXGI formats. // DXGI formats.
enum DXGI_FORMAT enum DXGI_FORMAT
{ {
DXGI_FORMAT_UNKNOWN = 0, DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2, DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3, DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4, DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5, DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6, DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7, DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8, DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10, DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11, DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12, DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13, DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14, DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15, DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16, DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17, DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18, DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19, DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24, DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25, DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26, DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28, DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30, DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31, DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32, DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33, DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34, DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35, DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36, DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37, DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38, DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39, DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40, DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41, DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42, DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43, DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44, DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45, DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48, DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49, DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50, DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51, DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52, DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53, DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54, DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55, DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56, DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57, DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58, DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59, DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60, DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61, DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62, DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63, DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64, DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65, DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66, DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68, DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69, DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70, DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71, DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72, DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73, DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74, DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75, DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76, DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77, DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78, DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79, DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80, DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81, DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82, DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83, DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84, DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85, DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86, DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87, DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88, DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94, DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95, DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96, DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97, DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98, DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99, DXGI_FORMAT_BC7_UNORM_SRGB = 99,
}; };
extern uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask); extern uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
struct NVIMAGE_CLASS DDSPixelFormat struct NVIMAGE_CLASS DDSPixelFormat
{ {
uint size; uint size;
uint flags; uint flags;
uint fourcc; uint fourcc;
uint bitcount; uint bitcount;
uint rmask; uint rmask;
uint gmask; uint gmask;
uint bmask; uint bmask;
uint amask; uint amask;
}; };
struct NVIMAGE_CLASS DDSCaps struct NVIMAGE_CLASS DDSCaps
{ {
uint caps1; uint caps1;
uint caps2; uint caps2;
uint caps3; uint caps3;
uint caps4; uint caps4;
}; };
/// DDS file header for DX10. /// DDS file header for DX10.
struct NVIMAGE_CLASS DDSHeader10 struct NVIMAGE_CLASS DDSHeader10
{ {
uint dxgiFormat; uint dxgiFormat;
uint resourceDimension; uint resourceDimension;
uint miscFlag; uint miscFlag;
uint arraySize; uint arraySize;
uint reserved; uint reserved;
}; };
/// DDS file header. /// DDS file header.
struct NVIMAGE_CLASS DDSHeader struct NVIMAGE_CLASS DDSHeader
{ {
uint fourcc; uint fourcc;
uint size; uint size;
uint flags; uint flags;
uint height; uint height;
uint width; uint width;
uint pitch; uint pitch;
uint depth; uint depth;
uint mipmapcount; uint mipmapcount;
uint reserved[11]; uint reserved[11];
DDSPixelFormat pf; DDSPixelFormat pf;
DDSCaps caps; DDSCaps caps;
uint notused; uint notused;
DDSHeader10 header10; DDSHeader10 header10;
// Helper methods. // Helper methods.
DDSHeader(); DDSHeader();
void setWidth(uint w); void setWidth(uint w);
void setHeight(uint h); void setHeight(uint h);
void setDepth(uint d); void setDepth(uint d);
void setMipmapCount(uint count); void setMipmapCount(uint count);
void setTexture2D(); void setTexture2D();
void setTexture3D(); void setTexture3D();
void setTextureCube(); void setTextureCube();
void setLinearSize(uint size); void setLinearSize(uint size);
void setPitch(uint pitch); void setPitch(uint pitch);
void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3); void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
void setFormatCode(uint code); void setFormatCode(uint code);
void setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3); void setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask); void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
void setDX10Format(uint format); void setDX10Format(uint format);
void setNormalFlag(bool b); void setNormalFlag(bool b);
void setSrgbFlag(bool b); void setSrgbFlag(bool b);
void setHasAlphaFlag(bool b); void setHasAlphaFlag(bool b);
void setUserVersion(int version); void setUserVersion(int version);
void swapBytes(); void swapBytes();
bool hasDX10Header() const; bool hasDX10Header() const;
uint signature() const; uint signature() const;
uint toolVersion() const; uint toolVersion() const;
uint userVersion() const; uint userVersion() const;
bool isNormalMap() const; bool isNormalMap() const;
bool isSrgb() const; bool isSrgb() const;
bool hasAlpha() const; bool hasAlpha() const;
uint d3d9Format() const; uint d3d9Format() const;
uint pixelSize() const; // In bits! uint pixelSize() const; // In bits!
uint blockSize() const; // In bytes! uint blockSize() const; // In bytes!
bool isBlockFormat() const; bool isBlockFormat() const;
}; };
NVIMAGE_API Stream & operator<< (Stream & s, DDSHeader & header); NVIMAGE_API Stream & operator<< (Stream & s, DDSHeader & header);
/// DirectDraw Surface. (DDS) /// DirectDraw Surface. (DDS)
class NVIMAGE_CLASS DirectDrawSurface class NVIMAGE_CLASS DirectDrawSurface
{ {
public: public:
DirectDrawSurface(); DirectDrawSurface();
DirectDrawSurface(const char * file); DirectDrawSurface(const char * file);
DirectDrawSurface(Stream * stream); DirectDrawSurface(Stream * stream);
~DirectDrawSurface(); ~DirectDrawSurface();
bool load(const char * filename); bool load(const char * filename);
bool load(Stream * stream); bool load(Stream * stream);
bool isValid() const; bool isValid() const;
bool isSupported() const; bool isSupported() const;
bool hasAlpha() const; bool hasAlpha() const;
uint mipmapCount() const; uint mipmapCount() const;
uint width() const; uint width() const;
uint height() const; uint height() const;
uint depth() const; uint depth() const;
bool isTexture1D() const; bool isTexture1D() const;
bool isTexture2D() const; bool isTexture2D() const;
bool isTexture3D() const; bool isTexture3D() const;
bool isTextureCube() const; bool isTextureCube() const;
void setNormalFlag(bool b); void setNormalFlag(bool b);
void setHasAlphaFlag(bool b); void setHasAlphaFlag(bool b);
void setUserVersion(int version); void setUserVersion(int version);
void mipmap(Image * img, uint f, uint m); void mipmap(Image * img, uint f, uint m);
uint surfaceWidth(uint mipmap) const; uint surfaceWidth(uint mipmap) const;
uint surfaceHeight(uint mipmap) const; uint surfaceHeight(uint mipmap) const;
uint surfaceDepth(uint mipmap) const; uint surfaceDepth(uint mipmap) const;
uint surfaceSize(uint mipmap) const; uint surfaceSize(uint mipmap) const;
bool readSurface(uint face, uint mipmap, void * data, uint size); bool readSurface(uint face, uint mipmap, void * data, uint size);
void printInfo() const; void printInfo() const;
// Only initialized after loading. // Only initialized after loading.
DDSHeader header; DDSHeader header;
private: private:
uint faceSize() const; uint faceSize() const;
uint offset(uint face, uint mipmap); uint offset(uint face, uint mipmap);
void readLinearImage(Image * img); void readLinearImage(Image * img);
void readBlockImage(Image * img); void readBlockImage(Image * img);
void readBlock(ColorBlock * rgba); void readBlock(ColorBlock * rgba);
private: private:
Stream * stream; Stream * stream;
}; };
} // nv namespace } // nv namespace
#endif // NV_IMAGE_DIRECTDRAWSURFACE_H #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 // This code is in the public domain -- castanyo@yahoo.es
#pragma once #pragma once
#ifndef NV_IMAGE_FILTER_H #ifndef NV_IMAGE_FILTER_H
#define NV_IMAGE_FILTER_H #define NV_IMAGE_FILTER_H
#include "nvimage.h" #include "nvimage.h"
#include "nvcore/Debug.h" #include "nvcore/Debug.h"
namespace nv namespace nv
{ {
class Vector4; class Vector4;
/// Base filter class. /// Base filter class.
class NVIMAGE_CLASS Filter class NVIMAGE_CLASS Filter
{ {
public: public:
Filter(float width); Filter(float width);
virtual ~Filter(); virtual ~Filter();
float width() const { return m_width; } float width() const { return m_width; }
float sampleDelta(float x, float scale) const; float sampleDelta(float x, float scale) const;
float sampleBox(float x, float scale, int samples) const; float sampleBox(float x, float scale, int samples) const;
float sampleTriangle(float x, float scale, int samples) const; float sampleTriangle(float x, float scale, int samples) const;
virtual float evaluate(float x) const = 0; virtual float evaluate(float x) const = 0;
protected: protected:
const float m_width; const float m_width;
}; };
// Box filter. // Box filter.
class NVIMAGE_CLASS BoxFilter : public Filter class NVIMAGE_CLASS BoxFilter : public Filter
{ {
public: public:
BoxFilter(); BoxFilter();
BoxFilter(float width); BoxFilter(float width);
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
}; };
// Triangle (bilinear/tent) filter. // Triangle (bilinear/tent) filter.
class NVIMAGE_CLASS TriangleFilter : public Filter class NVIMAGE_CLASS TriangleFilter : public Filter
{ {
public: public:
TriangleFilter(); TriangleFilter();
TriangleFilter(float width); TriangleFilter(float width);
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
}; };
// Quadratic (bell) filter. // Quadratic (bell) filter.
class NVIMAGE_CLASS QuadraticFilter : public Filter class NVIMAGE_CLASS QuadraticFilter : public Filter
{ {
public: public:
QuadraticFilter(); QuadraticFilter();
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
}; };
// Cubic filter from Thatcher Ulrich. // Cubic filter from Thatcher Ulrich.
class NVIMAGE_CLASS CubicFilter : public Filter class NVIMAGE_CLASS CubicFilter : public Filter
{ {
public: public:
CubicFilter(); CubicFilter();
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
}; };
// Cubic b-spline filter from Paul Heckbert. // Cubic b-spline filter from Paul Heckbert.
class NVIMAGE_CLASS BSplineFilter : public Filter class NVIMAGE_CLASS BSplineFilter : public Filter
{ {
public: public:
BSplineFilter(); BSplineFilter();
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
}; };
/// Mitchell & Netravali's two-param cubic /// Mitchell & Netravali's two-param cubic
/// @see "Reconstruction Filters in Computer Graphics", SIGGRAPH 88 /// @see "Reconstruction Filters in Computer Graphics", SIGGRAPH 88
class NVIMAGE_CLASS MitchellFilter : public Filter class NVIMAGE_CLASS MitchellFilter : public Filter
{ {
public: public:
MitchellFilter(); MitchellFilter();
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
void setParameters(float b, float c); void setParameters(float b, float c);
private: private:
float p0, p2, p3; float p0, p2, p3;
float q0, q1, q2, q3; float q0, q1, q2, q3;
}; };
// Lanczos3 filter. // Lanczos3 filter.
class NVIMAGE_CLASS LanczosFilter : public Filter class NVIMAGE_CLASS LanczosFilter : public Filter
{ {
public: public:
LanczosFilter(); LanczosFilter();
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
}; };
// Sinc filter. // Sinc filter.
class NVIMAGE_CLASS SincFilter : public Filter class NVIMAGE_CLASS SincFilter : public Filter
{ {
public: public:
SincFilter(float w); SincFilter(float w);
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
}; };
// Kaiser filter. // Kaiser filter.
class NVIMAGE_CLASS KaiserFilter : public Filter class NVIMAGE_CLASS KaiserFilter : public Filter
{ {
public: public:
KaiserFilter(float w); KaiserFilter(float w);
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
void setParameters(float a, float stretch); void setParameters(float a, float stretch);
private: private:
float alpha; float alpha;
float stretch; float stretch;
}; };
// Gaussian filter. // Gaussian filter.
class GaussianFilter : public Filter class GaussianFilter : public Filter
{ {
public: public:
GaussianFilter(float w); GaussianFilter(float w);
virtual float evaluate(float x) const; virtual float evaluate(float x) const;
void setParameters(float variance); void setParameters(float variance);
private: private:
float variance; float variance;
}; };
/// A 1D kernel. Used to precompute filter weights. /// A 1D kernel. Used to precompute filter weights.
class NVIMAGE_CLASS Kernel1 class NVIMAGE_CLASS Kernel1
{ {
NV_FORBID_COPY(Kernel1); NV_FORBID_COPY(Kernel1);
public: public:
Kernel1(const Filter & f, int iscale, int samples = 32); Kernel1(const Filter & f, int iscale, int samples = 32);
~Kernel1(); ~Kernel1();
float valueAt(uint x) const { float valueAt(uint x) const {
nvDebugCheck(x < (uint)m_windowSize); nvDebugCheck(x < (uint)m_windowSize);
return m_data[x]; return m_data[x];
} }
int windowSize() const { int windowSize() const {
return m_windowSize; return m_windowSize;
} }
float width() const { float width() const {
return m_width; return m_width;
} }
void debugPrint(); void debugPrint();
private: private:
int m_windowSize; int m_windowSize;
float m_width; float m_width;
float * m_data; float * m_data;
}; };
/// A 2D kernel. /// A 2D kernel.
class NVIMAGE_CLASS Kernel2 class NVIMAGE_CLASS Kernel2
{ {
public: public:
Kernel2(uint width); Kernel2(uint width);
Kernel2(uint width, const float * data); Kernel2(uint width, const float * data);
Kernel2(const Kernel2 & k); Kernel2(const Kernel2 & k);
~Kernel2(); ~Kernel2();
void normalize(); void normalize();
void transpose(); void transpose();
float valueAt(uint x, uint y) const { float valueAt(uint x, uint y) const {
return m_data[y * m_windowSize + x]; return m_data[y * m_windowSize + x];
} }
uint windowSize() const { uint windowSize() const {
return m_windowSize; return m_windowSize;
} }
void initLaplacian(); void initLaplacian();
void initEdgeDetection(); void initEdgeDetection();
void initSobel(); void initSobel();
void initPrewitt(); void initPrewitt();
void initBlendedSobel(const Vector4 & scale); void initBlendedSobel(const Vector4 & scale);
private: private:
const uint m_windowSize; const uint m_windowSize;
float * m_data; float * m_data;
}; };
/// A 1D polyphase kernel /// A 1D polyphase kernel
class NVIMAGE_CLASS PolyphaseKernel class NVIMAGE_CLASS PolyphaseKernel
{ {
NV_FORBID_COPY(PolyphaseKernel); NV_FORBID_COPY(PolyphaseKernel);
public: public:
PolyphaseKernel(const Filter & f, uint srcLength, uint dstLength, int samples = 32); PolyphaseKernel(const Filter & f, uint srcLength, uint dstLength, int samples = 32);
~PolyphaseKernel(); ~PolyphaseKernel();
int windowSize() const { int windowSize() const {
return m_windowSize; return m_windowSize;
} }
uint length() const { uint length() const {
return m_length; return m_length;
} }
float width() const { float width() const {
return m_width; return m_width;
} }
float valueAt(uint column, uint x) const { float valueAt(uint column, uint x) const {
nvDebugCheck(column < m_length); nvDebugCheck(column < m_length);
nvDebugCheck(x < (uint)m_windowSize); nvDebugCheck(x < (uint)m_windowSize);
return m_data[column * m_windowSize + x]; return m_data[column * m_windowSize + x];
} }
void debugPrint() const; void debugPrint() const;
private: private:
int m_windowSize; int m_windowSize;
uint m_length; uint m_length;
float m_width; float m_width;
float * m_data; float * m_data;
}; };
} // nv namespace } // nv namespace
#endif // NV_IMAGE_FILTER_H #endif // NV_IMAGE_FILTER_H

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

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

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

@ -1,59 +1,59 @@
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com> // Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, // restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell // copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
// //
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
#ifndef NV_IMAGE_NORMALMAP_H #ifndef NV_IMAGE_NORMALMAP_H
#define NV_IMAGE_NORMALMAP_H #define NV_IMAGE_NORMALMAP_H
#include "nvimage.h" #include "nvimage.h"
#include "FloatImage.h" #include "FloatImage.h"
#include "nvmath/Vector.h" #include "nvmath/Vector.h"
namespace nv namespace nv
{ {
class Image; class Image;
enum NormalMapFilter enum NormalMapFilter
{ {
NormalMapFilter_Sobel3x3, // fine detail NormalMapFilter_Sobel3x3, // fine detail
NormalMapFilter_Sobel5x5, // medium detail NormalMapFilter_Sobel5x5, // medium detail
NormalMapFilter_Sobel7x7, // large detail NormalMapFilter_Sobel7x7, // large detail
NormalMapFilter_Sobel9x9, // very large NormalMapFilter_Sobel9x9, // very large
}; };
// @@ These two functions should be deprecated: // @@ 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, NormalMapFilter filter = NormalMapFilter_Sobel3x3);
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights); 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); FloatImage * createNormalMap(const FloatImage * img, FloatImage::WrapMode wm, Vector4::Arg filterWeights);
void normalizeNormalMap(FloatImage * img); void normalizeNormalMap(FloatImage * img);
// @@ Add generation of DU/DV maps. // @@ Add generation of DU/DV maps.
} // nv namespace } // nv namespace
#endif // NV_IMAGE_NORMALMAP_H #endif // NV_IMAGE_NORMALMAP_H

@ -1,118 +1,118 @@
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com> // Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, // restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell // copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
// //
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
#ifndef NV_IMAGE_PIXELFORMAT_H #ifndef NV_IMAGE_PIXELFORMAT_H
#define NV_IMAGE_PIXELFORMAT_H #define NV_IMAGE_PIXELFORMAT_H
#include "nvimage.h" #include "nvimage.h"
namespace nv namespace nv
{ {
namespace PixelFormat namespace PixelFormat
{ {
// Convert component @a c having @a inbits to the returned value having @a outbits. // Convert component @a c having @a inbits to the returned value having @a outbits.
inline uint convert(uint c, uint inbits, uint outbits) inline uint convert(uint c, uint inbits, uint outbits)
{ {
if (inbits == 0) if (inbits == 0)
{ {
return 0; return 0;
} }
else if (inbits >= outbits) else if (inbits >= outbits)
{ {
// truncate // truncate
return c >> (inbits - outbits); return c >> (inbits - outbits);
} }
else else
{ {
// bitexpand // bitexpand
return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits); return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
} }
} }
// Get pixel component shift and size given its mask. // Get pixel component shift and size given its mask.
inline void maskShiftAndSize(uint mask, uint * shift, uint * size) inline void maskShiftAndSize(uint mask, uint * shift, uint * size)
{ {
if (!mask) if (!mask)
{ {
*shift = 0; *shift = 0;
*size = 0; *size = 0;
return; return;
} }
*shift = 0; *shift = 0;
while((mask & 1) == 0) { while((mask & 1) == 0) {
++(*shift); ++(*shift);
mask >>= 1; mask >>= 1;
} }
*size = 0; *size = 0;
while((mask & 1) == 1) { while((mask & 1) == 1) {
++(*size); ++(*size);
mask >>= 1; mask >>= 1;
} }
} }
inline float quantizeCeil(float f, int inbits, int outbits) inline float quantizeCeil(float f, int inbits, int outbits)
{ {
nvDebugCheck(f >= 0.0f && f <= 1.0f); nvDebugCheck(f >= 0.0f && f <= 1.0f);
//uint i = f * (float(1 << inbits) - 1); //uint i = f * (float(1 << inbits) - 1);
//i = convert(i, inbits, outbits); //i = convert(i, inbits, outbits);
//float result = float(i) / (float(1 << outbits) - 1); //float result = float(i) / (float(1 << outbits) - 1);
//nvCheck(result >= f); //nvCheck(result >= f);
float result; float result;
int offset = 0; int offset = 0;
do { do {
uint i = offset + uint(f * (float(1 << inbits) - 1)); uint i = offset + uint(f * (float(1 << inbits) - 1));
i = convert(i, inbits, outbits); i = convert(i, inbits, outbits);
result = float(i) / (float(1 << outbits) - 1); result = float(i) / (float(1 << outbits) - 1);
offset++; offset++;
} while (result < f); } while (result < f);
return result; return result;
} }
/* /*
inline float quantizeRound(float f, int bits) inline float quantizeRound(float f, int bits)
{ {
nvDebugCheck(f >= 0.0f && f <= 1.0f); nvDebugCheck(f >= 0.0f && f <= 1.0f);
float scale = float(1 << bits); float scale = float(1 << bits);
return fround(f * scale) / scale; return fround(f * scale) / scale;
} }
inline float quantizeFloor(float f, int bits) inline float quantizeFloor(float f, int bits)
{ {
nvDebugCheck(f >= 0.0f && f <= 1.0f); nvDebugCheck(f >= 0.0f && f <= 1.0f);
float scale = float(1 << bits); float scale = float(1 << bits);
return floor(f * scale) / scale; return floor(f * scale) / scale;
} }
*/ */
} // PixelFormat namespace } // PixelFormat namespace
} // nv namespace } // nv namespace
#endif // NV_IMAGE_PIXELFORMAT_H #endif // NV_IMAGE_PIXELFORMAT_H

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

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

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

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

File diff suppressed because it is too large Load Diff

@ -1,30 +1,30 @@
#pragma once #pragma once
#ifndef NV_MATH_HALF_H #ifndef NV_MATH_HALF_H
#define NV_MATH_HALF_H #define NV_MATH_HALF_H
#include "nvmath.h" #include "nvmath.h"
namespace nv { namespace nv {
uint32 half_to_float( uint16 h ); uint32 half_to_float( uint16 h );
uint16 half_from_float( uint32 f ); uint16 half_from_float( uint32 f );
void half_init_tables(); void half_init_tables();
uint32 fast_half_to_float(uint16 h); uint32 fast_half_to_float(uint16 h);
inline uint16 to_half(float c) { inline uint16 to_half(float c) {
union { float f; uint32 u; } f; union { float f; uint32 u; } f;
f.f = c; f.f = c;
return nv::half_from_float( f.u ); return nv::half_from_float( f.u );
} }
inline float to_float(uint16 c) { inline float to_float(uint16 c) {
union { float f; uint32 u; } f; union { float f; uint32 u; } f;
f.u = nv::fast_half_to_float( c ); f.u = nv::fast_half_to_float( c );
return f.f; return f.f;
} }
} // nv namespace } // nv namespace
#endif // NV_MATH_HALF_H #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)); 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); return isFinite(v.x) && isFinite(v.y);
} }
inline Vector2 validate(Vector2::Arg v, Vector2::Arg fallback = Vector2(0.0f)) 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; Vector2 vf = v;
nv::floatCleanup(vf.component, 2); nv::floatCleanup(vf.component, 2);
return vf; return vf;
@ -567,14 +567,14 @@ namespace nv
return Vector3(ceilf(v.x), ceilf(v.y), ceilf(v.z)); 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); return isFinite(v.x) && isFinite(v.y) && isFinite(v.z);
} }
inline Vector3 validate(Vector3::Arg v, Vector3::Arg fallback = Vector3(0.0f)) 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; Vector3 vf = v;
nv::floatCleanup(vf.component, 3); nv::floatCleanup(vf.component, 3);
return vf; 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)); 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); 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)) 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; Vector4 vf = v;
nv::floatCleanup(vf.component, 4); nv::floatCleanup(vf.component, 4);
return vf; return vf;

@ -5,14 +5,13 @@
#define NV_MATH_H #define NV_MATH_H
#include "nvcore/nvcore.h" #include "nvcore/nvcore.h"
#include "nvcore/Debug.h" #include "nvcore/Debug.h" // nvDebugCheck
#include "nvcore/Utils.h" // clamp #include "nvcore/Utils.h" // clamp
#include <math.h> #include <math.h>
#include <limits.h> // INT_MAX
#if NV_OS_WIN32 || NV_OS_XBOX #if NV_OS_WIN32 || NV_OS_XBOX
#include <float.h> #include <float.h> // finite, isnan
#endif #endif
// Function linkage // Function linkage
@ -105,9 +104,12 @@ namespace nv
inline float toRadian(float degree) { return degree * (PI / 180.0f); } inline float toRadian(float degree) { return degree * (PI / 180.0f); }
inline float toDegree(float radian) { return radian * (180.0f / PI); } 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) 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) 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 // This code is in the public domain -- castano@gmail.com
#pragma once #pragma once
#ifndef NV_THREAD_THREADPOOL_H #ifndef NV_THREAD_THREADPOOL_H
#define NV_THREAD_THREADPOOL_H #define NV_THREAD_THREADPOOL_H
#include "nvthread.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 CubeSurface CubeSurface::irradianceFilter(int size) const
{ {
// @@ TODO // @@ TODO
@ -237,7 +266,7 @@ SolidAngleTable::SolidAngleTable(uint edgeLength) : size(edgeLength/2) {
for (uint y = 0; y < size; y++) { for (uint y = 0; y < size; y++) {
for (uint x = 0; x < size; x++) { 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; CubeSurface filteredCube;
filteredCube.m->allocate(size); 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) { if (m->solidAngleTable == NULL) {
m->solidAngleTable = new SolidAngleTable(edgeLength); m->solidAngleTable = new SolidAngleTable(edgeLength);
} }

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

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

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

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

Loading…
Cancel
Save