?? plugindds.cpp
字號:
// ==========================================================
// DDS Loader
//
// Design and implementation by
// - Volker G鋜tner (volkerg@gmx.at)
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================
#include "FreeImage.h"
#include "Utilities.h"
// ----------------------------------------------------------
// Definitions for the DDS format
// ----------------------------------------------------------
#ifdef WIN32
#pragma pack(push, 1)
#else
#pragma pack(1)
#endif
typedef struct tagDDPIXELFORMAT {
DWORD dwSize; // size of this structure (must be 32)
DWORD dwFlags; // see DDPF_*
DWORD dwFourCC;
DWORD dwRGBBitCount; // Total number of bits for RGB formats
DWORD dwRBitMask;
DWORD dwGBitMask;
DWORD dwBBitMask;
DWORD dwRGBAlphaBitMask;
} DDPIXELFORMAT;
// DIRECTDRAW PIXELFORMAT FLAGS
enum {
DDPF_ALPHAPIXELS = 0x00000001l, // surface has alpha channel
DDPF_ALPHA = 0x00000002l, // alpha only
DDPF_FOURCC = 0x00000004l, // FOURCC available
DDPF_RGB = 0x00000040l // RGB(A) bitmap
};
typedef struct tagDDCAPS2 {
DWORD dwCaps1; // Zero or more of the DDSCAPS_* members
DWORD dwCaps2; // Zero or more of the DDSCAPS2_* members
DWORD dwReserved[2];
} DDCAPS2;
// DIRECTDRAWSURFACE CAPABILITY FLAGS
enum {
DDSCAPS_ALPHA = 0x00000002l, // alpha only surface
DDSCAPS_COMPLEX = 0x00000008l, // complex surface structure
DDSCAPS_TEXTURE = 0x00001000l, // used as texture (should always be set)
DDSCAPS_MIPMAP = 0x00400000l // Mipmap present
};
enum {
DDSCAPS2_CUBEMAP = 0x00000200L,
DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400L,
DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800L,
DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000L,
DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000L,
DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000L,
DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000L,
DDSCAPS2_VOLUME = 0x00200000L
};
typedef struct tagDDSURFACEDESC2 {
DWORD dwSize; // size of this structure (must be 124)
DWORD dwFlags; // combination of the DDSS_* flags
DWORD dwHeight;
DWORD dwWidth;
DWORD dwPitchOrLinearSize;
DWORD dwDepth; // Depth of a volume texture
DWORD dwMipMapCount;
DWORD dwReserved1[11];
DDPIXELFORMAT ddpfPixelFormat;
DDCAPS2 ddsCaps;
DWORD dwReserved2;
} DDSURFACEDESC2;
enum {
DDSD_CAPS = 0x00000001l,
DDSD_HEIGHT = 0x00000002l,
DDSD_WITH = 0x00000004l,
DDSD_PITCH = 0x00000008l,
DDSD_ALPHABITDEPTH = 0x00000080l,
DDSD_PIXELFORMAT = 0x00001000l,
DDSD_MIPMAPCOUNT = 0x00020000l,
DDSD_LINEARSIZE = 0x00080000l,
DDSD_DEPTH = 0x00800000l
};
typedef struct tagDDSHEADER {
DWORD dwMagic; // FOURCC: "DDS "
DDSURFACEDESC2 surfaceDesc;
} DDSHEADER;
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
#define FOURCC_DXT1 MAKEFOURCC('D','X','T','1')
#define FOURCC_DXT2 MAKEFOURCC('D','X','T','2')
#define FOURCC_DXT3 MAKEFOURCC('D','X','T','3')
#define FOURCC_DXT4 MAKEFOURCC('D','X','T','4')
#define FOURCC_DXT5 MAKEFOURCC('D','X','T','5')
// ----------------------------------------------------------
// Structures used by DXT textures
// ----------------------------------------------------------
typedef struct tagColor8888 {
BYTE b;
BYTE g;
BYTE r;
BYTE a;
} Color8888;
typedef struct tagColor565 {
WORD b : 5;
WORD g : 6;
WORD r : 5;
} Color565;
typedef struct tagDXTColBlock {
Color565 colors[2];
BYTE row[4];
} DXTColBlock;
typedef struct tagDXTAlphaBlockExplicit {
WORD row[4];
} DXTAlphaBlockExplicit;
typedef struct tagDXTAlphaBlock3BitLinear {
BYTE alpha[2];
BYTE data[6];
} DXTAlphaBlock3BitLinear;
typedef struct tagDXT1Block
{
DXTColBlock color;
} DXT1Block;
typedef struct tagDXT3Block { // also used by dxt2
DXTAlphaBlockExplicit alpha;
DXTColBlock color;
} DXT3Block;
typedef struct tagDXT5Block { // also used by dxt4
DXTAlphaBlock3BitLinear alpha;
DXTColBlock color;
} DXT5Block;
#ifdef WIN32
# pragma pack(pop)
#else
# pragma pack()
#endif
// ----------------------------------------------------------
// Internal functions
// ----------------------------------------------------------
#ifdef FREEIMAGE_BIGENDIAN
static void
SwapHeader(DDSHEADER *header) {
SwapLong(&header->dwMagic);
SwapLong(&header->surfaceDesc.dwSize);
SwapLong(&header->surfaceDesc.dwFlags);
SwapLong(&header->surfaceDesc.dwHeight);
SwapLong(&header->surfaceDesc.dwWidth);
SwapLong(&header->surfaceDesc.dwPitchOrLinearSize);
SwapLong(&header->surfaceDesc.dwDepth);
SwapLong(&header->surfaceDesc.dwMipMapCount);
for(int i=0; i<11; i++) {
SwapLong(&header->surfaceDesc.dwReserved1[i]);
}
SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwSize);
SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwFlags);
SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwFourCC);
SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwRGBBitCount);
SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwRBitMask);
SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwGBitMask);
SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwBBitMask);
SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwRGBAlphaBitMask);
SwapLong(&header->surfaceDesc.ddsCaps.dwCaps1);
SwapLong(&header->surfaceDesc.ddsCaps.dwCaps2);
SwapLong(&header->surfaceDesc.ddsCaps.dwReserved[0]);
SwapLong(&header->surfaceDesc.ddsCaps.dwReserved[1]);
SwapLong(&header->surfaceDesc.dwReserved2);
}
#endif
// ==========================================================
// Get the 4 possible colors for a block
//
static void
GetBlockColors (const DXTColBlock &block, Color8888 colors[4], bool isDXT1) {
int i;
for (i = 0; i < 2; i++) {
colors[i].a = 0xff;
colors[i].r = block.colors[i].r * 0xff / 0x1f;
colors[i].g = block.colors[i].g * 0xff / 0x3f;
colors[i].b = block.colors[i].b * 0xff / 0x1f;
}
WORD *wCol = (WORD *)block.colors;
if (wCol[0] > wCol[1] || !isDXT1) {
// 4 color block
for (i = 0; i < 2; i++) {
colors[i + 2].a = 0xff;
colors[i + 2].r = (WORD (colors[0].r) * (2 - i) + WORD (colors[1].r) * (1 + i)) / 3;
colors[i + 2].g = (WORD (colors[0].g) * (2 - i) + WORD (colors[1].g) * (1 + i)) / 3;
colors[i + 2].b = (WORD (colors[0].b) * (2 - i) + WORD (colors[1].b) * (1 + i)) / 3;
}
}
else {
// 3 color block, number 4 is transparent
colors[2].a = 0xff;
colors[2].r = (WORD (colors[0].r) + WORD (colors[1].r)) / 2;
colors[2].g = (WORD (colors[0].g) + WORD (colors[1].g)) / 2;
colors[2].b = (WORD (colors[0].b) + WORD (colors[1].b)) / 2;
colors[3].a = 0x00;
colors[3].g = 0x00;
colors[3].b = 0x00;
colors[3].r = 0x00;
}
}
struct DXT_INFO_1 {
typedef DXT1Block Block;
enum {
isDXT1 = 1,
bytesPerBlock = 8
};
};
struct DXT_INFO_3 {
typedef DXT3Block Block;
enum {
isDXT1 = 1,
bytesPerBlock = 16
};
};
struct DXT_INFO_5 {
typedef DXT5Block Block;
enum
{
isDXT1 = 1,
bytesPerBlock = 16
};
};
template <class INFO> class DXT_BLOCKDECODER_BASE {
protected:
Color8888 m_colors[4];
const typename INFO::Block *m_pBlock;
unsigned m_colorRow;
public:
void Setup (const BYTE *pBlock) {
m_pBlock = (const typename INFO::Block *)pBlock;
GetBlockColors (m_pBlock->color, m_colors, INFO::isDXT1);
}
void SetY (int y) {
m_colorRow = m_pBlock->color.row[y];
}
void GetColor (int x, int y, Color8888 &color) {
unsigned bits = (m_colorRow >> (x * 2)) & 3;
color = m_colors[bits];
}
};
class DXT_BLOCKDECODER_1 : public DXT_BLOCKDECODER_BASE <DXT_INFO_1> {
public:
typedef DXT_INFO_1 INFO;
};
class DXT_BLOCKDECODER_3 : public DXT_BLOCKDECODER_BASE <DXT_INFO_3> {
public:
typedef DXT_BLOCKDECODER_BASE <DXT_INFO_3> base;
typedef DXT_INFO_3 INFO;
protected:
unsigned m_alphaRow;
public:
void SetY (int y) {
base::SetY (y);
m_alphaRow = m_pBlock->alpha.row[y];
}
void GetColor (int x, int y, Color8888 &color) {
base::GetColor (x, y, color);
const unsigned bits = (m_alphaRow >> (x * 4)) & 0xF;
color.a = (bits * 0xFF) / 0xF;
}
};
class DXT_BLOCKDECODER_5 : public DXT_BLOCKDECODER_BASE <DXT_INFO_5> {
public:
typedef DXT_BLOCKDECODER_BASE <DXT_INFO_5> base;
typedef DXT_INFO_5 INFO;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -