Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
DirectXTexUtil.cpp
Go to the documentation of this file.
1 //-------------------------------------------------------------------------------------
2 // DirectXTexUtil.cpp
3 //
4 // DirectX Texture Library - Utilities
5 //
6 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
7 // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
8 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
9 // PARTICULAR PURPOSE.
10 //
11 // Copyright (c) Microsoft Corporation. All rights reserved.
12 //
13 // http://go.microsoft.com/fwlink/?LinkId=248926
14 //-------------------------------------------------------------------------------------
15 
16 #include "directxtexp.h"
17 
18 //-------------------------------------------------------------------------------------
19 // WIC Pixel Format Translation Data
20 //-------------------------------------------------------------------------------------
22 {
23  GUID wic;
24  DXGI_FORMAT format;
25  bool srgb;
26 };
27 
29 {
30  { GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT, false },
31 
32  { GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT, false },
33  { GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM, true },
34 
35  { GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM, true },
36  { GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM, true }, // DXGI 1.1
37  { GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM, true }, // DXGI 1.1
38 
39  { GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, true }, // DXGI 1.1
40  { GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM, true },
41 
42  { GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM, true },
43  { GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM, true },
44 
45  { GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT, false },
46  { GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT, false },
47  { GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM, true },
48  { GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM, true },
49 
50  { GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM, false },
51 
52  { GUID_WICPixelFormatBlackWhite, DXGI_FORMAT_R1_UNORM, false },
53 };
54 
55 static bool g_WIC2 = false;
56 
57 namespace DirectX
58 {
59 
60 //=====================================================================================
61 // WIC Utilities
62 //=====================================================================================
63 
64 _Use_decl_annotations_
65 DXGI_FORMAT _WICToDXGI( const GUID& guid )
66 {
67  for( size_t i=0; i < _countof(g_WICFormats); ++i )
68  {
69  if ( memcmp( &g_WICFormats[i].wic, &guid, sizeof(GUID) ) == 0 )
70  return g_WICFormats[i].format;
71  }
72 
73 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
74  if ( g_WIC2 )
75  {
76  if ( memcmp( &GUID_WICPixelFormat96bppRGBFloat, &guid, sizeof(GUID) ) == 0 )
77  return DXGI_FORMAT_R32G32B32_FLOAT;
78  }
79 #endif
80 
81  return DXGI_FORMAT_UNKNOWN;
82 }
83 
84 _Use_decl_annotations_
85 bool _DXGIToWIC( DXGI_FORMAT format, GUID& guid, bool ignoreRGBvsBGR )
86 {
87  switch( format )
88  {
89  case DXGI_FORMAT_R8G8B8A8_UNORM:
90  case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
91  if ( ignoreRGBvsBGR )
92  {
93  // If we are not doing conversion so don't really care about BGR vs RGB color-order,
94  // we can use the canonical WIC 32bppBGRA format which avoids an extra format conversion when using the WIC scaler
95  memcpy( &guid, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID) );
96  }
97  else
98  {
99  memcpy( &guid, &GUID_WICPixelFormat32bppRGBA, sizeof(GUID) );
100  }
101  return true;
102 
103  case DXGI_FORMAT_D32_FLOAT:
104  memcpy( &guid, &GUID_WICPixelFormat32bppGrayFloat, sizeof(GUID) );
105  return true;
106 
107  case DXGI_FORMAT_D16_UNORM:
108  memcpy( &guid, &GUID_WICPixelFormat16bppGray, sizeof(GUID) );
109  return true;
110 
111  case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
112  memcpy( &guid, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID) );
113  return true;
114 
115  case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
116  memcpy( &guid, &GUID_WICPixelFormat32bppBGR, sizeof(GUID) );
117  return true;
118 
119 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
120  case DXGI_FORMAT_R32G32B32_FLOAT:
121  if ( g_WIC2 )
122  {
123  memcpy( &guid, &GUID_WICPixelFormat96bppRGBFloat, sizeof(GUID) );
124  return true;
125  }
126  break;
127 #endif
128 
129  default:
130  for( size_t i=0; i < _countof(g_WICFormats); ++i )
131  {
132  if ( g_WICFormats[i].format == format )
133  {
134  memcpy( &guid, &g_WICFormats[i].wic, sizeof(GUID) );
135  return true;
136  }
137  }
138  break;
139  }
140 
141  memcpy( &guid, &GUID_NULL, sizeof(GUID) );
142  return false;
143 }
144 
145 DWORD _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetGUID )
146 {
147  DWORD srgb = 0;
148 
149  for( size_t i=0; i < _countof(g_WICFormats); ++i )
150  {
151  if ( memcmp( &g_WICFormats[i].wic, &sourceGUID, sizeof(GUID) ) == 0 )
152  {
153  if ( g_WICFormats[i].srgb )
154  srgb |= TEX_FILTER_SRGB_IN;
155  }
156 
157  if ( memcmp( &g_WICFormats[i].wic, &targetGUID, sizeof(GUID) ) == 0 )
158  {
159  if ( g_WICFormats[i].srgb )
160  srgb |= TEX_FILTER_SRGB_OUT;
161  }
162  }
163 
165  {
167  }
168 
169  return srgb;
170 }
171 
172 bool _IsWIC2()
173 {
174  return g_WIC2;
175 }
176 
177 IWICImagingFactory* _GetWIC()
178 {
179  static IWICImagingFactory* s_Factory = nullptr;
180 
181  if ( s_Factory )
182  return s_Factory;
183 
184 #if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
185  HRESULT hr = CoCreateInstance(
186  CLSID_WICImagingFactory2,
187  nullptr,
188  CLSCTX_INPROC_SERVER,
189  __uuidof(IWICImagingFactory2),
190  (LPVOID*)&s_Factory
191  );
192 
193  if ( SUCCEEDED(hr) )
194  {
195  // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed
196  g_WIC2 = true;
197  }
198  else
199  {
200  hr = CoCreateInstance(
201  CLSID_WICImagingFactory1,
202  nullptr,
203  CLSCTX_INPROC_SERVER,
204  __uuidof(IWICImagingFactory),
205  (LPVOID*)&s_Factory
206  );
207 
208  if ( FAILED(hr) )
209  {
210  s_Factory = nullptr;
211  return nullptr;
212  }
213  }
214 #else
215  HRESULT hr = CoCreateInstance(
216  CLSID_WICImagingFactory,
217  nullptr,
218  CLSCTX_INPROC_SERVER,
219  __uuidof(IWICImagingFactory),
220  (LPVOID*)&s_Factory
221  );
222 
223  if ( FAILED(hr) )
224  {
225  s_Factory = nullptr;
226  return nullptr;
227  }
228 #endif
229 
230  return s_Factory;
231 }
232 
233 
234 //-------------------------------------------------------------------------------------
235 // Public helper function to get common WIC codec GUIDs
236 //-------------------------------------------------------------------------------------
237 _Use_decl_annotations_
238 REFGUID GetWICCodec( WICCodecs codec )
239 {
240  switch( codec )
241  {
242  case WIC_CODEC_BMP:
243  return GUID_ContainerFormatBmp;
244 
245  case WIC_CODEC_JPEG:
246  return GUID_ContainerFormatJpeg;
247 
248  case WIC_CODEC_PNG:
249  return GUID_ContainerFormatPng;
250 
251  case WIC_CODEC_TIFF:
252  return GUID_ContainerFormatTiff;
253 
254  case WIC_CODEC_GIF:
255  return GUID_ContainerFormatGif;
256 
257  case WIC_CODEC_WMP:
258  return GUID_ContainerFormatWmp;
259 
260  case WIC_CODEC_ICO:
261  return GUID_ContainerFormatIco;
262 
263  default:
264  return GUID_NULL;
265  }
266 }
267 
268 
269 //=====================================================================================
270 // DXGI Format Utilities
271 //=====================================================================================
272 
273 //-------------------------------------------------------------------------------------
274 // Returns bits-per-pixel for a given DXGI format, or 0 on failure
275 //-------------------------------------------------------------------------------------
276 _Use_decl_annotations_
277 size_t BitsPerPixel( DXGI_FORMAT fmt )
278 {
279  switch( static_cast<int>(fmt) )
280  {
281  case DXGI_FORMAT_R32G32B32A32_TYPELESS:
282  case DXGI_FORMAT_R32G32B32A32_FLOAT:
283  case DXGI_FORMAT_R32G32B32A32_UINT:
284  case DXGI_FORMAT_R32G32B32A32_SINT:
285  return 128;
286 
287  case DXGI_FORMAT_R32G32B32_TYPELESS:
288  case DXGI_FORMAT_R32G32B32_FLOAT:
289  case DXGI_FORMAT_R32G32B32_UINT:
290  case DXGI_FORMAT_R32G32B32_SINT:
291  return 96;
292 
293  case DXGI_FORMAT_R16G16B16A16_TYPELESS:
294  case DXGI_FORMAT_R16G16B16A16_FLOAT:
295  case DXGI_FORMAT_R16G16B16A16_UNORM:
296  case DXGI_FORMAT_R16G16B16A16_UINT:
297  case DXGI_FORMAT_R16G16B16A16_SNORM:
298  case DXGI_FORMAT_R16G16B16A16_SINT:
299  case DXGI_FORMAT_R32G32_TYPELESS:
300  case DXGI_FORMAT_R32G32_FLOAT:
301  case DXGI_FORMAT_R32G32_UINT:
302  case DXGI_FORMAT_R32G32_SINT:
303  case DXGI_FORMAT_R32G8X24_TYPELESS:
304  case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
305  case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
306  case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
307  case DXGI_FORMAT_Y416:
308  case DXGI_FORMAT_Y210:
309  case DXGI_FORMAT_Y216:
310  return 64;
311 
312  case DXGI_FORMAT_R10G10B10A2_TYPELESS:
313  case DXGI_FORMAT_R10G10B10A2_UNORM:
314  case DXGI_FORMAT_R10G10B10A2_UINT:
315  case DXGI_FORMAT_R11G11B10_FLOAT:
316  case DXGI_FORMAT_R8G8B8A8_TYPELESS:
317  case DXGI_FORMAT_R8G8B8A8_UNORM:
318  case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
319  case DXGI_FORMAT_R8G8B8A8_UINT:
320  case DXGI_FORMAT_R8G8B8A8_SNORM:
321  case DXGI_FORMAT_R8G8B8A8_SINT:
322  case DXGI_FORMAT_R16G16_TYPELESS:
323  case DXGI_FORMAT_R16G16_FLOAT:
324  case DXGI_FORMAT_R16G16_UNORM:
325  case DXGI_FORMAT_R16G16_UINT:
326  case DXGI_FORMAT_R16G16_SNORM:
327  case DXGI_FORMAT_R16G16_SINT:
328  case DXGI_FORMAT_R32_TYPELESS:
329  case DXGI_FORMAT_D32_FLOAT:
330  case DXGI_FORMAT_R32_FLOAT:
331  case DXGI_FORMAT_R32_UINT:
332  case DXGI_FORMAT_R32_SINT:
333  case DXGI_FORMAT_R24G8_TYPELESS:
334  case DXGI_FORMAT_D24_UNORM_S8_UINT:
335  case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
336  case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
337  case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
338  case DXGI_FORMAT_R8G8_B8G8_UNORM:
339  case DXGI_FORMAT_G8R8_G8B8_UNORM:
340  case DXGI_FORMAT_B8G8R8A8_UNORM:
341  case DXGI_FORMAT_B8G8R8X8_UNORM:
342  case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
343  case DXGI_FORMAT_B8G8R8A8_TYPELESS:
344  case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
345  case DXGI_FORMAT_B8G8R8X8_TYPELESS:
346  case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
347  case DXGI_FORMAT_AYUV:
348  case DXGI_FORMAT_Y410:
349  case DXGI_FORMAT_YUY2:
350  case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */:
351  case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */:
352  return 32;
353 
354  case DXGI_FORMAT_P010:
355  case DXGI_FORMAT_P016:
356  case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */:
357  case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */:
358  case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */:
359  return 24;
360 
361  case DXGI_FORMAT_R8G8_TYPELESS:
362  case DXGI_FORMAT_R8G8_UNORM:
363  case DXGI_FORMAT_R8G8_UINT:
364  case DXGI_FORMAT_R8G8_SNORM:
365  case DXGI_FORMAT_R8G8_SINT:
366  case DXGI_FORMAT_R16_TYPELESS:
367  case DXGI_FORMAT_R16_FLOAT:
368  case DXGI_FORMAT_D16_UNORM:
369  case DXGI_FORMAT_R16_UNORM:
370  case DXGI_FORMAT_R16_UINT:
371  case DXGI_FORMAT_R16_SNORM:
372  case DXGI_FORMAT_R16_SINT:
373  case DXGI_FORMAT_B5G6R5_UNORM:
374  case DXGI_FORMAT_B5G5R5A1_UNORM:
375  case DXGI_FORMAT_A8P8:
376  case DXGI_FORMAT_B4G4R4A4_UNORM:
377  return 16;
378 
379  case DXGI_FORMAT_NV12:
380  case DXGI_FORMAT_420_OPAQUE:
381  case DXGI_FORMAT_NV11:
382  return 12;
383 
384  case DXGI_FORMAT_R8_TYPELESS:
385  case DXGI_FORMAT_R8_UNORM:
386  case DXGI_FORMAT_R8_UINT:
387  case DXGI_FORMAT_R8_SNORM:
388  case DXGI_FORMAT_R8_SINT:
389  case DXGI_FORMAT_A8_UNORM:
390  case DXGI_FORMAT_AI44:
391  case DXGI_FORMAT_IA44:
392  case DXGI_FORMAT_P8:
393  return 8;
394 
395  case DXGI_FORMAT_R1_UNORM:
396  return 1;
397 
398  case DXGI_FORMAT_BC1_TYPELESS:
399  case DXGI_FORMAT_BC1_UNORM:
400  case DXGI_FORMAT_BC1_UNORM_SRGB:
401  case DXGI_FORMAT_BC4_TYPELESS:
402  case DXGI_FORMAT_BC4_UNORM:
403  case DXGI_FORMAT_BC4_SNORM:
404  return 4;
405 
406  case DXGI_FORMAT_BC2_TYPELESS:
407  case DXGI_FORMAT_BC2_UNORM:
408  case DXGI_FORMAT_BC2_UNORM_SRGB:
409  case DXGI_FORMAT_BC3_TYPELESS:
410  case DXGI_FORMAT_BC3_UNORM:
411  case DXGI_FORMAT_BC3_UNORM_SRGB:
412  case DXGI_FORMAT_BC5_TYPELESS:
413  case DXGI_FORMAT_BC5_UNORM:
414  case DXGI_FORMAT_BC5_SNORM:
415  case DXGI_FORMAT_BC6H_TYPELESS:
416  case DXGI_FORMAT_BC6H_UF16:
417  case DXGI_FORMAT_BC6H_SF16:
418  case DXGI_FORMAT_BC7_TYPELESS:
419  case DXGI_FORMAT_BC7_UNORM:
420  case DXGI_FORMAT_BC7_UNORM_SRGB:
421  return 8;
422 
423  default:
424  return 0;
425  }
426 }
427 
428 
429 //-------------------------------------------------------------------------------------
430 // Returns bits-per-color-channel for a given DXGI format, or 0 on failure
431 // For mixed formats, it returns the largest color-depth in the format
432 //-------------------------------------------------------------------------------------
433 _Use_decl_annotations_
434 size_t BitsPerColor( DXGI_FORMAT fmt )
435 {
436  switch( static_cast<int>(fmt) )
437  {
438  case DXGI_FORMAT_R32G32B32A32_TYPELESS:
439  case DXGI_FORMAT_R32G32B32A32_FLOAT:
440  case DXGI_FORMAT_R32G32B32A32_UINT:
441  case DXGI_FORMAT_R32G32B32A32_SINT:
442  case DXGI_FORMAT_R32G32B32_TYPELESS:
443  case DXGI_FORMAT_R32G32B32_FLOAT:
444  case DXGI_FORMAT_R32G32B32_UINT:
445  case DXGI_FORMAT_R32G32B32_SINT:
446  case DXGI_FORMAT_R32G32_TYPELESS:
447  case DXGI_FORMAT_R32G32_FLOAT:
448  case DXGI_FORMAT_R32G32_UINT:
449  case DXGI_FORMAT_R32G32_SINT:
450  case DXGI_FORMAT_R32G8X24_TYPELESS:
451  case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
452  case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
453  case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
454  case DXGI_FORMAT_R32_TYPELESS:
455  case DXGI_FORMAT_D32_FLOAT:
456  case DXGI_FORMAT_R32_FLOAT:
457  case DXGI_FORMAT_R32_UINT:
458  case DXGI_FORMAT_R32_SINT:
459  return 32;
460 
461  case DXGI_FORMAT_R24G8_TYPELESS:
462  case DXGI_FORMAT_D24_UNORM_S8_UINT:
463  case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
464  case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
465  return 24;
466 
467  case DXGI_FORMAT_R16G16B16A16_TYPELESS:
468  case DXGI_FORMAT_R16G16B16A16_FLOAT:
469  case DXGI_FORMAT_R16G16B16A16_UNORM:
470  case DXGI_FORMAT_R16G16B16A16_UINT:
471  case DXGI_FORMAT_R16G16B16A16_SNORM:
472  case DXGI_FORMAT_R16G16B16A16_SINT:
473  case DXGI_FORMAT_R16G16_TYPELESS:
474  case DXGI_FORMAT_R16G16_FLOAT:
475  case DXGI_FORMAT_R16G16_UNORM:
476  case DXGI_FORMAT_R16G16_UINT:
477  case DXGI_FORMAT_R16G16_SNORM:
478  case DXGI_FORMAT_R16G16_SINT:
479  case DXGI_FORMAT_R16_TYPELESS:
480  case DXGI_FORMAT_R16_FLOAT:
481  case DXGI_FORMAT_D16_UNORM:
482  case DXGI_FORMAT_R16_UNORM:
483  case DXGI_FORMAT_R16_UINT:
484  case DXGI_FORMAT_R16_SNORM:
485  case DXGI_FORMAT_R16_SINT:
486  case DXGI_FORMAT_BC6H_TYPELESS:
487  case DXGI_FORMAT_BC6H_UF16:
488  case DXGI_FORMAT_BC6H_SF16:
489  case DXGI_FORMAT_Y416:
490  case DXGI_FORMAT_P016:
491  case DXGI_FORMAT_Y216:
492  return 16;
493 
494  case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
495  return 14;
496 
497  case DXGI_FORMAT_R11G11B10_FLOAT:
498  return 11;
499 
500  case DXGI_FORMAT_R10G10B10A2_TYPELESS:
501  case DXGI_FORMAT_R10G10B10A2_UNORM:
502  case DXGI_FORMAT_R10G10B10A2_UINT:
503  case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
504  case DXGI_FORMAT_Y410:
505  case DXGI_FORMAT_P010:
506  case DXGI_FORMAT_Y210:
507  return 10;
508 
509  case DXGI_FORMAT_R8G8B8A8_TYPELESS:
510  case DXGI_FORMAT_R8G8B8A8_UNORM:
511  case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
512  case DXGI_FORMAT_R8G8B8A8_UINT:
513  case DXGI_FORMAT_R8G8B8A8_SNORM:
514  case DXGI_FORMAT_R8G8B8A8_SINT:
515  case DXGI_FORMAT_R8G8_TYPELESS:
516  case DXGI_FORMAT_R8G8_UNORM:
517  case DXGI_FORMAT_R8G8_UINT:
518  case DXGI_FORMAT_R8G8_SNORM:
519  case DXGI_FORMAT_R8G8_SINT:
520  case DXGI_FORMAT_R8_TYPELESS:
521  case DXGI_FORMAT_R8_UNORM:
522  case DXGI_FORMAT_R8_UINT:
523  case DXGI_FORMAT_R8_SNORM:
524  case DXGI_FORMAT_R8_SINT:
525  case DXGI_FORMAT_A8_UNORM:
526  case DXGI_FORMAT_R8G8_B8G8_UNORM:
527  case DXGI_FORMAT_G8R8_G8B8_UNORM:
528  case DXGI_FORMAT_BC4_TYPELESS:
529  case DXGI_FORMAT_BC4_UNORM:
530  case DXGI_FORMAT_BC4_SNORM:
531  case DXGI_FORMAT_BC5_TYPELESS:
532  case DXGI_FORMAT_BC5_UNORM:
533  case DXGI_FORMAT_BC5_SNORM:
534  case DXGI_FORMAT_B8G8R8A8_UNORM:
535  case DXGI_FORMAT_B8G8R8X8_UNORM:
536  case DXGI_FORMAT_B8G8R8A8_TYPELESS:
537  case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
538  case DXGI_FORMAT_B8G8R8X8_TYPELESS:
539  case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
540  case DXGI_FORMAT_AYUV:
541  case DXGI_FORMAT_NV12:
542  case DXGI_FORMAT_420_OPAQUE:
543  case DXGI_FORMAT_YUY2:
544  case DXGI_FORMAT_NV11:
545  return 8;
546 
547  case DXGI_FORMAT_BC7_TYPELESS:
548  case DXGI_FORMAT_BC7_UNORM:
549  case DXGI_FORMAT_BC7_UNORM_SRGB:
550  return 7;
551 
552  case DXGI_FORMAT_BC1_TYPELESS:
553  case DXGI_FORMAT_BC1_UNORM:
554  case DXGI_FORMAT_BC1_UNORM_SRGB:
555  case DXGI_FORMAT_BC2_TYPELESS:
556  case DXGI_FORMAT_BC2_UNORM:
557  case DXGI_FORMAT_BC2_UNORM_SRGB:
558  case DXGI_FORMAT_BC3_TYPELESS:
559  case DXGI_FORMAT_BC3_UNORM:
560  case DXGI_FORMAT_BC3_UNORM_SRGB:
561  case DXGI_FORMAT_B5G6R5_UNORM:
562  return 6;
563 
564  case DXGI_FORMAT_B5G5R5A1_UNORM:
565  return 5;
566 
567  case DXGI_FORMAT_B4G4R4A4_UNORM:
568  return 4;
569 
570  case DXGI_FORMAT_R1_UNORM:
571  return 1;
572 
573  case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */:
574  case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */:
575  // These are Xbox One platform specific types
576  return 10;
577 
578  case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */:
579  case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */:
580  case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */:
581  // These are Xbox One platform specific types
582  return 16;
583 
584  case DXGI_FORMAT_AI44:
585  case DXGI_FORMAT_IA44:
586  case DXGI_FORMAT_P8:
587  case DXGI_FORMAT_A8P8:
588  // Palettized formats return 0 for this function
589 
590  default:
591  return 0;
592  }
593 }
594 
595 
596 //-------------------------------------------------------------------------------------
597 // Computes the image row pitch in bytes, and the slice ptich (size in bytes of the image)
598 // based on DXGI format, width, and height
599 //-------------------------------------------------------------------------------------
600 _Use_decl_annotations_
601 void ComputePitch( DXGI_FORMAT fmt, size_t width, size_t height,
602  size_t& rowPitch, size_t& slicePitch, DWORD flags )
603 {
604  assert( IsValid(fmt) );
605 
606  if ( IsCompressed(fmt) )
607  {
608  size_t bpb = ( fmt == DXGI_FORMAT_BC1_TYPELESS
609  || fmt == DXGI_FORMAT_BC1_UNORM
610  || fmt == DXGI_FORMAT_BC1_UNORM_SRGB
611  || fmt == DXGI_FORMAT_BC4_TYPELESS
612  || fmt == DXGI_FORMAT_BC4_UNORM
613  || fmt == DXGI_FORMAT_BC4_SNORM) ? 8 : 16;
614  size_t nbw = std::max<size_t>( 1, (width + 3) / 4 );
615  size_t nbh = std::max<size_t>( 1, (height + 3) / 4 );
616  rowPitch = nbw * bpb;
617 
618  slicePitch = rowPitch * nbh;
619  }
620  else if ( IsPacked(fmt) )
621  {
622  size_t bpe = ( fmt == DXGI_FORMAT_Y210 || fmt == DXGI_FORMAT_Y216 ) ? 8 : 4;
623  rowPitch = ( ( width + 1 ) >> 1 ) * bpe;
624 
625  slicePitch = rowPitch * height;
626  }
627  else if ( fmt == DXGI_FORMAT_NV11 )
628  {
629  rowPitch = ( ( width + 3 ) >> 2 ) * 4;
630 
631  // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
632  slicePitch = rowPitch * height * 2;
633  }
634  else if ( IsPlanar(fmt) )
635  {
636  size_t bpe = ( fmt == DXGI_FORMAT_P010 || fmt == DXGI_FORMAT_P016
637  || fmt == DXGI_FORMAT(118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */)
638  || fmt == DXGI_FORMAT(119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */)
639  || fmt == DXGI_FORMAT(120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */) ) ? 4 : 2;
640  rowPitch = ( ( width + 1 ) >> 1 ) * bpe;
641 
642  slicePitch = rowPitch * ( height + ( ( height + 1 ) >> 1 ) );
643  }
644  else
645  {
646  size_t bpp;
647 
648  if ( flags & CP_FLAGS_24BPP )
649  bpp = 24;
650  else if ( flags & CP_FLAGS_16BPP )
651  bpp = 16;
652  else if ( flags & CP_FLAGS_8BPP )
653  bpp = 8;
654  else
655  bpp = BitsPerPixel( fmt );
656 
657  if ( flags & CP_FLAGS_LEGACY_DWORD )
658  {
659  // Special computation for some incorrectly created DDS files based on
660  // legacy DirectDraw assumptions about pitch alignment
661  rowPitch = ( ( width * bpp + 31 ) / 32 ) * sizeof(uint32_t);
662  slicePitch = rowPitch * height;
663  }
664  else if ( flags & CP_FLAGS_PARAGRAPH )
665  {
666  rowPitch = ( ( width * bpp + 127 ) / 128 ) * 16;
667  slicePitch = rowPitch * height;
668  }
669  else
670  {
671  rowPitch = ( width * bpp + 7 ) / 8;
672  slicePitch = rowPitch * height;
673  }
674  }
675 }
676 
677 
678 //-------------------------------------------------------------------------------------
679 // Converts to an SRGB equivalent type if available
680 //-------------------------------------------------------------------------------------
681 _Use_decl_annotations_
682 DXGI_FORMAT MakeSRGB( DXGI_FORMAT fmt )
683 {
684  switch( fmt )
685  {
686  case DXGI_FORMAT_R8G8B8A8_UNORM:
687  return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
688 
689  case DXGI_FORMAT_BC1_UNORM:
690  return DXGI_FORMAT_BC1_UNORM_SRGB;
691 
692  case DXGI_FORMAT_BC2_UNORM:
693  return DXGI_FORMAT_BC2_UNORM_SRGB;
694 
695  case DXGI_FORMAT_BC3_UNORM:
696  return DXGI_FORMAT_BC3_UNORM_SRGB;
697 
698  case DXGI_FORMAT_B8G8R8A8_UNORM:
699  return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
700 
701  case DXGI_FORMAT_B8G8R8X8_UNORM:
702  return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
703 
704  case DXGI_FORMAT_BC7_UNORM:
705  return DXGI_FORMAT_BC7_UNORM_SRGB;
706 
707  default:
708  return fmt;
709  }
710 }
711 
712 
713 //-------------------------------------------------------------------------------------
714 // Converts to a format to an equivalent TYPELESS format if available
715 //-------------------------------------------------------------------------------------
716 _Use_decl_annotations_
717 DXGI_FORMAT MakeTypeless( DXGI_FORMAT fmt )
718 {
719  switch( fmt )
720  {
721  case DXGI_FORMAT_R32G32B32A32_FLOAT:
722  case DXGI_FORMAT_R32G32B32A32_UINT:
723  case DXGI_FORMAT_R32G32B32A32_SINT:
724  return DXGI_FORMAT_R32G32B32A32_TYPELESS;
725 
726  case DXGI_FORMAT_R32G32B32_FLOAT:
727  case DXGI_FORMAT_R32G32B32_UINT:
728  case DXGI_FORMAT_R32G32B32_SINT:
729  return DXGI_FORMAT_R32G32B32_TYPELESS;
730 
731  case DXGI_FORMAT_R16G16B16A16_FLOAT:
732  case DXGI_FORMAT_R16G16B16A16_UNORM:
733  case DXGI_FORMAT_R16G16B16A16_UINT:
734  case DXGI_FORMAT_R16G16B16A16_SNORM:
735  case DXGI_FORMAT_R16G16B16A16_SINT:
736  return DXGI_FORMAT_R16G16B16A16_TYPELESS;
737 
738  case DXGI_FORMAT_R32G32_FLOAT:
739  case DXGI_FORMAT_R32G32_UINT:
740  case DXGI_FORMAT_R32G32_SINT:
741  return DXGI_FORMAT_R32G32_TYPELESS;
742 
743  case DXGI_FORMAT_R10G10B10A2_UNORM:
744  case DXGI_FORMAT_R10G10B10A2_UINT:
745  return DXGI_FORMAT_R10G10B10A2_TYPELESS;
746 
747  case DXGI_FORMAT_R8G8B8A8_UNORM:
748  case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
749  case DXGI_FORMAT_R8G8B8A8_UINT:
750  case DXGI_FORMAT_R8G8B8A8_SNORM:
751  case DXGI_FORMAT_R8G8B8A8_SINT:
752  return DXGI_FORMAT_R8G8B8A8_TYPELESS;
753 
754  case DXGI_FORMAT_R16G16_FLOAT:
755  case DXGI_FORMAT_R16G16_UNORM:
756  case DXGI_FORMAT_R16G16_UINT:
757  case DXGI_FORMAT_R16G16_SNORM:
758  case DXGI_FORMAT_R16G16_SINT:
759  return DXGI_FORMAT_R16G16_TYPELESS;
760 
761  case DXGI_FORMAT_D32_FLOAT:
762  case DXGI_FORMAT_R32_FLOAT:
763  case DXGI_FORMAT_R32_UINT:
764  case DXGI_FORMAT_R32_SINT:
765  return DXGI_FORMAT_R32_TYPELESS;
766 
767  case DXGI_FORMAT_R8G8_UNORM:
768  case DXGI_FORMAT_R8G8_UINT:
769  case DXGI_FORMAT_R8G8_SNORM:
770  case DXGI_FORMAT_R8G8_SINT:
771  return DXGI_FORMAT_R8G8_TYPELESS;
772 
773  case DXGI_FORMAT_R16_FLOAT:
774  case DXGI_FORMAT_D16_UNORM:
775  case DXGI_FORMAT_R16_UNORM:
776  case DXGI_FORMAT_R16_UINT:
777  case DXGI_FORMAT_R16_SNORM:
778  case DXGI_FORMAT_R16_SINT:
779  return DXGI_FORMAT_R16_TYPELESS;
780 
781  case DXGI_FORMAT_R8_UNORM:
782  case DXGI_FORMAT_R8_UINT:
783  case DXGI_FORMAT_R8_SNORM:
784  case DXGI_FORMAT_R8_SINT:
785  case DXGI_FORMAT_A8_UNORM:
786  return DXGI_FORMAT_R8_TYPELESS;
787 
788  case DXGI_FORMAT_BC1_UNORM:
789  case DXGI_FORMAT_BC1_UNORM_SRGB:
790  return DXGI_FORMAT_BC1_TYPELESS;
791 
792  case DXGI_FORMAT_BC2_UNORM:
793  case DXGI_FORMAT_BC2_UNORM_SRGB:
794  return DXGI_FORMAT_BC2_TYPELESS;
795 
796  case DXGI_FORMAT_BC3_UNORM:
797  case DXGI_FORMAT_BC3_UNORM_SRGB:
798  return DXGI_FORMAT_BC3_TYPELESS;
799 
800  case DXGI_FORMAT_BC4_UNORM:
801  case DXGI_FORMAT_BC4_SNORM:
802  return DXGI_FORMAT_BC4_TYPELESS;
803 
804  case DXGI_FORMAT_BC5_UNORM:
805  case DXGI_FORMAT_BC5_SNORM:
806  return DXGI_FORMAT_BC5_TYPELESS;
807 
808  case DXGI_FORMAT_B8G8R8A8_UNORM:
809  case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
810  return DXGI_FORMAT_B8G8R8A8_TYPELESS;
811 
812  case DXGI_FORMAT_B8G8R8X8_UNORM:
813  case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
814  return DXGI_FORMAT_B8G8R8X8_TYPELESS;
815 
816  case DXGI_FORMAT_BC6H_UF16:
817  case DXGI_FORMAT_BC6H_SF16:
818  return DXGI_FORMAT_BC6H_TYPELESS;
819 
820  case DXGI_FORMAT_BC7_UNORM:
821  case DXGI_FORMAT_BC7_UNORM_SRGB:
822  return DXGI_FORMAT_BC7_TYPELESS;
823 
824  default:
825  return fmt;
826  }
827 }
828 
829 
830 //-------------------------------------------------------------------------------------
831 // Converts to a TYPELESS format to an equivalent UNORM format if available
832 //-------------------------------------------------------------------------------------
833 _Use_decl_annotations_
834 DXGI_FORMAT MakeTypelessUNORM( DXGI_FORMAT fmt )
835 {
836  switch( fmt )
837  {
838  case DXGI_FORMAT_R16G16B16A16_TYPELESS:
839  return DXGI_FORMAT_R16G16B16A16_UNORM;
840 
841  case DXGI_FORMAT_R10G10B10A2_TYPELESS:
842  return DXGI_FORMAT_R10G10B10A2_UNORM;
843 
844  case DXGI_FORMAT_R8G8B8A8_TYPELESS:
845  return DXGI_FORMAT_R8G8B8A8_UNORM;
846 
847  case DXGI_FORMAT_R16G16_TYPELESS:
848  return DXGI_FORMAT_R16G16_UNORM;
849 
850  case DXGI_FORMAT_R8G8_TYPELESS:
851  return DXGI_FORMAT_R8G8_UNORM;
852 
853  case DXGI_FORMAT_R16_TYPELESS:
854  return DXGI_FORMAT_R16_UNORM;
855 
856  case DXGI_FORMAT_R8_TYPELESS:
857  return DXGI_FORMAT_R8_UNORM;
858 
859  case DXGI_FORMAT_BC1_TYPELESS:
860  return DXGI_FORMAT_BC1_UNORM;
861 
862  case DXGI_FORMAT_BC2_TYPELESS:
863  return DXGI_FORMAT_BC2_UNORM;
864 
865  case DXGI_FORMAT_BC3_TYPELESS:
866  return DXGI_FORMAT_BC3_UNORM;
867 
868  case DXGI_FORMAT_BC4_TYPELESS:
869  return DXGI_FORMAT_BC4_UNORM;
870 
871  case DXGI_FORMAT_BC5_TYPELESS:
872  return DXGI_FORMAT_BC5_UNORM;
873 
874  case DXGI_FORMAT_B8G8R8A8_TYPELESS:
875  return DXGI_FORMAT_B8G8R8A8_UNORM;
876 
877  case DXGI_FORMAT_B8G8R8X8_TYPELESS:
878  return DXGI_FORMAT_B8G8R8X8_UNORM;
879 
880  case DXGI_FORMAT_BC7_TYPELESS:
881  return DXGI_FORMAT_BC7_UNORM;
882 
883  default:
884  return fmt;
885  }
886 }
887 
888 
889 //-------------------------------------------------------------------------------------
890 // Converts to a TYPELESS format to an equivalent FLOAT format if available
891 //-------------------------------------------------------------------------------------
892 _Use_decl_annotations_
893 DXGI_FORMAT MakeTypelessFLOAT( DXGI_FORMAT fmt )
894 {
895  switch( fmt )
896  {
897  case DXGI_FORMAT_R32G32B32A32_TYPELESS:
898  return DXGI_FORMAT_R32G32B32A32_FLOAT;
899 
900  case DXGI_FORMAT_R32G32B32_TYPELESS:
901  return DXGI_FORMAT_R32G32B32_FLOAT;
902 
903  case DXGI_FORMAT_R16G16B16A16_TYPELESS:
904  return DXGI_FORMAT_R16G16B16A16_FLOAT;
905 
906  case DXGI_FORMAT_R32G32_TYPELESS:
907  return DXGI_FORMAT_R32G32_FLOAT;
908 
909  case DXGI_FORMAT_R16G16_TYPELESS:
910  return DXGI_FORMAT_R16G16_FLOAT;
911 
912  case DXGI_FORMAT_R32_TYPELESS:
913  return DXGI_FORMAT_R32_FLOAT;
914 
915  case DXGI_FORMAT_R16_TYPELESS:
916  return DXGI_FORMAT_R16_FLOAT;
917 
918  default:
919  return fmt;
920  }
921 }
922 
923 
924 //=====================================================================================
925 // TexMetadata
926 //=====================================================================================
927 
928 _Use_decl_annotations_
929 size_t TexMetadata::ComputeIndex( size_t mip, size_t item, size_t slice ) const
930 {
931  if ( mip >= mipLevels )
932  return size_t(-1);
933 
934  switch( dimension )
935  {
938  if ( slice > 0 )
939  return size_t(-1);
940 
941  if ( item >= arraySize )
942  return size_t(-1);
943 
944  return (item*( mipLevels ) + mip);
945 
947  if ( item > 0 )
948  {
949  // No support for arrays of volumes
950  return size_t(-1);
951  }
952  else
953  {
954  size_t index = 0;
955  size_t d = depth;
956 
957  for( size_t level = 0; level < mip; ++level )
958  {
959  index += d;
960  if ( d > 1 )
961  d >>= 1;
962  }
963 
964  if ( slice >= d )
965  return size_t(-1);
966 
967  index += slice;
968 
969  return index;
970  }
971  break;
972 
973  default:
974  return size_t(-1);
975  }
976 }
977 
978 
979 //=====================================================================================
980 // Blob - Bitmap image container
981 //=====================================================================================
982 
984 {
985  if ( this != &moveFrom )
986  {
987  Release();
988 
989  _buffer = moveFrom._buffer;
990  _size = moveFrom._size;
991 
992  moveFrom._buffer = nullptr;
993  moveFrom._size = 0;
994  }
995  return *this;
996 }
997 
999 {
1000  if ( _buffer )
1001  {
1002  _aligned_free( _buffer );
1003  _buffer = nullptr;
1004  }
1005 
1006  _size = 0;
1007 }
1008 
1009 _Use_decl_annotations_
1010 HRESULT Blob::Initialize( size_t size )
1011 {
1012  if ( !size )
1013  return E_INVALIDARG;
1014 
1015  Release();
1016 
1017  _buffer = _aligned_malloc( size, 16 );
1018  if ( !_buffer )
1019  {
1020  Release();
1021  return E_OUTOFMEMORY;
1022  }
1023 
1024  _size = size;
1025 
1026  return S_OK;
1027 }
1028 
1029 }; // namespace
size_t BitsPerColor(_In_ DXGI_FORMAT fmt)
bool IsPlanar(_In_ DXGI_FORMAT fmt)
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ DXGI_FORMAT _In_ DWORD flags
Definition: DirectXTexP.h:170
bool IsPacked(_In_ DXGI_FORMAT fmt)
size_t _In_ DXGI_FORMAT size_t _In_ TEXP_LEGACY_FORMAT _In_ DWORD flags assert(pDestination &&outSize > 0)
HRESULT Initialize(_In_ size_t size)
IWICImagingFactory * _GetWIC()
size_t ComputeIndex(_In_ size_t mip, _In_ size_t item, _In_ size_t slice) const
DXGI_FORMAT format
bool IsCompressed(_In_ DXGI_FORMAT fmt)
void ComputePitch(_In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _Out_ size_t &rowPitch, _Out_ size_t &slicePitch, _In_ DWORD flags=CP_FLAGS_NONE)
bool _IsWIC2()
DXGI_FORMAT MakeTypelessUNORM(_In_ DXGI_FORMAT fmt)
bool IsValid(_In_ DXGI_FORMAT fmt)
static bool g_WIC2
DWORD _CheckWICColorSpace(_In_ const GUID &sourceGUID, _In_ const GUID &targetGUID)
TEX_DIMENSION dimension
Definition: DirectXTex.h:126
DXGI_FORMAT MakeSRGB(_In_ DXGI_FORMAT fmt)
DXGI_FORMAT MakeTypelessFLOAT(_In_ DXGI_FORMAT fmt)
REFGUID GetWICCodec(_In_ WICCodecs codec)
DXGI_FORMAT MakeTypeless(_In_ DXGI_FORMAT fmt)
DXGI_FORMAT _WICToDXGI(_In_ const GUID &guid)
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
bool _DXGIToWIC(_In_ DXGI_FORMAT format, _Out_ GUID &guid, _In_ bool ignoreRGBvsBGR=false)
size_t BitsPerPixel(_In_ DXGI_FORMAT fmt)
_In_ size_t _In_ size_t size
Definition: DirectXTexP.h:175
Blob & operator=(Blob &&moveFrom)
static WICTranslate g_WICFormats[]