stbi_DDS_aug_c.h 15 KB

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