Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/FreeImage/PluginDDS.cpp  view on Meta::CPAN

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;
	// expand from 565 to 888
	for (i = 0; i < 2; i++)	{
		colors[i].a = 0xff;
		/*
		colors[i].r = (BYTE)(block.colors[i].r * 0xff / 0x1f);
		colors[i].g = (BYTE)(block.colors[i].g * 0xff / 0x3f);
		colors[i].b = (BYTE)(block.colors[i].b * 0xff / 0x1f);
		*/
		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> {



( run in 0.487 second using v1.01-cache-2.11-cpan-787462296c9 )