Module: wine Branch: master Commit: ab0d2b1434d8f81e1f291cc10115e5cef7f1d3b6 URL: https://source.winehq.org/git/wine.git/?a=commit;h=ab0d2b1434d8f81e1f291cc10...
Author: Ziqing Hui zhui@codeweavers.com Date: Thu May 28 13:08:39 2020 +0800
windowscodecs: Get DDS parameters when initialize.
Signed-off-by: Ziqing Hui zhui@codeweavers.com Signed-off-by: Esme Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/windowscodecs/ddsformat.c | 100 ++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 36 deletions(-)
diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c index de4cd1ea01..7341147245 100644 --- a/dlls/windowscodecs/ddsformat.c +++ b/dlls/windowscodecs/ddsformat.c @@ -93,6 +93,18 @@ typedef struct { DWORD miscFlags2; } DDS_HEADER_DXT10;
+typedef struct dds_info { + UINT width; + UINT height; + UINT depth; + UINT mip_levels; + UINT array_size; + UINT frame_count; + DXGI_FORMAT format; + WICDdsDimension dimension; + WICDdsAlphaMode alpha_mode; +} dds_info; + typedef struct DdsDecoder { IWICBitmapDecoder IWICBitmapDecoder_iface; IWICDdsDecoder IWICDdsDecoder_iface; @@ -102,6 +114,7 @@ typedef struct DdsDecoder { CRITICAL_SECTION lock; DDS_HEADER header; DDS_HEADER_DXT10 header_dxt10; + dds_info info; } DdsDecoder;
typedef struct DdsFrameDecode { @@ -175,6 +188,45 @@ static WICDdsAlphaMode get_alpha_mode_from_fourcc(DWORD fourcc) } }
+static void get_dds_info(dds_info* info, DDS_HEADER *header, DDS_HEADER_DXT10 *header_dxt10) +{ + int i; + UINT depth; + + info->width = header->width; + info->height = header->height; + info->depth = 1; + info->mip_levels = 1; + info->array_size = 1; + if (header->depth) info->depth = header->depth; + if (header->mipMapCount) info->mip_levels = header->mipMapCount; + + if (has_extended_header(header)) { + if (header_dxt10->arraySize) info->array_size = header_dxt10->arraySize; + info->format = header_dxt10->dxgiFormat; + info->dimension = get_dimension(NULL, header_dxt10); + info->alpha_mode = header_dxt10->miscFlags2 & 0x00000008; + } else { + info->format = get_format_from_fourcc(header->ddspf.fourCC); + info->dimension = get_dimension(header, NULL); + info->alpha_mode = get_alpha_mode_from_fourcc(header->ddspf.fourCC); + } + + /* get frame count */ + if (info->depth == 1) { + info->frame_count = info->array_size * info->mip_levels; + } else { + info->frame_count = 0; + depth = info->depth; + for (i = 0; i < info->mip_levels; i++) + { + info->frame_count += depth; + if (depth > 1) depth /= 2; + } + info->frame_count *= info->array_size; + } +} + static inline DdsDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) { return CONTAINING_RECORD(iface, DdsDecoder, IWICBitmapDecoder_iface); @@ -497,6 +549,8 @@ static HRESULT WINAPI DdsDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p } }
+ get_dds_info(&This->info, &This->header, &This->header_dxt10); + This->initialized = TRUE; This->stream = pIStream; IStream_AddRef(pIStream); @@ -571,33 +625,17 @@ static HRESULT WINAPI DdsDecoder_GetFrameCount(IWICBitmapDecoder *iface, UINT *pCount) { DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); - UINT arraySize = 1, mipMapCount = 1, depth = 1; - int i;
if (!pCount) return E_INVALIDARG; if (!This->initialized) return WINCODEC_ERR_WRONGSTATE;
EnterCriticalSection(&This->lock);
- if (This->header.mipMapCount) mipMapCount = This->header.mipMapCount; - if (This->header.depth) depth = This->header.depth; - if (has_extended_header(&This->header) && This->header_dxt10.arraySize) arraySize = This->header_dxt10.arraySize; - - if (depth == 1) { - *pCount = arraySize * mipMapCount; - } else { - *pCount = 0; - for (i = 0; i < mipMapCount; i++) - { - *pCount += depth; - if (depth > 1) depth /= 2; - } - *pCount *= arraySize; - } + *pCount = This->info.frame_count;
LeaveCriticalSection(&This->lock);
- TRACE("(%p) <-- %d\n", iface, *pCount); + TRACE("(%p) -> %d\n", iface, *pCount);
return S_OK; } @@ -667,24 +705,14 @@ static HRESULT WINAPI DdsDecoder_Dds_GetParameters(IWICDdsDecoder *iface, 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); - } + parameters->Width = This->info.width; + parameters->Height = This->info.height; + parameters->Depth = This->info.depth; + parameters->MipLevels = This->info.mip_levels; + parameters->ArraySize = This->info.array_size; + parameters->DxgiFormat = This->info.format; + parameters->Dimension = This->info.dimension; + parameters->AlphaMode = This->info.alpha_mode;
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,