image.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  1. /*
  2. * Copyright 2011-2013 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include "bgfx_p.h"
  6. #include <bx/float4_t.h>
  7. #include <math.h> // powf, sqrtf
  8. #include "image.h"
  9. namespace bgfx
  10. {
  11. static const uint32_t s_bitsPerPixel[TextureFormat::Count] =
  12. {
  13. 4, // BC1
  14. 8, // BC2
  15. 8, // BC3
  16. 4, // BC4
  17. 8, // BC5
  18. 4, // ETC1
  19. 4, // ETC2
  20. 4, // ETC2A
  21. 4, // ETC2A1
  22. 2, // PTC12
  23. 4, // PTC14
  24. 2, // PTC12A
  25. 4, // PTC14A
  26. 2, // PTC22
  27. 4, // PTC24
  28. 0, // Unknown
  29. 8, // L8
  30. 32, // BGRA8
  31. 64, // RGBA16
  32. 64, // RGBA16F
  33. 16, // R5G6B5
  34. 16, // RGBA4
  35. 16, // RGB5A1
  36. 32, // RGB10A2
  37. };
  38. uint32_t getBitsPerPixel(TextureFormat::Enum _format)
  39. {
  40. return s_bitsPerPixel[_format];
  41. }
  42. void imageSolid(uint32_t _width, uint32_t _height, uint32_t _solid, void* _dst)
  43. {
  44. uint32_t* dst = (uint32_t*)_dst;
  45. for (uint32_t ii = 0, num = _width*_height; ii < num; ++ii)
  46. {
  47. *dst++ = _solid;
  48. }
  49. }
  50. void imageCheckerboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst)
  51. {
  52. uint32_t* dst = (uint32_t*)_dst;
  53. for (uint32_t yy = 0; yy < _height; ++yy)
  54. {
  55. for (uint32_t xx = 0; xx < _width; ++xx)
  56. {
  57. uint32_t abgr = ( (xx/_step)&1) ^ ( (yy/_step)&1) ? _1 : _0;
  58. *dst++ = abgr;
  59. }
  60. }
  61. }
  62. void imageRgba8Downsample2x2Ref(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
  63. {
  64. const uint32_t dstwidth = _width/2;
  65. const uint32_t dstheight = _height/2;
  66. if (0 == dstwidth
  67. || 0 == dstheight)
  68. {
  69. return;
  70. }
  71. uint8_t* dst = (uint8_t*)_dst;
  72. const uint8_t* src = (const uint8_t*)_src;
  73. for (uint32_t yy = 0, ystep = _pitch*2; yy < dstheight; ++yy, src += ystep)
  74. {
  75. const uint8_t* rgba = src;
  76. for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba += 8, dst += 4)
  77. {
  78. float rr = powf(rgba[ 0], 2.2f);
  79. float gg = powf(rgba[ 1], 2.2f);
  80. float bb = powf(rgba[ 2], 2.2f);
  81. float aa = rgba[ 3];
  82. rr += powf(rgba[ 4], 2.2f);
  83. gg += powf(rgba[ 5], 2.2f);
  84. bb += powf(rgba[ 6], 2.2f);
  85. aa += rgba[ 7];
  86. rr += powf(rgba[_pitch+0], 2.2f);
  87. gg += powf(rgba[_pitch+1], 2.2f);
  88. bb += powf(rgba[_pitch+2], 2.2f);
  89. aa += rgba[_pitch+3];
  90. rr += powf(rgba[_pitch+4], 2.2f);
  91. gg += powf(rgba[_pitch+5], 2.2f);
  92. bb += powf(rgba[_pitch+6], 2.2f);
  93. aa += rgba[_pitch+7];
  94. rr *= 0.25f;
  95. gg *= 0.25f;
  96. bb *= 0.25f;
  97. aa *= 0.25f;
  98. rr = powf(rr, 1.0f/2.2f);
  99. gg = powf(gg, 1.0f/2.2f);
  100. bb = powf(bb, 1.0f/2.2f);
  101. dst[0] = (uint8_t)rr;
  102. dst[1] = (uint8_t)gg;
  103. dst[2] = (uint8_t)bb;
  104. dst[3] = (uint8_t)aa;
  105. }
  106. }
  107. }
  108. void imageRgba8Downsample2x2(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
  109. {
  110. const uint32_t dstwidth = _width/2;
  111. const uint32_t dstheight = _height/2;
  112. if (0 == dstwidth
  113. || 0 == dstheight)
  114. {
  115. return;
  116. }
  117. uint8_t* dst = (uint8_t*)_dst;
  118. const uint8_t* src = (const uint8_t*)_src;
  119. using namespace bx;
  120. const float4_t unpack = float4_ld(1.0f, 1.0f/256.0f, 1.0f/65536.0f, 1.0f/16777216.0f);
  121. const float4_t pack = float4_ld(1.0f, 256.0f*0.5f, 65536.0f, 16777216.0f*0.5f);
  122. const float4_t umask = float4_ild(0xff, 0xff00, 0xff0000, 0xff000000);
  123. const float4_t pmask = float4_ild(0xff, 0x7f80, 0xff0000, 0x7f800000);
  124. const float4_t wflip = float4_ild(0, 0, 0, 0x80000000);
  125. const float4_t wadd = float4_ld(0.0f, 0.0f, 0.0f, 32768.0f*65536.0f);
  126. const float4_t gamma = float4_ld(1.0f/2.2f, 1.0f/2.2f, 1.0f/2.2f, 1.0f);
  127. const float4_t linear = float4_ld(2.2f, 2.2f, 2.2f, 1.0f);
  128. const float4_t quater = float4_splat(0.25f);
  129. for (uint32_t yy = 0, ystep = _pitch*2; yy < dstheight; ++yy, src += ystep)
  130. {
  131. const uint8_t* rgba = src;
  132. for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba += 8, dst += 4)
  133. {
  134. const float4_t abgr0 = float4_splat(rgba);
  135. const float4_t abgr1 = float4_splat(rgba+4);
  136. const float4_t abgr2 = float4_splat(rgba+_pitch);
  137. const float4_t abgr3 = float4_splat(rgba+_pitch+4);
  138. const float4_t abgr0m = float4_and(abgr0, umask);
  139. const float4_t abgr1m = float4_and(abgr1, umask);
  140. const float4_t abgr2m = float4_and(abgr2, umask);
  141. const float4_t abgr3m = float4_and(abgr3, umask);
  142. const float4_t abgr0x = float4_xor(abgr0m, wflip);
  143. const float4_t abgr1x = float4_xor(abgr1m, wflip);
  144. const float4_t abgr2x = float4_xor(abgr2m, wflip);
  145. const float4_t abgr3x = float4_xor(abgr3m, wflip);
  146. const float4_t abgr0f = float4_itof(abgr0x);
  147. const float4_t abgr1f = float4_itof(abgr1x);
  148. const float4_t abgr2f = float4_itof(abgr2x);
  149. const float4_t abgr3f = float4_itof(abgr3x);
  150. const float4_t abgr0c = float4_add(abgr0f, wadd);
  151. const float4_t abgr1c = float4_add(abgr1f, wadd);
  152. const float4_t abgr2c = float4_add(abgr2f, wadd);
  153. const float4_t abgr3c = float4_add(abgr3f, wadd);
  154. const float4_t abgr0n = float4_mul(abgr0c, unpack);
  155. const float4_t abgr1n = float4_mul(abgr1c, unpack);
  156. const float4_t abgr2n = float4_mul(abgr2c, unpack);
  157. const float4_t abgr3n = float4_mul(abgr3c, unpack);
  158. const float4_t abgr0l = float4_pow(abgr0n, linear);
  159. const float4_t abgr1l = float4_pow(abgr1n, linear);
  160. const float4_t abgr2l = float4_pow(abgr2n, linear);
  161. const float4_t abgr3l = float4_pow(abgr3n, linear);
  162. const float4_t sum0 = float4_add(abgr0l, abgr1l);
  163. const float4_t sum1 = float4_add(abgr2l, abgr3l);
  164. const float4_t sum2 = float4_add(sum0, sum1);
  165. const float4_t avg0 = float4_mul(sum2, quater);
  166. const float4_t avg1 = float4_pow(avg0, gamma);
  167. const float4_t avg2 = float4_mul(avg1, pack);
  168. const float4_t ftoi0 = float4_ftoi(avg2);
  169. const float4_t ftoi1 = float4_and(ftoi0, pmask);
  170. const float4_t zwxy = float4_swiz_zwxy(ftoi1);
  171. const float4_t tmp0 = float4_or(ftoi1, zwxy);
  172. const float4_t yyyy = float4_swiz_yyyy(tmp0);
  173. const float4_t tmp1 = float4_iadd(yyyy, yyyy);
  174. const float4_t result = float4_or(tmp0, tmp1);
  175. float4_stx(dst, result);
  176. }
  177. }
  178. }
  179. void imageSwizzleBgra8Ref(uint32_t _width, uint32_t _height, const void* _src, void* _dst)
  180. {
  181. const uint8_t* src = (uint8_t*) _src;
  182. uint8_t* dst = (uint8_t*)_dst;
  183. for (uint32_t xx = 0, num = _width*_height; xx < num; ++xx, src += 4, dst += 4)
  184. {
  185. uint8_t rr = src[0];
  186. uint8_t gg = src[1];
  187. uint8_t bb = src[2];
  188. uint8_t aa = src[3];
  189. dst[0] = bb;
  190. dst[1] = gg;
  191. dst[2] = rr;
  192. dst[3] = aa;
  193. }
  194. }
  195. void imageSwizzleBgra8(uint32_t _width, uint32_t _height, const void* _src, void* _dst)
  196. {
  197. // Test can we do four 4-byte pixels at the time.
  198. if (0 != (_width&0x3)
  199. || _width < 4
  200. || !bx::isPtrAligned(_src, 16)
  201. || !bx::isPtrAligned(_dst, 16) )
  202. {
  203. BX_WARN(false, "Image swizzle is taking slow path.");
  204. BX_WARN(bx::isPtrAligned(_src, 16), "Source %p is not 16-byte aligned.", _src);
  205. BX_WARN(bx::isPtrAligned(_dst, 16), "Destination %p is not 16-byte aligned.", _dst);
  206. BX_WARN(_width < 4, "Image width must be multiple of 4 (width %d).", _width);
  207. imageSwizzleBgra8Ref(_width, _height, _src, _dst);
  208. return;
  209. }
  210. const uint32_t dstpitch = _width*4;
  211. using namespace bx;
  212. const float4_t mf0f0 = float4_isplat(0xff00ff00);
  213. const float4_t m0f0f = float4_isplat(0x00ff00ff);
  214. const uint8_t* src = (uint8_t*) _src;
  215. uint8_t* dst = (uint8_t*)_dst;
  216. for (uint32_t xx = 0, num = dstpitch/16*_height; xx < num; ++xx, src += 16, dst += 16)
  217. {
  218. const float4_t tabgr = float4_ld(src);
  219. const float4_t t00ab = float4_srl(tabgr, 16);
  220. const float4_t tgr00 = float4_sll(tabgr, 16);
  221. const float4_t tgrab = float4_or(t00ab, tgr00);
  222. const float4_t ta0g0 = float4_and(tabgr, mf0f0);
  223. const float4_t t0r0b = float4_and(tgrab, m0f0f);
  224. const float4_t targb = float4_or(ta0g0, t0r0b);
  225. float4_st(dst, targb);
  226. }
  227. }
  228. void imageWriteTga(bx::WriterI* _writer, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bool _grayscale, bool _yflip)
  229. {
  230. uint8_t type = _grayscale ? 3 : 2;
  231. uint8_t bpp = _grayscale ? 8 : 32;
  232. uint8_t header[18] = {};
  233. header[2] = type;
  234. header[12] = _width&0xff;
  235. header[13] = (_width>>8)&0xff;
  236. header[14] = _height&0xff;
  237. header[15] = (_height>>8)&0xff;
  238. header[16] = bpp;
  239. header[17] = 32;
  240. bx::write(_writer, header, sizeof(header) );
  241. uint32_t dstPitch = _width*bpp/8;
  242. if (_yflip)
  243. {
  244. uint8_t* data = (uint8_t*)_src + _srcPitch*_height - _srcPitch;
  245. for (uint32_t yy = 0; yy < _height; ++yy)
  246. {
  247. bx::write(_writer, data, dstPitch);
  248. data -= _srcPitch;
  249. }
  250. }
  251. else if (_srcPitch == dstPitch)
  252. {
  253. bx::write(_writer, _src, _height*_srcPitch);
  254. }
  255. else
  256. {
  257. uint8_t* data = (uint8_t*)_src;
  258. for (uint32_t yy = 0; yy < _height; ++yy)
  259. {
  260. bx::write(_writer, data, dstPitch);
  261. data += _srcPitch;
  262. }
  263. }
  264. }
  265. uint32_t bitRangeConvert(uint32_t _in, uint32_t _from, uint32_t _to)
  266. {
  267. using namespace bx;
  268. uint32_t tmp0 = uint32_sll(1, _to);
  269. uint32_t tmp1 = uint32_sll(1, _from);
  270. uint32_t tmp2 = uint32_dec(tmp0);
  271. uint32_t tmp3 = uint32_dec(tmp1);
  272. uint32_t tmp4 = uint32_mul(_in, tmp2);
  273. uint32_t tmp5 = uint32_add(tmp3, tmp4);
  274. uint32_t tmp6 = uint32_srl(tmp5, _from);
  275. uint32_t tmp7 = uint32_add(tmp5, tmp6);
  276. uint32_t result = uint32_srl(tmp7, _from);
  277. return result;
  278. }
  279. void decodeBlockDxt(uint8_t _dst[16*4], const uint8_t _src[8])
  280. {
  281. uint8_t colors[4*3];
  282. uint32_t c0 = _src[0] | (_src[1] << 8);
  283. colors[0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
  284. colors[1] = bitRangeConvert( (c0>> 5)&0x3f, 6, 8);
  285. colors[2] = bitRangeConvert( (c0>>11)&0x1f, 5, 8);
  286. uint32_t c1 = _src[2] | (_src[3] << 8);
  287. colors[3] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
  288. colors[4] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
  289. colors[5] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
  290. colors[6] = (2*colors[0] + colors[3]) / 3;
  291. colors[7] = (2*colors[1] + colors[4]) / 3;
  292. colors[8] = (2*colors[2] + colors[5]) / 3;
  293. colors[ 9] = (colors[0] + 2*colors[3]) / 3;
  294. colors[10] = (colors[1] + 2*colors[4]) / 3;
  295. colors[11] = (colors[2] + 2*colors[5]) / 3;
  296. for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
  297. {
  298. int idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 3;
  299. _dst[ii+0] = colors[idx+0];
  300. _dst[ii+1] = colors[idx+1];
  301. _dst[ii+2] = colors[idx+2];
  302. }
  303. }
  304. void decodeBlockDxt1(uint8_t _dst[16*4], const uint8_t _src[8])
  305. {
  306. uint8_t colors[4*4];
  307. uint32_t c0 = _src[0] | (_src[1] << 8);
  308. colors[0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
  309. colors[1] = bitRangeConvert( (c0>> 5)&0x3f, 6, 8);
  310. colors[2] = bitRangeConvert( (c0>>11)&0x1f, 5, 8);
  311. colors[3] = 255;
  312. uint32_t c1 = _src[2] | (_src[3] << 8);
  313. colors[4] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
  314. colors[5] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
  315. colors[6] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
  316. colors[7] = 255;
  317. if (c0 > c1)
  318. {
  319. colors[ 8] = (2*colors[0] + colors[4]) / 3;
  320. colors[ 9] = (2*colors[1] + colors[5]) / 3;
  321. colors[10] = (2*colors[2] + colors[6]) / 3;
  322. colors[11] = 255;
  323. colors[12] = (colors[0] + 2*colors[4]) / 3;
  324. colors[13] = (colors[1] + 2*colors[5]) / 3;
  325. colors[14] = (colors[2] + 2*colors[6]) / 3;
  326. colors[15] = 255;
  327. }
  328. else
  329. {
  330. colors[ 8] = (colors[0] + colors[4]) / 2;
  331. colors[ 9] = (colors[1] + colors[5]) / 2;
  332. colors[10] = (colors[2] + colors[6]) / 2;
  333. colors[11] = 255;
  334. colors[12] = 0;
  335. colors[13] = 0;
  336. colors[14] = 0;
  337. colors[15] = 0;
  338. }
  339. for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
  340. {
  341. int idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 4;
  342. _dst[ii+0] = colors[idx+0];
  343. _dst[ii+1] = colors[idx+1];
  344. _dst[ii+2] = colors[idx+2];
  345. _dst[ii+3] = colors[idx+3];
  346. }
  347. }
  348. void decodeBlockDxt23A(uint8_t _dst[16*4], const uint8_t _src[8])
  349. {
  350. for (uint32_t ii = 0, next = 0; ii < 16*4; ii += 4, next += 4)
  351. {
  352. uint32_t c0 = (_src[next>>3] >> (next&7) ) & 0xf;
  353. _dst[ii] = bitRangeConvert(c0, 4, 8);
  354. }
  355. }
  356. void decodeBlockDxt45A(uint8_t _dst[16*4], const uint8_t _src[8])
  357. {
  358. uint8_t alpha[8];
  359. alpha[0] = _src[0];
  360. alpha[1] = _src[1];
  361. if (alpha[0] > alpha[1])
  362. {
  363. alpha[2] = (6*alpha[0] + 1*alpha[1]) / 7;
  364. alpha[3] = (5*alpha[0] + 2*alpha[1]) / 7;
  365. alpha[4] = (4*alpha[0] + 3*alpha[1]) / 7;
  366. alpha[5] = (3*alpha[0] + 4*alpha[1]) / 7;
  367. alpha[6] = (2*alpha[0] + 5*alpha[1]) / 7;
  368. alpha[7] = (1*alpha[0] + 6*alpha[1]) / 7;
  369. }
  370. else
  371. {
  372. alpha[2] = (4*alpha[0] + 1*alpha[1]) / 5;
  373. alpha[3] = (3*alpha[0] + 2*alpha[1]) / 5;
  374. alpha[4] = (2*alpha[0] + 3*alpha[1]) / 5;
  375. alpha[5] = (1*alpha[0] + 4*alpha[1]) / 5;
  376. alpha[6] = 0;
  377. alpha[7] = 255;
  378. }
  379. uint32_t idx0 = _src[2];
  380. uint32_t idx1 = _src[5];
  381. idx0 |= uint32_t(_src[3])<<8;
  382. idx1 |= uint32_t(_src[6])<<8;
  383. idx0 |= uint32_t(_src[4])<<16;
  384. idx1 |= uint32_t(_src[7])<<16;
  385. for (uint32_t ii = 0; ii < 8*4; ii += 4)
  386. {
  387. _dst[ii] = alpha[idx0&7];
  388. _dst[ii+32] = alpha[idx1&7];
  389. idx0 >>= 3;
  390. idx1 >>= 3;
  391. }
  392. }
  393. static const int32_t s_mod[8][4] =
  394. {
  395. { 2, 8, -2, -8},
  396. { 15, 17, -15, -17},
  397. { 9, 29, -9, -29},
  398. { 13, 42, -13, -42},
  399. { 18, 60, -18, -60},
  400. { 24, 80, -24, -80},
  401. { 33, 106, -33, -106},
  402. { 47, 183, -47, -183},
  403. };
  404. int8_t uint8_add2c(int32_t _a, int32_t _b)
  405. {
  406. return _b & 0x4
  407. ? _a - ( (~_b + 1) & 0x7)
  408. : _a + _b
  409. ;
  410. }
  411. int8_t uint8_satadd(int32_t _a, int32_t _b)
  412. {
  413. using namespace bx;
  414. const int32_t add = _a + _b;
  415. const uint32_t min = uint32_min(add, 255);
  416. const uint32_t result = uint32_max(min, 0);
  417. return result;
  418. }
  419. void decodeBlockEtc1(uint8_t _dst[16*4], const uint8_t _src[8])
  420. {
  421. bool flipBit = 0 != (_src[3] & 0x1);
  422. bool diffBit = 0 != (_src[3] & 0x2);
  423. uint8_t rgb[8];
  424. if (diffBit)
  425. {
  426. rgb[0] = _src[0] >> 3;
  427. rgb[1] = _src[1] >> 3;
  428. rgb[2] = _src[2] >> 3;
  429. uint8_t diff[3];
  430. diff[0] = _src[0] & 0x07;
  431. diff[1] = _src[1] & 0x07;
  432. diff[2] = _src[2] & 0x07;
  433. rgb[4] = uint8_add2c(rgb[0], diff[0]);
  434. rgb[5] = uint8_add2c(rgb[1], diff[1]);
  435. rgb[6] = uint8_add2c(rgb[2], diff[2]);
  436. rgb[0] = bitRangeConvert(rgb[0], 5, 8);
  437. rgb[1] = bitRangeConvert(rgb[1], 5, 8);
  438. rgb[2] = bitRangeConvert(rgb[2], 5, 8);
  439. rgb[4] = bitRangeConvert(rgb[4], 5, 8);
  440. rgb[5] = bitRangeConvert(rgb[5], 5, 8);
  441. rgb[6] = bitRangeConvert(rgb[6], 5, 8);
  442. }
  443. else
  444. {
  445. rgb[0] = _src[0] >> 4;
  446. rgb[1] = _src[1] >> 4;
  447. rgb[2] = _src[2] >> 4;
  448. rgb[4] = _src[0] & 0xf;
  449. rgb[5] = _src[1] & 0xf;
  450. rgb[6] = _src[2] & 0xf;
  451. rgb[0] = bitRangeConvert(rgb[0], 4, 8);
  452. rgb[1] = bitRangeConvert(rgb[1], 4, 8);
  453. rgb[2] = bitRangeConvert(rgb[2], 4, 8);
  454. rgb[4] = bitRangeConvert(rgb[4], 4, 8);
  455. rgb[5] = bitRangeConvert(rgb[5], 4, 8);
  456. rgb[6] = bitRangeConvert(rgb[6], 4, 8);
  457. }
  458. uint32_t table[2];
  459. table[0] = (_src[3] >> 5) & 0x7;
  460. table[1] = (_src[3] >> 2) & 0x7;
  461. uint32_t indexBits = 0
  462. | (_src[4]<<24)
  463. | (_src[5]<<16)
  464. | (_src[6]<< 8)
  465. | (_src[7] )
  466. ;
  467. if (flipBit)
  468. {
  469. for (uint32_t ii = 0; ii < 16; ++ii)
  470. {
  471. const uint32_t block = (ii>>1)&1;
  472. const uint32_t color = block<<2;
  473. const uint32_t idx = (ii&0xc) | ( (ii & 0x3)<<4);
  474. const uint32_t lsbi = (indexBits >> ii) & 1;
  475. const uint32_t msbi = (indexBits >> (16 + ii) ) & 1;
  476. const int32_t mod = s_mod[table[block] ][lsbi + msbi*2];
  477. _dst[idx + 0] = uint8_satadd(rgb[color+2], mod);
  478. _dst[idx + 1] = uint8_satadd(rgb[color+1], mod);
  479. _dst[idx + 2] = uint8_satadd(rgb[color+0], mod);
  480. }
  481. }
  482. else
  483. {
  484. for (uint32_t ii = 0; ii < 16; ++ii)
  485. {
  486. const uint32_t block = ii>>3;
  487. const uint32_t color = block<<2;
  488. const uint32_t idx = (ii&0xc) | ( (ii & 0x3)<<4);
  489. const uint32_t lsbi = (indexBits >> ii) & 1;
  490. const uint32_t msbi = (indexBits >> (16 + ii) ) & 1;
  491. const int32_t mod = s_mod[table[block] ][lsbi + msbi*2];
  492. _dst[idx + 0] = uint8_satadd(rgb[color+2], mod);
  493. _dst[idx + 1] = uint8_satadd(rgb[color+1], mod);
  494. _dst[idx + 2] = uint8_satadd(rgb[color+0], mod);
  495. }
  496. }
  497. }
  498. // DDS
  499. #define DDS_MAGIC BX_MAKEFOURCC('D', 'D', 'S', ' ')
  500. #define DDS_HEADER_SIZE 124
  501. #define DDS_IMAGE_DATA_OFFSET (DDS_HEADER_SIZE + 4)
  502. #define DDS_DXT1 BX_MAKEFOURCC('D', 'X', 'T', '1')
  503. #define DDS_DXT2 BX_MAKEFOURCC('D', 'X', 'T', '2')
  504. #define DDS_DXT3 BX_MAKEFOURCC('D', 'X', 'T', '3')
  505. #define DDS_DXT4 BX_MAKEFOURCC('D', 'X', 'T', '4')
  506. #define DDS_DXT5 BX_MAKEFOURCC('D', 'X', 'T', '5')
  507. #define DDS_ATI1 BX_MAKEFOURCC('A', 'T', 'I', '1')
  508. #define DDS_BC4U BX_MAKEFOURCC('B', 'C', '4', 'U')
  509. #define DDS_ATI2 BX_MAKEFOURCC('A', 'T', 'I', '2')
  510. #define DDS_BC5U BX_MAKEFOURCC('B', 'C', '5', 'U')
  511. #define D3DFMT_A16B16G16R16 36
  512. #define D3DFMT_A16B16G16R16F 113
  513. #define DDSD_CAPS 0x00000001
  514. #define DDSD_HEIGHT 0x00000002
  515. #define DDSD_WIDTH 0x00000004
  516. #define DDSD_PITCH 0x00000008
  517. #define DDSD_PIXELFORMAT 0x00001000
  518. #define DDSD_MIPMAPCOUNT 0x00020000
  519. #define DDSD_LINEARSIZE 0x00080000
  520. #define DDSD_DEPTH 0x00800000
  521. #define DDPF_ALPHAPIXELS 0x00000001
  522. #define DDPF_ALPHA 0x00000002
  523. #define DDPF_FOURCC 0x00000004
  524. #define DDPF_INDEXED 0x00000020
  525. #define DDPF_RGB 0x00000040
  526. #define DDPF_YUV 0x00000200
  527. #define DDPF_LUMINANCE 0x00020000
  528. #define DDSCAPS_COMPLEX 0x00000008
  529. #define DDSCAPS_TEXTURE 0x00001000
  530. #define DDSCAPS_MIPMAP 0x00400000
  531. #define DDSCAPS2_CUBEMAP 0x00000200
  532. #define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
  533. #define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
  534. #define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
  535. #define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
  536. #define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
  537. #define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
  538. #define DDS_CUBEMAP_ALLFACES (DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX \
  539. |DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY \
  540. |DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ)
  541. #define DDSCAPS2_VOLUME 0x00200000
  542. static struct TranslateDdsFormat
  543. {
  544. uint32_t m_format;
  545. TextureFormat::Enum m_textureFormat;
  546. } s_translateDdsFormat[] =
  547. {
  548. { DDS_DXT1, TextureFormat::BC1 },
  549. { DDS_DXT2, TextureFormat::BC2 },
  550. { DDS_DXT3, TextureFormat::BC2 },
  551. { DDS_DXT4, TextureFormat::BC3 },
  552. { DDS_DXT5, TextureFormat::BC3 },
  553. { DDS_ATI1, TextureFormat::BC4 },
  554. { DDS_BC4U, TextureFormat::BC4 },
  555. { DDS_ATI2, TextureFormat::BC5 },
  556. { DDS_BC5U, TextureFormat::BC5 },
  557. { D3DFMT_A16B16G16R16, TextureFormat::RGBA16 },
  558. { D3DFMT_A16B16G16R16F, TextureFormat::RGBA16F },
  559. { DDPF_RGB|DDPF_ALPHAPIXELS, TextureFormat::BGRA8 },
  560. { DDPF_INDEXED, TextureFormat::L8 },
  561. { DDPF_LUMINANCE, TextureFormat::L8 },
  562. { DDPF_ALPHA, TextureFormat::L8 },
  563. };
  564. bool imageParseDds(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
  565. {
  566. uint32_t headerSize;
  567. bx::read(_reader, headerSize);
  568. if (headerSize < DDS_HEADER_SIZE)
  569. {
  570. return false;
  571. }
  572. uint32_t flags;
  573. bx::read(_reader, flags);
  574. if ( (flags & (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT) ) != (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT) )
  575. {
  576. return false;
  577. }
  578. uint32_t height;
  579. bx::read(_reader, height);
  580. uint32_t width;
  581. bx::read(_reader, width);
  582. uint32_t pitch;
  583. bx::read(_reader, pitch);
  584. uint32_t depth;
  585. bx::read(_reader, depth);
  586. uint32_t mips;
  587. bx::read(_reader, mips);
  588. bx::skip(_reader, 44); // reserved
  589. bx::skip(_reader, 4); // pixel format size
  590. uint32_t pixelFlags;
  591. bx::read(_reader, pixelFlags);
  592. uint32_t fourcc;
  593. bx::read(_reader, fourcc);
  594. uint32_t rgbCount;
  595. bx::read(_reader, rgbCount);
  596. uint32_t rbitmask;
  597. bx::read(_reader, rbitmask);
  598. uint32_t gbitmask;
  599. bx::read(_reader, gbitmask);
  600. uint32_t bbitmask;
  601. bx::read(_reader, bbitmask);
  602. uint32_t abitmask;
  603. bx::read(_reader, abitmask);
  604. uint32_t caps[4];
  605. bx::read(_reader, caps);
  606. if ( (caps[0] & DDSCAPS_TEXTURE) == 0)
  607. {
  608. return false;
  609. }
  610. bool cubeMap = 0 != (caps[1] & DDSCAPS2_CUBEMAP);
  611. if (cubeMap)
  612. {
  613. if ( (caps[1] & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
  614. {
  615. // parital cube map is not supported.
  616. return false;
  617. }
  618. }
  619. bx::skip(_reader, 4); // reserved
  620. uint8_t bpp = 0;
  621. uint8_t blockSize = 1;
  622. TextureFormat::Enum format = TextureFormat::Unknown;
  623. bool hasAlpha = pixelFlags & DDPF_ALPHAPIXELS;
  624. uint32_t ddsFormat = pixelFlags & DDPF_FOURCC ? fourcc : pixelFlags;
  625. for (uint32_t ii = 0; ii < BX_COUNTOF(s_translateDdsFormat); ++ii)
  626. {
  627. if (s_translateDdsFormat[ii].m_format == ddsFormat)
  628. {
  629. format = s_translateDdsFormat[ii].m_textureFormat;
  630. break;
  631. }
  632. }
  633. bpp = getBitsPerPixel(format);
  634. blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
  635. blockSize = blockSize*bpp/8;
  636. _imageContainer.m_data = NULL;
  637. _imageContainer.m_size = 0;
  638. _imageContainer.m_offset = DDS_IMAGE_DATA_OFFSET;
  639. _imageContainer.m_width = width;
  640. _imageContainer.m_height = height;
  641. _imageContainer.m_depth = depth;
  642. _imageContainer.m_format = format;
  643. _imageContainer.m_blockSize = blockSize;
  644. _imageContainer.m_numMips = (caps[0] & DDSCAPS_MIPMAP) ? mips : 1;
  645. _imageContainer.m_bpp = bpp;
  646. _imageContainer.m_hasAlpha = hasAlpha;
  647. _imageContainer.m_cubeMap = cubeMap;
  648. _imageContainer.m_ktx = false;
  649. return TextureFormat::Unknown != format;
  650. }
  651. // KTX
  652. #define KTX_MAGIC BX_MAKEFOURCC(0xAB, 'K', 'T', 'X')
  653. #define KTX_HEADER_SIZE 64
  654. #define KTX_ETC1_RGB8_OES 0x8D64
  655. #define KTX_COMPRESSED_R11_EAC 0x9270
  656. #define KTX_COMPRESSED_SIGNED_R11_EAC 0x9271
  657. #define KTX_COMPRESSED_RG11_EAC 0x9272
  658. #define KTX_COMPRESSED_SIGNED_RG11_EAC 0x9273
  659. #define KTX_COMPRESSED_RGB8_ETC2 0x9274
  660. #define KTX_COMPRESSED_SRGB8_ETC2 0x9275
  661. #define KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
  662. #define KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
  663. #define KTX_COMPRESSED_RGBA8_ETC2_EAC 0x9278
  664. #define KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
  665. #define KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
  666. #define KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
  667. #define KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
  668. #define KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
  669. #define KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
  670. #define KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
  671. #define KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
  672. #define KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
  673. #define KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
  674. #define KTX_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
  675. #define KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
  676. #define KTX_RGBA16 0x805B
  677. #define KTX_RGBA16F 0x881A
  678. static struct TranslateKtxFormat
  679. {
  680. uint32_t m_format;
  681. TextureFormat::Enum m_textureFormat;
  682. } s_translateKtxFormat[] =
  683. {
  684. { KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT, TextureFormat::BC1 },
  685. { KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT, TextureFormat::BC2 },
  686. { KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT, TextureFormat::BC3 },
  687. { KTX_COMPRESSED_LUMINANCE_LATC1_EXT, TextureFormat::BC4 },
  688. { KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, TextureFormat::BC5 },
  689. { KTX_ETC1_RGB8_OES, TextureFormat::ETC1 },
  690. { KTX_COMPRESSED_RGB8_ETC2, TextureFormat::ETC2 },
  691. { KTX_COMPRESSED_RGBA8_ETC2_EAC, TextureFormat::ETC2A },
  692. { KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, TextureFormat::ETC2A1 },
  693. { KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, TextureFormat::PTC12 },
  694. { KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, TextureFormat::PTC12A },
  695. { KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, TextureFormat::PTC14 },
  696. { KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, TextureFormat::PTC14A },
  697. { KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, TextureFormat::PTC22 },
  698. { KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, TextureFormat::PTC24 },
  699. { KTX_RGBA16, TextureFormat::RGBA16 },
  700. { KTX_RGBA16F, TextureFormat::RGBA16F },
  701. { KTX_COMPRESSED_R11_EAC, TextureFormat::Unknown },
  702. { KTX_COMPRESSED_SIGNED_R11_EAC, TextureFormat::Unknown },
  703. { KTX_COMPRESSED_RG11_EAC, TextureFormat::Unknown },
  704. { KTX_COMPRESSED_SIGNED_RG11_EAC, TextureFormat::Unknown },
  705. { KTX_COMPRESSED_SRGB8_ETC2, TextureFormat::Unknown },
  706. { KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, TextureFormat::Unknown },
  707. { KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, TextureFormat::Unknown },
  708. };
  709. bool imageParseKtx(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
  710. {
  711. uint8_t identifier[8];
  712. bx::read(_reader, identifier);
  713. if (identifier[1] != '1'
  714. && identifier[2] != '1')
  715. {
  716. return false;
  717. }
  718. uint32_t endianness;
  719. bx::read(_reader, endianness);
  720. bool fromLittleEndian = 0x04030201 == endianness;
  721. uint32_t glType;
  722. bx::readHE(_reader, glType, fromLittleEndian);
  723. uint32_t glTypeSize;
  724. bx::readHE(_reader, glTypeSize, fromLittleEndian);
  725. uint32_t glFormat;
  726. bx::readHE(_reader, glFormat, fromLittleEndian);
  727. uint32_t glInternalFormat;
  728. bx::readHE(_reader, glInternalFormat, fromLittleEndian);
  729. uint32_t glBaseInternalFormat;
  730. bx::readHE(_reader, glBaseInternalFormat, fromLittleEndian);
  731. uint32_t width;
  732. bx::readHE(_reader, width, fromLittleEndian);
  733. uint32_t height;
  734. bx::readHE(_reader, height, fromLittleEndian);
  735. uint32_t depth;
  736. bx::readHE(_reader, depth, fromLittleEndian);
  737. uint32_t numberOfArrayElements;
  738. bx::readHE(_reader, numberOfArrayElements, fromLittleEndian);
  739. uint32_t numFaces;
  740. bx::readHE(_reader, numFaces, fromLittleEndian);
  741. uint32_t numMips;
  742. bx::readHE(_reader, numMips, fromLittleEndian);
  743. uint32_t metaDataSize;
  744. bx::readHE(_reader, metaDataSize, fromLittleEndian);
  745. // skip meta garbage...
  746. int64_t offset = bx::skip(_reader, metaDataSize);
  747. uint8_t bpp = 0;
  748. uint8_t blockSize = 1;
  749. TextureFormat::Enum format = TextureFormat::Unknown;
  750. bool hasAlpha = false;
  751. for (uint32_t ii = 0; ii < BX_COUNTOF(s_translateKtxFormat); ++ii)
  752. {
  753. if (s_translateKtxFormat[ii].m_format == glInternalFormat)
  754. {
  755. format = s_translateKtxFormat[ii].m_textureFormat;
  756. break;
  757. }
  758. }
  759. bpp = getBitsPerPixel(format);
  760. blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
  761. blockSize = blockSize*bpp/8;
  762. _imageContainer.m_data = NULL;
  763. _imageContainer.m_size = 0;
  764. _imageContainer.m_offset = (uint32_t)offset;
  765. _imageContainer.m_width = width;
  766. _imageContainer.m_height = height;
  767. _imageContainer.m_depth = depth;
  768. _imageContainer.m_format = format;
  769. _imageContainer.m_blockSize = blockSize;
  770. _imageContainer.m_numMips = numMips;
  771. _imageContainer.m_bpp = bpp;
  772. _imageContainer.m_hasAlpha = hasAlpha;
  773. _imageContainer.m_cubeMap = numFaces > 1;
  774. _imageContainer.m_ktx = true;
  775. return TextureFormat::Unknown != format;
  776. }
  777. // PVR3
  778. #define PVR3_MAKE8CC(_a, _b, _c, _d, _e, _f, _g, _h) (uint64_t(BX_MAKEFOURCC(_a, _b, _c, _d) ) | (uint64_t(BX_MAKEFOURCC(_e, _f, _g, _h) )<<32) )
  779. #define PVR3_MAGIC BX_MAKEFOURCC('P', 'V', 'R', 3)
  780. #define PVR3_HEADER_SIZE 52
  781. #define PVR3_PVRTC1_2BPP_RGB 0
  782. #define PVR3_PVRTC1_2BPP_RGBA 1
  783. #define PVR3_PVRTC1_4BPP_RGB 2
  784. #define PVR3_PVRTC1_4BPP_RGBA 3
  785. #define PVR3_ETC1 6
  786. #define PVR3_DXT1 7
  787. #define PVR3_DXT2 8
  788. #define PVR3_DXT3 9
  789. #define PVR3_DXT4 10
  790. #define PVR3_DXT5 11
  791. #define PVR3_BC4 12
  792. #define PVR3_BC5 13
  793. #define PVR3_RGBA16 PVR3_MAKE8CC('r', 'g', 'b', 'a', 16, 16, 16, 16)
  794. #define PVR3_CHANNEL_TYPE_ANY UINT32_MAX
  795. #define PVR3_CHANNEL_TYPE_FLOAT UINT32_C(12)
  796. static struct TranslatePvr3Format
  797. {
  798. uint64_t m_format;
  799. uint32_t m_channelTypeMask;
  800. TextureFormat::Enum m_textureFormat;
  801. } s_translatePvr3Format[] =
  802. {
  803. { PVR3_PVRTC1_2BPP_RGB, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC12 },
  804. { PVR3_PVRTC1_2BPP_RGBA, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC12 },
  805. { PVR3_PVRTC1_4BPP_RGB, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC14 },
  806. { PVR3_PVRTC1_4BPP_RGBA, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC14 },
  807. { PVR3_ETC1, PVR3_CHANNEL_TYPE_ANY, TextureFormat::ETC1 },
  808. { PVR3_DXT1, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC1 },
  809. { PVR3_DXT2, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC2 },
  810. { PVR3_DXT3, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC2 },
  811. { PVR3_DXT4, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC3 },
  812. { PVR3_DXT5, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC3 },
  813. { PVR3_BC4, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC4 },
  814. { PVR3_BC5, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC5 },
  815. { PVR3_RGBA16, PVR3_CHANNEL_TYPE_FLOAT, TextureFormat::RGBA16F },
  816. { PVR3_RGBA16, PVR3_CHANNEL_TYPE_ANY, TextureFormat::RGBA16 },
  817. };
  818. bool imageParsePvr3(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
  819. {
  820. uint32_t flags;
  821. bx::read(_reader, flags);
  822. uint64_t pixelFormat;
  823. bx::read(_reader, pixelFormat);
  824. uint32_t colorSpace;
  825. bx::read(_reader, colorSpace); // 0 - linearRGB, 1 - sRGB
  826. uint32_t channelType;
  827. bx::read(_reader, channelType);
  828. uint32_t height;
  829. bx::read(_reader, height);
  830. uint32_t width;
  831. bx::read(_reader, width);
  832. uint32_t depth;
  833. bx::read(_reader, depth);
  834. uint32_t numSurfaces;
  835. bx::read(_reader, numSurfaces);
  836. uint32_t numFaces;
  837. bx::read(_reader, numFaces);
  838. uint32_t numMips;
  839. bx::read(_reader, numMips);
  840. uint32_t metaDataSize;
  841. bx::read(_reader, metaDataSize);
  842. // skip meta garbage...
  843. int64_t offset = bx::skip(_reader, metaDataSize);
  844. uint8_t bpp = 0;
  845. uint8_t blockSize = 1;
  846. TextureFormat::Enum format = TextureFormat::Unknown;
  847. bool hasAlpha = false;
  848. for (uint32_t ii = 0; ii < BX_COUNTOF(s_translatePvr3Format); ++ii)
  849. {
  850. if (s_translatePvr3Format[ii].m_format == pixelFormat
  851. && channelType == (s_translatePvr3Format[ii].m_channelTypeMask & channelType) )
  852. {
  853. format = s_translatePvr3Format[ii].m_textureFormat;
  854. break;
  855. }
  856. }
  857. bpp = getBitsPerPixel(format);
  858. blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
  859. blockSize = blockSize*bpp/8;
  860. _imageContainer.m_data = NULL;
  861. _imageContainer.m_size = 0;
  862. _imageContainer.m_offset = (uint32_t)offset;
  863. _imageContainer.m_width = width;
  864. _imageContainer.m_height = height;
  865. _imageContainer.m_depth = depth;
  866. _imageContainer.m_format = format;
  867. _imageContainer.m_blockSize = blockSize;
  868. _imageContainer.m_numMips = numMips;
  869. _imageContainer.m_bpp = bpp;
  870. _imageContainer.m_hasAlpha = hasAlpha;
  871. _imageContainer.m_cubeMap = numFaces > 1;
  872. _imageContainer.m_ktx = false;
  873. return TextureFormat::Unknown != format;
  874. }
  875. bool imageParse(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
  876. {
  877. uint32_t magic;
  878. bx::read(_reader, magic);
  879. if (DDS_MAGIC == magic)
  880. {
  881. return imageParseDds(_imageContainer, _reader);
  882. }
  883. else if (KTX_MAGIC == magic)
  884. {
  885. return imageParseKtx(_imageContainer, _reader);
  886. }
  887. else if (PVR3_MAGIC == magic)
  888. {
  889. return imageParsePvr3(_imageContainer, _reader);
  890. }
  891. else if (BGFX_CHUNK_MAGIC_TEX == magic)
  892. {
  893. TextureCreate tc;
  894. bx::read(_reader, tc);
  895. uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(tc.m_format) );
  896. uint32_t blockSize = tc.m_format < TextureFormat::Unknown ? 4*4 : 1;
  897. blockSize = blockSize*bpp/8;
  898. _imageContainer.m_format = tc.m_format;
  899. _imageContainer.m_offset = UINT32_MAX;
  900. if (NULL == tc.m_mem)
  901. {
  902. _imageContainer.m_data = NULL;
  903. _imageContainer.m_size = 0;
  904. }
  905. else
  906. {
  907. _imageContainer.m_data = tc.m_mem->data;
  908. _imageContainer.m_size = tc.m_mem->size;
  909. }
  910. _imageContainer.m_width = tc.m_width;
  911. _imageContainer.m_height = tc.m_height;
  912. _imageContainer.m_depth = tc.m_depth;
  913. _imageContainer.m_blockSize = blockSize;
  914. _imageContainer.m_numMips = tc.m_numMips;
  915. _imageContainer.m_bpp = getBitsPerPixel(TextureFormat::Enum(tc.m_format) );
  916. _imageContainer.m_hasAlpha = false;
  917. _imageContainer.m_cubeMap = tc.m_cubeMap;
  918. _imageContainer.m_ktx = false;
  919. return true;
  920. }
  921. return false;
  922. }
  923. bool imageParse(ImageContainer& _imageContainer, const void* _data, uint32_t _size)
  924. {
  925. bx::MemoryReader reader(_data, _size);
  926. return imageParse(_imageContainer, &reader);
  927. }
  928. void imageDecodeToBgra8(uint8_t* _dst, const uint8_t* _src, uint32_t _width, uint32_t _height, uint8_t _type)
  929. {
  930. const uint8_t* src = _src;
  931. uint32_t width = _width/4;
  932. uint32_t height = _height/4;
  933. uint32_t pitch = _width*4;
  934. uint8_t temp[16*4];
  935. switch (_type)
  936. {
  937. case TextureFormat::BC1:
  938. for (uint32_t yy = 0; yy < height; ++yy)
  939. {
  940. for (uint32_t xx = 0; xx < width; ++xx)
  941. {
  942. decodeBlockDxt1(temp, src);
  943. src += 8;
  944. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  945. memcpy(&dst[0*pitch], &temp[ 0], 16);
  946. memcpy(&dst[1*pitch], &temp[16], 16);
  947. memcpy(&dst[2*pitch], &temp[32], 16);
  948. memcpy(&dst[3*pitch], &temp[48], 16);
  949. }
  950. }
  951. break;
  952. case TextureFormat::BC2:
  953. for (uint32_t yy = 0; yy < height; ++yy)
  954. {
  955. for (uint32_t xx = 0; xx < width; ++xx)
  956. {
  957. decodeBlockDxt23A(temp+3, src);
  958. src += 8;
  959. decodeBlockDxt(temp, src);
  960. src += 8;
  961. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  962. memcpy(&dst[0*pitch], &temp[ 0], 16);
  963. memcpy(&dst[1*pitch], &temp[16], 16);
  964. memcpy(&dst[2*pitch], &temp[32], 16);
  965. memcpy(&dst[3*pitch], &temp[48], 16);
  966. }
  967. }
  968. break;
  969. case TextureFormat::BC3:
  970. for (uint32_t yy = 0; yy < height; ++yy)
  971. {
  972. for (uint32_t xx = 0; xx < width; ++xx)
  973. {
  974. decodeBlockDxt45A(temp+3, src);
  975. src += 8;
  976. decodeBlockDxt(temp, src);
  977. src += 8;
  978. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  979. memcpy(&dst[0*pitch], &temp[ 0], 16);
  980. memcpy(&dst[1*pitch], &temp[16], 16);
  981. memcpy(&dst[2*pitch], &temp[32], 16);
  982. memcpy(&dst[3*pitch], &temp[48], 16);
  983. }
  984. }
  985. break;
  986. case TextureFormat::BC4:
  987. for (uint32_t yy = 0; yy < height; ++yy)
  988. {
  989. for (uint32_t xx = 0; xx < width; ++xx)
  990. {
  991. decodeBlockDxt45A(temp, src);
  992. src += 8;
  993. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  994. memcpy(&dst[0*pitch], &temp[ 0], 16);
  995. memcpy(&dst[1*pitch], &temp[16], 16);
  996. memcpy(&dst[2*pitch], &temp[32], 16);
  997. memcpy(&dst[3*pitch], &temp[48], 16);
  998. }
  999. }
  1000. break;
  1001. case TextureFormat::BC5:
  1002. for (uint32_t yy = 0; yy < height; ++yy)
  1003. {
  1004. for (uint32_t xx = 0; xx < width; ++xx)
  1005. {
  1006. decodeBlockDxt45A(temp+1, src);
  1007. src += 8;
  1008. decodeBlockDxt45A(temp+2, src);
  1009. src += 8;
  1010. for (uint32_t ii = 0; ii < 16; ++ii)
  1011. {
  1012. float nx = temp[ii*4+2]*2.0f/255.0f - 1.0f;
  1013. float ny = temp[ii*4+1]*2.0f/255.0f - 1.0f;
  1014. float nz = sqrtf(1.0f - nx*nx - ny*ny);
  1015. temp[ii*4+0] = uint8_t( (nz + 1.0f)*255.0f/2.0f);
  1016. temp[ii*4+3] = 0;
  1017. }
  1018. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  1019. memcpy(&dst[0*pitch], &temp[ 0], 16);
  1020. memcpy(&dst[1*pitch], &temp[16], 16);
  1021. memcpy(&dst[2*pitch], &temp[32], 16);
  1022. memcpy(&dst[3*pitch], &temp[48], 16);
  1023. }
  1024. }
  1025. break;
  1026. case TextureFormat::ETC1:
  1027. for (uint32_t yy = 0; yy < height; ++yy)
  1028. {
  1029. for (uint32_t xx = 0; xx < width; ++xx)
  1030. {
  1031. decodeBlockEtc1(temp, src);
  1032. src += 8;
  1033. uint8_t* dst = &_dst[(yy*pitch+xx*4)*4];
  1034. memcpy(&dst[0*pitch], &temp[ 0], 16);
  1035. memcpy(&dst[1*pitch], &temp[16], 16);
  1036. memcpy(&dst[2*pitch], &temp[32], 16);
  1037. memcpy(&dst[3*pitch], &temp[48], 16);
  1038. }
  1039. }
  1040. break;
  1041. default:
  1042. // Decompression not implemented... Make ugly red-yellow checkerboard texture.
  1043. imageCheckerboard(_width, _height, 16, UINT32_C(0xffff0000), UINT32_C(0xffffff00), _dst);
  1044. break;
  1045. }
  1046. }
  1047. bool imageGetRawData(const ImageContainer& _imageContainer, uint8_t _side, uint8_t _lod, const void* _data, uint32_t _size, ImageMip& _mip)
  1048. {
  1049. const uint32_t blockSize = _imageContainer.m_blockSize;
  1050. uint32_t offset = _imageContainer.m_offset;
  1051. const uint8_t bpp = _imageContainer.m_bpp;
  1052. TextureFormat::Enum type = TextureFormat::Enum(_imageContainer.m_format);
  1053. bool hasAlpha = _imageContainer.m_hasAlpha;
  1054. if (UINT32_MAX == _imageContainer.m_offset)
  1055. {
  1056. if (NULL == _imageContainer.m_data)
  1057. {
  1058. return false;
  1059. }
  1060. offset = 0;
  1061. _data = _imageContainer.m_data;
  1062. _size = _imageContainer.m_size;
  1063. }
  1064. for (uint8_t side = 0, numSides = _imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
  1065. {
  1066. uint32_t width = _imageContainer.m_width;
  1067. uint32_t height = _imageContainer.m_height;
  1068. uint32_t depth = _imageContainer.m_depth;
  1069. for (uint8_t lod = 0, num = _imageContainer.m_numMips; lod < num; ++lod)
  1070. {
  1071. // skip imageSize in KTX format.
  1072. offset += _imageContainer.m_ktx ? sizeof(uint32_t) : 0;
  1073. width = bx::uint32_max(1, width);
  1074. height = bx::uint32_max(1, height);
  1075. depth = bx::uint32_max(1, depth);
  1076. uint32_t size = width*height*depth*blockSize;
  1077. if (TextureFormat::Unknown > type)
  1078. {
  1079. width = bx::uint32_max(1, (width + 3)>>2);
  1080. height = bx::uint32_max(1, (height + 3)>>2);
  1081. size = width*height*depth*blockSize;
  1082. width <<= 2;
  1083. height <<= 2;
  1084. }
  1085. if (side == _side
  1086. && lod == _lod)
  1087. {
  1088. _mip.m_width = width;
  1089. _mip.m_height = height;
  1090. _mip.m_blockSize = blockSize;
  1091. _mip.m_size = size;
  1092. _mip.m_data = (const uint8_t*)_data + offset;
  1093. _mip.m_bpp = bpp;
  1094. _mip.m_format = type;
  1095. _mip.m_hasAlpha = hasAlpha;
  1096. return true;
  1097. }
  1098. offset += size;
  1099. BX_CHECK(offset <= _size, "Reading past size of data buffer! (offset %d, size %d)", offset, _size);
  1100. BX_UNUSED(_size);
  1101. width >>= 1;
  1102. height >>= 1;
  1103. depth >>= 1;
  1104. }
  1105. }
  1106. return false;
  1107. }
  1108. } // namespace bgfx