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 )