From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 15 ++++++-- dlls/d3dx9_36/surface.c | 61 +++++++++--------------------- dlls/d3dx9_36/texture.c | 23 +++++++++--- dlls/d3dx9_36/util.c | 71 +++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/volume.c | 7 +++- 5 files changed, 125 insertions(+), 52 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index c8f72562953..b8c5b2518e5 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -164,6 +164,14 @@ static inline void set_volume_struct(struct volume *volume, uint32_t width, uint volume->depth = depth; }
+enum d3dx_resource_type +{ + D3DX_RESOURCE_TYPE_TEXTURE_2D, + D3DX_RESOURCE_TYPE_TEXTURE_3D, + D3DX_RESOURCE_TYPE_CUBE_TEXTURE, + D3DX_RESOURCE_TYPE_COUNT, +}; + /* These values act as indexes into the pixel_format_desc table. */ enum d3dx_pixel_format_id { @@ -276,7 +284,7 @@ static inline void set_d3dx_pixels(struct d3dx_pixels *pixels, const void *data, #define D3DX_IMAGE_INFO_ONLY 1 struct d3dx_image { - D3DRESOURCETYPE resource_type; + enum d3dx_resource_type resource_type; enum d3dx_pixel_format_id format;
struct volume size; @@ -303,7 +311,7 @@ HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3d void d3dx_image_cleanup(struct d3dx_image *image); HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t layer, uint32_t mip_level, struct d3dx_pixels *pixels); -void d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image); +BOOL d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image);
struct d3dx_include_from_file { @@ -369,6 +377,7 @@ HRESULT write_buffer_to_file(const WCHAR *filename, ID3DXBuffer *buffer);
D3DFORMAT d3dformat_from_d3dx_pixel_format_id(enum d3dx_pixel_format_id format); enum d3dx_pixel_format_id d3dx_pixel_format_id_from_d3dformat(D3DFORMAT format); +enum d3dx_resource_type d3dx_resource_type_from_d3dresourcetype(D3DRESOURCETYPE type); const struct pixel_format_desc *get_d3dx_pixel_format_info(enum d3dx_pixel_format_id format); const struct pixel_format_desc *get_format_info(D3DFORMAT format); const struct pixel_format_desc *get_format_info_idx(int idx); @@ -383,7 +392,7 @@ HRESULT unlock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, IDirect3DSurface9 *temp_surface, BOOL update); uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height, uint32_t depth, uint32_t mip_levels); -HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE resource_type, +HRESULT d3dx_init_dds_header(struct dds_header *header, enum d3dx_resource_type resource_type, enum d3dx_pixel_format_id format, const struct volume *size, uint32_t mip_levels); HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, D3DXIMAGE_FILEFORMAT file_format, ID3DXBuffer **dst_buffer); diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index ebcd3ffc69d..ddfc2c6e581 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -423,7 +423,7 @@ uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint return layer_size; }
-HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE resource_type, +HRESULT d3dx_init_dds_header(struct dds_header *header, enum d3dx_resource_type resource_type, enum d3dx_pixel_format_id format, const struct volume *size, uint32_t mip_levels) { HRESULT hr; @@ -454,7 +454,7 @@ HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE resource header->miplevels = mip_levels; }
- if (resource_type == D3DRTYPE_CUBETEXTURE) + if (resource_type == D3DX_RESOURCE_TYPE_CUBE_TEXTURE) { header->caps |= DDS_CAPS_COMPLEX; header->caps2 |= (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES); @@ -846,7 +846,7 @@ HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct
header = ID3DXBuffer_GetBufferPointer(buffer); pixels = (uint8_t *)ID3DXBuffer_GetBufferPointer(buffer) + header_size; - hr = d3dx_init_dds_header(header, D3DRTYPE_TEXTURE, dst_format, &src_pixels->size, 1); + hr = d3dx_init_dds_header(header, D3DX_RESOURCE_TYPE_TEXTURE_2D, dst_format, &src_pixels->size, 1); if (FAILED(hr)) goto exit; if (is_index_format(dst_fmt_desc)) @@ -1026,7 +1026,7 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src if (header->flags & DDS_DEPTH) { image->size.depth = max(header->depth, 1); - image->resource_type = D3DRTYPE_VOLUMETEXTURE; + image->resource_type = D3DX_RESOURCE_TYPE_TEXTURE_3D; } else if (header->caps2 & DDS_CAPS2_CUBEMAP) { @@ -1037,10 +1037,12 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src }
image->layer_count = 6; - image->resource_type = D3DRTYPE_CUBETEXTURE; + image->resource_type = D3DX_RESOURCE_TYPE_CUBE_TEXTURE; } else - image->resource_type = D3DRTYPE_TEXTURE; + { + image->resource_type = D3DX_RESOURCE_TYPE_TEXTURE_2D; + }
image->layer_pitch = d3dx_calculate_layer_pixels_size(image->format, image->size.width, image->size.height, image->size.depth, image->mip_levels); @@ -1366,7 +1368,7 @@ static HRESULT d3dx_initialize_image_from_wic(const void *src_data, uint32_t src image->size.depth = 1; image->mip_levels = 1; image->layer_count = 1; - image->resource_type = D3DRTYPE_TEXTURE; + image->resource_type = D3DX_RESOURCE_TYPE_TEXTURE_2D;
exit: if (bitmap_frame) @@ -1607,7 +1609,7 @@ static HRESULT d3dx_initialize_image_from_tga(const void *src_data, uint32_t src set_volume_struct(&image->size, header->width, header->height, 1); image->mip_levels = 1; image->layer_count = 1; - image->resource_type = D3DRTYPE_TEXTURE; + image->resource_type = D3DX_RESOURCE_TYPE_TEXTURE_2D; image->image_file_format = D3DXIFF_TGA;
if (!(flags & D3DX_IMAGE_INFO_ONLY)) @@ -1725,39 +1727,6 @@ HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t layer, uint32_t return D3D_OK; }
-void d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image) -{ - info->ImageFileFormat = image->image_file_format; - info->Width = image->size.width; - info->Height = image->size.height; - info->Depth = image->size.depth; - info->MipLevels = image->mip_levels; - switch (image->format) - { - case D3DX_PIXEL_FORMAT_P1_UINT: - case D3DX_PIXEL_FORMAT_P2_UINT: - case D3DX_PIXEL_FORMAT_P4_UINT: - info->Format = D3DFMT_P8; - break; - - case D3DX_PIXEL_FORMAT_R16G16B16_UNORM: - info->Format = D3DFMT_A16B16G16R16; - break; - - case D3DX_PIXEL_FORMAT_B8G8R8_UNORM: - if (info->ImageFileFormat == D3DXIFF_PNG || info->ImageFileFormat == D3DXIFF_JPG) - info->Format = D3DFMT_X8R8G8B8; - else - info->Format = d3dformat_from_d3dx_pixel_format_id(image->format); - break; - - default: - info->Format = d3dformat_from_d3dx_pixel_format_id(image->format); - break; - } - info->ResourceType = image->resource_type; -} - /************************************************************ * D3DXGetImageInfoFromFileInMemory * @@ -1798,7 +1767,8 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(const void *data, UINT datasize, return D3DXERR_INVALIDDATA; }
- d3dximage_info_from_d3dx_image(info, &image); + if (!d3dximage_info_from_d3dx_image(info, &image)) + return D3DXERR_INVALIDDATA; return D3D_OK; }
@@ -2015,7 +1985,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, if (FAILED(hr)) return D3DXERR_INVALIDDATA;
- d3dximage_info_from_d3dx_image(&img_info, &image); + if (!d3dximage_info_from_d3dx_image(&img_info, &image)) + { + hr = D3DXERR_INVALIDDATA; + goto exit; + } + if (pSrcRect) src_rect = *pSrcRect; else diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 9464cae6fa2..02bfbca2cc6 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -612,7 +612,11 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi return hr; }
- d3dximage_info_from_d3dx_image(&imginfo, &image); + if (!d3dximage_info_from_d3dx_image(&imginfo, &image)) + { + hr = D3DXERR_INVALIDDATA; + goto err; + }
/* handle default values */ if (!width || width == D3DX_DEFAULT_NONPOW2 || width == D3DX_FROM_FILE || width == D3DX_DEFAULT) @@ -1142,7 +1146,11 @@ HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic return hr; }
- d3dximage_info_from_d3dx_image(&image_info, &image); + if (!d3dximage_info_from_d3dx_image(&image_info, &image)) + { + hr = D3DXERR_INVALIDDATA; + goto err; + }
/* Handle default values. */ if (!width || width == D3DX_DEFAULT_NONPOW2 || width == D3DX_FROM_FILE || width == D3DX_DEFAULT) @@ -1374,7 +1382,12 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, return hr; }
- d3dximage_info_from_d3dx_image(&img_info, &image); + if (!d3dximage_info_from_d3dx_image(&img_info, &image)) + { + hr = D3DXERR_INVALIDDATA; + goto err; + } + if (img_info.ResourceType != D3DRTYPE_CUBETEXTURE) { hr = E_FAIL; @@ -1974,8 +1987,8 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE if (FAILED(hr)) return hr;
- hr = d3dx_init_dds_header((struct dds_header *)ID3DXBuffer_GetBufferPointer(buffer), type, fmt_desc->format, &size, - levels); + hr = d3dx_init_dds_header((struct dds_header *)ID3DXBuffer_GetBufferPointer(buffer), + d3dx_resource_type_from_d3dresourcetype(type), fmt_desc->format, &size, levels); if (FAILED(hr)) goto exit;
diff --git a/dlls/d3dx9_36/util.c b/dlls/d3dx9_36/util.c index c41a8eb7647..261d1eb02a4 100644 --- a/dlls/d3dx9_36/util.c +++ b/dlls/d3dx9_36/util.c @@ -192,6 +192,77 @@ enum d3dx_pixel_format_id d3dx_pixel_format_id_from_d3dformat(D3DFORMAT format) } }
+enum d3dx_resource_type d3dx_resource_type_from_d3dresourcetype(D3DRESOURCETYPE type) +{ + switch (type) + { + case D3DRTYPE_TEXTURE: return D3DX_RESOURCE_TYPE_TEXTURE_2D; + case D3DRTYPE_VOLUMETEXTURE: return D3DX_RESOURCE_TYPE_TEXTURE_3D; + case D3DRTYPE_CUBETEXTURE: return D3DX_RESOURCE_TYPE_CUBE_TEXTURE; + default: + FIXME("No d3dx_resource_type for D3DRESOURCETYPE %d.\n", type); + return D3DX_RESOURCE_TYPE_COUNT; + } +} + +static D3DRESOURCETYPE d3dresourcetype_from_d3dx_resource_type(enum d3dx_resource_type type) +{ + switch (type) + { + case D3DX_RESOURCE_TYPE_TEXTURE_2D: return D3DRTYPE_TEXTURE; + case D3DX_RESOURCE_TYPE_TEXTURE_3D: return D3DRTYPE_VOLUMETEXTURE; + case D3DX_RESOURCE_TYPE_CUBE_TEXTURE: return D3DRTYPE_CUBETEXTURE; + default: + FIXME("No D3DRESOURCETYPE for d3dx_resource_type %d.\n", type); + return D3DRTYPE_FORCE_DWORD; + } +} + +BOOL d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image) +{ + D3DRESOURCETYPE rtype = d3dresourcetype_from_d3dx_resource_type(image->resource_type); + + if (rtype == D3DRTYPE_FORCE_DWORD) + return FALSE; + + switch (image->format) + { + case D3DX_PIXEL_FORMAT_P1_UINT: + case D3DX_PIXEL_FORMAT_P2_UINT: + case D3DX_PIXEL_FORMAT_P4_UINT: + info->Format = D3DFMT_P8; + break; + + case D3DX_PIXEL_FORMAT_R16G16B16_UNORM: + info->Format = D3DFMT_A16B16G16R16; + break; + + case D3DX_PIXEL_FORMAT_B8G8R8_UNORM: + if (image->image_file_format == D3DXIFF_PNG || image->image_file_format == D3DXIFF_JPG) + info->Format = D3DFMT_X8R8G8B8; + else + info->Format = d3dformat_from_d3dx_pixel_format_id(image->format); + break; + + default: + { + D3DFORMAT fmt = d3dformat_from_d3dx_pixel_format_id(image->format); + + if (fmt == D3DFMT_UNKNOWN) + return FALSE; + info->Format = fmt; + break; + } + } + info->ImageFileFormat = image->image_file_format; + info->Width = image->size.width; + info->Height = image->size.height; + info->Depth = image->size.depth; + info->MipLevels = image->mip_levels; + info->ResourceType = rtype; + return TRUE; +} + /************************************************************ * map_view_of_file * diff --git a/dlls/d3dx9_36/volume.c b/dlls/d3dx9_36/volume.c index 546959b017e..4389cf77e9e 100644 --- a/dlls/d3dx9_36/volume.c +++ b/dlls/d3dx9_36/volume.c @@ -201,7 +201,12 @@ HRESULT WINAPI D3DXLoadVolumeFromFileInMemory(IDirect3DVolume9 *dst_volume, cons if (FAILED(hr)) return D3DXERR_INVALIDDATA;
- d3dximage_info_from_d3dx_image(&image_info, &image); + if (!d3dximage_info_from_d3dx_image(&image_info, &image)) + { + hr = D3DXERR_INVALIDDATA; + goto exit; + } + if (src_box) { if (src_box->Right > image_info.Width