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"
20 #include "wine/heap.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
},
48 static const DXGI_FORMAT to_be_converted_format
[] =
52 DXGI_FORMAT_R8G8_UNORM
,
53 DXGI_FORMAT_B5G6R5_UNORM
,
54 DXGI_FORMAT_B4G4R4A4_UNORM
,
55 DXGI_FORMAT_B5G5R5A1_UNORM
,
56 DXGI_FORMAT_B8G8R8X8_UNORM
,
57 DXGI_FORMAT_B8G8R8A8_UNORM
60 static D3DX10_IMAGE_FILE_FORMAT
wic_container_guid_to_file_format(GUID
*container_format
)
64 for (i
= 0; i
< ARRAY_SIZE(file_formats
); ++i
)
66 if (IsEqualGUID(file_formats
[i
].wic_container_guid
, container_format
))
67 return file_formats
[i
].d3dx_file_format
;
69 return D3DX10_IFF_FORCE_DWORD
;
72 static D3D10_RESOURCE_DIMENSION
wic_dimension_to_d3dx10_dimension(WICDdsDimension wic_dimension
)
74 switch (wic_dimension
)
77 return D3D10_RESOURCE_DIMENSION_TEXTURE1D
;
79 case WICDdsTextureCube
:
80 return D3D10_RESOURCE_DIMENSION_TEXTURE2D
;
82 return D3D10_RESOURCE_DIMENSION_TEXTURE3D
;
84 return D3D10_RESOURCE_DIMENSION_UNKNOWN
;
88 static DXGI_FORMAT
get_d3dx10_dds_format(DXGI_FORMAT format
)
92 for (i
= 0; i
< ARRAY_SIZE(to_be_converted_format
); ++i
)
94 if (format
== to_be_converted_format
[i
])
95 return DXGI_FORMAT_R8G8B8A8_UNORM
;
100 static HRESULT
load_file(const WCHAR
*filename
, void **buffer
, DWORD
*size
)
107 file
= CreateFileW(filename
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
108 if (file
== INVALID_HANDLE_VALUE
)
110 hr
= HRESULT_FROM_WIN32(GetLastError());
114 *size
= GetFileSize(file
, NULL
);
115 if (*size
== INVALID_FILE_SIZE
)
117 hr
= HRESULT_FROM_WIN32(GetLastError());
121 *buffer
= heap_alloc(*size
);
128 ret
= ReadFile(file
, *buffer
, *size
, &bytes_read
, NULL
);
131 hr
= HRESULT_FROM_WIN32(GetLastError());
134 if (bytes_read
!= *size
)
146 if (file
!= INVALID_HANDLE_VALUE
)
151 static HRESULT
load_resource(HMODULE module
, HRSRC res_info
, void **buffer
, DWORD
*size
)
155 if (!(*size
= SizeofResource(module
, res_info
)))
156 return HRESULT_FROM_WIN32(GetLastError());
158 if (!(resource
= LoadResource(module
, res_info
)))
159 return HRESULT_FROM_WIN32(GetLastError());
161 if (!(*buffer
= LockResource(resource
)))
162 return HRESULT_FROM_WIN32(GetLastError());
167 HRESULT WINAPI
D3DX10GetImageInfoFromFileA(const char *src_file
, ID3DX10ThreadPump
*pump
, D3DX10_IMAGE_INFO
*info
,
174 TRACE("src_file %s, pump %p, info %p, result %p.\n", debugstr_a(src_file
), pump
, info
, result
);
176 if (!src_file
|| !info
)
179 str_len
= MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, NULL
, 0);
181 return HRESULT_FROM_WIN32(GetLastError());
183 buffer
= heap_alloc(str_len
* sizeof(*buffer
));
185 return E_OUTOFMEMORY
;
187 MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, buffer
, str_len
);
188 hr
= D3DX10GetImageInfoFromFileW(buffer
, pump
, info
, result
);
195 HRESULT WINAPI
D3DX10GetImageInfoFromFileW(const WCHAR
*src_file
, ID3DX10ThreadPump
*pump
, D3DX10_IMAGE_INFO
*info
,
202 TRACE("src_file %s, pump %p, info %p, result %p.\n", debugstr_w(src_file
), pump
, info
, result
);
204 if (!src_file
|| !info
)
207 if (FAILED(load_file(src_file
, &buffer
, &size
)))
208 return D3D10_ERROR_FILE_NOT_FOUND
;
210 hr
= D3DX10GetImageInfoFromMemory(buffer
, size
, pump
, info
, result
);
217 HRESULT WINAPI
D3DX10GetImageInfoFromResourceA(HMODULE module
, const char *resource
, ID3DX10ThreadPump
*pump
,
218 D3DX10_IMAGE_INFO
*info
, HRESULT
*result
)
225 TRACE("module %p, resource %s, pump %p, info %p, result %p.\n",
226 module
, debugstr_a(resource
), pump
, info
, result
);
228 if (!resource
|| !info
)
229 return D3DX10_ERR_INVALID_DATA
;
231 res_info
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
);
234 /* Try loading the resource as bitmap data */
235 res_info
= FindResourceA(module
, resource
, (const char *)RT_BITMAP
);
237 return D3DX10_ERR_INVALID_DATA
;
240 hr
= load_resource(module
, res_info
, &buffer
, &size
);
242 return D3DX10_ERR_INVALID_DATA
;
244 return D3DX10GetImageInfoFromMemory(buffer
, size
, pump
, info
, result
);
247 HRESULT WINAPI
D3DX10GetImageInfoFromResourceW(HMODULE module
, const WCHAR
*resource
, ID3DX10ThreadPump
*pump
,
248 D3DX10_IMAGE_INFO
*info
, HRESULT
*result
)
255 TRACE("module %p, resource %s, pump %p, info %p, result %p.\n",
256 module
, debugstr_w(resource
), pump
, info
, result
);
258 if (!resource
|| !info
)
259 return D3DX10_ERR_INVALID_DATA
;
261 res_info
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
);
264 /* Try loading the resource as bitmap data */
265 res_info
= FindResourceW(module
, resource
, (const WCHAR
*)RT_BITMAP
);
267 return D3DX10_ERR_INVALID_DATA
;
270 hr
= load_resource(module
, res_info
, &buffer
, &size
);
272 return D3DX10_ERR_INVALID_DATA
;
274 return D3DX10GetImageInfoFromMemory(buffer
, size
, pump
, info
, result
);
277 HRESULT WINAPI
D3DX10GetImageInfoFromMemory(const void *src_data
, SIZE_T src_data_size
, ID3DX10ThreadPump
*pump
,
278 D3DX10_IMAGE_INFO
*img_info
, HRESULT
*hresult
)
280 IWICBitmapFrameDecode
*frame
= NULL
;
281 IWICImagingFactory
*factory
= NULL
;
282 IWICDdsDecoder
*dds_decoder
= NULL
;
283 IWICBitmapDecoder
*decoder
= NULL
;
284 WICDdsParameters dds_params
;
285 IWICStream
*stream
= NULL
;
286 unsigned int frame_count
;
287 GUID container_format
;
290 TRACE("src_data %p, src_data_size %lu, pump %p, img_info %p, hresult %p.\n",
291 src_data
, src_data_size
, pump
, img_info
, hresult
);
293 if (!src_data
|| !src_data_size
|| !img_info
)
296 FIXME("Thread pump is not supported yet.\n");
298 WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION
, &factory
);
299 IWICImagingFactory_CreateStream(factory
, &stream
);
300 hr
= IWICStream_InitializeFromMemory(stream
, (BYTE
*)src_data
, src_data_size
);
303 WARN("Failed to initialize stream.\n");
306 hr
= IWICImagingFactory_CreateDecoderFromStream(factory
, (IStream
*)stream
, NULL
, 0, &decoder
);
310 hr
= IWICBitmapDecoder_GetContainerFormat(decoder
, &container_format
);
313 img_info
->ImageFileFormat
= wic_container_guid_to_file_format(&container_format
);
314 if (img_info
->ImageFileFormat
== D3DX10_IFF_FORCE_DWORD
)
317 WARN("Unsupported image file format %s.\n", debugstr_guid(&container_format
));
321 hr
= IWICBitmapDecoder_GetFrameCount(decoder
, &frame_count
);
322 if (FAILED(hr
) || !frame_count
)
324 hr
= IWICBitmapDecoder_GetFrame(decoder
, 0, &frame
);
327 hr
= IWICBitmapFrameDecode_GetSize(frame
, &img_info
->Width
, &img_info
->Height
);
331 if (img_info
->ImageFileFormat
== D3DX10_IFF_DDS
)
333 hr
= IWICBitmapDecoder_QueryInterface(decoder
, &IID_IWICDdsDecoder
, (void **)&dds_decoder
);
336 hr
= IWICDdsDecoder_GetParameters(dds_decoder
, &dds_params
);
339 img_info
->ArraySize
= dds_params
.ArraySize
;
340 img_info
->Depth
= dds_params
.Depth
;
341 img_info
->MipLevels
= dds_params
.MipLevels
;
342 img_info
->ResourceDimension
= wic_dimension_to_d3dx10_dimension(dds_params
.Dimension
);
343 img_info
->Format
= get_d3dx10_dds_format(dds_params
.DxgiFormat
);
344 img_info
->MiscFlags
= 0;
345 if (dds_params
.Dimension
== WICDdsTextureCube
)
347 img_info
->MiscFlags
= D3D10_RESOURCE_MISC_TEXTURECUBE
;
348 img_info
->ArraySize
*= 6;
353 img_info
->ArraySize
= 1;
355 img_info
->MipLevels
= 1;
356 img_info
->ResourceDimension
= D3D10_RESOURCE_DIMENSION_TEXTURE2D
;
357 img_info
->Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
358 img_info
->MiscFlags
= 0;
363 IWICDdsDecoder_Release(dds_decoder
);
365 IWICBitmapFrameDecode_Release(frame
);
367 IWICBitmapDecoder_Release(decoder
);
369 IWICStream_Release(stream
);
371 IWICImagingFactory_Release(factory
);
375 WARN("Invalid or unsupported image file.\n");