uid issue
This commit is contained in:
172
public/bitmap/bitmap.h
Normal file
172
public/bitmap/bitmap.h
Normal file
@ -0,0 +1,172 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef BITMAP_H
|
||||
#define BITMAP_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "bitmap/imageformat.h"
|
||||
#include "color.h"
|
||||
#include "dbg.h"
|
||||
|
||||
class CUtlBuffer;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlBuffer;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A Bitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
struct Bitmap_t
|
||||
{
|
||||
Bitmap_t() { Reset(); }
|
||||
~Bitmap_t() { Clear(); }
|
||||
|
||||
//
|
||||
// Accessors
|
||||
//
|
||||
inline int Width() const { return m_nWidth; }
|
||||
inline int Height() const { return m_nHeight; }
|
||||
inline ImageFormat Format() const { return m_ImageFormat; }
|
||||
inline unsigned char *GetBits() const { return m_pBits; }
|
||||
inline int Stride() const { return m_nStride; }
|
||||
inline bool GetOwnsBuffer() const { return m_bOwnsBuffer; }
|
||||
|
||||
/// Allocate the buffer. Discards existing data, freeing it if we own it
|
||||
void Init( int nWidth, int nHeight, ImageFormat imageFormat, int nStride = 0 );
|
||||
|
||||
/// Set the bitmap to the specified buffer. Any existing data is discarded/freed
|
||||
/// as appropriate.
|
||||
void SetBuffer( int nWidth, int nHeight, ImageFormat imageFormat, unsigned char *pBits, bool bAssumeOwnership, int nStride = 0 );
|
||||
|
||||
/// Sets / releases ownershp of the buffer. This does not otherwise alter the
|
||||
/// state of the bitmap.
|
||||
void SetOwnsBuffer( bool bOwnsBuffer )
|
||||
{
|
||||
Assert( m_pBits );
|
||||
m_bOwnsBuffer = bOwnsBuffer;
|
||||
}
|
||||
|
||||
/// Free up all memory and reset to default state
|
||||
void Clear();
|
||||
|
||||
/// Return true if we have a valid size and buffer
|
||||
bool IsValid() const;
|
||||
|
||||
/// Get pointer to raw pixel data.
|
||||
unsigned char *GetPixel( int x, int y );
|
||||
const unsigned char *GetPixel( int x, int y ) const;
|
||||
|
||||
/// Get pixel value at specified coordinates
|
||||
Color GetColor( int x, int y ) const;
|
||||
|
||||
/// Set pixel value at specified coordinates
|
||||
void SetColor( int x, int y, Color c );
|
||||
|
||||
/// Set this bitmap to be a logical copy of the specified
|
||||
/// bitmap. No memory is allocated or copied, just copying
|
||||
/// some pointers. We can also optionally transfer ownership
|
||||
/// of the buffer.
|
||||
void MakeLogicalCopyOf( Bitmap_t &src, bool bTransferBufferOwnership = false );
|
||||
|
||||
/// Set this bitmap to be a cropped rectangle from the given bitmap.
|
||||
/// The source pointer can be NULL or point to this, which means to do
|
||||
/// the crop in place.
|
||||
void Crop( int x0, int y0, int nWidth, int nHeight, const Bitmap_t *pImgSource = NULL );
|
||||
|
||||
/// Blit a rectangle of pixel data into this image.
|
||||
void SetPixelData( const Bitmap_t &src, int nSrcX1, int nSrcY1, int nCopySizeX, int nCopySizeY, int nDestX1, int nDestY1 );
|
||||
|
||||
/// Blit the entire source image into this image, at the specified offset.
|
||||
/// the rectangle is clipped if necessary
|
||||
void SetPixelData( const Bitmap_t &src, int nDestX1 = 0, int nDestY1 = 0 );
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
|
||||
/// Dimensions
|
||||
int m_nWidth;
|
||||
int m_nHeight;
|
||||
|
||||
/// Size, in bytes, of one pixel
|
||||
int m_nPixelSize;
|
||||
|
||||
/// Image row stride, in bytes
|
||||
int m_nStride;
|
||||
|
||||
// Do we own this buffer?
|
||||
bool m_bOwnsBuffer;
|
||||
|
||||
/// Pixel format
|
||||
ImageFormat m_ImageFormat;
|
||||
|
||||
/// Bitmap data. Must be allocated with malloc/free. Don't use
|
||||
/// new/delete
|
||||
unsigned char *m_pBits;
|
||||
};
|
||||
|
||||
inline void Bitmap_t::Reset()
|
||||
{
|
||||
m_nWidth = 0;
|
||||
m_nHeight = 0;
|
||||
m_ImageFormat = IMAGE_FORMAT_UNKNOWN;
|
||||
m_pBits = NULL;
|
||||
m_nPixelSize = 0;
|
||||
m_bOwnsBuffer = false;
|
||||
m_nStride = 0;
|
||||
}
|
||||
|
||||
inline unsigned char *Bitmap_t::GetPixel( int x, int y )
|
||||
{
|
||||
if ( !m_pBits )
|
||||
return NULL;
|
||||
|
||||
return m_pBits + (y*m_nStride) + x* m_nPixelSize;
|
||||
}
|
||||
|
||||
inline const unsigned char *Bitmap_t::GetPixel( int x, int y ) const
|
||||
{
|
||||
if ( !m_pBits )
|
||||
return NULL;
|
||||
|
||||
return m_pBits + (y*m_nStride) + x* m_nPixelSize;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Loads a bitmap from an arbitrary file: could be a TGA, PSD, or PFM.
|
||||
// LoadBitmap autodetects which type, and returns it
|
||||
//-----------------------------------------------------------------------------
|
||||
enum BitmapFileType_t
|
||||
{
|
||||
BITMAP_FILE_TYPE_UNKNOWN = -1,
|
||||
BITMAP_FILE_TYPE_PSD = 0,
|
||||
BITMAP_FILE_TYPE_TGA,
|
||||
BITMAP_FILE_TYPE_PFM,
|
||||
};
|
||||
|
||||
BitmapFileType_t LoadBitmapFile( CUtlBuffer &buf, Bitmap_t *pBitmap );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PFM file loading related methods
|
||||
//-----------------------------------------------------------------------------
|
||||
bool PFMReadFileR32F( CUtlBuffer &fileBuffer, Bitmap_t &bitmap, float pfmScale );
|
||||
bool PFMReadFileRGB323232F( CUtlBuffer &fileBuffer, Bitmap_t &bitmap, float pfmScale );
|
||||
bool PFMReadFileRGBA32323232F( CUtlBuffer &fileBuffer, Bitmap_t &bitmap, float pfmScale );
|
||||
bool PFMGetInfo_AndAdvanceToTextureBits( CUtlBuffer &pfmBuffer, int &nWidth, int &nHeight, ImageFormat &imageFormat );
|
||||
|
||||
|
||||
#endif // BITMAP_H
|
146
public/bitmap/colorformat.h
Normal file
146
public/bitmap/colorformat.h
Normal file
@ -0,0 +1,146 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef COLORFORMAT_H
|
||||
#define COLORFORMAT_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "mathlib/vector.h"
|
||||
#include "mathlib/vector2d.h"
|
||||
#include "mathlib/vector4d.h"
|
||||
#include "mathlib/vertexcolor.h"
|
||||
|
||||
enum ColorFormat_t
|
||||
{
|
||||
COLOR_FORMAT_UNKNOWN = 0,
|
||||
COLOR_FORMAT_R32G32B32A32_TYPELESS = 1,
|
||||
COLOR_FORMAT_R32G32B32A32_FLOAT = 2,
|
||||
COLOR_FORMAT_R32G32B32A32_UINT = 3,
|
||||
COLOR_FORMAT_R32G32B32A32_SINT = 4,
|
||||
COLOR_FORMAT_R32G32B32_TYPELESS = 5,
|
||||
COLOR_FORMAT_R32G32B32_FLOAT = 6,
|
||||
COLOR_FORMAT_R32G32B32_UINT = 7,
|
||||
COLOR_FORMAT_R32G32B32_SINT = 8,
|
||||
COLOR_FORMAT_R16G16B16A16_TYPELESS = 9,
|
||||
COLOR_FORMAT_R16G16B16A16_FLOAT = 10,
|
||||
COLOR_FORMAT_R16G16B16A16_UNORM = 11,
|
||||
COLOR_FORMAT_R16G16B16A16_UINT = 12,
|
||||
COLOR_FORMAT_R16G16B16A16_SNORM = 13,
|
||||
COLOR_FORMAT_R16G16B16A16_SINT = 14,
|
||||
COLOR_FORMAT_R32G32_TYPELESS = 15,
|
||||
COLOR_FORMAT_R32G32_FLOAT = 16,
|
||||
COLOR_FORMAT_R32G32_UINT = 17,
|
||||
COLOR_FORMAT_R32G32_SINT = 18,
|
||||
COLOR_FORMAT_R32G8X24_TYPELESS = 19,
|
||||
COLOR_FORMAT_D32_FLOAT_S8X24_UINT = 20,
|
||||
COLOR_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
|
||||
COLOR_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
|
||||
COLOR_FORMAT_R10G10B10A2_TYPELESS = 23,
|
||||
COLOR_FORMAT_R10G10B10A2_UNORM = 24,
|
||||
COLOR_FORMAT_R10G10B10A2_UINT = 25,
|
||||
COLOR_FORMAT_R11G11B10_FLOAT = 26,
|
||||
COLOR_FORMAT_R8G8B8A8_TYPELESS = 27,
|
||||
COLOR_FORMAT_R8G8B8A8_UNORM = 28,
|
||||
COLOR_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
|
||||
COLOR_FORMAT_R8G8B8A8_UINT = 30,
|
||||
COLOR_FORMAT_R8G8B8A8_SNORM = 31,
|
||||
COLOR_FORMAT_R8G8B8A8_SINT = 32,
|
||||
COLOR_FORMAT_R16G16_TYPELESS = 33,
|
||||
COLOR_FORMAT_R16G16_FLOAT = 34,
|
||||
COLOR_FORMAT_R16G16_UNORM = 35,
|
||||
COLOR_FORMAT_R16G16_UINT = 36,
|
||||
COLOR_FORMAT_R16G16_SNORM = 37,
|
||||
COLOR_FORMAT_R16G16_SINT = 38,
|
||||
COLOR_FORMAT_R32_TYPELESS = 39,
|
||||
COLOR_FORMAT_D32_FLOAT = 40,
|
||||
COLOR_FORMAT_R32_FLOAT = 41,
|
||||
COLOR_FORMAT_R32_UINT = 42,
|
||||
COLOR_FORMAT_R32_SINT = 43,
|
||||
COLOR_FORMAT_R24G8_TYPELESS = 44,
|
||||
COLOR_FORMAT_D24_UNORM_S8_UINT = 45,
|
||||
COLOR_FORMAT_R24_UNORM_X8_TYPELESS = 46,
|
||||
COLOR_FORMAT_X24_TYPELESS_G8_UINT = 47,
|
||||
COLOR_FORMAT_R8G8_TYPELESS = 48,
|
||||
COLOR_FORMAT_R8G8_UNORM = 49,
|
||||
COLOR_FORMAT_R8G8_UINT = 50,
|
||||
COLOR_FORMAT_R8G8_SNORM = 51,
|
||||
COLOR_FORMAT_R8G8_SINT = 52,
|
||||
COLOR_FORMAT_R16_TYPELESS = 53,
|
||||
COLOR_FORMAT_R16_FLOAT = 54,
|
||||
COLOR_FORMAT_D16_UNORM = 55,
|
||||
COLOR_FORMAT_R16_UNORM = 56,
|
||||
COLOR_FORMAT_R16_UINT = 57,
|
||||
COLOR_FORMAT_R16_SNORM = 58,
|
||||
COLOR_FORMAT_R16_SINT = 59,
|
||||
COLOR_FORMAT_R8_TYPELESS = 60,
|
||||
COLOR_FORMAT_R8_UNORM = 61,
|
||||
COLOR_FORMAT_R8_UINT = 62,
|
||||
COLOR_FORMAT_R8_SNORM = 63,
|
||||
COLOR_FORMAT_R8_SINT = 64,
|
||||
COLOR_FORMAT_A8_UNORM = 65,
|
||||
COLOR_FORMAT_R1_UNORM = 66,
|
||||
COLOR_FORMAT_R9G9B9E5_SHAREDEXP = 67,
|
||||
COLOR_FORMAT_R8G8_B8G8_UNORM = 68,
|
||||
COLOR_FORMAT_G8R8_G8B8_UNORM = 69,
|
||||
COLOR_FORMAT_BC1_TYPELESS = 70,
|
||||
COLOR_FORMAT_BC1_UNORM = 71,
|
||||
COLOR_FORMAT_BC1_UNORM_SRGB = 72,
|
||||
COLOR_FORMAT_BC2_TYPELESS = 73,
|
||||
COLOR_FORMAT_BC2_UNORM = 74,
|
||||
COLOR_FORMAT_BC2_UNORM_SRGB = 75,
|
||||
COLOR_FORMAT_BC3_TYPELESS = 76,
|
||||
COLOR_FORMAT_BC3_UNORM = 77,
|
||||
COLOR_FORMAT_BC3_UNORM_SRGB = 78,
|
||||
COLOR_FORMAT_BC4_TYPELESS = 79,
|
||||
COLOR_FORMAT_BC4_UNORM = 80,
|
||||
COLOR_FORMAT_BC4_SNORM = 81,
|
||||
COLOR_FORMAT_BC5_TYPELESS = 82,
|
||||
COLOR_FORMAT_BC5_UNORM = 83,
|
||||
COLOR_FORMAT_BC5_SNORM = 84,
|
||||
COLOR_FORMAT_B5G6R5_UNORM = 85,
|
||||
COLOR_FORMAT_B5G5R5A1_UNORM = 86,
|
||||
COLOR_FORMAT_B8G8R8A8_UNORM = 87,
|
||||
COLOR_FORMAT_B8G8R8X8_UNORM = 88,
|
||||
COLOR_FORMAT_FORCE_UINT = 0xffffffffUL,
|
||||
};
|
||||
|
||||
template < class T > inline ColorFormat_t ComputeColorFormat( T* )
|
||||
{
|
||||
return COLOR_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
template <> inline ColorFormat_t ComputeColorFormat( float32* )
|
||||
{
|
||||
return COLOR_FORMAT_R32_FLOAT;
|
||||
}
|
||||
|
||||
template <> inline ColorFormat_t ComputeColorFormat( Vector2D* )
|
||||
{
|
||||
return COLOR_FORMAT_R32G32_FLOAT;
|
||||
}
|
||||
|
||||
template <> inline ColorFormat_t ComputeColorFormat( Vector* )
|
||||
{
|
||||
return COLOR_FORMAT_R32G32B32_FLOAT;
|
||||
}
|
||||
|
||||
template <> inline ColorFormat_t ComputeColorFormat( Vector4D* )
|
||||
{
|
||||
return COLOR_FORMAT_R32G32B32A32_FLOAT;
|
||||
}
|
||||
|
||||
template <> inline ColorFormat_t ComputeColorFormat( VertexColor_t* )
|
||||
{
|
||||
// FIXME: How to get at SRGB formats?
|
||||
return COLOR_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
|
||||
|
||||
#endif // COLORFORMAT_H
|
68
public/bitmap/cubemap.h
Normal file
68
public/bitmap/cubemap.h
Normal file
@ -0,0 +1,68 @@
|
||||
//===== Copyright <20> 1996-2007, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: a class for performing cube-mapped spherical sample lookups.
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef CUBEMAP_H
|
||||
#define CUBEMAP_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "tier1/utlmemory.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
template<class T, int RES> struct CCubeMap
|
||||
{
|
||||
T m_Samples[6][RES][RES];
|
||||
|
||||
public:
|
||||
FORCEINLINE void GetCoords( Vector const &vecNormalizedDirection, int &nX, int &nY, int &nFace )
|
||||
{
|
||||
// find largest magnitude component
|
||||
int nLargest = 0;
|
||||
int nAxis0 = 1;
|
||||
int nAxis1 = 2;
|
||||
if ( fabs( vecNormalizedDirection[1] ) > fabs( vecNormalizedDirection[0] ) )
|
||||
{
|
||||
nLargest = 1;
|
||||
nAxis0 = 0;
|
||||
nAxis1 = 2;
|
||||
}
|
||||
if ( fabs( vecNormalizedDirection[2] ) > fabs( vecNormalizedDirection[nLargest] ) )
|
||||
{
|
||||
nLargest = 2;
|
||||
nAxis0 = 0;
|
||||
nAxis1 = 1;
|
||||
}
|
||||
float flZ = vecNormalizedDirection[nLargest];
|
||||
if ( flZ < 0 )
|
||||
{
|
||||
flZ = - flZ;
|
||||
nLargest += 3;
|
||||
}
|
||||
nFace = nLargest;
|
||||
flZ = 1.0 / flZ;
|
||||
nX = RemapValClamped( vecNormalizedDirection[nAxis0] * flZ, -1, 1, 0, RES - 1 );
|
||||
nY = RemapValClamped( vecNormalizedDirection[nAxis1] * flZ, -1, 1, 0, RES - 1 );
|
||||
}
|
||||
|
||||
FORCEINLINE T & GetSample( Vector const &vecNormalizedDirection )
|
||||
{
|
||||
int nX, nY, nFace;
|
||||
GetCoords( vecNormalizedDirection, nX, nY, nFace );
|
||||
return m_Samples[nFace][nX][nY];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CUBEMAP_H
|
833
public/bitmap/floatbitmap.h
Normal file
833
public/bitmap/floatbitmap.h
Normal file
@ -0,0 +1,833 @@
|
||||
//======= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef FLOATBITMAP_H
|
||||
#define FLOATBITMAP_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/utlsoacontainer.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "bitmap/imageformat.h"
|
||||
|
||||
class IThreadPool;
|
||||
|
||||
|
||||
struct PixRGBAF
|
||||
{
|
||||
float Red;
|
||||
float Green;
|
||||
float Blue;
|
||||
float Alpha;
|
||||
};
|
||||
|
||||
struct PixRGBA8
|
||||
{
|
||||
unsigned char Red;
|
||||
unsigned char Green;
|
||||
unsigned char Blue;
|
||||
unsigned char Alpha;
|
||||
};
|
||||
|
||||
inline PixRGBAF PixRGBA8_to_F( PixRGBA8 const &x )
|
||||
{
|
||||
PixRGBAF f;
|
||||
f.Red = x.Red / float( 255.0f );
|
||||
f.Green = x.Green / float( 255.0f );
|
||||
f.Blue = x.Blue / float( 255.0f );
|
||||
f.Alpha = x.Alpha / float( 255.0f );
|
||||
return f;
|
||||
}
|
||||
|
||||
inline PixRGBA8 PixRGBAF_to_8( PixRGBAF const &f )
|
||||
{
|
||||
PixRGBA8 x;
|
||||
x.Red = ( unsigned char )MAX( 0, MIN( 255.0,255.0*f.Red ) );
|
||||
x.Green = ( unsigned char )MAX( 0, MIN( 255.0,255.0*f.Green ) );
|
||||
x.Blue = ( unsigned char )MAX( 0, MIN( 255.0,255.0*f.Blue ) );
|
||||
x.Alpha = ( unsigned char )MAX( 0, MIN( 255.0,255.0*f.Alpha ) );
|
||||
return x;
|
||||
}
|
||||
|
||||
#define SPFLAGS_MAXGRADIENT 1
|
||||
|
||||
// bit flag options for ComputeSelfShadowedBumpmapFromHeightInAlphaChannel:
|
||||
#define SSBUMP_OPTION_NONDIRECTIONAL 1 // generate ambient occlusion only
|
||||
#define SSBUMP_MOD2X_DETAIL_TEXTURE 2 // scale so that a flat unshadowed
|
||||
// value is 0.5, and bake rgb luminance
|
||||
// in.
|
||||
|
||||
// attributes for csoaa container
|
||||
enum FBMAttribute_t
|
||||
{
|
||||
FBM_ATTR_RED = 0,
|
||||
FBM_ATTR_GREEN = 1,
|
||||
FBM_ATTR_BLUE = 2,
|
||||
FBM_ATTR_ALPHA = 3,
|
||||
|
||||
FBM_ATTR_COUNT
|
||||
};
|
||||
|
||||
enum FBMAttributeMask_t
|
||||
{
|
||||
FBM_ATTR_RED_MASK = ( 1 << FBM_ATTR_RED ),
|
||||
FBM_ATTR_GREEN_MASK = ( 1 << FBM_ATTR_GREEN ),
|
||||
FBM_ATTR_BLUE_MASK = ( 1 << FBM_ATTR_BLUE ),
|
||||
FBM_ATTR_ALPHA_MASK = ( 1 << FBM_ATTR_ALPHA ),
|
||||
|
||||
FBM_ATTR_RGB_MASK = FBM_ATTR_RED_MASK | FBM_ATTR_GREEN_MASK | FBM_ATTR_BLUE_MASK,
|
||||
FBM_ATTR_RGBA_MASK = FBM_ATTR_RED_MASK | FBM_ATTR_GREEN_MASK | FBM_ATTR_BLUE_MASK | FBM_ATTR_ALPHA_MASK,
|
||||
};
|
||||
|
||||
|
||||
enum DownsampleFlags_t
|
||||
{
|
||||
DOWNSAMPLE_CLAMPS = 0x1,
|
||||
DOWNSAMPLE_CLAMPT = 0x2,
|
||||
DOWNSAMPLE_CLAMPU = 0x4,
|
||||
DOWNSAMPLE_ALPHATEST = 0x10,
|
||||
};
|
||||
|
||||
struct DownsampleInfo_t
|
||||
{
|
||||
int m_nFlags; // see DownsampleFlags_t
|
||||
float m_flAlphaThreshhold;
|
||||
float m_flAlphaHiFreqThreshhold;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Float bitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
class FloatBitMap_t : public CSOAContainer
|
||||
{
|
||||
typedef CSOAContainer BaseClass;
|
||||
|
||||
public:
|
||||
FloatBitMap_t();
|
||||
FloatBitMap_t( int nWidth, int nHeight, int nDepth = 1, int nAttributeMask = FBM_ATTR_RGBA_MASK ); // make one and allocate space
|
||||
FloatBitMap_t( const char *pFilename ); // read one from a file (tga or pfm)
|
||||
FloatBitMap_t( const FloatBitMap_t *pOrig );
|
||||
|
||||
// Initialize, shutdown
|
||||
void Init( int nWidth, int nHeight, int nDepth = 1, int nAttributeMask = FBM_ATTR_RGBA_MASK );
|
||||
void Shutdown();
|
||||
|
||||
// Computes the attribute mask
|
||||
int GetAttributeMask() const;
|
||||
|
||||
// Does the bitmap have data for a particular component?
|
||||
bool HasAttributeData( FBMAttribute_t a ) const;
|
||||
|
||||
// Compute valid attribute list
|
||||
int ComputeValidAttributeList( int pIndex[4] ) const;
|
||||
|
||||
// Methods to initialize bitmap data
|
||||
bool LoadFromPFM( const char *pFilename ); // load from floating point pixmap (.pfm) file
|
||||
bool LoadFromPSD( const char *pFilename ); // load from psd file
|
||||
void InitializeWithRandomPixelsFromAnotherFloatBM( const FloatBitMap_t &other );
|
||||
void Clear( float r, float g, float b, float alpha ); // set all pixels to speicifed values (0..1 nominal)
|
||||
void LoadFromBuffer( const void *pBuffer, size_t nBufSize, ImageFormat fmt, float flGamma ); // Assumes dimensions match the bitmap size
|
||||
void LoadFromFloatBitmap( const FloatBitMap_t *pOrig );
|
||||
|
||||
// Methods to write bitmap data to files
|
||||
bool WriteTGAFile( const char *pFilename ) const;
|
||||
bool WritePFM( const char *pFilename ); // save to floating point pixmap (.pfm) file
|
||||
void WriteToBuffer( void *pBuffer, size_t nBufSize, ImageFormat fmt, float flGamma ) const; // Assumes dimensions match the bitmap size
|
||||
|
||||
// Methods to read + write constant values
|
||||
const float &ConstantValue( int comp ) const;
|
||||
|
||||
// Methods to read + write individual pixels
|
||||
float &Pixel( int x, int y, int z, int comp ) const;
|
||||
float &PixelWrapped( int x, int y, int z, int comp ) const;
|
||||
float &PixelClamped( int x, int y, int z, int comp ) const;
|
||||
float &Alpha( int x, int y, int z ) const;
|
||||
|
||||
// look up a pixel value with bilinear interpolation
|
||||
float InterpolatedPixel( float x, float y, int comp ) const;
|
||||
float InterpolatedPixel( float x, float y, float z, int comp ) const;
|
||||
|
||||
PixRGBAF PixelRGBAF( int x, int y, int z ) const;
|
||||
void WritePixelRGBAF(int x, int y, int z, PixRGBAF value) const;
|
||||
void WritePixel(int x, int y, int z, int comp, float value);
|
||||
|
||||
// Method to slam a particular channel to always be the same value
|
||||
void SetChannel( int comp, float flValue );
|
||||
|
||||
// paste, performing boundary matching. Alpha channel can be used to make
|
||||
// brush shape irregular
|
||||
void SmartPaste( const FloatBitMap_t &brush, int xofs, int yofs, uint32 flags );
|
||||
|
||||
// force to be tileable using poisson formula
|
||||
void MakeTileable( void );
|
||||
|
||||
void ReSize( int NewXSize, int NewYSize );
|
||||
|
||||
// Makes the image be a sub-range of the current image
|
||||
void Crop( int x, int y, int z, int nWidth, int nHeight, int nDepth );
|
||||
|
||||
// find the bounds of the area that has non-zero alpha.
|
||||
void GetAlphaBounds( int &minx, int &miny, int &maxx, int &maxy );
|
||||
|
||||
// Solve the poisson equation for an image. The alpha channel of the image controls which
|
||||
// pixels are "modifiable", and can be used to set boundary conditions. Alpha=0 means the pixel
|
||||
// is locked. deltas are in the order [(x,y)-(x,y-1),(x,y)-(x-1,y),(x,y)-(x+1,y),(x,y)-(x,y+1)
|
||||
void Poisson( FloatBitMap_t * deltas[4],
|
||||
int n_iters,
|
||||
uint32 flags // SPF_xxx
|
||||
);
|
||||
|
||||
void QuarterSize( FloatBitMap_t *pBitmap ); // get a new one downsampled
|
||||
void QuarterSizeBlocky( FloatBitMap_t *pBitmap ); // get a new one downsampled
|
||||
void QuarterSizeWithGaussian( FloatBitMap_t *pBitmap ); // downsample 2x using a gaussian
|
||||
|
||||
// Downsample using nice filter (NOTE: Dest bitmap needs to have been initialized w/ final size)
|
||||
void DownsampleNiceFiltered( const DownsampleInfo_t& info, FloatBitMap_t *pBitmap );
|
||||
|
||||
void RaiseToPower( float pow );
|
||||
void ScaleGradients( void );
|
||||
void Logize( void ); // pix=log(1+pix)
|
||||
void UnLogize( void ); // pix=exp(pix)-1
|
||||
|
||||
// compress to 8 bits converts the hdr texture to an 8 bit texture, encoding a scale factor
|
||||
// in the alpha channel. upon return, the original pixel can be (approximately) recovered
|
||||
// by the formula rgb*alpha*overbright.
|
||||
// this function performs special numerical optimization on the texture to minimize the error
|
||||
// when using bilinear filtering to read the texture.
|
||||
void CompressTo8Bits( float overbright );
|
||||
// decompress a bitmap converted by CompressTo8Bits
|
||||
void Uncompress( float overbright );
|
||||
|
||||
|
||||
Vector AverageColor( void ); // average rgb value of all pixels
|
||||
float BrightestColor( void ); // highest vector magnitude
|
||||
|
||||
void ScaleRGB( float scale_factor ); // for all pixels, r,g,b*=scale_factor
|
||||
|
||||
// given a bitmap with height stored in the alpha channel, generate vector positions and normals
|
||||
void ComputeVertexPositionsAndNormals( float flHeightScale, Vector ** ppPosOut, Vector ** ppNormalOut ) const;
|
||||
|
||||
// generate a normal map with height stored in alpha. uses hl2 tangent basis to support baked
|
||||
// self shadowing. the bump scale maps the height of a pixel relative to the edges of the
|
||||
// pixel. This function may take a while - many millions of rays may be traced. applications
|
||||
// using this method need to link w/ raytrace.lib
|
||||
FloatBitMap_t * ComputeSelfShadowedBumpmapFromHeightInAlphaChannel(
|
||||
float bump_scale, int nrays_to_trace_per_pixel = 100,
|
||||
uint32 nOptionFlags = 0 // SSBUMP_OPTION_XXX
|
||||
) const;
|
||||
|
||||
|
||||
// generate a conventional normal map from a source with height stored in alpha.
|
||||
FloatBitMap_t *ComputeBumpmapFromHeightInAlphaChannel( float bump_scale ) const ;
|
||||
|
||||
// bilateral (edge preserving) smoothing filter. edge_threshold_value defines the difference in
|
||||
// values over which filtering will not occur. Each channel is filtered independently. large
|
||||
// radii will run slow, since the bilateral filter is neither separable, nor is it a
|
||||
// convolution that can be done via fft.
|
||||
void TileableBilateralFilter( int radius_in_pixels, float edge_threshold_value );
|
||||
|
||||
// Sets a thread pool for all float bitmap work to be done on
|
||||
static void SetThreadPool( IThreadPool* pPool );
|
||||
|
||||
protected:
|
||||
void QuarterSize2D( FloatBitMap_t *pDest, int nStart, int nCount );
|
||||
void QuarterSize3D( FloatBitMap_t *pDest, int nStart, int nCount );
|
||||
void QuarterSizeBlocky2D( FloatBitMap_t *pDest, int nStart, int nCount );
|
||||
void QuarterSizeBlocky3D( FloatBitMap_t *pDest, int nStart, int nCount );
|
||||
|
||||
template< class T > void LoadFromBufferRGBFloat( const T *pBuffer, int nPixelCount );
|
||||
template< class T > void LoadFromBufferRGB( const T *pBuffer, int nPixelCount, const float *pGammaTable );
|
||||
template< class T > void LoadFromBufferRGBAFloat( const T *pBuffer, int nPixelCount );
|
||||
template< class T > void LoadFromBufferRGBA( const T *pBuffer, int nPixelCount, const float *pGammaTable );
|
||||
template< class T > void LoadFromBufferUV( const T *pBuffer, int nPixelCount );
|
||||
template< class T > void LoadFromBufferUVWQ( const T *pBuffer, int nPixelCount );
|
||||
template< class T > void LoadFromBufferUVLX( const T *pBuffer, int nPixelCount );
|
||||
template< class T > void WriteToBufferRGB( T *pBuffer, int nPixelCount, const uint16 *pInvGammaTable ) const;
|
||||
template< class T > void WriteToBufferRGBFloat( T *pBuffer, int nPixelCount ) const;
|
||||
template< class T > void WriteToBufferRGBA( T *pBuffer, int nPixelCount, const uint16 *pInvGammaTable ) const;
|
||||
template< class T > void WriteToBufferRGBAFloat( T *pBuffer, int nPixelCount ) const;
|
||||
template< class T > void WriteToBufferUV( T *pBuffer, int nPixelCount ) const;
|
||||
template< class T > void WriteToBufferUVWQ( T *pBuffer, int nPixelCount ) const;
|
||||
template< class T > void WriteToBufferUVLX( T *pBuffer, int nPixelCount ) const;
|
||||
|
||||
static int CoordWrap( int nC, int nLimit );
|
||||
|
||||
static IThreadPool *sm_pFBMThreadPool;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
inline FloatBitMap_t::FloatBitMap_t(void)
|
||||
{
|
||||
}
|
||||
|
||||
inline void FloatBitMap_t::Init( int nXSize, int nYSize, int nZSize, int nAttributeMask )
|
||||
{
|
||||
PurgeData();
|
||||
SetAttributeType( FBM_ATTR_RED, ATTRDATATYPE_FLOAT, ( nAttributeMask & FBM_ATTR_RED_MASK ) != 0 );
|
||||
SetAttributeType( FBM_ATTR_GREEN, ATTRDATATYPE_FLOAT, ( nAttributeMask & FBM_ATTR_GREEN_MASK ) != 0 );
|
||||
SetAttributeType( FBM_ATTR_BLUE, ATTRDATATYPE_FLOAT, ( nAttributeMask & FBM_ATTR_BLUE_MASK ) != 0 );
|
||||
SetAttributeType( FBM_ATTR_ALPHA, ATTRDATATYPE_FLOAT, ( nAttributeMask & FBM_ATTR_ALPHA_MASK ) != 0 );
|
||||
AllocateData( nXSize, nYSize, nZSize );
|
||||
|
||||
// Default alpha to white. All others default to 0.0 by default
|
||||
if ( ( nAttributeMask & FBM_ATTR_ALPHA_MASK ) == 0 )
|
||||
{
|
||||
FillAttr( FBM_ATTR_ALPHA, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Computes the attribute mask
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int FloatBitMap_t::GetAttributeMask() const
|
||||
{
|
||||
int nMask = 0;
|
||||
if ( HasAllocatedMemory( FBM_ATTR_RED ) )
|
||||
nMask |= FBM_ATTR_RED_MASK;
|
||||
if ( HasAllocatedMemory( FBM_ATTR_GREEN ) )
|
||||
nMask |= FBM_ATTR_GREEN_MASK;
|
||||
if ( HasAllocatedMemory( FBM_ATTR_BLUE ) )
|
||||
nMask |= FBM_ATTR_BLUE_MASK;
|
||||
if ( HasAllocatedMemory( FBM_ATTR_ALPHA ) )
|
||||
nMask |= FBM_ATTR_ALPHA_MASK;
|
||||
return nMask;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute valid attribute list
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int FloatBitMap_t::ComputeValidAttributeList( int pIndex[4] ) const
|
||||
{
|
||||
int nCount = 0;
|
||||
if ( HasAllocatedMemory( FBM_ATTR_RED ) )
|
||||
pIndex[ nCount++ ] = FBM_ATTR_RED;
|
||||
if ( HasAllocatedMemory( FBM_ATTR_GREEN ) )
|
||||
pIndex[ nCount++ ] = FBM_ATTR_GREEN;
|
||||
if ( HasAllocatedMemory( FBM_ATTR_BLUE ) )
|
||||
pIndex[ nCount++ ] = FBM_ATTR_BLUE;
|
||||
if ( HasAllocatedMemory( FBM_ATTR_ALPHA ) )
|
||||
pIndex[ nCount++ ] = FBM_ATTR_ALPHA;
|
||||
return nCount;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the bitmap have data for a particular component?
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool FloatBitMap_t::HasAttributeData( FBMAttribute_t a ) const
|
||||
{
|
||||
return HasAllocatedMemory( a );
|
||||
}
|
||||
|
||||
|
||||
inline int FloatBitMap_t::CoordWrap( int nC, int nLimit )
|
||||
{
|
||||
if ( nC >= nLimit )
|
||||
{
|
||||
nC %= nLimit;
|
||||
}
|
||||
else if ( nC < 0 )
|
||||
{
|
||||
nC += nLimit * ( ( -nC + nLimit-1 ) / nLimit );
|
||||
}
|
||||
return nC;
|
||||
}
|
||||
|
||||
inline float &FloatBitMap_t::Pixel(int x, int y, int z, int comp) const
|
||||
{
|
||||
Assert( (x >= 0 ) && (x < NumCols() ) );
|
||||
Assert( (y >= 0) && (y < NumRows() ) );
|
||||
Assert( (z >= 0) && (z < NumSlices() ) );
|
||||
float *pData = ElementPointer<float>( comp, x, y, z );
|
||||
return *pData;
|
||||
}
|
||||
|
||||
inline const float &FloatBitMap_t::ConstantValue( int comp ) const
|
||||
{
|
||||
Assert( !HasAllocatedMemory( comp ) );
|
||||
return Pixel( 0, 0, 0, comp );
|
||||
}
|
||||
|
||||
inline float &FloatBitMap_t::PixelWrapped(int x, int y, int z, int comp) const
|
||||
{
|
||||
// like Pixel except wraps around to other side
|
||||
x = CoordWrap( x, NumCols() );
|
||||
y = CoordWrap( y, NumRows() );
|
||||
z = CoordWrap( z, NumSlices() );
|
||||
return Pixel( x, y, z, comp );
|
||||
}
|
||||
|
||||
inline float &FloatBitMap_t::PixelClamped(int x, int y, int z, int comp) const
|
||||
{
|
||||
// like Pixel except wraps around to other side
|
||||
x = clamp( x, 0, NumCols() - 1 );
|
||||
y = clamp( y, 0, NumRows() - 1 );
|
||||
z = clamp( z, 0, NumSlices() - 1 );
|
||||
return Pixel( x, y, z, comp );
|
||||
}
|
||||
|
||||
|
||||
inline float &FloatBitMap_t::Alpha( int x, int y, int z ) const
|
||||
{
|
||||
Assert( ( x >= 0 ) && ( x < NumCols() ) );
|
||||
Assert( ( y >= 0 ) && ( y < NumRows() ) );
|
||||
Assert( ( z >= 0 ) && ( z < NumSlices() ) );
|
||||
return Pixel( x, y, z, FBM_ATTR_ALPHA );
|
||||
}
|
||||
|
||||
inline PixRGBAF FloatBitMap_t::PixelRGBAF( int x, int y, int z ) const
|
||||
{
|
||||
Assert( ( x >= 0 ) && ( x < NumCols() ) );
|
||||
Assert( ( y >= 0 ) && ( y < NumRows() ) );
|
||||
Assert( ( z >= 0 ) && ( z < NumSlices() ) );
|
||||
|
||||
PixRGBAF RetPix;
|
||||
RetPix.Red = Pixel( x, y, z, FBM_ATTR_RED );
|
||||
RetPix.Green = Pixel( x, y, z, FBM_ATTR_GREEN );
|
||||
RetPix.Blue = Pixel( x, y, z, FBM_ATTR_BLUE );
|
||||
RetPix.Alpha = Pixel( x, y, z, FBM_ATTR_ALPHA );
|
||||
return RetPix;
|
||||
}
|
||||
|
||||
|
||||
inline void FloatBitMap_t::WritePixelRGBAF( int x, int y, int z, PixRGBAF value ) const
|
||||
{
|
||||
Pixel( x, y, z, FBM_ATTR_RED ) = value.Red;
|
||||
Pixel( x, y, z, FBM_ATTR_GREEN ) = value.Green;
|
||||
Pixel( x, y, z, FBM_ATTR_BLUE ) = value.Blue;
|
||||
Pixel( x, y, z, FBM_ATTR_ALPHA ) = value.Alpha;
|
||||
}
|
||||
|
||||
|
||||
inline void FloatBitMap_t::WritePixel(int x, int y, int z, int comp, float value)
|
||||
{
|
||||
Pixel( x, y, z, comp ) = value;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Loads an array of image data into a buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T > void FloatBitMap_t::LoadFromBufferRGBFloat( const T *pBuffer, int nPixelCount )
|
||||
{
|
||||
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
Pixel( x, y, z, FBM_ATTR_RED ) = pBuffer[x].r;
|
||||
Pixel( x, y, z, FBM_ATTR_GREEN ) = pBuffer[x].g;
|
||||
Pixel( x, y, z, FBM_ATTR_BLUE ) = pBuffer[x].b;
|
||||
Pixel( x, y, z, FBM_ATTR_ALPHA ) = 1.0f;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::LoadFromBufferRGB( const T *pBuffer, int nPixelCount, const float *pGammaTable )
|
||||
{
|
||||
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
Pixel( x, y, z, FBM_ATTR_RED ) = pGammaTable[ pBuffer[x].RTo10Bit( ) ];
|
||||
Pixel( x, y, z, FBM_ATTR_GREEN ) = pGammaTable[ pBuffer[x].GTo10Bit( ) ];
|
||||
Pixel( x, y, z, FBM_ATTR_BLUE ) = pGammaTable[ pBuffer[x].BTo10Bit( ) ];
|
||||
Pixel( x, y, z, FBM_ATTR_ALPHA ) = 1.0f;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::LoadFromBufferRGBAFloat( const T *pBuffer, int nPixelCount )
|
||||
{
|
||||
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
Pixel( x, y, z, FBM_ATTR_RED ) = pBuffer[x].r;
|
||||
Pixel( x, y, z, FBM_ATTR_GREEN ) = pBuffer[x].g;
|
||||
Pixel( x, y, z, FBM_ATTR_BLUE ) = pBuffer[x].b;
|
||||
Pixel( x, y, z, FBM_ATTR_ALPHA ) = pBuffer[x].a;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::LoadFromBufferRGBA( const T *pBuffer, int nPixelCount, const float *pGammaTable )
|
||||
{
|
||||
float flOO1023 = 1.0f / 1023.0f;
|
||||
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
Pixel( x, y, z, FBM_ATTR_RED ) = pGammaTable[ pBuffer[x].RTo10Bit( ) ];
|
||||
Pixel( x, y, z, FBM_ATTR_GREEN ) = pGammaTable[ pBuffer[x].GTo10Bit( ) ];
|
||||
Pixel( x, y, z, FBM_ATTR_BLUE ) = pGammaTable[ pBuffer[x].BTo10Bit( ) ];
|
||||
Pixel( x, y, z, FBM_ATTR_ALPHA ) = pBuffer[x].ATo10Bit( ) * flOO1023;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Loads from UV buffers
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T > void FloatBitMap_t::LoadFromBufferUV( const T *pBuffer, int nPixelCount )
|
||||
{
|
||||
float fl2O255 = 2.0f / 255.0f;
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
Pixel( x, y, z, FBM_ATTR_RED ) = ( pBuffer[x].u + 128 ) * fl2O255 - 1.0f;
|
||||
Pixel( x, y, z, FBM_ATTR_GREEN ) = ( pBuffer[x].v + 128 ) * fl2O255 - 1.0f;
|
||||
Pixel( x, y, z, FBM_ATTR_BLUE ) = 0.0f;
|
||||
Pixel( x, y, z, FBM_ATTR_ALPHA ) = 1.0f;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::LoadFromBufferUVWQ( const T *pBuffer, int nPixelCount )
|
||||
{
|
||||
float fl2O255 = 2.0f / 255.0f;
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
Pixel( x, y, z, FBM_ATTR_RED ) = ( pBuffer[x].u + 128 ) * fl2O255 - 1.0f;
|
||||
Pixel( x, y, z, FBM_ATTR_GREEN ) = ( pBuffer[x].v + 128 ) * fl2O255 - 1.0f;
|
||||
Pixel( x, y, z, FBM_ATTR_BLUE ) = ( pBuffer[x].w + 128 ) * fl2O255 - 1.0f;
|
||||
Pixel( x, y, z, FBM_ATTR_ALPHA ) = ( pBuffer[x].q + 128 ) * fl2O255 - 1.0f;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::LoadFromBufferUVLX( const T *pBuffer, int nPixelCount )
|
||||
{
|
||||
float flOO255 = 1.0f / 255.0f;
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
Pixel( x, y, z, FBM_ATTR_RED ) = ( pBuffer[x].u + 128 ) * 2.0f * flOO255 - 1.0f;
|
||||
Pixel( x, y, z, FBM_ATTR_GREEN ) = ( pBuffer[x].v + 128 ) * 2.0f * flOO255 - 1.0f;
|
||||
Pixel( x, y, z, FBM_ATTR_BLUE ) = pBuffer[x].l * flOO255;
|
||||
Pixel( x, y, z, FBM_ATTR_ALPHA ) = 1.0f;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes an array of image data into a buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T > void FloatBitMap_t::WriteToBufferRGBFloat( T *pBuffer, int nPixelCount ) const
|
||||
{
|
||||
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
pBuffer[x].r = Pixel( x, y, z, FBM_ATTR_RED );
|
||||
pBuffer[x].g = Pixel( x, y, z, FBM_ATTR_GREEN );
|
||||
pBuffer[x].b = Pixel( x, y, z, FBM_ATTR_BLUE );
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::WriteToBufferRGB( T *pBuffer, int nPixelCount, const uint16 *pInvGammaTable ) const
|
||||
{
|
||||
int c;
|
||||
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_RED ) + 0.5f );
|
||||
pBuffer[x].RFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
|
||||
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_GREEN ) + 0.5f );
|
||||
pBuffer[x].GFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
|
||||
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_BLUE ) + 0.5f );
|
||||
pBuffer[x].BFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::WriteToBufferRGBAFloat( T *pBuffer, int nPixelCount ) const
|
||||
{
|
||||
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
pBuffer[x].r = Pixel( x, y, z, FBM_ATTR_RED );
|
||||
pBuffer[x].g = Pixel( x, y, z, FBM_ATTR_GREEN );
|
||||
pBuffer[x].b = Pixel( x, y, z, FBM_ATTR_BLUE );
|
||||
pBuffer[x].a = Pixel( x, y, z, FBM_ATTR_ALPHA );
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::WriteToBufferRGBA( T *pBuffer, int nPixelCount, const uint16 *pInvGammaTable ) const
|
||||
{
|
||||
int c;
|
||||
Assert( nPixelCount == NumCols() * NumRows() * NumSlices() );
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_RED ) + 0.5f );
|
||||
pBuffer[x].RFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
|
||||
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_GREEN ) + 0.5f );
|
||||
pBuffer[x].GFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
|
||||
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_BLUE ) + 0.5f );
|
||||
pBuffer[x].BFrom10Bit( pInvGammaTable[ clamp( c, 0, 1023 ) ] );
|
||||
c = ( int )( 1023.0f * Pixel( x, y, z, FBM_ATTR_ALPHA ) + 0.5f );
|
||||
pBuffer[x].AFrom10Bit( clamp( c, 0, 1023 ) );
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes to UV buffers
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T > void FloatBitMap_t::WriteToBufferUV( T *pBuffer, int nPixelCount ) const
|
||||
{
|
||||
int c;
|
||||
float fl255O2 = 255.0f / 2.0f;
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_RED ) + 1.0f ) );
|
||||
pBuffer[x].u = clamp( c, 0, 255 ) - 128;
|
||||
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_GREEN ) + 1.0f ) );
|
||||
pBuffer[x].v = clamp( c, 0, 255 ) - 128;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::WriteToBufferUVWQ( T *pBuffer, int nPixelCount ) const
|
||||
{
|
||||
int c;
|
||||
float fl255O2 = 255.0f / 2.0f;
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_RED ) + 1.0f ) );
|
||||
pBuffer[x].u = clamp( c, 0, 255 ) - 128;
|
||||
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_GREEN ) + 1.0f ) );
|
||||
pBuffer[x].v = clamp( c, 0, 255 ) - 128;
|
||||
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_BLUE ) + 1.0f ) );
|
||||
pBuffer[x].w = clamp( c, 0, 255 ) - 128;
|
||||
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_ALPHA ) + 1.0f ) );
|
||||
pBuffer[x].q = clamp( c, 0, 255 ) - 128;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class T > void FloatBitMap_t::WriteToBufferUVLX( T *pBuffer, int nPixelCount ) const
|
||||
{
|
||||
int c;
|
||||
float fl255O2 = 255.0f / 2.0f;
|
||||
for( int z = 0; z < NumSlices(); ++z )
|
||||
{
|
||||
for( int y = 0; y < NumRows(); ++y )
|
||||
{
|
||||
for( int x = 0; x < NumCols(); ++x )
|
||||
{
|
||||
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_RED ) + 1.0f ) );
|
||||
pBuffer[x].u = clamp( c, 0, 255 ) - 128;
|
||||
c = ( int )( fl255O2 * ( Pixel( x, y, z, FBM_ATTR_GREEN ) + 1.0f ) );
|
||||
pBuffer[x].v = clamp( c, 0, 255 ) - 128;
|
||||
c = ( int )( 255.0f * Pixel( x, y, z, FBM_ATTR_BLUE ) );
|
||||
pBuffer[x].l = clamp( c, 0, 255 );
|
||||
pBuffer[x].x = 255;
|
||||
}
|
||||
pBuffer += NumCols();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// a FloatCubeMap_t holds the floating point bitmaps for 6 faces of a cube map
|
||||
class FloatCubeMap_t
|
||||
{
|
||||
public:
|
||||
FloatBitMap_t face_maps[6];
|
||||
|
||||
FloatCubeMap_t(int xfsize, int yfsize)
|
||||
{
|
||||
// make an empty one with face dimensions xfsize x yfsize
|
||||
for(int f=0;f<6;f++)
|
||||
{
|
||||
face_maps[f].Init(xfsize,yfsize);
|
||||
}
|
||||
}
|
||||
|
||||
// load basenamebk,pfm, basenamedn.pfm, basenameft.pfm, ...
|
||||
FloatCubeMap_t(const char *basename);
|
||||
|
||||
// save basenamebk,pfm, basenamedn.pfm, basenameft.pfm, ...
|
||||
void WritePFMs(const char *basename);
|
||||
|
||||
Vector AverageColor(void)
|
||||
{
|
||||
Vector ret(0,0,0);
|
||||
int nfaces = 0;
|
||||
for( int f = 0;f < 6;f ++ )
|
||||
if ( face_maps[f].NumElements() )
|
||||
{
|
||||
nfaces++;
|
||||
ret += face_maps[f].AverageColor();
|
||||
}
|
||||
if ( nfaces )
|
||||
ret *= ( 1.0 / nfaces );
|
||||
return ret;
|
||||
}
|
||||
|
||||
float BrightestColor( void )
|
||||
{
|
||||
float ret = 0.0;
|
||||
for( int f = 0;f < 6;f ++ )
|
||||
if ( face_maps[f].NumElements() )
|
||||
{
|
||||
ret = MAX( ret, face_maps[f].BrightestColor() );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// generate the N-order spherical harmonic coeffcients to approxiamte this cubemap.
|
||||
// for order N, this will fill in 1 + 2 * N + N^2 vectors ( 0 = 0, 1 = 4, 2 = 9 .. )
|
||||
// vectors are used to hold the r,g,b coeffs
|
||||
void CalculateSphericalHarmonicApproximation( int nOrder, Vector *flCoeffs );
|
||||
|
||||
// inverse of above
|
||||
void GenerateFromSphericalHarmonics( int nOrder, Vector const *flCoeffs );
|
||||
|
||||
// resample a cubemap to one of possibly a lower resolution, using a given phong exponent.
|
||||
// dot-product weighting will be used for the filtering operation.
|
||||
void Resample(FloatCubeMap_t &dest, float flPhongExponent);
|
||||
|
||||
// returns the normalized direciton vector through a given pixel of a given face
|
||||
Vector PixelDirection(int face, int x, int y);
|
||||
|
||||
// returns the direction vector throught the center of a cubemap face
|
||||
Vector FaceNormal( int nFaceNumber );
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// Image Pyramid class.
|
||||
#define MAX_IMAGE_PYRAMID_LEVELS 16 // up to 64kx64k
|
||||
|
||||
enum ImagePyramidMode_t
|
||||
{
|
||||
PYRAMID_MODE_GAUSSIAN,
|
||||
};
|
||||
|
||||
class FloatImagePyramid_t
|
||||
{
|
||||
public:
|
||||
int m_nLevels;
|
||||
FloatBitMap_t *m_pLevels[MAX_IMAGE_PYRAMID_LEVELS]; // level 0 is highest res
|
||||
|
||||
FloatImagePyramid_t(void)
|
||||
{
|
||||
m_nLevels = 0;
|
||||
memset( m_pLevels, 0, sizeof( m_pLevels ));
|
||||
}
|
||||
|
||||
// build one. clones data from src for level 0.
|
||||
FloatImagePyramid_t(const FloatBitMap_t &src, ImagePyramidMode_t mode);
|
||||
|
||||
// read or write a Pixel from a given level. All coordinates are specified in the same domain as the base level.
|
||||
float &Pixel(int x, int y, int component, int level) const;
|
||||
|
||||
FloatBitMap_t *Level(int lvl) const
|
||||
{
|
||||
Assert( lvl < m_nLevels );
|
||||
return m_pLevels[lvl];
|
||||
}
|
||||
// rebuild all levels above the specified level
|
||||
void ReconstructLowerResolutionLevels(int starting_level);
|
||||
|
||||
~FloatImagePyramid_t(void);
|
||||
|
||||
void WriteTGAs(const char *basename) const; // outputs name_00.tga, name_01.tga,...
|
||||
};
|
||||
|
||||
#endif
|
679
public/bitmap/imageformat.h
Normal file
679
public/bitmap/imageformat.h
Normal file
@ -0,0 +1,679 @@
|
||||
//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef IMAGEFORMAT_H
|
||||
#define IMAGEFORMAT_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tier0/platform.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
#include "bitmap/imageformat_declarations.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Color structures
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma warning ( disable : 4293 )
|
||||
template< int nBitCount > FORCEINLINE int ConvertTo10Bit( int x )
|
||||
{
|
||||
switch ( nBitCount )
|
||||
{
|
||||
case 1:
|
||||
return ( x & 0x1 ) ? 0x3FF : 0;
|
||||
case 2:
|
||||
return ( x << 8 ) | ( x << 6 ) | ( x << 4 ) | ( x << 2 ) | x;
|
||||
case 3:
|
||||
return ( x << 7 ) | ( x << 4 ) | ( x << 1 ) | ( x >> 2 );
|
||||
case 4:
|
||||
return ( x << 6 ) | ( x << 2 ) | ( x >> 2 );
|
||||
default:
|
||||
#if defined(POSIX) || defined(_PS3)
|
||||
return ( x << ( 10 - nBitCount ) ) | ( x >> MAX( 0, MIN( 32, ( nBitCount - ( 10 - nBitCount ) ) ) ) );
|
||||
#else // !_PS3
|
||||
return ( x << ( 10 - nBitCount ) ) | ( x >> ( nBitCount - ( 10 - nBitCount ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#pragma warning ( default : 4293 )
|
||||
|
||||
template< int nBitCount > FORCEINLINE int ConvertFrom10Bit( int x )
|
||||
{
|
||||
return ( x >> ( 10 - nBitCount ) );
|
||||
}
|
||||
|
||||
struct R32F_t
|
||||
{
|
||||
float32 r;
|
||||
};
|
||||
|
||||
struct RG3232F_t
|
||||
{
|
||||
float32 r;
|
||||
float32 g;
|
||||
};
|
||||
|
||||
struct RGB323232F_t
|
||||
{
|
||||
float32 r;
|
||||
float32 g;
|
||||
float32 b;
|
||||
};
|
||||
|
||||
struct RGBA32323232F_t
|
||||
{
|
||||
float32 r;
|
||||
float32 g;
|
||||
float32 b;
|
||||
float32 a;
|
||||
};
|
||||
|
||||
struct RGBA1010102_t
|
||||
{
|
||||
uint32 r : 10;
|
||||
uint32 g : 10;
|
||||
uint32 b : 10;
|
||||
uint32 a : 2;
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<10>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<10>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<10>( b ); }
|
||||
inline int ATo10Bit( ) const { return ConvertTo10Bit<2>( a ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<10>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<10>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<10>( b10 ); }
|
||||
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<10>( a10 ); }
|
||||
};
|
||||
|
||||
struct BGRA1010102_t
|
||||
{
|
||||
uint32 b : 10;
|
||||
uint32 g : 10;
|
||||
uint32 r : 10;
|
||||
uint32 a : 2;
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<10>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<10>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<10>( b ); }
|
||||
inline int ATo10Bit( ) const { return ConvertTo10Bit<2>( a ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<10>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<10>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<10>( b10 ); }
|
||||
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<10>( a10 ); }
|
||||
};
|
||||
|
||||
struct BGRA8888_t
|
||||
{
|
||||
uint8 b; // change the order of names to change the
|
||||
uint8 g; // order of the output ARGB or BGRA, etc...
|
||||
uint8 r; // Last one is MSB, 1st is LSB.
|
||||
uint8 a;
|
||||
inline BGRA8888_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
*( unsigned int * )this = *( unsigned int * )∈
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
|
||||
inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
|
||||
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
|
||||
};
|
||||
|
||||
struct ABGR8888_t
|
||||
{
|
||||
uint8 a;
|
||||
uint8 b; // change the order of names to change the
|
||||
uint8 g; // order of the output ARGB or BGRA, etc...
|
||||
uint8 r; // Last one is MSB, 1st is LSB.
|
||||
inline ABGR8888_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r;
|
||||
g = in.g;
|
||||
b = in.b;
|
||||
a = in.a;
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
|
||||
inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
|
||||
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
|
||||
};
|
||||
|
||||
|
||||
struct RGBA8888_t
|
||||
{
|
||||
uint8 r; // change the order of names to change the
|
||||
uint8 g; // order of the output ARGB or BGRA, etc...
|
||||
uint8 b; // Last one is MSB, 1st is LSB.
|
||||
uint8 a;
|
||||
inline RGBA8888_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r;
|
||||
g = in.g;
|
||||
b = in.b;
|
||||
a = in.a;
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
|
||||
inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
|
||||
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
|
||||
};
|
||||
|
||||
struct RGB888_t
|
||||
{
|
||||
uint8 r;
|
||||
uint8 g;
|
||||
uint8 b;
|
||||
inline RGB888_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r;
|
||||
g = in.g;
|
||||
b = in.b;
|
||||
return *this;
|
||||
}
|
||||
inline bool operator==( const RGB888_t& in ) const
|
||||
{
|
||||
return ( r == in.r ) && ( g == in.g ) && ( b == in.b );
|
||||
}
|
||||
inline bool operator!=( const RGB888_t& in ) const
|
||||
{
|
||||
return ( r != in.r ) || ( g != in.g ) || ( b != in.b );
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
|
||||
};
|
||||
|
||||
struct BGR888_t
|
||||
{
|
||||
uint8 b;
|
||||
uint8 g;
|
||||
uint8 r;
|
||||
inline BGR888_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r;
|
||||
g = in.g;
|
||||
b = in.b;
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
|
||||
};
|
||||
|
||||
struct BGRX8888_t
|
||||
{
|
||||
uint8 b;
|
||||
uint8 g;
|
||||
uint8 r;
|
||||
uint8 x;
|
||||
inline BGRX8888_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r;
|
||||
g = in.g;
|
||||
b = in.b;
|
||||
x = 255;
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
|
||||
};
|
||||
|
||||
|
||||
// 360 uses this structure for x86 dxt decoding
|
||||
#if defined( _X360 )
|
||||
#pragma bitfield_order( push, lsb_to_msb )
|
||||
#elif defined( _PS3 )
|
||||
#pragma ms_struct on
|
||||
#pragma reverse_bitfields on
|
||||
#endif
|
||||
struct BGR565_t
|
||||
{
|
||||
uint16 b : 5; // order of names changes
|
||||
uint16 g : 6; // byte order of output to 32 bit
|
||||
uint16 r : 5;
|
||||
inline BGR565_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r >> 3;
|
||||
g = in.g >> 2;
|
||||
b = in.b >> 3;
|
||||
return *this;
|
||||
}
|
||||
inline BGR565_t &Set( int red, int green, int blue )
|
||||
{
|
||||
r = red >> 3;
|
||||
g = green >> 2;
|
||||
b = blue >> 3;
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<6>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<6>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
|
||||
};
|
||||
#if defined( _X360 )
|
||||
#pragma bitfield_order( pop )
|
||||
#elif defined( _PS3 )
|
||||
#pragma ms_struct off
|
||||
#pragma reverse_bitfields off
|
||||
#endif
|
||||
|
||||
struct BGRA5551_t
|
||||
{
|
||||
uint16 b : 5; // order of names changes
|
||||
uint16 g : 5; // byte order of output to 32 bit
|
||||
uint16 r : 5;
|
||||
uint16 a : 1;
|
||||
inline BGRA5551_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r >> 3;
|
||||
g = in.g >> 3;
|
||||
b = in.b >> 3;
|
||||
a = in.a >> 7;
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<5>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
|
||||
inline int ATo10Bit( ) const { return ConvertTo10Bit<1>( a ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<5>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
|
||||
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<1>( a10 ); }
|
||||
};
|
||||
|
||||
struct BGRA4444_t
|
||||
{
|
||||
uint16 b : 4; // order of names changes
|
||||
uint16 g : 4; // byte order of output to 32 bit
|
||||
uint16 r : 4;
|
||||
uint16 a : 4;
|
||||
inline BGRA4444_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r >> 4;
|
||||
g = in.g >> 4;
|
||||
b = in.b >> 4;
|
||||
a = in.a >> 4;
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<4>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<4>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<4>( b ); }
|
||||
inline int ATo10Bit( ) const { return ConvertTo10Bit<4>( a ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<4>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<4>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<4>( b10 ); }
|
||||
inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<4>( a10 ); }
|
||||
};
|
||||
|
||||
struct RGBX5551_t
|
||||
{
|
||||
uint16 r : 5;
|
||||
uint16 g : 5;
|
||||
uint16 b : 5;
|
||||
uint16 x : 1;
|
||||
inline RGBX5551_t& operator=( const BGRA8888_t& in )
|
||||
{
|
||||
r = in.r >> 3;
|
||||
g = in.g >> 3;
|
||||
b = in.b >> 3;
|
||||
return *this;
|
||||
}
|
||||
inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
|
||||
inline int GTo10Bit( ) const { return ConvertTo10Bit<5>( g ); }
|
||||
inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
|
||||
inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
|
||||
inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<5>( g10 ); }
|
||||
inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
|
||||
};
|
||||
|
||||
struct UV88_t
|
||||
{
|
||||
int8 u;
|
||||
int8 v;
|
||||
};
|
||||
|
||||
struct UVWQ8888_t
|
||||
{
|
||||
int8 u;
|
||||
int8 v;
|
||||
int8 w;
|
||||
int8 q;
|
||||
};
|
||||
|
||||
struct UVLX8888_t
|
||||
{
|
||||
int8 u;
|
||||
int8 v;
|
||||
uint8 l;
|
||||
uint8 x;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// some important constants
|
||||
//-----------------------------------------------------------------------------
|
||||
#define ARTWORK_GAMMA ( 2.2f )
|
||||
#define IMAGE_MAX_DIM ( 2048 )
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// information about each image format
|
||||
//-----------------------------------------------------------------------------
|
||||
struct ImageFormatInfo_t
|
||||
{
|
||||
const char* m_pName;
|
||||
uint8 m_nNumBytes;
|
||||
uint8 m_nNumRedBits;
|
||||
uint8 m_nNumGreenBits;
|
||||
uint8 m_nNumBlueBits;
|
||||
uint8 m_nNumAlphaBits;
|
||||
uint8 m_nNumDepthBits;
|
||||
uint8 m_nNumStencilBits;
|
||||
bool m_bIsCompressed:1;
|
||||
bool m_bIsFloat:1;
|
||||
bool m_bIsDepthFormat : 1;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Computes nice filters for a compression ratio
|
||||
//-----------------------------------------------------------------------------
|
||||
struct KernelInfo_t
|
||||
{
|
||||
float *m_pKernel;
|
||||
float *m_pInvKernel;
|
||||
int m_nWidth;
|
||||
int m_nHeight;
|
||||
int m_nDepth;
|
||||
int m_nDiameter;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates the target console type that a given operation is for.
|
||||
// (e.g. you may be running on the PC but you're generating textures
|
||||
// for X360 or PS3, so IsPC, IsX360, etc. do not work)
|
||||
//-----------------------------------------------------------------------------
|
||||
enum VtfConsoleFormatType_t
|
||||
{
|
||||
VTF_CONSOLE_360,
|
||||
VTF_CONSOLE_PS3
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Various methods related to pixelmaps and color formats
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace ImageLoader
|
||||
{
|
||||
bool GetInfo( const char *fileName, int *width, int *height, enum ImageFormat *imageFormat, float *sourceGamma );
|
||||
|
||||
// Generates a nice filter kernel
|
||||
void ComputeNiceFilterKernel( float flWRatio, float flHRatio, float flDRatio, KernelInfo_t *pKernel );
|
||||
void CleanupNiceFilterKernel( KernelInfo_t *pKernel );
|
||||
|
||||
// adjustedheight received the height adjusted for compression (/4 for dxt)
|
||||
int GetMemRequired( int width, int height, int depth, ImageFormat imageFormat, bool mipmap, int *pAdjustedHeightOut = NULL );
|
||||
int GetMemRequired( int width, int height, int depth, int nMipmapCount, ImageFormat imageFormat, int *pAdjustedHeightOut = NULL );
|
||||
|
||||
// This version is for mipmaps which are stored biggest level to smallest level in memory
|
||||
int GetMipMapLevelByteOffset( int width, int height, ImageFormat imageFormat, int skipMipLevels, int nDepth = 1 );
|
||||
|
||||
// This version is for mipmaps which are stored smallest level to largest level in memory
|
||||
int GetMipMapLevelByteOffsetReverse( int nWidth, int nHeight, int nDepth, int nTotalMipCount, ImageFormat imageFormat, int nMipLevel );
|
||||
|
||||
void GetMipMapLevelDimensions( int *width, int *height, int skipMipLevels );
|
||||
void GetMipMapLevelDimensions( int &nWidth, int &nHeight, int &nDepth, int nMipLevel );
|
||||
int GetNumMipMapLevels( int width, int height, int depth = 1 );
|
||||
bool Load( unsigned char *imageData, const char *fileName, int width, int height, ImageFormat imageFormat, float targetGamma, bool mipmap );
|
||||
bool Load( unsigned char *imageData, FILE *fp, int width, int height,
|
||||
enum ImageFormat imageFormat, float targetGamma, bool mipmap );
|
||||
|
||||
// convert from any image format to any other image format.
|
||||
// return false if the conversion cannot be performed.
|
||||
// Strides denote the number of bytes per each line,
|
||||
// by default assumes width * # of bytes per pixel
|
||||
bool ConvertImageFormat( const unsigned char *src, enum ImageFormat srcImageFormat,
|
||||
unsigned char *dst, enum ImageFormat dstImageFormat,
|
||||
int width, int height, int srcStride = 0, int dstStride = 0 );
|
||||
|
||||
// must be used in conjunction with ConvertImageFormat() to pre-swap and post-swap
|
||||
void PreConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width = 0, int stride = 0 );
|
||||
void PostConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width = 0, int stride = 0 );
|
||||
void ByteSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0 );
|
||||
bool IsFormatValidForConversion( ImageFormat fmt );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// convert back and forth from D3D format to ImageFormat, regardless of
|
||||
// whether it's supported or not
|
||||
// FIXME: Move into shaderapidx8/rendersystemdx9
|
||||
//-----------------------------------------------------------------------------
|
||||
ImageFormat D3DFormatToImageFormat( D3DFORMAT format );
|
||||
D3DFORMAT ImageFormatToD3DFormat( ImageFormat format );
|
||||
|
||||
// Flags for ResampleRGBA8888
|
||||
enum
|
||||
{
|
||||
RESAMPLE_NORMALMAP = 0x1,
|
||||
RESAMPLE_ALPHATEST = 0x2,
|
||||
RESAMPLE_NICE_FILTER = 0x4,
|
||||
RESAMPLE_CLAMPS = 0x8,
|
||||
RESAMPLE_CLAMPT = 0x10,
|
||||
RESAMPLE_CLAMPU = 0x20,
|
||||
};
|
||||
|
||||
struct ResampleInfo_t
|
||||
{
|
||||
|
||||
ResampleInfo_t() : m_nFlags(0), m_flAlphaThreshhold(0.4f), m_flAlphaHiFreqThreshhold(0.4f), m_nSrcDepth(1), m_nDestDepth(1)
|
||||
{
|
||||
m_flColorScale[0] = 1.0f, m_flColorScale[1] = 1.0f, m_flColorScale[2] = 1.0f, m_flColorScale[3] = 1.0f;
|
||||
m_flColorGoal[0] = 0.0f, m_flColorGoal[1] = 0.0f, m_flColorGoal[2] = 0.0f, m_flColorGoal[3] = 0.0f;
|
||||
}
|
||||
|
||||
unsigned char *m_pSrc;
|
||||
unsigned char *m_pDest;
|
||||
|
||||
int m_nSrcWidth;
|
||||
int m_nSrcHeight;
|
||||
int m_nSrcDepth;
|
||||
|
||||
int m_nDestWidth;
|
||||
int m_nDestHeight;
|
||||
int m_nDestDepth;
|
||||
|
||||
float m_flSrcGamma;
|
||||
float m_flDestGamma;
|
||||
|
||||
float m_flColorScale[4]; // Color scale factors RGBA
|
||||
float m_flColorGoal[4]; // Color goal values RGBA DestColor = ColorGoal + scale * (SrcColor - ColorGoal)
|
||||
|
||||
float m_flAlphaThreshhold;
|
||||
float m_flAlphaHiFreqThreshhold;
|
||||
|
||||
int m_nFlags;
|
||||
};
|
||||
|
||||
bool ResampleRGBA8888( const ResampleInfo_t &info );
|
||||
bool ResampleRGBA16161616( const ResampleInfo_t &info );
|
||||
bool ResampleRGB323232F( const ResampleInfo_t &info );
|
||||
bool ResampleRGBA32323232F( const ResampleInfo_t &info );
|
||||
|
||||
void ConvertNormalMapRGBA8888ToDUDVMapUVLX8888( const unsigned char *src, int width, int height, unsigned char *dst_ );
|
||||
void ConvertNormalMapRGBA8888ToDUDVMapUVWQ8888( const unsigned char *src, int width, int height, unsigned char *dst_ );
|
||||
void ConvertNormalMapRGBA8888ToDUDVMapUV88( const unsigned char *src, int width, int height, unsigned char *dst_ );
|
||||
void ConvertNormalMapARGB8888ToDXT5GA( const unsigned char *src, unsigned char *dst, int width, int height );
|
||||
|
||||
void ConvertIA88ImageToNormalMapRGBA8888( const unsigned char *src, int width,
|
||||
int height, unsigned char *dst,
|
||||
float bumpScale );
|
||||
|
||||
void NormalizeNormalMapRGBA8888( unsigned char *src, int numTexels );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gamma correction
|
||||
//-----------------------------------------------------------------------------
|
||||
void GammaCorrectRGBA8888( unsigned char *src, unsigned char* dst,
|
||||
int width, int height, int depth, float srcGamma, float dstGamma );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes a gamma table
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConstructGammaTable( unsigned char* pTable, float srcGamma, float dstGamma );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gamma corrects using a previously constructed gamma table
|
||||
//-----------------------------------------------------------------------------
|
||||
void GammaCorrectRGBA8888( unsigned char* pSrc, unsigned char* pDst,
|
||||
int width, int height, int depth, unsigned char* pGammaTable );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Generates a number of mipmap levels
|
||||
//-----------------------------------------------------------------------------
|
||||
void GenerateMipmapLevels( unsigned char* pSrc, unsigned char* pDst, int width,
|
||||
int height, int depth, ImageFormat imageFormat, float srcGamma, float dstGamma,
|
||||
int numLevels = 0 );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// operations on square images (src and dst can be the same)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RotateImageLeft( const unsigned char *src, unsigned char *dst,
|
||||
int widthHeight, ImageFormat imageFormat );
|
||||
bool RotateImage180( const unsigned char *src, unsigned char *dst,
|
||||
int widthHeight, ImageFormat imageFormat );
|
||||
bool FlipImageVertically( void *pSrc, void *pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0 );
|
||||
bool FlipImageHorizontally( void *pSrc, void *pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0 );
|
||||
bool SwapAxes( unsigned char *src,
|
||||
int widthHeight, ImageFormat imageFormat );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns info about each image format
|
||||
//-----------------------------------------------------------------------------
|
||||
const ImageFormatInfo_t &ImageFormatInfo( ImageFormat fmt );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the name of the image format
|
||||
//-----------------------------------------------------------------------------
|
||||
inline char const* GetName( ImageFormat fmt )
|
||||
{
|
||||
return ImageFormatInfo(fmt).m_pName;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the size of the image format in bytes. Be careful - compressed formats will return 0
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int SizeInBytes( ImageFormat fmt )
|
||||
{
|
||||
return ImageFormatInfo(fmt).m_nNumBytes;
|
||||
}
|
||||
|
||||
/// return the byte size of a given w/h. Works with compressed formats
|
||||
inline int SizeInBytes( ImageFormat fmt, int nWidth, int nHeight )
|
||||
{
|
||||
ImageFormatInfo_t const &info = ImageFormatInfo( fmt );
|
||||
if ( info.m_bIsCompressed )
|
||||
{
|
||||
// !!BUG!! hardcoded 4x4 block size, dxt1, dxt5
|
||||
int nNumBytesPerBlock = 8;
|
||||
if ( fmt == IMAGE_FORMAT_DXT5 )
|
||||
{
|
||||
nNumBytesPerBlock = 16;
|
||||
}
|
||||
return nNumBytesPerBlock * ( ( nWidth + 3 ) / 4 ) * ( ( nHeight +3 )/ 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return info.m_nNumBytes * nWidth * nHeight;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the image format support transparency?
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool IsTransparent( ImageFormat fmt )
|
||||
{
|
||||
return ImageFormatInfo(fmt).m_nNumAlphaBits > 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is the image format compressed?
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool IsCompressed( ImageFormat fmt )
|
||||
{
|
||||
return ImageFormatInfo(fmt).m_bIsCompressed;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is the image format compressed?
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool IsDepthFormat( ImageFormat fmt )
|
||||
{
|
||||
return ImageFormatInfo(fmt).m_bIsDepthFormat;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is any channel > 8 bits?
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool HasChannelLargerThan8Bits( ImageFormat fmt )
|
||||
{
|
||||
ImageFormatInfo_t info = ImageFormatInfo(fmt);
|
||||
return ( info.m_nNumRedBits > 8 || info.m_nNumGreenBits > 8 || info.m_nNumBlueBits > 8 || info.m_nNumAlphaBits > 8 );
|
||||
}
|
||||
|
||||
inline bool IsFloatFormat( ImageFormat fmt )
|
||||
{
|
||||
return ( fmt == IMAGE_FORMAT_RGBA16161616F ) ||
|
||||
( fmt == IMAGE_FORMAT_RG1616F ) ||
|
||||
( fmt == IMAGE_FORMAT_R32F ) ||
|
||||
( fmt == IMAGE_FORMAT_RG3232F ) ||
|
||||
( fmt == IMAGE_FORMAT_RGB323232F ) ||
|
||||
( fmt == IMAGE_FORMAT_RGBA32323232F );
|
||||
}
|
||||
|
||||
inline bool IsRuntimeCompressed( ImageFormat fmt )
|
||||
{
|
||||
return ( fmt == IMAGE_FORMAT_DXT1_RUNTIME ) || ( fmt == IMAGE_FORMAT_DXT5_RUNTIME );
|
||||
}
|
||||
|
||||
} // end namespace ImageLoader
|
||||
|
||||
|
||||
#endif // IMAGEFORMAT_H
|
189
public/bitmap/imageformat_declarations.h
Normal file
189
public/bitmap/imageformat_declarations.h
Normal file
@ -0,0 +1,189 @@
|
||||
//========== Copyright <20> Valve Corporation, All rights reserved. ========
|
||||
|
||||
#ifndef IMAGEFORMAT_DECLARATIONS_HDR
|
||||
#define IMAGEFORMAT_DECLARATIONS_HDR
|
||||
|
||||
|
||||
enum NormalDecodeMode_t
|
||||
{
|
||||
NORMAL_DECODE_NONE = 0,
|
||||
NORMAL_DECODE_ATI2N = 1,
|
||||
NORMAL_DECODE_ATI2N_ALPHA = 2
|
||||
};
|
||||
|
||||
// Forward declaration
|
||||
#ifdef _WIN32
|
||||
typedef enum _D3DFORMAT D3DFORMAT;
|
||||
typedef enum DXGI_FORMAT;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The various image format types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// don't bitch that inline functions aren't used!!!!
|
||||
#ifndef SPU
|
||||
#pragma warning(disable : 4514)
|
||||
#endif
|
||||
|
||||
enum ImageFormat
|
||||
{
|
||||
IMAGE_FORMAT_DEFAULT = -2, // Use this image format if you want to perform tool operations on the texture
|
||||
IMAGE_FORMAT_UNKNOWN = -1,
|
||||
IMAGE_FORMAT_RGBA8888 = 0,
|
||||
IMAGE_FORMAT_ABGR8888,
|
||||
IMAGE_FORMAT_RGB888,
|
||||
IMAGE_FORMAT_BGR888,
|
||||
IMAGE_FORMAT_RGB565,
|
||||
IMAGE_FORMAT_I8,
|
||||
IMAGE_FORMAT_IA88,
|
||||
IMAGE_FORMAT_P8,
|
||||
IMAGE_FORMAT_A8,
|
||||
IMAGE_FORMAT_RGB888_BLUESCREEN,
|
||||
IMAGE_FORMAT_BGR888_BLUESCREEN,
|
||||
IMAGE_FORMAT_ARGB8888,
|
||||
IMAGE_FORMAT_BGRA8888,
|
||||
IMAGE_FORMAT_DXT1,
|
||||
IMAGE_FORMAT_DXT3,
|
||||
IMAGE_FORMAT_DXT5,
|
||||
IMAGE_FORMAT_BGRX8888,
|
||||
IMAGE_FORMAT_BGR565,
|
||||
IMAGE_FORMAT_BGRX5551,
|
||||
IMAGE_FORMAT_BGRA4444,
|
||||
IMAGE_FORMAT_DXT1_ONEBITALPHA,
|
||||
IMAGE_FORMAT_BGRA5551,
|
||||
IMAGE_FORMAT_UV88,
|
||||
IMAGE_FORMAT_UVWQ8888,
|
||||
IMAGE_FORMAT_RGBA16161616F,
|
||||
IMAGE_FORMAT_RGBA16161616,
|
||||
IMAGE_FORMAT_UVLX8888,
|
||||
IMAGE_FORMAT_R32F, // Single-channel 32-bit floating point
|
||||
IMAGE_FORMAT_RGB323232F, // NOTE: D3D9 does not have this format
|
||||
IMAGE_FORMAT_RGBA32323232F,
|
||||
IMAGE_FORMAT_RG1616F,
|
||||
IMAGE_FORMAT_RG3232F,
|
||||
IMAGE_FORMAT_RGBX8888,
|
||||
|
||||
IMAGE_FORMAT_NULL, // Dummy format which takes no video memory
|
||||
|
||||
// Compressed normal map formats
|
||||
IMAGE_FORMAT_ATI2N, // One-surface ATI2N / DXN format
|
||||
IMAGE_FORMAT_ATI1N, // Two-surface ATI1N format
|
||||
|
||||
IMAGE_FORMAT_RGBA1010102, // 10 bit-per component render targets
|
||||
IMAGE_FORMAT_BGRA1010102,
|
||||
IMAGE_FORMAT_R16F, // 16 bit FP format
|
||||
|
||||
// Depth-stencil texture formats
|
||||
IMAGE_FORMAT_D16,
|
||||
IMAGE_FORMAT_D15S1,
|
||||
IMAGE_FORMAT_D32,
|
||||
IMAGE_FORMAT_D24S8,
|
||||
IMAGE_FORMAT_LINEAR_D24S8,
|
||||
IMAGE_FORMAT_D24X8,
|
||||
IMAGE_FORMAT_D24X4S4,
|
||||
IMAGE_FORMAT_D24FS8,
|
||||
IMAGE_FORMAT_D16_SHADOW, // Specific formats for shadow mapping
|
||||
IMAGE_FORMAT_D24X8_SHADOW, // Specific formats for shadow mapping
|
||||
|
||||
// supporting these specific formats as non-tiled for procedural cpu access (360-specific)
|
||||
IMAGE_FORMAT_LINEAR_BGRX8888,
|
||||
IMAGE_FORMAT_LINEAR_RGBA8888,
|
||||
IMAGE_FORMAT_LINEAR_ABGR8888,
|
||||
IMAGE_FORMAT_LINEAR_ARGB8888,
|
||||
IMAGE_FORMAT_LINEAR_BGRA8888,
|
||||
IMAGE_FORMAT_LINEAR_RGB888,
|
||||
IMAGE_FORMAT_LINEAR_BGR888,
|
||||
IMAGE_FORMAT_LINEAR_BGRX5551,
|
||||
IMAGE_FORMAT_LINEAR_I8,
|
||||
IMAGE_FORMAT_LINEAR_RGBA16161616,
|
||||
IMAGE_FORMAT_LINEAR_A8,
|
||||
IMAGE_FORMAT_LINEAR_DXT1,
|
||||
IMAGE_FORMAT_LINEAR_DXT3,
|
||||
IMAGE_FORMAT_LINEAR_DXT5,
|
||||
|
||||
IMAGE_FORMAT_LE_BGRX8888,
|
||||
IMAGE_FORMAT_LE_BGRA8888,
|
||||
|
||||
// these are used for runtime conversion to DXT1/5
|
||||
IMAGE_FORMAT_DXT1_RUNTIME,
|
||||
IMAGE_FORMAT_DXT5_RUNTIME,
|
||||
|
||||
// special depth format
|
||||
IMAGE_FORMAT_INTZ,
|
||||
|
||||
NUM_IMAGE_FORMATS
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if defined( DX_TO_GL_ABSTRACTION ) || defined( _PS3 )
|
||||
typedef enum _D3DFORMAT
|
||||
{
|
||||
D3DFMT_INDEX16,
|
||||
D3DFMT_D16,
|
||||
D3DFMT_D24S8,
|
||||
D3DFMT_A8R8G8B8,
|
||||
D3DFMT_A4R4G4B4,
|
||||
D3DFMT_X8R8G8B8,
|
||||
D3DFMT_R5G6R5,
|
||||
D3DFMT_X1R5G5B5,
|
||||
D3DFMT_A1R5G5B5,
|
||||
D3DFMT_L8,
|
||||
D3DFMT_A8L8,
|
||||
D3DFMT_A,
|
||||
D3DFMT_DXT1,
|
||||
D3DFMT_DXT3,
|
||||
D3DFMT_DXT5,
|
||||
D3DFMT_V8U8,
|
||||
D3DFMT_Q8W8V8U8,
|
||||
D3DFMT_X8L8V8U8,
|
||||
D3DFMT_A16B16G16R16F,
|
||||
D3DFMT_A16B16G16R16,
|
||||
D3DFMT_R32F,
|
||||
D3DFMT_A32B32G32R32F,
|
||||
D3DFMT_R8G8B8,
|
||||
D3DFMT_D24X4S4,
|
||||
D3DFMT_A8,
|
||||
D3DFMT_R5G6B5,
|
||||
D3DFMT_D15S1,
|
||||
D3DFMT_D24X8,
|
||||
D3DFMT_VERTEXDATA,
|
||||
D3DFMT_INDEX32,
|
||||
|
||||
// new d3d format enums for Source main engine (i.e Portal2, AS, Dota)
|
||||
D3DFMT_D24FS8,
|
||||
D3DFMT_A8B8G8R8,
|
||||
D3DFMT_P8,
|
||||
D3DFMT_G16R16F,
|
||||
D3DFMT_G32R32F,
|
||||
D3DFMT_X8B8G8R8,
|
||||
D3DFMT_A2B10G10R10,
|
||||
D3DFMT_A2R10G10B10,
|
||||
D3DFMT_R16F,
|
||||
D3DFMT_D32,
|
||||
|
||||
// adding fake D3D format names for the vendor specific ones (eases debugging/logging)
|
||||
|
||||
// NV shadow depth tex
|
||||
D3DFMT_NV_INTZ = 0x5a544e49, // MAKEFOURCC('I','N','T','Z')
|
||||
D3DFMT_NV_RAWZ = 0x5a574152, // MAKEFOURCC('R','A','W','Z')
|
||||
|
||||
// NV null tex
|
||||
D3DFMT_NV_NULL = 0x4c4c554e, // MAKEFOURCC('N','U','L','L')
|
||||
|
||||
// ATI shadow depth tex
|
||||
D3DFMT_ATI_D16 = 0x36314644, // MAKEFOURCC('D','F','1','6')
|
||||
D3DFMT_ATI_D24S8 = 0x34324644, // MAKEFOURCC('D','F','2','4')
|
||||
|
||||
// ATI 1N and 2N compressed tex
|
||||
D3DFMT_ATI_2N = 0x32495441, // MAKEFOURCC('A', 'T', 'I', '2')
|
||||
D3DFMT_ATI_1N = 0x31495441, // MAKEFOURCC('A', 'T', 'I', '1')
|
||||
|
||||
D3DFMT_UNKNOWN
|
||||
} D3DFORMAT;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
105
public/bitmap/psd.h
Normal file
105
public/bitmap/psd.h
Normal file
@ -0,0 +1,105 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Methods relating to saving + loading PSD files (photoshop)
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef PSD_H
|
||||
#define PSD_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "bitmap/imageformat.h" //ImageFormat enum definition
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlBuffer;
|
||||
struct Bitmap_t;
|
||||
|
||||
class PSDImageResources
|
||||
{
|
||||
public:
|
||||
enum Resource {
|
||||
eResFileInfo = 0x0404
|
||||
};
|
||||
|
||||
struct ResElement {
|
||||
Resource m_eType;
|
||||
// unsigned char m_pReserved[4];
|
||||
unsigned short m_numBytes;
|
||||
unsigned char const *m_pvData;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit PSDImageResources( unsigned int numBytes, unsigned char const *pvBuffer ) : m_numBytes( numBytes ), m_pvBuffer( pvBuffer ) {}
|
||||
|
||||
public:
|
||||
ResElement FindElement( Resource eType ) const;
|
||||
|
||||
protected:
|
||||
unsigned int m_numBytes;
|
||||
unsigned char const * m_pvBuffer;
|
||||
};
|
||||
|
||||
class PSDResFileInfo
|
||||
{
|
||||
public:
|
||||
enum ResFileInfo {
|
||||
eTitle = 0x05,
|
||||
eAuthor = 0x50,
|
||||
eAuthorTitle = 0x55,
|
||||
eDescription = 0x78,
|
||||
eDescriptionWriter = 0x7A,
|
||||
eKeywords = 0x19,
|
||||
eCopyrightNotice = 0x74
|
||||
};
|
||||
|
||||
struct ResFileInfoElement {
|
||||
ResFileInfo m_eType;
|
||||
unsigned short m_numBytes;
|
||||
unsigned char const *m_pvData;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit PSDResFileInfo( PSDImageResources::ResElement res ) : m_res( res ) {}
|
||||
|
||||
public:
|
||||
ResFileInfoElement FindElement( ResFileInfo eType ) const;
|
||||
|
||||
protected:
|
||||
PSDImageResources::ResElement m_res;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is a file a PSD file?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsPSDFile( const char *pFileName, const char *pPathID );
|
||||
bool IsPSDFile( CUtlBuffer &buf );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns information about the PSD file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool PSDGetInfo( const char *pFileName, const char *pPathID, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma );
|
||||
bool PSDGetInfo( CUtlBuffer &buf, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Get PSD file image resources, pointers refer into the utlbuffer
|
||||
//-----------------------------------------------------------------------------
|
||||
PSDImageResources PSDGetImageResources( CUtlBuffer &buf );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads the PSD file into the specified buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
bool PSDReadFileRGBA8888( CUtlBuffer &buf, Bitmap_t &bitmap );
|
||||
bool PSDReadFileRGBA8888( const char *pFileName, const char *pPathID, Bitmap_t &bitmap );
|
||||
|
||||
|
||||
#endif // PSD_H
|
136
public/bitmap/psheet.h
Normal file
136
public/bitmap/psheet.h
Normal file
@ -0,0 +1,136 @@
|
||||
//===== Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: sheet definitions for particles and other sprite functions
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef PSHEET_H
|
||||
#define PSHEET_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/utlobjectreference.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
#include "tier1/utlvector.h"
|
||||
|
||||
class CUtlBuffer;
|
||||
|
||||
// classes for keeping a dictionary of sheet files in memory. A sheet is a bunch of frames packewd
|
||||
// within one texture. Each sheet has 1 or more frame sequences stored for it.
|
||||
|
||||
|
||||
// for fast lookups to retrieve sequence data, we store the sequence information discretized into
|
||||
// a fixed # of frames. If this discretenesss is a visual problem, you can lerp the blend values to get it
|
||||
// perfect.
|
||||
#define SEQUENCE_SAMPLE_COUNT 512
|
||||
|
||||
#define MAX_IMAGES_PER_FRAME_ON_DISK 4
|
||||
#define MAX_IMAGES_PER_FRAME_IN_MEMORY 2
|
||||
|
||||
struct SequenceSampleTextureCoords_t
|
||||
{
|
||||
float m_fLeft_U0;
|
||||
float m_fTop_V0;
|
||||
float m_fRight_U0;
|
||||
float m_fBottom_V0;
|
||||
|
||||
float m_fLeft_U1;
|
||||
float m_fTop_V1;
|
||||
float m_fRight_U1;
|
||||
float m_fBottom_V1;
|
||||
};
|
||||
|
||||
struct SheetSequenceSample_t
|
||||
{
|
||||
// coordinates of two rectangles (old and next frame coords)
|
||||
|
||||
SequenceSampleTextureCoords_t m_TextureCoordData[MAX_IMAGES_PER_FRAME_IN_MEMORY];
|
||||
|
||||
float m_fBlendFactor;
|
||||
|
||||
void CopyFirstFrameToOthers(void)
|
||||
{
|
||||
// for old format files only supporting one image per frame
|
||||
for(int i=1; i < MAX_IMAGES_PER_FRAME_IN_MEMORY; i++)
|
||||
{
|
||||
m_TextureCoordData[i] = m_TextureCoordData[0];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
enum SheetSequenceFlags_t
|
||||
{
|
||||
SEQ_FLAG_CLAMP = 0x1, // as opposed to loop
|
||||
SEQ_FLAG_NO_ALPHA = 0x2, // packed as sequence-rgb (alpha channel should be ignored)
|
||||
SEQ_FLAG_NO_COLOR = 0x4, // packed as sequence-a (color channels should be ignored)
|
||||
};
|
||||
|
||||
class CSheet
|
||||
{
|
||||
public:
|
||||
// read form a .sht file. This is the usual thing to do
|
||||
CSheet( CUtlBuffer &buf );
|
||||
CSheet( void );
|
||||
~CSheet( void );
|
||||
|
||||
const SheetSequenceSample_t *GetSampleForSequence( float flAge, float flAgeScale, int nSequence, bool bForceLoop );
|
||||
|
||||
// references for smart ptrs
|
||||
CUtlReferenceList<CSheet> m_References;
|
||||
|
||||
struct SheetInfo_t
|
||||
{
|
||||
SheetSequenceSample_t *m_pSamples;
|
||||
uint8 m_SeqFlags;
|
||||
bool m_bSequenceIsCopyOfAnotherSequence;
|
||||
int16 m_nNumFrames;
|
||||
float m_flFrameSpan;
|
||||
};
|
||||
|
||||
CUtlVector< SheetInfo_t > m_SheetInfo;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class IMesh;
|
||||
class IMaterial;
|
||||
|
||||
// A heavier-weight version of CSheet with more bells and whistles
|
||||
|
||||
class CSheetExtended
|
||||
{
|
||||
public:
|
||||
explicit CSheetExtended( IMaterial* pMaterial );
|
||||
~CSheetExtended();
|
||||
|
||||
int GetSheetSequenceCount();
|
||||
int GetNthSequenceIndex( int nSequenceNumber );
|
||||
const SheetSequenceSample_t *GetSampleForSequence( float flAge, float flAgeScale, int nSequence, bool bForceLoop );
|
||||
float GetSequenceTimeSpan( int nSequenceIndex );
|
||||
|
||||
void DrawSheet( IMesh *pMesh, const Vector &vCenter, float flRadius, int nSheetSequence, float flAge, float flSheetPreviewSpeed, bool bLoopSheetPreview, int nSecondarySequence=-1, bool bOverrideSpriteCard=false );
|
||||
|
||||
bool ValidSheetData();
|
||||
|
||||
bool SequenceHasAlphaData( int nSequenceIndex );
|
||||
bool SequenceHasColorData( int nSequenceIndex );
|
||||
|
||||
// Helper
|
||||
static bool IsMaterialSeparateAlphaColorMaterial( IMaterial* pMat );
|
||||
static bool IsMaterialDualSequence( IMaterial* pMat );
|
||||
|
||||
private:
|
||||
void LoadFromBuffer( CUtlBuffer& buf );
|
||||
void LoadFromMaterial( IMaterial* pMaterial );
|
||||
|
||||
// TEMP: Store in a CSheet for now - eventually we'll want more data
|
||||
CSheet* m_pSheetData;
|
||||
CMaterialReference m_Material;
|
||||
};
|
||||
|
||||
|
||||
#endif // PSHEET_H
|
||||
|
624
public/bitmap/stb_dxt.h
Normal file
624
public/bitmap/stb_dxt.h
Normal file
@ -0,0 +1,624 @@
|
||||
// stb_dxt.h - v1.04 - DXT1/DXT5 compressor - public domain
|
||||
// original by fabian "ryg" giesen - ported to C by stb
|
||||
// use '#define STB_DXT_IMPLEMENTATION' before including to create the implementation
|
||||
//
|
||||
// USAGE:
|
||||
// call stb_compress_dxt_block() for every block (you must pad)
|
||||
// source should be a 4x4 block of RGBA data in row-major order;
|
||||
// A is ignored if you specify alpha=0; you can turn on dithering
|
||||
// and "high quality" using mode.
|
||||
//
|
||||
// version history:
|
||||
// v1.04 - (ryg) default to no rounding bias for lerped colors (as per S3TC/DX10 spec);
|
||||
// single color match fix (allow for inexact color interpolation);
|
||||
// optimal DXT5 index finder; "high quality" mode that runs multiple refinement steps.
|
||||
// v1.03 - (stb) endianness support
|
||||
// v1.02 - (stb) fix alpha encoding bug
|
||||
// v1.01 - (stb) fix bug converting to RGB that messed up quality, thanks ryg & cbloom
|
||||
// v1.00 - (stb) first release
|
||||
|
||||
#ifndef STB_INCLUDE_STB_DXT_H
|
||||
#define STB_INCLUDE_STB_DXT_H
|
||||
|
||||
// compression mode (bitflags)
|
||||
#define STB_DXT_NORMAL 0
|
||||
#define STB_DXT_DITHER 1 // use dithering. dubious win. never use for normal maps and the like!
|
||||
#define STB_DXT_HIGHQUAL 2 // high quality mode, does two refinement steps instead of 1. ~30-40% slower.
|
||||
|
||||
void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode);
|
||||
#define STB_COMPRESS_DXT_BLOCK
|
||||
|
||||
#ifdef STB_DXT_IMPLEMENTATION
|
||||
|
||||
// configuration options for DXT encoder. set them in the project/makefile or just define
|
||||
// them at the top.
|
||||
|
||||
// STB_DXT_USE_ROUNDING_BIAS
|
||||
// use a rounding bias during color interpolation. this is closer to what "ideal"
|
||||
// interpolation would do but doesn't match the S3TC/DX10 spec. old versions (pre-1.03)
|
||||
// implicitly had this turned on.
|
||||
//
|
||||
// in case you're targeting a specific type of hardware (e.g. console programmers):
|
||||
// NVidia and Intel GPUs (as of 2010) as well as DX9 ref use DXT decoders that are closer
|
||||
// to STB_DXT_USE_ROUNDING_BIAS. AMD/ATI, S3 and DX10 ref are closer to rounding with no bias.
|
||||
// you also see "(a*5 + b*3) / 8" on some old GPU designs.
|
||||
// #define STB_DXT_USE_ROUNDING_BIAS
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h> // memset
|
||||
|
||||
static unsigned char stb__Expand5[32];
|
||||
static unsigned char stb__Expand6[64];
|
||||
static unsigned char stb__OMatch5[256][2];
|
||||
static unsigned char stb__OMatch6[256][2];
|
||||
static unsigned char stb__QuantRBTab[256+16];
|
||||
static unsigned char stb__QuantGTab[256+16];
|
||||
|
||||
static int stb__Mul8Bit(int a, int b)
|
||||
{
|
||||
int t = a*b + 128;
|
||||
return (t + (t >> 8)) >> 8;
|
||||
}
|
||||
|
||||
static void stb__From16Bit(unsigned char *out, unsigned short v)
|
||||
{
|
||||
int rv = (v & 0xf800) >> 11;
|
||||
int gv = (v & 0x07e0) >> 5;
|
||||
int bv = (v & 0x001f) >> 0;
|
||||
|
||||
out[0] = stb__Expand5[rv];
|
||||
out[1] = stb__Expand6[gv];
|
||||
out[2] = stb__Expand5[bv];
|
||||
out[3] = 0;
|
||||
}
|
||||
|
||||
static unsigned short stb__As16Bit(int r, int g, int b)
|
||||
{
|
||||
return (stb__Mul8Bit(r,31) << 11) + (stb__Mul8Bit(g,63) << 5) + stb__Mul8Bit(b,31);
|
||||
}
|
||||
|
||||
// linear interpolation at 1/3 point between a and b, using desired rounding type
|
||||
static int stb__Lerp13(int a, int b)
|
||||
{
|
||||
#ifdef STB_DXT_USE_ROUNDING_BIAS
|
||||
// with rounding bias
|
||||
return a + stb__Mul8Bit(b-a, 0x55);
|
||||
#else
|
||||
// without rounding bias
|
||||
// replace "/ 3" by "* 0xaaab) >> 17" if your compiler sucks or you really need every ounce of speed.
|
||||
return (2*a + b) / 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
// lerp RGB color
|
||||
static void stb__Lerp13RGB(unsigned char *out, unsigned char *p1, unsigned char *p2)
|
||||
{
|
||||
out[0] = stb__Lerp13(p1[0], p2[0]);
|
||||
out[1] = stb__Lerp13(p1[1], p2[1]);
|
||||
out[2] = stb__Lerp13(p1[2], p2[2]);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
// compute table to reproduce constant colors as accurately as possible
|
||||
static void stb__PrepareOptTable(unsigned char *Table,const unsigned char *expand,int size)
|
||||
{
|
||||
int i,mn,mx;
|
||||
for (i=0;i<256;i++) {
|
||||
int bestErr = 256;
|
||||
for (mn=0;mn<size;mn++) {
|
||||
for (mx=0;mx<size;mx++) {
|
||||
int mine = expand[mn];
|
||||
int maxe = expand[mx];
|
||||
int err = abs(stb__Lerp13(maxe, mine) - i);
|
||||
|
||||
// DX10 spec says that interpolation must be within 3% of "correct" result,
|
||||
// add this as error term. (normally we'd expect a random distribution of
|
||||
// +-1.5% error, but nowhere in the spec does it say that the error has to be
|
||||
// unbiased - better safe than sorry).
|
||||
err += abs(maxe - mine) * 3 / 100;
|
||||
|
||||
if(err < bestErr)
|
||||
{
|
||||
Table[i*2+0] = mx;
|
||||
Table[i*2+1] = mn;
|
||||
bestErr = err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void stb__EvalColors(unsigned char *color,unsigned short c0,unsigned short c1)
|
||||
{
|
||||
stb__From16Bit(color+ 0, c0);
|
||||
stb__From16Bit(color+ 4, c1);
|
||||
stb__Lerp13RGB(color+ 8, color+0, color+4);
|
||||
stb__Lerp13RGB(color+12, color+4, color+0);
|
||||
}
|
||||
|
||||
// Block dithering function. Simply dithers a block to 565 RGB.
|
||||
// (Floyd-Steinberg)
|
||||
static void stb__DitherBlock(unsigned char *dest, unsigned char *block)
|
||||
{
|
||||
int err[8],*ep1 = err,*ep2 = err+4, *et;
|
||||
int ch,y;
|
||||
|
||||
// process channels seperately
|
||||
for (ch=0; ch<3; ++ch) {
|
||||
unsigned char *bp = block+ch, *dp = dest+ch;
|
||||
unsigned char *quant = (ch == 1) ? stb__QuantGTab+8 : stb__QuantRBTab+8;
|
||||
memset(err, 0, sizeof(err));
|
||||
for(y=0; y<4; ++y) {
|
||||
dp[ 0] = quant[bp[ 0] + ((3*ep2[1] + 5*ep2[0]) >> 4)];
|
||||
ep1[0] = bp[ 0] - dp[ 0];
|
||||
dp[ 4] = quant[bp[ 4] + ((7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]) >> 4)];
|
||||
ep1[1] = bp[ 4] - dp[ 4];
|
||||
dp[ 8] = quant[bp[ 8] + ((7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]) >> 4)];
|
||||
ep1[2] = bp[ 8] - dp[ 8];
|
||||
dp[12] = quant[bp[12] + ((7*ep1[2] + 5*ep2[3] + ep2[2]) >> 4)];
|
||||
ep1[3] = bp[12] - dp[12];
|
||||
bp += 16;
|
||||
dp += 16;
|
||||
et = ep1, ep1 = ep2, ep2 = et; // swap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The color matching function
|
||||
static unsigned int stb__MatchColorsBlock(unsigned char *block, unsigned char *color,int dither)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
int dirr = color[0*4+0] - color[1*4+0];
|
||||
int dirg = color[0*4+1] - color[1*4+1];
|
||||
int dirb = color[0*4+2] - color[1*4+2];
|
||||
int dots[16];
|
||||
int stops[4];
|
||||
int i;
|
||||
int c0Point, halfPoint, c3Point;
|
||||
|
||||
for(i=0;i<16;i++)
|
||||
dots[i] = block[i*4+0]*dirr + block[i*4+1]*dirg + block[i*4+2]*dirb;
|
||||
|
||||
for(i=0;i<4;i++)
|
||||
stops[i] = color[i*4+0]*dirr + color[i*4+1]*dirg + color[i*4+2]*dirb;
|
||||
|
||||
// think of the colors as arranged on a line; project point onto that line, then choose
|
||||
// next color out of available ones. we compute the crossover points for "best color in top
|
||||
// half"/"best in bottom half" and then the same inside that subinterval.
|
||||
//
|
||||
// relying on this 1d approximation isn't always optimal in terms of euclidean distance,
|
||||
// but it's very close and a lot faster.
|
||||
// http://cbloomrants.blogspot.com/2008/12/12-08-08-dxtc-summary.html
|
||||
|
||||
c0Point = (stops[1] + stops[3]) >> 1;
|
||||
halfPoint = (stops[3] + stops[2]) >> 1;
|
||||
c3Point = (stops[2] + stops[0]) >> 1;
|
||||
|
||||
if(!dither) {
|
||||
// the version without dithering is straightforward
|
||||
for (i=15;i>=0;i--) {
|
||||
int dot = dots[i];
|
||||
mask <<= 2;
|
||||
|
||||
if(dot < halfPoint)
|
||||
mask |= (dot < c0Point) ? 1 : 3;
|
||||
else
|
||||
mask |= (dot < c3Point) ? 2 : 0;
|
||||
}
|
||||
} else {
|
||||
// with floyd-steinberg dithering
|
||||
int err[8],*ep1 = err,*ep2 = err+4;
|
||||
int *dp = dots, y;
|
||||
|
||||
c0Point <<= 4;
|
||||
halfPoint <<= 4;
|
||||
c3Point <<= 4;
|
||||
for(i=0;i<8;i++)
|
||||
err[i] = 0;
|
||||
|
||||
for(y=0;y<4;y++)
|
||||
{
|
||||
int dot,lmask,step;
|
||||
|
||||
dot = (dp[0] << 4) + (3*ep2[1] + 5*ep2[0]);
|
||||
if(dot < halfPoint)
|
||||
step = (dot < c0Point) ? 1 : 3;
|
||||
else
|
||||
step = (dot < c3Point) ? 2 : 0;
|
||||
ep1[0] = dp[0] - stops[step];
|
||||
lmask = step;
|
||||
|
||||
dot = (dp[1] << 4) + (7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]);
|
||||
if(dot < halfPoint)
|
||||
step = (dot < c0Point) ? 1 : 3;
|
||||
else
|
||||
step = (dot < c3Point) ? 2 : 0;
|
||||
ep1[1] = dp[1] - stops[step];
|
||||
lmask |= step<<2;
|
||||
|
||||
dot = (dp[2] << 4) + (7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]);
|
||||
if(dot < halfPoint)
|
||||
step = (dot < c0Point) ? 1 : 3;
|
||||
else
|
||||
step = (dot < c3Point) ? 2 : 0;
|
||||
ep1[2] = dp[2] - stops[step];
|
||||
lmask |= step<<4;
|
||||
|
||||
dot = (dp[3] << 4) + (7*ep1[2] + 5*ep2[3] + ep2[2]);
|
||||
if(dot < halfPoint)
|
||||
step = (dot < c0Point) ? 1 : 3;
|
||||
else
|
||||
step = (dot < c3Point) ? 2 : 0;
|
||||
ep1[3] = dp[3] - stops[step];
|
||||
lmask |= step<<6;
|
||||
|
||||
dp += 4;
|
||||
mask |= lmask << (y*8);
|
||||
{ int *et = ep1; ep1 = ep2; ep2 = et; } // swap
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
// The color optimization function. (Clever code, part 1)
|
||||
static void stb__OptimizeColorsBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16)
|
||||
{
|
||||
int mind = 0x7fffffff,maxd = -0x7fffffff;
|
||||
unsigned char *minp, *maxp;
|
||||
double magn;
|
||||
int v_r,v_g,v_b;
|
||||
static const int nIterPower = 4;
|
||||
float covf[6],vfr,vfg,vfb;
|
||||
|
||||
// determine color distribution
|
||||
int cov[6];
|
||||
int mu[3],min[3],max[3];
|
||||
int ch,i,iter;
|
||||
|
||||
for(ch=0;ch<3;ch++)
|
||||
{
|
||||
const unsigned char *bp = ((const unsigned char *) block) + ch;
|
||||
int muv,minv,maxv;
|
||||
|
||||
muv = minv = maxv = bp[0];
|
||||
for(i=4;i<64;i+=4)
|
||||
{
|
||||
muv += bp[i];
|
||||
if (bp[i] < minv) minv = bp[i];
|
||||
else if (bp[i] > maxv) maxv = bp[i];
|
||||
}
|
||||
|
||||
mu[ch] = (muv + 8) >> 4;
|
||||
min[ch] = minv;
|
||||
max[ch] = maxv;
|
||||
}
|
||||
|
||||
// determine covariance matrix
|
||||
for (i=0;i<6;i++)
|
||||
cov[i] = 0;
|
||||
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
int r = block[i*4+0] - mu[0];
|
||||
int g = block[i*4+1] - mu[1];
|
||||
int b = block[i*4+2] - mu[2];
|
||||
|
||||
cov[0] += r*r;
|
||||
cov[1] += r*g;
|
||||
cov[2] += r*b;
|
||||
cov[3] += g*g;
|
||||
cov[4] += g*b;
|
||||
cov[5] += b*b;
|
||||
}
|
||||
|
||||
// convert covariance matrix to float, find principal axis via power iter
|
||||
for(i=0;i<6;i++)
|
||||
covf[i] = cov[i] / 255.0f;
|
||||
|
||||
vfr = (float) (max[0] - min[0]);
|
||||
vfg = (float) (max[1] - min[1]);
|
||||
vfb = (float) (max[2] - min[2]);
|
||||
|
||||
for(iter=0;iter<nIterPower;iter++)
|
||||
{
|
||||
float r = vfr*covf[0] + vfg*covf[1] + vfb*covf[2];
|
||||
float g = vfr*covf[1] + vfg*covf[3] + vfb*covf[4];
|
||||
float b = vfr*covf[2] + vfg*covf[4] + vfb*covf[5];
|
||||
|
||||
vfr = r;
|
||||
vfg = g;
|
||||
vfb = b;
|
||||
}
|
||||
|
||||
magn = fabs(vfr);
|
||||
if (fabs(vfg) > magn) magn = fabs(vfg);
|
||||
if (fabs(vfb) > magn) magn = fabs(vfb);
|
||||
|
||||
if(magn < 4.0f) { // too small, default to luminance
|
||||
v_r = 299; // JPEG YCbCr luma coefs, scaled by 1000.
|
||||
v_g = 587;
|
||||
v_b = 114;
|
||||
} else {
|
||||
magn = 512.0 / magn;
|
||||
v_r = (int) (vfr * magn);
|
||||
v_g = (int) (vfg * magn);
|
||||
v_b = (int) (vfb * magn);
|
||||
}
|
||||
|
||||
// Pick colors at extreme points
|
||||
for(i=0;i<16;i++)
|
||||
{
|
||||
int dot = block[i*4+0]*v_r + block[i*4+1]*v_g + block[i*4+2]*v_b;
|
||||
|
||||
if (dot < mind) {
|
||||
mind = dot;
|
||||
minp = block+i*4;
|
||||
}
|
||||
|
||||
if (dot > maxd) {
|
||||
maxd = dot;
|
||||
maxp = block+i*4;
|
||||
}
|
||||
}
|
||||
|
||||
*pmax16 = stb__As16Bit(maxp[0],maxp[1],maxp[2]);
|
||||
*pmin16 = stb__As16Bit(minp[0],minp[1],minp[2]);
|
||||
}
|
||||
|
||||
static int stb__sclamp(float y, int p0, int p1)
|
||||
{
|
||||
int x = (int) y;
|
||||
if (x < p0) return p0;
|
||||
if (x > p1) return p1;
|
||||
return x;
|
||||
}
|
||||
|
||||
// The refinement function. (Clever code, part 2)
|
||||
// Tries to optimize colors to suit block contents better.
|
||||
// (By solving a least squares system via normal equations+Cramer's rule)
|
||||
static int stb__RefineBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16, unsigned int mask)
|
||||
{
|
||||
static const int w1Tab[4] = { 3,0,2,1 };
|
||||
static const int prods[4] = { 0x090000,0x000900,0x040102,0x010402 };
|
||||
// ^some magic to save a lot of multiplies in the accumulating loop...
|
||||
// (precomputed products of weights for least squares system, accumulated inside one 32-bit register)
|
||||
|
||||
float frb,fg;
|
||||
unsigned short oldMin, oldMax, min16, max16;
|
||||
int i, akku = 0, xx,xy,yy;
|
||||
int At1_r,At1_g,At1_b;
|
||||
int At2_r,At2_g,At2_b;
|
||||
unsigned int cm = mask;
|
||||
|
||||
oldMin = *pmin16;
|
||||
oldMax = *pmax16;
|
||||
|
||||
if((mask ^ (mask<<2)) < 4) // all pixels have the same index?
|
||||
{
|
||||
// yes, linear system would be singular; solve using optimal
|
||||
// single-color match on average color
|
||||
int r = 8, g = 8, b = 8;
|
||||
for (i=0;i<16;++i) {
|
||||
r += block[i*4+0];
|
||||
g += block[i*4+1];
|
||||
b += block[i*4+2];
|
||||
}
|
||||
|
||||
r >>= 4; g >>= 4; b >>= 4;
|
||||
|
||||
max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0];
|
||||
min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1];
|
||||
} else {
|
||||
At1_r = At1_g = At1_b = 0;
|
||||
At2_r = At2_g = At2_b = 0;
|
||||
for (i=0;i<16;++i,cm>>=2) {
|
||||
int step = cm&3;
|
||||
int w1 = w1Tab[step];
|
||||
int r = block[i*4+0];
|
||||
int g = block[i*4+1];
|
||||
int b = block[i*4+2];
|
||||
|
||||
akku += prods[step];
|
||||
At1_r += w1*r;
|
||||
At1_g += w1*g;
|
||||
At1_b += w1*b;
|
||||
At2_r += r;
|
||||
At2_g += g;
|
||||
At2_b += b;
|
||||
}
|
||||
|
||||
At2_r = 3*At2_r - At1_r;
|
||||
At2_g = 3*At2_g - At1_g;
|
||||
At2_b = 3*At2_b - At1_b;
|
||||
|
||||
// extract solutions and decide solvability
|
||||
xx = akku >> 16;
|
||||
yy = (akku >> 8) & 0xff;
|
||||
xy = (akku >> 0) & 0xff;
|
||||
|
||||
frb = 3.0f * 31.0f / 255.0f / (xx*yy - xy*xy);
|
||||
fg = frb * 63.0f / 31.0f;
|
||||
|
||||
// solve.
|
||||
max16 = stb__sclamp((At1_r*yy - At2_r*xy)*frb+0.5f,0,31) << 11;
|
||||
max16 |= stb__sclamp((At1_g*yy - At2_g*xy)*fg +0.5f,0,63) << 5;
|
||||
max16 |= stb__sclamp((At1_b*yy - At2_b*xy)*frb+0.5f,0,31) << 0;
|
||||
|
||||
min16 = stb__sclamp((At2_r*xx - At1_r*xy)*frb+0.5f,0,31) << 11;
|
||||
min16 |= stb__sclamp((At2_g*xx - At1_g*xy)*fg +0.5f,0,63) << 5;
|
||||
min16 |= stb__sclamp((At2_b*xx - At1_b*xy)*frb+0.5f,0,31) << 0;
|
||||
}
|
||||
|
||||
*pmin16 = min16;
|
||||
*pmax16 = max16;
|
||||
return oldMin != min16 || oldMax != max16;
|
||||
}
|
||||
|
||||
// Color block compression
|
||||
static void stb__CompressColorBlock(unsigned char *dest, unsigned char *block, int mode)
|
||||
{
|
||||
unsigned int mask;
|
||||
int i;
|
||||
int dither;
|
||||
int refinecount;
|
||||
unsigned short max16, min16;
|
||||
unsigned char dblock[16*4],color[4*4];
|
||||
|
||||
dither = mode & STB_DXT_DITHER;
|
||||
refinecount = (mode & STB_DXT_HIGHQUAL) ? 2 : 1;
|
||||
|
||||
// check if block is constant
|
||||
for (i=1;i<16;i++)
|
||||
if (((unsigned int *) block)[i] != ((unsigned int *) block)[0])
|
||||
break;
|
||||
|
||||
if(i == 16) { // constant color
|
||||
int r = block[0], g = block[1], b = block[2];
|
||||
mask = 0xaaaaaaaa;
|
||||
max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0];
|
||||
min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1];
|
||||
} else {
|
||||
// first step: compute dithered version for PCA if desired
|
||||
if(dither)
|
||||
stb__DitherBlock(dblock,block);
|
||||
|
||||
// second step: pca+map along principal axis
|
||||
stb__OptimizeColorsBlock(dither ? dblock : block,&max16,&min16);
|
||||
if (max16 != min16) {
|
||||
stb__EvalColors(color,max16,min16);
|
||||
mask = stb__MatchColorsBlock(block,color,dither);
|
||||
} else
|
||||
mask = 0;
|
||||
|
||||
// third step: refine (multiple times if requested)
|
||||
for (i=0;i<refinecount;i++) {
|
||||
unsigned int lastmask = mask;
|
||||
|
||||
if (stb__RefineBlock(dither ? dblock : block,&max16,&min16,mask)) {
|
||||
if (max16 != min16) {
|
||||
stb__EvalColors(color,max16,min16);
|
||||
mask = stb__MatchColorsBlock(block,color,dither);
|
||||
} else {
|
||||
mask = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(mask == lastmask)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write the color block
|
||||
if(max16 < min16)
|
||||
{
|
||||
unsigned short t = min16;
|
||||
min16 = max16;
|
||||
max16 = t;
|
||||
mask ^= 0x55555555;
|
||||
}
|
||||
|
||||
dest[0] = (unsigned char) (max16);
|
||||
dest[1] = (unsigned char) (max16 >> 8);
|
||||
dest[2] = (unsigned char) (min16);
|
||||
dest[3] = (unsigned char) (min16 >> 8);
|
||||
dest[4] = (unsigned char) (mask);
|
||||
dest[5] = (unsigned char) (mask >> 8);
|
||||
dest[6] = (unsigned char) (mask >> 16);
|
||||
dest[7] = (unsigned char) (mask >> 24);
|
||||
}
|
||||
|
||||
// Alpha block compression (this is easy for a change)
|
||||
static void stb__CompressAlphaBlock(unsigned char *dest,unsigned char *src,int mode)
|
||||
{
|
||||
int i,dist,bias,dist4,dist2,bits,mask;
|
||||
|
||||
// find min/max color
|
||||
int mn,mx;
|
||||
mn = mx = src[3];
|
||||
|
||||
for (i=1;i<16;i++)
|
||||
{
|
||||
if (src[i*4+3] < mn) mn = src[i*4+3];
|
||||
else if (src[i*4+3] > mx) mx = src[i*4+3];
|
||||
}
|
||||
|
||||
// encode them
|
||||
((unsigned char *)dest)[0] = mx;
|
||||
((unsigned char *)dest)[1] = mn;
|
||||
dest += 2;
|
||||
|
||||
// determine bias and emit color indices
|
||||
// given the choice of mx/mn, these indices are optimal:
|
||||
// http://fgiesen.wordpress.com/2009/12/15/dxt5-alpha-block-index-determination/
|
||||
dist = mx-mn;
|
||||
dist4 = dist*4;
|
||||
dist2 = dist*2;
|
||||
bias = (dist < 8) ? (dist - 1) : (dist/2 + 2);
|
||||
bias -= mn * 7;
|
||||
bits = 0,mask=0;
|
||||
|
||||
for (i=0;i<16;i++) {
|
||||
int a = src[i*4+3]*7 + bias;
|
||||
int ind,t;
|
||||
|
||||
// select index. this is a "linear scale" lerp factor between 0 (val=min) and 7 (val=max).
|
||||
t = (a >= dist4) ? -1 : 0; ind = t & 4; a -= dist4 & t;
|
||||
t = (a >= dist2) ? -1 : 0; ind += t & 2; a -= dist2 & t;
|
||||
ind += (a >= dist);
|
||||
|
||||
// turn linear scale into DXT index (0/1 are extremal pts)
|
||||
ind = -ind & 7;
|
||||
ind ^= (2 > ind);
|
||||
|
||||
// write index
|
||||
mask |= ind << bits;
|
||||
if((bits += 3) >= 8) {
|
||||
*dest++ = mask;
|
||||
mask >>= 8;
|
||||
bits -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void stb__InitDXT()
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<32;i++)
|
||||
stb__Expand5[i] = (i<<3)|(i>>2);
|
||||
|
||||
for(i=0;i<64;i++)
|
||||
stb__Expand6[i] = (i<<2)|(i>>4);
|
||||
|
||||
for(i=0;i<256+16;i++)
|
||||
{
|
||||
int v = i-8 < 0 ? 0 : i-8 > 255 ? 255 : i-8;
|
||||
stb__QuantRBTab[i] = stb__Expand5[stb__Mul8Bit(v,31)];
|
||||
stb__QuantGTab[i] = stb__Expand6[stb__Mul8Bit(v,63)];
|
||||
}
|
||||
|
||||
stb__PrepareOptTable(&stb__OMatch5[0][0],stb__Expand5,32);
|
||||
stb__PrepareOptTable(&stb__OMatch6[0][0],stb__Expand6,64);
|
||||
}
|
||||
|
||||
void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode)
|
||||
{
|
||||
static int init=1;
|
||||
if (init) {
|
||||
stb__InitDXT();
|
||||
init=0;
|
||||
}
|
||||
|
||||
if (alpha) {
|
||||
stb__CompressAlphaBlock(dest,(unsigned char*) src,mode);
|
||||
dest += 8;
|
||||
}
|
||||
|
||||
stb__CompressColorBlock(dest,(unsigned char*) src,mode);
|
||||
}
|
||||
#endif // STB_DXT_IMPLEMENTATION
|
||||
|
||||
#endif // STB_INCLUDE_STB_DXT_H
|
5099
public/bitmap/stb_image.c
Normal file
5099
public/bitmap/stb_image.c
Normal file
File diff suppressed because it is too large
Load Diff
80
public/bitmap/stb_image.h
Normal file
80
public/bitmap/stb_image.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* stbi-1.29 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
|
||||
when you control the images you're loading
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
QUICK NOTES:
|
||||
Primarily of interest to game developers and other people who can
|
||||
avoid problematic images and only need the trivial interface
|
||||
|
||||
JPEG baseline (no JPEG progressive)
|
||||
PNG 8-bit only
|
||||
|
||||
TGA (not sure what subset, if a subset)
|
||||
BMP non-1bpp, non-RLE
|
||||
PSD (composited view only, no extra channels)
|
||||
|
||||
GIF (*comp always reports as 4-channel)
|
||||
HDR (radiance rgbE format)
|
||||
PIC (Softimage PIC)
|
||||
|
||||
- decoded from memory or through stdio FILE (define STBI_NO_STDIO to remove code)
|
||||
- supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
|
||||
|
||||
Latest revisions:
|
||||
1.29 (2010-08-16) various warning fixes from Aurelien Pocheville
|
||||
1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ)
|
||||
1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila)
|
||||
allow trailing 0s at end of image data (Laurent Gomila)
|
||||
1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ
|
||||
1.25 (2010-07-17) refix trans_data warning (Won Chun)
|
||||
1.24 (2010-07-12) perf improvements reading from files
|
||||
minor perf improvements for jpeg
|
||||
deprecated type-specific functions in hope of feedback
|
||||
attempt to fix trans_data warning (Won Chun)
|
||||
1.23 fixed bug in iPhone support
|
||||
1.22 (2010-07-10) removed image *writing* support to stb_image_write.h
|
||||
stbi_info support from Jetro Lauha
|
||||
GIF support from Jean-Marc Lienher
|
||||
iPhone PNG-extensions from James Brown
|
||||
warning-fixes from Nicolas Schulz and Janez Zemva
|
||||
1.21 fix use of 'uint8' in header (reported by jon blow)
|
||||
1.20 added support for Softimage PIC, by Tom Seddon
|
||||
|
||||
See end of file for full revision history.
|
||||
|
||||
TODO:
|
||||
stbi_info support for BMP,PSD,HDR,PIC
|
||||
rewrite stbi_info and load_file variations to share file handling code
|
||||
(current system allows individual functions to be called directly,
|
||||
since each does all the work, but I doubt anyone uses this in practice)
|
||||
|
||||
|
||||
============================ Contributors =========================
|
||||
|
||||
Image formats Optimizations & bugfixes
|
||||
Sean Barrett (jpeg, png, bmp) Fabian "ryg" Giesen
|
||||
Nicolas Schulz (hdr, psd)
|
||||
Jonathan Dummer (tga) Bug fixes & warning fixes
|
||||
Jean-Marc Lienher (gif) Marc LeBlanc
|
||||
Tom Seddon (pic) Christpher Lloyd
|
||||
Thatcher Ulrich (psd) Dave Moore
|
||||
Won Chun
|
||||
the Horde3D community
|
||||
Extensions, features Janez Zemva
|
||||
Jetro Lauha (stbi_info) Jonathan Blow
|
||||
James "moose2000" Brown (iPhone PNG) Laurent Gomila
|
||||
Aruelien Pocheville
|
||||
|
||||
If your name should be here but isn't, let Sean know.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
||||
#define STBI_INCLUDE_STB_IMAGE_H
|
||||
|
||||
// To get a header file for this, either cut and paste the header,
|
||||
// or create stb_image.h, #define STBI_HEADER_FILE_ONLY, and
|
||||
// then include stb_image.c from it.
|
||||
|
||||
#define STBI_HEADER_FILE_ONLY
|
||||
#include "stb_image.c"
|
72
public/bitmap/texturepacker.h
Normal file
72
public/bitmap/texturepacker.h
Normal file
@ -0,0 +1,72 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TEXTUREPACKER_H
|
||||
#define TEXTUREPACKER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utlntree.h"
|
||||
|
||||
|
||||
#define DEFAULT_TEXTURE_PAGE_WIDTH 1024
|
||||
#define DEFAULT_TEXTURE_PAGE_WIDTH 1024
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: manages texture packing of textures as they are added.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTexturePacker
|
||||
{
|
||||
public:
|
||||
struct TreeEntry_t
|
||||
{
|
||||
Rect_t rc;
|
||||
bool bInUse;
|
||||
};
|
||||
|
||||
CTexturePacker( int texWidth = DEFAULT_TEXTURE_PAGE_WIDTH, int texHeight = DEFAULT_TEXTURE_PAGE_WIDTH, int pixelGap = 0 );
|
||||
~CTexturePacker();
|
||||
|
||||
// Use -1 if you want to insert at the root.
|
||||
int InsertRect( const Rect_t& texRect, int nodeIndex = -1 );
|
||||
bool RemoveRect( int nodeIndex );
|
||||
const TreeEntry_t &GetEntry( int i )
|
||||
{
|
||||
return m_Tree[i];
|
||||
}
|
||||
int GetPageWidth()
|
||||
{
|
||||
return m_PageWidth;
|
||||
}
|
||||
int GetPageHeight()
|
||||
{
|
||||
return m_PageHeight;
|
||||
}
|
||||
|
||||
// clears the tree
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
bool IsLeaf( int nodeIndex );
|
||||
bool IsLeftChild( int nodeIndexParent, int nodeIndexChild );
|
||||
bool IsRightChild( int nodeIndexParent, int nodeIndexChild );
|
||||
|
||||
// Pixel gap between textures.
|
||||
int m_PixelGap;
|
||||
int m_PageWidth;
|
||||
int m_PageHeight;
|
||||
|
||||
|
||||
|
||||
CUtlNTree< TreeEntry_t > m_Tree;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // TEXTUREPACKER_H
|
45
public/bitmap/tgaloader.h
Normal file
45
public/bitmap/tgaloader.h
Normal file
@ -0,0 +1,45 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef TGALOADER_H
|
||||
#define TGALOADER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "bitmap/imageformat.h"
|
||||
#include "tier1/utlmemory.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlBuffer;
|
||||
|
||||
|
||||
namespace TGALoader
|
||||
{
|
||||
|
||||
int TGAHeaderSize();
|
||||
|
||||
bool GetInfo( const char *fileName, int *width, int *height, ImageFormat *imageFormat, float *sourceGamma );
|
||||
bool GetInfo( CUtlBuffer &buf, int *width, int *height, ImageFormat *imageFormat, float *sourceGamma );
|
||||
|
||||
bool Load( unsigned char *imageData, const char *fileName, int width, int height,
|
||||
ImageFormat imageFormat, float targetGamma, bool mipmap );
|
||||
bool Load( unsigned char *imageData, CUtlBuffer &buf, int width, int height,
|
||||
ImageFormat imageFormat, float targetGamma, bool mipmap );
|
||||
|
||||
bool LoadRGBA8888( const char *pFileName, CUtlMemory<unsigned char> &outputData, int &outWidth, int &outHeight );
|
||||
bool LoadRGBA8888( CUtlBuffer &buf, CUtlMemory<unsigned char> &outputData, int &outWidth, int &outHeight );
|
||||
|
||||
} // end namespace TGALoader
|
||||
|
||||
#endif // TGALOADER_H
|
35
public/bitmap/tgawriter.h
Normal file
35
public/bitmap/tgawriter.h
Normal file
@ -0,0 +1,35 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef TGAWRITER_H
|
||||
#define TGAWRITER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/interface.h"
|
||||
#include "bitmap/imageformat.h" //ImageFormat enum definition
|
||||
|
||||
class CUtlBuffer;
|
||||
|
||||
namespace TGAWriter
|
||||
{
|
||||
bool WriteToBuffer( unsigned char *pImageData, CUtlBuffer &buffer, int width, int height, ImageFormat srcFormat, ImageFormat dstFormat );
|
||||
|
||||
// Write out a simple tga file from a memory buffer.
|
||||
bool WriteTGAFile( const char *fileName, int width, int height, enum ImageFormat srcFormat, uint8 const *srcData, int nStride );
|
||||
|
||||
// Routines for writing to files without allocating any memory in the TGA writer
|
||||
// Useful for very large files such as posters, which are rendered as sub-rects
|
||||
bool WriteDummyFileNoAlloc( const char *fileName, int width, int height, ImageFormat dstFormat );
|
||||
bool WriteRectNoAlloc( unsigned char *pImageData, const char *fileName, int nXOrigin, int nYOrigin, int width, int height, int nStride, ImageFormat srcFormat );
|
||||
bool WriteRectNoAllocFeather( unsigned char *pImageData, const char *fileName, int nXOrigin, int nYOrigin, int width, int height, int nGuardBandWidth, int nGuardBandHeight, int nStride, enum ImageFormat srcFormat );
|
||||
|
||||
} // end namespace TGAWriter
|
||||
|
||||
#endif // TGAWRITER_H
|
Reference in New Issue
Block a user