Subversion Repositories gelsvn

Rev

Rev 373 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
594 jab 1
/**
2
 * @file stbi_DDS_aug_c.h
3
 * @brief DDS file support
4
 */
369 jab 5
 
6
///	DDS file support, does decoding, _not_ direct uploading
7
///	(use SOIL for that ;-)
8
 
9
///	A bunch of DirectDraw Surface structures and flags
10
typedef struct {
11
    unsigned int    dwMagic;
12
    unsigned int    dwSize;
13
    unsigned int    dwFlags;
14
    unsigned int    dwHeight;
15
    unsigned int    dwWidth;
16
    unsigned int    dwPitchOrLinearSize;
17
    unsigned int    dwDepth;
18
    unsigned int    dwMipMapCount;
19
    unsigned int    dwReserved1[ 11 ];
20
 
21
    //  DDPIXELFORMAT
22
    struct {
23
      unsigned int    dwSize;
24
      unsigned int    dwFlags;
25
      unsigned int    dwFourCC;
26
      unsigned int    dwRGBBitCount;
27
      unsigned int    dwRBitMask;
28
      unsigned int    dwGBitMask;
29
      unsigned int    dwBBitMask;
30
      unsigned int    dwAlphaBitMask;
31
    }               sPixelFormat;
32
 
33
    //  DDCAPS2
34
    struct {
35
      unsigned int    dwCaps1;
36
      unsigned int    dwCaps2;
37
      unsigned int    dwDDSX;
38
      unsigned int    dwReserved;
39
    }               sCaps;
40
    unsigned int    dwReserved2;
41
} DDS_header ;
42
 
43
//	the following constants were copied directly off the MSDN website
44
 
45
//	The dwFlags member of the original DDSURFACEDESC2 structure
46
//	can be set to one or more of the following values.
47
#define DDSD_CAPS	0x00000001
48
#define DDSD_HEIGHT	0x00000002
49
#define DDSD_WIDTH	0x00000004
50
#define DDSD_PITCH	0x00000008
51
#define DDSD_PIXELFORMAT	0x00001000
52
#define DDSD_MIPMAPCOUNT	0x00020000
53
#define DDSD_LINEARSIZE	0x00080000
54
#define DDSD_DEPTH	0x00800000
55
 
56
//	DirectDraw Pixel Format
57
#define DDPF_ALPHAPIXELS	0x00000001
58
#define DDPF_FOURCC	0x00000004
59
#define DDPF_RGB	0x00000040
60
 
61
//	The dwCaps1 member of the DDSCAPS2 structure can be
62
//	set to one or more of the following values.
63
#define DDSCAPS_COMPLEX	0x00000008
64
#define DDSCAPS_TEXTURE	0x00001000
65
#define DDSCAPS_MIPMAP	0x00400000
66
 
67
//	The dwCaps2 member of the DDSCAPS2 structure can be
68
//	set to one or more of the following values.
69
#define DDSCAPS2_CUBEMAP	0x00000200
70
#define DDSCAPS2_CUBEMAP_POSITIVEX	0x00000400
71
#define DDSCAPS2_CUBEMAP_NEGATIVEX	0x00000800
72
#define DDSCAPS2_CUBEMAP_POSITIVEY	0x00001000
73
#define DDSCAPS2_CUBEMAP_NEGATIVEY	0x00002000
74
#define DDSCAPS2_CUBEMAP_POSITIVEZ	0x00004000
75
#define DDSCAPS2_CUBEMAP_NEGATIVEZ	0x00008000
76
#define DDSCAPS2_VOLUME	0x00200000
77
 
78
static int dds_test(stbi *s)
79
{
80
	//	check the magic number
81
	if (get8(s) != 'D') return 0;
82
	if (get8(s) != 'D') return 0;
83
	if (get8(s) != 'S') return 0;
84
	if (get8(s) != ' ') return 0;
85
	//	check header size
86
	if (get32le(s) != 124) return 0;
87
	return 1;
88
}
89
#ifndef STBI_NO_STDIO
90
int      stbi_dds_test_file        (FILE *f)
91
{
92
   stbi s;
93
   int r,n = ftell(f);
94
   start_file(&s,f);
95
   r = dds_test(&s);
96
   fseek(f,n,SEEK_SET);
97
   return r;
98
}
99
#endif
100
 
101
int      stbi_dds_test_memory      (stbi_uc const *buffer, int len)
102
{
103
   stbi s;
104
   start_mem(&s,buffer, len);
105
   return dds_test(&s);
106
}
107
 
108
//	helper functions
109
int stbi_convert_bit_range( int c, int from_bits, int to_bits )
110
{
111
	int b = (1 << (from_bits - 1)) + c * ((1 << to_bits) - 1);
112
	return (b + (b >> from_bits)) >> from_bits;
113
}
114
void stbi_rgb_888_from_565( unsigned int c, int *r, int *g, int *b )
115
{
116
	*r = stbi_convert_bit_range( (c >> 11) & 31, 5, 8 );
117
	*g = stbi_convert_bit_range( (c >> 05) & 63, 6, 8 );
118
	*b = stbi_convert_bit_range( (c >> 00) & 31, 5, 8 );
119
}
120
void stbi_decode_DXT1_block(
121
			unsigned char uncompressed[16*4],
122
			unsigned char compressed[8] )
123
{
124
	int next_bit = 4*8;
125
	int i, r, g, b;
126
	int c0, c1;
127
	unsigned char decode_colors[4*4];
128
	//	find the 2 primary colors
129
	c0 = compressed[0] + (compressed[1] << 8);
130
	c1 = compressed[2] + (compressed[3] << 8);
131
	stbi_rgb_888_from_565( c0, &r, &g, &b );
132
	decode_colors[0] = r;
133
	decode_colors[1] = g;
134
	decode_colors[2] = b;
135
	decode_colors[3] = 255;
136
	stbi_rgb_888_from_565( c1, &r, &g, &b );
137
	decode_colors[4] = r;
138
	decode_colors[5] = g;
139
	decode_colors[6] = b;
140
	decode_colors[7] = 255;
141
	if( c0 > c1 )
142
	{
143
		//	no alpha, 2 interpolated colors
144
		decode_colors[8] = (2*decode_colors[0] + decode_colors[4]) / 3;
145
		decode_colors[9] = (2*decode_colors[1] + decode_colors[5]) / 3;
146
		decode_colors[10] = (2*decode_colors[2] + decode_colors[6]) / 3;
147
		decode_colors[11] = 255;
148
		decode_colors[12] = (decode_colors[0] + 2*decode_colors[4]) / 3;
149
		decode_colors[13] = (decode_colors[1] + 2*decode_colors[5]) / 3;
150
		decode_colors[14] = (decode_colors[2] + 2*decode_colors[6]) / 3;
151
		decode_colors[15] = 255;
152
	} else
153
	{
154
		//	1 interpolated color, alpha
155
		decode_colors[8] = (decode_colors[0] + decode_colors[4]) / 2;
156
		decode_colors[9] = (decode_colors[1] + decode_colors[5]) / 2;
157
		decode_colors[10] = (decode_colors[2] + decode_colors[6]) / 2;
158
		decode_colors[11] = 255;
159
		decode_colors[12] = 0;
160
		decode_colors[13] = 0;
161
		decode_colors[14] = 0;
162
		decode_colors[15] = 0;
163
	}
164
	//	decode the block
165
	for( i = 0; i < 16*4; i += 4 )
166
	{
167
		int idx = ((compressed[next_bit>>3] >> (next_bit & 7)) & 3) * 4;
168
		next_bit += 2;
169
		uncompressed[i+0] = decode_colors[idx+0];
170
		uncompressed[i+1] = decode_colors[idx+1];
171
		uncompressed[i+2] = decode_colors[idx+2];
172
		uncompressed[i+3] = decode_colors[idx+3];
173
	}
174
	//	done
175
}
176
void stbi_decode_DXT23_alpha_block(
177
			unsigned char uncompressed[16*4],
178
			unsigned char compressed[8] )
179
{
180
	int i, next_bit = 0;
181
	//	each alpha value gets 4 bits
182
	for( i = 3; i < 16*4; i += 4 )
183
	{
184
		uncompressed[i] = stbi_convert_bit_range(
185
				(compressed[next_bit>>3] >> (next_bit&7)) & 15,
186
				4, 8 );
187
		next_bit += 4;
188
	}
189
}
190
void stbi_decode_DXT45_alpha_block(
191
			unsigned char uncompressed[16*4],
192
			unsigned char compressed[8] )
193
{
194
	int i, next_bit = 8*2;
195
	unsigned char decode_alpha[8];
196
	//	each alpha value gets 3 bits, and the 1st 2 bytes are the range
197
	decode_alpha[0] = compressed[0];
198
	decode_alpha[1] = compressed[1];
199
	if( decode_alpha[0] > decode_alpha[1] )
200
	{
201
		//	6 step intermediate
202
		decode_alpha[2] = (6*decode_alpha[0] + 1*decode_alpha[1]) / 7;
203
		decode_alpha[3] = (5*decode_alpha[0] + 2*decode_alpha[1]) / 7;
204
		decode_alpha[4] = (4*decode_alpha[0] + 3*decode_alpha[1]) / 7;
205
		decode_alpha[5] = (3*decode_alpha[0] + 4*decode_alpha[1]) / 7;
206
		decode_alpha[6] = (2*decode_alpha[0] + 5*decode_alpha[1]) / 7;
207
		decode_alpha[7] = (1*decode_alpha[0] + 6*decode_alpha[1]) / 7;
208
	} else
209
	{
210
		//	4 step intermediate, pluss full and none
211
		decode_alpha[2] = (4*decode_alpha[0] + 1*decode_alpha[1]) / 5;
212
		decode_alpha[3] = (3*decode_alpha[0] + 2*decode_alpha[1]) / 5;
213
		decode_alpha[4] = (2*decode_alpha[0] + 3*decode_alpha[1]) / 5;
214
		decode_alpha[5] = (1*decode_alpha[0] + 4*decode_alpha[1]) / 5;
215
		decode_alpha[6] = 0;
216
		decode_alpha[7] = 255;
217
	}
218
	for( i = 3; i < 16*4; i += 4 )
219
	{
220
		int idx = 0, bit;
221
		bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
222
		idx += bit << 0;
223
		++next_bit;
224
		bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
225
		idx += bit << 1;
226
		++next_bit;
227
		bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
228
		idx += bit << 2;
229
		++next_bit;
230
		uncompressed[i] = decode_alpha[idx & 7];
231
	}
232
	//	done
233
}
234
void stbi_decode_DXT_color_block(
235
			unsigned char uncompressed[16*4],
236
			unsigned char compressed[8] )
237
{
238
	int next_bit = 4*8;
239
	int i, r, g, b;
240
	int c0, c1;
241
	unsigned char decode_colors[4*3];
242
	//	find the 2 primary colors
243
	c0 = compressed[0] + (compressed[1] << 8);
244
	c1 = compressed[2] + (compressed[3] << 8);
245
	stbi_rgb_888_from_565( c0, &r, &g, &b );
246
	decode_colors[0] = r;
247
	decode_colors[1] = g;
248
	decode_colors[2] = b;
249
	stbi_rgb_888_from_565( c1, &r, &g, &b );
250
	decode_colors[3] = r;
251
	decode_colors[4] = g;
252
	decode_colors[5] = b;
253
	//	Like DXT1, but no choicees:
254
	//	no alpha, 2 interpolated colors
255
	decode_colors[6] = (2*decode_colors[0] + decode_colors[3]) / 3;
256
	decode_colors[7] = (2*decode_colors[1] + decode_colors[4]) / 3;
257
	decode_colors[8] = (2*decode_colors[2] + decode_colors[5]) / 3;
258
	decode_colors[9] = (decode_colors[0] + 2*decode_colors[3]) / 3;
259
	decode_colors[10] = (decode_colors[1] + 2*decode_colors[4]) / 3;
260
	decode_colors[11] = (decode_colors[2] + 2*decode_colors[5]) / 3;
261
	//	decode the block
262
	for( i = 0; i < 16*4; i += 4 )
263
	{
264
		int idx = ((compressed[next_bit>>3] >> (next_bit & 7)) & 3) * 3;
265
		next_bit += 2;
266
		uncompressed[i+0] = decode_colors[idx+0];
267
		uncompressed[i+1] = decode_colors[idx+1];
268
		uncompressed[i+2] = decode_colors[idx+2];
269
	}
270
	//	done
271
}
272
static stbi_uc *dds_load(stbi *s, int *x, int *y, int *comp, int req_comp)
273
{
274
	//	all variables go up front
275
	stbi_uc *dds_data = NULL;
276
	stbi_uc block[16*4];
277
	stbi_uc compressed[8];
278
	int flags, DXT_family;
279
	int has_alpha, has_mipmap;
280
	int is_compressed, cubemap_faces;
281
	int block_pitch, num_blocks;
282
	DDS_header header;
283
	int i, sz, cf;
284
	//	load the header
285
	if( sizeof( DDS_header ) != 128 )
286
	{
287
		return NULL;
288
	}
289
	getn( s, (stbi_uc*)(&header), 128 );
290
	//	and do some checking
291
	if( header.dwMagic != (('D' << 0) | ('D' << 8) | ('S' << 16) | (' ' << 24)) ) return NULL;
292
	if( header.dwSize != 124 ) return NULL;
293
	flags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
294
	if( (header.dwFlags & flags) != flags ) return NULL;
295
	/*	According to the MSDN spec, the dwFlags should contain
296
		DDSD_LINEARSIZE if it's compressed, or DDSD_PITCH if
297
		uncompressed.  Some DDS writers do not conform to the
298
		spec, so I need to make my reader more tolerant	*/
299
	if( header.sPixelFormat.dwSize != 32 ) return NULL;
300
	flags = DDPF_FOURCC | DDPF_RGB;
301
	if( (header.sPixelFormat.dwFlags & flags) == 0 ) return NULL;
302
	if( (header.sCaps.dwCaps1 & DDSCAPS_TEXTURE) == 0 ) return NULL;
303
	//	get the image data
304
	s->img_x = header.dwWidth;
305
	s->img_y = header.dwHeight;
306
	s->img_n = 4;
307
	is_compressed = (header.sPixelFormat.dwFlags & DDPF_FOURCC) / DDPF_FOURCC;
308
	has_alpha = (header.sPixelFormat.dwFlags & DDPF_ALPHAPIXELS) / DDPF_ALPHAPIXELS;
309
	has_mipmap = (header.sCaps.dwCaps1 & DDSCAPS_MIPMAP) && (header.dwMipMapCount > 1);
310
	cubemap_faces = (header.sCaps.dwCaps2 & DDSCAPS2_CUBEMAP) / DDSCAPS2_CUBEMAP;
311
	/*	I need cubemaps to have square faces	*/
312
	cubemap_faces &= (s->img_x == s->img_y);
313
	cubemap_faces *= 5;
314
	cubemap_faces += 1;
315
	block_pitch = (s->img_x+3) >> 2;
316
	num_blocks = block_pitch * ((s->img_y+3) >> 2);
317
	/*	let the user know what's going on	*/
318
	*x = s->img_x;
319
	*y = s->img_y;
320
	*comp = s->img_n;
321
	/*	is this uncompressed?	*/
322
	if( is_compressed )
323
	{
324
		/*	compressed	*/
325
		//	note: header.sPixelFormat.dwFourCC is something like (('D'<<0)|('X'<<8)|('T'<<16)|('1'<<24))
326
		DXT_family = 1 + (header.sPixelFormat.dwFourCC >> 24) - '1';
327
		if( (DXT_family < 1) || (DXT_family > 5) ) return NULL;
328
		/*	check the expected size...oops, nevermind...
329
			those non-compliant writers leave
330
			dwPitchOrLinearSize == 0	*/
331
		//	passed all the tests, get the RAM for decoding
332
		sz = (s->img_x)*(s->img_y)*4*cubemap_faces;
333
		dds_data = (unsigned char*)malloc( sz );
334
		/*	do this once for each face	*/
335
		for( cf = 0; cf < cubemap_faces; ++ cf )
336
		{
337
			//	now read and decode all the blocks
338
			for( i = 0; i < num_blocks; ++i )
339
			{
340
				//	where are we?
341
				int bx, by, bw=4, bh=4;
342
				int ref_x = 4 * (i % block_pitch);
343
				int ref_y = 4 * (i / block_pitch);
344
				//	get the next block's worth of compressed data, and decompress it
345
				if( DXT_family == 1 )
346
				{
347
					//	DXT1
348
					getn( s, compressed, 8 );
349
					stbi_decode_DXT1_block( block, compressed );
350
				} else if( DXT_family < 4 )
351
				{
352
					//	DXT2/3
353
					getn( s, compressed, 8 );
354
					stbi_decode_DXT23_alpha_block ( block, compressed );
355
					getn( s, compressed, 8 );
356
					stbi_decode_DXT_color_block ( block, compressed );
357
				} else
358
				{
359
					//	DXT4/5
360
					getn( s, compressed, 8 );
361
					stbi_decode_DXT45_alpha_block ( block, compressed );
362
					getn( s, compressed, 8 );
363
					stbi_decode_DXT_color_block ( block, compressed );
364
				}
365
				//	is this a partial block?
373 jrf 366
				if( ref_x + 4 > (int)s->img_x )
369 jab 367
				{
368
					bw = s->img_x - ref_x;
369
				}
373 jrf 370
				if( ref_y + 4 > (int)s->img_y )
369 jab 371
				{
372
					bh = s->img_y - ref_y;
373
				}
374
				//	now drop our decompressed data into the buffer
375
				for( by = 0; by < bh; ++by )
376
				{
377
					int idx = 4*((ref_y+by+cf*s->img_x)*s->img_x + ref_x);
378
					for( bx = 0; bx < bw*4; ++bx )
379
					{
380
 
381
						dds_data[idx+bx] = block[by*16+bx];
382
					}
383
				}
384
			}
385
			/*	done reading and decoding the main image...
386
				skip MIPmaps if present	*/
387
			if( has_mipmap )
388
			{
389
				int block_size = 16;
390
				if( DXT_family == 1 )
391
				{
392
					block_size = 8;
393
				}
373 jrf 394
				for( i = 1; i < (int)header.dwMipMapCount; ++i )
369 jab 395
				{
396
					int mx = s->img_x >> (i + 2);
397
					int my = s->img_y >> (i + 2);
398
					if( mx < 1 )
399
					{
400
						mx = 1;
401
					}
402
					if( my < 1 )
403
					{
404
						my = 1;
405
					}
406
					skip( s, mx*my*block_size );
407
				}
408
			}
409
		}/* per cubemap face */
410
	} else
411
	{
412
		/*	uncompressed	*/
413
		DXT_family = 0;
414
		s->img_n = 3;
415
		if( has_alpha )
416
		{
417
			s->img_n = 4;
418
		}
419
		*comp = s->img_n;
420
		sz = s->img_x*s->img_y*s->img_n*cubemap_faces;
421
		dds_data = (unsigned char*)malloc( sz );
422
		/*	do this once for each face	*/
423
		for( cf = 0; cf < cubemap_faces; ++ cf )
424
		{
425
			/*	read the main image for this face	*/
426
			getn( s, &dds_data[cf*s->img_x*s->img_y*s->img_n], s->img_x*s->img_y*s->img_n );
427
			/*	done reading and decoding the main image...
428
				skip MIPmaps if present	*/
429
			if( has_mipmap )
430
			{
373 jrf 431
				for( i = 1; i < (int)header.dwMipMapCount; ++i )
369 jab 432
				{
433
					int mx = s->img_x >> i;
434
					int my = s->img_y >> i;
435
					if( mx < 1 )
436
					{
437
						mx = 1;
438
					}
439
					if( my < 1 )
440
					{
441
						my = 1;
442
					}
443
					skip( s, mx*my*s->img_n );
444
				}
445
			}
446
		}
447
		/*	data was BGR, I need it RGB	*/
448
		for( i = 0; i < sz; i += s->img_n )
449
		{
450
			unsigned char temp = dds_data[i];
451
			dds_data[i] = dds_data[i+2];
452
			dds_data[i+2] = temp;
453
		}
454
	}
455
	/*	finished decompressing into RGBA,
456
		adjust the y size if we have a cubemap
457
		note: sz is already up to date	*/
458
	s->img_y *= cubemap_faces;
459
	*y = s->img_y;
460
	//	did the user want something else, or
461
	//	see if all the alpha values are 255 (i.e. no transparency)
462
	has_alpha = 0;
463
	if( s->img_n == 4)
464
	{
465
		for( i = 3; (i < sz) && (has_alpha == 0); i += 4 )
466
		{
467
			has_alpha |= (dds_data[i] < 255);
468
		}
469
	}
470
	if( (req_comp <= 4) && (req_comp >= 1) )
471
	{
472
		//	user has some requirements, meet them
473
		if( req_comp != s->img_n )
474
		{
475
			dds_data = convert_format( dds_data, s->img_n, req_comp, s->img_x, s->img_y );
476
			*comp = s->img_n;
477
		}
478
	} else
479
	{
480
		//	user had no requirements, only drop to RGB is no alpha
481
		if( (has_alpha == 0) && (s->img_n == 4) )
482
		{
483
			dds_data = convert_format( dds_data, 4, 3, s->img_x, s->img_y );
484
			*comp = 3;
485
		}
486
	}
487
	//	OK, done
488
	return dds_data;
489
}
490
 
491
#ifndef STBI_NO_STDIO
492
stbi_uc *stbi_dds_load_from_file   (FILE *f,                  int *x, int *y, int *comp, int req_comp)
493
{
494
	stbi s;
495
   start_file(&s,f);
496
   return dds_load(&s,x,y,comp,req_comp);
497
}
498
 
499
stbi_uc *stbi_dds_load             (char *filename,           int *x, int *y, int *comp, int req_comp)
500
{
501
   stbi_uc *data;
502
   FILE *f = fopen(filename, "rb");
503
   if (!f) return NULL;
504
   data = stbi_dds_load_from_file(f,x,y,comp,req_comp);
505
   fclose(f);
506
   return data;
507
}
508
#endif
509
 
510
stbi_uc *stbi_dds_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
511
{
512
	stbi s;
513
   start_mem(&s,buffer, len);
514
   return dds_load(&s,x,y,comp,req_comp);
515
}