[3/5] d3dx9: Implement D3DXSaveSurfaceToFileW.
Józef Kucia
joseph.kucia at gmail.com
Wed May 2 07:55:37 CDT 2012
This implementation is able to save surfaces only when the pixel format
conversion isn't needed.
---
dlls/d3dx9_36/surface.c | 166 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 162 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 70627fd..5989984 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -59,6 +59,19 @@ static D3DFORMAT wic_guid_to_d3dformat(const GUID *guid)
return D3DFMT_UNKNOWN;
}
+static const GUID *d3dformat_to_wic_guid(D3DFORMAT format)
+{
+ int i;
+
+ for (i = 0; i < sizeof(wic_pixel_formats) / sizeof(wic_pixel_formats[0]); i++)
+ {
+ if(wic_pixel_formats[i].d3dformat == format)
+ return wic_pixel_formats[i].wic_guid;
+ }
+
+ return NULL;
+}
+
/* dds_header.flags */
#define DDS_CAPS 0x1
#define DDS_HEIGHT 0x2
@@ -1387,9 +1400,154 @@ HRESULT WINAPI D3DXSaveSurfaceToFileA(LPCSTR dst_filename, D3DXIMAGE_FILEFORMAT
return hr;
}
-HRESULT WINAPI D3DXSaveSurfaceToFileW(LPCWSTR pDestFile, D3DXIMAGE_FILEFORMAT DestFormat,
- LPDIRECT3DSURFACE9 pSrcSurface, const PALETTEENTRY* pSrcPalette, const RECT* pSrcRect)
+HRESULT WINAPI D3DXSaveSurfaceToFileW(LPCWSTR dst_filename, D3DXIMAGE_FILEFORMAT file_format,
+ IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect)
{
- FIXME("(%p, %d, %p, %p, %p): stub\n", pDestFile, DestFormat, pSrcSurface, pSrcPalette, pSrcRect);
- return D3DERR_INVALIDCALL;
+ IWICImagingFactory *factory;
+ IWICBitmapEncoder *encoder = NULL;
+ IWICBitmapFrameEncode *frame = NULL;
+ IPropertyBag2 *encoder_options = NULL;
+ IWICStream *stream = NULL;
+ HRESULT hr;
+ HRESULT initresult;
+ const CLSID *encoder_clsid;
+ const GUID *pixel_format_guid;
+ WICPixelFormatGUID wic_pixel_format;
+ D3DFORMAT d3d_pixel_format;
+ D3DSURFACE_DESC src_surface_desc;
+ D3DLOCKED_RECT locked_rect;
+ int width, height;
+
+ TRACE("(%s, %d, %p, %p, %p)\n",
+ wine_dbgstr_w(dst_filename), file_format, src_surface, src_palette, src_rect);
+
+ if (!dst_filename || !src_surface) return D3DERR_INVALIDCALL;
+
+ if (src_palette)
+ {
+ FIXME("Saving surfaces with palettized pixel formats not implemented yet\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ switch (file_format)
+ {
+ case D3DXIFF_BMP:
+ encoder_clsid = &CLSID_WICBmpEncoder;
+ break;
+ case D3DXIFF_PNG:
+ encoder_clsid = &CLSID_WICPngEncoder;
+ break;
+ case D3DXIFF_JPG:
+ encoder_clsid = &CLSID_WICJpegEncoder;
+ break;
+ case D3DXIFF_DDS:
+ case D3DXIFF_DIB:
+ case D3DXIFF_HDR:
+ case D3DXIFF_PFM:
+ case D3DXIFF_TGA:
+ case D3DXIFF_PPM:
+ FIXME("File format %u is not supported yet\n", file_format);
+ return E_NOTIMPL;
+ default:
+ return D3DERR_INVALIDCALL;
+ }
+
+ IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc);
+ if (src_rect)
+ {
+ if (src_rect->left == src_rect->right || src_rect->top == src_rect->bottom)
+ return D3D_OK;
+ if (src_rect->left < 0 || src_rect->top < 0)
+ return D3DERR_INVALIDCALL;
+ if (src_rect->left > src_rect->right || src_rect->top > src_rect->bottom)
+ return D3DERR_INVALIDCALL;
+ if (src_rect->right > src_surface_desc.Width || src_rect->bottom > src_surface_desc.Height)
+ return D3DERR_INVALIDCALL;
+
+ width = src_rect->right - src_rect->left;
+ height = src_rect->bottom - src_rect->top;
+ }
+ else
+ {
+ width = src_surface_desc.Width;
+ height = src_surface_desc.Height;
+ }
+
+ initresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+
+ hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IWICImagingFactory, (void **)&factory);
+ if (FAILED(hr)) goto cleanup_err;
+
+ hr = IWICImagingFactory_CreateStream(factory, &stream);
+ IWICImagingFactory_Release(factory);
+ if (FAILED(hr)) goto cleanup_err;
+
+ hr = IWICStream_InitializeFromFilename(stream, dst_filename, GENERIC_WRITE);
+ if (FAILED(hr)) goto cleanup_err;
+
+ hr = CoCreateInstance(encoder_clsid, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IWICBitmapEncoder, (void **)&encoder);
+ if (FAILED(hr)) goto cleanup_err;
+
+ hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache);
+ IStream_Release((IStream *)stream);
+ stream = NULL;
+ if (FAILED(hr)) goto cleanup_err;
+
+ hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame, &encoder_options);
+ if (FAILED(hr)) goto cleanup_err;
+
+ hr = IWICBitmapFrameEncode_Initialize(frame, encoder_options);
+ if (FAILED(hr)) goto cleanup_err;
+
+ hr = IWICBitmapFrameEncode_SetSize(frame, width, height);
+ if (FAILED(hr)) goto cleanup_err;
+
+ pixel_format_guid = d3dformat_to_wic_guid(src_surface_desc.Format);
+ if (!pixel_format_guid)
+ {
+ FIXME("Pixel format %#x is not supported yet\n", src_surface_desc.Format);
+ hr = E_NOTIMPL;
+ goto cleanup;
+ }
+
+ memcpy(&wic_pixel_format, pixel_format_guid, sizeof(GUID));
+ hr = IWICBitmapFrameEncode_SetPixelFormat(frame, &wic_pixel_format);
+ d3d_pixel_format = wic_guid_to_d3dformat(&wic_pixel_format);
+ if (SUCCEEDED(hr) && d3d_pixel_format != D3DFMT_UNKNOWN)
+ {
+ TRACE("Using pixel format %s %#x\n", debugstr_guid(&wic_pixel_format), d3d_pixel_format);
+
+ if (src_surface_desc.Format == d3d_pixel_format) /* Simple copy */
+ {
+ hr = IDirect3DSurface9_LockRect(src_surface, &locked_rect, src_rect, D3DLOCK_READONLY);
+ if (SUCCEEDED(hr))
+ {
+ IWICBitmapFrameEncode_WritePixels(frame, height,
+ locked_rect.Pitch, height * locked_rect.Pitch, locked_rect.pBits);
+ IDirect3DSurface9_UnlockRect(src_surface);
+ hr = IWICBitmapFrameEncode_Commit(frame);
+ }
+ }
+ else FIXME("Unsupported pixel format conversion %#x -> %#x\n", src_surface_desc.Format, d3d_pixel_format);
+ }
+ else WARN("Unsupported pixel format %#x\n", src_surface_desc.Format);
+
+ if (SUCCEEDED(hr)) hr = IWICBitmapEncoder_Commit(encoder);
+
+cleanup_err:
+ if (FAILED(hr)) hr = D3DERR_INVALIDCALL;
+
+cleanup:
+ if (stream) IStream_Release((IStream *)stream);
+
+ if (frame) IWICBitmapFrameEncode_Release(frame);
+ if (encoder_options) IPropertyBag2_Release(encoder_options);
+
+ if (encoder) IWICBitmapEncoder_Release(encoder);
+
+ if (SUCCEEDED(initresult)) CoUninitialize();
+
+ return hr;
}
--
1.7.8.6
More information about the wine-patches
mailing list