Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
8.1 KiB

  1. //======= Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Image Byte Swapping. Isolate routines to own module to allow librarian
  4. // to ignore xbox 360 dependenices in non-applicable win32 projects.
  5. //
  6. //=============================================================================//
  7. #if defined( _WIN32 ) && !defined( _X360 ) && !defined( DX_TO_GL_ABSTRACTION )
  8. #include <windows.h>
  9. #endif
  10. #include "tier0/platform.h"
  11. #include "tier0/dbg.h"
  12. #include "bitmap/imageformat.h"
  13. // Should be last include
  14. #include "tier0/memdbgon.h"
  15. #if defined( _WIN32 ) && !defined( _X360 ) && !defined( NO_X360_XDK ) && !defined( DX_TO_GL_ABSTRACTION )
  16. #if defined( XDK_INSTALLED )
  17. // the x86 version of the 360 (used by win32 tools)
  18. // It would have been nice to use the 360 D3DFORMAT bit encodings, but the codes
  19. // are different for WIN32, and this routine is used by a WIN32 library to
  20. // manipulate 360 data, so there can be no reliance on WIN32 D3DFORMAT bits
  21. #include "d3d9.h"
  22. #include "XGraphics.h"
  23. #endif
  24. #endif
  25. namespace ImageLoader
  26. {
  27. //-----------------------------------------------------------------------------
  28. // Known formats that can be converted. Used as a trap for 360 formats
  29. // that may occur but have not been validated yet.
  30. //-----------------------------------------------------------------------------
  31. bool IsFormatValidForConversion( ImageFormat fmt )
  32. {
  33. switch ( fmt )
  34. {
  35. case IMAGE_FORMAT_RGBA8888:
  36. case IMAGE_FORMAT_ABGR8888:
  37. case IMAGE_FORMAT_RGB888:
  38. case IMAGE_FORMAT_BGR888:
  39. case IMAGE_FORMAT_ARGB8888:
  40. case IMAGE_FORMAT_BGRA8888:
  41. case IMAGE_FORMAT_BGRX8888:
  42. case IMAGE_FORMAT_UVWQ8888:
  43. case IMAGE_FORMAT_RGBA16161616F:
  44. case IMAGE_FORMAT_RGBA16161616:
  45. case IMAGE_FORMAT_UVLX8888:
  46. case IMAGE_FORMAT_DXT1:
  47. case IMAGE_FORMAT_DXT1_ONEBITALPHA:
  48. case IMAGE_FORMAT_DXT3:
  49. case IMAGE_FORMAT_DXT5:
  50. case IMAGE_FORMAT_UV88:
  51. return true;
  52. // untested formats
  53. default:
  54. case IMAGE_FORMAT_RGB565:
  55. case IMAGE_FORMAT_I8:
  56. case IMAGE_FORMAT_IA88:
  57. case IMAGE_FORMAT_A8:
  58. case IMAGE_FORMAT_RGB888_BLUESCREEN:
  59. case IMAGE_FORMAT_BGR888_BLUESCREEN:
  60. case IMAGE_FORMAT_BGR565:
  61. case IMAGE_FORMAT_BGRX5551:
  62. case IMAGE_FORMAT_BGRA4444:
  63. case IMAGE_FORMAT_BGRA5551:
  64. case IMAGE_FORMAT_ATI1N:
  65. case IMAGE_FORMAT_ATI2N:
  66. break;
  67. }
  68. return false;
  69. }
  70. //-----------------------------------------------------------------------------
  71. // Swaps the image element type within the format.
  72. // This is to ensure that >8 bit channels are in the correct endian format
  73. // as expected by the conversion process, which varies according to format,
  74. // input, and output.
  75. //-----------------------------------------------------------------------------
  76. void PreConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width, int stride )
  77. {
  78. Assert( IsFormatValidForConversion( imageFormat ) );
  79. #ifndef DX_TO_GL_ABSTRACTION
  80. if ( IsPC() )
  81. {
  82. // running as a win32 tool, data is in expected order
  83. // for conversion code
  84. return;
  85. }
  86. // If licensees don't have the XDK installed they are not going to be able to do image conversion and shouldn't need to
  87. #if defined (XDK_INSTALLED)
  88. // running on 360 and converting, input data must be x86 order
  89. // swap to ensure conversion code gets valid data
  90. XGENDIANTYPE xEndian;
  91. switch ( imageFormat )
  92. {
  93. default:
  94. return;
  95. case IMAGE_FORMAT_RGBA16161616F:
  96. case IMAGE_FORMAT_RGBA16161616:
  97. xEndian = XGENDIAN_8IN16;
  98. break;
  99. }
  100. int count;
  101. if ( !stride )
  102. {
  103. stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
  104. count = nImageSize / stride;
  105. XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
  106. }
  107. else
  108. {
  109. int nRows = nImageSize/stride;
  110. for ( int i=0; i<nRows; i++ )
  111. {
  112. XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
  113. pImageData += stride;
  114. }
  115. }
  116. #endif // XDK_INSTALLED
  117. #endif // COMPILER_MSVC32
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Swaps image bytes for use on a big endian platform. This is used after the conversion
  121. // process to match the 360 d3dformats.
  122. //-----------------------------------------------------------------------------
  123. void PostConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width, int stride )
  124. {
  125. Assert( IsFormatValidForConversion( imageFormat ) );
  126. #ifndef DX_TO_GL_ABSTRACTION
  127. // If licensees don't have the XDK installed they are not going to be able to do image conversion and shouldn't need to
  128. #if defined (XDK_INSTALLED)
  129. // It would have been nice to use the 360 D3DFORMAT bit encodings, but the codes
  130. // are different for win32, and this routine is used by a win32 library to
  131. // manipulate 360 data, so there can be no reliance on D3DFORMAT bits
  132. XGENDIANTYPE xEndian;
  133. switch ( imageFormat )
  134. {
  135. default:
  136. return;
  137. case IMAGE_FORMAT_RGBA16161616F:
  138. case IMAGE_FORMAT_RGBA16161616:
  139. if ( IsGameConsole() )
  140. {
  141. // running on 360 the conversion output is correct
  142. return;
  143. }
  144. // running on the pc, the output needs to be in 360 order
  145. xEndian = XGENDIAN_8IN16;
  146. break;
  147. case IMAGE_FORMAT_DXT1:
  148. case IMAGE_FORMAT_DXT1_ONEBITALPHA:
  149. case IMAGE_FORMAT_DXT3:
  150. case IMAGE_FORMAT_DXT5:
  151. case IMAGE_FORMAT_UV88:
  152. case IMAGE_FORMAT_ATI1N:
  153. case IMAGE_FORMAT_ATI2N:
  154. // Don't endian swap compressed textures for PS3, but swap everything else just like Xbox360
  155. if ( targetConsole == VTF_CONSOLE_PS3 )
  156. return;
  157. xEndian = XGENDIAN_8IN16;
  158. break;
  159. case IMAGE_FORMAT_BGRA8888:
  160. case IMAGE_FORMAT_BGRX8888:
  161. case IMAGE_FORMAT_UVWQ8888:
  162. case IMAGE_FORMAT_UVLX8888:
  163. xEndian = XGENDIAN_8IN32;
  164. break;
  165. }
  166. int count;
  167. if ( !stride )
  168. {
  169. stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
  170. count = nImageSize / stride;
  171. XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
  172. }
  173. else
  174. {
  175. int nRows = nImageSize/stride;
  176. for ( int i=0; i<nRows; i++ )
  177. {
  178. XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
  179. pImageData += stride;
  180. }
  181. }
  182. #endif // XDK_INSTALLED
  183. #endif // COMPILER_MSVC32
  184. }
  185. //-----------------------------------------------------------------------------
  186. // Swaps image bytes.
  187. //-----------------------------------------------------------------------------
  188. void ByteSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width, int stride )
  189. {
  190. Assert( IsFormatValidForConversion( imageFormat ) );
  191. #ifndef DX_TO_GL_ABSTRACTION
  192. // If licensees don't have the XDK installed they are not going to be able to do image conversion and shouldn't need to
  193. #if defined (XDK_INSTALLED)
  194. XGENDIANTYPE xEndian;
  195. switch ( imageFormat )
  196. {
  197. case IMAGE_FORMAT_BGR888:
  198. case IMAGE_FORMAT_I8:
  199. case IMAGE_FORMAT_A8:
  200. default:
  201. return;
  202. case IMAGE_FORMAT_BGRA8888:
  203. case IMAGE_FORMAT_BGRX8888:
  204. case IMAGE_FORMAT_UVWQ8888:
  205. case IMAGE_FORMAT_UVLX8888:
  206. case IMAGE_FORMAT_R32F:
  207. case IMAGE_FORMAT_RGBA32323232F:
  208. xEndian = XGENDIAN_8IN32;
  209. break;
  210. case IMAGE_FORMAT_BGR565:
  211. case IMAGE_FORMAT_BGRX5551:
  212. case IMAGE_FORMAT_BGRA5551:
  213. case IMAGE_FORMAT_BGRA4444:
  214. case IMAGE_FORMAT_IA88:
  215. case IMAGE_FORMAT_DXT1:
  216. case IMAGE_FORMAT_DXT1_ONEBITALPHA:
  217. case IMAGE_FORMAT_DXT3:
  218. case IMAGE_FORMAT_DXT5:
  219. case IMAGE_FORMAT_ATI1N:
  220. case IMAGE_FORMAT_ATI2N:
  221. case IMAGE_FORMAT_UV88:
  222. case IMAGE_FORMAT_RGBA16161616F:
  223. case IMAGE_FORMAT_RGBA16161616:
  224. xEndian = XGENDIAN_8IN16;
  225. break;
  226. }
  227. int count;
  228. if ( !stride )
  229. {
  230. stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
  231. count = nImageSize / stride;
  232. XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
  233. }
  234. else
  235. {
  236. int nRows = nImageSize/stride;
  237. for ( int i=0; i<nRows; i++ )
  238. {
  239. XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
  240. pImageData += stride;
  241. }
  242. }
  243. #endif // XDK_INSTALLED
  244. #endif // COMPILER_MSVC32
  245. }
  246. }