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