windowscodecs: Initialize block data in DdsDecoder_Dds_GetFrame().
Signed-off-by: Ziqing Hui <zhui@codeweavers.com> Signed-off-by: Esme Povirk <vincent@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bf454cc394
commit
a805c1f198
|
@ -57,6 +57,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||||
|
|
||||||
#define DDS_RESOURCE_MISC_TEXTURECUBE 0x00000004
|
#define DDS_RESOURCE_MISC_TEXTURECUBE 0x00000004
|
||||||
|
|
||||||
|
#define DDS_BLOCK_WIDTH 4
|
||||||
|
#define DDS_BLOCK_HEIGHT 4
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DWORD size;
|
DWORD size;
|
||||||
DWORD flags;
|
DWORD flags;
|
||||||
|
@ -132,6 +135,7 @@ typedef struct DdsFrameDecode {
|
||||||
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
|
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
|
||||||
IWICDdsFrameDecode IWICDdsFrameDecode_iface;
|
IWICDdsFrameDecode IWICDdsFrameDecode_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
BYTE *data;
|
||||||
dds_frame_info info;
|
dds_frame_info info;
|
||||||
} DdsFrameDecode;
|
} DdsFrameDecode;
|
||||||
|
|
||||||
|
@ -322,7 +326,10 @@ static ULONG WINAPI DdsFrameDecode_Release(IWICBitmapFrameDecode *iface)
|
||||||
|
|
||||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||||
|
|
||||||
if (ref == 0) HeapFree(GetProcessHeap(), 0, This);
|
if (ref == 0) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->data);
|
||||||
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
|
}
|
||||||
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
@ -811,9 +818,11 @@ static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *iface,
|
||||||
{
|
{
|
||||||
DdsDecoder *This = impl_from_IWICDdsDecoder(iface);
|
DdsDecoder *This = impl_from_IWICDdsDecoder(iface);
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
UINT width = 0, height = 0;
|
LARGE_INTEGER seek;
|
||||||
int j;
|
UINT width, height, depth, width_in_blocks, height_in_blocks, size;
|
||||||
DdsFrameDecode *frame_decode;
|
UINT frame_width = 0, frame_height = 0, frame_width_in_blocks = 0, frame_height_in_blocks = 0, frame_size = 0;
|
||||||
|
UINT bytes_per_block, bytesread, i;
|
||||||
|
DdsFrameDecode *frame_decode = NULL;
|
||||||
|
|
||||||
TRACE("(%p,%u,%u,%u,%p)\n", iface, arrayIndex, mipLevel, sliceIndex, bitmapFrame);
|
TRACE("(%p,%u,%u,%u,%p)\n", iface, arrayIndex, mipLevel, sliceIndex, bitmapFrame);
|
||||||
|
|
||||||
|
@ -825,31 +834,60 @@ static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *iface,
|
||||||
hr = WINCODEC_ERR_WRONGSTATE;
|
hr = WINCODEC_ERR_WRONGSTATE;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrayIndex >= This->info.array_size || mipLevel >= This->info.mip_levels || sliceIndex >= This->info.depth) {
|
if (arrayIndex >= This->info.array_size || mipLevel >= This->info.mip_levels || sliceIndex >= This->info.depth) {
|
||||||
hr = E_INVALIDARG;
|
hr = E_INVALIDARG;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bytes_per_block = get_bytes_per_block(This->info.format);
|
||||||
|
seek.QuadPart = sizeof(DWORD) + sizeof(DDS_HEADER);
|
||||||
|
if (has_extended_header(&This->header)) seek.QuadPart += sizeof(DDS_HEADER_DXT10);
|
||||||
|
|
||||||
width = This->info.width;
|
width = This->info.width;
|
||||||
height = This->info.height;
|
height = This->info.height;
|
||||||
for (j = 0; j < mipLevel; j++)
|
depth = This->info.depth;
|
||||||
|
for (i = 0; i < This->info.mip_levels; i++)
|
||||||
{
|
{
|
||||||
|
width_in_blocks = (width + DDS_BLOCK_WIDTH - 1) / DDS_BLOCK_WIDTH;
|
||||||
|
height_in_blocks = (height + DDS_BLOCK_HEIGHT - 1) / DDS_BLOCK_HEIGHT;
|
||||||
|
size = width_in_blocks * height_in_blocks * bytes_per_block;
|
||||||
|
|
||||||
|
if (i < mipLevel) {
|
||||||
|
seek.QuadPart += size * depth;
|
||||||
|
} else if (i == mipLevel){
|
||||||
|
seek.QuadPart += size * sliceIndex;
|
||||||
|
frame_width = width;
|
||||||
|
frame_height = height;
|
||||||
|
frame_width_in_blocks = width_in_blocks;
|
||||||
|
frame_height_in_blocks = height_in_blocks;
|
||||||
|
frame_size = frame_width_in_blocks * frame_height_in_blocks * bytes_per_block;
|
||||||
|
if (arrayIndex == 0) break;
|
||||||
|
}
|
||||||
|
seek.QuadPart += arrayIndex * size * depth;
|
||||||
|
|
||||||
if (width > 1) width /= 2;
|
if (width > 1) width /= 2;
|
||||||
if (height > 1) height /= 2;
|
if (height > 1) height /= 2;
|
||||||
|
if (depth > 1) depth /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = DdsFrameDecode_CreateInstance(&frame_decode);
|
hr = DdsFrameDecode_CreateInstance(&frame_decode);
|
||||||
if (hr != S_OK) goto end;
|
if (hr != S_OK) goto end;
|
||||||
|
frame_decode->info.width = frame_width;
|
||||||
frame_decode->info.width = width;
|
frame_decode->info.height = frame_height;
|
||||||
frame_decode->info.height = height;
|
|
||||||
frame_decode->info.format = This->info.format;
|
frame_decode->info.format = This->info.format;
|
||||||
frame_decode->info.bytes_per_block = get_bytes_per_block(This->info.format);
|
frame_decode->info.bytes_per_block = bytes_per_block;
|
||||||
frame_decode->info.block_width = 4;
|
frame_decode->info.block_width = DDS_BLOCK_WIDTH;
|
||||||
frame_decode->info.block_height = 4;
|
frame_decode->info.block_height = DDS_BLOCK_HEIGHT;
|
||||||
frame_decode->info.width_in_blocks = (width + frame_decode->info.block_width - 1) / frame_decode->info.block_width;
|
frame_decode->info.width_in_blocks = frame_width_in_blocks;
|
||||||
frame_decode->info.height_in_blocks = (width + frame_decode->info.block_height - 1) / frame_decode->info.block_height;
|
frame_decode->info.height_in_blocks = frame_height_in_blocks;
|
||||||
|
frame_decode->data = HeapAlloc(GetProcessHeap(), 0, frame_size);
|
||||||
|
hr = IStream_Seek(This->stream, seek, SEEK_SET, NULL);
|
||||||
|
if (hr != S_OK) goto end;
|
||||||
|
hr = IStream_Read(This->stream, frame_decode->data, frame_size, &bytesread);
|
||||||
|
if (hr != S_OK || bytesread != frame_size) {
|
||||||
|
hr = WINCODEC_ERR_STREAMREAD;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
*bitmapFrame = &frame_decode->IWICBitmapFrameDecode_iface;
|
*bitmapFrame = &frame_decode->IWICBitmapFrameDecode_iface;
|
||||||
|
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
|
@ -857,6 +895,8 @@ static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *iface,
|
||||||
end:
|
end:
|
||||||
LeaveCriticalSection(&This->lock);
|
LeaveCriticalSection(&This->lock);
|
||||||
|
|
||||||
|
if (hr != S_OK && frame_decode) DdsFrameDecode_Release(&frame_decode->IWICBitmapFrameDecode_iface);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue