irrlicht/source/Irrlicht/CImageLoaderDDS.h

325 lines
5.6 KiB
C++

// Copyright (C) 2002-2011 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"
#include "IImageLoader.h"
namespace irr
{
namespace video
{
#if defined(_IRR_COMPILE_WITH_DDS_LOADER_) || defined(_IRR_COMPILE_WITH_DDS_WRITER_)
// byte-align structures
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# define PACK_STRUCT
#endif
/* dependencies */
/* dds definition */
enum eDDSPixelFormat
{
DDS_PF_ARGB8888,
DDS_PF_DXT1,
DDS_PF_DXT2,
DDS_PF_DXT3,
DDS_PF_DXT4,
DDS_PF_DXT5,
DDS_PF_UNKNOWN
};
/* 16bpp stuff */
#define DDS_LOW_5 0x001F;
#define DDS_MID_6 0x07E0;
#define DDS_HIGH_5 0xF800;
#define DDS_MID_555 0x03E0;
#define DDS_HI_555 0x7C00;
/* structures */
struct ddsColorKey
{
u32 colorSpaceLowValue;
u32 colorSpaceHighValue;
} PACK_STRUCT;
struct ddsCaps
{
u32 caps1;
u32 caps2;
u32 caps3;
u32 caps4;
} PACK_STRUCT;
struct ddsMultiSampleCaps
{
u16 flipMSTypes;
u16 bltMSTypes;
} PACK_STRUCT;
struct ddsPixelFormat
{
u32 size;
u32 flags;
u32 fourCC;
union
{
u32 rgbBitCount;
u32 yuvBitCount;
u32 zBufferBitDepth;
u32 alphaBitDepth;
u32 luminanceBitCount;
u32 bumpBitCount;
u32 privateFormatBitCount;
};
union
{
u32 rBitMask;
u32 yBitMask;
u32 stencilBitDepth;
u32 luminanceBitMask;
u32 bumpDuBitMask;
u32 operations;
};
union
{
u32 gBitMask;
u32 uBitMask;
u32 zBitMask;
u32 bumpDvBitMask;
ddsMultiSampleCaps multiSampleCaps;
};
union
{
u32 bBitMask;
u32 vBitMask;
u32 stencilBitMask;
u32 bumpLuminanceBitMask;
};
union
{
u32 rgbAlphaBitMask;
u32 yuvAlphaBitMask;
u32 luminanceAlphaBitMask;
u32 rgbZBitMask;
u32 yuvZBitMask;
};
} PACK_STRUCT;
struct ddsBuffer
{
/* magic: 'dds ' */
c8 magic[ 4 ];
/* directdraw surface */
u32 size;
u32 flags;
u32 height;
u32 width;
union
{
s32 pitch;
u32 linearSize;
};
u32 backBufferCount;
union
{
u32 mipMapCount;
u32 refreshRate;
u32 srcVBHandle;
};
u32 alphaBitDepth;
u32 reserved;
void *surface;
union
{
ddsColorKey ckDestOverlay;
u32 emptyFaceColor;
};
ddsColorKey ckDestBlt;
ddsColorKey ckSrcOverlay;
ddsColorKey ckSrcBlt;
union
{
ddsPixelFormat pixelFormat;
u32 fvf;
};
ddsCaps caps;
u32 textureStage;
/* data (Varying size) */
u8 data[ 4 ];
} PACK_STRUCT;
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;
/* public functions */
s32 DDSGetInfo( ddsBuffer *dds, s32 *width, s32 *height, eDDSPixelFormat *pf );
s32 DDSDecompress( ddsBuffer *dds, u8 *pixels );
/* 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__*/
// Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
#endif // compiled with loader or reader
#ifdef _IRR_COMPILE_WITH_DDS_LOADER_
/*!
Surface Loader for targa 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;
//! returns true if the file maybe is able to be loaded by this class
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file
virtual IImage* loadImage(io::IReadFile* file) const;
private:
};
#endif // compiled with loader
} // end namespace video
} // end namespace irr
#endif