dds.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. /*
  2. * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include "bgfx_p.h"
  6. #include "dds.h"
  7. namespace bgfx
  8. {
  9. #define DDS_MAGIC BX_MAKEFOURCC('D','D','S',' ')
  10. #define DDS_HEADER_SIZE 124
  11. #define DDS_IMAGE_DATA_OFFSET (DDS_HEADER_SIZE + 4)
  12. #define DDS_DXT1 BX_MAKEFOURCC('D', 'X', 'T', '1')
  13. #define DDS_DXT2 BX_MAKEFOURCC('D', 'X', 'T', '2')
  14. #define DDS_DXT3 BX_MAKEFOURCC('D', 'X', 'T', '3')
  15. #define DDS_DXT4 BX_MAKEFOURCC('D', 'X', 'T', '4')
  16. #define DDS_DXT5 BX_MAKEFOURCC('D', 'X', 'T', '5')
  17. #define D3DFMT_A16B16G16R16F 113
  18. #define DDSD_CAPS 0x00000001
  19. #define DDSD_HEIGHT 0x00000002
  20. #define DDSD_WIDTH 0x00000004
  21. #define DDSD_PITCH 0x00000008
  22. #define DDSD_PIXELFORMAT 0x00001000
  23. #define DDSD_MIPMAPCOUNT 0x00020000
  24. #define DDSD_LINEARSIZE 0x00080000
  25. #define DDSD_DEPTH 0x00800000
  26. #define DDPF_ALPHAPIXELS 0x00000001
  27. #define DDPF_ALPHA 0x00000002
  28. #define DDPF_FOURCC 0x00000004
  29. #define DDPF_INDEXED 0x00000020
  30. #define DDPF_RGB 0x00000040
  31. #define DDPF_YUV 0x00000200
  32. #define DDPF_LUMINANCE 0x00020000
  33. #define DDSCAPS_COMPLEX 0x00000008
  34. #define DDSCAPS_TEXTURE 0x00001000
  35. #define DDSCAPS_MIPMAP 0x00400000
  36. #define DDSCAPS2_CUBEMAP 0x00000200
  37. #define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
  38. #define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
  39. #define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
  40. #define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
  41. #define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
  42. #define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
  43. #define DDS_CUBEMAP_ALLFACES (DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX \
  44. |DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY \
  45. |DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ)
  46. #define DDSCAPS2_VOLUME 0x00200000
  47. bool isDds(const Memory* _mem)
  48. {
  49. bx::MemoryReader reader(_mem->data, _mem->size);
  50. uint32_t magic;
  51. bx::read(&reader, magic);
  52. return DDS_MAGIC == magic;
  53. }
  54. uint32_t bitRangeConvert(uint32_t _in, uint32_t _from, uint32_t _to)
  55. {
  56. uint32_t tmp0 = uint32_sll(1, _to);
  57. uint32_t tmp1 = uint32_sll(1, _from);
  58. uint32_t tmp2 = uint32_dec(tmp0);
  59. uint32_t tmp3 = uint32_dec(tmp1);
  60. uint32_t tmp4 = uint32_mul(_in, tmp2);
  61. uint32_t tmp5 = uint32_add(tmp3, tmp4);
  62. uint32_t tmp6 = uint32_srl(tmp5, _from);
  63. uint32_t tmp7 = uint32_add(tmp5, tmp6);
  64. uint32_t result = uint32_srl(tmp7, _from);
  65. return result;
  66. }
  67. void decodeBlockDxt(uint8_t _dst[16*4], const uint8_t _src[8])
  68. {
  69. uint8_t colors[4*3];
  70. uint32_t c0 = _src[0] | (_src[1] << 8);
  71. colors[0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
  72. colors[1] = bitRangeConvert( (c0>> 5)&0x3f, 6, 8);
  73. colors[2] = bitRangeConvert( (c0>>11)&0x1f, 5, 8);
  74. uint32_t c1 = _src[2] | (_src[3] << 8);
  75. colors[3] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
  76. colors[4] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
  77. colors[5] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
  78. colors[6] = (2*colors[0] + colors[3]) / 3;
  79. colors[7] = (2*colors[1] + colors[4]) / 3;
  80. colors[8] = (2*colors[2] + colors[5]) / 3;
  81. colors[ 9] = (colors[0] + 2*colors[3]) / 3;
  82. colors[10] = (colors[1] + 2*colors[4]) / 3;
  83. colors[11] = (colors[2] + 2*colors[5]) / 3;
  84. for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
  85. {
  86. int idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 3;
  87. _dst[ii+0] = colors[idx+0];
  88. _dst[ii+1] = colors[idx+1];
  89. _dst[ii+2] = colors[idx+2];
  90. }
  91. }
  92. void decodeBlockDxt1(uint8_t _dst[16*4], const uint8_t _src[8])
  93. {
  94. uint8_t colors[4*4];
  95. uint32_t c0 = _src[0] | (_src[1] << 8);
  96. colors[0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
  97. colors[1] = bitRangeConvert( (c0>> 5)&0x3f, 6, 8);
  98. colors[2] = bitRangeConvert( (c0>>11)&0x1f, 5, 8);
  99. colors[3] = 255;
  100. uint32_t c1 = _src[2] | (_src[3] << 8);
  101. colors[4] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
  102. colors[5] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
  103. colors[6] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
  104. colors[7] = 255;
  105. if (c0 > c1)
  106. {
  107. colors[ 8] = (2*colors[0] + colors[4]) / 3;
  108. colors[ 9] = (2*colors[1] + colors[5]) / 3;
  109. colors[10] = (2*colors[2] + colors[6]) / 3;
  110. colors[11] = 255;
  111. colors[12] = (colors[0] + 2*colors[4]) / 3;
  112. colors[13] = (colors[1] + 2*colors[5]) / 3;
  113. colors[14] = (colors[2] + 2*colors[6]) / 3;
  114. colors[15] = 255;
  115. }
  116. else
  117. {
  118. colors[ 8] = (colors[0] + colors[4]) / 2;
  119. colors[ 9] = (colors[1] + colors[5]) / 2;
  120. colors[10] = (colors[2] + colors[6]) / 2;
  121. colors[11] = 255;
  122. colors[12] = 0;
  123. colors[13] = 0;
  124. colors[14] = 0;
  125. colors[15] = 0;
  126. }
  127. for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
  128. {
  129. int idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 4;
  130. _dst[ii+0] = colors[idx+0];
  131. _dst[ii+1] = colors[idx+1];
  132. _dst[ii+2] = colors[idx+2];
  133. _dst[ii+3] = colors[idx+3];
  134. }
  135. }
  136. void decodeBlockDxt23A(uint8_t _dst[16*4], const uint8_t _src[8])
  137. {
  138. for (uint32_t ii = 3, next = 0; ii < 16*4; ii += 4, next += 4)
  139. {
  140. uint32_t c0 = (_src[next>>3] >> (next&7) ) & 0xf;
  141. _dst[ii] = bitRangeConvert(c0, 4, 8);
  142. }
  143. }
  144. void decodeBlockDxt45A(uint8_t _dst[16*4], const uint8_t _src[8])
  145. {
  146. uint8_t alpha[8];
  147. alpha[0] = _src[0];
  148. alpha[1] = _src[1];
  149. if (alpha[0] > alpha[1])
  150. {
  151. alpha[2] = (6*alpha[0] + 1*alpha[1]) / 7;
  152. alpha[3] = (5*alpha[0] + 2*alpha[1]) / 7;
  153. alpha[4] = (4*alpha[0] + 3*alpha[1]) / 7;
  154. alpha[5] = (3*alpha[0] + 4*alpha[1]) / 7;
  155. alpha[6] = (2*alpha[0] + 5*alpha[1]) / 7;
  156. alpha[7] = (1*alpha[0] + 6*alpha[1]) / 7;
  157. }
  158. else
  159. {
  160. alpha[2] = (4*alpha[0] + 1*alpha[1]) / 5;
  161. alpha[3] = (3*alpha[0] + 2*alpha[1]) / 5;
  162. alpha[4] = (2*alpha[0] + 3*alpha[1]) / 5;
  163. alpha[5] = (1*alpha[0] + 4*alpha[1]) / 5;
  164. alpha[6] = 0;
  165. alpha[7] = 255;
  166. }
  167. for (uint32_t ii = 3, next = 8*2; ii < 16*4; ii += 4, ++next)
  168. {
  169. uint32_t bit = (_src[next>>3] >> (next&7) ) & 1;
  170. uint32_t idx = bit;
  171. ++next;
  172. bit = (_src[next>>3] >> (next&7) ) & 1;
  173. idx += bit << 1;
  174. ++next;
  175. bit = (_src[next>>3] >> (next&7) ) & 1;
  176. idx += bit << 2;
  177. _dst[ii] = alpha[idx & 7];
  178. }
  179. }
  180. uint32_t Mip::getDecodedSize() const
  181. {
  182. return m_width*m_height*4;
  183. }
  184. void Mip::decode(uint8_t* _dst)
  185. {
  186. const uint8_t* src = m_data;
  187. if (TextureFormat::Unknown > m_type)
  188. {
  189. uint32_t width = m_width/4;
  190. uint32_t height = m_height/4;
  191. uint32_t pitch = m_width*4;
  192. uint8_t temp[16*4];
  193. switch (m_type)
  194. {
  195. case TextureFormat::Dxt1:
  196. for (uint32_t yy = 0; yy < height; ++yy)
  197. {
  198. for (uint32_t xx = 0; xx < width; ++xx)
  199. {
  200. decodeBlockDxt1(temp, src);
  201. src += 8;
  202. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  203. memcpy(dst, temp, 16);
  204. memcpy(&dst[pitch], &temp[16], 16);
  205. memcpy(&dst[2*pitch], &temp[32], 16);
  206. memcpy(&dst[3*pitch], &temp[48], 16);
  207. }
  208. }
  209. break;
  210. case TextureFormat::Dxt3:
  211. for (uint32_t yy = 0; yy < height; ++yy)
  212. {
  213. for (uint32_t xx = 0; xx < width; ++xx)
  214. {
  215. decodeBlockDxt23A(temp, src);
  216. src += 8;
  217. decodeBlockDxt(temp, src);
  218. src += 8;
  219. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  220. memcpy(dst, temp, 16);
  221. memcpy(&dst[pitch], &temp[16], 16);
  222. memcpy(&dst[2*pitch], &temp[32], 16);
  223. memcpy(&dst[3*pitch], &temp[48], 16);
  224. }
  225. }
  226. break;
  227. case TextureFormat::Dxt5:
  228. for (uint32_t yy = 0; yy < height; ++yy)
  229. {
  230. for (uint32_t xx = 0; xx < width; ++xx)
  231. {
  232. decodeBlockDxt45A(temp, src);
  233. src += 8;
  234. decodeBlockDxt(temp, src);
  235. src += 8;
  236. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  237. memcpy(dst, temp, 16);
  238. memcpy(&dst[pitch], &temp[16], 16);
  239. memcpy(&dst[2*pitch], &temp[32], 16);
  240. memcpy(&dst[3*pitch], &temp[48], 16);
  241. }
  242. }
  243. break;
  244. }
  245. }
  246. else
  247. {
  248. uint32_t width = m_width;
  249. uint32_t height = m_height;
  250. if (m_bpp == 8
  251. || m_bpp == 32
  252. || m_bpp == 64)
  253. {
  254. uint32_t pitch = m_width*m_bpp/8;
  255. memcpy(_dst, src, pitch*height);
  256. }
  257. else
  258. {
  259. uint32_t pitch = m_width*4;
  260. for (uint32_t yy = 0; yy < height; ++yy)
  261. {
  262. uint8_t* dst = &_dst[yy*pitch];
  263. for (uint32_t xx = 0; xx < width; ++xx)
  264. {
  265. memcpy(dst, src, 3);
  266. dst[3] = 255;
  267. dst += 4;
  268. src += 3;
  269. }
  270. }
  271. }
  272. }
  273. }
  274. bool parseDds(Dds& _dds, const Memory* _mem)
  275. {
  276. bx::MemoryReader reader(_mem->data, _mem->size);
  277. uint32_t magic;
  278. bx::read(&reader, magic);
  279. if (DDS_MAGIC != magic)
  280. {
  281. return false;
  282. }
  283. uint32_t headerSize;
  284. bx::read(&reader, headerSize);
  285. if (headerSize < DDS_HEADER_SIZE)
  286. {
  287. return false;
  288. }
  289. uint32_t flags;
  290. bx::read(&reader, flags);
  291. if ( (flags & (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT) ) != (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT) )
  292. {
  293. return false;
  294. }
  295. uint32_t height;
  296. bx::read(&reader, height);
  297. uint32_t width;
  298. bx::read(&reader, width);
  299. uint32_t pitch;
  300. bx::read(&reader, pitch);
  301. uint32_t depth;
  302. bx::read(&reader, depth);
  303. uint32_t mips;
  304. bx::read(&reader, mips);
  305. bx::skip(&reader, 44); // reserved
  306. bx::skip(&reader, 4); // pixel format size
  307. uint32_t pixelFlags;
  308. bx::read(&reader, pixelFlags);
  309. uint32_t fourcc;
  310. bx::read(&reader, fourcc);
  311. uint32_t rgbCount;
  312. bx::read(&reader, rgbCount);
  313. uint32_t rbitmask;
  314. bx::read(&reader, rbitmask);
  315. uint32_t gbitmask;
  316. bx::read(&reader, gbitmask);
  317. uint32_t bbitmask;
  318. bx::read(&reader, bbitmask);
  319. uint32_t abitmask;
  320. bx::read(&reader, abitmask);
  321. uint32_t caps[4];
  322. bx::read(&reader, caps);
  323. if ( (caps[0] & DDSCAPS_TEXTURE) == 0)
  324. {
  325. return false;
  326. }
  327. bool cubeMap = 0 != (caps[1] & DDSCAPS2_CUBEMAP);
  328. if (cubeMap)
  329. {
  330. if ( (caps[1] & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
  331. {
  332. // parital cube map is not supported.
  333. return false;
  334. }
  335. }
  336. bx::skip(&reader, 4); // reserved
  337. uint8_t bpp = 0;
  338. uint8_t blockSize = 1;
  339. TextureFormat::Enum type = TextureFormat::Unknown;
  340. bool hasAlpha = pixelFlags & DDPF_ALPHAPIXELS;
  341. if (pixelFlags & DDPF_FOURCC)
  342. {
  343. switch (fourcc)
  344. {
  345. case DDS_DXT1:
  346. type = TextureFormat::Dxt1;
  347. blockSize = 8;
  348. bpp = 4;
  349. break;
  350. case DDS_DXT2:
  351. case DDS_DXT3:
  352. type = TextureFormat::Dxt3;
  353. blockSize = 16;
  354. bpp = 4;
  355. break;
  356. case DDS_DXT4:
  357. case DDS_DXT5:
  358. type = TextureFormat::Dxt5;
  359. blockSize = 16;
  360. bpp = 4;
  361. break;
  362. case D3DFMT_A16B16G16R16F:
  363. type = TextureFormat::RGBA16;
  364. blockSize = 8;
  365. bpp = 64;
  366. break;
  367. }
  368. }
  369. else
  370. {
  371. switch (pixelFlags)
  372. {
  373. case DDPF_RGB:
  374. type = TextureFormat::BGRX8;
  375. blockSize = 3;
  376. bpp = 24;
  377. break;
  378. case DDPF_RGB|DDPF_ALPHAPIXELS:
  379. type = TextureFormat::BGRA8;
  380. blockSize = 4;
  381. bpp = 32;
  382. break;
  383. case DDPF_INDEXED:
  384. case DDPF_LUMINANCE:
  385. case DDPF_ALPHA:
  386. type = TextureFormat::L8;
  387. bpp = 8;
  388. break;
  389. // type = TextureFormat::A8;
  390. // bpp = 1;
  391. // break;
  392. default:
  393. bpp = 0;
  394. break;
  395. }
  396. }
  397. _dds.m_type = type;
  398. _dds.m_width = width;
  399. _dds.m_height = height;
  400. _dds.m_depth = depth;
  401. _dds.m_blockSize = blockSize;
  402. _dds.m_numMips = (caps[0] & DDSCAPS_MIPMAP) ? mips : 1;
  403. _dds.m_bpp = bpp;
  404. _dds.m_hasAlpha = hasAlpha;
  405. _dds.m_cubeMap = cubeMap;
  406. return true;
  407. }
  408. bool getRawImageData(const Dds& _dds, uint8_t _side, uint8_t _lod, const Memory* _mem, Mip& _mip)
  409. {
  410. uint32_t blockSize = _dds.m_blockSize;
  411. uint32_t offset = DDS_IMAGE_DATA_OFFSET;
  412. uint8_t bpp = _dds.m_bpp;
  413. TextureFormat::Enum type = _dds.m_type;
  414. bool hasAlpha = _dds.m_hasAlpha;
  415. for (uint8_t side = 0, numSides = _dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
  416. {
  417. uint32_t width = _dds.m_width;
  418. uint32_t height = _dds.m_height;
  419. uint32_t depth = _dds.m_depth;
  420. for (uint8_t lod = 0, num = _dds.m_numMips; lod < num; ++lod)
  421. {
  422. width = uint32_max(1, width);
  423. height = uint32_max(1, height);
  424. depth = uint32_max(1, depth);
  425. uint32_t size = width*height*depth*blockSize;
  426. if (TextureFormat::Unknown > type)
  427. {
  428. width = uint32_max(1, (width + 3)>>2);
  429. height = uint32_max(1, (height + 3)>>2);
  430. size = width*height*depth*blockSize;
  431. width <<= 2;
  432. height <<= 2;
  433. }
  434. if (side == _side
  435. && lod == _lod)
  436. {
  437. _mip.m_width = width;
  438. _mip.m_height = height;
  439. _mip.m_blockSize = blockSize;
  440. _mip.m_size = size;
  441. _mip.m_data = _mem->data + offset;
  442. _mip.m_bpp = bpp;
  443. _mip.m_type = type;
  444. _mip.m_hasAlpha = hasAlpha;
  445. return true;
  446. }
  447. offset += size;
  448. width >>= 1;
  449. height >>= 1;
  450. depth >>= 1;
  451. }
  452. }
  453. return false;
  454. }
  455. } // namespace bgfx