2 * Copyright 2020 Ziqing Hui for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "wine/debug.h"
26 #include "dxhelpers.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
30 HRESULT WINAPI
WICCreateImagingFactory_Proxy(UINT sdk_version
, IWICImagingFactory
**imaging_factory
);
34 const GUID
*wic_container_guid
;
35 D3DX10_IMAGE_FILE_FORMAT d3dx_file_format
;
39 { &GUID_ContainerFormatBmp
, D3DX10_IFF_BMP
},
40 { &GUID_ContainerFormatJpeg
, D3DX10_IFF_JPG
},
41 { &GUID_ContainerFormatPng
, D3DX10_IFF_PNG
},
42 { &GUID_ContainerFormatDds
, D3DX10_IFF_DDS
},
43 { &GUID_ContainerFormatTiff
, D3DX10_IFF_TIFF
},
44 { &GUID_ContainerFormatGif
, D3DX10_IFF_GIF
},
45 { &GUID_ContainerFormatWmp
, D3DX10_IFF_WMP
},
51 DXGI_FORMAT dxgi_format
;
55 { &GUID_WICPixelFormatBlackWhite
, DXGI_FORMAT_R1_UNORM
},
56 { &GUID_WICPixelFormat8bppAlpha
, DXGI_FORMAT_A8_UNORM
},
57 { &GUID_WICPixelFormat8bppGray
, DXGI_FORMAT_R8_UNORM
},
58 { &GUID_WICPixelFormat16bppGray
, DXGI_FORMAT_R16_UNORM
},
59 { &GUID_WICPixelFormat16bppGrayHalf
, DXGI_FORMAT_R16_FLOAT
},
60 { &GUID_WICPixelFormat32bppGrayFloat
, DXGI_FORMAT_R32_FLOAT
},
61 { &GUID_WICPixelFormat16bppBGR565
, DXGI_FORMAT_B5G6R5_UNORM
},
62 { &GUID_WICPixelFormat16bppBGRA5551
, DXGI_FORMAT_B5G5R5A1_UNORM
},
63 { &GUID_WICPixelFormat32bppBGR
, DXGI_FORMAT_B8G8R8X8_UNORM
},
64 { &GUID_WICPixelFormat32bppBGRA
, DXGI_FORMAT_B8G8R8A8_UNORM
},
65 { &GUID_WICPixelFormat32bppRGBA
, DXGI_FORMAT_R8G8B8A8_UNORM
},
66 { &GUID_WICPixelFormat32bppRGBA1010102
, DXGI_FORMAT_R10G10B10A2_UNORM
},
67 { &GUID_WICPixelFormat32bppRGBA1010102XR
, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
},
68 { &GUID_WICPixelFormat64bppRGBA
, DXGI_FORMAT_R16G16B16A16_UNORM
},
69 { &GUID_WICPixelFormat64bppRGBAHalf
, DXGI_FORMAT_R16G16B16A16_FLOAT
},
70 { &GUID_WICPixelFormat96bppRGBFloat
, DXGI_FORMAT_R32G32B32_FLOAT
},
71 { &GUID_WICPixelFormat128bppRGBAFloat
, DXGI_FORMAT_R32G32B32A32_FLOAT
}
74 static const DXGI_FORMAT block_compressed_formats
[] =
76 DXGI_FORMAT_BC1_TYPELESS
, DXGI_FORMAT_BC1_UNORM
, DXGI_FORMAT_BC1_UNORM_SRGB
,
77 DXGI_FORMAT_BC2_TYPELESS
, DXGI_FORMAT_BC2_UNORM
, DXGI_FORMAT_BC2_UNORM_SRGB
,
78 DXGI_FORMAT_BC3_TYPELESS
, DXGI_FORMAT_BC3_UNORM
, DXGI_FORMAT_BC3_UNORM_SRGB
,
79 DXGI_FORMAT_BC4_TYPELESS
, DXGI_FORMAT_BC4_UNORM
, DXGI_FORMAT_BC4_SNORM
,
80 DXGI_FORMAT_BC5_TYPELESS
, DXGI_FORMAT_BC5_UNORM
, DXGI_FORMAT_BC5_SNORM
,
81 DXGI_FORMAT_BC6H_TYPELESS
, DXGI_FORMAT_BC6H_UF16
, DXGI_FORMAT_BC6H_SF16
,
82 DXGI_FORMAT_BC7_TYPELESS
, DXGI_FORMAT_BC7_UNORM
, DXGI_FORMAT_BC7_UNORM_SRGB
85 static const DXGI_FORMAT to_be_converted_format
[] =
89 DXGI_FORMAT_R8G8_UNORM
,
90 DXGI_FORMAT_B5G6R5_UNORM
,
91 DXGI_FORMAT_B4G4R4A4_UNORM
,
92 DXGI_FORMAT_B5G5R5A1_UNORM
,
93 DXGI_FORMAT_B8G8R8X8_UNORM
,
94 DXGI_FORMAT_B8G8R8A8_UNORM
97 static D3DX10_IMAGE_FILE_FORMAT
wic_container_guid_to_file_format(GUID
*container_format
)
101 for (i
= 0; i
< ARRAY_SIZE(file_formats
); ++i
)
103 if (IsEqualGUID(file_formats
[i
].wic_container_guid
, container_format
))
104 return file_formats
[i
].d3dx_file_format
;
106 return D3DX10_IFF_FORCE_DWORD
;
109 static const GUID
*dxgi_format_to_wic_guid(DXGI_FORMAT format
)
113 for (i
= 0; i
< ARRAY_SIZE(wic_pixel_formats
); ++i
)
115 if (wic_pixel_formats
[i
].dxgi_format
== format
)
116 return wic_pixel_formats
[i
].wic_guid
;
122 static D3D10_RESOURCE_DIMENSION
wic_dimension_to_d3dx10_dimension(WICDdsDimension wic_dimension
)
124 switch (wic_dimension
)
126 case WICDdsTexture1D
:
127 return D3D10_RESOURCE_DIMENSION_TEXTURE1D
;
128 case WICDdsTexture2D
:
129 case WICDdsTextureCube
:
130 return D3D10_RESOURCE_DIMENSION_TEXTURE2D
;
131 case WICDdsTexture3D
:
132 return D3D10_RESOURCE_DIMENSION_TEXTURE3D
;
134 return D3D10_RESOURCE_DIMENSION_UNKNOWN
;
138 static BOOL
is_block_compressed(DXGI_FORMAT format
)
142 for (i
= 0; i
< ARRAY_SIZE(block_compressed_formats
); ++i
)
143 if (format
== block_compressed_formats
[i
])
149 static unsigned int get_bpp_from_format(DXGI_FORMAT format
)
153 case DXGI_FORMAT_R32G32B32A32_TYPELESS
:
154 case DXGI_FORMAT_R32G32B32A32_FLOAT
:
155 case DXGI_FORMAT_R32G32B32A32_UINT
:
156 case DXGI_FORMAT_R32G32B32A32_SINT
:
158 case DXGI_FORMAT_R32G32B32_TYPELESS
:
159 case DXGI_FORMAT_R32G32B32_FLOAT
:
160 case DXGI_FORMAT_R32G32B32_UINT
:
161 case DXGI_FORMAT_R32G32B32_SINT
:
163 case DXGI_FORMAT_R16G16B16A16_TYPELESS
:
164 case DXGI_FORMAT_R16G16B16A16_FLOAT
:
165 case DXGI_FORMAT_R16G16B16A16_UNORM
:
166 case DXGI_FORMAT_R16G16B16A16_UINT
:
167 case DXGI_FORMAT_R16G16B16A16_SNORM
:
168 case DXGI_FORMAT_R16G16B16A16_SINT
:
169 case DXGI_FORMAT_R32G32_TYPELESS
:
170 case DXGI_FORMAT_R32G32_FLOAT
:
171 case DXGI_FORMAT_R32G32_UINT
:
172 case DXGI_FORMAT_R32G32_SINT
:
173 case DXGI_FORMAT_R32G8X24_TYPELESS
:
174 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT
:
175 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS
:
176 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT
:
177 case DXGI_FORMAT_Y416
:
178 case DXGI_FORMAT_Y210
:
179 case DXGI_FORMAT_Y216
:
181 case DXGI_FORMAT_R10G10B10A2_TYPELESS
:
182 case DXGI_FORMAT_R10G10B10A2_UNORM
:
183 case DXGI_FORMAT_R10G10B10A2_UINT
:
184 case DXGI_FORMAT_R11G11B10_FLOAT
:
185 case DXGI_FORMAT_R8G8B8A8_TYPELESS
:
186 case DXGI_FORMAT_R8G8B8A8_UNORM
:
187 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
:
188 case DXGI_FORMAT_R8G8B8A8_UINT
:
189 case DXGI_FORMAT_R8G8B8A8_SNORM
:
190 case DXGI_FORMAT_R8G8B8A8_SINT
:
191 case DXGI_FORMAT_R16G16_TYPELESS
:
192 case DXGI_FORMAT_R16G16_FLOAT
:
193 case DXGI_FORMAT_R16G16_UNORM
:
194 case DXGI_FORMAT_R16G16_UINT
:
195 case DXGI_FORMAT_R16G16_SNORM
:
196 case DXGI_FORMAT_R16G16_SINT
:
197 case DXGI_FORMAT_R32_TYPELESS
:
198 case DXGI_FORMAT_D32_FLOAT
:
199 case DXGI_FORMAT_R32_FLOAT
:
200 case DXGI_FORMAT_R32_UINT
:
201 case DXGI_FORMAT_R32_SINT
:
202 case DXGI_FORMAT_R24G8_TYPELESS
:
203 case DXGI_FORMAT_D24_UNORM_S8_UINT
:
204 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS
:
205 case DXGI_FORMAT_X24_TYPELESS_G8_UINT
:
206 case DXGI_FORMAT_R9G9B9E5_SHAREDEXP
:
207 case DXGI_FORMAT_R8G8_B8G8_UNORM
:
208 case DXGI_FORMAT_G8R8_G8B8_UNORM
:
209 case DXGI_FORMAT_B8G8R8A8_UNORM
:
210 case DXGI_FORMAT_B8G8R8X8_UNORM
:
211 case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
:
212 case DXGI_FORMAT_B8G8R8A8_TYPELESS
:
213 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
:
214 case DXGI_FORMAT_B8G8R8X8_TYPELESS
:
215 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB
:
216 case DXGI_FORMAT_AYUV
:
217 case DXGI_FORMAT_Y410
:
218 case DXGI_FORMAT_YUY2
:
220 case DXGI_FORMAT_P010
:
221 case DXGI_FORMAT_P016
:
223 case DXGI_FORMAT_R8G8_TYPELESS
:
224 case DXGI_FORMAT_R8G8_UNORM
:
225 case DXGI_FORMAT_R8G8_UINT
:
226 case DXGI_FORMAT_R8G8_SNORM
:
227 case DXGI_FORMAT_R8G8_SINT
:
228 case DXGI_FORMAT_R16_TYPELESS
:
229 case DXGI_FORMAT_R16_FLOAT
:
230 case DXGI_FORMAT_D16_UNORM
:
231 case DXGI_FORMAT_R16_UNORM
:
232 case DXGI_FORMAT_R16_UINT
:
233 case DXGI_FORMAT_R16_SNORM
:
234 case DXGI_FORMAT_R16_SINT
:
235 case DXGI_FORMAT_B5G6R5_UNORM
:
236 case DXGI_FORMAT_B5G5R5A1_UNORM
:
237 case DXGI_FORMAT_A8P8
:
238 case DXGI_FORMAT_B4G4R4A4_UNORM
:
240 case DXGI_FORMAT_NV12
:
241 case DXGI_FORMAT_420_OPAQUE
:
242 case DXGI_FORMAT_NV11
:
244 case DXGI_FORMAT_R8_TYPELESS
:
245 case DXGI_FORMAT_R8_UNORM
:
246 case DXGI_FORMAT_R8_UINT
:
247 case DXGI_FORMAT_R8_SNORM
:
248 case DXGI_FORMAT_R8_SINT
:
249 case DXGI_FORMAT_A8_UNORM
:
250 case DXGI_FORMAT_AI44
:
251 case DXGI_FORMAT_IA44
:
253 case DXGI_FORMAT_BC2_TYPELESS
:
254 case DXGI_FORMAT_BC2_UNORM
:
255 case DXGI_FORMAT_BC2_UNORM_SRGB
:
256 case DXGI_FORMAT_BC3_TYPELESS
:
257 case DXGI_FORMAT_BC3_UNORM
:
258 case DXGI_FORMAT_BC3_UNORM_SRGB
:
259 case DXGI_FORMAT_BC5_TYPELESS
:
260 case DXGI_FORMAT_BC5_UNORM
:
261 case DXGI_FORMAT_BC5_SNORM
:
262 case DXGI_FORMAT_BC6H_TYPELESS
:
263 case DXGI_FORMAT_BC6H_UF16
:
264 case DXGI_FORMAT_BC6H_SF16
:
265 case DXGI_FORMAT_BC7_TYPELESS
:
266 case DXGI_FORMAT_BC7_UNORM
:
267 case DXGI_FORMAT_BC7_UNORM_SRGB
:
269 case DXGI_FORMAT_BC1_TYPELESS
:
270 case DXGI_FORMAT_BC1_UNORM
:
271 case DXGI_FORMAT_BC1_UNORM_SRGB
:
272 case DXGI_FORMAT_BC4_TYPELESS
:
273 case DXGI_FORMAT_BC4_UNORM
:
274 case DXGI_FORMAT_BC4_SNORM
:
276 case DXGI_FORMAT_R1_UNORM
:
283 static DXGI_FORMAT
get_d3dx10_dds_format(DXGI_FORMAT format
)
287 for (i
= 0; i
< ARRAY_SIZE(to_be_converted_format
); ++i
)
289 if (format
== to_be_converted_format
[i
])
290 return DXGI_FORMAT_R8G8B8A8_UNORM
;
295 HRESULT WINAPI
D3DX10GetImageInfoFromFileA(const char *src_file
, ID3DX10ThreadPump
*pump
, D3DX10_IMAGE_INFO
*info
,
302 TRACE("src_file %s, pump %p, info %p, result %p.\n", debugstr_a(src_file
), pump
, info
, result
);
307 str_len
= MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, NULL
, 0);
309 return HRESULT_FROM_WIN32(GetLastError());
311 buffer
= malloc(str_len
* sizeof(*buffer
));
313 return E_OUTOFMEMORY
;
315 MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, buffer
, str_len
);
316 hr
= D3DX10GetImageInfoFromFileW(buffer
, pump
, info
, result
);
323 HRESULT WINAPI
D3DX10GetImageInfoFromFileW(const WCHAR
*src_file
, ID3DX10ThreadPump
*pump
, D3DX10_IMAGE_INFO
*info
,
330 TRACE("src_file %s, pump %p, info %p, result %p.\n", debugstr_w(src_file
), pump
, info
, result
);
337 ID3DX10DataProcessor
*processor
;
338 ID3DX10DataLoader
*loader
;
340 if (FAILED((hr
= D3DX10CreateAsyncFileLoaderW(src_file
, &loader
))))
342 if (FAILED((hr
= D3DX10CreateAsyncTextureInfoProcessor(info
, &processor
))))
344 ID3DX10DataLoader_Destroy(loader
);
347 hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, result
, NULL
);
350 ID3DX10DataLoader_Destroy(loader
);
351 ID3DX10DataProcessor_Destroy(processor
);
356 if (SUCCEEDED((hr
= load_file(src_file
, &buffer
, &size
))))
358 hr
= get_image_info(buffer
, size
, info
);
366 HRESULT WINAPI
D3DX10GetImageInfoFromResourceA(HMODULE module
, const char *resource
, ID3DX10ThreadPump
*pump
,
367 D3DX10_IMAGE_INFO
*info
, HRESULT
*result
)
373 TRACE("module %p, resource %s, pump %p, info %p, result %p.\n",
374 module
, debugstr_a(resource
), pump
, info
, result
);
378 ID3DX10DataProcessor
*processor
;
379 ID3DX10DataLoader
*loader
;
381 if (FAILED((hr
= D3DX10CreateAsyncResourceLoaderA(module
, resource
, &loader
))))
383 if (FAILED((hr
= D3DX10CreateAsyncTextureInfoProcessor(info
, &processor
))))
385 ID3DX10DataLoader_Destroy(loader
);
388 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, result
, NULL
))))
390 ID3DX10DataLoader_Destroy(loader
);
391 ID3DX10DataProcessor_Destroy(processor
);
396 if (FAILED((hr
= load_resourceA(module
, resource
, &buffer
, &size
))))
398 hr
= get_image_info(buffer
, size
, info
);
404 HRESULT WINAPI
D3DX10GetImageInfoFromResourceW(HMODULE module
, const WCHAR
*resource
, ID3DX10ThreadPump
*pump
,
405 D3DX10_IMAGE_INFO
*info
, HRESULT
*result
)
411 TRACE("module %p, resource %s, pump %p, info %p, result %p.\n",
412 module
, debugstr_w(resource
), pump
, info
, result
);
416 ID3DX10DataProcessor
*processor
;
417 ID3DX10DataLoader
*loader
;
419 if (FAILED((hr
= D3DX10CreateAsyncResourceLoaderW(module
, resource
, &loader
))))
421 if (FAILED((hr
= D3DX10CreateAsyncTextureInfoProcessor(info
, &processor
))))
423 ID3DX10DataLoader_Destroy(loader
);
426 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, result
, NULL
))))
428 ID3DX10DataLoader_Destroy(loader
);
429 ID3DX10DataProcessor_Destroy(processor
);
434 if (FAILED((hr
= load_resourceW(module
, resource
, &buffer
, &size
))))
436 hr
= get_image_info(buffer
, size
, info
);
442 HRESULT
get_image_info(const void *data
, SIZE_T size
, D3DX10_IMAGE_INFO
*img_info
)
444 IWICBitmapFrameDecode
*frame
= NULL
;
445 IWICImagingFactory
*factory
= NULL
;
446 IWICDdsDecoder
*dds_decoder
= NULL
;
447 IWICBitmapDecoder
*decoder
= NULL
;
448 WICDdsParameters dds_params
;
449 IWICStream
*stream
= NULL
;
450 unsigned int frame_count
;
451 GUID container_format
;
454 WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION
, &factory
);
455 IWICImagingFactory_CreateStream(factory
, &stream
);
456 hr
= IWICStream_InitializeFromMemory(stream
, (BYTE
*)data
, size
);
459 WARN("Failed to initialize stream.\n");
462 hr
= IWICImagingFactory_CreateDecoderFromStream(factory
, (IStream
*)stream
, NULL
, 0, &decoder
);
466 hr
= IWICBitmapDecoder_GetContainerFormat(decoder
, &container_format
);
469 img_info
->ImageFileFormat
= wic_container_guid_to_file_format(&container_format
);
470 if (img_info
->ImageFileFormat
== D3DX10_IFF_FORCE_DWORD
)
473 WARN("Unsupported image file format %s.\n", debugstr_guid(&container_format
));
477 hr
= IWICBitmapDecoder_GetFrameCount(decoder
, &frame_count
);
478 if (FAILED(hr
) || !frame_count
)
480 hr
= IWICBitmapDecoder_GetFrame(decoder
, 0, &frame
);
483 hr
= IWICBitmapFrameDecode_GetSize(frame
, &img_info
->Width
, &img_info
->Height
);
487 if (img_info
->ImageFileFormat
== D3DX10_IFF_DDS
)
489 hr
= IWICBitmapDecoder_QueryInterface(decoder
, &IID_IWICDdsDecoder
, (void **)&dds_decoder
);
492 hr
= IWICDdsDecoder_GetParameters(dds_decoder
, &dds_params
);
495 img_info
->ArraySize
= dds_params
.ArraySize
;
496 img_info
->Depth
= dds_params
.Depth
;
497 img_info
->MipLevels
= dds_params
.MipLevels
;
498 img_info
->ResourceDimension
= wic_dimension_to_d3dx10_dimension(dds_params
.Dimension
);
499 img_info
->Format
= get_d3dx10_dds_format(dds_params
.DxgiFormat
);
500 img_info
->MiscFlags
= 0;
501 if (dds_params
.Dimension
== WICDdsTextureCube
)
503 img_info
->MiscFlags
= D3D10_RESOURCE_MISC_TEXTURECUBE
;
504 img_info
->ArraySize
*= 6;
509 img_info
->ArraySize
= 1;
511 img_info
->MipLevels
= 1;
512 img_info
->ResourceDimension
= D3D10_RESOURCE_DIMENSION_TEXTURE2D
;
513 img_info
->Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
514 img_info
->MiscFlags
= 0;
519 IWICDdsDecoder_Release(dds_decoder
);
521 IWICBitmapFrameDecode_Release(frame
);
523 IWICBitmapDecoder_Release(decoder
);
525 IWICStream_Release(stream
);
527 IWICImagingFactory_Release(factory
);
531 WARN("Invalid or unsupported image file.\n");
537 HRESULT WINAPI
D3DX10GetImageInfoFromMemory(const void *src_data
, SIZE_T src_data_size
, ID3DX10ThreadPump
*pump
,
538 D3DX10_IMAGE_INFO
*img_info
, HRESULT
*result
)
542 TRACE("src_data %p, src_data_size %Iu, pump %p, img_info %p, hresult %p.\n",
543 src_data
, src_data_size
, pump
, img_info
, result
);
550 ID3DX10DataProcessor
*processor
;
551 ID3DX10DataLoader
*loader
;
553 if (FAILED((hr
= D3DX10CreateAsyncMemoryLoader(src_data
, src_data_size
, &loader
))))
555 if (FAILED((hr
= D3DX10CreateAsyncTextureInfoProcessor(img_info
, &processor
))))
557 ID3DX10DataLoader_Destroy(loader
);
560 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, result
, NULL
))))
562 ID3DX10DataLoader_Destroy(loader
);
563 ID3DX10DataProcessor_Destroy(processor
);
568 hr
= get_image_info(src_data
, src_data_size
, img_info
);
574 static HRESULT
create_texture(ID3D10Device
*device
, const void *data
, SIZE_T size
,
575 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3D10Resource
**texture
)
577 D3D10_SUBRESOURCE_DATA
*resource_data
;
578 D3DX10_IMAGE_LOAD_INFO load_info_copy
;
581 init_load_info(load_info
, &load_info_copy
);
583 if (FAILED((hr
= load_texture_data(data
, size
, &load_info_copy
, &resource_data
))))
585 hr
= create_d3d_texture(device
, &load_info_copy
, resource_data
, texture
);
590 HRESULT WINAPI
D3DX10CreateTextureFromFileA(ID3D10Device
*device
, const char *src_file
,
591 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
597 TRACE("device %p, src_file %s, load_info %p, pump %p, texture %p, hresult %p.\n",
598 device
, debugstr_a(src_file
), load_info
, pump
, texture
, hresult
);
605 if (!(str_len
= MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, NULL
, 0)))
606 return HRESULT_FROM_WIN32(GetLastError());
608 if (!(buffer
= malloc(str_len
* sizeof(*buffer
))))
609 return E_OUTOFMEMORY
;
611 MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, buffer
, str_len
);
612 hr
= D3DX10CreateTextureFromFileW(device
, buffer
, load_info
, pump
, texture
, hresult
);
619 HRESULT WINAPI
D3DX10CreateTextureFromFileW(ID3D10Device
*device
, const WCHAR
*src_file
,
620 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
626 TRACE("device %p, src_file %s, load_info %p, pump %p, texture %p, hresult %p.\n",
627 device
, debugstr_w(src_file
), load_info
, pump
, texture
, hresult
);
634 if (FAILED((hr
= load_file(src_file
, &buffer
, &size
))))
641 hr
= D3DX10CreateTextureFromMemory(device
, buffer
, size
, load_info
, pump
, texture
, hresult
);
648 HRESULT WINAPI
D3DX10CreateTextureFromResourceA(ID3D10Device
*device
, HMODULE module
, const char *resource
,
649 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
655 TRACE("device %p, module %p, resource %s, load_info %p, pump %p, texture %p, hresult %p.\n",
656 device
, module
, debugstr_a(resource
), load_info
, pump
, texture
, hresult
);
661 hr
= load_resourceA(module
, resource
, &buffer
, &size
);
665 return D3DX10CreateTextureFromMemory(device
, buffer
, size
, load_info
, pump
, texture
, hresult
);
668 HRESULT WINAPI
D3DX10CreateTextureFromResourceW(ID3D10Device
*device
, HMODULE module
, const WCHAR
*resource
,
669 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
675 TRACE("device %p, module %p, resource %s, load_info %p, pump %p, texture %p, hresult %p.\n",
676 device
, module
, debugstr_w(resource
), load_info
, pump
, texture
, hresult
);
681 hr
= load_resourceW(module
, resource
, &buffer
, &size
);
685 return D3DX10CreateTextureFromMemory(device
, buffer
, size
, load_info
, pump
, texture
, hresult
);
688 void init_load_info(const D3DX10_IMAGE_LOAD_INFO
*load_info
, D3DX10_IMAGE_LOAD_INFO
*out
)
696 out
->Width
= D3DX10_DEFAULT
;
697 out
->Height
= D3DX10_DEFAULT
;
698 out
->Depth
= D3DX10_DEFAULT
;
699 out
->FirstMipLevel
= D3DX10_DEFAULT
;
700 out
->MipLevels
= D3DX10_DEFAULT
;
701 out
->Usage
= D3DX10_DEFAULT
;
702 out
->BindFlags
= D3DX10_DEFAULT
;
703 out
->CpuAccessFlags
= D3DX10_DEFAULT
;
704 out
->MiscFlags
= D3DX10_DEFAULT
;
705 out
->Format
= D3DX10_DEFAULT
;
706 out
->Filter
= D3DX10_DEFAULT
;
707 out
->MipFilter
= D3DX10_DEFAULT
;
708 out
->pSrcInfo
= NULL
;
711 HRESULT
load_texture_data(const void *data
, SIZE_T size
, D3DX10_IMAGE_LOAD_INFO
*load_info
,
712 D3D10_SUBRESOURCE_DATA
**resource_data
)
714 unsigned int frame_count
, width
, height
, stride
, frame_size
;
715 IWICFormatConverter
*converter
= NULL
;
716 IWICDdsFrameDecode
*dds_frame
= NULL
;
717 IWICBitmapFrameDecode
*frame
= NULL
;
718 IWICImagingFactory
*factory
= NULL
;
719 IWICBitmapDecoder
*decoder
= NULL
;
720 BYTE
*res_data
= NULL
, *buffer
;
721 D3DX10_IMAGE_INFO img_info
;
722 IWICStream
*stream
= NULL
;
723 const GUID
*dst_format
;
728 if (load_info
->Width
!= D3DX10_DEFAULT
)
729 FIXME("load_info->Width is ignored.\n");
730 if (load_info
->Height
!= D3DX10_DEFAULT
)
731 FIXME("load_info->Height is ignored.\n");
732 if (load_info
->Depth
!= D3DX10_DEFAULT
)
733 FIXME("load_info->Depth is ignored.\n");
734 if (load_info
->FirstMipLevel
!= D3DX10_DEFAULT
)
735 FIXME("load_info->FirstMipLevel is ignored.\n");
736 if (load_info
->MipLevels
!= D3DX10_DEFAULT
)
737 FIXME("load_info->MipLevels is ignored.\n");
738 if (load_info
->Usage
!= D3DX10_DEFAULT
)
739 FIXME("load_info->Usage is ignored.\n");
740 if (load_info
->BindFlags
!= D3DX10_DEFAULT
)
741 FIXME("load_info->BindFlags is ignored.\n");
742 if (load_info
->CpuAccessFlags
!= D3DX10_DEFAULT
)
743 FIXME("load_info->CpuAccessFlags is ignored.\n");
744 if (load_info
->MiscFlags
!= D3DX10_DEFAULT
)
745 FIXME("load_info->MiscFlags is ignored.\n");
746 if (load_info
->Format
!= D3DX10_DEFAULT
)
747 FIXME("load_info->Format is ignored.\n");
748 if (load_info
->Filter
!= D3DX10_DEFAULT
)
749 FIXME("load_info->Filter is ignored.\n");
750 if (load_info
->MipFilter
!= D3DX10_DEFAULT
)
751 FIXME("load_info->MipFilter is ignored.\n");
752 if (load_info
->pSrcInfo
)
753 FIXME("load_info->pSrcInfo is ignored.\n");
755 if (FAILED(D3DX10GetImageInfoFromMemory(data
, size
, NULL
, &img_info
, NULL
)))
757 if (img_info
.MiscFlags
& D3D10_RESOURCE_MISC_TEXTURECUBE
)
759 FIXME("Cube map is not supported.\n");
762 if (img_info
.ArraySize
!= 1)
764 FIXME("img_info.ArraySize = %u not supported.\n", img_info
.ArraySize
);
768 if (FAILED(hr
= WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION
, &factory
)))
770 if (FAILED(hr
= IWICImagingFactory_CreateStream(factory
, &stream
)))
772 if (FAILED(hr
= IWICStream_InitializeFromMemory(stream
, (BYTE
*)data
, size
)))
774 if (FAILED(hr
= IWICImagingFactory_CreateDecoderFromStream(factory
, (IStream
*)stream
, NULL
, 0, &decoder
)))
776 if (FAILED(hr
= IWICBitmapDecoder_GetFrameCount(decoder
, &frame_count
)) || !frame_count
)
778 if (FAILED(hr
= IWICBitmapDecoder_GetFrame(decoder
, 0, &frame
)))
780 if (FAILED(hr
= IWICBitmapFrameDecode_GetPixelFormat(frame
, &src_format
)))
783 width
= img_info
.Width
;
784 height
= img_info
.Height
;
785 if (is_block_compressed(img_info
.Format
))
787 width
= (width
+ 3) & ~3;
788 height
= (height
+ 3) & ~3;
790 stride
= (width
* get_bpp_from_format(img_info
.Format
) + 7) / 8;
791 frame_size
= stride
* height
;
793 if (!(res_data
= malloc(sizeof(**resource_data
) + frame_size
)))
798 buffer
= res_data
+ sizeof(**resource_data
);
800 if (is_block_compressed(img_info
.Format
))
802 if (FAILED(hr
= IWICBitmapFrameDecode_QueryInterface(frame
, &IID_IWICDdsFrameDecode
, (void **)&dds_frame
)))
804 if (FAILED(hr
= IWICDdsFrameDecode_CopyBlocks(dds_frame
, NULL
, stride
* 4, frame_size
, buffer
)))
809 if (!(dst_format
= dxgi_format_to_wic_guid(img_info
.Format
)))
812 FIXME("Unsupported DXGI format %#x.\n", img_info
.Format
);
816 if (IsEqualGUID(&src_format
, dst_format
))
818 if (FAILED(hr
= IWICBitmapFrameDecode_CopyPixels(frame
, NULL
, stride
, frame_size
, buffer
)))
823 if (FAILED(hr
= IWICImagingFactory_CreateFormatConverter(factory
, &converter
)))
825 if (FAILED(hr
= IWICFormatConverter_CanConvert(converter
, &src_format
, dst_format
, &can_convert
)))
829 WARN("Format converting %s to %s is not supported by WIC.\n",
830 debugstr_guid(&src_format
), debugstr_guid(dst_format
));
833 if (FAILED(hr
= IWICFormatConverter_Initialize(converter
, (IWICBitmapSource
*)frame
, dst_format
,
834 WICBitmapDitherTypeErrorDiffusion
, 0, 0, WICBitmapPaletteTypeCustom
)))
836 if (FAILED(hr
= IWICFormatConverter_CopyPixels(converter
, NULL
, stride
, frame_size
, buffer
)))
841 load_info
->Width
= width
;
842 load_info
->Height
= height
;
843 load_info
->MipLevels
= 1;
844 load_info
->Format
= img_info
.Format
;
845 load_info
->Usage
= D3D10_USAGE_DEFAULT
;
846 load_info
->BindFlags
= D3D10_BIND_SHADER_RESOURCE
;
847 load_info
->MiscFlags
= img_info
.MiscFlags
;
849 *resource_data
= (D3D10_SUBRESOURCE_DATA
*)res_data
;
851 (*resource_data
)->pSysMem
= buffer
;
852 (*resource_data
)->SysMemPitch
= stride
;
853 (*resource_data
)->SysMemSlicePitch
= frame_size
;
859 IWICFormatConverter_Release(converter
);
861 IWICDdsFrameDecode_Release(dds_frame
);
864 IWICBitmapFrameDecode_Release(frame
);
866 IWICBitmapDecoder_Release(decoder
);
868 IWICStream_Release(stream
);
870 IWICImagingFactory_Release(factory
);
874 HRESULT
create_d3d_texture(ID3D10Device
*device
, D3DX10_IMAGE_LOAD_INFO
*load_info
,
875 D3D10_SUBRESOURCE_DATA
*resource_data
, ID3D10Resource
**texture
)
877 D3D10_TEXTURE2D_DESC texture_2d_desc
;
878 ID3D10Texture2D
*texture_2d
;
881 memset(&texture_2d_desc
, 0, sizeof(texture_2d_desc
));
882 texture_2d_desc
.Width
= load_info
->Width
;
883 texture_2d_desc
.Height
= load_info
->Height
;
884 texture_2d_desc
.MipLevels
= load_info
->MipLevels
;
885 texture_2d_desc
.ArraySize
= 1;
886 texture_2d_desc
.Format
= load_info
->Format
;
887 texture_2d_desc
.SampleDesc
.Count
= 1;
888 texture_2d_desc
.Usage
= load_info
->Usage
;
889 texture_2d_desc
.BindFlags
= load_info
->BindFlags
;
890 texture_2d_desc
.MiscFlags
= load_info
->MiscFlags
;
892 if (FAILED(hr
= ID3D10Device_CreateTexture2D(device
, &texture_2d_desc
, resource_data
, &texture_2d
)))
895 *texture
= (ID3D10Resource
*)texture_2d
;
899 HRESULT WINAPI
D3DX10CreateTextureFromMemory(ID3D10Device
*device
, const void *src_data
, SIZE_T src_data_size
,
900 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
904 TRACE("device %p, src_data %p, src_data_size %Iu, load_info %p, pump %p, texture %p, hresult %p.\n",
905 device
, src_data
, src_data_size
, load_info
, pump
, texture
, hresult
);
912 FIXME("Thread pump is not supported yet.\n");
914 hr
= create_texture(device
, src_data
, src_data_size
, load_info
, texture
);