aboutsummaryrefslogtreecommitdiff
path: root/source/Irrlicht/CImageLoaderDDS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Irrlicht/CImageLoaderDDS.cpp')
-rw-r--r--source/Irrlicht/CImageLoaderDDS.cpp887
1 files changed, 0 insertions, 887 deletions
diff --git a/source/Irrlicht/CImageLoaderDDS.cpp b/source/Irrlicht/CImageLoaderDDS.cpp
deleted file mode 100644
index 0a4ab3d..0000000
--- a/source/Irrlicht/CImageLoaderDDS.cpp
+++ /dev/null
@@ -1,887 +0,0 @@
-// Copyright (C) 2013 Patryk Nadrowski
-// Heavily based on the DDS loader implemented by Thomas Alten
-// and DDS loader from IrrSpintz implemented by Thomas Ince
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-/*
- Based on Code from Copyright (c) 2003 Randy Reddig
- Based on code from Nvidia's DDS example:
- http://www.nvidia.com/object/dxtc_decompression_code.html
-
- mainly c to cpp
-*/
-
-#include "CImageLoaderDDS.h"
-
-#if defined(_IRR_COMPILE_WITH_DDS_LOADER_) || defined(_IRR_COMPILE_WITH_DDS_DECODER_LOADER_)
-
-#include "IReadFile.h"
-#include "os.h"
-#include "CColorConverter.h"
-#include "CImage.h"
-#include "irrString.h"
-
-// Header flag values
-#define DDSD_CAPS 0x00000001
-#define DDSD_HEIGHT 0x00000002
-#define DDSD_WIDTH 0x00000004
-#define DDSD_PITCH 0x00000008
-#define DDSD_PIXELFORMAT 0x00001000
-#define DDSD_MIPMAPCOUNT 0x00020000
-#define DDSD_LINEARSIZE 0x00080000
-#define DDSD_DEPTH 0x00800000
-
-// Pixel format flag values
-#define DDPF_ALPHAPIXELS 0x00000001
-#define DDPF_ALPHA 0x00000002
-#define DDPF_FOURCC 0x00000004
-#define DDPF_RGB 0x00000040
-#define DDPF_COMPRESSED 0x00000080
-#define DDPF_LUMINANCE 0x00020000
-
-// Caps1 values
-#define DDSCAPS1_COMPLEX 0x00000008
-#define DDSCAPS1_TEXTURE 0x00001000
-#define DDSCAPS1_MIPMAP 0x00400000
-
-// Caps2 values
-#define DDSCAPS2_CUBEMAP 0x00000200
-#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
-#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
-#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
-#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
-#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
-#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
-#define DDSCAPS2_VOLUME 0x00200000
-
-namespace irr
-{
-
-namespace video
-{
-
-/*
-DDSGetInfo()
-extracts relevant info from a dds texture, returns 0 on success
-*/
-s32 DDSGetInfo(ddsHeader* dds, s32* width, s32* height, eDDSPixelFormat* pf)
-{
- /* dummy test */
- if( dds == NULL )
- return -1;
-
- /* test dds header */
- if( *((s32*) dds->Magic) != *((s32*) "DDS ") )
- return -1;
- if( DDSLittleLong( dds->Size ) != 124 )
- return -1;
- if( !(DDSLittleLong( dds->Flags ) & DDSD_PIXELFORMAT) )
- return -1;
- if( !(DDSLittleLong( dds->Flags ) & DDSD_CAPS) )
- return -1;
-
- /* extract width and height */
- if( width != NULL )
- *width = DDSLittleLong( dds->Width );
- if( height != NULL )
- *height = DDSLittleLong( dds->Height );
-
- /* get pixel format */
-
- /* extract fourCC */
- const u32 fourCC = dds->PixelFormat.FourCC;
-
- /* test it */
- if( fourCC == 0 )
- *pf = DDS_PF_ARGB8888;
- else if( fourCC == *((u32*) "DXT1") )
- *pf = DDS_PF_DXT1;
- else if( fourCC == *((u32*) "DXT2") )
- *pf = DDS_PF_DXT2;
- else if( fourCC == *((u32*) "DXT3") )
- *pf = DDS_PF_DXT3;
- else if( fourCC == *((u32*) "DXT4") )
- *pf = DDS_PF_DXT4;
- else if( fourCC == *((u32*) "DXT5") )
- *pf = DDS_PF_DXT5;
- else
- *pf = DDS_PF_UNKNOWN;
-
- /* return ok */
- return 0;
-}
-
-
-#ifdef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
-
-/*
-DDSDecompressARGB8888()
-decompresses an argb 8888 format texture
-*/
-s32 DDSDecompressARGB8888(ddsHeader* dds, u8* data, s32 width, s32 height, u8* pixels)
-{
- /* setup */
- u8* in = data;
- u8* out = pixels;
-
- /* walk y */
- for(s32 y = 0; y < height; y++)
- {
- /* walk x */
- for(s32 x = 0; x < width; x++)
- {
- *out++ = *in++;
- *out++ = *in++;
- *out++ = *in++;
- *out++ = *in++;
- }
- }
-
- /* return ok */
- return 0;
-}
-
-
-/*!
- DDSGetColorBlockColors()
- extracts colors from a dds color block
-*/
-void DDSGetColorBlockColors(ddsColorBlock* block, ddsColor colors[4])
-{
- u16 word;
-
-
- /* color 0 */
- word = DDSLittleShort( block->colors[ 0 ] );
- colors[ 0 ].a = 0xff;
-
- /* extract rgb bits */
- colors[ 0 ].b = (u8) word;
- colors[ 0 ].b <<= 3;
- colors[ 0 ].b |= (colors[ 0 ].b >> 5);
- word >>= 5;
- colors[ 0 ].g = (u8) word;
- colors[ 0 ].g <<= 2;
- colors[ 0 ].g |= (colors[ 0 ].g >> 5);
- word >>= 6;
- colors[ 0 ].r = (u8) word;
- colors[ 0 ].r <<= 3;
- colors[ 0 ].r |= (colors[ 0 ].r >> 5);
-
- /* same for color 1 */
- word = DDSLittleShort( block->colors[ 1 ] );
- colors[ 1 ].a = 0xff;
-
- /* extract rgb bits */
- colors[ 1 ].b = (u8) word;
- colors[ 1 ].b <<= 3;
- colors[ 1 ].b |= (colors[ 1 ].b >> 5);
- word >>= 5;
- colors[ 1 ].g = (u8) word;
- colors[ 1 ].g <<= 2;
- colors[ 1 ].g |= (colors[ 1 ].g >> 5);
- word >>= 6;
- colors[ 1 ].r = (u8) word;
- colors[ 1 ].r <<= 3;
- colors[ 1 ].r |= (colors[ 1 ].r >> 5);
-
- /* use this for all but the super-freak math method */
- if( block->colors[ 0 ] > block->colors[ 1 ] )
- {
- /* four-color block: derive the other two colors.
- 00 = color 0, 01 = color 1, 10 = color 2, 11 = color 3
- these two bit codes correspond to the 2-bit fields
- stored in the 64-bit block. */
-
- word = ((u16) colors[ 0 ].r * 2 + (u16) colors[ 1 ].r ) / 3;
- /* no +1 for rounding */
- /* as bits have been shifted to 888 */
- colors[ 2 ].r = (u8) word;
- word = ((u16) colors[ 0 ].g * 2 + (u16) colors[ 1 ].g) / 3;
- colors[ 2 ].g = (u8) word;
- word = ((u16) colors[ 0 ].b * 2 + (u16) colors[ 1 ].b) / 3;
- colors[ 2 ].b = (u8) word;
- colors[ 2 ].a = 0xff;
-
- word = ((u16) colors[ 0 ].r + (u16) colors[ 1 ].r * 2) / 3;
- colors[ 3 ].r = (u8) word;
- word = ((u16) colors[ 0 ].g + (u16) colors[ 1 ].g * 2) / 3;
- colors[ 3 ].g = (u8) word;
- word = ((u16) colors[ 0 ].b + (u16) colors[ 1 ].b * 2) / 3;
- colors[ 3 ].b = (u8) word;
- colors[ 3 ].a = 0xff;
- }
- else
- {
- /* three-color block: derive the other color.
- 00 = color 0, 01 = color 1, 10 = color 2,
- 11 = transparent.
- These two bit codes correspond to the 2-bit fields
- stored in the 64-bit block */
-
- word = ((u16) colors[ 0 ].r + (u16) colors[ 1 ].r) / 2;
- colors[ 2 ].r = (u8) word;
- word = ((u16) colors[ 0 ].g + (u16) colors[ 1 ].g) / 2;
- colors[ 2 ].g = (u8) word;
- word = ((u16) colors[ 0 ].b + (u16) colors[ 1 ].b) / 2;
- colors[ 2 ].b = (u8) word;
- colors[ 2 ].a = 0xff;
-
- /* random color to indicate alpha */
- colors[ 3 ].r = 0x00;
- colors[ 3 ].g = 0xff;
- colors[ 3 ].b = 0xff;
- colors[ 3 ].a = 0x00;
- }
-}
-
-
-/*
-DDSDecodeColorBlock()
-decodes a dds color block
-fixme: make endian-safe
-*/
-
-void DDSDecodeColorBlock(u32* pixel, ddsColorBlock* block, s32 width, u32 colors[4])
-{
- s32 r, n;
- u32 bits;
- u32 masks[] = { 3, 12, 3 << 4, 3 << 6 }; /* bit masks = 00000011, 00001100, 00110000, 11000000 */
- s32 shift[] = { 0, 2, 4, 6 };
-
-
- /* r steps through lines in y */
- for( r = 0; r < 4; r++, pixel += (width - 4) ) /* no width * 4 as u32 ptr inc will * 4 */
- {
- /* width * 4 bytes per pixel per line, each j dxtc row is 4 lines of pixels */
-
- /* n steps through pixels */
- for( n = 0; n < 4; n++ )
- {
- bits = block->row[ r ] & masks[ n ];
- bits >>= shift[ n ];
-
- switch( bits )
- {
- case 0:
- *pixel = colors[ 0 ];
- pixel++;
- break;
-
- case 1:
- *pixel = colors[ 1 ];
- pixel++;
- break;
-
- case 2:
- *pixel = colors[ 2 ];
- pixel++;
- break;
-
- case 3:
- *pixel = colors[ 3 ];
- pixel++;
- break;
-
- default:
- /* invalid */
- pixel++;
- break;
- }
- }
- }
-}
-
-
-/*
-DDSDecodeAlphaExplicit()
-decodes a dds explicit alpha block
-*/
-void DDSDecodeAlphaExplicit(u32* pixel, ddsAlphaBlockExplicit* alphaBlock, s32 width, u32 alphaZero)
-{
- s32 row, pix;
- u16 word;
- ddsColor color;
-
-
- /* clear color */
- color.r = 0;
- color.g = 0;
- color.b = 0;
-
- /* walk rows */
- for( row = 0; row < 4; row++, pixel += (width - 4) )
- {
- word = DDSLittleShort( alphaBlock->row[ row ] );
-
- /* walk pixels */
- for( pix = 0; pix < 4; pix++ )
- {
- /* zero the alpha bits of image pixel */
- *pixel &= alphaZero;
- color.a = word & 0x000F;
- color.a = color.a | (color.a << 4);
- *pixel |= *((u32*) &color);
- word >>= 4; /* move next bits to lowest 4 */
- pixel++; /* move to next pixel in the row */
- }
- }
-}
-
-
-
-/*
-DDSDecodeAlpha3BitLinear()
-decodes interpolated alpha block
-*/
-void DDSDecodeAlpha3BitLinear(u32* pixel, ddsAlphaBlock3BitLinear* alphaBlock, s32 width, u32 alphaZero)
-{
-
- s32 row, pix;
- u32 stuff;
- u8 bits[ 4 ][ 4 ];
- u16 alphas[ 8 ];
- ddsColor aColors[ 4 ][ 4 ];
-
- /* get initial alphas */
- alphas[ 0 ] = alphaBlock->alpha0;
- alphas[ 1 ] = alphaBlock->alpha1;
-
- /* 8-alpha block */
- if( alphas[ 0 ] > alphas[ 1 ] )
- {
- /* 000 = alpha_0, 001 = alpha_1, others are interpolated */
- alphas[ 2 ] = ( 6 * alphas[ 0 ] + alphas[ 1 ]) / 7; /* bit code 010 */
- alphas[ 3 ] = ( 5 * alphas[ 0 ] + 2 * alphas[ 1 ]) / 7; /* bit code 011 */
- alphas[ 4 ] = ( 4 * alphas[ 0 ] + 3 * alphas[ 1 ]) / 7; /* bit code 100 */
- alphas[ 5 ] = ( 3 * alphas[ 0 ] + 4 * alphas[ 1 ]) / 7; /* bit code 101 */
- alphas[ 6 ] = ( 2 * alphas[ 0 ] + 5 * alphas[ 1 ]) / 7; /* bit code 110 */
- alphas[ 7 ] = ( alphas[ 0 ] + 6 * alphas[ 1 ]) / 7; /* bit code 111 */
- }
-
- /* 6-alpha block */
- else
- {
- /* 000 = alpha_0, 001 = alpha_1, others are interpolated */
- alphas[ 2 ] = (4 * alphas[ 0 ] + alphas[ 1 ]) / 5; /* bit code 010 */
- alphas[ 3 ] = (3 * alphas[ 0 ] + 2 * alphas[ 1 ]) / 5; /* bit code 011 */
- alphas[ 4 ] = (2 * alphas[ 0 ] + 3 * alphas[ 1 ]) / 5; /* bit code 100 */
- alphas[ 5 ] = ( alphas[ 0 ] + 4 * alphas[ 1 ]) / 5; /* bit code 101 */
- alphas[ 6 ] = 0; /* bit code 110 */
- alphas[ 7 ] = 255; /* bit code 111 */
- }
-
- /* decode 3-bit fields into array of 16 bytes with same value */
-
- /* first two rows of 4 pixels each */
- stuff = *((u32*) &(alphaBlock->stuff[ 0 ]));
-
- bits[ 0 ][ 0 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 0 ][ 1 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 0 ][ 2 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 0 ][ 3 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 1 ][ 0 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 1 ][ 1 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 1 ][ 2 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 1 ][ 3 ] = (u8) (stuff & 0x00000007);
-
- /* last two rows */
- stuff = *((u32*) &(alphaBlock->stuff[ 3 ])); /* last 3 bytes */
-
- bits[ 2 ][ 0 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 2 ][ 1 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 2 ][ 2 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 2 ][ 3 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 3 ][ 0 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 3 ][ 1 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 3 ][ 2 ] = (u8) (stuff & 0x00000007);
- stuff >>= 3;
- bits[ 3 ][ 3 ] = (u8) (stuff & 0x00000007);
-
- /* decode the codes into alpha values */
- for( row = 0; row < 4; row++ )
- {
- for( pix=0; pix < 4; pix++ )
- {
- aColors[ row ][ pix ].r = 0;
- aColors[ row ][ pix ].g = 0;
- aColors[ row ][ pix ].b = 0;
- aColors[ row ][ pix ].a = (u8) alphas[ bits[ row ][ pix ] ];
- }
- }
-
- /* write out alpha values to the image bits */
- for( row = 0; row < 4; row++, pixel += width-4 )
- {
- for( pix = 0; pix < 4; pix++ )
- {
- /* zero the alpha bits of image pixel */
- *pixel &= alphaZero;
-
- /* or the bits into the prev. nulled alpha */
- *pixel |= *((u32*) &(aColors[ row ][ pix ]));
- pixel++;
- }
- }
-}
-
-
-/*
-DDSDecompressDXT1()
-decompresses a dxt1 format texture
-*/
-s32 DDSDecompressDXT1(ddsHeader* dds, u8* data, s32 width, s32 height, u8* pixels)
-{
- s32 x, y, xBlocks, yBlocks;
- u32 *pixel;
- ddsColorBlock *block;
- ddsColor colors[ 4 ];
-
- /* setup */
- xBlocks = width / 4;
- yBlocks = height / 4;
-
- /* walk y */
- for( y = 0; y < yBlocks; y++ )
- {
- /* 8 bytes per block */
- block = (ddsColorBlock*) (data + y * xBlocks * 8);
-
- /* walk x */
- for( x = 0; x < xBlocks; x++, block++ )
- {
- DDSGetColorBlockColors( block, colors );
- pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4);
- DDSDecodeColorBlock( pixel, block, width, (u32*) colors );
- }
- }
-
- /* return ok */
- return 0;
-}
-
-
-/*
-DDSDecompressDXT3()
-decompresses a dxt3 format texture
-*/
-
-s32 DDSDecompressDXT3(ddsHeader* dds, u8* data, s32 width, s32 height, u8* pixels)
-{
- s32 x, y, xBlocks, yBlocks;
- u32 *pixel, alphaZero;
- ddsColorBlock *block;
- ddsAlphaBlockExplicit *alphaBlock;
- ddsColor colors[ 4 ];
-
- /* setup */
- xBlocks = width / 4;
- yBlocks = height / 4;
-
- /* create zero alpha */
- colors[ 0 ].a = 0;
- colors[ 0 ].r = 0xFF;
- colors[ 0 ].g = 0xFF;
- colors[ 0 ].b = 0xFF;
- alphaZero = *((u32*) &colors[ 0 ]);
-
- /* walk y */
- for( y = 0; y < yBlocks; y++ )
- {
- /* 8 bytes per block, 1 block for alpha, 1 block for color */
- block = (ddsColorBlock*) (data + y * xBlocks * 16);
-
- /* walk x */
- for( x = 0; x < xBlocks; x++, block++ )
- {
- /* get alpha block */
- alphaBlock = (ddsAlphaBlockExplicit*) block;
-
- /* get color block */
- block++;
- DDSGetColorBlockColors( block, colors );
-
- /* decode color block */
- pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4);
- DDSDecodeColorBlock( pixel, block, width, (u32*) colors );
-
- /* overwrite alpha bits with alpha block */
- DDSDecodeAlphaExplicit( pixel, alphaBlock, width, alphaZero );
- }
- }
-
- /* return ok */
- return 0;
-}
-
-
-/*
-DDSDecompressDXT5()
-decompresses a dxt5 format texture
-*/
-s32 DDSDecompressDXT5(ddsHeader* dds, u8* data, s32 width, s32 height, u8* pixels)
-{
- s32 x, y, xBlocks, yBlocks;
- u32 *pixel, alphaZero;
- ddsColorBlock *block;
- ddsAlphaBlock3BitLinear *alphaBlock;
- ddsColor colors[ 4 ];
-
- /* setup */
- xBlocks = width / 4;
- yBlocks = height / 4;
-
- /* create zero alpha */
- colors[ 0 ].a = 0;
- colors[ 0 ].r = 0xFF;
- colors[ 0 ].g = 0xFF;
- colors[ 0 ].b = 0xFF;
- alphaZero = *((u32*) &colors[ 0 ]);
-
- /* walk y */
- for( y = 0; y < yBlocks; y++ )
- {
- /* 8 bytes per block, 1 block for alpha, 1 block for color */
- block = (ddsColorBlock*) (data + y * xBlocks * 16);
-
- /* walk x */
- for( x = 0; x < xBlocks; x++, block++ )
- {
- /* get alpha block */
- alphaBlock = (ddsAlphaBlock3BitLinear*) block;
-
- /* get color block */
- block++;
- DDSGetColorBlockColors( block, colors );
-
- /* decode color block */
- pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4);
- DDSDecodeColorBlock( pixel, block, width, (u32*) colors );
-
- /* overwrite alpha bits with alpha block */
- DDSDecodeAlpha3BitLinear( pixel, alphaBlock, width, alphaZero );
- }
- }
-
- /* return ok */
- return 0;
-}
-
-
-/*
-DDSDecompressDXT2()
-decompresses a dxt2 format texture (fixme: un-premultiply alpha)
-*/
-s32 DDSDecompressDXT2(ddsHeader* dds, u8* data, s32 width, s32 height, u8* pixels)
-{
- /* decompress dxt3 first */
- const s32 r = DDSDecompressDXT3( dds, data, width, height, pixels );
-
- /* return to sender */
- return r;
-}
-
-
-/*
-DDSDecompressDXT4()
-decompresses a dxt4 format texture (fixme: un-premultiply alpha)
-*/
-s32 DDSDecompressDXT4(ddsHeader* dds, u8* data, s32 width, s32 height, u8* pixels)
-{
- /* decompress dxt5 first */
- const s32 r = DDSDecompressDXT5( dds, data, width, height, pixels );
-
- /* return to sender */
- return r;
-}
-
-
-/*
-DDSDecompress()
-decompresses a dds texture into an rgba image buffer, returns 0 on success
-*/
-s32 DDSDecompress(ddsHeader* dds, u8* data, u8* pixels)
-{
- s32 width, height;
- eDDSPixelFormat pf;
-
- /* get dds info */
- s32 r = DDSGetInfo( dds, &width, &height, &pf );
- if ( r )
- return r;
-
- /* decompress */
- switch( pf )
- {
- case DDS_PF_ARGB8888:
- /* fixme: support other [a]rgb formats */
- r = DDSDecompressARGB8888( dds, data, width, height, pixels );
- break;
-
- case DDS_PF_DXT1:
- r = DDSDecompressDXT1( dds, data, width, height, pixels );
- break;
-
- case DDS_PF_DXT2:
- r = DDSDecompressDXT2( dds, data, width, height, pixels );
- break;
-
- case DDS_PF_DXT3:
- r = DDSDecompressDXT3( dds, data, width, height, pixels );
- break;
-
- case DDS_PF_DXT4:
- r = DDSDecompressDXT4( dds, data, width, height, pixels );
- break;
-
- case DDS_PF_DXT5:
- r = DDSDecompressDXT5( dds, data, width, height, pixels );
- break;
-
- default: // DDS_PF_UNKNOWN
- r = -1;
- break;
- }
-
- /* return to sender */
- return r;
-}
-
-#endif
-
-
-//! returns true if the file maybe is able to be loaded by this class
-//! based on the file extension (e.g. ".tga")
-bool CImageLoaderDDS::isALoadableFileExtension(const io::path& filename) const
-{
- return core::hasFileExtension(filename, "dds");
-}
-
-
-//! returns true if the file maybe is able to be loaded by this class
-bool CImageLoaderDDS::isALoadableFileFormat(io::IReadFile* file) const
-{
- if (!file)
- return false;
-
- c8 MagicWord[4];
- file->read(&MagicWord, 4);
-
- return (MagicWord[0] == 'D' && MagicWord[1] == 'D' && MagicWord[2] == 'S');
-}
-
-
-//! creates a surface from the file
-IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const
-{
- ddsHeader header;
- IImage* image = 0;
- s32 width, height;
- eDDSPixelFormat pixelFormat;
- ECOLOR_FORMAT format = ECF_UNKNOWN;
- u32 dataSize = 0;
- u32 mipMapsDataSize = 0;
- bool is3D = false;
- bool useAlpha = false;
- u32 mipMapCount = 0;
-
- file->seek(0);
- file->read(&header, sizeof(ddsHeader));
-
- if (0 == DDSGetInfo(&header, &width, &height, &pixelFormat))
- {
- is3D = header.Depth > 0 && (header.Flags & DDSD_DEPTH);
-
- if (!is3D)
- header.Depth = 1;
-
- useAlpha = header.PixelFormat.Flags & DDPF_ALPHAPIXELS;
-
- if (header.MipMapCount > 0 && (header.Flags & DDSD_MIPMAPCOUNT))
- mipMapCount = header.MipMapCount;
-
-#ifdef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
- u32 newSize = file->getSize() - sizeof(ddsHeader);
- u8* memFile = new u8[newSize];
- file->read(memFile, newSize);
-
- image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));
-
- if (DDSDecompress(&header, memFile, (u8*)image->lock()) == -1)
- {
- image->unlock();
- image->drop();
- image = 0;
- }
-
- delete[] memFile;
-#else
- if (header.PixelFormat.Flags & DDPF_RGB) // Uncompressed formats
- {
-// u32 byteCount = header.PixelFormat.RGBBitCount / 8;
-
- if( header.Flags & DDSD_PITCH )
- dataSize = header.PitchOrLinearSize * header.Height * header.Depth * (header.PixelFormat.RGBBitCount / 8);
- else
- dataSize = header.Width * header.Height * header.Depth * (header.PixelFormat.RGBBitCount / 8);
-
- u8* data = new u8[dataSize];
- file->read(data, dataSize);
-
- switch (header.PixelFormat.RGBBitCount) // Bytes per pixel
- {
- case 16:
- {
- if (useAlpha)
- {
- if (header.PixelFormat.ABitMask == 0x8000)
- format = ECF_A1R5G5B5;
- }
- else
- {
- if (header.PixelFormat.RBitMask == 0xf800)
- format = ECF_R5G6B5;
- }
-
- break;
- }
- case 24:
- {
- if (!useAlpha)
- {
- if (header.PixelFormat.RBitMask == 0xff0000)
- format = ECF_R8G8B8;
- }
-
- break;
- }
- case 32:
- {
- if (useAlpha)
- {
- if (header.PixelFormat.RBitMask & 0xff0000)
- format = ECF_A8R8G8B8;
- else if (header.PixelFormat.RBitMask & 0xff)
- {
- // convert from A8B8G8R8 to A8R8G8B8
- u8 tmp = 0;
-
- for (u32 i = 0; i < dataSize; i += 4)
- {
- tmp = data[i];
- data[i] = data[i+2];
- data[i+2] = tmp;
- }
- }
- }
-
- break;
- }
- }
-
- if (format != ECF_UNKNOWN)
- {
- if (!is3D) // Currently 3D textures are unsupported.
- {
- image = new CImage(format, core::dimension2d<u32>(header.Width, header.Height), data, true, true);
- }
- }
- else
- {
- delete[] data;
- }
- }
- else if (header.PixelFormat.Flags & DDPF_FOURCC) // Compressed formats
- {
- switch(pixelFormat)
- {
- case DDS_PF_DXT1:
- {
- format = ECF_DXT1;
- break;
- }
- case DDS_PF_DXT2:
- case DDS_PF_DXT3:
- {
- format = ECF_DXT3;
- break;
- }
- case DDS_PF_DXT4:
- case DDS_PF_DXT5:
- {
- format = ECF_DXT5;
- break;
- }
- default: // either not compressed or unknown
- break;
- }
-
- if( format != ECF_UNKNOWN )
- {
- if (!is3D) // Currently 3D textures are unsupported.
- {
- dataSize = IImage::getDataSizeFromFormat(format, header.Width, header.Height);
-
- u8* data = new u8[dataSize];
- file->read(data, dataSize);
-
- image = new CImage(format, core::dimension2d<u32>(header.Width, header.Height), data, true, true);
-
- if (mipMapCount > 0)
- {
- u32 tmpWidth = header.Width;
- u32 tmpHeight = header.Height;
-
- do
- {
- if (tmpWidth > 1)
- tmpWidth >>= 1;
-
- if (tmpHeight > 1)
- tmpHeight >>= 1;
-
- mipMapsDataSize += IImage::getDataSizeFromFormat(format, tmpWidth, tmpHeight);
- }
- while (tmpWidth != 1 || tmpHeight != 1);
-
- u8* mipMapsData = new u8[mipMapsDataSize];
- file->read(mipMapsData, mipMapsDataSize);
-
- image->setMipMapsData(mipMapsData, true, true);
- }
- }
- }
- }
-#endif
- }
-
- return image;
-}
-
-
-//! creates a loader which is able to load dds images
-IImageLoader* createImageLoaderDDS()
-{
- return new CImageLoaderDDS();
-}
-
-
-} // end namespace video
-} // end namespace irr
-
-#endif
-