Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PluginDDS.cpp view on Meta::CPAN
colors[i].r = (BYTE)((block.colors[i].r << 3U) | (block.colors[i].r >> 2U));
colors[i].g = (BYTE)((block.colors[i].g << 2U) | (block.colors[i].g >> 4U));
colors[i].b = (BYTE)((block.colors[i].b << 3U) | (block.colors[i].b >> 2U));
}
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 = (BYTE)((WORD (colors[0].r) * (2 - i) + WORD (colors[1].r) * (1 + i)) / 3);
colors[i + 2].g = (BYTE)((WORD (colors[0].g) * (2 - i) + WORD (colors[1].g) * (1 + i)) / 3);
colors[i + 2].b = (BYTE)((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 = (BYTE)((WORD (colors[0].r) + WORD (colors[1].r)) / 2);
colors[2].g = (BYTE)((WORD (colors[0].g) + WORD (colors[1].g)) / 2);
colors[2].b = (BYTE)((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 = (BYTE)((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;
protected:
unsigned m_alphas[8];
unsigned m_alphaBits;
int m_offset;
public:
void Setup (const BYTE *pBlock) {
base::Setup (pBlock);
const DXTAlphaBlock3BitLinear &block = m_pBlock->alpha;
m_alphas[0] = block.alpha[0];
m_alphas[1] = block.alpha[1];
if (m_alphas[0] > m_alphas[1]) {
// 8 alpha block
for (int i = 0; i < 6; i++) {
m_alphas[i + 2] = ((6 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 3) / 7;
}
}
else {
// 6 alpha block
for (int i = 0; i < 4; i++) {
m_alphas[i + 2] = ((4 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 2) / 5;
}
m_alphas[6] = 0;
m_alphas[7] = 0xFF;
}
}
void SetY (int y) {
base::SetY (y);
int i = y / 2;
const DXTAlphaBlock3BitLinear &block = m_pBlock->alpha;
m_alphaBits = unsigned(block.data[0 + i * 3]) | (unsigned(block.data[1 + i * 3]) << 8)
| (unsigned(block.data[2 + i * 3]) << 16);
m_offset = (y & 1) * 12;
}
void GetColor (int x, int y, Color8888 &color) {
base::GetColor (x, y, color);
unsigned bits = (m_alphaBits >> (x * 3 + m_offset)) & 7;
color.a = (BYTE)m_alphas[bits];
}
};
template <class DECODER> void DecodeDXTBlock (BYTE *dstData, const BYTE *srcBlock, long dstPitch, int bw, int bh) {
DECODER decoder;
decoder.Setup (srcBlock);
for (int y = 0; y < bh; y++) {
BYTE *dst = dstData - y * dstPitch;
decoder.SetY (y);
for (int x = 0; x < bw; x++) {
decoder.GetColor (x, y, (Color8888 &)*dst);
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
INPLACESWAP(dst[FI_RGBA_RED], dst[FI_RGBA_BLUE]);
#endif
dst += 4;
}
}
}
// ==========================================================
// Plugin Interface
// ==========================================================
( run in 1.037 second using v1.01-cache-2.11-cpan-62a16548d74 )