Alien-FreeImage

 view release on metacpan or  search on metacpan

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

	int widthRest = (int) width & 3;
	int heightRest = (int) height & 3;
	int inputLine = (width + 3) / 4;
	int y = 0;

	if (height >= 4) {
		for (; y < height; y += 4) {
			io->read_proc (input_buffer, sizeof (typename INFO::Block), inputLine, handle);
			// TODO: probably need some endian work here
			BYTE *pbSrc = (BYTE *)input_buffer;
			BYTE *pbDst = FreeImage_GetScanLine (dib, height - y - 1);

			if (width >= 4) {
				for (int x = 0; x < width; x += 4) {
					DecodeDXTBlock <DECODER> (pbDst, pbSrc,	line, 4, 4);
					pbSrc += INFO::bytesPerBlock;
					pbDst += 4 * 4;
				}
			}
			if (widthRest) {
				DecodeDXTBlock <DECODER> (pbDst, pbSrc, line, widthRest, 4);
			}
		}
	}
	if (heightRest)	{
		io->read_proc (input_buffer, sizeof (typename INFO::Block), inputLine, handle);
		// TODO: probably need some endian work here
		BYTE *pbSrc = (BYTE *)input_buffer;
		BYTE *pbDst = FreeImage_GetScanLine (dib, height - y - 1);

		if (width >= 4) {
			for (int x = 0; x < width; x += 4) {
				DecodeDXTBlock <DECODER> (pbDst, pbSrc,	line, 4, heightRest);
				pbSrc += INFO::bytesPerBlock;
				pbDst += 4 * 4;
			}
		}
		if (widthRest) {
			DecodeDXTBlock <DECODER> (pbDst, pbSrc,	line, widthRest, heightRest);
		}

	}

	delete [] input_buffer;
}

static FIBITMAP *
LoadDXT (int type, DDSURFACEDESC2 &desc, FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	int width = (int)desc.dwWidth & ~3;
	int height = (int)desc.dwHeight & ~3;

	// allocate a 32-bit dib
	FIBITMAP *dib = FreeImage_Allocate (width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
	if (dib == NULL)
		return NULL;

	int bpp = FreeImage_GetBPP (dib);
	int line = CalculateLine (width, bpp);
	BYTE *bits = FreeImage_GetBits (dib);

	// select the right decoder
	switch (type) {
		case 1:
			LoadDXT_Helper <DXT_BLOCKDECODER_1> (io, handle, page, flags, data, dib, width, height, line);
			break;
		case 3:
			LoadDXT_Helper <DXT_BLOCKDECODER_3> (io, handle, page, flags, data, dib, width, height, line);
			break;
		case 5:
			LoadDXT_Helper <DXT_BLOCKDECODER_5> (io, handle, page, flags, data, dib, width, height, line);
			break;
	}
	
	return dib;
}
// ==========================================================
// Plugin Implementation
// ==========================================================

static const char * DLL_CALLCONV
Format() {
	return "DDS";
}

static const char * DLL_CALLCONV
Description() {
	return "DirectX Surface";
}

static const char * DLL_CALLCONV
Extension() {
	return "dds";
}

static const char * DLL_CALLCONV
RegExpr() {
	return NULL;
}

static const char * DLL_CALLCONV
MimeType() {
	return "image/x-dds";
}

static BOOL DLL_CALLCONV
Validate(FreeImageIO *io, fi_handle handle) {
	DDSHEADER header;
	memset(&header, 0, sizeof(header));
	io->read_proc(&header, 1, sizeof(header), handle);
#ifdef FREEIMAGE_BIGENDIAN
	SwapHeader(&header);
#endif
	if (header.dwMagic != MAKEFOURCC ('D','D','S',' '))
		return FALSE;
	if (header.surfaceDesc.dwSize != sizeof (header.surfaceDesc) ||
		header.surfaceDesc.ddpfPixelFormat.dwSize != sizeof (header.surfaceDesc.ddpfPixelFormat))
		return FALSE;
	return TRUE;
}

static BOOL DLL_CALLCONV



( run in 1.199 second using v1.01-cache-2.11-cpan-d7f47b0818f )