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.

679 lines
23 KiB

  1. //===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #ifndef IMAGEFORMAT_H
  7. #define IMAGEFORMAT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include <stdio.h>
  12. #include "tier0/platform.h"
  13. #include "tier0/dbg.h"
  14. #include "bitmap/imageformat_declarations.h"
  15. //-----------------------------------------------------------------------------
  16. // Color structures
  17. //-----------------------------------------------------------------------------
  18. #pragma warning ( disable : 4293 )
  19. template< int nBitCount > FORCEINLINE int ConvertTo10Bit( int x )
  20. {
  21. switch ( nBitCount )
  22. {
  23. case 1:
  24. return ( x & 0x1 ) ? 0x3FF : 0;
  25. case 2:
  26. return ( x << 8 ) | ( x << 6 ) | ( x << 4 ) | ( x << 2 ) | x;
  27. case 3:
  28. return ( x << 7 ) | ( x << 4 ) | ( x << 1 ) | ( x >> 2 );
  29. case 4:
  30. return ( x << 6 ) | ( x << 2 ) | ( x >> 2 );
  31. default:
  32. #if defined(POSIX) || defined(_PS3)
  33. return ( x << ( 10 - nBitCount ) ) | ( x >> MAX( 0, MIN( 32, ( nBitCount - ( 10 - nBitCount ) ) ) ) );
  34. #else // !_PS3
  35. return ( x << ( 10 - nBitCount ) ) | ( x >> ( nBitCount - ( 10 - nBitCount ) ) );
  36. #endif
  37. }
  38. }
  39. #pragma warning ( default : 4293 )
  40. template< int nBitCount > FORCEINLINE int ConvertFrom10Bit( int x )
  41. {
  42. return ( x >> ( 10 - nBitCount ) );
  43. }
  44. struct R32F_t
  45. {
  46. float32 r;
  47. };
  48. struct RG3232F_t
  49. {
  50. float32 r;
  51. float32 g;
  52. };
  53. struct RGB323232F_t
  54. {
  55. float32 r;
  56. float32 g;
  57. float32 b;
  58. };
  59. struct RGBA32323232F_t
  60. {
  61. float32 r;
  62. float32 g;
  63. float32 b;
  64. float32 a;
  65. };
  66. struct RGBA1010102_t
  67. {
  68. uint32 r : 10;
  69. uint32 g : 10;
  70. uint32 b : 10;
  71. uint32 a : 2;
  72. inline int RTo10Bit( ) const { return ConvertTo10Bit<10>( r ); }
  73. inline int GTo10Bit( ) const { return ConvertTo10Bit<10>( g ); }
  74. inline int BTo10Bit( ) const { return ConvertTo10Bit<10>( b ); }
  75. inline int ATo10Bit( ) const { return ConvertTo10Bit<2>( a ); }
  76. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<10>( r10 ); }
  77. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<10>( g10 ); }
  78. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<10>( b10 ); }
  79. inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<10>( a10 ); }
  80. };
  81. struct BGRA1010102_t
  82. {
  83. uint32 b : 10;
  84. uint32 g : 10;
  85. uint32 r : 10;
  86. uint32 a : 2;
  87. inline int RTo10Bit( ) const { return ConvertTo10Bit<10>( r ); }
  88. inline int GTo10Bit( ) const { return ConvertTo10Bit<10>( g ); }
  89. inline int BTo10Bit( ) const { return ConvertTo10Bit<10>( b ); }
  90. inline int ATo10Bit( ) const { return ConvertTo10Bit<2>( a ); }
  91. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<10>( r10 ); }
  92. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<10>( g10 ); }
  93. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<10>( b10 ); }
  94. inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<10>( a10 ); }
  95. };
  96. struct BGRA8888_t
  97. {
  98. uint8 b; // change the order of names to change the
  99. uint8 g; // order of the output ARGB or BGRA, etc...
  100. uint8 r; // Last one is MSB, 1st is LSB.
  101. uint8 a;
  102. inline BGRA8888_t& operator=( const BGRA8888_t& in )
  103. {
  104. *( unsigned int * )this = *( unsigned int * )&in;
  105. return *this;
  106. }
  107. inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
  108. inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
  109. inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
  110. inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
  111. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
  112. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
  113. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
  114. inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
  115. };
  116. struct ABGR8888_t
  117. {
  118. uint8 a;
  119. uint8 b; // change the order of names to change the
  120. uint8 g; // order of the output ARGB or BGRA, etc...
  121. uint8 r; // Last one is MSB, 1st is LSB.
  122. inline ABGR8888_t& operator=( const BGRA8888_t& in )
  123. {
  124. r = in.r;
  125. g = in.g;
  126. b = in.b;
  127. a = in.a;
  128. return *this;
  129. }
  130. inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
  131. inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
  132. inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
  133. inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
  134. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
  135. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
  136. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
  137. inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
  138. };
  139. struct RGBA8888_t
  140. {
  141. uint8 r; // change the order of names to change the
  142. uint8 g; // order of the output ARGB or BGRA, etc...
  143. uint8 b; // Last one is MSB, 1st is LSB.
  144. uint8 a;
  145. inline RGBA8888_t& operator=( const BGRA8888_t& in )
  146. {
  147. r = in.r;
  148. g = in.g;
  149. b = in.b;
  150. a = in.a;
  151. return *this;
  152. }
  153. inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
  154. inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
  155. inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
  156. inline int ATo10Bit( ) const { return ConvertTo10Bit<8>( a ); }
  157. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
  158. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
  159. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
  160. inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<8>( a10 ); }
  161. };
  162. struct RGB888_t
  163. {
  164. uint8 r;
  165. uint8 g;
  166. uint8 b;
  167. inline RGB888_t& operator=( const BGRA8888_t& in )
  168. {
  169. r = in.r;
  170. g = in.g;
  171. b = in.b;
  172. return *this;
  173. }
  174. inline bool operator==( const RGB888_t& in ) const
  175. {
  176. return ( r == in.r ) && ( g == in.g ) && ( b == in.b );
  177. }
  178. inline bool operator!=( const RGB888_t& in ) const
  179. {
  180. return ( r != in.r ) || ( g != in.g ) || ( b != in.b );
  181. }
  182. inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
  183. inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
  184. inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
  185. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
  186. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
  187. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
  188. };
  189. struct BGR888_t
  190. {
  191. uint8 b;
  192. uint8 g;
  193. uint8 r;
  194. inline BGR888_t& operator=( const BGRA8888_t& in )
  195. {
  196. r = in.r;
  197. g = in.g;
  198. b = in.b;
  199. return *this;
  200. }
  201. inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
  202. inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
  203. inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
  204. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
  205. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
  206. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
  207. };
  208. struct BGRX8888_t
  209. {
  210. uint8 b;
  211. uint8 g;
  212. uint8 r;
  213. uint8 x;
  214. inline BGRX8888_t& operator=( const BGRA8888_t& in )
  215. {
  216. r = in.r;
  217. g = in.g;
  218. b = in.b;
  219. x = 255;
  220. return *this;
  221. }
  222. inline int RTo10Bit( ) const { return ConvertTo10Bit<8>( r ); }
  223. inline int GTo10Bit( ) const { return ConvertTo10Bit<8>( g ); }
  224. inline int BTo10Bit( ) const { return ConvertTo10Bit<8>( b ); }
  225. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<8>( r10 ); }
  226. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<8>( g10 ); }
  227. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<8>( b10 ); }
  228. };
  229. // 360 uses this structure for x86 dxt decoding
  230. #if defined( _X360 )
  231. #pragma bitfield_order( push, lsb_to_msb )
  232. #elif defined( _PS3 )
  233. #pragma ms_struct on
  234. #pragma reverse_bitfields on
  235. #endif
  236. struct BGR565_t
  237. {
  238. uint16 b : 5; // order of names changes
  239. uint16 g : 6; // byte order of output to 32 bit
  240. uint16 r : 5;
  241. inline BGR565_t& operator=( const BGRA8888_t& in )
  242. {
  243. r = in.r >> 3;
  244. g = in.g >> 2;
  245. b = in.b >> 3;
  246. return *this;
  247. }
  248. inline BGR565_t &Set( int red, int green, int blue )
  249. {
  250. r = red >> 3;
  251. g = green >> 2;
  252. b = blue >> 3;
  253. return *this;
  254. }
  255. inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
  256. inline int GTo10Bit( ) const { return ConvertTo10Bit<6>( g ); }
  257. inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
  258. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
  259. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<6>( g10 ); }
  260. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
  261. };
  262. #if defined( _X360 )
  263. #pragma bitfield_order( pop )
  264. #elif defined( _PS3 )
  265. #pragma ms_struct off
  266. #pragma reverse_bitfields off
  267. #endif
  268. struct BGRA5551_t
  269. {
  270. uint16 b : 5; // order of names changes
  271. uint16 g : 5; // byte order of output to 32 bit
  272. uint16 r : 5;
  273. uint16 a : 1;
  274. inline BGRA5551_t& operator=( const BGRA8888_t& in )
  275. {
  276. r = in.r >> 3;
  277. g = in.g >> 3;
  278. b = in.b >> 3;
  279. a = in.a >> 7;
  280. return *this;
  281. }
  282. inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
  283. inline int GTo10Bit( ) const { return ConvertTo10Bit<5>( g ); }
  284. inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
  285. inline int ATo10Bit( ) const { return ConvertTo10Bit<1>( a ); }
  286. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
  287. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<5>( g10 ); }
  288. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
  289. inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<1>( a10 ); }
  290. };
  291. struct BGRA4444_t
  292. {
  293. uint16 b : 4; // order of names changes
  294. uint16 g : 4; // byte order of output to 32 bit
  295. uint16 r : 4;
  296. uint16 a : 4;
  297. inline BGRA4444_t& operator=( const BGRA8888_t& in )
  298. {
  299. r = in.r >> 4;
  300. g = in.g >> 4;
  301. b = in.b >> 4;
  302. a = in.a >> 4;
  303. return *this;
  304. }
  305. inline int RTo10Bit( ) const { return ConvertTo10Bit<4>( r ); }
  306. inline int GTo10Bit( ) const { return ConvertTo10Bit<4>( g ); }
  307. inline int BTo10Bit( ) const { return ConvertTo10Bit<4>( b ); }
  308. inline int ATo10Bit( ) const { return ConvertTo10Bit<4>( a ); }
  309. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<4>( r10 ); }
  310. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<4>( g10 ); }
  311. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<4>( b10 ); }
  312. inline void AFrom10Bit( int a10 ) { a = ConvertFrom10Bit<4>( a10 ); }
  313. };
  314. struct RGBX5551_t
  315. {
  316. uint16 r : 5;
  317. uint16 g : 5;
  318. uint16 b : 5;
  319. uint16 x : 1;
  320. inline RGBX5551_t& operator=( const BGRA8888_t& in )
  321. {
  322. r = in.r >> 3;
  323. g = in.g >> 3;
  324. b = in.b >> 3;
  325. return *this;
  326. }
  327. inline int RTo10Bit( ) const { return ConvertTo10Bit<5>( r ); }
  328. inline int GTo10Bit( ) const { return ConvertTo10Bit<5>( g ); }
  329. inline int BTo10Bit( ) const { return ConvertTo10Bit<5>( b ); }
  330. inline void RFrom10Bit( int r10 ) { r = ConvertFrom10Bit<5>( r10 ); }
  331. inline void GFrom10Bit( int g10 ) { g = ConvertFrom10Bit<5>( g10 ); }
  332. inline void BFrom10Bit( int b10 ) { b = ConvertFrom10Bit<5>( b10 ); }
  333. };
  334. struct UV88_t
  335. {
  336. int8 u;
  337. int8 v;
  338. };
  339. struct UVWQ8888_t
  340. {
  341. int8 u;
  342. int8 v;
  343. int8 w;
  344. int8 q;
  345. };
  346. struct UVLX8888_t
  347. {
  348. int8 u;
  349. int8 v;
  350. uint8 l;
  351. uint8 x;
  352. };
  353. //-----------------------------------------------------------------------------
  354. // some important constants
  355. //-----------------------------------------------------------------------------
  356. #define ARTWORK_GAMMA ( 2.2f )
  357. #define IMAGE_MAX_DIM ( 2048 )
  358. //-----------------------------------------------------------------------------
  359. // information about each image format
  360. //-----------------------------------------------------------------------------
  361. struct ImageFormatInfo_t
  362. {
  363. const char* m_pName;
  364. uint8 m_nNumBytes;
  365. uint8 m_nNumRedBits;
  366. uint8 m_nNumGreenBits;
  367. uint8 m_nNumBlueBits;
  368. uint8 m_nNumAlphaBits;
  369. uint8 m_nNumDepthBits;
  370. uint8 m_nNumStencilBits;
  371. bool m_bIsCompressed:1;
  372. bool m_bIsFloat:1;
  373. bool m_bIsDepthFormat : 1;
  374. };
  375. //-----------------------------------------------------------------------------
  376. // Computes nice filters for a compression ratio
  377. //-----------------------------------------------------------------------------
  378. struct KernelInfo_t
  379. {
  380. float *m_pKernel;
  381. float *m_pInvKernel;
  382. int m_nWidth;
  383. int m_nHeight;
  384. int m_nDepth;
  385. int m_nDiameter;
  386. };
  387. //-----------------------------------------------------------------------------
  388. // Indicates the target console type that a given operation is for.
  389. // (e.g. you may be running on the PC but you're generating textures
  390. // for X360 or PS3, so IsPC, IsX360, etc. do not work)
  391. //-----------------------------------------------------------------------------
  392. enum VtfConsoleFormatType_t
  393. {
  394. VTF_CONSOLE_360,
  395. VTF_CONSOLE_PS3
  396. };
  397. //-----------------------------------------------------------------------------
  398. // Various methods related to pixelmaps and color formats
  399. //-----------------------------------------------------------------------------
  400. namespace ImageLoader
  401. {
  402. bool GetInfo( const char *fileName, int *width, int *height, enum ImageFormat *imageFormat, float *sourceGamma );
  403. // Generates a nice filter kernel
  404. void ComputeNiceFilterKernel( float flWRatio, float flHRatio, float flDRatio, KernelInfo_t *pKernel );
  405. void CleanupNiceFilterKernel( KernelInfo_t *pKernel );
  406. // adjustedheight received the height adjusted for compression (/4 for dxt)
  407. int GetMemRequired( int width, int height, int depth, ImageFormat imageFormat, bool mipmap, int *pAdjustedHeightOut = NULL );
  408. int GetMemRequired( int width, int height, int depth, int nMipmapCount, ImageFormat imageFormat, int *pAdjustedHeightOut = NULL );
  409. // This version is for mipmaps which are stored biggest level to smallest level in memory
  410. int GetMipMapLevelByteOffset( int width, int height, ImageFormat imageFormat, int skipMipLevels, int nDepth = 1 );
  411. // This version is for mipmaps which are stored smallest level to largest level in memory
  412. int GetMipMapLevelByteOffsetReverse( int nWidth, int nHeight, int nDepth, int nTotalMipCount, ImageFormat imageFormat, int nMipLevel );
  413. void GetMipMapLevelDimensions( int *width, int *height, int skipMipLevels );
  414. void GetMipMapLevelDimensions( int &nWidth, int &nHeight, int &nDepth, int nMipLevel );
  415. int GetNumMipMapLevels( int width, int height, int depth = 1 );
  416. bool Load( unsigned char *imageData, const char *fileName, int width, int height, ImageFormat imageFormat, float targetGamma, bool mipmap );
  417. bool Load( unsigned char *imageData, FILE *fp, int width, int height,
  418. enum ImageFormat imageFormat, float targetGamma, bool mipmap );
  419. // convert from any image format to any other image format.
  420. // return false if the conversion cannot be performed.
  421. // Strides denote the number of bytes per each line,
  422. // by default assumes width * # of bytes per pixel
  423. bool ConvertImageFormat( const unsigned char *src, enum ImageFormat srcImageFormat,
  424. unsigned char *dst, enum ImageFormat dstImageFormat,
  425. int width, int height, int srcStride = 0, int dstStride = 0 );
  426. // must be used in conjunction with ConvertImageFormat() to pre-swap and post-swap
  427. void PreConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width = 0, int stride = 0 );
  428. void PostConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width = 0, int stride = 0 );
  429. void ByteSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0 );
  430. bool IsFormatValidForConversion( ImageFormat fmt );
  431. //-----------------------------------------------------------------------------
  432. // convert back and forth from D3D format to ImageFormat, regardless of
  433. // whether it's supported or not
  434. // FIXME: Move into shaderapidx8/rendersystemdx9
  435. //-----------------------------------------------------------------------------
  436. ImageFormat D3DFormatToImageFormat( D3DFORMAT format );
  437. D3DFORMAT ImageFormatToD3DFormat( ImageFormat format );
  438. // Flags for ResampleRGBA8888
  439. enum
  440. {
  441. RESAMPLE_NORMALMAP = 0x1,
  442. RESAMPLE_ALPHATEST = 0x2,
  443. RESAMPLE_NICE_FILTER = 0x4,
  444. RESAMPLE_CLAMPS = 0x8,
  445. RESAMPLE_CLAMPT = 0x10,
  446. RESAMPLE_CLAMPU = 0x20,
  447. };
  448. struct ResampleInfo_t
  449. {
  450. ResampleInfo_t() : m_nFlags(0), m_flAlphaThreshhold(0.4f), m_flAlphaHiFreqThreshhold(0.4f), m_nSrcDepth(1), m_nDestDepth(1)
  451. {
  452. m_flColorScale[0] = 1.0f, m_flColorScale[1] = 1.0f, m_flColorScale[2] = 1.0f, m_flColorScale[3] = 1.0f;
  453. m_flColorGoal[0] = 0.0f, m_flColorGoal[1] = 0.0f, m_flColorGoal[2] = 0.0f, m_flColorGoal[3] = 0.0f;
  454. }
  455. unsigned char *m_pSrc;
  456. unsigned char *m_pDest;
  457. int m_nSrcWidth;
  458. int m_nSrcHeight;
  459. int m_nSrcDepth;
  460. int m_nDestWidth;
  461. int m_nDestHeight;
  462. int m_nDestDepth;
  463. float m_flSrcGamma;
  464. float m_flDestGamma;
  465. float m_flColorScale[4]; // Color scale factors RGBA
  466. float m_flColorGoal[4]; // Color goal values RGBA DestColor = ColorGoal + scale * (SrcColor - ColorGoal)
  467. float m_flAlphaThreshhold;
  468. float m_flAlphaHiFreqThreshhold;
  469. int m_nFlags;
  470. };
  471. bool ResampleRGBA8888( const ResampleInfo_t &info );
  472. bool ResampleRGBA16161616( const ResampleInfo_t &info );
  473. bool ResampleRGB323232F( const ResampleInfo_t &info );
  474. bool ResampleRGBA32323232F( const ResampleInfo_t &info );
  475. void ConvertNormalMapRGBA8888ToDUDVMapUVLX8888( const unsigned char *src, int width, int height, unsigned char *dst_ );
  476. void ConvertNormalMapRGBA8888ToDUDVMapUVWQ8888( const unsigned char *src, int width, int height, unsigned char *dst_ );
  477. void ConvertNormalMapRGBA8888ToDUDVMapUV88( const unsigned char *src, int width, int height, unsigned char *dst_ );
  478. void ConvertNormalMapARGB8888ToDXT5GA( const unsigned char *src, unsigned char *dst, int width, int height );
  479. void ConvertIA88ImageToNormalMapRGBA8888( const unsigned char *src, int width,
  480. int height, unsigned char *dst,
  481. float bumpScale );
  482. void NormalizeNormalMapRGBA8888( unsigned char *src, int numTexels );
  483. //-----------------------------------------------------------------------------
  484. // Gamma correction
  485. //-----------------------------------------------------------------------------
  486. void GammaCorrectRGBA8888( unsigned char *src, unsigned char* dst,
  487. int width, int height, int depth, float srcGamma, float dstGamma );
  488. //-----------------------------------------------------------------------------
  489. // Makes a gamma table
  490. //-----------------------------------------------------------------------------
  491. void ConstructGammaTable( unsigned char* pTable, float srcGamma, float dstGamma );
  492. //-----------------------------------------------------------------------------
  493. // Gamma corrects using a previously constructed gamma table
  494. //-----------------------------------------------------------------------------
  495. void GammaCorrectRGBA8888( unsigned char* pSrc, unsigned char* pDst,
  496. int width, int height, int depth, unsigned char* pGammaTable );
  497. //-----------------------------------------------------------------------------
  498. // Generates a number of mipmap levels
  499. //-----------------------------------------------------------------------------
  500. void GenerateMipmapLevels( unsigned char* pSrc, unsigned char* pDst, int width,
  501. int height, int depth, ImageFormat imageFormat, float srcGamma, float dstGamma,
  502. int numLevels = 0 );
  503. //-----------------------------------------------------------------------------
  504. // operations on square images (src and dst can be the same)
  505. //-----------------------------------------------------------------------------
  506. bool RotateImageLeft( const unsigned char *src, unsigned char *dst,
  507. int widthHeight, ImageFormat imageFormat );
  508. bool RotateImage180( const unsigned char *src, unsigned char *dst,
  509. int widthHeight, ImageFormat imageFormat );
  510. bool FlipImageVertically( void *pSrc, void *pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0 );
  511. bool FlipImageHorizontally( void *pSrc, void *pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0 );
  512. bool SwapAxes( unsigned char *src,
  513. int widthHeight, ImageFormat imageFormat );
  514. //-----------------------------------------------------------------------------
  515. // Returns info about each image format
  516. //-----------------------------------------------------------------------------
  517. const ImageFormatInfo_t &ImageFormatInfo( ImageFormat fmt );
  518. //-----------------------------------------------------------------------------
  519. // Gets the name of the image format
  520. //-----------------------------------------------------------------------------
  521. inline char const* GetName( ImageFormat fmt )
  522. {
  523. return ImageFormatInfo(fmt).m_pName;
  524. }
  525. //-----------------------------------------------------------------------------
  526. // Gets the size of the image format in bytes. Be careful - compressed formats will return 0
  527. //-----------------------------------------------------------------------------
  528. inline int SizeInBytes( ImageFormat fmt )
  529. {
  530. return ImageFormatInfo(fmt).m_nNumBytes;
  531. }
  532. /// return the byte size of a given w/h. Works with compressed formats
  533. inline int SizeInBytes( ImageFormat fmt, int nWidth, int nHeight )
  534. {
  535. ImageFormatInfo_t const &info = ImageFormatInfo( fmt );
  536. if ( info.m_bIsCompressed )
  537. {
  538. // !!BUG!! hardcoded 4x4 block size, dxt1, dxt5
  539. int nNumBytesPerBlock = 8;
  540. if ( fmt == IMAGE_FORMAT_DXT5 )
  541. {
  542. nNumBytesPerBlock = 16;
  543. }
  544. return nNumBytesPerBlock * ( ( nWidth + 3 ) / 4 ) * ( ( nHeight +3 )/ 4 );
  545. }
  546. else
  547. {
  548. return info.m_nNumBytes * nWidth * nHeight;
  549. }
  550. }
  551. //-----------------------------------------------------------------------------
  552. // Does the image format support transparency?
  553. //-----------------------------------------------------------------------------
  554. inline bool IsTransparent( ImageFormat fmt )
  555. {
  556. return ImageFormatInfo(fmt).m_nNumAlphaBits > 0;
  557. }
  558. //-----------------------------------------------------------------------------
  559. // Is the image format compressed?
  560. //-----------------------------------------------------------------------------
  561. inline bool IsCompressed( ImageFormat fmt )
  562. {
  563. return ImageFormatInfo(fmt).m_bIsCompressed;
  564. }
  565. //-----------------------------------------------------------------------------
  566. // Is the image format compressed?
  567. //-----------------------------------------------------------------------------
  568. inline bool IsDepthFormat( ImageFormat fmt )
  569. {
  570. return ImageFormatInfo(fmt).m_bIsDepthFormat;
  571. }
  572. //-----------------------------------------------------------------------------
  573. // Is any channel > 8 bits?
  574. //-----------------------------------------------------------------------------
  575. inline bool HasChannelLargerThan8Bits( ImageFormat fmt )
  576. {
  577. ImageFormatInfo_t info = ImageFormatInfo(fmt);
  578. return ( info.m_nNumRedBits > 8 || info.m_nNumGreenBits > 8 || info.m_nNumBlueBits > 8 || info.m_nNumAlphaBits > 8 );
  579. }
  580. inline bool IsFloatFormat( ImageFormat fmt )
  581. {
  582. return ( fmt == IMAGE_FORMAT_RGBA16161616F ) ||
  583. ( fmt == IMAGE_FORMAT_RG1616F ) ||
  584. ( fmt == IMAGE_FORMAT_R32F ) ||
  585. ( fmt == IMAGE_FORMAT_RG3232F ) ||
  586. ( fmt == IMAGE_FORMAT_RGB323232F ) ||
  587. ( fmt == IMAGE_FORMAT_RGBA32323232F );
  588. }
  589. inline bool IsRuntimeCompressed( ImageFormat fmt )
  590. {
  591. return ( fmt == IMAGE_FORMAT_DXT1_RUNTIME ) || ( fmt == IMAGE_FORMAT_DXT5_RUNTIME );
  592. }
  593. } // end namespace ImageLoader
  594. #endif // IMAGEFORMAT_H