From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 2 ++ dlls/d3dx9_36/d3dx_helpers.c | 36 ++++++++++++++-------------- dlls/d3dx9_36/d3dx_helpers.h | 17 ++++++++++++-- dlls/d3dx9_36/surface.c | 3 +-- dlls/d3dx9_36/util.c | 44 +++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/volume.c | 3 +-- 6 files changed, 80 insertions(+), 25 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 0ced5b35e1b..655529b004b 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -74,6 +74,8 @@ D3DXIMAGE_FILEFORMAT d3dximage_fileformat_from_d3dx_image_file_format(enum d3dx_ 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); +HRESULT d3dx9_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, + D3DXIMAGE_FILEFORMAT file_format, ID3DXBuffer **dst_buffer);
HRESULT lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLOCKED_RECT *lock, IDirect3DSurface9 **temp_surface, BOOL write); diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index a4a8e8b091f..76b64c188aa 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -727,17 +727,17 @@ static enum d3dx_pixel_format_id d3dx_get_closest_d3dx_pixel_format_id(const enu }
HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, - enum d3dx_image_file_format file_format, ID3DXBuffer **dst_buffer) + enum d3dx_image_file_format file_format, const struct d3dx_buffer_wrapper *wrapper, + struct d3dx_buffer *dst_buffer) { enum d3dx_pixel_format_id dst_format = src_fmt_desc->format; const struct pixel_format_desc *dst_fmt_desc; uint32_t dst_row_pitch, dst_slice_pitch; struct d3dx_pixels dst_pixels; uint8_t *pixels, *tmp_buf; - ID3DXBuffer *buffer; HRESULT hr;
- *dst_buffer = buffer = NULL; + memset(dst_buffer, 0, sizeof(*dst_buffer)); pixels = tmp_buf = NULL; switch (file_format) { @@ -812,18 +812,17 @@ HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct uint32_t header_size;
header_size = is_index_format(dst_fmt_desc) ? sizeof(*header) + DDS_PALETTE_SIZE : sizeof(*header); - hr = D3DXCreateBuffer((dst_slice_pitch * src_pixels->size.depth) + header_size, &buffer); + hr = wrapper->d3dx_buffer_create((dst_slice_pitch * src_pixels->size.depth) + header_size, dst_buffer); if (FAILED(hr)) return hr;
- header = ID3DXBuffer_GetBufferPointer(buffer); - pixels = (uint8_t *)ID3DXBuffer_GetBufferPointer(buffer) + header_size; + header = dst_buffer->buffer_data; + pixels = (uint8_t *)dst_buffer->buffer_data + header_size; 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)) - memcpy((uint8_t *)ID3DXBuffer_GetBufferPointer(buffer) + sizeof(*header), src_pixels->palette, - DDS_PALETTE_SIZE); + memcpy((uint8_t *)dst_buffer->buffer_data + sizeof(*header), src_pixels->palette, DDS_PALETTE_SIZE); break; }
@@ -831,12 +830,12 @@ HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct { struct tga_header *header;
- hr = D3DXCreateBuffer(dst_slice_pitch + sizeof(*header), &buffer); + hr = wrapper->d3dx_buffer_create(dst_slice_pitch + sizeof(*header), dst_buffer); if (FAILED(hr)) return hr;
- header = ID3DXBuffer_GetBufferPointer(buffer); - pixels = (uint8_t *)ID3DXBuffer_GetBufferPointer(buffer) + sizeof(*header); + header = dst_buffer->buffer_data; + pixels = (uint8_t *)dst_buffer->buffer_data + sizeof(*header);
memset(header, 0, sizeof(*header)); header->image_type = TGA_IMAGETYPE_TRUECOLOR; @@ -879,7 +878,7 @@ HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct }
/* WIC path, encode the image. */ - if (!buffer) + if (!dst_buffer->buffer_data) { IStream *wic_file = NULL; uint32_t buf_size = 0; @@ -887,33 +886,32 @@ HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct hr = d3dx_pixels_save_wic(&dst_pixels, dst_fmt_desc, file_format, &wic_file, &buf_size); if (FAILED(hr)) goto exit; - hr = D3DXCreateBuffer(buf_size, &buffer); + hr = wrapper->d3dx_buffer_create(buf_size, dst_buffer); if (FAILED(hr)) { IStream_Release(wic_file); goto exit; }
- hr = IStream_Read(wic_file, ID3DXBuffer_GetBufferPointer(buffer), buf_size, NULL); + hr = IStream_Read(wic_file, dst_buffer->buffer_data, buf_size, NULL); IStream_Release(wic_file); if (FAILED(hr)) goto exit; } } /* Return an empty buffer for size 0 images via WIC. */ - else if (!buffer) + else if (!dst_buffer->buffer_data) { FIXME("Returning empty buffer for size 0 image.\n"); - hr = D3DXCreateBuffer(64, &buffer); + hr = wrapper->d3dx_buffer_create(64, dst_buffer); if (FAILED(hr)) goto exit; }
- *dst_buffer = buffer; exit: free(tmp_buf); - if (*dst_buffer != buffer) - ID3DXBuffer_Release(buffer); + if (FAILED(hr)) + wrapper->d3dx_buffer_destroy(dst_buffer); return hr; }
diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index 16fb7cb2f67..0f440831259 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -359,8 +359,6 @@ uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint uint32_t depth, uint32_t mip_levels); 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, - enum d3dx_image_file_format file_format, ID3DXBuffer **dst_buffer); const char *debug_d3dx_image_file_format(enum d3dx_image_file_format format); HRESULT d3dx_pixels_init(const void *data, uint32_t row_pitch, uint32_t slice_pitch, const PALETTEENTRY *palette, enum d3dx_pixel_format_id format, uint32_t left, uint32_t top, uint32_t right, @@ -374,6 +372,21 @@ void get_aligned_rect(uint32_t left, uint32_t top, uint32_t right, uint32_t bott unsigned short float_32_to_16(const float in); float float_16_to_32(const unsigned short in);
+struct d3dx_buffer +{ + void *buffer_iface; + void *buffer_data; +}; + +struct d3dx_buffer_wrapper +{ + HRESULT (*d3dx_buffer_create)(unsigned int size, struct d3dx_buffer *d3dx_buffer); + void (*d3dx_buffer_destroy)(struct d3dx_buffer *d3dx_buffer); +}; + +HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, + enum d3dx_image_file_format file_format, const struct d3dx_buffer_wrapper *wrapper, struct d3dx_buffer *dst_buffer); + /* debug helpers */ const char *debug_d3dx_image_file_format(enum d3dx_image_file_format format); #endif /* __WINE_D3DX_HELPERS_H */ diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index d8f2fead91c..8734907b31f 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -859,8 +859,7 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE return hr; }
- hr = d3dx_save_pixels_to_memory(&src_pixels, src_fmt_desc, - d3dx_image_file_format_from_d3dximage_fileformat(file_format), &buffer); + hr = d3dx9_save_pixels_to_memory(&src_pixels, src_fmt_desc, file_format, &buffer); if (FAILED(hr)) { unlock_surface(src_surface, NULL, temp_surface, FALSE); diff --git a/dlls/d3dx9_36/util.c b/dlls/d3dx9_36/util.c index 2801a5ae669..8a9aade34f8 100644 --- a/dlls/d3dx9_36/util.c +++ b/dlls/d3dx9_36/util.c @@ -241,6 +241,50 @@ BOOL d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *ima return TRUE; }
+static void d3dx9_buffer_destroy(struct d3dx_buffer *d3dx_buffer) +{ + ID3DXBuffer *buffer_iface = (ID3DXBuffer *)d3dx_buffer->buffer_iface; + + if (buffer_iface) + ID3DXBuffer_Release(buffer_iface); + d3dx_buffer->buffer_iface = d3dx_buffer->buffer_data = NULL; +} + +static HRESULT d3dx9_buffer_create(unsigned int size, struct d3dx_buffer *buffer) +{ + ID3DXBuffer *buffer_iface; + HRESULT hr; + + hr = D3DXCreateBuffer(size, &buffer_iface); + if (FAILED(hr)) + return hr; + + buffer->buffer_iface = buffer_iface; + buffer->buffer_data = ID3DXBuffer_GetBufferPointer(buffer_iface); + return S_OK; +} + +static const struct d3dx_buffer_wrapper d3dx9_buffer_wrapper = +{ + d3dx9_buffer_create, + d3dx9_buffer_destroy, +}; + +HRESULT d3dx9_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, + D3DXIMAGE_FILEFORMAT file_format, ID3DXBuffer **dst_buffer) +{ + struct d3dx_buffer buffer; + HRESULT hr; + + *dst_buffer = NULL; + hr = d3dx_save_pixels_to_memory(src_pixels, src_fmt_desc, + d3dx_image_file_format_from_d3dximage_fileformat(file_format), &d3dx9_buffer_wrapper, &buffer); + if (SUCCEEDED(hr)) + *dst_buffer = (ID3DXBuffer *)buffer.buffer_iface; + + return hr; +} + /************************************************************ * map_view_of_file * diff --git a/dlls/d3dx9_36/volume.c b/dlls/d3dx9_36/volume.c index 1d01a3639b5..3c656697f47 100644 --- a/dlls/d3dx9_36/volume.c +++ b/dlls/d3dx9_36/volume.c @@ -356,8 +356,7 @@ HRESULT WINAPI D3DXSaveVolumeToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_ return hr; }
- hr = d3dx_save_pixels_to_memory(&src_pixels, src_fmt_desc, - d3dx_image_file_format_from_d3dximage_fileformat(file_format), &buffer); + hr = d3dx9_save_pixels_to_memory(&src_pixels, src_fmt_desc, file_format, &buffer); IDirect3DVolume9_UnlockBox(src_volume); if (SUCCEEDED(hr)) *dst_buffer = buffer;