Ziqing Hui : windowsccodecs: Implement DdsDecoder_Dds_GetParameters().
Alexandre Julliard
julliard at winehq.org
Wed May 13 16:29:53 CDT 2020
Module: wine
Branch: master
Commit: d622b134dd69f685caf06fcbe28c9f7d5dbde626
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d622b134dd69f685caf06fcbe28c9f7d5dbde626
Author: Ziqing Hui <zhui at codeweavers.com>
Date: Tue May 12 10:25:22 2020 +0800
windowsccodecs: Implement DdsDecoder_Dds_GetParameters().
Signed-off-by: Ziqing Hui <zhui at codeweavers.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/windowscodecs/ddsformat.c | 110 ++++++++++++++++++++++++++++++++++-
dlls/windowscodecs/tests/ddsformat.c | 5 --
2 files changed, 108 insertions(+), 7 deletions(-)
diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c
index f096f94b6a..de4cd1ea01 100644
--- a/dlls/windowscodecs/ddsformat.c
+++ b/dlls/windowscodecs/ddsformat.c
@@ -48,6 +48,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
#define DDPF_LUMINANCE 0x00020000
#define DDPF_BUMPDUDV 0x00080000
+#define DDSCAPS2_CUBEMAP 0x00000200
+#define DDSCAPS2_VOLUME 0x00200000
+
+#define DDS_DIMENSION_TEXTURE1D 2
+#define DDS_DIMENSION_TEXTURE2D 3
+#define DDS_DIMENSION_TEXTURE3D 4
+
+#define DDS_RESOURCE_MISC_TEXTURECUBE 0x00000004
+
typedef struct {
DWORD size;
DWORD flags;
@@ -107,6 +116,65 @@ static inline BOOL has_extended_header(DDS_HEADER *header)
(header->ddspf.fourCC == MAKEFOURCC('D', 'X', '1', '0'));
}
+static WICDdsDimension get_dimension(DDS_HEADER *header, DDS_HEADER_DXT10 *header_dxt10)
+{
+ if (header_dxt10) {
+ if (header_dxt10->miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE) return WICDdsTextureCube;
+ switch (header_dxt10->resourceDimension)
+ {
+ case DDS_DIMENSION_TEXTURE1D: return WICDdsTexture1D;
+ case DDS_DIMENSION_TEXTURE2D: return WICDdsTexture2D;
+ case DDS_DIMENSION_TEXTURE3D: return WICDdsTexture3D;
+ default: return WICDdsTexture2D;
+ }
+ } else {
+ if (header->caps2 & DDSCAPS2_CUBEMAP) {
+ return WICDdsTextureCube;
+ } else if (header->caps2 & DDSCAPS2_VOLUME) {
+ return WICDdsTexture3D;
+ } else {
+ return WICDdsTexture2D;
+ }
+ }
+}
+
+static DXGI_FORMAT get_format_from_fourcc(DWORD fourcc)
+{
+ switch (fourcc)
+ {
+ case MAKEFOURCC('D', 'X', 'T', '1'):
+ return DXGI_FORMAT_BC1_UNORM;
+ case MAKEFOURCC('D', 'X', 'T', '2'):
+ case MAKEFOURCC('D', 'X', 'T', '3'):
+ return DXGI_FORMAT_BC2_UNORM;
+ case MAKEFOURCC('D', 'X', 'T', '4'):
+ case MAKEFOURCC('D', 'X', 'T', '5'):
+ return DXGI_FORMAT_BC3_UNORM;
+ case MAKEFOURCC('D', 'X', '1', '0'):
+ /* format is indicated in extended header */
+ return DXGI_FORMAT_UNKNOWN;
+ default:
+ /* there are DDS files where fourCC is set directly to DXGI_FORMAT enumeration value */
+ return fourcc;
+ }
+}
+
+static WICDdsAlphaMode get_alpha_mode_from_fourcc(DWORD fourcc)
+{
+ switch (fourcc)
+ {
+ case MAKEFOURCC('D', 'X', 'T', '1'):
+ case MAKEFOURCC('D', 'X', 'T', '2'):
+ case MAKEFOURCC('D', 'X', 'T', '4'):
+ return WICDdsAlphaModePremultiplied;
+ case MAKEFOURCC('D', 'X', 'T', '3'):
+ case MAKEFOURCC('D', 'X', 'T', '5'):
+ return WICDdsAlphaModeStraight;
+ default:
+ return WICDdsAlphaModeUnknown;
+ }
+}
+
static inline DdsDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
{
return CONTAINING_RECORD(iface, DdsDecoder, IWICBitmapDecoder_iface);
@@ -587,9 +655,47 @@ static ULONG WINAPI DdsDecoder_Dds_Release(IWICDdsDecoder *iface)
static HRESULT WINAPI DdsDecoder_Dds_GetParameters(IWICDdsDecoder *iface,
WICDdsParameters *parameters)
{
- TRACE("(%p,%p): Stub.\n", iface, parameters);
+ DdsDecoder *This = impl_from_IWICDdsDecoder(iface);
+ HRESULT hr;
- return E_NOTIMPL;
+ if (!parameters) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->lock);
+
+ if (!This->initialized) {
+ hr = WINCODEC_ERR_WRONGSTATE;
+ goto end;
+ }
+
+ parameters->Width = This->header.width;
+ parameters->Height = This->header.height;
+ parameters->Depth = 1;
+ parameters->MipLevels = 1;
+ parameters->ArraySize = 1;
+ if (This->header.depth) parameters->Depth = This->header.depth;
+ if (This->header.mipMapCount) parameters->MipLevels = This->header.mipMapCount;
+
+ if (has_extended_header(&This->header)) {
+ if (This->header_dxt10.arraySize) parameters->ArraySize = This->header_dxt10.arraySize;
+ parameters->DxgiFormat = This->header_dxt10.dxgiFormat;
+ parameters->Dimension = get_dimension(NULL, &This->header_dxt10);
+ parameters->AlphaMode = This->header_dxt10.miscFlags2 & 0x00000008;
+ } else {
+ parameters->DxgiFormat = get_format_from_fourcc(This->header.ddspf.fourCC);
+ parameters->Dimension = get_dimension(&This->header, NULL);
+ parameters->AlphaMode = get_alpha_mode_from_fourcc(This->header.ddspf.fourCC);
+ }
+
+ TRACE("(%p) -> (%dx%d depth=%d mipLevels=%d arraySize=%d dxgiFormat=0x%x dimension=0x%x alphaMode=0x%x)\n",
+ iface, parameters->Width, parameters->Height, parameters->Depth, parameters->MipLevels,
+ parameters->ArraySize, parameters->DxgiFormat, parameters->Dimension, parameters->AlphaMode);
+
+ hr = S_OK;
+
+end:
+ LeaveCriticalSection(&This->lock);
+
+ return hr;
}
static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *iface,
diff --git a/dlls/windowscodecs/tests/ddsformat.c b/dlls/windowscodecs/tests/ddsformat.c
index f0814b46ef..209d39f11f 100644
--- a/dlls/windowscodecs/tests/ddsformat.c
+++ b/dlls/windowscodecs/tests/ddsformat.c
@@ -320,12 +320,10 @@ static void test_dds_decoder_image_parameters(void)
hr = IWICBitmapDecoder_GetFrameCount(decoder, NULL);
ok (hr == E_INVALIDARG, "%d: Expected hr=E_INVALIDARG, got %x\n", i, hr);
- todo_wine {
hr = IWICDdsDecoder_GetParameters(dds_decoder, ¶meters);
ok(hr == WINCODEC_ERR_WRONGSTATE, "%d: Expected hr=WINCODEC_ERR_WRONGSTATE, got %x\n", i, hr);
hr = IWICDdsDecoder_GetParameters(dds_decoder, NULL);
ok(hr == E_INVALIDARG, "%d: Expected hr=E_INVALIDARG, got %x\n", i, hr);
- };
hr = init_decoder(decoder, stream, S_OK, -1);
if (hr != S_OK) goto next;
@@ -339,8 +337,6 @@ static void test_dds_decoder_image_parameters(void)
hr = IWICBitmapDecoder_GetFrameCount(decoder, NULL);
ok (hr == E_INVALIDARG, "%d: Expected hr=S_OK, got %x\n", i, hr);
-
- todo_wine {
hr = IWICDdsDecoder_GetParameters(dds_decoder, ¶meters);
ok (hr == S_OK, "%d: GetParameters failed, hr=%x\n", i, hr);
if (hr == S_OK) {
@@ -363,7 +359,6 @@ static void test_dds_decoder_image_parameters(void)
}
hr = IWICDdsDecoder_GetParameters(dds_decoder, NULL);
ok (hr == E_INVALIDARG, "%d: Expected hr=E_INVALIDARG, got %x\n", i, hr);
- };
next:
if (decoder) IWICBitmapDecoder_Release(decoder);
More information about the wine-cvs
mailing list