1 #include	<stdint.h>
2 #include	"base.h"
3 #include	"Image.h"
4 
5 namespace	DisplayOutput
6 {
7 
8 //
9 #pragma pack (push, 1)
10 
11 struct DDSHeader {
12 	unsigned int ddsIdentifier;
13 	unsigned int size;
14 	unsigned int flags;
15 	unsigned int height;
16 	unsigned int width;
17 	unsigned int pitchOrLinearSize;
18 	unsigned int depth;
19 	unsigned int nMipMaps;
20 	unsigned int reserved[11];
21 	unsigned int size2;
22 	unsigned int flags2;
23 	unsigned int fourCC;
24 	unsigned int bpp;
25 
26 	unsigned int rBitMask;
27 	unsigned int gBitMask;
28 	unsigned int bBitMask;
29 	unsigned int aBitMask;
30 
31 	unsigned int caps1;
32 	unsigned int caps2;
33 	unsigned int reserved2[3];
34 };
35 #pragma pack (pop)
36 
37 /*
38 	LoadDDS().
39 
40 */
LoadDDS(const std::string & _fileName,const bool _wantMipMaps)41 bool	CImage::LoadDDS( const std::string &_fileName, const bool _wantMipMaps )
42 {
43 	DDSHeader	header;
44 
45 	FILE *pFileData = fopen( _fileName.c_str(), "rb" );
46 	if( !pFileData )
47 	{
48 		ThrowStr( ("CImage::LoadDDS() Unable to open " + _fileName).c_str() );
49 		return( false );
50 	}
51 
52 	fread( &header, sizeof(header), 1, pFileData );
53 	if( header.ddsIdentifier != MCHAR4('D', 'D', 'S', ' ') )
54 	{
55 		ThrowStr( ("CImage::LoadDDS() No valid header in " + _fileName) );
56 		return( false );
57 	}
58 
59 	m_Width    = header.width;
60 	m_Height   = header.height;
61 
62 	m_nMipMaps = header.nMipMaps;
63 
64 	if( m_nMipMaps <= 0 || !_wantMipMaps )
65 		m_nMipMaps = 1;
66 	else
67 		m_nMipMaps = getNumberOfMipMapsFromDimesions();
68 
69 	switch( header.fourCC )
70 	{
71 		case MCHAR4('D', 'X', 'T', '1'):
72 			m_Format = CImageFormat( eImage_DXT1 );
73 			break;
74 		case MCHAR4('D', 'X', 'T', '3'):
75 			m_Format = CImageFormat( eImage_DXT3 );
76 			break;
77 		case MCHAR4('D', 'X', 'T', '5'):
78 			m_Format = CImageFormat( eImage_DXT5 );
79 			break;
80 		default:
81 			switch( header.bpp )
82 			{
83 				case 8:
84 					m_Format = CImageFormat( eImage_I8 );
85 					break;
86 				case 16:
87 					if( header.aBitMask )
88 						m_Format = CImageFormat( eImage_IA8 );
89 					else
90 						m_Format = CImageFormat( eImage_I16 );
91 					break;
92 				case 24:
93 					m_Format = CImageFormat( eImage_RGB8 );
94 					break;
95 				case 32:
96 					m_Format = CImageFormat( eImage_RGBA8 );
97 					break;
98 				default:
99 					return( false );
100 			}
101 	}
102 
103 	//	Calculate how large buffer we need possibly including mipmaps.
104 	uint32 readSize = getMipMappedSize( 0, m_nMipMaps );
105 	uint32 size;
106 
107 	if( m_Format.isPlain() && _wantMipMaps )
108 		size = getMipMappedSize( 0, 0x7fffffff );
109 	else
110 		size = readSize;
111 
112 	m_spData = new Base::CAlignedBuffer( size );
113 	fread( m_spData->GetBufferPtr(), readSize, 1, pFileData );
114 
115 	/*if( m_Format.is( eImage_RGB8 ) || m_Format.is( eImage_RGBA8 ) )
116 	{
117 		int nChannels = m_Format.GetChannels();
118 		flipChannels( m_pData, readSize / nChannels, nChannels );
119 	}*/
120 
121 	fclose( pFileData );
122 
123 	return( true );
124 }
125 };
126