[3/5] d3dx9: Implement the support for saving a surface to a DDS file.
Józef Kucia
joseph.kucia at gmail.com
Mon Sep 24 06:46:38 CDT 2012
---
dlls/d3dx9_36/surface.c | 93 +++++++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/tests/surface.c | 3 +-
2 files changed, 95 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 3bf8cb1..770a2e5 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -275,6 +275,27 @@ static D3DFORMAT dds_pixel_format_to_d3dformat(const struct dds_pixel_format *pi
return D3DFMT_UNKNOWN;
}
+static HRESULT d3dformat_to_dds_pixel_format(struct dds_pixel_format *pixel_format, D3DFORMAT d3dformat)
+{
+ memset(pixel_format, 0, sizeof(*pixel_format));
+
+ pixel_format->size = sizeof(*pixel_format);
+
+ if (d3dformat == D3DFMT_R8G8B8)
+ {
+ pixel_format->flags = DDS_PF_RGB;
+ pixel_format->bpp = 24;
+ pixel_format->rmask = 0xff0000;
+ pixel_format->gmask = 0x00ff00;
+ pixel_format->bmask = 0x0000ff;
+ pixel_format->amask = 0x000000;
+ return D3D_OK;
+ }
+
+ WARN("Unknown pixel format %#x\n", d3dformat);
+ return E_NOTIMPL;
+}
+
static HRESULT calculate_dds_surface_size(D3DFORMAT format, UINT width, UINT height,
UINT *pitch, UINT *size)
{
@@ -410,6 +431,77 @@ static HRESULT load_surface_from_dds(IDirect3DSurface9 *dst_surface, const PALET
src_pitch, NULL, src_rect, filter, color_key);
}
+static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSurface9 *src_surface, const RECT *src_rect)
+{
+ HRESULT hr;
+ UINT dst_pitch, surface_size, file_size;
+ D3DSURFACE_DESC src_desc;
+ D3DLOCKED_RECT locked_rect;
+ ID3DXBuffer *buffer;
+ struct dds_header *header;
+ BYTE *pixels;
+ struct volume volume;
+ const struct pixel_format_desc *pixel_format;
+
+ if (src_rect)
+ {
+ FIXME("Saving a part of a surface to a DDS file is not implemented yet\n");
+ return E_NOTIMPL;
+ }
+
+ hr = IDirect3DSurface9_GetDesc(src_surface, &src_desc);
+ if (FAILED(hr)) return hr;
+
+ pixel_format = get_format_info(src_desc.Format);
+ if (pixel_format->type == FORMAT_UNKNOWN) return E_NOTIMPL;
+
+ file_size = calculate_dds_file_size(src_desc.Format, src_desc.Width, src_desc.Height, 1, 1, 1);
+
+ hr = calculate_dds_surface_size(src_desc.Format, src_desc.Width, src_desc.Height, &dst_pitch, &surface_size);
+ if (FAILED(hr)) return hr;
+
+ hr = D3DXCreateBuffer(file_size, &buffer);
+ if (FAILED(hr)) return hr;
+
+ header = ID3DXBuffer_GetBufferPointer(buffer);
+ pixels = (BYTE *)(header + 1);
+
+ memset(header, 0, sizeof(header));
+ header->signature = MAKEFOURCC('D','D','S',' ');
+ header->size = sizeof(*header);
+ header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PITCH | DDS_PIXELFORMAT | DDS_MIPMAPCOUNT;
+ header->height = src_desc.Height;
+ header->width = src_desc.Width;
+ header->pitch_or_linear_size = dst_pitch;
+ header->depth = 1;
+ header->miplevels = 1;
+ header->caps = DDS_CAPS_TEXTURE;
+ hr = d3dformat_to_dds_pixel_format(&header->pixel_format, src_desc.Format);
+ if (FAILED(hr))
+ {
+ ID3DXBuffer_Release(buffer);
+ return hr;
+ }
+
+ hr = IDirect3DSurface9_LockRect(src_surface, &locked_rect, NULL, D3DLOCK_READONLY);
+ if (FAILED(hr))
+ {
+ ID3DXBuffer_Release(buffer);
+ return hr;
+ }
+
+ volume.width = src_desc.Width;
+ volume.height = src_desc.Height;
+ volume.depth = 1;
+ copy_simple_data(locked_rect.pBits, locked_rect.Pitch, 0, &volume, pixel_format,
+ pixels, dst_pitch, 0, &volume, pixel_format, 0);
+
+ IDirect3DSurface9_UnlockRect(src_surface);
+
+ *dst_buffer = buffer;
+ return D3D_OK;
+}
+
HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette,
const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key,
const D3DXIMAGE_INFO *src_info)
@@ -1761,6 +1853,7 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE
encoder_clsid = &CLSID_WICJpegEncoder;
break;
case D3DXIFF_DDS:
+ return save_dds_surface_to_memory(dst_buffer, src_surface, src_rect);
case D3DXIFF_DIB:
case D3DXIFF_HDR:
case D3DXIFF_PFM:
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index 5a01200..50ed2b2 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -1156,9 +1156,10 @@ next_tests:
ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
hr = D3DXSaveSurfaceToFileA("saved_surface.tga", D3DXIFF_TGA, surface, NULL, NULL);
ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
+ }
+
hr = D3DXSaveSurfaceToFileA("saved_surface.dds", D3DXIFF_DDS, surface, NULL, NULL);
ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
- }
hr = D3DXSaveSurfaceToFileA("saved_surface", D3DXIFF_PFM + 1, surface, NULL, NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
--
1.7.12
More information about the wine-patches
mailing list