irrlicht/source/Irrlicht/CImageLoaderDDS.h

216 lines
3.5 KiB
C++

// Copyright (C) 2002-2012 Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_IMAGE_LOADER_DDS_H_INCLUDED__
#define __C_IMAGE_LOADER_DDS_H_INCLUDED__
#include "IrrCompileConfig.h"
#if defined(_IRR_COMPILE_WITH_DDS_LOADER_) || defined(_IRR_COMPILE_WITH_DDS_DECODER_LOADER_)
#include "IImageLoader.h"
namespace irr
{
namespace video
{
/* dds pixel format types */
enum eDDSPixelFormat
{
DDS_PF_ARGB8888,
DDS_PF_DXT1,
DDS_PF_DXT2,
DDS_PF_DXT3,
DDS_PF_DXT4,
DDS_PF_DXT5,
DDS_PF_UNKNOWN
};
// byte-align structures
#include "irrpack.h"
/* structures */
struct ddsPixelFormat
{
u32 Size;
u32 Flags;
u32 FourCC;
u32 RGBBitCount;
u32 RBitMask;
u32 GBitMask;
u32 BBitMask;
u32 ABitMask;
} PACK_STRUCT;
struct ddsCaps
{
u32 caps1;
u32 caps2;
u32 caps3;
u32 caps4;
} PACK_STRUCT;
struct ddsHeader
{
c8 Magic[4];
u32 Size;
u32 Flags;
u32 Height;
u32 Width;
u32 PitchOrLinearSize;
u32 Depth;
u32 MipMapCount;
u32 Reserved1[11];
ddsPixelFormat PixelFormat;
ddsCaps Caps;
u32 Reserved2;
} PACK_STRUCT;
#ifdef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
struct ddsColorBlock
{
u16 colors[ 2 ];
u8 row[ 4 ];
} PACK_STRUCT;
struct ddsAlphaBlockExplicit
{
u16 row[ 4 ];
} PACK_STRUCT;
struct ddsAlphaBlock3BitLinear
{
u8 alpha0;
u8 alpha1;
u8 stuff[ 6 ];
} PACK_STRUCT;
struct ddsColor
{
u8 r, g, b, a;
} PACK_STRUCT;
#endif
// Default alignment
#include "irrunpack.h"
/* endian tomfoolery */
typedef union
{
f32 f;
c8 c[ 4 ];
}
floatSwapUnion;
#ifndef __BIG_ENDIAN__
#ifdef _SGI_SOURCE
#define __BIG_ENDIAN__
#endif
#endif
#ifdef __BIG_ENDIAN__
s32 DDSBigLong( s32 src ) { return src; }
s16 DDSBigShort( s16 src ) { return src; }
f32 DDSBigFloat( f32 src ) { return src; }
s32 DDSLittleLong( s32 src )
{
return ((src & 0xFF000000) >> 24) |
((src & 0x00FF0000) >> 8) |
((src & 0x0000FF00) << 8) |
((src & 0x000000FF) << 24);
}
s16 DDSLittleShort( s16 src )
{
return ((src & 0xFF00) >> 8) |
((src & 0x00FF) << 8);
}
f32 DDSLittleFloat( f32 src )
{
floatSwapUnion in,out;
in.f = src;
out.c[ 0 ] = in.c[ 3 ];
out.c[ 1 ] = in.c[ 2 ];
out.c[ 2 ] = in.c[ 1 ];
out.c[ 3 ] = in.c[ 0 ];
return out.f;
}
#else /*__BIG_ENDIAN__*/
s32 DDSLittleLong( s32 src ) { return src; }
s16 DDSLittleShort( s16 src ) { return src; }
f32 DDSLittleFloat( f32 src ) { return src; }
s32 DDSBigLong( s32 src )
{
return ((src & 0xFF000000) >> 24) |
((src & 0x00FF0000) >> 8) |
((src & 0x0000FF00) << 8) |
((src & 0x000000FF) << 24);
}
s16 DDSBigShort( s16 src )
{
return ((src & 0xFF00) >> 8) |
((src & 0x00FF) << 8);
}
f32 DDSBigFloat( f32 src )
{
floatSwapUnion in,out;
in.f = src;
out.c[ 0 ] = in.c[ 3 ];
out.c[ 1 ] = in.c[ 2 ];
out.c[ 2 ] = in.c[ 1 ];
out.c[ 3 ] = in.c[ 0 ];
return out.f;
}
#endif /*__BIG_ENDIAN__*/
/*!
Surface Loader for DDS images
*/
class CImageLoaderDDS : public IImageLoader
{
public:
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
virtual bool isALoadableFileExtension(const io::path& filename) const _IRR_OVERRIDE_;
//! returns true if the file maybe is able to be loaded by this class
virtual bool isALoadableFileFormat(io::IReadFile* file) const _IRR_OVERRIDE_;
//! creates a surface from the file
virtual IImage* loadImage(io::IReadFile* file) const _IRR_OVERRIDE_;
};
} // end namespace video
} // end namespace irr
#endif // compiled with DDS loader
#endif