DXT Compression/Decompression Library
nvDXT is a compression and decompression library to link to your existing projects. You specify compression options in the class CompressionOptions located in nvdxt_options.h. The library will create the MIP map levels for you during compression, or you can specify you own. You can specify your own MIP map compressor callback to receive each of the compressed MIP levels.
The decompressor will decompress all MIP map into one image file where all MIP maps are concatenated together.
The library name is nvDXTLib.lib.
Compresses an image with a user supplied callback with the data for each MIP level created.
For each MIP level, your callback will be called.
Only supports input of RGB 24 or ARGB 32 bpp.
See nvDXT.cpp for example. This example require the NVSDK to build.
HRESULT
nvDXTcompress(unsigned char * raw_data, // pointer to data (24 or 32 bit)unsigned long w, // width in texels
unsigned long h, // height in texels
DWORD pitch, // in bytes
CompressionOptions * options, // structure defined in nvdxt_options.h
DWORD depth, // 3 or 4
MIPcallback callback = 0); // callback for generated levels
if callback is == 0 (or not specified), then WriteDTXnFile is called with all file info
instead of your callback
typedef HRESULT (*MIPcallback)(
void * data, // pointer to the data to compressed data
int miplevel, // what MIP level this is
DWORD size // size of the data
);
// You must write the routines (or provide stubs)
// void WriteDTXnFile(count, buffer);
// void ReadDTXnFile(count, buffer);
//
//
void WriteDTXnFile(DWORD count, void * buffer);
void ReadDTXnFile(DWORD count, void * buffer);
Fill in the structure CompressionOptions
struct CompressionOptions{
bool bMipMapsInImage; // mip have been loaded in during read
short MipMapType; // dNoMipMaps, dSpecifyMipMaps, dUseExistingMipMaps, dGenerateMipMaps
short SpecifiedMipMaps; // if dSpecifyMipMaps is set (number of mipmaps to generate)
short MIPFilterType; // for MIP maps
/*
for MIPFilterType, specify one of:
dMIPFilterBox
dMIPFilterCubic
dMIPFilterFullDFT
dMIPFilterKaiser
dMIPFilterLinearLightKaiser
*/
bool bBinaryAlpha; // zero or one alpha channel
bool bNormalMap; // Is a normal Map
bool bDuDvMap; // Is a DuDv (EMBM) map
bool bAlphaBorder; // make an alpha border
bool bBorder; // make a color border
tPixel BorderColor; // color of border
bool bFadeColor; // fade color over MIP maps
bool bFadeAlpha; // fade alpha over MIP maps
tPixel FadeToColor; // color to fade to
int FadeToAlpha; // alpha value to fade to (0-255)
int FadeToDelay; // start fading after 'n' MIP maps
int FadeAmount; // percentage of color to fade in
bool bDitherColor; // enable dithering during 16 bit conversion
bool bDitherEachMIPLevel;// enable dithering during 16 bit conversion for each MIP level (after filtering)
bool bGreyScale; // treat image as a grey scale
short TextureType; // regular decal, cube or volume
/*
for TextureType, specify one of:
dTextureType2D
dTextureTypeCube
dTextureTypeImage
*/
short TextureFormat;
/*
for TextureFormat, specify one of:
dDXT1,
dDXT1a,
dDXT3,
dDXT5,
d4444,
d1555,
d565,
d8888,
d888,
d555,
not supported yet dNVHS, dNVHU
*/
bool bSwapRGB; // swap color positions R and G
} CompressionOptions;
// error return codes
#define DXTERR_INPUT_POINTER_ZERO -1
#define DXTERR_DEPTH_IS_NOT_3_OR_4 -2
#define DXTERR_NON_POWER_2 -3
example callback to store compressed image in a
Direct3D texture
LPDIRECT3DTEXTURE8 pCurrentTexture = 0;
HRESULT LoadAllMipSurfaces(void * data,
int iLevel)
{
HRESULT hr;
LPDIRECT3DSURFACE8
psurf;
D3DSURFACE_DESC
sd;
D3DLOCKED_RECT
lr;
hr = pCurrentTexture->GetSurfaceLevel(iLevel, &psurf);
if (FAILED(hr))
return hr;
psurf->GetDesc(&sd);
hr = pCurrentTexture->LockRect(iLevel, &lr, NULL, 0);
if (FAILED(hr))
return hr;
memcpy(lr.pBits, data, sd.Size);
hr = pCurrentTexture->UnlockRect(iLevel);
ReleasePpo(&psurf);
return 0;
}
calling sequence
hr = D3DXCreateTexture(m_pd3dDevice, Width, Height, nMips, 0, D3DFMT_DXT3,
D3DPOOL_MANAGED, &pCurrentTexture);
nvDXTcompress(raw_data, Width, Height, DXT3, true, 4,
LoadAllMipSurfaces);
If you have existing MIP maps you must combine them so each MIP level is followed by its next MIP level. Conceptually, it looks like this:
in CompressionOptions
MipMapType = dUseExistingMipMaps;
You must specify all MIP levels.
nvDXTcompress((unsigned char *)raw_data, width, height, pitch, &options, depth, 0);
width = src_pitch * 2
pitch = src_pitch * 2
To decompress an image use this call to read all MIP chains into one buffer:
unsigned char * nvDXTdecompress(int & w, int & h, int & depth, int & total_width, int & rowBytes, int & src_format);
returns pointer to image data;
w : image width
h : image height
depth : number of bytes per pixel, 3 or 4
total_width : total number of texels wide the resulting image is.
byte_pitch = total_width * depth;
the next MIP map image starts at base + row_bytes, next one starts at base + row_bytes / 2, etc.
src_format: format the original file is
see readdxt.cpp for example