aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderDDS.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderDDS.cpp
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderDDS.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderDDS.cpp1424
1 files changed, 712 insertions, 712 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderDDS.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderDDS.cpp
index 646abd2..69cb98c 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderDDS.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderDDS.cpp
@@ -1,712 +1,712 @@
1// Copyright (C) 2002-2012 Thomas Alten 1// Copyright (C) 2002-2012 Thomas Alten
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4 4
5/* 5/*
6 Based on Code from Copyright (c) 2003 Randy Reddig 6 Based on Code from Copyright (c) 2003 Randy Reddig
7 Based on code from Nvidia's DDS example: 7 Based on code from Nvidia's DDS example:
8 http://www.nvidia.com/object/dxtc_decompression_code.html 8 http://www.nvidia.com/object/dxtc_decompression_code.html
9 9
10 mainly c to cpp 10 mainly c to cpp
11*/ 11*/
12 12
13 13
14#include "CImageLoaderDDS.h" 14#include "CImageLoaderDDS.h"
15 15
16#ifdef _IRR_COMPILE_WITH_DDS_LOADER_ 16#ifdef _IRR_COMPILE_WITH_DDS_LOADER_
17 17
18#include "IReadFile.h" 18#include "IReadFile.h"
19#include "os.h" 19#include "os.h"
20#include "CColorConverter.h" 20#include "CColorConverter.h"
21#include "CImage.h" 21#include "CImage.h"
22#include "irrString.h" 22#include "irrString.h"
23 23
24 24
25namespace irr 25namespace irr
26{ 26{
27 27
28namespace video 28namespace video
29{ 29{
30 30
31namespace 31namespace
32{ 32{
33 33
34/*! 34/*!
35 DDSDecodePixelFormat() 35 DDSDecodePixelFormat()
36 determines which pixel format the dds texture is in 36 determines which pixel format the dds texture is in
37*/ 37*/
38void DDSDecodePixelFormat( ddsBuffer *dds, eDDSPixelFormat *pf ) 38void DDSDecodePixelFormat( ddsBuffer *dds, eDDSPixelFormat *pf )
39{ 39{
40 /* dummy check */ 40 /* dummy check */
41 if( dds == NULL || pf == NULL ) 41 if( dds == NULL || pf == NULL )
42 return; 42 return;
43 43
44 /* extract fourCC */ 44 /* extract fourCC */
45 const u32 fourCC = dds->pixelFormat.fourCC; 45 const u32 fourCC = dds->pixelFormat.fourCC;
46 46
47 /* test it */ 47 /* test it */
48 if( fourCC == 0 ) 48 if( fourCC == 0 )
49 *pf = DDS_PF_ARGB8888; 49 *pf = DDS_PF_ARGB8888;
50 else if( fourCC == *((u32*) "DXT1") ) 50 else if( fourCC == *((u32*) "DXT1") )
51 *pf = DDS_PF_DXT1; 51 *pf = DDS_PF_DXT1;
52 else if( fourCC == *((u32*) "DXT2") ) 52 else if( fourCC == *((u32*) "DXT2") )
53 *pf = DDS_PF_DXT2; 53 *pf = DDS_PF_DXT2;
54 else if( fourCC == *((u32*) "DXT3") ) 54 else if( fourCC == *((u32*) "DXT3") )
55 *pf = DDS_PF_DXT3; 55 *pf = DDS_PF_DXT3;
56 else if( fourCC == *((u32*) "DXT4") ) 56 else if( fourCC == *((u32*) "DXT4") )
57 *pf = DDS_PF_DXT4; 57 *pf = DDS_PF_DXT4;
58 else if( fourCC == *((u32*) "DXT5") ) 58 else if( fourCC == *((u32*) "DXT5") )
59 *pf = DDS_PF_DXT5; 59 *pf = DDS_PF_DXT5;
60 else 60 else
61 *pf = DDS_PF_UNKNOWN; 61 *pf = DDS_PF_UNKNOWN;
62} 62}
63 63
64 64
65/*! 65/*!
66DDSGetInfo() 66DDSGetInfo()
67extracts relevant info from a dds texture, returns 0 on success 67extracts relevant info from a dds texture, returns 0 on success
68*/ 68*/
69s32 DDSGetInfo( ddsBuffer *dds, s32 *width, s32 *height, eDDSPixelFormat *pf ) 69s32 DDSGetInfo( ddsBuffer *dds, s32 *width, s32 *height, eDDSPixelFormat *pf )
70{ 70{
71 /* dummy test */ 71 /* dummy test */
72 if( dds == NULL ) 72 if( dds == NULL )
73 return -1; 73 return -1;
74 74
75 /* test dds header */ 75 /* test dds header */
76 if( *((s32*) dds->magic) != *((s32*) "DDS ") ) 76 if( *((s32*) dds->magic) != *((s32*) "DDS ") )
77 return -1; 77 return -1;
78 if( DDSLittleLong( dds->size ) != 124 ) 78 if( DDSLittleLong( dds->size ) != 124 )
79 return -1; 79 return -1;
80 80
81 /* extract width and height */ 81 /* extract width and height */
82 if( width != NULL ) 82 if( width != NULL )
83 *width = DDSLittleLong( dds->width ); 83 *width = DDSLittleLong( dds->width );
84 if( height != NULL ) 84 if( height != NULL )
85 *height = DDSLittleLong( dds->height ); 85 *height = DDSLittleLong( dds->height );
86 86
87 /* get pixel format */ 87 /* get pixel format */
88 DDSDecodePixelFormat( dds, pf ); 88 DDSDecodePixelFormat( dds, pf );
89 89
90 /* return ok */ 90 /* return ok */
91 return 0; 91 return 0;
92} 92}
93 93
94 94
95/*! 95/*!
96 DDSGetColorBlockColors() 96 DDSGetColorBlockColors()
97 extracts colors from a dds color block 97 extracts colors from a dds color block
98*/ 98*/
99void DDSGetColorBlockColors( ddsColorBlock *block, ddsColor colors[ 4 ] ) 99void DDSGetColorBlockColors( ddsColorBlock *block, ddsColor colors[ 4 ] )
100{ 100{
101 u16 word; 101 u16 word;
102 102
103 103
104 /* color 0 */ 104 /* color 0 */
105 word = DDSLittleShort( block->colors[ 0 ] ); 105 word = DDSLittleShort( block->colors[ 0 ] );
106 colors[ 0 ].a = 0xff; 106 colors[ 0 ].a = 0xff;
107 107
108 /* extract rgb bits */ 108 /* extract rgb bits */
109 colors[ 0 ].b = (u8) word; 109 colors[ 0 ].b = (u8) word;
110 colors[ 0 ].b <<= 3; 110 colors[ 0 ].b <<= 3;
111 colors[ 0 ].b |= (colors[ 0 ].b >> 5); 111 colors[ 0 ].b |= (colors[ 0 ].b >> 5);
112 word >>= 5; 112 word >>= 5;
113 colors[ 0 ].g = (u8) word; 113 colors[ 0 ].g = (u8) word;
114 colors[ 0 ].g <<= 2; 114 colors[ 0 ].g <<= 2;
115 colors[ 0 ].g |= (colors[ 0 ].g >> 5); 115 colors[ 0 ].g |= (colors[ 0 ].g >> 5);
116 word >>= 6; 116 word >>= 6;
117 colors[ 0 ].r = (u8) word; 117 colors[ 0 ].r = (u8) word;
118 colors[ 0 ].r <<= 3; 118 colors[ 0 ].r <<= 3;
119 colors[ 0 ].r |= (colors[ 0 ].r >> 5); 119 colors[ 0 ].r |= (colors[ 0 ].r >> 5);
120 120
121 /* same for color 1 */ 121 /* same for color 1 */
122 word = DDSLittleShort( block->colors[ 1 ] ); 122 word = DDSLittleShort( block->colors[ 1 ] );
123 colors[ 1 ].a = 0xff; 123 colors[ 1 ].a = 0xff;
124 124
125 /* extract rgb bits */ 125 /* extract rgb bits */
126 colors[ 1 ].b = (u8) word; 126 colors[ 1 ].b = (u8) word;
127 colors[ 1 ].b <<= 3; 127 colors[ 1 ].b <<= 3;
128 colors[ 1 ].b |= (colors[ 1 ].b >> 5); 128 colors[ 1 ].b |= (colors[ 1 ].b >> 5);
129 word >>= 5; 129 word >>= 5;
130 colors[ 1 ].g = (u8) word; 130 colors[ 1 ].g = (u8) word;
131 colors[ 1 ].g <<= 2; 131 colors[ 1 ].g <<= 2;
132 colors[ 1 ].g |= (colors[ 1 ].g >> 5); 132 colors[ 1 ].g |= (colors[ 1 ].g >> 5);
133 word >>= 6; 133 word >>= 6;
134 colors[ 1 ].r = (u8) word; 134 colors[ 1 ].r = (u8) word;
135 colors[ 1 ].r <<= 3; 135 colors[ 1 ].r <<= 3;
136 colors[ 1 ].r |= (colors[ 1 ].r >> 5); 136 colors[ 1 ].r |= (colors[ 1 ].r >> 5);
137 137
138 /* use this for all but the super-freak math method */ 138 /* use this for all but the super-freak math method */
139 if( block->colors[ 0 ] > block->colors[ 1 ] ) 139 if( block->colors[ 0 ] > block->colors[ 1 ] )
140 { 140 {
141 /* four-color block: derive the other two colors. 141 /* four-color block: derive the other two colors.
142 00 = color 0, 01 = color 1, 10 = color 2, 11 = color 3 142 00 = color 0, 01 = color 1, 10 = color 2, 11 = color 3
143 these two bit codes correspond to the 2-bit fields 143 these two bit codes correspond to the 2-bit fields
144 stored in the 64-bit block. */ 144 stored in the 64-bit block. */
145 145
146 word = ((u16) colors[ 0 ].r * 2 + (u16) colors[ 1 ].r ) / 3; 146 word = ((u16) colors[ 0 ].r * 2 + (u16) colors[ 1 ].r ) / 3;
147 /* no +1 for rounding */ 147 /* no +1 for rounding */
148 /* as bits have been shifted to 888 */ 148 /* as bits have been shifted to 888 */
149 colors[ 2 ].r = (u8) word; 149 colors[ 2 ].r = (u8) word;
150 word = ((u16) colors[ 0 ].g * 2 + (u16) colors[ 1 ].g) / 3; 150 word = ((u16) colors[ 0 ].g * 2 + (u16) colors[ 1 ].g) / 3;
151 colors[ 2 ].g = (u8) word; 151 colors[ 2 ].g = (u8) word;
152 word = ((u16) colors[ 0 ].b * 2 + (u16) colors[ 1 ].b) / 3; 152 word = ((u16) colors[ 0 ].b * 2 + (u16) colors[ 1 ].b) / 3;
153 colors[ 2 ].b = (u8) word; 153 colors[ 2 ].b = (u8) word;
154 colors[ 2 ].a = 0xff; 154 colors[ 2 ].a = 0xff;
155 155
156 word = ((u16) colors[ 0 ].r + (u16) colors[ 1 ].r * 2) / 3; 156 word = ((u16) colors[ 0 ].r + (u16) colors[ 1 ].r * 2) / 3;
157 colors[ 3 ].r = (u8) word; 157 colors[ 3 ].r = (u8) word;
158 word = ((u16) colors[ 0 ].g + (u16) colors[ 1 ].g * 2) / 3; 158 word = ((u16) colors[ 0 ].g + (u16) colors[ 1 ].g * 2) / 3;
159 colors[ 3 ].g = (u8) word; 159 colors[ 3 ].g = (u8) word;
160 word = ((u16) colors[ 0 ].b + (u16) colors[ 1 ].b * 2) / 3; 160 word = ((u16) colors[ 0 ].b + (u16) colors[ 1 ].b * 2) / 3;
161 colors[ 3 ].b = (u8) word; 161 colors[ 3 ].b = (u8) word;
162 colors[ 3 ].a = 0xff; 162 colors[ 3 ].a = 0xff;
163 } 163 }
164 else 164 else
165 { 165 {
166 /* three-color block: derive the other color. 166 /* three-color block: derive the other color.
167 00 = color 0, 01 = color 1, 10 = color 2, 167 00 = color 0, 01 = color 1, 10 = color 2,
168 11 = transparent. 168 11 = transparent.
169 These two bit codes correspond to the 2-bit fields 169 These two bit codes correspond to the 2-bit fields
170 stored in the 64-bit block */ 170 stored in the 64-bit block */
171 171
172 word = ((u16) colors[ 0 ].r + (u16) colors[ 1 ].r) / 2; 172 word = ((u16) colors[ 0 ].r + (u16) colors[ 1 ].r) / 2;
173 colors[ 2 ].r = (u8) word; 173 colors[ 2 ].r = (u8) word;
174 word = ((u16) colors[ 0 ].g + (u16) colors[ 1 ].g) / 2; 174 word = ((u16) colors[ 0 ].g + (u16) colors[ 1 ].g) / 2;
175 colors[ 2 ].g = (u8) word; 175 colors[ 2 ].g = (u8) word;
176 word = ((u16) colors[ 0 ].b + (u16) colors[ 1 ].b) / 2; 176 word = ((u16) colors[ 0 ].b + (u16) colors[ 1 ].b) / 2;
177 colors[ 2 ].b = (u8) word; 177 colors[ 2 ].b = (u8) word;
178 colors[ 2 ].a = 0xff; 178 colors[ 2 ].a = 0xff;
179 179
180 /* random color to indicate alpha */ 180 /* random color to indicate alpha */
181 colors[ 3 ].r = 0x00; 181 colors[ 3 ].r = 0x00;
182 colors[ 3 ].g = 0xff; 182 colors[ 3 ].g = 0xff;
183 colors[ 3 ].b = 0xff; 183 colors[ 3 ].b = 0xff;
184 colors[ 3 ].a = 0x00; 184 colors[ 3 ].a = 0x00;
185 } 185 }
186} 186}
187 187
188 188
189/* 189/*
190DDSDecodeColorBlock() 190DDSDecodeColorBlock()
191decodes a dds color block 191decodes a dds color block
192fixme: make endian-safe 192fixme: make endian-safe
193*/ 193*/
194 194
195void DDSDecodeColorBlock( u32 *pixel, ddsColorBlock *block, s32 width, u32 colors[ 4 ] ) 195void DDSDecodeColorBlock( u32 *pixel, ddsColorBlock *block, s32 width, u32 colors[ 4 ] )
196{ 196{
197 s32 r, n; 197 s32 r, n;
198 u32 bits; 198 u32 bits;
199 u32 masks[] = { 3, 12, 3 << 4, 3 << 6 }; /* bit masks = 00000011, 00001100, 00110000, 11000000 */ 199 u32 masks[] = { 3, 12, 3 << 4, 3 << 6 }; /* bit masks = 00000011, 00001100, 00110000, 11000000 */
200 s32 shift[] = { 0, 2, 4, 6 }; 200 s32 shift[] = { 0, 2, 4, 6 };
201 201
202 202
203 /* r steps through lines in y */ 203 /* r steps through lines in y */
204 for( r = 0; r < 4; r++, pixel += (width - 4) ) /* no width * 4 as u32 ptr inc will * 4 */ 204 for( r = 0; r < 4; r++, pixel += (width - 4) ) /* no width * 4 as u32 ptr inc will * 4 */
205 { 205 {
206 /* width * 4 bytes per pixel per line, each j dxtc row is 4 lines of pixels */ 206 /* width * 4 bytes per pixel per line, each j dxtc row is 4 lines of pixels */
207 207
208 /* n steps through pixels */ 208 /* n steps through pixels */
209 for( n = 0; n < 4; n++ ) 209 for( n = 0; n < 4; n++ )
210 { 210 {
211 bits = block->row[ r ] & masks[ n ]; 211 bits = block->row[ r ] & masks[ n ];
212 bits >>= shift[ n ]; 212 bits >>= shift[ n ];
213 213
214 switch( bits ) 214 switch( bits )
215 { 215 {
216 case 0: 216 case 0:
217 *pixel = colors[ 0 ]; 217 *pixel = colors[ 0 ];
218 pixel++; 218 pixel++;
219 break; 219 break;
220 220
221 case 1: 221 case 1:
222 *pixel = colors[ 1 ]; 222 *pixel = colors[ 1 ];
223 pixel++; 223 pixel++;
224 break; 224 break;
225 225
226 case 2: 226 case 2:
227 *pixel = colors[ 2 ]; 227 *pixel = colors[ 2 ];
228 pixel++; 228 pixel++;
229 break; 229 break;
230 230
231 case 3: 231 case 3:
232 *pixel = colors[ 3 ]; 232 *pixel = colors[ 3 ];
233 pixel++; 233 pixel++;
234 break; 234 break;
235 235
236 default: 236 default:
237 /* invalid */ 237 /* invalid */
238 pixel++; 238 pixel++;
239 break; 239 break;
240 } 240 }
241 } 241 }
242 } 242 }
243} 243}
244 244
245 245
246/* 246/*
247DDSDecodeAlphaExplicit() 247DDSDecodeAlphaExplicit()
248decodes a dds explicit alpha block 248decodes a dds explicit alpha block
249*/ 249*/
250void DDSDecodeAlphaExplicit( u32 *pixel, ddsAlphaBlockExplicit *alphaBlock, s32 width, u32 alphaZero ) 250void DDSDecodeAlphaExplicit( u32 *pixel, ddsAlphaBlockExplicit *alphaBlock, s32 width, u32 alphaZero )
251{ 251{
252 s32 row, pix; 252 s32 row, pix;
253 u16 word; 253 u16 word;
254 ddsColor color; 254 ddsColor color;
255 255
256 256
257 /* clear color */ 257 /* clear color */
258 color.r = 0; 258 color.r = 0;
259 color.g = 0; 259 color.g = 0;
260 color.b = 0; 260 color.b = 0;
261 261
262 /* walk rows */ 262 /* walk rows */
263 for( row = 0; row < 4; row++, pixel += (width - 4) ) 263 for( row = 0; row < 4; row++, pixel += (width - 4) )
264 { 264 {
265 word = DDSLittleShort( alphaBlock->row[ row ] ); 265 word = DDSLittleShort( alphaBlock->row[ row ] );
266 266
267 /* walk pixels */ 267 /* walk pixels */
268 for( pix = 0; pix < 4; pix++ ) 268 for( pix = 0; pix < 4; pix++ )
269 { 269 {
270 /* zero the alpha bits of image pixel */ 270 /* zero the alpha bits of image pixel */
271 *pixel &= alphaZero; 271 *pixel &= alphaZero;
272 color.a = word & 0x000F; 272 color.a = word & 0x000F;
273 color.a = color.a | (color.a << 4); 273 color.a = color.a | (color.a << 4);
274 *pixel |= *((u32*) &color); 274 *pixel |= *((u32*) &color);
275 word >>= 4; /* move next bits to lowest 4 */ 275 word >>= 4; /* move next bits to lowest 4 */
276 pixel++; /* move to next pixel in the row */ 276 pixel++; /* move to next pixel in the row */
277 } 277 }
278 } 278 }
279} 279}
280 280
281 281
282 282
283/* 283/*
284DDSDecodeAlpha3BitLinear() 284DDSDecodeAlpha3BitLinear()
285decodes interpolated alpha block 285decodes interpolated alpha block
286*/ 286*/
287void DDSDecodeAlpha3BitLinear( u32 *pixel, ddsAlphaBlock3BitLinear *alphaBlock, s32 width, u32 alphaZero ) 287void DDSDecodeAlpha3BitLinear( u32 *pixel, ddsAlphaBlock3BitLinear *alphaBlock, s32 width, u32 alphaZero )
288{ 288{
289 289
290 s32 row, pix; 290 s32 row, pix;
291 u32 stuff; 291 u32 stuff;
292 u8 bits[ 4 ][ 4 ]; 292 u8 bits[ 4 ][ 4 ];
293 u16 alphas[ 8 ]; 293 u16 alphas[ 8 ];
294 ddsColor aColors[ 4 ][ 4 ]; 294 ddsColor aColors[ 4 ][ 4 ];
295 295
296 /* get initial alphas */ 296 /* get initial alphas */
297 alphas[ 0 ] = alphaBlock->alpha0; 297 alphas[ 0 ] = alphaBlock->alpha0;
298 alphas[ 1 ] = alphaBlock->alpha1; 298 alphas[ 1 ] = alphaBlock->alpha1;
299 299
300 /* 8-alpha block */ 300 /* 8-alpha block */
301 if( alphas[ 0 ] > alphas[ 1 ] ) 301 if( alphas[ 0 ] > alphas[ 1 ] )
302 { 302 {
303 /* 000 = alpha_0, 001 = alpha_1, others are interpolated */ 303 /* 000 = alpha_0, 001 = alpha_1, others are interpolated */
304 alphas[ 2 ] = ( 6 * alphas[ 0 ] + alphas[ 1 ]) / 7; /* bit code 010 */ 304 alphas[ 2 ] = ( 6 * alphas[ 0 ] + alphas[ 1 ]) / 7; /* bit code 010 */
305 alphas[ 3 ] = ( 5 * alphas[ 0 ] + 2 * alphas[ 1 ]) / 7; /* bit code 011 */ 305 alphas[ 3 ] = ( 5 * alphas[ 0 ] + 2 * alphas[ 1 ]) / 7; /* bit code 011 */
306 alphas[ 4 ] = ( 4 * alphas[ 0 ] + 3 * alphas[ 1 ]) / 7; /* bit code 100 */ 306 alphas[ 4 ] = ( 4 * alphas[ 0 ] + 3 * alphas[ 1 ]) / 7; /* bit code 100 */
307 alphas[ 5 ] = ( 3 * alphas[ 0 ] + 4 * alphas[ 1 ]) / 7; /* bit code 101 */ 307 alphas[ 5 ] = ( 3 * alphas[ 0 ] + 4 * alphas[ 1 ]) / 7; /* bit code 101 */
308 alphas[ 6 ] = ( 2 * alphas[ 0 ] + 5 * alphas[ 1 ]) / 7; /* bit code 110 */ 308 alphas[ 6 ] = ( 2 * alphas[ 0 ] + 5 * alphas[ 1 ]) / 7; /* bit code 110 */
309 alphas[ 7 ] = ( alphas[ 0 ] + 6 * alphas[ 1 ]) / 7; /* bit code 111 */ 309 alphas[ 7 ] = ( alphas[ 0 ] + 6 * alphas[ 1 ]) / 7; /* bit code 111 */
310 } 310 }
311 311
312 /* 6-alpha block */ 312 /* 6-alpha block */
313 else 313 else
314 { 314 {
315 /* 000 = alpha_0, 001 = alpha_1, others are interpolated */ 315 /* 000 = alpha_0, 001 = alpha_1, others are interpolated */
316 alphas[ 2 ] = (4 * alphas[ 0 ] + alphas[ 1 ]) / 5; /* bit code 010 */ 316 alphas[ 2 ] = (4 * alphas[ 0 ] + alphas[ 1 ]) / 5; /* bit code 010 */
317 alphas[ 3 ] = (3 * alphas[ 0 ] + 2 * alphas[ 1 ]) / 5; /* bit code 011 */ 317 alphas[ 3 ] = (3 * alphas[ 0 ] + 2 * alphas[ 1 ]) / 5; /* bit code 011 */
318 alphas[ 4 ] = (2 * alphas[ 0 ] + 3 * alphas[ 1 ]) / 5; /* bit code 100 */ 318 alphas[ 4 ] = (2 * alphas[ 0 ] + 3 * alphas[ 1 ]) / 5; /* bit code 100 */
319 alphas[ 5 ] = ( alphas[ 0 ] + 4 * alphas[ 1 ]) / 5; /* bit code 101 */ 319 alphas[ 5 ] = ( alphas[ 0 ] + 4 * alphas[ 1 ]) / 5; /* bit code 101 */
320 alphas[ 6 ] = 0; /* bit code 110 */ 320 alphas[ 6 ] = 0; /* bit code 110 */
321 alphas[ 7 ] = 255; /* bit code 111 */ 321 alphas[ 7 ] = 255; /* bit code 111 */
322 } 322 }
323 323
324 /* decode 3-bit fields into array of 16 bytes with same value */ 324 /* decode 3-bit fields into array of 16 bytes with same value */
325 325
326 /* first two rows of 4 pixels each */ 326 /* first two rows of 4 pixels each */
327 stuff = *((u32*) &(alphaBlock->stuff[ 0 ])); 327 stuff = *((u32*) &(alphaBlock->stuff[ 0 ]));
328 328
329 bits[ 0 ][ 0 ] = (u8) (stuff & 0x00000007); 329 bits[ 0 ][ 0 ] = (u8) (stuff & 0x00000007);
330 stuff >>= 3; 330 stuff >>= 3;
331 bits[ 0 ][ 1 ] = (u8) (stuff & 0x00000007); 331 bits[ 0 ][ 1 ] = (u8) (stuff & 0x00000007);
332 stuff >>= 3; 332 stuff >>= 3;
333 bits[ 0 ][ 2 ] = (u8) (stuff & 0x00000007); 333 bits[ 0 ][ 2 ] = (u8) (stuff & 0x00000007);
334 stuff >>= 3; 334 stuff >>= 3;
335 bits[ 0 ][ 3 ] = (u8) (stuff & 0x00000007); 335 bits[ 0 ][ 3 ] = (u8) (stuff & 0x00000007);
336 stuff >>= 3; 336 stuff >>= 3;
337 bits[ 1 ][ 0 ] = (u8) (stuff & 0x00000007); 337 bits[ 1 ][ 0 ] = (u8) (stuff & 0x00000007);
338 stuff >>= 3; 338 stuff >>= 3;
339 bits[ 1 ][ 1 ] = (u8) (stuff & 0x00000007); 339 bits[ 1 ][ 1 ] = (u8) (stuff & 0x00000007);
340 stuff >>= 3; 340 stuff >>= 3;
341 bits[ 1 ][ 2 ] = (u8) (stuff & 0x00000007); 341 bits[ 1 ][ 2 ] = (u8) (stuff & 0x00000007);
342 stuff >>= 3; 342 stuff >>= 3;
343 bits[ 1 ][ 3 ] = (u8) (stuff & 0x00000007); 343 bits[ 1 ][ 3 ] = (u8) (stuff & 0x00000007);
344 344
345 /* last two rows */ 345 /* last two rows */
346 stuff = *((u32*) &(alphaBlock->stuff[ 3 ])); /* last 3 bytes */ 346 stuff = *((u32*) &(alphaBlock->stuff[ 3 ])); /* last 3 bytes */
347 347
348 bits[ 2 ][ 0 ] = (u8) (stuff & 0x00000007); 348 bits[ 2 ][ 0 ] = (u8) (stuff & 0x00000007);
349 stuff >>= 3; 349 stuff >>= 3;
350 bits[ 2 ][ 1 ] = (u8) (stuff & 0x00000007); 350 bits[ 2 ][ 1 ] = (u8) (stuff & 0x00000007);
351 stuff >>= 3; 351 stuff >>= 3;
352 bits[ 2 ][ 2 ] = (u8) (stuff & 0x00000007); 352 bits[ 2 ][ 2 ] = (u8) (stuff & 0x00000007);
353 stuff >>= 3; 353 stuff >>= 3;
354 bits[ 2 ][ 3 ] = (u8) (stuff & 0x00000007); 354 bits[ 2 ][ 3 ] = (u8) (stuff & 0x00000007);
355 stuff >>= 3; 355 stuff >>= 3;
356 bits[ 3 ][ 0 ] = (u8) (stuff & 0x00000007); 356 bits[ 3 ][ 0 ] = (u8) (stuff & 0x00000007);
357 stuff >>= 3; 357 stuff >>= 3;
358 bits[ 3 ][ 1 ] = (u8) (stuff & 0x00000007); 358 bits[ 3 ][ 1 ] = (u8) (stuff & 0x00000007);
359 stuff >>= 3; 359 stuff >>= 3;
360 bits[ 3 ][ 2 ] = (u8) (stuff & 0x00000007); 360 bits[ 3 ][ 2 ] = (u8) (stuff & 0x00000007);
361 stuff >>= 3; 361 stuff >>= 3;
362 bits[ 3 ][ 3 ] = (u8) (stuff & 0x00000007); 362 bits[ 3 ][ 3 ] = (u8) (stuff & 0x00000007);
363 363
364 /* decode the codes into alpha values */ 364 /* decode the codes into alpha values */
365 for( row = 0; row < 4; row++ ) 365 for( row = 0; row < 4; row++ )
366 { 366 {
367 for( pix=0; pix < 4; pix++ ) 367 for( pix=0; pix < 4; pix++ )
368 { 368 {
369 aColors[ row ][ pix ].r = 0; 369 aColors[ row ][ pix ].r = 0;
370 aColors[ row ][ pix ].g = 0; 370 aColors[ row ][ pix ].g = 0;
371 aColors[ row ][ pix ].b = 0; 371 aColors[ row ][ pix ].b = 0;
372 aColors[ row ][ pix ].a = (u8) alphas[ bits[ row ][ pix ] ]; 372 aColors[ row ][ pix ].a = (u8) alphas[ bits[ row ][ pix ] ];
373 } 373 }
374 } 374 }
375 375
376 /* write out alpha values to the image bits */ 376 /* write out alpha values to the image bits */
377 for( row = 0; row < 4; row++, pixel += width-4 ) 377 for( row = 0; row < 4; row++, pixel += width-4 )
378 { 378 {
379 for( pix = 0; pix < 4; pix++ ) 379 for( pix = 0; pix < 4; pix++ )
380 { 380 {
381 /* zero the alpha bits of image pixel */ 381 /* zero the alpha bits of image pixel */
382 *pixel &= alphaZero; 382 *pixel &= alphaZero;
383 383
384 /* or the bits into the prev. nulled alpha */ 384 /* or the bits into the prev. nulled alpha */
385 *pixel |= *((u32*) &(aColors[ row ][ pix ])); 385 *pixel |= *((u32*) &(aColors[ row ][ pix ]));
386 pixel++; 386 pixel++;
387 } 387 }
388 } 388 }
389} 389}
390 390
391 391
392/* 392/*
393DDSDecompressDXT1() 393DDSDecompressDXT1()
394decompresses a dxt1 format texture 394decompresses a dxt1 format texture
395*/ 395*/
396s32 DDSDecompressDXT1( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) 396s32 DDSDecompressDXT1( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
397{ 397{
398 s32 x, y, xBlocks, yBlocks; 398 s32 x, y, xBlocks, yBlocks;
399 u32 *pixel; 399 u32 *pixel;
400 ddsColorBlock *block; 400 ddsColorBlock *block;
401 ddsColor colors[ 4 ]; 401 ddsColor colors[ 4 ];
402 402
403 /* setup */ 403 /* setup */
404 xBlocks = width / 4; 404 xBlocks = width / 4;
405 yBlocks = height / 4; 405 yBlocks = height / 4;
406 406
407 /* walk y */ 407 /* walk y */
408 for( y = 0; y < yBlocks; y++ ) 408 for( y = 0; y < yBlocks; y++ )
409 { 409 {
410 /* 8 bytes per block */ 410 /* 8 bytes per block */
411 block = (ddsColorBlock*) (dds->data + y * xBlocks * 8); 411 block = (ddsColorBlock*) (dds->data + y * xBlocks * 8);
412 412
413 /* walk x */ 413 /* walk x */
414 for( x = 0; x < xBlocks; x++, block++ ) 414 for( x = 0; x < xBlocks; x++, block++ )
415 { 415 {
416 DDSGetColorBlockColors( block, colors ); 416 DDSGetColorBlockColors( block, colors );
417 pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4); 417 pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4);
418 DDSDecodeColorBlock( pixel, block, width, (u32*) colors ); 418 DDSDecodeColorBlock( pixel, block, width, (u32*) colors );
419 } 419 }
420 } 420 }
421 421
422 /* return ok */ 422 /* return ok */
423 return 0; 423 return 0;
424} 424}
425 425
426 426
427/* 427/*
428DDSDecompressDXT3() 428DDSDecompressDXT3()
429decompresses a dxt3 format texture 429decompresses a dxt3 format texture
430*/ 430*/
431 431
432s32 DDSDecompressDXT3( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) 432s32 DDSDecompressDXT3( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
433{ 433{
434 s32 x, y, xBlocks, yBlocks; 434 s32 x, y, xBlocks, yBlocks;
435 u32 *pixel, alphaZero; 435 u32 *pixel, alphaZero;
436 ddsColorBlock *block; 436 ddsColorBlock *block;
437 ddsAlphaBlockExplicit *alphaBlock; 437 ddsAlphaBlockExplicit *alphaBlock;
438 ddsColor colors[ 4 ]; 438 ddsColor colors[ 4 ];
439 439
440 /* setup */ 440 /* setup */
441 xBlocks = width / 4; 441 xBlocks = width / 4;
442 yBlocks = height / 4; 442 yBlocks = height / 4;
443 443
444 /* create zero alpha */ 444 /* create zero alpha */
445 colors[ 0 ].a = 0; 445 colors[ 0 ].a = 0;
446 colors[ 0 ].r = 0xFF; 446 colors[ 0 ].r = 0xFF;
447 colors[ 0 ].g = 0xFF; 447 colors[ 0 ].g = 0xFF;
448 colors[ 0 ].b = 0xFF; 448 colors[ 0 ].b = 0xFF;
449 alphaZero = *((u32*) &colors[ 0 ]); 449 alphaZero = *((u32*) &colors[ 0 ]);
450 450
451 /* walk y */ 451 /* walk y */
452 for( y = 0; y < yBlocks; y++ ) 452 for( y = 0; y < yBlocks; y++ )
453 { 453 {
454 /* 8 bytes per block, 1 block for alpha, 1 block for color */ 454 /* 8 bytes per block, 1 block for alpha, 1 block for color */
455 block = (ddsColorBlock*) (dds->data + y * xBlocks * 16); 455 block = (ddsColorBlock*) (dds->data + y * xBlocks * 16);
456 456
457 /* walk x */ 457 /* walk x */
458 for( x = 0; x < xBlocks; x++, block++ ) 458 for( x = 0; x < xBlocks; x++, block++ )
459 { 459 {
460 /* get alpha block */ 460 /* get alpha block */
461 alphaBlock = (ddsAlphaBlockExplicit*) block; 461 alphaBlock = (ddsAlphaBlockExplicit*) block;
462 462
463 /* get color block */ 463 /* get color block */
464 block++; 464 block++;
465 DDSGetColorBlockColors( block, colors ); 465 DDSGetColorBlockColors( block, colors );
466 466
467 /* decode color block */ 467 /* decode color block */
468 pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4); 468 pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4);
469 DDSDecodeColorBlock( pixel, block, width, (u32*) colors ); 469 DDSDecodeColorBlock( pixel, block, width, (u32*) colors );
470 470
471 /* overwrite alpha bits with alpha block */ 471 /* overwrite alpha bits with alpha block */
472 DDSDecodeAlphaExplicit( pixel, alphaBlock, width, alphaZero ); 472 DDSDecodeAlphaExplicit( pixel, alphaBlock, width, alphaZero );
473 } 473 }
474 } 474 }
475 475
476 /* return ok */ 476 /* return ok */
477 return 0; 477 return 0;
478} 478}
479 479
480 480
481/* 481/*
482DDSDecompressDXT5() 482DDSDecompressDXT5()
483decompresses a dxt5 format texture 483decompresses a dxt5 format texture
484*/ 484*/
485s32 DDSDecompressDXT5( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) 485s32 DDSDecompressDXT5( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
486{ 486{
487 s32 x, y, xBlocks, yBlocks; 487 s32 x, y, xBlocks, yBlocks;
488 u32 *pixel, alphaZero; 488 u32 *pixel, alphaZero;
489 ddsColorBlock *block; 489 ddsColorBlock *block;
490 ddsAlphaBlock3BitLinear *alphaBlock; 490 ddsAlphaBlock3BitLinear *alphaBlock;
491 ddsColor colors[ 4 ]; 491 ddsColor colors[ 4 ];
492 492
493 /* setup */ 493 /* setup */
494 xBlocks = width / 4; 494 xBlocks = width / 4;
495 yBlocks = height / 4; 495 yBlocks = height / 4;
496 496
497 /* create zero alpha */ 497 /* create zero alpha */
498 colors[ 0 ].a = 0; 498 colors[ 0 ].a = 0;
499 colors[ 0 ].r = 0xFF; 499 colors[ 0 ].r = 0xFF;
500 colors[ 0 ].g = 0xFF; 500 colors[ 0 ].g = 0xFF;
501 colors[ 0 ].b = 0xFF; 501 colors[ 0 ].b = 0xFF;
502 alphaZero = *((u32*) &colors[ 0 ]); 502 alphaZero = *((u32*) &colors[ 0 ]);
503 503
504 /* walk y */ 504 /* walk y */
505 for( y = 0; y < yBlocks; y++ ) 505 for( y = 0; y < yBlocks; y++ )
506 { 506 {
507 /* 8 bytes per block, 1 block for alpha, 1 block for color */ 507 /* 8 bytes per block, 1 block for alpha, 1 block for color */
508 block = (ddsColorBlock*) (dds->data + y * xBlocks * 16); 508 block = (ddsColorBlock*) (dds->data + y * xBlocks * 16);
509 509
510 /* walk x */ 510 /* walk x */
511 for( x = 0; x < xBlocks; x++, block++ ) 511 for( x = 0; x < xBlocks; x++, block++ )
512 { 512 {
513 /* get alpha block */ 513 /* get alpha block */
514 alphaBlock = (ddsAlphaBlock3BitLinear*) block; 514 alphaBlock = (ddsAlphaBlock3BitLinear*) block;
515 515
516 /* get color block */ 516 /* get color block */
517 block++; 517 block++;
518 DDSGetColorBlockColors( block, colors ); 518 DDSGetColorBlockColors( block, colors );
519 519
520 /* decode color block */ 520 /* decode color block */
521 pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4); 521 pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4);
522 DDSDecodeColorBlock( pixel, block, width, (u32*) colors ); 522 DDSDecodeColorBlock( pixel, block, width, (u32*) colors );
523 523
524 /* overwrite alpha bits with alpha block */ 524 /* overwrite alpha bits with alpha block */
525 DDSDecodeAlpha3BitLinear( pixel, alphaBlock, width, alphaZero ); 525 DDSDecodeAlpha3BitLinear( pixel, alphaBlock, width, alphaZero );
526 } 526 }
527 } 527 }
528 528
529 /* return ok */ 529 /* return ok */
530 return 0; 530 return 0;
531} 531}
532 532
533 533
534/* 534/*
535DDSDecompressDXT2() 535DDSDecompressDXT2()
536decompresses a dxt2 format texture (fixme: un-premultiply alpha) 536decompresses a dxt2 format texture (fixme: un-premultiply alpha)
537*/ 537*/
538s32 DDSDecompressDXT2( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) 538s32 DDSDecompressDXT2( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
539{ 539{
540 /* decompress dxt3 first */ 540 /* decompress dxt3 first */
541 const s32 r = DDSDecompressDXT3( dds, width, height, pixels ); 541 const s32 r = DDSDecompressDXT3( dds, width, height, pixels );
542 542
543 /* return to sender */ 543 /* return to sender */
544 return r; 544 return r;
545} 545}
546 546
547 547
548/* 548/*
549DDSDecompressDXT4() 549DDSDecompressDXT4()
550decompresses a dxt4 format texture (fixme: un-premultiply alpha) 550decompresses a dxt4 format texture (fixme: un-premultiply alpha)
551*/ 551*/
552s32 DDSDecompressDXT4( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) 552s32 DDSDecompressDXT4( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
553{ 553{
554 /* decompress dxt5 first */ 554 /* decompress dxt5 first */
555 const s32 r = DDSDecompressDXT5( dds, width, height, pixels ); 555 const s32 r = DDSDecompressDXT5( dds, width, height, pixels );
556 556
557 /* return to sender */ 557 /* return to sender */
558 return r; 558 return r;
559} 559}
560 560
561 561
562/* 562/*
563DDSDecompressARGB8888() 563DDSDecompressARGB8888()
564decompresses an argb 8888 format texture 564decompresses an argb 8888 format texture
565*/ 565*/
566s32 DDSDecompressARGB8888( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) 566s32 DDSDecompressARGB8888( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
567{ 567{
568 /* setup */ 568 /* setup */
569 u8* in = dds->data; 569 u8* in = dds->data;
570 u8* out = pixels; 570 u8* out = pixels;
571 571
572 /* walk y */ 572 /* walk y */
573 for(s32 y = 0; y < height; y++) 573 for(s32 y = 0; y < height; y++)
574 { 574 {
575 /* walk x */ 575 /* walk x */
576 for(s32 x = 0; x < width; x++) 576 for(s32 x = 0; x < width; x++)
577 { 577 {
578 *out++ = *in++; 578 *out++ = *in++;
579 *out++ = *in++; 579 *out++ = *in++;
580 *out++ = *in++; 580 *out++ = *in++;
581 *out++ = *in++; 581 *out++ = *in++;
582 } 582 }
583 } 583 }
584 584
585 /* return ok */ 585 /* return ok */
586 return 0; 586 return 0;
587} 587}
588 588
589 589
590/* 590/*
591DDSDecompress() 591DDSDecompress()
592decompresses a dds texture into an rgba image buffer, returns 0 on success 592decompresses a dds texture into an rgba image buffer, returns 0 on success
593*/ 593*/
594s32 DDSDecompress( ddsBuffer *dds, u8 *pixels ) 594s32 DDSDecompress( ddsBuffer *dds, u8 *pixels )
595{ 595{
596 s32 width, height; 596 s32 width, height;
597 eDDSPixelFormat pf; 597 eDDSPixelFormat pf;
598 598
599 /* get dds info */ 599 /* get dds info */
600 s32 r = DDSGetInfo( dds, &width, &height, &pf ); 600 s32 r = DDSGetInfo( dds, &width, &height, &pf );
601 if ( r ) 601 if ( r )
602 return r; 602 return r;
603 603
604 /* decompress */ 604 /* decompress */
605 switch( pf ) 605 switch( pf )
606 { 606 {
607 case DDS_PF_ARGB8888: 607 case DDS_PF_ARGB8888:
608 /* fixme: support other [a]rgb formats */ 608 /* fixme: support other [a]rgb formats */
609 r = DDSDecompressARGB8888( dds, width, height, pixels ); 609 r = DDSDecompressARGB8888( dds, width, height, pixels );
610 break; 610 break;
611 611
612 case DDS_PF_DXT1: 612 case DDS_PF_DXT1:
613 r = DDSDecompressDXT1( dds, width, height, pixels ); 613 r = DDSDecompressDXT1( dds, width, height, pixels );
614 break; 614 break;
615 615
616 case DDS_PF_DXT2: 616 case DDS_PF_DXT2:
617 r = DDSDecompressDXT2( dds, width, height, pixels ); 617 r = DDSDecompressDXT2( dds, width, height, pixels );
618 break; 618 break;
619 619
620 case DDS_PF_DXT3: 620 case DDS_PF_DXT3:
621 r = DDSDecompressDXT3( dds, width, height, pixels ); 621 r = DDSDecompressDXT3( dds, width, height, pixels );
622 break; 622 break;
623 623
624 case DDS_PF_DXT4: 624 case DDS_PF_DXT4:
625 r = DDSDecompressDXT4( dds, width, height, pixels ); 625 r = DDSDecompressDXT4( dds, width, height, pixels );
626 break; 626 break;
627 627
628 case DDS_PF_DXT5: 628 case DDS_PF_DXT5:
629 r = DDSDecompressDXT5( dds, width, height, pixels ); 629 r = DDSDecompressDXT5( dds, width, height, pixels );
630 break; 630 break;
631 631
632 default: 632 default:
633 case DDS_PF_UNKNOWN: 633 case DDS_PF_UNKNOWN:
634 memset( pixels, 0xFF, width * height * 4 ); 634 memset( pixels, 0xFF, width * height * 4 );
635 r = -1; 635 r = -1;
636 break; 636 break;
637 } 637 }
638 638
639 /* return to sender */ 639 /* return to sender */
640 return r; 640 return r;
641} 641}
642 642
643} // end anonymous namespace 643} // end anonymous namespace
644 644
645 645
646//! returns true if the file maybe is able to be loaded by this class 646//! returns true if the file maybe is able to be loaded by this class
647//! based on the file extension (e.g. ".tga") 647//! based on the file extension (e.g. ".tga")
648bool CImageLoaderDDS::isALoadableFileExtension(const io::path& filename) const 648bool CImageLoaderDDS::isALoadableFileExtension(const io::path& filename) const
649{ 649{
650 return core::hasFileExtension ( filename, "dds" ); 650 return core::hasFileExtension ( filename, "dds" );
651} 651}
652 652
653 653
654//! returns true if the file maybe is able to be loaded by this class 654//! returns true if the file maybe is able to be loaded by this class
655bool CImageLoaderDDS::isALoadableFileFormat(io::IReadFile* file) const 655bool CImageLoaderDDS::isALoadableFileFormat(io::IReadFile* file) const
656{ 656{
657 if (!file) 657 if (!file)
658 return false; 658 return false;
659 659
660 ddsBuffer header; 660 ddsBuffer header;
661 file->read(&header, sizeof(header)); 661 file->read(&header, sizeof(header));
662 662
663 s32 width, height; 663 s32 width, height;
664 eDDSPixelFormat pixelFormat; 664 eDDSPixelFormat pixelFormat;
665 665
666 return (0 == DDSGetInfo( &header, &width, &height, &pixelFormat)); 666 return (0 == DDSGetInfo( &header, &width, &height, &pixelFormat));
667} 667}
668 668
669 669
670//! creates a surface from the file 670//! creates a surface from the file
671IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const 671IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const
672{ 672{
673 u8 *memFile = new u8 [ file->getSize() ]; 673 u8 *memFile = new u8 [ file->getSize() ];
674 file->read ( memFile, file->getSize() ); 674 file->read ( memFile, file->getSize() );
675 675
676 ddsBuffer *header = (ddsBuffer*) memFile; 676 ddsBuffer *header = (ddsBuffer*) memFile;
677 IImage* image = 0; 677 IImage* image = 0;
678 s32 width, height; 678 s32 width, height;
679 eDDSPixelFormat pixelFormat; 679 eDDSPixelFormat pixelFormat;
680 680
681 if ( 0 == DDSGetInfo( header, &width, &height, &pixelFormat) ) 681 if ( 0 == DDSGetInfo( header, &width, &height, &pixelFormat) )
682 { 682 {
683 image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height)); 683 image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));
684 684
685 if ( DDSDecompress( header, (u8*) image->lock() ) == -1) 685 if ( DDSDecompress( header, (u8*) image->lock() ) == -1)
686 { 686 {
687 image->unlock(); 687 image->unlock();
688 image->drop(); 688 image->drop();
689 image = 0; 689 image = 0;
690 } 690 }
691 } 691 }
692 692
693 delete [] memFile; 693 delete [] memFile;
694 if ( image ) 694 if ( image )
695 image->unlock(); 695 image->unlock();
696 696
697 return image; 697 return image;
698} 698}
699 699
700 700
701//! creates a loader which is able to load dds images 701//! creates a loader which is able to load dds images
702IImageLoader* createImageLoaderDDS() 702IImageLoader* createImageLoaderDDS()
703{ 703{
704 return new CImageLoaderDDS(); 704 return new CImageLoaderDDS();
705} 705}
706 706
707 707
708} // end namespace video 708} // end namespace video
709} // end namespace irr 709} // end namespace irr
710 710
711#endif 711#endif
712 712