texturec.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * Copyright 2011-2015 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. // Just hacking DDS loading code in here.
  9. #include "bgfx_p.h"
  10. #include "image.h"
  11. #include <libsquish/squish.h>
  12. #include <etc1/etc1.h>
  13. #include <nvtt/nvtt.h>
  14. #include <pvrtc/PvrTcEncoder.h>
  15. #include <tinyexr/tinyexr.h>
  16. #if 0
  17. # define BX_TRACE(_format, ...) fprintf(stderr, "" _format "\n", ##__VA_ARGS__)
  18. #endif // DEBUG
  19. #include <bx/bx.h>
  20. #include <bx/allocator.h>
  21. #include <bx/commandline.h>
  22. #include <bx/uint32_t.h>
  23. namespace bgfx
  24. {
  25. const Memory* alloc(uint32_t _size)
  26. {
  27. Memory* mem = (Memory*)::realloc(NULL, sizeof(Memory) + _size);
  28. mem->size = _size;
  29. mem->data = (uint8_t*)mem + sizeof(Memory);
  30. return mem;
  31. }
  32. void release(const Memory* _mem)
  33. {
  34. Memory* mem = const_cast<Memory*>(_mem);
  35. ::free(mem);
  36. }
  37. void imageEncodeFromRgba8(uint8_t* _dst, const uint8_t* _src, uint32_t _width, uint32_t _height, uint8_t _format)
  38. {
  39. TextureFormat::Enum format = TextureFormat::Enum(_format);
  40. switch (format)
  41. {
  42. case TextureFormat::BC1:
  43. case TextureFormat::BC2:
  44. case TextureFormat::BC3:
  45. case TextureFormat::BC4:
  46. case TextureFormat::BC5:
  47. squish::CompressImage(_src, _width, _height, _dst
  48. , format == TextureFormat::BC1 ? squish::kDxt1
  49. : format == TextureFormat::BC2 ? squish::kDxt3
  50. : format == TextureFormat::BC3 ? squish::kDxt5
  51. : format == TextureFormat::BC4 ? squish::kBc4
  52. : squish::kBc5
  53. );
  54. break;
  55. case TextureFormat::BC6H:
  56. nvtt::compressBC6H(_src, _width, _height, 4, _dst);
  57. break;
  58. case TextureFormat::BC7:
  59. nvtt::compressBC7(_src, _width, _height, 4, _dst);
  60. break;
  61. case TextureFormat::ETC1:
  62. etc1_encode_image(_src, _width, _height, 4, _width*4, _dst);
  63. break;
  64. case TextureFormat::ETC2:
  65. case TextureFormat::ETC2A:
  66. case TextureFormat::ETC2A1:
  67. case TextureFormat::PTC12:
  68. break;
  69. case TextureFormat::PTC14:
  70. {
  71. using namespace Javelin;
  72. RgbBitmap bmp;
  73. bmp.width = _width;
  74. bmp.height = _height;
  75. bmp.data = const_cast<uint8_t*>(_src);
  76. PvrTcEncoder::EncodeRgb4Bpp(_dst, bmp);
  77. bmp.data = NULL;
  78. }
  79. break;
  80. case TextureFormat::PTC12A:
  81. break;
  82. case TextureFormat::PTC14A:
  83. {
  84. using namespace Javelin;
  85. RgbaBitmap bmp;
  86. bmp.width = _width;
  87. bmp.height = _height;
  88. bmp.data = const_cast<uint8_t*>(_src);
  89. PvrTcEncoder::EncodeRgba4Bpp(_dst, bmp);
  90. bmp.data = NULL;
  91. }
  92. break;
  93. case TextureFormat::PTC22:
  94. case TextureFormat::PTC24:
  95. break;
  96. default:
  97. break;
  98. }
  99. }
  100. } // namespace bgfx
  101. void help(const char* _error = NULL)
  102. {
  103. if (NULL != _error)
  104. {
  105. fprintf(stderr, "Error:\n%s\n\n", _error);
  106. }
  107. fprintf(stderr
  108. , "texturec, bgfx texture compiler tool\n"
  109. "Copyright 2011-2015 Branimir Karadzic. All rights reserved.\n"
  110. "License: http://www.opensource.org/licenses/BSD-2-Clause\n\n"
  111. );
  112. }
  113. int main(int _argc, const char* _argv[])
  114. {
  115. using namespace bgfx;
  116. bx::CommandLine cmdLine(_argc, _argv);
  117. if (cmdLine.hasArg('h', "help") )
  118. {
  119. help();
  120. return EXIT_FAILURE;
  121. }
  122. const char* inputFileName = cmdLine.findOption('i');
  123. if (NULL == inputFileName)
  124. {
  125. help("Input file must be specified.");
  126. return EXIT_FAILURE;
  127. }
  128. const char* outputFileName = cmdLine.findOption('o');
  129. if (NULL == outputFileName)
  130. {
  131. help("Output file must be specified.");
  132. return EXIT_FAILURE;
  133. }
  134. bx::CrtFileReader reader;
  135. if (0 != bx::open(&reader, inputFileName) )
  136. {
  137. help("Failed to open input file.");
  138. return EXIT_FAILURE;
  139. }
  140. const bool mips = cmdLine.hasArg('m', "mips");
  141. const char* type = cmdLine.findOption('t');
  142. TextureFormat::Enum format = TextureFormat::BGRA8;
  143. if (NULL != type)
  144. {
  145. if (0 == bx::stricmp(type, "bc1")
  146. || 0 == bx::stricmp(type, "dxt1") )
  147. {
  148. format = TextureFormat::BC1;
  149. }
  150. else if (0 == bx::stricmp(type, "bc2")
  151. || 0 == bx::stricmp(type, "dxt3") )
  152. {
  153. format = TextureFormat::BC2;
  154. }
  155. else if (0 == bx::stricmp(type, "bc3")
  156. || 0 == bx::stricmp(type, "dxt5") )
  157. {
  158. format = TextureFormat::BC3;
  159. }
  160. else if (0 == bx::stricmp(type, "bc4") )
  161. {
  162. format = TextureFormat::BC4;
  163. }
  164. else if (0 == bx::stricmp(type, "bc5") )
  165. {
  166. format = TextureFormat::BC5;
  167. }
  168. else if (0 == bx::stricmp(type, "etc1") )
  169. {
  170. format = TextureFormat::ETC1;
  171. }
  172. else if (0 == bx::stricmp(type, "bc6h") )
  173. {
  174. format = TextureFormat::BC6H;
  175. }
  176. else if (0 == bx::stricmp(type, "bc7") )
  177. {
  178. format = TextureFormat::BC7;
  179. }
  180. else if (0 == bx::stricmp(type, "ptc14") )
  181. {
  182. format = TextureFormat::PTC14;
  183. }
  184. else if (0 == bx::stricmp(type, "ptc14a") )
  185. {
  186. format = TextureFormat::PTC14A;
  187. }
  188. }
  189. uint32_t size = (uint32_t)bx::getSize(&reader);
  190. const Memory* mem = alloc(size);
  191. bx::read(&reader, mem->data, mem->size);
  192. bx::close(&reader);
  193. ImageContainer imageContainer;
  194. bool loaded = imageParse(imageContainer, mem->data, mem->size);
  195. if (!loaded)
  196. {
  197. }
  198. BX_UNUSED(mips);
  199. if (loaded)
  200. {
  201. bx::CrtAllocator allocator;
  202. uint8_t* output = NULL;
  203. ImageMip mip;
  204. if (imageGetRawData(imageContainer, 0, 0, mem->data, mem->size, mip) )
  205. {
  206. uint8_t* rgba = (uint8_t*)BX_ALLOC(&allocator, imageGetSize(TextureFormat::RGBA8, mip.m_width, mip.m_height) );
  207. imageDecodeToRgba8(rgba, mip.m_data, mip.m_width, mip.m_height, mip.m_width*mip.m_bpp/8, mip.m_format);
  208. output = (uint8_t*)BX_ALLOC(&allocator, imageGetSize(format, mip.m_width, mip.m_height) );
  209. imageContainer.m_format = format;
  210. imageEncodeFromRgba8(output, rgba, mip.m_width, mip.m_height, format);
  211. BX_FREE(&allocator, rgba);
  212. }
  213. if (NULL != output)
  214. {
  215. bx::CrtFileWriter writer;
  216. if (0 == bx::open(&writer, outputFileName) )
  217. {
  218. if (NULL != bx::stristr(outputFileName, ".ktx") )
  219. {
  220. imageWriteKtx(&writer, imageContainer, mem->data, mem->size);
  221. }
  222. bx::close(&writer);
  223. }
  224. BX_FREE(&allocator, output);
  225. }
  226. }
  227. release(mem);
  228. return EXIT_SUCCESS;
  229. }