DXTCodec.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __DXTCODEC_H__
  21. #define __DXTCODEC_H__
  22. /*
  23. ================================================================================================
  24. Contains the DxtEncoder and DxtDecoder declarations.
  25. ================================================================================================
  26. */
  27. /*
  28. ================================================
  29. idDxtEncoder encodes Images in a number of DXT formats. Raw input Images are assumed to be in
  30. 4-byte RGBA format. Raw input NormalMaps are assumed to be in 4-byte tangent-space NxNyNz format.
  31. The supported formats are:
  32. * DXT1 = colors in 4x4 block approximated by equidistant points on a line through 3D space
  33. * DXT2 = DXT3 + colors are pre-multiplied by alpha
  34. * DXT3 = DXT1 + explicit 4-bit alpha
  35. * DXT4 = DXT5 + colors are pre-multiplied by alpha
  36. * DXT5 = DXT1 + alpha values in 4x4 block approximated by equidistant points on line through alpha space
  37. * CTX1 = colors in a 4x4 block approximated by equidistant points on a line through 2D space
  38. * DXN1 = one DXT5 alpha block (aka DXT5A, or ATI1N)
  39. * DXN2 = two DXT5 alpha blocks (aka 3Dc, or ATI2N)
  40. ================================================
  41. */
  42. class idDxtEncoder {
  43. public:
  44. idDxtEncoder() { srcPadding = dstPadding = 0; }
  45. ~idDxtEncoder() {}
  46. void SetSrcPadding( int pad ) { srcPadding = pad; }
  47. void SetDstPadding( int pad ) { dstPadding = pad; }
  48. // high quality DXT1 compression (no alpha), uses exhaustive search to find a line through color space and is very slow
  49. void CompressImageDXT1HQ( const byte *inBuf, byte *outBuf, int width, int height );
  50. // fast DXT1 compression (no alpha), for real-time use at the cost of a little quality
  51. void CompressImageDXT1Fast( const byte *inBuf, byte *outBuf, int width, int height );
  52. void CompressImageDXT1Fast_Generic( const byte *inBuf, byte *outBuf, int width, int height );
  53. void CompressImageDXT1Fast_SSE2( const byte *inBuf, byte *outBuf, int width, int height );
  54. // high quality DXT1 compression (with alpha), uses exhaustive search to find a line through color space and is very slow
  55. void CompressImageDXT1AlphaHQ( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  56. // fast DXT1 compression (with alpha), for real-time use at the cost of a little quality
  57. void CompressImageDXT1AlphaFast( const byte *inBuf, byte *outBuf, int width, int height );
  58. void CompressImageDXT1AlphaFast_Generic( const byte *inBuf, byte *outBuf, int width, int height );
  59. void CompressImageDXT1AlphaFast_SSE2( const byte *inBuf, byte *outBuf, int width, int height );
  60. // high quality DXT5 compression, uses exhaustive search to find a line through color space and is generally
  61. // too slow to actually use for anything
  62. void CompressImageDXT5HQ( const byte *inBuf, byte *outBuf, int width, int height );
  63. // fast DXT5 compression for real-time use at the cost of a little quality
  64. void CompressImageDXT5Fast( const byte *inBuf, byte *outBuf, int width, int height );
  65. void CompressImageDXT5Fast_Generic( const byte *inBuf, byte *outBuf, int width, int height );
  66. void CompressImageDXT5Fast_SSE2( const byte *inBuf, byte *outBuf, int width, int height );
  67. // high quality CTX1 compression, uses exhaustive search to find a line through 2D space and is very slow
  68. void CompressImageCTX1HQ( const byte *inBuf, byte *outBuf, int width, int height );
  69. // fast CTX1 compression for real-time use
  70. void CompressImageCTX1Fast( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  71. void CompressImageCTX1Fast_Generic( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  72. void CompressImageCTX1Fast_SSE2( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  73. // high quality DXN1 (aka DXT5A or ATI1N) compression, uses exhaustive search to find a line through color space and is very slow
  74. void CompressImageDXN1HQ( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  75. // fast single channel compression into, DXN1 (aka DXT5A or ATI1N) format, for real-time use
  76. void CompressImageDXN1Fast( const byte *inBuf, byte *outBuf, int width, int height );
  77. void CompressImageDXN1Fast_Generic( const byte *inBuf, byte *outBuf, int width, int height );
  78. void CompressImageDXN1Fast_SSE2( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  79. // high quality YCoCg DXT5 compression, uses exhaustive search to find a line through color space and is very slow
  80. void CompressYCoCgDXT5HQ( const byte *inBuf, byte *outBuf, int width, int height );
  81. // fast YCoCg DXT5 compression for real-time use (the input is expected to be in CoCg_Y format)
  82. void CompressYCoCgDXT5Fast( const byte *inBuf, byte *outBuf, int width, int height );
  83. void CompressYCoCgDXT5Fast_Generic( const byte *inBuf, byte *outBuf, int width, int height );
  84. void CompressYCoCgDXT5Fast_SSE2( const byte *inBuf, byte *outBuf, int width, int height );
  85. // fast YCoCg-Alpha DXT5 compression for real-time use (the input is expected to be in CoCgAY format)
  86. void CompressYCoCgAlphaDXT5Fast( const byte *inBuf, byte *outBuf, int width, int height );
  87. // high quality YCoCg CTX1 + DXT5A compression, uses exhaustive search to find a line through 2D space and is very slow
  88. void CompressYCoCgCTX1DXT5AHQ( const byte *inBuf, byte *outBuf, int width, int height );
  89. // fast YCoCg CTX1 + DXT5A compression for real-time use (the input is expected to be in CoCg_Y format)
  90. void CompressYCoCgCTX1DXT5AFast( const byte *inBuf, byte *outBuf, int width, int height );
  91. void CompressYCoCgCTX1DXT5AFast_Generic( const byte *inBuf, byte *outBuf, int width, int height );
  92. void CompressYCoCgCTX1DXT5AFast_SSE2( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  93. // high quality tangent space NxNyNz normal map compression into DXT1 format (Nz is not used)
  94. void CompressNormalMapDXT1HQ( const byte *inBuf, byte *outBuf, int width, int height );
  95. void CompressNormalMapDXT1RenormalizeHQ( const byte *inBuf, byte *outBuf, int width, int height );
  96. // fast tangent space NxNyNz normal map compression into DXT1 format (Nz is not used), for real-time use
  97. void CompressNormalMapDXT1Fast( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  98. void CompressNormalMapDXT1Fast_Generic( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  99. void CompressNormalMapDXT1Fast_SSE2( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  100. // high quality tangent space _Ny_Nx normal map compression into DXT5 format
  101. void CompressNormalMapDXT5HQ( const byte *inBuf, byte *outBuf, int width, int height );
  102. void CompressNormalMapDXT5RenormalizeHQ( const byte *inBuf, byte *outBuf, int width, int height );
  103. // fast tangent space _Ny_Nx normal map compression into DXT5 format, for real-time use
  104. void CompressNormalMapDXT5Fast( const byte *inBuf, byte *outBuf, int width, int height );
  105. void CompressNormalMapDXT5Fast_Generic( const byte *inBuf, byte *outBuf, int width, int height );
  106. void CompressNormalMapDXT5Fast_SSE2( const byte *inBuf, byte *outBuf, int width, int height );
  107. // high quality tangent space NxNy_ normal map compression into DXN2 (3Dc, ATI2N) format
  108. void CompressNormalMapDXN2HQ( const byte *inBuf, byte *outBuf, int width, int height );
  109. // fast tangent space NxNy_ normal map compression into DXN2 (3Dc, ATI2N) format, for real-time use
  110. void CompressNormalMapDXN2Fast( const byte *inBuf, byte *outBuf, int width, int height );
  111. void CompressNormalMapDXN2Fast_Generic( const byte *inBuf, byte *outBuf, int width, int height );
  112. void CompressNormalMapDXN2Fast_SSE2( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  113. // fast single channel conversion from DXN1 (aka DXT5A or ATI1N) to DXT1, reasonably fast (also works in-place)
  114. void ConvertImageDXN1_DXT1( const byte *inBuf, byte *outBuf, int width, int height );
  115. // fast single channel conversion from DXT1 to DXN1 (aka DXT5A or ATI1N), reasonably fast (also works in-place)
  116. void ConvertImageDXT1_DXN1( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  117. // fast tangent space NxNyNz normal map conversion from DXN (3Dc, ATI2N) to DXT5, reasonably fast (also works in-place)
  118. void ConvertNormalMapDXN2_DXT5( const byte *inBuf, byte *outBuf, int width, int height );
  119. // fast tangent space NxNyNz normal map conversion DXT5 to DXN (3Dc, ATI2N), reasonably fast (also works in-place)
  120. void ConvertNormalMapDXT5_DXN2( const byte *inBuf, byte *outBuf, int width, int height );
  121. private:
  122. int width;
  123. int height;
  124. byte * outData;
  125. int srcPadding;
  126. int dstPadding;
  127. void EmitByte( byte b );
  128. void EmitUShort( unsigned short s );
  129. void EmitUInt( unsigned int i );
  130. unsigned int AlphaDistance( const byte a1, const byte a2 ) const;
  131. unsigned int ColorDistance( const byte *c1, const byte *c2 ) const;
  132. unsigned int ColorDistanceWeighted( const byte *c1, const byte *c2 ) const;
  133. unsigned int CTX1Distance( const byte *c1, const byte *c2 ) const;
  134. unsigned short ColorTo565( const byte *color ) const;
  135. unsigned short ColorTo565( byte r, byte g, byte b ) const;
  136. void ColorFrom565( unsigned short c565, byte *color ) const;
  137. byte GreenFrom565( unsigned short c565 ) const;
  138. void NV4XHardwareBugFix( byte *minColor, byte *maxColor ) const;
  139. bool HasConstantValuePer4x4Block( const byte *inBuf, int width, int height, int channel ) const;
  140. void WriteTinyColorDXT1( const byte *inBuf, int width, int height );
  141. void WriteTinyColorDXT5( const byte *inBuf, int width, int height );
  142. void WriteTinyColorCTX1DXT5A( const byte *inBuf, int width, int height );
  143. void WriteTinyNormalMapDXT5( const byte *NxNy, int width, int height );
  144. void WriteTinyNormalMapDXN( const byte *NxNy, int width, int height );
  145. void WriteTinyDXT5A( const byte *NxNy, int width, int height );
  146. void GetMinMaxColorsMaxDist( const byte *colorBlock, byte *minColor, byte *maxColor ) const;
  147. void GetMinMaxColorsLuminance( const byte *colorBlock, byte *minColor, byte *maxColor ) const;
  148. int GetSquareAlphaError( const byte *colorBlock, const int alphaOffset, const byte minAlpha, const byte maxAlpha, int lastError ) const;
  149. int GetMinMaxAlphaHQ( const byte *colorBlock, const int alphaOffset, byte *minColor, byte *maxColor ) const;
  150. int GetSquareColorsError( const byte *colorBlock, const unsigned short color0, const unsigned short color1, int lastError ) const;
  151. int GetMinMaxColorsHQ( const byte *colorBlock, byte *minColor, byte *maxColor, bool noBlack ) const;
  152. int GetSquareCTX1Error( const byte *colorBlock, const byte *color0, const byte *color1, int lastError ) const;
  153. int GetMinMaxCTX1HQ( const byte *colorBlock, byte *minColor, byte *maxColor ) const;
  154. int GetSquareNormalYError( const byte *colorBlock, const unsigned short color0, const unsigned short color1, int lastError, int scale ) const;
  155. int GetMinMaxNormalYHQ( const byte *colorBlock, byte *minColor, byte *maxColor, bool noBlack, int scale ) const;
  156. int GetSquareNormalsDXT1Error( const int *colorBlock, const unsigned short color0, const unsigned short color1, int lastError, unsigned int &colorIndices ) const;
  157. int GetMinMaxNormalsDXT1HQ( const byte *colorBlock, byte *minColor, byte *maxColor, unsigned int &colorIndices, bool noBlack ) const;
  158. int GetSquareNormalsDXT5Error( const int *normalBlock, const byte *minNormal, const byte *maxNormal, int lastError, unsigned int &colorIndices, byte *alphaIndices ) const;
  159. int GetMinMaxNormalsDXT5HQ( const byte *normalBlock, byte *minColor, byte *maxColor, unsigned int &colorIndices, byte *alphaIndices ) const;
  160. int GetMinMaxNormalsDXT5HQFast( const byte *normalBlock, byte *minColor, byte *maxColor, unsigned int &colorIndices, byte *alphaIndices ) const;
  161. void ScaleYCoCg( byte *colorBlock ) const;
  162. void BiasScaleNormalY( byte *colorBlock ) const;
  163. void RotateNormalsDXT1( byte *block ) const;
  164. void RotateNormalsDXT5( byte *block ) const;
  165. int FindColorIndices( const byte *colorBlock, const unsigned short color0, const unsigned short color1, unsigned int &result ) const;
  166. int FindAlphaIndices( const byte *colorBlock, const int alphaOffset, const byte alpha0, const byte alpha1, byte *indexes ) const;
  167. int FindCTX1Indices( const byte *colorBlock, const byte *color0, const byte *color1, unsigned int &result ) const;
  168. void ExtractBlock( const byte *inPtr, int width, byte *colorBlock ) const;
  169. void GetMinMaxBBox( const byte *colorBlock, byte *minColor, byte *maxColor ) const;
  170. void InsetColorsBBox( byte *minColor, byte *maxColor ) const;
  171. void SelectColorsDiagonal( const byte *colorBlock, byte *minColor, byte *maxColor ) const;
  172. void ScaleYCoCg( byte *colorBlock, byte *minColor, byte *maxColor ) const;
  173. void InsetYCoCgAlpaBBox( byte *minColor, byte *maxColor ) const;
  174. void InsetYCoCgBBox( byte *minColor, byte *maxColor ) const;
  175. void SelectYCoCgDiagonal( const byte *colorBlock, byte *minColor, byte *maxColor ) const;
  176. void InsetNormalsBBoxDXT5( byte *minNormal, byte *maxNormal ) const;
  177. void InsetNormalsBBox3Dc( byte *minNormal, byte *maxNormal ) const;
  178. void EmitColorIndices( const byte *colorBlock, const byte *minColor, const byte *maxColor );
  179. void EmitColorAlphaIndices( const byte *colorBlock, const byte *minColor, const byte *maxColor );
  180. void EmitCTX1Indices( const byte *colorBlock, const byte *minColor, const byte *maxColor );
  181. void EmitAlphaIndices( const byte *colorBlock, const int channel, const byte minAlpha, const byte maxAlpha );
  182. void EmitGreenIndices( const byte *block, const int channel, const byte minGreen, const byte maxGreen );
  183. // Keeping the ASM versions to keep the performance of 32-bit debug builds reasonable.
  184. // The implementation using intrinsics is very slow in debug builds because registers are continuously spilled to memory.
  185. void ExtractBlock_SSE2( const byte *inPtr, int width, byte *colorBlock ) const;
  186. void GetMinMaxBBox_SSE2( const byte *colorBlock, byte *minColor, byte *maxColor ) const;
  187. void InsetColorsBBox_SSE2( byte *minColor, byte *maxColor ) const;
  188. void InsetNormalsBBoxDXT5_SSE2( byte *minNormal, byte *maxNormal ) const;
  189. void EmitColorIndices_SSE2( const byte *colorBlock, const byte *minColor, const byte *maxColor );
  190. void EmitColorAlphaIndices_SSE2( const byte *colorBlock, const byte *minColor, const byte *maxColor );
  191. void EmitCoCgIndices_SSE2( const byte *colorBlock, const byte *minColor, const byte *maxColor );
  192. void EmitAlphaIndices_SSE2( const byte *colorBlock, const int minAlpha, const int maxAlpha );
  193. void EmitAlphaIndices_SSE2( const byte *colorBlock, const int channelBitOffset, const int minAlpha, const int maxAlpha );
  194. void EmitGreenIndices_SSE2( const byte *block, const int channelBitOffset, const int minGreen, const int maxGreen );
  195. void ScaleYCoCg_SSE2( byte *colorBlock, byte *minColor, byte *maxColor ) const;
  196. void InsetYCoCgBBox_SSE2( byte *minColor, byte *maxColor ) const;
  197. void SelectYCoCgDiagonal_SSE2( const byte *colorBlock, byte *minColor, byte *maxColor ) const;
  198. void EmitNormalYIndices( const byte *normalBlock, const int offset, const byte minNormalY, const byte maxNormalY );
  199. void EmitNormalYIndices_SSE2( const byte *normalBlock, const int offset, const byte minNormalY, const byte maxNormalY );
  200. void DecodeDXNAlphaValues( const byte *inBuf, byte *values );
  201. void EncodeDXNAlphaValues( byte *outBuf, const byte min, const byte max, const byte *values );
  202. void DecodeNormalYValues( const byte *inBuf, byte &min, byte &max, byte *values );
  203. void EncodeNormalRGBIndices( byte *outBuf, const byte min, const byte max, const byte *values );
  204. };
  205. /*
  206. ========================
  207. idDxtEncoder::CompressImageDXT1Fast
  208. ========================
  209. */
  210. ID_INLINE void idDxtEncoder::CompressImageDXT1Fast( const byte *inBuf, byte *outBuf, int width, int height ) {
  211. #ifdef ID_WIN_X86_SSE2_INTRIN
  212. CompressImageDXT1Fast_SSE2( inBuf, outBuf, width, height );
  213. #else
  214. CompressImageDXT1Fast_Generic( inBuf, outBuf, width, height );
  215. #endif
  216. }
  217. /*
  218. ========================
  219. idDxtEncoder::CompressImageDXT1AlphaFast
  220. ========================
  221. */
  222. ID_INLINE void idDxtEncoder::CompressImageDXT1AlphaFast( const byte *inBuf, byte *outBuf, int width, int height ) {
  223. #ifdef ID_WIN_X86_SSE2_INTRIN
  224. CompressImageDXT1AlphaFast_SSE2( inBuf, outBuf, width, height );
  225. #else
  226. CompressImageDXT1AlphaFast_Generic( inBuf, outBuf, width, height );
  227. #endif
  228. }
  229. /*
  230. ========================
  231. idDxtEncoder::CompressImageDXT5Fast
  232. ========================
  233. */
  234. ID_INLINE void idDxtEncoder::CompressImageDXT5Fast( const byte *inBuf, byte *outBuf, int width, int height ) {
  235. #ifdef ID_WIN_X86_SSE2_INTRIN
  236. CompressImageDXT5Fast_SSE2( inBuf, outBuf, width, height );
  237. #else
  238. CompressImageDXT5Fast_Generic( inBuf, outBuf, width, height );
  239. #endif
  240. }
  241. /*
  242. ========================
  243. idDxtEncoder::CompressImageDXN1Fast
  244. ========================
  245. */
  246. ID_INLINE void idDxtEncoder::CompressImageDXN1Fast( const byte *inBuf, byte *outBuf, int width, int height ) {
  247. CompressImageDXN1Fast_Generic( inBuf, outBuf, width, height );
  248. }
  249. /*
  250. ========================
  251. idDxtEncoder::CompressYCoCgDXT5Fast
  252. ========================
  253. */
  254. ID_INLINE void idDxtEncoder::CompressYCoCgDXT5Fast( const byte *inBuf, byte *outBuf, int width, int height ) {
  255. #ifdef ID_WIN_X86_SSE2_INTRIN
  256. CompressYCoCgDXT5Fast_SSE2( inBuf, outBuf, width, height );
  257. #else
  258. CompressYCoCgDXT5Fast_Generic( inBuf, outBuf, width, height );
  259. #endif
  260. }
  261. /*
  262. ========================
  263. idDxtEncoder::CompressYCoCgCTX1DXT5AFast
  264. ========================
  265. */
  266. ID_INLINE void idDxtEncoder::CompressYCoCgCTX1DXT5AFast( const byte *inBuf, byte *outBuf, int width, int height ) {
  267. CompressYCoCgCTX1DXT5AFast_Generic( inBuf, outBuf, width, height );
  268. }
  269. /*
  270. ========================
  271. idDxtEncoder::CompressNormalMapDXT5Fast
  272. ========================
  273. */
  274. ID_INLINE void idDxtEncoder::CompressNormalMapDXT5Fast( const byte *inBuf, byte *outBuf, int width, int height ) {
  275. #ifdef ID_WIN_X86_SSE2_INTRIN
  276. CompressNormalMapDXT5Fast_SSE2( inBuf, outBuf, width, height );
  277. #else
  278. CompressNormalMapDXT5Fast_Generic( inBuf, outBuf, width, height );
  279. #endif
  280. }
  281. /*
  282. ========================
  283. idDxtEncoder::CompressNormalMapDXN2Fast
  284. ========================
  285. */
  286. ID_INLINE void idDxtEncoder::CompressNormalMapDXN2Fast( const byte *inBuf, byte *outBuf, int width, int height ) {
  287. CompressNormalMapDXN2Fast_Generic( inBuf, outBuf, width, height );
  288. }
  289. /*
  290. ========================
  291. idDxtEncoder::EmitByte
  292. ========================
  293. */
  294. ID_INLINE void idDxtEncoder::EmitByte( byte b ) {
  295. *outData = b;
  296. outData += 1;
  297. }
  298. /*
  299. ========================
  300. idDxtEncoder::EmitUShort
  301. ========================
  302. */
  303. ID_INLINE void idDxtEncoder::EmitUShort( unsigned short s ) {
  304. *((unsigned short *)outData) = s;
  305. outData += 2;
  306. }
  307. /*
  308. ========================
  309. idDxtEncoder::EmitUInt
  310. ========================
  311. */
  312. ID_INLINE void idDxtEncoder::EmitUInt( unsigned int i ) {
  313. *((unsigned int *)outData) = i;
  314. outData += 4;
  315. }
  316. /*
  317. ========================
  318. idDxtEncoder::AlphaDistance
  319. ========================
  320. */
  321. ID_INLINE unsigned int idDxtEncoder::AlphaDistance( const byte a1, const byte a2 ) const {
  322. return ( a1 - a2 ) * ( a1 - a2 );
  323. }
  324. /*
  325. ========================
  326. idDxtEncoder::ColorDistance
  327. ========================
  328. */
  329. ID_INLINE unsigned int idDxtEncoder::ColorDistance( const byte *c1, const byte *c2 ) const {
  330. return ( ( c1[ 0 ] - c2[ 0 ] ) * ( c1[ 0 ] - c2[ 0 ] ) ) + ( ( c1[ 1 ] - c2[ 1 ] ) * ( c1[ 1 ] - c2[ 1 ] ) ) + ( ( c1[ 2 ] - c2[ 2 ] ) * ( c1[ 2 ] - c2[ 2 ] ) );
  331. }
  332. /*
  333. ========================
  334. idDxtEncoder::ColorDistanceWeighted
  335. ========================
  336. */
  337. ID_INLINE unsigned int idDxtEncoder::ColorDistanceWeighted( const byte *c1, const byte *c2 ) const {
  338. int r, g, b;
  339. int rmean;
  340. // http://www.compuphase.com/cmetric.htm
  341. rmean = ( (int)c1[0] + (int)c2[0] ) / 2;
  342. r = (int)c1[0] - (int)c2[0];
  343. g = (int)c1[1] - (int)c2[1];
  344. b = (int)c1[2] - (int)c2[2];
  345. return ( ( ( 512 + rmean ) * r * r ) >> 8 ) + 4 * g * g + ( ( ( 767 - rmean ) * b * b ) >> 8 );
  346. }
  347. /*
  348. ========================
  349. idDxtEncoder::CTX1Distance
  350. ========================
  351. */
  352. ID_INLINE unsigned int idDxtEncoder::CTX1Distance( const byte *c1, const byte *c2 ) const {
  353. return ( ( c1[ 0 ] - c2[ 0 ] ) * ( c1[ 0 ] - c2[ 0 ] ) ) + ( ( c1[ 1 ] - c2[ 1 ] ) * ( c1[ 1 ] - c2[ 1 ] ) );
  354. }
  355. /*
  356. ========================
  357. idDxtEncoder::ColorTo565
  358. ========================
  359. */
  360. ID_INLINE unsigned short idDxtEncoder::ColorTo565( const byte *color ) const {
  361. return ( ( color[ 0 ] >> 3 ) << 11 ) | ( ( color[ 1 ] >> 2 ) << 5 ) | ( color[ 2 ] >> 3 );
  362. }
  363. /*
  364. ========================
  365. idDxtEncoder::ColorFrom565
  366. ========================
  367. */
  368. ID_INLINE void idDxtEncoder::ColorFrom565( unsigned short c565, byte *color ) const {
  369. color[0] = byte( ( ( c565 >> 8 ) & ( ( ( 1 << ( 8 - 3 ) ) - 1 ) << 3 ) ) | ( ( c565 >> 13 ) & ((1<<3)-1) ) );
  370. color[1] = byte( ( ( c565 >> 3 ) & ( ( ( 1 << ( 8 - 2 ) ) - 1 ) << 2 ) ) | ( ( c565 >> 9 ) & ((1<<2)-1) ) );
  371. color[2] = byte( ( ( c565 << 3 ) & ( ( ( 1 << ( 8 - 3 ) ) - 1 ) << 3 ) ) | ( ( c565 >> 2 ) & ((1<<3)-1) ) );
  372. }
  373. /*
  374. ========================
  375. idDxtEncoder::ColorTo565
  376. ========================
  377. */
  378. ID_INLINE unsigned short idDxtEncoder::ColorTo565( byte r, byte g, byte b ) const {
  379. return ( ( r >> 3 ) << 11 ) | ( ( g >> 2 ) << 5 ) | ( b >> 3 );
  380. }
  381. /*
  382. ========================
  383. idDxtEncoder::GreenFrom565
  384. ========================
  385. */
  386. ID_INLINE byte idDxtEncoder::GreenFrom565( unsigned short c565 ) const {
  387. byte c = byte( ( c565 & ( ( ( 1 << 6 ) - 1 ) << 5 ) ) >> 3 );
  388. return ( c | ( c >> 6 ) );
  389. }
  390. /*
  391. ================================================
  392. idDxtDecoder decodes DXT-compressed Images. Raw output Images are in
  393. 4-byte RGBA format. Raw output NormalMaps are in 4-byte tangent-space NxNyNz format.
  394. ================================================
  395. */
  396. class idDxtDecoder {
  397. public:
  398. // DXT1 decompression (no alpha)
  399. void DecompressImageDXT1( const byte *inBuf, byte *outBuf, int width, int height );
  400. // DXT5 decompression
  401. void DecompressImageDXT5( const byte *inBuf, byte *outBuf, int width, int height );
  402. // DXT5 decompression with nVidia 7x hardware bug
  403. void DecompressImageDXT5_nVidia7x( const byte *inBuf, byte *outBuf, int width, int height );
  404. // CTX1
  405. void DecompressImageCTX1( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  406. // DXN1
  407. void DecompressImageDXN1( const byte *inBuf, byte *outBuf, int width, int height ) { /* not implemented */ assert( 0 ); }
  408. // YCoCg DXT5 (the output is in CoCg_Y format)
  409. void DecompressYCoCgDXT5( const byte *inBuf, byte *outBuf, int width, int height );
  410. // YCoCg CTX1 + DXT5A (the output is in CoCg_Y format)
  411. void DecompressYCoCgCTX1DXT5A( const byte *inBuf, byte *outBuf, int width, int height );
  412. // tangent space normal map decompression from DXT1 format
  413. void DecompressNormalMapDXT1( const byte *inBuf, byte *outBuf, int width, int height );
  414. void DecompressNormalMapDXT1Renormalize( const byte *inBuf, byte *outBuf, int width, int height );
  415. // tangent space normal map decompression from DXT5 format
  416. void DecompressNormalMapDXT5( const byte *inBuf, byte *outBuf, int width, int height );
  417. void DecompressNormalMapDXT5Renormalize( const byte *inBuf, byte *outBuf, int width, int height );
  418. // tangent space normal map decompression from DXN2 format
  419. void DecompressNormalMapDXN2( const byte *inBuf, byte *outBuf, int width, int height );
  420. // decompose a DXT image into indices and two images with colors
  421. void DecomposeImageDXT1( const byte *inBuf, byte *colorIndices, byte *pic1, byte *pic2, int width, int height );
  422. void DecomposeImageDXT5( const byte *inBuf, byte *colorIndices, byte *alphaIndices, byte *pic1, byte *pic2, int width, int height );
  423. private:
  424. int width;
  425. int height;
  426. const byte * inData;
  427. byte ReadByte();
  428. unsigned short ReadUShort();
  429. unsigned int ReadUInt();
  430. unsigned short ColorTo565( const byte *color ) const;
  431. void ColorFrom565( unsigned short c565, byte *color ) const;
  432. unsigned short NormalYTo565( byte y ) const;
  433. byte NormalYFrom565( unsigned short c565 ) const;
  434. byte NormalScaleFrom565( unsigned short c565 ) const;
  435. byte NormalBiasFrom565( unsigned short c565 ) const;
  436. void EmitBlock( byte *outPtr, int x, int y, const byte *colorBlock );
  437. void DecodeAlphaValues( byte *colorBlock, const int offset );
  438. void DecodeColorValues( byte *colorBlock, bool noBlack, bool writeAlpha );
  439. void DecodeCTX1Values( byte *colorBlock );
  440. void DecomposeColorBlock( byte colors[2][4], byte colorIndices[16], bool noBlack );
  441. void DecomposeAlphaBlock( byte colors[2][4], byte alphaIndices[16] );
  442. void DecodeNormalYValues( byte *normalBlock, const int offsetY, byte &bias, byte &scale );
  443. void DeriveNormalZValues( byte *normalBlock );
  444. };
  445. /*
  446. ========================
  447. idDxtDecoder::ReadByte
  448. ========================
  449. */
  450. ID_INLINE byte idDxtDecoder::ReadByte() {
  451. byte b = *inData;
  452. inData += 1;
  453. return b;
  454. }
  455. /*
  456. ========================
  457. idDxtDecoder::ReadUShort
  458. ========================
  459. */
  460. ID_INLINE unsigned short idDxtDecoder::ReadUShort() {
  461. unsigned short s = *((unsigned short *)inData);
  462. inData += 2;
  463. return s;
  464. }
  465. /*
  466. ========================
  467. idDxtDecoder::ReadUInt
  468. ========================
  469. */
  470. ID_INLINE unsigned int idDxtDecoder::ReadUInt() {
  471. unsigned int i = *((unsigned int *)inData);
  472. inData += 4;
  473. return i;
  474. }
  475. /*
  476. ========================
  477. idDxtDecoder::ColorTo565
  478. ========================
  479. */
  480. ID_INLINE unsigned short idDxtDecoder::ColorTo565( const byte *color ) const {
  481. return ( ( color[ 0 ] >> 3 ) << 11 ) | ( ( color[ 1 ] >> 2 ) << 5 ) | ( color[ 2 ] >> 3 );
  482. }
  483. /*
  484. ========================
  485. idDxtDecoder::ColorFrom565
  486. ========================
  487. */
  488. ID_INLINE void idDxtDecoder::ColorFrom565( unsigned short c565, byte *color ) const {
  489. color[0] = byte( ( ( c565 >> 8 ) & ( ( ( 1 << ( 8 - 3 ) ) - 1 ) << 3 ) ) | ( ( c565 >> 13 ) & ((1<<3)-1) ) );
  490. color[1] = byte( ( ( c565 >> 3 ) & ( ( ( 1 << ( 8 - 2 ) ) - 1 ) << 2 ) ) | ( ( c565 >> 9 ) & ((1<<2)-1) ) );
  491. color[2] = byte( ( ( c565 << 3 ) & ( ( ( 1 << ( 8 - 3 ) ) - 1 ) << 3 ) ) | ( ( c565 >> 2 ) & ((1<<3)-1) ) );
  492. }
  493. /*
  494. ========================
  495. idDxtDecoder::NormalYTo565
  496. ========================
  497. */
  498. ID_INLINE unsigned short idDxtDecoder::NormalYTo565( byte y ) const {
  499. return ( ( y >> 2 ) << 5 );
  500. }
  501. /*
  502. ========================
  503. idDxtDecoder::NormalYFrom565
  504. ========================
  505. */
  506. ID_INLINE byte idDxtDecoder::NormalYFrom565( unsigned short c565 ) const {
  507. byte c = byte( ( c565 & ( ( ( 1 << 6 ) - 1 ) << 5 ) ) >> 3 );
  508. return ( c | ( c >> 6 ) );
  509. }
  510. /*
  511. ========================
  512. idDxtDecoder::NormalBiasFrom565
  513. ========================
  514. */
  515. ID_INLINE byte idDxtDecoder::NormalBiasFrom565( unsigned short c565 ) const {
  516. byte c = byte( ( c565 & ( ( ( 1 << 5 ) - 1 ) << 11 ) ) >> 8 );
  517. return ( c | ( c >> 5 ) );
  518. }
  519. /*
  520. ========================
  521. idDxtDecoder::NormalScaleFrom565
  522. ========================
  523. */
  524. ID_INLINE byte idDxtDecoder::NormalScaleFrom565( unsigned short c565 ) const {
  525. byte c = byte( ( c565 & ( ( ( 1 << 5 ) - 1 ) << 0 ) ) << 3 );
  526. return ( c | ( c >> 5 ) );
  527. }
  528. #endif // !__DXTCODEC_H__