windowscodecs: Add support for extended DDS header.

Signed-off-by: Ziqing Hui <zhui@codeweavers.com>
Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Ziqing Hui 2020-04-22 16:38:07 +08:00 committed by Alexandre Julliard
parent 3d247caab5
commit 2e7056b4ac
1 changed files with 32 additions and 0 deletions

View File

@ -34,6 +34,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
#define DDS_MAGIC 0x20534444 #define DDS_MAGIC 0x20534444
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
#endif
#define DDPF_ALPHAPIXELS 0x00000001
#define DDPF_ALPHA 0x00000002
#define DDPF_FOURCC 0x00000004
#define DDPF_PALETTEINDEXED8 0x00000020
#define DDPF_RGB 0x00000040
#define DDPF_LUMINANCE 0x00020000
#define DDPF_BUMPDUDV 0x00080000
typedef struct { typedef struct {
DWORD size; DWORD size;
@ -63,6 +76,14 @@ typedef struct {
DWORD reserved2; DWORD reserved2;
} DDS_HEADER; } DDS_HEADER;
typedef struct {
DWORD dxgiFormat;
DWORD resourceDimension;
DWORD miscFlag;
DWORD arraySize;
DWORD miscFlags2;
} DDS_HEADER_DXT10;
typedef struct DdsDecoder { typedef struct DdsDecoder {
IWICBitmapDecoder IWICBitmapDecoder_iface; IWICBitmapDecoder IWICBitmapDecoder_iface;
LONG ref; LONG ref;
@ -70,6 +91,7 @@ typedef struct DdsDecoder {
IStream *stream; IStream *stream;
CRITICAL_SECTION lock; CRITICAL_SECTION lock;
DDS_HEADER header; DDS_HEADER header;
DDS_HEADER_DXT10 header_dxt10;
} DdsDecoder; } DdsDecoder;
static inline DdsDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) static inline DdsDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
@ -180,6 +202,16 @@ static HRESULT WINAPI DdsDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
goto end; goto end;
} }
if (This->header.ddspf.flags & DDPF_FOURCC &&
This->header.ddspf.fourCC == MAKEFOURCC('D', 'X', '1', '0')) {
hr = IStream_Read(pIStream, &This->header_dxt10, sizeof(This->header_dxt10), &bytesread);
if (FAILED(hr)) goto end;
if (bytesread != sizeof(This->header_dxt10)) {
hr = WINCODEC_ERR_STREAMREAD;
goto end;
}
}
This->initialized = TRUE; This->initialized = TRUE;
This->stream = pIStream; This->stream = pIStream;
IStream_AddRef(pIStream); IStream_AddRef(pIStream);