Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
DirectXTexWIC.cpp
Go to the documentation of this file.
1 //-------------------------------------------------------------------------------------
2 // DirectXTexWIC.cpp
3 //
4 // DirectX Texture Library - WIC-based file reader/writer
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 using Microsoft::WRL::ComPtr;
19 
20 //-------------------------------------------------------------------------------------
21 // IStream support for WIC Memory routines
22 //-------------------------------------------------------------------------------------
23 
24 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
25 
26  #include <shcore.h>
27  #pragma comment(lib,"shcore.lib")
28 
29 #ifdef __cplusplus_winrt
30 
31  static inline HRESULT CreateMemoryStream( _Outptr_ IStream** stream )
32  {
33  auto randomAccessStream = ref new ::Windows::Storage::Streams::InMemoryRandomAccessStream();
34  return CreateStreamOverRandomAccessStream( randomAccessStream, IID_PPV_ARGS( stream ) );
35  }
36 
37 #else
38 
39  #include <wrl\client.h>
40  #include <wrl\wrappers\corewrappers.h>
41  #include <windows.storage.streams.h>
42 
43  static inline HRESULT CreateMemoryStream( _Outptr_ IStream** stream )
44  {
45  Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IRandomAccessStream> abiStream;
46  HRESULT hr = Windows::Foundation::ActivateInstance(
47  Microsoft::WRL::Wrappers::HStringReference( RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream ).Get(),
48  abiStream.GetAddressOf() );
49 
50  if (SUCCEEDED(hr))
51  {
52  hr = CreateStreamOverRandomAccessStream( abiStream.Get(), IID_PPV_ARGS( stream ) );
53  }
54  return hr;
55  }
56 
57 #endif // __cplusplus_winrt
58 
59 #else
60 
61  static inline HRESULT CreateMemoryStream( _Outptr_ IStream** stream )
62  {
63  return CreateStreamOnHGlobal( 0, TRUE, stream );
64  }
65 
66 #endif
67 
68 
69 //-------------------------------------------------------------------------------------
70 // WIC Pixel Format nearest conversion table
71 //-------------------------------------------------------------------------------------
72 
73 struct WICConvert
74 {
75  GUID source;
76  GUID target;
77 };
78 
80 {
81  // Directly support the formats listed in XnaTexUtil::g_WICFormats, so no conversion required
82  // Note target GUID in this conversion table must be one of those directly supported formats.
83 
84  { GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
85  { GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
86  { GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
87  { GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
88 
89  { GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
90  { GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
91 
92  { GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT
93  { GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT
94 
95  { GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM
96  { GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM
97 
98  { GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
99  { GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
100  { GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
101  { GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
102 
103  { GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
104  { GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
105  { GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
106  { GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
107  { GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
108 
109  { GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
110  { GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
111  { GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
112  { GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
113  { GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
114  { GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
115  { GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
116 
117  { GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
118  { GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
119  { GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
120  { GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
121  { GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
122 
123  { GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
124  { GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
125  { GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
126  { GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
127 
128 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
129  { GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
130  { GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
131  { GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
132 #endif
133 
134  // We don't support n-channel formats
135 };
136 
137 namespace DirectX
138 {
139 
140 //-------------------------------------------------------------------------------------
141 // Returns the DXGI format and optionally the WIC pixel GUID to convert to
142 //-------------------------------------------------------------------------------------
143 static DXGI_FORMAT _DetermineFormat( _In_ const WICPixelFormatGUID& pixelFormat, _In_ DWORD flags,
144  _Out_opt_ WICPixelFormatGUID* pConvert )
145 {
146  if ( pConvert )
147  memset( pConvert, 0, sizeof(WICPixelFormatGUID) );
148 
149  DXGI_FORMAT format = _WICToDXGI( pixelFormat );
150 
151  if ( format == DXGI_FORMAT_UNKNOWN )
152  {
153  if ( memcmp( &GUID_WICPixelFormat96bppRGBFixedPoint, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 )
154  {
155 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
156  if ( _IsWIC2() )
157  {
158  if ( pConvert )
159  memcpy( pConvert, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID) );
160  format = DXGI_FORMAT_R32G32B32_FLOAT;
161  }
162  else
163 #endif
164  {
165  if ( pConvert )
166  memcpy( pConvert, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) );
167  format = DXGI_FORMAT_R32G32B32A32_FLOAT;
168  }
169  }
170  else
171  {
172  for( size_t i=0; i < _countof(g_WICConvert); ++i )
173  {
174  if ( memcmp( &g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 )
175  {
176  if ( pConvert )
177  memcpy( pConvert, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) );
178 
179  format = _WICToDXGI( g_WICConvert[i].target );
180  assert( format != DXGI_FORMAT_UNKNOWN );
181  break;
182  }
183  }
184  }
185  }
186 
187  // Handle special cases based on flags
188  switch (format)
189  {
190  case DXGI_FORMAT_B8G8R8A8_UNORM: // BGRA
191  case DXGI_FORMAT_B8G8R8X8_UNORM: // BGRX
192  if ( flags & WIC_FLAGS_FORCE_RGB )
193  {
194  format = DXGI_FORMAT_R8G8B8A8_UNORM;
195  if ( pConvert )
196  memcpy( pConvert, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID) );
197  }
198  break;
199 
200  case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
201  if ( flags & WIC_FLAGS_NO_X2_BIAS )
202  {
203  format = DXGI_FORMAT_R10G10B10A2_UNORM;
204  if ( pConvert )
205  memcpy( pConvert, &GUID_WICPixelFormat32bppRGBA1010102, sizeof(WICPixelFormatGUID) );
206  }
207  break;
208 
209  case DXGI_FORMAT_B5G5R5A1_UNORM:
210  case DXGI_FORMAT_B5G6R5_UNORM:
211  if ( flags & WIC_FLAGS_NO_16BPP )
212  {
213  format = DXGI_FORMAT_R8G8B8A8_UNORM;
214  if ( pConvert )
215  memcpy( pConvert, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID) );
216  }
217  break;
218 
219  case DXGI_FORMAT_R1_UNORM:
220  if ( !(flags & WIC_FLAGS_ALLOW_MONO ) )
221  {
222  // By default we want to promote a black & white to gresycale since R1 is not a generally supported D3D format
223  format = DXGI_FORMAT_R8_UNORM;
224  if ( pConvert )
225  memcpy( pConvert, &GUID_WICPixelFormat8bppGray, sizeof(WICPixelFormatGUID) );
226  }
227  }
228 
229  return format;
230 }
231 
232 
233 //-------------------------------------------------------------------------------------
234 // Determines metadata for image
235 //-------------------------------------------------------------------------------------
236 static HRESULT _DecodeMetadata( _In_ DWORD flags,
237  _In_ IWICBitmapDecoder *decoder, _In_ IWICBitmapFrameDecode *frame,
238  _Out_ TexMetadata& metadata, _Out_opt_ WICPixelFormatGUID* pConvert )
239 {
240  if ( !decoder || !frame )
241  return E_POINTER;
242 
243  memset( &metadata, 0, sizeof(TexMetadata) );
244  metadata.depth = 1;
245  metadata.mipLevels = 1;
246  metadata.dimension = TEX_DIMENSION_TEXTURE2D;
247 
248  UINT w, h;
249  HRESULT hr = frame->GetSize( &w, &h );
250  if ( FAILED(hr) )
251  return hr;
252 
253  metadata.width = w;
254  metadata.height = h;
255 
256  if ( flags & WIC_FLAGS_ALL_FRAMES )
257  {
258  UINT fcount;
259  hr = decoder->GetFrameCount( &fcount );
260  if ( FAILED(hr) )
261  return hr;
262 
263  metadata.arraySize = fcount;
264  }
265  else
266  metadata.arraySize = 1;
267 
268  WICPixelFormatGUID pixelFormat;
269  hr = frame->GetPixelFormat( &pixelFormat );
270  if ( FAILED(hr) )
271  return hr;
272 
273  metadata.format = _DetermineFormat( pixelFormat, flags, pConvert );
274  if ( metadata.format == DXGI_FORMAT_UNKNOWN )
275  return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
276 
277  if ( !( flags & WIC_FLAGS_IGNORE_SRGB ) )
278  {
279  GUID containerFormat;
280  hr = decoder->GetContainerFormat( &containerFormat );
281  if ( FAILED(hr) )
282  return hr;
283 
284  ComPtr<IWICMetadataQueryReader> metareader;
285  hr = frame->GetMetadataQueryReader( metareader.GetAddressOf() );
286  if ( SUCCEEDED(hr) )
287  {
288  // Check for sRGB colorspace metadata
289  bool sRGB = false;
290 
291  PROPVARIANT value;
292  PropVariantInit( &value );
293 
294  if ( memcmp( &containerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 )
295  {
296  // Check for sRGB chunk
297  if ( SUCCEEDED( metareader->GetMetadataByName( L"/sRGB/RenderingIntent", &value ) ) && value.vt == VT_UI1 )
298  {
299  sRGB = true;
300  }
301  }
302  else if ( SUCCEEDED( metareader->GetMetadataByName( L"System.Image.ColorSpace", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 )
303  {
304  sRGB = true;
305  }
306 
307  PropVariantClear( &value );
308 
309  if ( sRGB )
310  metadata.format = MakeSRGB( metadata.format );
311  }
312  else if ( hr == WINCODEC_ERR_UNSUPPORTEDOPERATION )
313  {
314  // Some formats just don't support metadata (BMP, ICO, etc.), so ignore this failure
315  hr = S_OK;
316  }
317  }
318 
319  return hr;
320 }
321 
322 
323 //-------------------------------------------------------------------------------------
324 // Decodes a single frame
325 //-------------------------------------------------------------------------------------
326 static HRESULT _DecodeSingleFrame( _In_ DWORD flags, _In_ const TexMetadata& metadata, _In_ const WICPixelFormatGUID& convertGUID,
327  _In_ IWICBitmapFrameDecode *frame, _Inout_ ScratchImage& image )
328 {
329  if ( !frame )
330  return E_POINTER;
331 
332  HRESULT hr = image.Initialize2D( metadata.format, metadata.width, metadata.height, 1, 1 );
333  if ( FAILED(hr) )
334  return hr;
335 
336  const Image *img = image.GetImage( 0, 0, 0 );
337  if ( !img )
338  return E_POINTER;
339 
340  IWICImagingFactory* pWIC = _GetWIC();
341  if ( !pWIC )
342  return E_NOINTERFACE;
343 
344  if ( memcmp( &convertGUID, &GUID_NULL, sizeof(GUID) ) == 0 )
345  {
346  hr = frame->CopyPixels( 0, static_cast<UINT>( img->rowPitch ), static_cast<UINT>( img->slicePitch ), img->pixels );
347  if ( FAILED(hr) )
348  return hr;
349  }
350  else
351  {
352  ComPtr<IWICFormatConverter> FC;
353  hr = pWIC->CreateFormatConverter( FC.GetAddressOf() );
354  if ( FAILED(hr) )
355  return hr;
356 
357  hr = FC->Initialize( frame, convertGUID, _GetWICDither( flags ), 0, 0, WICBitmapPaletteTypeCustom );
358  if ( FAILED(hr) )
359  return hr;
360 
361  hr = FC->CopyPixels( 0, static_cast<UINT>( img->rowPitch ), static_cast<UINT>( img->slicePitch ), img->pixels );
362  if ( FAILED(hr) )
363  return hr;
364  }
365 
366  return S_OK;
367 }
368 
369 
370 //-------------------------------------------------------------------------------------
371 // Decodes an image array, resizing/format converting as needed
372 //-------------------------------------------------------------------------------------
373 static HRESULT _DecodeMultiframe( _In_ DWORD flags, _In_ const TexMetadata& metadata,
374  _In_ IWICBitmapDecoder *decoder, _Inout_ ScratchImage& image )
375 {
376  if ( !decoder )
377  return E_POINTER;
378 
379  HRESULT hr = image.Initialize2D( metadata.format, metadata.width, metadata.height, metadata.arraySize, 1 );
380  if ( FAILED(hr) )
381  return hr;
382 
383  IWICImagingFactory* pWIC = _GetWIC();
384  if ( !pWIC )
385  return E_NOINTERFACE;
386 
387  WICPixelFormatGUID sourceGUID;
388  if ( !_DXGIToWIC( metadata.format, sourceGUID ) )
389  return E_FAIL;
390 
391  for( size_t index = 0; index < metadata.arraySize; ++index )
392  {
393  const Image* img = image.GetImage( 0, index, 0 );
394  if ( !img )
395  return E_POINTER;
396 
397  ComPtr<IWICBitmapFrameDecode> frame;
398  hr = decoder->GetFrame( static_cast<UINT>( index ), frame.GetAddressOf() );
399  if ( FAILED(hr) )
400  return hr;
401 
402  WICPixelFormatGUID pfGuid;
403  hr = frame->GetPixelFormat( &pfGuid );
404  if ( FAILED(hr) )
405  return hr;
406 
407  UINT w, h;
408  hr = frame->GetSize( &w, &h );
409  if ( FAILED(hr) )
410  return hr;
411 
412  if ( memcmp( &pfGuid, &sourceGUID, sizeof(WICPixelFormatGUID) ) == 0 )
413  {
414  if ( w == metadata.width && h == metadata.height )
415  {
416  // This frame does not need resized or format converted, just copy...
417  hr = frame->CopyPixels( 0, static_cast<UINT>( img->rowPitch ), static_cast<UINT>( img->slicePitch ), img->pixels );
418  if ( FAILED(hr) )
419  return hr;
420  }
421  else
422  {
423  // This frame needs resizing, but not format converted
424  ComPtr<IWICBitmapScaler> scaler;
425  hr = pWIC->CreateBitmapScaler( scaler.GetAddressOf() );
426  if ( FAILED(hr) )
427  return hr;
428 
429  hr = scaler->Initialize( frame.Get(), static_cast<UINT>( metadata.width ), static_cast<UINT>( metadata.height ), _GetWICInterp( flags ) );
430  if ( FAILED(hr) )
431  return hr;
432 
433  hr = scaler->CopyPixels( 0, static_cast<UINT>( img->rowPitch ), static_cast<UINT>( img->slicePitch ), img->pixels );
434  if ( FAILED(hr) )
435  return hr;
436  }
437  }
438  else
439  {
440  // This frame required format conversion
441  ComPtr<IWICFormatConverter> FC;
442  hr = pWIC->CreateFormatConverter( FC.GetAddressOf() );
443  if ( FAILED(hr) )
444  return hr;
445 
446  hr = FC->Initialize( frame.Get(), pfGuid, _GetWICDither( flags ), 0, 0, WICBitmapPaletteTypeCustom );
447  if ( FAILED(hr) )
448  return hr;
449 
450  if ( w == metadata.width && h == metadata.height )
451  {
452  // This frame is the same size, no need to scale
453  hr = FC->CopyPixels( 0, static_cast<UINT>( img->rowPitch ), static_cast<UINT>( img->slicePitch ), img->pixels );
454  if ( FAILED(hr) )
455  return hr;
456  }
457  else
458  {
459  // This frame needs resizing and format converted
460  ComPtr<IWICBitmapScaler> scaler;
461  hr = pWIC->CreateBitmapScaler( scaler.GetAddressOf() );
462  if ( FAILED(hr) )
463  return hr;
464 
465  hr = scaler->Initialize( FC.Get(), static_cast<UINT>( metadata.width ), static_cast<UINT>( metadata.height ), _GetWICInterp( flags ) );
466  if ( FAILED(hr) )
467  return hr;
468 
469  hr = scaler->CopyPixels( 0, static_cast<UINT>( img->rowPitch ), static_cast<UINT>( img->slicePitch ), img->pixels );
470  if ( FAILED(hr) )
471  return hr;
472  }
473  }
474  }
475 
476  return S_OK;
477 }
478 
479 
480 //-------------------------------------------------------------------------------------
481 // Encodes image metadata
482 //-------------------------------------------------------------------------------------
483 static HRESULT _EncodeMetadata( _In_ IWICBitmapFrameEncode* frame, _In_ const GUID& containerFormat, _In_ DXGI_FORMAT format )
484 {
485  if ( !frame )
486  return E_POINTER;
487 
488  ComPtr<IWICMetadataQueryWriter> metawriter;
489  HRESULT hr = frame->GetMetadataQueryWriter( metawriter.GetAddressOf() );
490  if ( SUCCEEDED( hr ) )
491  {
492  PROPVARIANT value;
493  PropVariantInit( &value );
494 
495  bool sRGB = IsSRGB( format );
496 
497  value.vt = VT_LPSTR;
498  value.pszVal = "DirectXTex";
499 
500  if ( memcmp( &containerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 )
501  {
502  // Set Software name
503  (void)metawriter->SetMetadataByName( L"/tEXt/{str=Software}", &value );
504 
505  // Set sRGB chunk
506  if ( sRGB )
507  {
508  value.vt = VT_UI1;
509  value.bVal = 0;
510  (void)metawriter->SetMetadataByName( L"/sRGB/RenderingIntent", &value );
511  }
512  }
513  else
514  {
515  // Set Software name
516  (void)metawriter->SetMetadataByName( L"System.ApplicationName", &value );
517 
518  if ( sRGB )
519  {
520  // Set JPEG EXIF Colorspace of sRGB
521  value.vt = VT_UI2;
522  value.uiVal = 1;
523  (void)metawriter->SetMetadataByName( L"System.Image.ColorSpace", &value );
524  }
525  }
526  }
527  else if ( hr == WINCODEC_ERR_UNSUPPORTEDOPERATION )
528  {
529  // Some formats just don't support metadata (BMP, ICO, etc.), so ignore this failure
530  hr = S_OK;
531  }
532 
533  return hr;
534 }
535 
536 
537 //-------------------------------------------------------------------------------------
538 // Encodes a single frame
539 //-------------------------------------------------------------------------------------
540 static HRESULT _EncodeImage( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID containerFormat,
541  _In_ IWICBitmapFrameEncode* frame, _In_opt_ IPropertyBag2* props, _In_opt_ const GUID* targetFormat )
542 {
543  if ( !frame )
544  return E_INVALIDARG;
545 
546  if ( !image.pixels )
547  return E_POINTER;
548 
549  WICPixelFormatGUID pfGuid;
550  if ( !_DXGIToWIC( image.format, pfGuid ) )
551  return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
552 
553  HRESULT hr = frame->Initialize( props );
554  if ( FAILED(hr) )
555  return hr;
556 
557 #ifdef _M_X64
558  if ( (image.width > 0xFFFFFFFF) || (image.height > 0xFFFFFFFF) )
559  return E_INVALIDARG;
560 #endif
561 
562  hr = frame->SetSize( static_cast<UINT>( image.width ), static_cast<UINT>( image.height ) );
563  if ( FAILED(hr) )
564  return hr;
565 
566  hr = frame->SetResolution( 72, 72 );
567  if ( FAILED(hr) )
568  return hr;
569 
570  WICPixelFormatGUID targetGuid = (targetFormat) ? (*targetFormat) : pfGuid;
571  hr = frame->SetPixelFormat( &targetGuid );
572  if ( FAILED(hr) )
573  return hr;
574 
575  if ( targetFormat && memcmp( targetFormat, &targetGuid, sizeof(WICPixelFormatGUID) ) != 0 )
576  {
577  // Requested output pixel format is not supported by the WIC codec
578  return E_FAIL;
579  }
580 
581  hr = _EncodeMetadata( frame, containerFormat, image.format );
582  if ( FAILED(hr) )
583  return hr;
584 
585  if ( memcmp( &targetGuid, &pfGuid, sizeof(WICPixelFormatGUID) ) != 0 )
586  {
587  // Conversion required to write
588  IWICImagingFactory* pWIC = _GetWIC();
589  if ( !pWIC )
590  return E_NOINTERFACE;
591 
592  ComPtr<IWICBitmap> source;
593  hr = pWIC->CreateBitmapFromMemory( static_cast<UINT>( image.width ), static_cast<UINT>( image.height ), pfGuid,
594  static_cast<UINT>( image.rowPitch ), static_cast<UINT>( image.slicePitch ),
595  image.pixels, source.GetAddressOf() );
596  if ( FAILED(hr) )
597  return hr;
598 
599  ComPtr<IWICFormatConverter> FC;
600  hr = pWIC->CreateFormatConverter( FC.GetAddressOf() );
601  if ( FAILED(hr) )
602  return hr;
603 
604  hr = FC->Initialize( source.Get(), targetGuid, _GetWICDither( flags ), 0, 0, WICBitmapPaletteTypeCustom );
605  if ( FAILED(hr) )
606  return hr;
607 
608  WICRect rect = { 0, 0, static_cast<UINT>( image.width ), static_cast<UINT>( image.height ) };
609  hr = frame->WriteSource( FC.Get(), &rect );
610  if ( FAILED(hr) )
611  return hr;
612  }
613  else
614  {
615  // No conversion required
616  hr = frame->WritePixels( static_cast<UINT>( image.height ), static_cast<UINT>( image.rowPitch ), static_cast<UINT>( image.slicePitch ),
617  reinterpret_cast<uint8_t*>( image.pixels ) );
618  if ( FAILED(hr) )
619  return hr;
620  }
621 
622  hr = frame->Commit();
623  if ( FAILED(hr) )
624  return hr;
625 
626  return S_OK;
627 }
628 
629 static HRESULT _EncodeSingleFrame( _In_ const Image& image, _In_ DWORD flags,
630  _In_ REFGUID containerFormat, _Inout_ IStream* stream,
631  _In_opt_ const GUID* targetFormat, _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps )
632 {
633  if ( !stream )
634  return E_INVALIDARG;
635 
636  // Initialize WIC
637  IWICImagingFactory* pWIC = _GetWIC();
638  if ( !pWIC )
639  return E_NOINTERFACE;
640 
641  ComPtr<IWICBitmapEncoder> encoder;
642  HRESULT hr = pWIC->CreateEncoder( containerFormat, 0, encoder.GetAddressOf() );
643  if ( FAILED(hr) )
644  return hr;
645 
646  hr = encoder->Initialize( stream, WICBitmapEncoderNoCache );
647  if ( FAILED(hr) )
648  return hr;
649 
650  ComPtr<IWICBitmapFrameEncode> frame;
651  ComPtr<IPropertyBag2> props;
652  hr = encoder->CreateNewFrame( frame.GetAddressOf(), props.GetAddressOf() );
653  if ( FAILED(hr) )
654  return hr;
655 
656  if ( memcmp( &containerFormat, &GUID_ContainerFormatBmp, sizeof(WICPixelFormatGUID) ) == 0 && _IsWIC2() )
657  {
658  // Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel
659  PROPBAG2 option = { 0 };
660  option.pstrName = L"EnableV5Header32bppBGRA";
661 
662  VARIANT varValue;
663  varValue.vt = VT_BOOL;
664  varValue.boolVal = VARIANT_TRUE;
665  (void)props->Write( 1, &option, &varValue );
666  }
667 
668  if ( setCustomProps )
669  {
670  setCustomProps( props.Get() );
671  }
672 
673  hr = _EncodeImage( image, flags, containerFormat, frame.Get(), props.Get(), targetFormat );
674  if ( FAILED(hr) )
675  return hr;
676 
677  hr = encoder->Commit();
678  if ( FAILED(hr) )
679  return hr;
680 
681  return S_OK;
682 }
683 
684 
685 //-------------------------------------------------------------------------------------
686 // Encodes an image array
687 //-------------------------------------------------------------------------------------
688 static HRESULT _EncodeMultiframe( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags,
689  _In_ REFGUID containerFormat, _Inout_ IStream* stream,
690  _In_opt_ const GUID* targetFormat, _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps )
691 {
692  if ( !stream || nimages < 2 )
693  return E_INVALIDARG;
694 
695  if ( !images )
696  return E_POINTER;
697 
698  // Initialize WIC
699  IWICImagingFactory* pWIC = _GetWIC();
700  if ( !pWIC )
701  return E_NOINTERFACE;
702 
703  ComPtr<IWICBitmapEncoder> encoder;
704  HRESULT hr = pWIC->CreateEncoder( containerFormat, 0, encoder.GetAddressOf() );
705  if ( FAILED(hr) )
706  return hr;
707 
708  ComPtr<IWICBitmapEncoderInfo> einfo;
709  hr = encoder->GetEncoderInfo( einfo.GetAddressOf() );
710  if ( FAILED(hr) )
711  return hr;
712 
713  BOOL mframe = FALSE;
714  hr = einfo->DoesSupportMultiframe( &mframe );
715  if ( FAILED(hr) )
716  return hr;
717 
718  if ( !mframe )
719  return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
720 
721  hr = encoder->Initialize( stream, WICBitmapEncoderNoCache );
722  if ( FAILED(hr) )
723  return hr;
724 
725  for( size_t index=0; index < nimages; ++index )
726  {
727  ComPtr<IWICBitmapFrameEncode> frame;
728  ComPtr<IPropertyBag2> props;
729  hr = encoder->CreateNewFrame( frame.GetAddressOf(), props.GetAddressOf() );
730  if ( FAILED(hr) )
731  return hr;
732 
733  if ( setCustomProps )
734  {
735  setCustomProps( props.Get() );
736  }
737 
738  hr = _EncodeImage( images[index], flags, containerFormat, frame.Get(), props.Get(), targetFormat );
739  if ( FAILED(hr) )
740  return hr;
741  }
742 
743  hr = encoder->Commit();
744  if ( FAILED(hr) )
745  return hr;
746 
747  return S_OK;
748 }
749 
750 
751 //=====================================================================================
752 // Entry-points
753 //=====================================================================================
754 
755 //-------------------------------------------------------------------------------------
756 // Obtain metadata from WIC-supported file in memory
757 //-------------------------------------------------------------------------------------
758 _Use_decl_annotations_
759 HRESULT GetMetadataFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata& metadata )
760 {
761  if ( !pSource || size == 0 )
762  return E_INVALIDARG;
763 
764 #ifdef _M_X64
765  if ( size > 0xFFFFFFFF )
766  return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE );
767 #endif
768 
769  IWICImagingFactory* pWIC = _GetWIC();
770  if ( !pWIC )
771  return E_NOINTERFACE;
772 
773  // Create input stream for memory
774  ComPtr<IWICStream> stream;
775  HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() );
776  if ( FAILED(hr) )
777  return hr;
778 
779  hr = stream->InitializeFromMemory( reinterpret_cast<BYTE*>( const_cast<void*>( pSource ) ),
780  static_cast<UINT>( size ) );
781  if ( FAILED(hr) )
782  return hr;
783 
784  // Initialize WIC
785  ComPtr<IWICBitmapDecoder> decoder;
786  hr = pWIC->CreateDecoderFromStream( stream.Get(), 0, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() );
787  if ( FAILED(hr) )
788  return hr;
789 
790  ComPtr<IWICBitmapFrameDecode> frame;
791  hr = decoder->GetFrame( 0, frame.GetAddressOf() );
792  if ( FAILED(hr) )
793  return hr;
794 
795  // Get metadata
796  hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), metadata, 0 );
797  if ( FAILED(hr) )
798  return hr;
799 
800  return S_OK;
801 }
802 
803 
804 //-------------------------------------------------------------------------------------
805 // Obtain metadata from WIC-supported file on disk
806 //-------------------------------------------------------------------------------------
807 _Use_decl_annotations_
808 HRESULT GetMetadataFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata& metadata )
809 {
810  if ( !szFile )
811  return E_INVALIDARG;
812 
813  IWICImagingFactory* pWIC = _GetWIC();
814  if ( !pWIC )
815  return E_NOINTERFACE;
816 
817  // Initialize WIC
818  ComPtr<IWICBitmapDecoder> decoder;
819  HRESULT hr = pWIC->CreateDecoderFromFilename( szFile, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() );
820  if ( FAILED(hr) )
821  return hr;
822 
823  ComPtr<IWICBitmapFrameDecode> frame;
824  hr = decoder->GetFrame( 0, frame.GetAddressOf() );
825  if ( FAILED(hr) )
826  return hr;
827 
828  // Get metadata
829  hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), metadata, 0 );
830  if ( FAILED(hr) )
831  return hr;
832 
833  return S_OK;
834 }
835 
836 
837 //-------------------------------------------------------------------------------------
838 // Load a WIC-supported file in memory
839 //-------------------------------------------------------------------------------------
840 _Use_decl_annotations_
841 HRESULT LoadFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata* metadata, ScratchImage& image )
842 {
843  if ( !pSource || size == 0 )
844  return E_INVALIDARG;
845 
846 #ifdef _M_X64
847  if ( size > 0xFFFFFFFF )
848  return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE );
849 #endif
850 
851  IWICImagingFactory* pWIC = _GetWIC();
852  if ( !pWIC )
853  return E_NOINTERFACE;
854 
855  image.Release();
856 
857  // Create input stream for memory
858  ComPtr<IWICStream> stream;
859  HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() );
860  if ( FAILED(hr) )
861  return hr;
862 
863  hr = stream->InitializeFromMemory( reinterpret_cast<uint8_t*>( const_cast<void*>( pSource ) ), static_cast<DWORD>( size ) );
864  if ( FAILED(hr) )
865  return hr;
866 
867  // Initialize WIC
868  ComPtr<IWICBitmapDecoder> decoder;
869  hr = pWIC->CreateDecoderFromStream( stream.Get(), 0, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() );
870  if ( FAILED(hr) )
871  return hr;
872 
873  ComPtr<IWICBitmapFrameDecode> frame;
874  hr = decoder->GetFrame( 0, frame.GetAddressOf() );
875  if ( FAILED(hr) )
876  return hr;
877 
878  // Get metadata
879  TexMetadata mdata;
880  WICPixelFormatGUID convertGUID = {0};
881  hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), mdata, &convertGUID );
882  if ( FAILED(hr) )
883  return hr;
884 
885  if ( (mdata.arraySize > 1) && (flags & WIC_FLAGS_ALL_FRAMES) )
886  {
887  hr = _DecodeMultiframe( flags, mdata, decoder.Get(), image );
888  }
889  else
890  {
891  hr = _DecodeSingleFrame( flags, mdata, convertGUID, frame.Get(), image );
892  }
893 
894  if ( FAILED(hr) )
895  {
896  image.Release();
897  return hr;
898  }
899 
900  if ( metadata )
901  memcpy( metadata, &mdata, sizeof(TexMetadata) );
902 
903  return S_OK;
904 }
905 
906 
907 //-------------------------------------------------------------------------------------
908 // Load a WIC-supported file from disk
909 //-------------------------------------------------------------------------------------
910 _Use_decl_annotations_
911 HRESULT LoadFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, ScratchImage& image )
912 {
913  if ( !szFile )
914  return E_INVALIDARG;
915 
916  IWICImagingFactory* pWIC = _GetWIC();
917  if ( !pWIC )
918  return E_NOINTERFACE;
919 
920  image.Release();
921 
922  // Initialize WIC
923  ComPtr<IWICBitmapDecoder> decoder;
924  HRESULT hr = pWIC->CreateDecoderFromFilename( szFile, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() );
925  if ( FAILED(hr) )
926  return hr;
927 
928  ComPtr<IWICBitmapFrameDecode> frame;
929  hr = decoder->GetFrame( 0, frame.GetAddressOf() );
930  if ( FAILED(hr) )
931  return hr;
932 
933  // Get metadata
934  TexMetadata mdata;
935  WICPixelFormatGUID convertGUID = {0};
936  hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), mdata, &convertGUID );
937  if ( FAILED(hr) )
938  return hr;
939 
940  if ( (mdata.arraySize > 1) && (flags & WIC_FLAGS_ALL_FRAMES) )
941  {
942  hr = _DecodeMultiframe( flags, mdata, decoder.Get(), image );
943  }
944  else
945  {
946  hr = _DecodeSingleFrame( flags, mdata, convertGUID, frame.Get(), image );
947  }
948 
949  if ( FAILED(hr) )
950  {
951  image.Release();
952  return hr;
953  }
954 
955  if ( metadata )
956  memcpy( metadata, &mdata, sizeof(TexMetadata) );
957 
958  return S_OK;
959 }
960 
961 
962 //-------------------------------------------------------------------------------------
963 // Save a WIC-supported file to memory
964 //-------------------------------------------------------------------------------------
965 _Use_decl_annotations_
966 HRESULT SaveToWICMemory( const Image& image, DWORD flags, REFGUID containerFormat, Blob& blob,
967  const GUID* targetFormat, std::function<void(IPropertyBag2*)> setCustomProps )
968 {
969  if ( !image.pixels )
970  return E_POINTER;
971 
972  blob.Release();
973 
974  ComPtr<IStream> stream;
975  HRESULT hr = CreateMemoryStream( stream.GetAddressOf() );
976  if ( FAILED(hr) )
977  return hr;
978 
979  hr = _EncodeSingleFrame( image, flags, containerFormat, stream.Get(), targetFormat, setCustomProps );
980  if ( FAILED(hr) )
981  return hr;
982 
983  // Copy stream data into blob
984  STATSTG stat;
985  hr = stream->Stat( &stat, STATFLAG_NONAME );
986  if ( FAILED(hr) )
987  return hr;
988 
989  if ( stat.cbSize.HighPart > 0 )
990  return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE );
991 
992  hr = blob.Initialize( stat.cbSize.LowPart );
993  if ( FAILED(hr) )
994  return hr;
995 
996  LARGE_INTEGER li = { 0 };
997  hr = stream->Seek( li, STREAM_SEEK_SET, 0 );
998  if ( FAILED(hr) )
999  return hr;
1000 
1001  DWORD bytesRead;
1002  hr = stream->Read( blob.GetBufferPointer(), static_cast<ULONG>( blob.GetBufferSize() ), &bytesRead );
1003  if ( FAILED(hr) )
1004  return hr;
1005 
1006  if ( bytesRead != blob.GetBufferSize() )
1007  return E_FAIL;
1008 
1009  return S_OK;
1010 }
1011 
1012 _Use_decl_annotations_
1013 HRESULT SaveToWICMemory( const Image* images, size_t nimages, DWORD flags, REFGUID containerFormat, Blob& blob,
1014  const GUID* targetFormat, std::function<void(IPropertyBag2*)> setCustomProps )
1015 {
1016  if ( !images || nimages == 0 )
1017  return E_INVALIDARG;
1018 
1019  blob.Release();
1020 
1021  ComPtr<IStream> stream;
1022  HRESULT hr = CreateMemoryStream( stream.GetAddressOf() );
1023  if ( FAILED(hr) )
1024  return hr;
1025 
1026  if ( nimages > 1 )
1027  hr = _EncodeMultiframe( images, nimages, flags, containerFormat, stream.Get(), targetFormat, setCustomProps );
1028  else
1029  hr = _EncodeSingleFrame( images[0], flags, containerFormat, stream.Get(), targetFormat, setCustomProps );
1030 
1031  if ( FAILED(hr) )
1032  return hr;
1033 
1034  // Copy stream data into blob
1035  STATSTG stat;
1036  hr = stream->Stat( &stat, STATFLAG_NONAME );
1037  if ( FAILED(hr) )
1038  return hr;
1039 
1040  if ( stat.cbSize.HighPart > 0 )
1041  return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE );
1042 
1043  hr = blob.Initialize( stat.cbSize.LowPart );
1044  if ( FAILED(hr) )
1045  return hr;
1046 
1047  LARGE_INTEGER li = { 0 };
1048  hr = stream->Seek( li, STREAM_SEEK_SET, 0 );
1049  if ( FAILED(hr) )
1050  return hr;
1051 
1052  DWORD bytesRead;
1053  hr = stream->Read( blob.GetBufferPointer(), static_cast<ULONG>( blob.GetBufferSize() ), &bytesRead );
1054  if ( FAILED(hr) )
1055  return hr;
1056 
1057  if ( bytesRead != blob.GetBufferSize() )
1058  return E_FAIL;
1059 
1060  return S_OK;
1061 }
1062 
1063 
1064 //-------------------------------------------------------------------------------------
1065 // Save a WIC-supported file to disk
1066 //-------------------------------------------------------------------------------------
1067 _Use_decl_annotations_
1068 HRESULT SaveToWICFile( const Image& image, DWORD flags, REFGUID containerFormat, LPCWSTR szFile,
1069  const GUID* targetFormat, std::function<void(IPropertyBag2*)> setCustomProps )
1070 {
1071  if ( !szFile )
1072  return E_INVALIDARG;
1073 
1074  if ( !image.pixels )
1075  return E_POINTER;
1076 
1077  IWICImagingFactory* pWIC = _GetWIC();
1078  if ( !pWIC )
1079  return E_NOINTERFACE;
1080 
1081  ComPtr<IWICStream> stream;
1082  HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() );
1083  if ( FAILED(hr) )
1084  return hr;
1085 
1086  hr = stream->InitializeFromFilename( szFile, GENERIC_WRITE );
1087  if ( FAILED(hr) )
1088  return hr;
1089 
1090  hr = _EncodeSingleFrame( image, flags, containerFormat, stream.Get(), targetFormat, setCustomProps );
1091  if ( FAILED(hr) )
1092  return hr;
1093 
1094  return S_OK;
1095 }
1096 
1097 _Use_decl_annotations_
1098 HRESULT SaveToWICFile( const Image* images, size_t nimages, DWORD flags, REFGUID containerFormat, LPCWSTR szFile, const GUID* targetFormat,
1099  std::function<void(IPropertyBag2*)> setCustomProps )
1100 {
1101  if ( !szFile || !images || nimages == 0 )
1102  return E_INVALIDARG;
1103 
1104  IWICImagingFactory* pWIC = _GetWIC();
1105  if ( !pWIC )
1106  return E_NOINTERFACE;
1107 
1108  ComPtr<IWICStream> stream;
1109  HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() );
1110  if ( FAILED(hr) )
1111  return hr;
1112 
1113  hr = stream->InitializeFromFilename( szFile, GENERIC_WRITE );
1114  if ( FAILED(hr) )
1115  return hr;
1116 
1117  if ( nimages > 1 )
1118  hr = _EncodeMultiframe( images, nimages, flags, containerFormat, stream.Get(), targetFormat, setCustomProps );
1119  else
1120  hr = _EncodeSingleFrame( images[0], flags, containerFormat, stream.Get(), targetFormat, setCustomProps );
1121 
1122  if ( FAILED(hr) )
1123  return hr;
1124 
1125  return S_OK;
1126 }
1127 
1128 }; // namespace
static HRESULT _DecodeMetadata(_In_ DWORD flags, _In_ IWICBitmapDecoder *decoder, _In_ IWICBitmapFrameDecode *frame, _Out_ TexMetadata &metadata, _Out_opt_ WICPixelFormatGUID *pConvert)
uint8_t * pixels
Definition: DirectXTex.h:230
static HRESULT _DecodeMultiframe(_In_ DWORD flags, _In_ const TexMetadata &metadata, _In_ IWICBitmapDecoder *decoder, _Inout_ ScratchImage &image)
HRESULT SaveToWICFile(_In_ const Image &image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat, _In_z_ LPCWSTR szFile, _In_opt_ const GUID *targetFormat=nullptr, _In_opt_ std::function< void(IPropertyBag2 *)> setCustomProps=nullptr)
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ DXGI_FORMAT _In_ DWORD flags
Definition: DirectXTexP.h:170
size_t _In_ DXGI_FORMAT size_t _In_ TEXP_LEGACY_FORMAT _In_ DWORD flags assert(pDestination &&outSize > 0)
HRESULT Initialize(_In_ size_t size)
static DXGI_FORMAT _DetermineFormat(_In_ const WICPixelFormatGUID &pixelFormat, _In_ DWORD flags, _Out_opt_ WICPixelFormatGUID *pConvert)
static HRESULT _EncodeMetadata(_In_ IWICBitmapFrameEncode *frame, _In_ const GUID &containerFormat, _In_ DXGI_FORMAT format)
IWICImagingFactory * _GetWIC()
void * GetBufferPointer() const
Definition: DirectXTex.h:298
size_t rowPitch
Definition: DirectXTex.h:228
static HRESULT _EncodeSingleFrame(_In_ const Image &image, _In_ DWORD flags, _In_ REFGUID containerFormat, _Inout_ IStream *stream, _In_opt_ const GUID *targetFormat, _In_opt_ std::function< void(IPropertyBag2 *)> setCustomProps)
_In_ size_t _In_ const TexMetadata & metadata
Definition: DirectXTexP.h:116
static HRESULT _DecodeSingleFrame(_In_ DWORD flags, _In_ const TexMetadata &metadata, _In_ const WICPixelFormatGUID &convertGUID, _In_ IWICBitmapFrameDecode *frame, _Inout_ ScratchImage &image)
bool _IsWIC2()
static WICConvert g_WICConvert[]
HRESULT LoadFromWICFile(_In_z_ LPCWSTR szFile, _In_ DWORD flags, _Out_opt_ TexMetadata *metadata, _Out_ ScratchImage &image)
HRESULT LoadFromWICMemory(_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, _Out_opt_ TexMetadata *metadata, _Out_ ScratchImage &image)
WICBitmapDitherType _GetWICDither(_In_ DWORD flags)
Definition: DirectXTexP.h:64
_In_ size_t _In_ DXGI_FORMAT _In_reads_(count) const XMVECTOR *pSource
static HRESULT CreateMemoryStream(_Outptr_ IStream **stream)
DXGI_FORMAT MakeSRGB(_In_ DXGI_FORMAT fmt)
bool IsSRGB(_In_ DXGI_FORMAT fmt)
DXGI_FORMAT _WICToDXGI(_In_ const GUID &guid)
static HRESULT _EncodeMultiframe(_In_reads_(nimages) const Image *images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID containerFormat, _Inout_ IStream *stream, _In_opt_ const GUID *targetFormat, _In_opt_ std::function< void(IPropertyBag2 *)> setCustomProps)
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
HRESULT GetMetadataFromWICMemory(_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, _Out_ TexMetadata &metadata)
static HRESULT _EncodeImage(_In_ const Image &image, _In_ DWORD flags, _In_ REFGUID containerFormat, _In_ IWICBitmapFrameEncode *frame, _In_opt_ IPropertyBag2 *props, _In_opt_ const GUID *targetFormat)
bool _DXGIToWIC(_In_ DXGI_FORMAT format, _Out_ GUID &guid, _In_ bool ignoreRGBvsBGR=false)
HRESULT SaveToWICMemory(_In_ const Image &image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat, _Out_ Blob &blob, _In_opt_ const GUID *targetFormat=nullptr, _In_opt_ std::function< void(IPropertyBag2 *)> setCustomProps=nullptr)
_In_ size_t _In_ size_t size
Definition: DirectXTexP.h:175
HRESULT GetMetadataFromWICFile(_In_z_ LPCWSTR szFile, _In_ DWORD flags, _Out_ TexMetadata &metadata)
size_t slicePitch
Definition: DirectXTex.h:229
WICBitmapInterpolationMode _GetWICInterp(_In_ DWORD flags)
Definition: DirectXTexP.h:84
size_t GetBufferSize() const
Definition: DirectXTex.h:299