image.cpp 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
  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 _srcPitch, 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 = _srcPitch*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[_srcPitch+0], 2.2f);
  87. gg += powf(rgba[_srcPitch+1], 2.2f);
  88. bb += powf(rgba[_srcPitch+2], 2.2f);
  89. aa += rgba[_srcPitch+3];
  90. rr += powf(rgba[_srcPitch+4], 2.2f);
  91. gg += powf(rgba[_srcPitch+5], 2.2f);
  92. bb += powf(rgba[_srcPitch+6], 2.2f);
  93. aa += rgba[_srcPitch+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 _srcPitch, 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 = _srcPitch*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+_srcPitch);
  137. const float4_t abgr3 = float4_splat(rgba+_srcPitch+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, uint32_t _srcPitch, const void* _src, void* _dst)
  180. {
  181. const uint8_t* src = (uint8_t*) _src;
  182. const uint8_t* next = src + _srcPitch;
  183. uint8_t* dst = (uint8_t*)_dst;
  184. for (uint32_t yy = 0; yy < _height; ++yy, src = next, next += _srcPitch)
  185. {
  186. for (uint32_t xx = 0; xx < _width; ++xx, src += 4, dst += 4)
  187. {
  188. uint8_t rr = src[0];
  189. uint8_t gg = src[1];
  190. uint8_t bb = src[2];
  191. uint8_t aa = src[3];
  192. dst[0] = bb;
  193. dst[1] = gg;
  194. dst[2] = rr;
  195. dst[3] = aa;
  196. }
  197. }
  198. }
  199. void imageSwizzleBgra8(uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, void* _dst)
  200. {
  201. // Test can we do four 4-byte pixels at the time.
  202. if (0 != (_width&0x3)
  203. || _width < 4
  204. || !bx::isPtrAligned(_src, 16)
  205. || !bx::isPtrAligned(_dst, 16) )
  206. {
  207. BX_WARN(false, "Image swizzle is taking slow path.");
  208. BX_WARN(bx::isPtrAligned(_src, 16), "Source %p is not 16-byte aligned.", _src);
  209. BX_WARN(bx::isPtrAligned(_dst, 16), "Destination %p is not 16-byte aligned.", _dst);
  210. BX_WARN(_width < 4, "Image width must be multiple of 4 (width %d).", _width);
  211. imageSwizzleBgra8Ref(_width, _height, _srcPitch, _src, _dst);
  212. return;
  213. }
  214. using namespace bx;
  215. const float4_t mf0f0 = float4_isplat(0xff00ff00);
  216. const float4_t m0f0f = float4_isplat(0x00ff00ff);
  217. const uint8_t* src = (uint8_t*) _src;
  218. const uint8_t* next = src + _srcPitch;
  219. uint8_t* dst = (uint8_t*)_dst;
  220. const uint32_t width = _width/4;
  221. for (uint32_t yy = 0; yy < _height; ++yy, src = next, next += _srcPitch)
  222. {
  223. for (uint32_t xx = 0; xx < width; ++xx, src += 16, dst += 16)
  224. {
  225. const float4_t tabgr = float4_ld(src);
  226. const float4_t t00ab = float4_srl(tabgr, 16);
  227. const float4_t tgr00 = float4_sll(tabgr, 16);
  228. const float4_t tgrab = float4_or(t00ab, tgr00);
  229. const float4_t ta0g0 = float4_and(tabgr, mf0f0);
  230. const float4_t t0r0b = float4_and(tgrab, m0f0f);
  231. const float4_t targb = float4_or(ta0g0, t0r0b);
  232. float4_st(dst, targb);
  233. }
  234. }
  235. }
  236. void imageCopy(uint32_t _width, uint32_t _height, uint32_t _bpp, uint32_t _srcPitch, const void* _src, void* _dst)
  237. {
  238. const uint32_t pitch = _width*_bpp/8;
  239. const uint8_t* src = (uint8_t*) _src;
  240. const uint8_t* next = src + _srcPitch;
  241. uint8_t* dst = (uint8_t*)_dst;
  242. for (uint32_t yy = 0; yy < _height; ++yy, src = next, next += _srcPitch)
  243. {
  244. memcpy(dst, src, pitch);
  245. }
  246. }
  247. void imageWriteTga(bx::WriterI* _writer, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bool _grayscale, bool _yflip)
  248. {
  249. uint8_t type = _grayscale ? 3 : 2;
  250. uint8_t bpp = _grayscale ? 8 : 32;
  251. uint8_t header[18] = {};
  252. header[2] = type;
  253. header[12] = _width&0xff;
  254. header[13] = (_width>>8)&0xff;
  255. header[14] = _height&0xff;
  256. header[15] = (_height>>8)&0xff;
  257. header[16] = bpp;
  258. header[17] = 32;
  259. bx::write(_writer, header, sizeof(header) );
  260. uint32_t dstPitch = _width*bpp/8;
  261. if (_yflip)
  262. {
  263. uint8_t* data = (uint8_t*)_src + _srcPitch*_height - _srcPitch;
  264. for (uint32_t yy = 0; yy < _height; ++yy)
  265. {
  266. bx::write(_writer, data, dstPitch);
  267. data -= _srcPitch;
  268. }
  269. }
  270. else if (_srcPitch == dstPitch)
  271. {
  272. bx::write(_writer, _src, _height*_srcPitch);
  273. }
  274. else
  275. {
  276. uint8_t* data = (uint8_t*)_src;
  277. for (uint32_t yy = 0; yy < _height; ++yy)
  278. {
  279. bx::write(_writer, data, dstPitch);
  280. data += _srcPitch;
  281. }
  282. }
  283. }
  284. uint32_t bitRangeConvert(uint32_t _in, uint32_t _from, uint32_t _to)
  285. {
  286. using namespace bx;
  287. uint32_t tmp0 = uint32_sll(1, _to);
  288. uint32_t tmp1 = uint32_sll(1, _from);
  289. uint32_t tmp2 = uint32_dec(tmp0);
  290. uint32_t tmp3 = uint32_dec(tmp1);
  291. uint32_t tmp4 = uint32_mul(_in, tmp2);
  292. uint32_t tmp5 = uint32_add(tmp3, tmp4);
  293. uint32_t tmp6 = uint32_srl(tmp5, _from);
  294. uint32_t tmp7 = uint32_add(tmp5, tmp6);
  295. uint32_t result = uint32_srl(tmp7, _from);
  296. return result;
  297. }
  298. void decodeBlockDxt(uint8_t _dst[16*4], const uint8_t _src[8])
  299. {
  300. uint8_t colors[4*3];
  301. uint32_t c0 = _src[0] | (_src[1] << 8);
  302. colors[0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
  303. colors[1] = bitRangeConvert( (c0>> 5)&0x3f, 6, 8);
  304. colors[2] = bitRangeConvert( (c0>>11)&0x1f, 5, 8);
  305. uint32_t c1 = _src[2] | (_src[3] << 8);
  306. colors[3] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
  307. colors[4] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
  308. colors[5] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
  309. colors[6] = (2*colors[0] + colors[3]) / 3;
  310. colors[7] = (2*colors[1] + colors[4]) / 3;
  311. colors[8] = (2*colors[2] + colors[5]) / 3;
  312. colors[ 9] = (colors[0] + 2*colors[3]) / 3;
  313. colors[10] = (colors[1] + 2*colors[4]) / 3;
  314. colors[11] = (colors[2] + 2*colors[5]) / 3;
  315. for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
  316. {
  317. int idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 3;
  318. _dst[ii+0] = colors[idx+0];
  319. _dst[ii+1] = colors[idx+1];
  320. _dst[ii+2] = colors[idx+2];
  321. }
  322. }
  323. void decodeBlockDxt1(uint8_t _dst[16*4], const uint8_t _src[8])
  324. {
  325. uint8_t colors[4*4];
  326. uint32_t c0 = _src[0] | (_src[1] << 8);
  327. colors[0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
  328. colors[1] = bitRangeConvert( (c0>> 5)&0x3f, 6, 8);
  329. colors[2] = bitRangeConvert( (c0>>11)&0x1f, 5, 8);
  330. colors[3] = 255;
  331. uint32_t c1 = _src[2] | (_src[3] << 8);
  332. colors[4] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
  333. colors[5] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
  334. colors[6] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
  335. colors[7] = 255;
  336. if (c0 > c1)
  337. {
  338. colors[ 8] = (2*colors[0] + colors[4]) / 3;
  339. colors[ 9] = (2*colors[1] + colors[5]) / 3;
  340. colors[10] = (2*colors[2] + colors[6]) / 3;
  341. colors[11] = 255;
  342. colors[12] = (colors[0] + 2*colors[4]) / 3;
  343. colors[13] = (colors[1] + 2*colors[5]) / 3;
  344. colors[14] = (colors[2] + 2*colors[6]) / 3;
  345. colors[15] = 255;
  346. }
  347. else
  348. {
  349. colors[ 8] = (colors[0] + colors[4]) / 2;
  350. colors[ 9] = (colors[1] + colors[5]) / 2;
  351. colors[10] = (colors[2] + colors[6]) / 2;
  352. colors[11] = 255;
  353. colors[12] = 0;
  354. colors[13] = 0;
  355. colors[14] = 0;
  356. colors[15] = 0;
  357. }
  358. for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
  359. {
  360. int idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 4;
  361. _dst[ii+0] = colors[idx+0];
  362. _dst[ii+1] = colors[idx+1];
  363. _dst[ii+2] = colors[idx+2];
  364. _dst[ii+3] = colors[idx+3];
  365. }
  366. }
  367. void decodeBlockDxt23A(uint8_t _dst[16*4], const uint8_t _src[8])
  368. {
  369. for (uint32_t ii = 0, next = 0; ii < 16*4; ii += 4, next += 4)
  370. {
  371. uint32_t c0 = (_src[next>>3] >> (next&7) ) & 0xf;
  372. _dst[ii] = bitRangeConvert(c0, 4, 8);
  373. }
  374. }
  375. void decodeBlockDxt45A(uint8_t _dst[16*4], const uint8_t _src[8])
  376. {
  377. uint8_t alpha[8];
  378. alpha[0] = _src[0];
  379. alpha[1] = _src[1];
  380. if (alpha[0] > alpha[1])
  381. {
  382. alpha[2] = (6*alpha[0] + 1*alpha[1]) / 7;
  383. alpha[3] = (5*alpha[0] + 2*alpha[1]) / 7;
  384. alpha[4] = (4*alpha[0] + 3*alpha[1]) / 7;
  385. alpha[5] = (3*alpha[0] + 4*alpha[1]) / 7;
  386. alpha[6] = (2*alpha[0] + 5*alpha[1]) / 7;
  387. alpha[7] = (1*alpha[0] + 6*alpha[1]) / 7;
  388. }
  389. else
  390. {
  391. alpha[2] = (4*alpha[0] + 1*alpha[1]) / 5;
  392. alpha[3] = (3*alpha[0] + 2*alpha[1]) / 5;
  393. alpha[4] = (2*alpha[0] + 3*alpha[1]) / 5;
  394. alpha[5] = (1*alpha[0] + 4*alpha[1]) / 5;
  395. alpha[6] = 0;
  396. alpha[7] = 255;
  397. }
  398. uint32_t idx0 = _src[2];
  399. uint32_t idx1 = _src[5];
  400. idx0 |= uint32_t(_src[3])<<8;
  401. idx1 |= uint32_t(_src[6])<<8;
  402. idx0 |= uint32_t(_src[4])<<16;
  403. idx1 |= uint32_t(_src[7])<<16;
  404. for (uint32_t ii = 0; ii < 8*4; ii += 4)
  405. {
  406. _dst[ii] = alpha[idx0&7];
  407. _dst[ii+32] = alpha[idx1&7];
  408. idx0 >>= 3;
  409. idx1 >>= 3;
  410. }
  411. }
  412. static const int32_t s_etc1Mod[8][4] =
  413. {
  414. { 2, 8, -2, -8},
  415. { 5, 17, -5, -17},
  416. { 9, 29, -9, -29},
  417. { 13, 42, -13, -42},
  418. { 18, 60, -18, -60},
  419. { 24, 80, -24, -80},
  420. { 33, 106, -33, -106},
  421. { 47, 183, -47, -183},
  422. };
  423. static const uint8_t s_etc2Mod[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
  424. uint8_t uint8_sat(int32_t _a)
  425. {
  426. using namespace bx;
  427. const uint32_t min = uint32_imin(_a, 255);
  428. const uint32_t result = uint32_imax(min, 0);
  429. return (uint8_t)result;
  430. }
  431. uint8_t uint8_satadd(int32_t _a, int32_t _b)
  432. {
  433. const int32_t add = _a + _b;
  434. return uint8_sat(add);
  435. }
  436. void decodeBlockEtc2ModeT(uint8_t _dst[16*4], const uint8_t _src[8])
  437. {
  438. uint8_t rgb[16];
  439. // 0 1 2 3 4 5 6 7
  440. // 7654321076543210765432107654321076543210765432107654321076543210
  441. // ...rr.rrggggbbbbrrrrggggbbbbDDD.mmmmmmmmmmmmmmmmllllllllllllllll
  442. // ^ ^ ^ ^ ^
  443. // +-- c0 +-- c1 | +-- msb +-- lsb
  444. // +-- dist
  445. rgb[ 0] = ( (_src[0] >> 1) & 0xc)
  446. | (_src[0] & 0x3)
  447. ;
  448. rgb[ 1] = _src[1] >> 4;
  449. rgb[ 2] = _src[1] & 0xf;
  450. rgb[ 8] = _src[2] >> 4;
  451. rgb[ 9] = _src[2] & 0xf;
  452. rgb[10] = _src[3] >> 4;
  453. rgb[ 0] = bitRangeConvert(rgb[ 0], 4, 8);
  454. rgb[ 1] = bitRangeConvert(rgb[ 1], 4, 8);
  455. rgb[ 2] = bitRangeConvert(rgb[ 2], 4, 8);
  456. rgb[ 8] = bitRangeConvert(rgb[ 8], 4, 8);
  457. rgb[ 9] = bitRangeConvert(rgb[ 9], 4, 8);
  458. rgb[10] = bitRangeConvert(rgb[10], 4, 8);
  459. uint8_t dist = (_src[3] >> 1) & 0x7;
  460. int32_t mod = s_etc2Mod[dist];
  461. rgb[ 4] = uint8_satadd(rgb[ 8], mod);
  462. rgb[ 5] = uint8_satadd(rgb[ 9], mod);
  463. rgb[ 6] = uint8_satadd(rgb[10], mod);
  464. rgb[12] = uint8_satadd(rgb[ 8], -mod);
  465. rgb[13] = uint8_satadd(rgb[ 9], -mod);
  466. rgb[14] = uint8_satadd(rgb[10], -mod);
  467. uint32_t indexMsb = (_src[4]<<8) | _src[5];
  468. uint32_t indexLsb = (_src[6]<<8) | _src[7];
  469. for (uint32_t ii = 0; ii < 16; ++ii)
  470. {
  471. const uint32_t idx = (ii&0xc) | ( (ii & 0x3)<<4);
  472. const uint32_t lsbi = indexLsb & 1;
  473. const uint32_t msbi = (indexMsb & 1)<<1;
  474. const uint32_t pal = (lsbi | msbi)<<2;
  475. _dst[idx + 0] = rgb[pal+2];
  476. _dst[idx + 1] = rgb[pal+1];
  477. _dst[idx + 2] = rgb[pal+0];
  478. _dst[idx + 3] = 255;
  479. indexLsb >>= 1;
  480. indexMsb >>= 1;
  481. }
  482. }
  483. void decodeBlockEtc2ModeH(uint8_t _dst[16*4], const uint8_t _src[8])
  484. {
  485. uint8_t rgb[16];
  486. // 0 1 2 3 4 5 6 7
  487. // 7654321076543210765432107654321076543210765432107654321076543210
  488. // .rrrrggg...gb.bbbrrrrggggbbbbDD.mmmmmmmmmmmmmmmmllllllllllllllll
  489. // ^ ^ ^ ^ ^
  490. // +-- c0 +-- c1 | +-- msb +-- lsb
  491. // +-- dist
  492. rgb[ 0] = (_src[0] >> 3) & 0xf;
  493. rgb[ 1] = ( (_src[0] << 1) & 0xe)
  494. | ( (_src[1] >> 4) & 0x1)
  495. ;
  496. rgb[ 2] = (_src[1] & 0x8)
  497. | ( (_src[1] << 1) & 0x6)
  498. | (_src[2] >> 7)
  499. ;
  500. rgb[ 8] = (_src[2] >> 3) & 0xf;
  501. rgb[ 9] = ( (_src[2] << 1) & 0xe)
  502. | (_src[3] >> 7)
  503. ;
  504. rgb[10] = (_src[2] >> 3) & 0xf;
  505. rgb[ 0] = bitRangeConvert(rgb[ 0], 4, 8);
  506. rgb[ 1] = bitRangeConvert(rgb[ 1], 4, 8);
  507. rgb[ 2] = bitRangeConvert(rgb[ 2], 4, 8);
  508. rgb[ 8] = bitRangeConvert(rgb[ 8], 4, 8);
  509. rgb[ 9] = bitRangeConvert(rgb[ 9], 4, 8);
  510. rgb[10] = bitRangeConvert(rgb[10], 4, 8);
  511. uint32_t col0 = uint32_t(rgb[0]<<16) | uint32_t(rgb[1]<<8) | uint32_t(rgb[ 2]);
  512. uint32_t col1 = uint32_t(rgb[8]<<16) | uint32_t(rgb[9]<<8) | uint32_t(rgb[10]);
  513. uint8_t dist = (_src[3] & 0x6) | (col0 >= col1);
  514. int32_t mod = s_etc2Mod[dist];
  515. rgb[ 4] = uint8_satadd(rgb[ 0], -mod);
  516. rgb[ 5] = uint8_satadd(rgb[ 1], -mod);
  517. rgb[ 6] = uint8_satadd(rgb[ 2], -mod);
  518. rgb[ 0] = uint8_satadd(rgb[ 0], mod);
  519. rgb[ 1] = uint8_satadd(rgb[ 1], mod);
  520. rgb[ 2] = uint8_satadd(rgb[ 2], mod);
  521. rgb[12] = uint8_satadd(rgb[ 8], -mod);
  522. rgb[13] = uint8_satadd(rgb[ 9], -mod);
  523. rgb[14] = uint8_satadd(rgb[10], -mod);
  524. rgb[ 8] = uint8_satadd(rgb[ 8], mod);
  525. rgb[ 9] = uint8_satadd(rgb[ 9], mod);
  526. rgb[10] = uint8_satadd(rgb[10], mod);
  527. uint32_t indexMsb = (_src[4]<<8) | _src[5];
  528. uint32_t indexLsb = (_src[6]<<8) | _src[7];
  529. for (uint32_t ii = 0; ii < 16; ++ii)
  530. {
  531. const uint32_t idx = (ii&0xc) | ( (ii & 0x3)<<4);
  532. const uint32_t lsbi = indexLsb & 1;
  533. const uint32_t msbi = (indexMsb & 1)<<1;
  534. const uint32_t pal = (lsbi | msbi)<<2;
  535. _dst[idx + 0] = rgb[pal+2];
  536. _dst[idx + 1] = rgb[pal+1];
  537. _dst[idx + 2] = rgb[pal+0];
  538. _dst[idx + 3] = 255;
  539. indexLsb >>= 1;
  540. indexMsb >>= 1;
  541. }
  542. }
  543. void decodeBlockEtc2ModePlanar(uint8_t _dst[16*4], const uint8_t _src[8])
  544. {
  545. // 0 1 2 3 4 5 6 7
  546. // 7654321076543210765432107654321076543210765432107654321076543210
  547. // .rrrrrrg.ggggggb...bb.bbbrrrrr.rgggggggbbbbbbrrrrrrgggggggbbbbbb
  548. // ^ ^ ^
  549. // +-- c0 +-- cH +-- cV
  550. uint8_t c0[3];
  551. uint8_t cH[3];
  552. uint8_t cV[3];
  553. c0[0] = (_src[0] >> 1) & 0x3f;
  554. c0[1] = ( (_src[0] & 1) << 6)
  555. | ( (_src[1] >> 1) & 0x3f)
  556. ;
  557. c0[2] = ( (_src[1] & 1) << 5)
  558. | ( (_src[2] & 0x18) )
  559. | ( (_src[2] << 1) & 6)
  560. | ( (_src[3] >> 7) )
  561. ;
  562. cH[0] = ( (_src[3] >> 1) & 0x3e)
  563. | (_src[3] & 1)
  564. ;
  565. cH[1] = _src[4] >> 1;
  566. cH[2] = ( (_src[4] & 1) << 5)
  567. | (_src[5] >> 3)
  568. ;
  569. cV[0] = ( (_src[5] & 0x7) << 3)
  570. | (_src[6] >> 5)
  571. ;
  572. cV[1] = ( (_src[6] & 0x1f) << 2)
  573. | (_src[7] >> 5)
  574. ;
  575. cV[2] = _src[7] & 0x3f;
  576. c0[0] = bitRangeConvert(c0[0], 6, 8);
  577. c0[1] = bitRangeConvert(c0[1], 7, 8);
  578. c0[2] = bitRangeConvert(c0[2], 6, 8);
  579. cH[0] = bitRangeConvert(cH[0], 6, 8);
  580. cH[1] = bitRangeConvert(cH[1], 7, 8);
  581. cH[2] = bitRangeConvert(cH[2], 6, 8);
  582. cV[0] = bitRangeConvert(cV[0], 6, 8);
  583. cV[1] = bitRangeConvert(cV[1], 7, 8);
  584. cV[2] = bitRangeConvert(cV[2], 6, 8);
  585. int16_t dy[3];
  586. dy[0] = cV[0] - c0[0];
  587. dy[1] = cV[1] - c0[1];
  588. dy[2] = cV[2] - c0[2];
  589. int16_t sx[3];
  590. sx[0] = int16_t(c0[0])<<2;
  591. sx[1] = int16_t(c0[1])<<2;
  592. sx[2] = int16_t(c0[2])<<2;
  593. int16_t ex[3];
  594. ex[0] = int16_t(cH[0])<<2;
  595. ex[1] = int16_t(cH[1])<<2;
  596. ex[2] = int16_t(cH[2])<<2;
  597. for (int32_t vv = 0; vv < 4; ++vv)
  598. {
  599. int16_t dx[3];
  600. dx[0] = (ex[0] - sx[0])>>2;
  601. dx[1] = (ex[1] - sx[1])>>2;
  602. dx[2] = (ex[2] - sx[2])>>2;
  603. for (int32_t hh = 0; hh < 4; ++hh)
  604. {
  605. const uint32_t idx = (vv<<4) + (hh<<2);
  606. _dst[idx + 0] = uint8_sat( (sx[2] + dx[2]*hh)>>2);
  607. _dst[idx + 1] = uint8_sat( (sx[1] + dx[1]*hh)>>2);
  608. _dst[idx + 2] = uint8_sat( (sx[0] + dx[0]*hh)>>2);
  609. _dst[idx + 3] = 255;
  610. }
  611. sx[0] += dy[0];
  612. sx[1] += dy[1];
  613. sx[2] += dy[2];
  614. ex[0] += dy[0];
  615. ex[1] += dy[1];
  616. ex[2] += dy[2];
  617. }
  618. }
  619. void decodeBlockEtc12(uint8_t _dst[16*4], const uint8_t _src[8])
  620. {
  621. bool flipBit = 0 != (_src[3] & 0x1);
  622. bool diffBit = 0 != (_src[3] & 0x2);
  623. uint8_t rgb[8];
  624. if (diffBit)
  625. {
  626. rgb[0] = _src[0] >> 3;
  627. rgb[1] = _src[1] >> 3;
  628. rgb[2] = _src[2] >> 3;
  629. int8_t diff[3];
  630. diff[0] = int8_t( (_src[0] & 0x7)<<5)>>5;
  631. diff[1] = int8_t( (_src[1] & 0x7)<<5)>>5;
  632. diff[2] = int8_t( (_src[2] & 0x7)<<5)>>5;
  633. int8_t rr = rgb[0] + diff[0];
  634. int8_t gg = rgb[1] + diff[1];
  635. int8_t bb = rgb[2] + diff[2];
  636. // Etc2 3-modes
  637. if (rr < 0 || rr > 31)
  638. {
  639. decodeBlockEtc2ModeT(_dst, _src);
  640. return;
  641. }
  642. if (gg < 0 || gg > 31)
  643. {
  644. decodeBlockEtc2ModeH(_dst, _src);
  645. return;
  646. }
  647. if (bb < 0 || bb > 31)
  648. {
  649. decodeBlockEtc2ModePlanar(_dst, _src);
  650. return;
  651. }
  652. // Etc1
  653. rgb[0] = bitRangeConvert(rgb[0], 5, 8);
  654. rgb[1] = bitRangeConvert(rgb[1], 5, 8);
  655. rgb[2] = bitRangeConvert(rgb[2], 5, 8);
  656. rgb[4] = bitRangeConvert(rr, 5, 8);
  657. rgb[5] = bitRangeConvert(gg, 5, 8);
  658. rgb[6] = bitRangeConvert(bb, 5, 8);
  659. }
  660. else
  661. {
  662. rgb[0] = _src[0] >> 4;
  663. rgb[1] = _src[1] >> 4;
  664. rgb[2] = _src[2] >> 4;
  665. rgb[4] = _src[0] & 0xf;
  666. rgb[5] = _src[1] & 0xf;
  667. rgb[6] = _src[2] & 0xf;
  668. rgb[0] = bitRangeConvert(rgb[0], 4, 8);
  669. rgb[1] = bitRangeConvert(rgb[1], 4, 8);
  670. rgb[2] = bitRangeConvert(rgb[2], 4, 8);
  671. rgb[4] = bitRangeConvert(rgb[4], 4, 8);
  672. rgb[5] = bitRangeConvert(rgb[5], 4, 8);
  673. rgb[6] = bitRangeConvert(rgb[6], 4, 8);
  674. }
  675. uint32_t table[2];
  676. table[0] = (_src[3] >> 5) & 0x7;
  677. table[1] = (_src[3] >> 2) & 0x7;
  678. uint32_t indexMsb = (_src[4]<<8) | _src[5];
  679. uint32_t indexLsb = (_src[6]<<8) | _src[7];
  680. if (flipBit)
  681. {
  682. for (uint32_t ii = 0; ii < 16; ++ii)
  683. {
  684. const uint32_t block = (ii>>1)&1;
  685. const uint32_t color = block<<2;
  686. const uint32_t idx = (ii&0xc) | ( (ii & 0x3)<<4);
  687. const uint32_t lsbi = indexLsb & 1;
  688. const uint32_t msbi = (indexMsb & 1)<<1;
  689. const int32_t mod = s_etc1Mod[table[block] ][lsbi | msbi];
  690. _dst[idx + 0] = uint8_satadd(rgb[color+2], mod);
  691. _dst[idx + 1] = uint8_satadd(rgb[color+1], mod);
  692. _dst[idx + 2] = uint8_satadd(rgb[color+0], mod);
  693. _dst[idx + 3] = 255;
  694. indexLsb >>= 1;
  695. indexMsb >>= 1;
  696. }
  697. }
  698. else
  699. {
  700. for (uint32_t ii = 0; ii < 16; ++ii)
  701. {
  702. const uint32_t block = ii>>3;
  703. const uint32_t color = block<<2;
  704. const uint32_t idx = (ii&0xc) | ( (ii & 0x3)<<4);
  705. const uint32_t lsbi = indexLsb & 1;
  706. const uint32_t msbi = (indexMsb & 1)<<1;
  707. const int32_t mod = s_etc1Mod[table[block] ][lsbi | msbi];
  708. _dst[idx + 0] = uint8_satadd(rgb[color+2], mod);
  709. _dst[idx + 1] = uint8_satadd(rgb[color+1], mod);
  710. _dst[idx + 2] = uint8_satadd(rgb[color+0], mod);
  711. _dst[idx + 3] = 255;
  712. indexLsb >>= 1;
  713. indexMsb >>= 1;
  714. }
  715. }
  716. }
  717. // DDS
  718. #define DDS_MAGIC BX_MAKEFOURCC('D', 'D', 'S', ' ')
  719. #define DDS_HEADER_SIZE 124
  720. #define DDS_IMAGE_DATA_OFFSET (DDS_HEADER_SIZE + 4)
  721. #define DDS_DXT1 BX_MAKEFOURCC('D', 'X', 'T', '1')
  722. #define DDS_DXT2 BX_MAKEFOURCC('D', 'X', 'T', '2')
  723. #define DDS_DXT3 BX_MAKEFOURCC('D', 'X', 'T', '3')
  724. #define DDS_DXT4 BX_MAKEFOURCC('D', 'X', 'T', '4')
  725. #define DDS_DXT5 BX_MAKEFOURCC('D', 'X', 'T', '5')
  726. #define DDS_ATI1 BX_MAKEFOURCC('A', 'T', 'I', '1')
  727. #define DDS_BC4U BX_MAKEFOURCC('B', 'C', '4', 'U')
  728. #define DDS_ATI2 BX_MAKEFOURCC('A', 'T', 'I', '2')
  729. #define DDS_BC5U BX_MAKEFOURCC('B', 'C', '5', 'U')
  730. #define D3DFMT_A16B16G16R16 36
  731. #define D3DFMT_A16B16G16R16F 113
  732. #define DDSD_CAPS 0x00000001
  733. #define DDSD_HEIGHT 0x00000002
  734. #define DDSD_WIDTH 0x00000004
  735. #define DDSD_PITCH 0x00000008
  736. #define DDSD_PIXELFORMAT 0x00001000
  737. #define DDSD_MIPMAPCOUNT 0x00020000
  738. #define DDSD_LINEARSIZE 0x00080000
  739. #define DDSD_DEPTH 0x00800000
  740. #define DDPF_ALPHAPIXELS 0x00000001
  741. #define DDPF_ALPHA 0x00000002
  742. #define DDPF_FOURCC 0x00000004
  743. #define DDPF_INDEXED 0x00000020
  744. #define DDPF_RGB 0x00000040
  745. #define DDPF_YUV 0x00000200
  746. #define DDPF_LUMINANCE 0x00020000
  747. #define DDSCAPS_COMPLEX 0x00000008
  748. #define DDSCAPS_TEXTURE 0x00001000
  749. #define DDSCAPS_MIPMAP 0x00400000
  750. #define DDSCAPS2_CUBEMAP 0x00000200
  751. #define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
  752. #define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
  753. #define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
  754. #define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
  755. #define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
  756. #define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
  757. #define DDS_CUBEMAP_ALLFACES (DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX \
  758. |DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY \
  759. |DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ)
  760. #define DDSCAPS2_VOLUME 0x00200000
  761. static struct TranslateDdsFormat
  762. {
  763. uint32_t m_format;
  764. TextureFormat::Enum m_textureFormat;
  765. } s_translateDdsFormat[] =
  766. {
  767. { DDS_DXT1, TextureFormat::BC1 },
  768. { DDS_DXT2, TextureFormat::BC2 },
  769. { DDS_DXT3, TextureFormat::BC2 },
  770. { DDS_DXT4, TextureFormat::BC3 },
  771. { DDS_DXT5, TextureFormat::BC3 },
  772. { DDS_ATI1, TextureFormat::BC4 },
  773. { DDS_BC4U, TextureFormat::BC4 },
  774. { DDS_ATI2, TextureFormat::BC5 },
  775. { DDS_BC5U, TextureFormat::BC5 },
  776. { D3DFMT_A16B16G16R16, TextureFormat::RGBA16 },
  777. { D3DFMT_A16B16G16R16F, TextureFormat::RGBA16F },
  778. { DDPF_RGB|DDPF_ALPHAPIXELS, TextureFormat::BGRA8 },
  779. { DDPF_INDEXED, TextureFormat::L8 },
  780. { DDPF_LUMINANCE, TextureFormat::L8 },
  781. { DDPF_ALPHA, TextureFormat::L8 },
  782. };
  783. bool imageParseDds(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
  784. {
  785. uint32_t headerSize;
  786. bx::read(_reader, headerSize);
  787. if (headerSize < DDS_HEADER_SIZE)
  788. {
  789. return false;
  790. }
  791. uint32_t flags;
  792. bx::read(_reader, flags);
  793. if ( (flags & (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT) ) != (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT) )
  794. {
  795. return false;
  796. }
  797. uint32_t height;
  798. bx::read(_reader, height);
  799. uint32_t width;
  800. bx::read(_reader, width);
  801. uint32_t pitch;
  802. bx::read(_reader, pitch);
  803. uint32_t depth;
  804. bx::read(_reader, depth);
  805. uint32_t mips;
  806. bx::read(_reader, mips);
  807. bx::skip(_reader, 44); // reserved
  808. bx::skip(_reader, 4); // pixel format size
  809. uint32_t pixelFlags;
  810. bx::read(_reader, pixelFlags);
  811. uint32_t fourcc;
  812. bx::read(_reader, fourcc);
  813. uint32_t rgbCount;
  814. bx::read(_reader, rgbCount);
  815. uint32_t rbitmask;
  816. bx::read(_reader, rbitmask);
  817. uint32_t gbitmask;
  818. bx::read(_reader, gbitmask);
  819. uint32_t bbitmask;
  820. bx::read(_reader, bbitmask);
  821. uint32_t abitmask;
  822. bx::read(_reader, abitmask);
  823. uint32_t caps[4];
  824. bx::read(_reader, caps);
  825. if ( (caps[0] & DDSCAPS_TEXTURE) == 0)
  826. {
  827. return false;
  828. }
  829. bool cubeMap = 0 != (caps[1] & DDSCAPS2_CUBEMAP);
  830. if (cubeMap)
  831. {
  832. if ( (caps[1] & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
  833. {
  834. // parital cube map is not supported.
  835. return false;
  836. }
  837. }
  838. bx::skip(_reader, 4); // reserved
  839. uint8_t bpp = 0;
  840. uint8_t blockSize = 1;
  841. TextureFormat::Enum format = TextureFormat::Unknown;
  842. bool hasAlpha = pixelFlags & DDPF_ALPHAPIXELS;
  843. uint32_t ddsFormat = pixelFlags & DDPF_FOURCC ? fourcc : pixelFlags;
  844. for (uint32_t ii = 0; ii < BX_COUNTOF(s_translateDdsFormat); ++ii)
  845. {
  846. if (s_translateDdsFormat[ii].m_format == ddsFormat)
  847. {
  848. format = s_translateDdsFormat[ii].m_textureFormat;
  849. break;
  850. }
  851. }
  852. bpp = getBitsPerPixel(format);
  853. blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
  854. blockSize = blockSize*bpp/8;
  855. _imageContainer.m_data = NULL;
  856. _imageContainer.m_size = 0;
  857. _imageContainer.m_offset = DDS_IMAGE_DATA_OFFSET;
  858. _imageContainer.m_width = width;
  859. _imageContainer.m_height = height;
  860. _imageContainer.m_depth = depth;
  861. _imageContainer.m_format = format;
  862. _imageContainer.m_blockSize = blockSize;
  863. _imageContainer.m_numMips = (caps[0] & DDSCAPS_MIPMAP) ? mips : 1;
  864. _imageContainer.m_bpp = bpp;
  865. _imageContainer.m_hasAlpha = hasAlpha;
  866. _imageContainer.m_cubeMap = cubeMap;
  867. _imageContainer.m_ktx = false;
  868. return TextureFormat::Unknown != format;
  869. }
  870. // KTX
  871. #define KTX_MAGIC BX_MAKEFOURCC(0xAB, 'K', 'T', 'X')
  872. #define KTX_HEADER_SIZE 64
  873. #define KTX_ETC1_RGB8_OES 0x8D64
  874. #define KTX_COMPRESSED_R11_EAC 0x9270
  875. #define KTX_COMPRESSED_SIGNED_R11_EAC 0x9271
  876. #define KTX_COMPRESSED_RG11_EAC 0x9272
  877. #define KTX_COMPRESSED_SIGNED_RG11_EAC 0x9273
  878. #define KTX_COMPRESSED_RGB8_ETC2 0x9274
  879. #define KTX_COMPRESSED_SRGB8_ETC2 0x9275
  880. #define KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
  881. #define KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
  882. #define KTX_COMPRESSED_RGBA8_ETC2_EAC 0x9278
  883. #define KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
  884. #define KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
  885. #define KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
  886. #define KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
  887. #define KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
  888. #define KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
  889. #define KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
  890. #define KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
  891. #define KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
  892. #define KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
  893. #define KTX_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
  894. #define KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
  895. #define KTX_RGBA16 0x805B
  896. #define KTX_RGBA16F 0x881A
  897. static struct TranslateKtxFormat
  898. {
  899. uint32_t m_format;
  900. TextureFormat::Enum m_textureFormat;
  901. } s_translateKtxFormat[] =
  902. {
  903. { KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT, TextureFormat::BC1 },
  904. { KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT, TextureFormat::BC2 },
  905. { KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT, TextureFormat::BC3 },
  906. { KTX_COMPRESSED_LUMINANCE_LATC1_EXT, TextureFormat::BC4 },
  907. { KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, TextureFormat::BC5 },
  908. { KTX_ETC1_RGB8_OES, TextureFormat::ETC1 },
  909. { KTX_COMPRESSED_RGB8_ETC2, TextureFormat::ETC2 },
  910. { KTX_COMPRESSED_RGBA8_ETC2_EAC, TextureFormat::ETC2A },
  911. { KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, TextureFormat::ETC2A1 },
  912. { KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, TextureFormat::PTC12 },
  913. { KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, TextureFormat::PTC12A },
  914. { KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, TextureFormat::PTC14 },
  915. { KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, TextureFormat::PTC14A },
  916. { KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, TextureFormat::PTC22 },
  917. { KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, TextureFormat::PTC24 },
  918. { KTX_RGBA16, TextureFormat::RGBA16 },
  919. { KTX_RGBA16F, TextureFormat::RGBA16F },
  920. { KTX_COMPRESSED_R11_EAC, TextureFormat::Unknown },
  921. { KTX_COMPRESSED_SIGNED_R11_EAC, TextureFormat::Unknown },
  922. { KTX_COMPRESSED_RG11_EAC, TextureFormat::Unknown },
  923. { KTX_COMPRESSED_SIGNED_RG11_EAC, TextureFormat::Unknown },
  924. { KTX_COMPRESSED_SRGB8_ETC2, TextureFormat::Unknown },
  925. { KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, TextureFormat::Unknown },
  926. { KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, TextureFormat::Unknown },
  927. };
  928. bool imageParseKtx(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
  929. {
  930. uint8_t identifier[8];
  931. bx::read(_reader, identifier);
  932. if (identifier[1] != '1'
  933. && identifier[2] != '1')
  934. {
  935. return false;
  936. }
  937. uint32_t endianness;
  938. bx::read(_reader, endianness);
  939. bool fromLittleEndian = 0x04030201 == endianness;
  940. uint32_t glType;
  941. bx::readHE(_reader, glType, fromLittleEndian);
  942. uint32_t glTypeSize;
  943. bx::readHE(_reader, glTypeSize, fromLittleEndian);
  944. uint32_t glFormat;
  945. bx::readHE(_reader, glFormat, fromLittleEndian);
  946. uint32_t glInternalFormat;
  947. bx::readHE(_reader, glInternalFormat, fromLittleEndian);
  948. uint32_t glBaseInternalFormat;
  949. bx::readHE(_reader, glBaseInternalFormat, fromLittleEndian);
  950. uint32_t width;
  951. bx::readHE(_reader, width, fromLittleEndian);
  952. uint32_t height;
  953. bx::readHE(_reader, height, fromLittleEndian);
  954. uint32_t depth;
  955. bx::readHE(_reader, depth, fromLittleEndian);
  956. uint32_t numberOfArrayElements;
  957. bx::readHE(_reader, numberOfArrayElements, fromLittleEndian);
  958. uint32_t numFaces;
  959. bx::readHE(_reader, numFaces, fromLittleEndian);
  960. uint32_t numMips;
  961. bx::readHE(_reader, numMips, fromLittleEndian);
  962. uint32_t metaDataSize;
  963. bx::readHE(_reader, metaDataSize, fromLittleEndian);
  964. // skip meta garbage...
  965. int64_t offset = bx::skip(_reader, metaDataSize);
  966. uint8_t bpp = 0;
  967. uint8_t blockSize = 1;
  968. TextureFormat::Enum format = TextureFormat::Unknown;
  969. bool hasAlpha = false;
  970. for (uint32_t ii = 0; ii < BX_COUNTOF(s_translateKtxFormat); ++ii)
  971. {
  972. if (s_translateKtxFormat[ii].m_format == glInternalFormat)
  973. {
  974. format = s_translateKtxFormat[ii].m_textureFormat;
  975. break;
  976. }
  977. }
  978. bpp = getBitsPerPixel(format);
  979. blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
  980. blockSize = blockSize*bpp/8;
  981. _imageContainer.m_data = NULL;
  982. _imageContainer.m_size = 0;
  983. _imageContainer.m_offset = (uint32_t)offset;
  984. _imageContainer.m_width = width;
  985. _imageContainer.m_height = height;
  986. _imageContainer.m_depth = depth;
  987. _imageContainer.m_format = format;
  988. _imageContainer.m_blockSize = blockSize;
  989. _imageContainer.m_numMips = numMips;
  990. _imageContainer.m_bpp = bpp;
  991. _imageContainer.m_hasAlpha = hasAlpha;
  992. _imageContainer.m_cubeMap = numFaces > 1;
  993. _imageContainer.m_ktx = true;
  994. return TextureFormat::Unknown != format;
  995. }
  996. // PVR3
  997. #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) )
  998. #define PVR3_MAGIC BX_MAKEFOURCC('P', 'V', 'R', 3)
  999. #define PVR3_HEADER_SIZE 52
  1000. #define PVR3_PVRTC1_2BPP_RGB 0
  1001. #define PVR3_PVRTC1_2BPP_RGBA 1
  1002. #define PVR3_PVRTC1_4BPP_RGB 2
  1003. #define PVR3_PVRTC1_4BPP_RGBA 3
  1004. #define PVR3_PVRTC2_2BPP_RGBA 4
  1005. #define PVR3_PVRTC2_4BPP_RGBA 5
  1006. #define PVR3_ETC1 6
  1007. #define PVR3_DXT1 7
  1008. #define PVR3_DXT2 8
  1009. #define PVR3_DXT3 9
  1010. #define PVR3_DXT4 10
  1011. #define PVR3_DXT5 11
  1012. #define PVR3_BC4 12
  1013. #define PVR3_BC5 13
  1014. #define PVR3_RGBA16 PVR3_MAKE8CC('r', 'g', 'b', 'a', 16, 16, 16, 16)
  1015. #define PVR3_CHANNEL_TYPE_ANY UINT32_MAX
  1016. #define PVR3_CHANNEL_TYPE_FLOAT UINT32_C(12)
  1017. static struct TranslatePvr3Format
  1018. {
  1019. uint64_t m_format;
  1020. uint32_t m_channelTypeMask;
  1021. TextureFormat::Enum m_textureFormat;
  1022. } s_translatePvr3Format[] =
  1023. {
  1024. { PVR3_PVRTC1_2BPP_RGB, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC12 },
  1025. { PVR3_PVRTC1_2BPP_RGBA, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC12A },
  1026. { PVR3_PVRTC1_4BPP_RGB, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC14 },
  1027. { PVR3_PVRTC1_4BPP_RGBA, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC14A },
  1028. { PVR3_PVRTC2_2BPP_RGBA, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC22 },
  1029. { PVR3_PVRTC2_4BPP_RGBA, PVR3_CHANNEL_TYPE_ANY, TextureFormat::PTC24 },
  1030. { PVR3_ETC1, PVR3_CHANNEL_TYPE_ANY, TextureFormat::ETC1 },
  1031. { PVR3_DXT1, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC1 },
  1032. { PVR3_DXT2, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC2 },
  1033. { PVR3_DXT3, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC2 },
  1034. { PVR3_DXT4, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC3 },
  1035. { PVR3_DXT5, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC3 },
  1036. { PVR3_BC4, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC4 },
  1037. { PVR3_BC5, PVR3_CHANNEL_TYPE_ANY, TextureFormat::BC5 },
  1038. { PVR3_RGBA16, PVR3_CHANNEL_TYPE_FLOAT, TextureFormat::RGBA16F },
  1039. { PVR3_RGBA16, PVR3_CHANNEL_TYPE_ANY, TextureFormat::RGBA16 },
  1040. };
  1041. bool imageParsePvr3(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
  1042. {
  1043. uint32_t flags;
  1044. bx::read(_reader, flags);
  1045. uint64_t pixelFormat;
  1046. bx::read(_reader, pixelFormat);
  1047. uint32_t colorSpace;
  1048. bx::read(_reader, colorSpace); // 0 - linearRGB, 1 - sRGB
  1049. uint32_t channelType;
  1050. bx::read(_reader, channelType);
  1051. uint32_t height;
  1052. bx::read(_reader, height);
  1053. uint32_t width;
  1054. bx::read(_reader, width);
  1055. uint32_t depth;
  1056. bx::read(_reader, depth);
  1057. uint32_t numSurfaces;
  1058. bx::read(_reader, numSurfaces);
  1059. uint32_t numFaces;
  1060. bx::read(_reader, numFaces);
  1061. uint32_t numMips;
  1062. bx::read(_reader, numMips);
  1063. uint32_t metaDataSize;
  1064. bx::read(_reader, metaDataSize);
  1065. // skip meta garbage...
  1066. int64_t offset = bx::skip(_reader, metaDataSize);
  1067. uint8_t bpp = 0;
  1068. uint8_t blockSize = 1;
  1069. TextureFormat::Enum format = TextureFormat::Unknown;
  1070. bool hasAlpha = false;
  1071. for (uint32_t ii = 0; ii < BX_COUNTOF(s_translatePvr3Format); ++ii)
  1072. {
  1073. if (s_translatePvr3Format[ii].m_format == pixelFormat
  1074. && channelType == (s_translatePvr3Format[ii].m_channelTypeMask & channelType) )
  1075. {
  1076. format = s_translatePvr3Format[ii].m_textureFormat;
  1077. break;
  1078. }
  1079. }
  1080. bpp = getBitsPerPixel(format);
  1081. blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
  1082. blockSize = blockSize*bpp/8;
  1083. _imageContainer.m_data = NULL;
  1084. _imageContainer.m_size = 0;
  1085. _imageContainer.m_offset = (uint32_t)offset;
  1086. _imageContainer.m_width = width;
  1087. _imageContainer.m_height = height;
  1088. _imageContainer.m_depth = depth;
  1089. _imageContainer.m_format = format;
  1090. _imageContainer.m_blockSize = blockSize;
  1091. _imageContainer.m_numMips = numMips;
  1092. _imageContainer.m_bpp = bpp;
  1093. _imageContainer.m_hasAlpha = hasAlpha;
  1094. _imageContainer.m_cubeMap = numFaces > 1;
  1095. _imageContainer.m_ktx = false;
  1096. return TextureFormat::Unknown != format;
  1097. }
  1098. bool imageParse(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
  1099. {
  1100. uint32_t magic;
  1101. bx::read(_reader, magic);
  1102. if (DDS_MAGIC == magic)
  1103. {
  1104. return imageParseDds(_imageContainer, _reader);
  1105. }
  1106. else if (KTX_MAGIC == magic)
  1107. {
  1108. return imageParseKtx(_imageContainer, _reader);
  1109. }
  1110. else if (PVR3_MAGIC == magic)
  1111. {
  1112. return imageParsePvr3(_imageContainer, _reader);
  1113. }
  1114. else if (BGFX_CHUNK_MAGIC_TEX == magic)
  1115. {
  1116. TextureCreate tc;
  1117. bx::read(_reader, tc);
  1118. uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(tc.m_format) );
  1119. uint32_t blockSize = tc.m_format < TextureFormat::Unknown ? 4*4 : 1;
  1120. blockSize = blockSize*bpp/8;
  1121. _imageContainer.m_format = tc.m_format;
  1122. _imageContainer.m_offset = UINT32_MAX;
  1123. if (NULL == tc.m_mem)
  1124. {
  1125. _imageContainer.m_data = NULL;
  1126. _imageContainer.m_size = 0;
  1127. }
  1128. else
  1129. {
  1130. _imageContainer.m_data = tc.m_mem->data;
  1131. _imageContainer.m_size = tc.m_mem->size;
  1132. }
  1133. _imageContainer.m_width = tc.m_width;
  1134. _imageContainer.m_height = tc.m_height;
  1135. _imageContainer.m_depth = tc.m_depth;
  1136. _imageContainer.m_blockSize = blockSize;
  1137. _imageContainer.m_numMips = tc.m_numMips;
  1138. _imageContainer.m_bpp = getBitsPerPixel(TextureFormat::Enum(tc.m_format) );
  1139. _imageContainer.m_hasAlpha = false;
  1140. _imageContainer.m_cubeMap = tc.m_cubeMap;
  1141. _imageContainer.m_ktx = false;
  1142. return true;
  1143. }
  1144. return false;
  1145. }
  1146. bool imageParse(ImageContainer& _imageContainer, const void* _data, uint32_t _size)
  1147. {
  1148. bx::MemoryReader reader(_data, _size);
  1149. return imageParse(_imageContainer, &reader);
  1150. }
  1151. void imageDecodeToBgra8(uint8_t* _dst, const uint8_t* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, uint8_t _type)
  1152. {
  1153. const uint8_t* src = _src;
  1154. uint32_t width = _width/4;
  1155. uint32_t height = _height/4;
  1156. uint8_t temp[16*4];
  1157. switch (_type)
  1158. {
  1159. case TextureFormat::BC1:
  1160. for (uint32_t yy = 0; yy < height; ++yy)
  1161. {
  1162. for (uint32_t xx = 0; xx < width; ++xx)
  1163. {
  1164. decodeBlockDxt1(temp, src);
  1165. src += 8;
  1166. uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
  1167. memcpy(&dst[0*_pitch], &temp[ 0], 16);
  1168. memcpy(&dst[1*_pitch], &temp[16], 16);
  1169. memcpy(&dst[2*_pitch], &temp[32], 16);
  1170. memcpy(&dst[3*_pitch], &temp[48], 16);
  1171. }
  1172. }
  1173. break;
  1174. case TextureFormat::BC2:
  1175. for (uint32_t yy = 0; yy < height; ++yy)
  1176. {
  1177. for (uint32_t xx = 0; xx < width; ++xx)
  1178. {
  1179. decodeBlockDxt23A(temp+3, src);
  1180. src += 8;
  1181. decodeBlockDxt(temp, src);
  1182. src += 8;
  1183. uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
  1184. memcpy(&dst[0*_pitch], &temp[ 0], 16);
  1185. memcpy(&dst[1*_pitch], &temp[16], 16);
  1186. memcpy(&dst[2*_pitch], &temp[32], 16);
  1187. memcpy(&dst[3*_pitch], &temp[48], 16);
  1188. }
  1189. }
  1190. break;
  1191. case TextureFormat::BC3:
  1192. for (uint32_t yy = 0; yy < height; ++yy)
  1193. {
  1194. for (uint32_t xx = 0; xx < width; ++xx)
  1195. {
  1196. decodeBlockDxt45A(temp+3, src);
  1197. src += 8;
  1198. decodeBlockDxt(temp, src);
  1199. src += 8;
  1200. uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
  1201. memcpy(&dst[0*_pitch], &temp[ 0], 16);
  1202. memcpy(&dst[1*_pitch], &temp[16], 16);
  1203. memcpy(&dst[2*_pitch], &temp[32], 16);
  1204. memcpy(&dst[3*_pitch], &temp[48], 16);
  1205. }
  1206. }
  1207. break;
  1208. case TextureFormat::BC4:
  1209. for (uint32_t yy = 0; yy < height; ++yy)
  1210. {
  1211. for (uint32_t xx = 0; xx < width; ++xx)
  1212. {
  1213. decodeBlockDxt45A(temp, src);
  1214. src += 8;
  1215. uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
  1216. memcpy(&dst[0*_pitch], &temp[ 0], 16);
  1217. memcpy(&dst[1*_pitch], &temp[16], 16);
  1218. memcpy(&dst[2*_pitch], &temp[32], 16);
  1219. memcpy(&dst[3*_pitch], &temp[48], 16);
  1220. }
  1221. }
  1222. break;
  1223. case TextureFormat::BC5:
  1224. for (uint32_t yy = 0; yy < height; ++yy)
  1225. {
  1226. for (uint32_t xx = 0; xx < width; ++xx)
  1227. {
  1228. decodeBlockDxt45A(temp+1, src);
  1229. src += 8;
  1230. decodeBlockDxt45A(temp+2, src);
  1231. src += 8;
  1232. for (uint32_t ii = 0; ii < 16; ++ii)
  1233. {
  1234. float nx = temp[ii*4+2]*2.0f/255.0f - 1.0f;
  1235. float ny = temp[ii*4+1]*2.0f/255.0f - 1.0f;
  1236. float nz = sqrtf(1.0f - nx*nx - ny*ny);
  1237. temp[ii*4+0] = uint8_t( (nz + 1.0f)*255.0f/2.0f);
  1238. temp[ii*4+3] = 0;
  1239. }
  1240. uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
  1241. memcpy(&dst[0*_pitch], &temp[ 0], 16);
  1242. memcpy(&dst[1*_pitch], &temp[16], 16);
  1243. memcpy(&dst[2*_pitch], &temp[32], 16);
  1244. memcpy(&dst[3*_pitch], &temp[48], 16);
  1245. }
  1246. }
  1247. break;
  1248. case TextureFormat::ETC1:
  1249. case TextureFormat::ETC2:
  1250. for (uint32_t yy = 0; yy < height; ++yy)
  1251. {
  1252. for (uint32_t xx = 0; xx < width; ++xx)
  1253. {
  1254. decodeBlockEtc12(temp, src);
  1255. src += 8;
  1256. uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
  1257. memcpy(&dst[0*_pitch], &temp[ 0], 16);
  1258. memcpy(&dst[1*_pitch], &temp[16], 16);
  1259. memcpy(&dst[2*_pitch], &temp[32], 16);
  1260. memcpy(&dst[3*_pitch], &temp[48], 16);
  1261. }
  1262. }
  1263. break;
  1264. case TextureFormat::ETC2A:
  1265. BX_WARN(false, "ETC2A decoder is not implemented.");
  1266. imageCheckerboard(_width, _height, 16, UINT32_C(0xff000000), UINT32_C(0xff00ff00), _dst);
  1267. break;
  1268. case TextureFormat::ETC2A1:
  1269. BX_WARN(false, "ETC2A1 decoder is not implemented.");
  1270. imageCheckerboard(_width, _height, 16, UINT32_C(0xff000000), UINT32_C(0xffff0000), _dst);
  1271. break;
  1272. case TextureFormat::PTC12:
  1273. BX_WARN(false, "PTC12 decoder is not implemented.");
  1274. imageCheckerboard(_width, _height, 16, UINT32_C(0xff000000), UINT32_C(0xffff00ff), _dst);
  1275. break;
  1276. case TextureFormat::PTC12A:
  1277. BX_WARN(false, "PTC12A decoder is not implemented.");
  1278. imageCheckerboard(_width, _height, 16, UINT32_C(0xff000000), UINT32_C(0xffffff00), _dst);
  1279. break;
  1280. case TextureFormat::PTC14:
  1281. BX_WARN(false, "PTC14 decoder is not implemented.");
  1282. imageCheckerboard(_width, _height, 16, UINT32_C(0xff000000), UINT32_C(0xff00ffff), _dst);
  1283. break;
  1284. case TextureFormat::PTC14A:
  1285. BX_WARN(false, "PTC14A decoder is not implemented.");
  1286. imageCheckerboard(_width, _height, 16, UINT32_C(0xffff0000), UINT32_C(0xff0000ff), _dst);
  1287. break;
  1288. case TextureFormat::PTC22:
  1289. BX_WARN(false, "PTC22 decoder is not implemented.");
  1290. imageCheckerboard(_width, _height, 16, UINT32_C(0xff00ff00), UINT32_C(0xff0000ff), _dst);
  1291. break;
  1292. case TextureFormat::PTC24:
  1293. BX_WARN(false, "PTC24 decoder is not implemented.");
  1294. imageCheckerboard(_width, _height, 16, UINT32_C(0xff000000), UINT32_C(0xffffffff), _dst);
  1295. break;
  1296. default:
  1297. // Decompression not implemented... Make ugly red-yellow checkerboard texture.
  1298. imageCheckerboard(_width, _height, 16, UINT32_C(0xffff0000), UINT32_C(0xffffff00), _dst);
  1299. break;
  1300. }
  1301. }
  1302. bool imageGetRawData(const ImageContainer& _imageContainer, uint8_t _side, uint8_t _lod, const void* _data, uint32_t _size, ImageMip& _mip)
  1303. {
  1304. const uint32_t blockSize = _imageContainer.m_blockSize;
  1305. uint32_t offset = _imageContainer.m_offset;
  1306. const uint8_t bpp = _imageContainer.m_bpp;
  1307. TextureFormat::Enum type = TextureFormat::Enum(_imageContainer.m_format);
  1308. bool hasAlpha = _imageContainer.m_hasAlpha;
  1309. if (UINT32_MAX == _imageContainer.m_offset)
  1310. {
  1311. if (NULL == _imageContainer.m_data)
  1312. {
  1313. return false;
  1314. }
  1315. offset = 0;
  1316. _data = _imageContainer.m_data;
  1317. _size = _imageContainer.m_size;
  1318. }
  1319. for (uint8_t side = 0, numSides = _imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
  1320. {
  1321. uint32_t width = _imageContainer.m_width;
  1322. uint32_t height = _imageContainer.m_height;
  1323. uint32_t depth = _imageContainer.m_depth;
  1324. for (uint8_t lod = 0, num = _imageContainer.m_numMips; lod < num; ++lod)
  1325. {
  1326. // skip imageSize in KTX format.
  1327. offset += _imageContainer.m_ktx ? sizeof(uint32_t) : 0;
  1328. width = bx::uint32_max(1, width);
  1329. height = bx::uint32_max(1, height);
  1330. depth = bx::uint32_max(1, depth);
  1331. uint32_t size = width*height*depth*blockSize;
  1332. if (TextureFormat::Unknown > type)
  1333. {
  1334. width = bx::uint32_max(1, (width + 3)>>2);
  1335. height = bx::uint32_max(1, (height + 3)>>2);
  1336. size = width*height*depth*blockSize;
  1337. width <<= 2;
  1338. height <<= 2;
  1339. }
  1340. if (side == _side
  1341. && lod == _lod)
  1342. {
  1343. _mip.m_width = width;
  1344. _mip.m_height = height;
  1345. _mip.m_blockSize = blockSize;
  1346. _mip.m_size = size;
  1347. _mip.m_data = (const uint8_t*)_data + offset;
  1348. _mip.m_bpp = bpp;
  1349. _mip.m_format = type;
  1350. _mip.m_hasAlpha = hasAlpha;
  1351. return true;
  1352. }
  1353. offset += size;
  1354. BX_CHECK(offset <= _size, "Reading past size of data buffer! (offset %d, size %d)", offset, _size);
  1355. BX_UNUSED(_size);
  1356. width >>= 1;
  1357. height >>= 1;
  1358. depth >>= 1;
  1359. }
  1360. }
  1361. return false;
  1362. }
  1363. } // namespace bgfx