Commit edb01d26 authored by Christian Costa's avatar Christian Costa Committed by Alexandre Julliard

d3dx9_36: Add support for D3DFMT_P8 and conversion to other ARGB formats + tests.

parent a047b2cb
...@@ -50,6 +50,7 @@ enum format_type { ...@@ -50,6 +50,7 @@ enum format_type {
FORMAT_ARGBF16,/* float 16 */ FORMAT_ARGBF16,/* float 16 */
FORMAT_ARGBF, /* float */ FORMAT_ARGBF, /* float */
FORMAT_DXT, FORMAT_DXT,
FORMAT_INDEX,
FORMAT_UNKNOWN FORMAT_UNKNOWN
}; };
...@@ -63,7 +64,7 @@ struct pixel_format_desc { ...@@ -63,7 +64,7 @@ struct pixel_format_desc {
UINT block_byte_count; UINT block_byte_count;
enum format_type type; enum format_type type;
void (*from_rgba)(const struct vec4 *src, struct vec4 *dst); void (*from_rgba)(const struct vec4 *src, struct vec4 *dst);
void (*to_rgba)(const struct vec4 *src, struct vec4 *dst); void (*to_rgba)(const struct vec4 *src, struct vec4 *dst, const PALETTEENTRY *palette);
}; };
HRESULT map_view_of_file(LPCWSTR filename, LPVOID *buffer, DWORD *length) DECLSPEC_HIDDEN; HRESULT map_view_of_file(LPCWSTR filename, LPVOID *buffer, DWORD *length) DECLSPEC_HIDDEN;
...@@ -80,11 +81,11 @@ void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, ...@@ -80,11 +81,11 @@ void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
const struct volume *src_size, const struct pixel_format_desc *src_format, const struct volume *src_size, const struct pixel_format_desc *src_format,
BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size,
const struct pixel_format_desc *dst_format, D3DCOLOR color_key) DECLSPEC_HIDDEN; const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette) DECLSPEC_HIDDEN;
void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
const struct volume *src_size, const struct pixel_format_desc *src_format, const struct volume *src_size, const struct pixel_format_desc *src_format,
BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size,
const struct pixel_format_desc *dst_format, D3DCOLOR color_key) DECLSPEC_HIDDEN; const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette) DECLSPEC_HIDDEN;
HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette, HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette,
DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN; DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
......
...@@ -1025,7 +1025,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, ...@@ -1025,7 +1025,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface,
D3DXIMAGE_INFO imginfo; D3DXIMAGE_INFO imginfo;
HRESULT hr; HRESULT hr;
IWICImagingFactory *factory; IWICImagingFactory *factory = NULL;
IWICBitmapDecoder *decoder; IWICBitmapDecoder *decoder;
IWICBitmapFrameDecode *bitmapframe; IWICBitmapFrameDecode *bitmapframe;
IWICStream *stream; IWICStream *stream;
...@@ -1084,6 +1084,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, ...@@ -1084,6 +1084,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface,
if (FAILED(IWICImagingFactory_CreateStream(factory, &stream))) if (FAILED(IWICImagingFactory_CreateStream(factory, &stream)))
{ {
IWICImagingFactory_Release(factory); IWICImagingFactory_Release(factory);
factory = NULL;
goto cleanup_err; goto cleanup_err;
} }
...@@ -1092,7 +1093,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, ...@@ -1092,7 +1093,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface,
hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream*)stream, NULL, 0, &decoder); hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream*)stream, NULL, 0, &decoder);
IWICStream_Release(stream); IWICStream_Release(stream);
IWICImagingFactory_Release(factory);
if (FAILED(hr)) if (FAILED(hr))
goto cleanup_err; goto cleanup_err;
...@@ -1113,6 +1113,8 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, ...@@ -1113,6 +1113,8 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface,
{ {
BYTE *buffer; BYTE *buffer;
DWORD pitch; DWORD pitch;
PALETTEENTRY *palette = NULL;
WICColor *colors = NULL;
pitch = formatdesc->bytes_per_pixel * wicrect.Width; pitch = formatdesc->bytes_per_pixel * wicrect.Width;
buffer = HeapAlloc(GetProcessHeap(), 0, pitch * wicrect.Height); buffer = HeapAlloc(GetProcessHeap(), 0, pitch * wicrect.Height);
...@@ -1120,13 +1122,51 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, ...@@ -1120,13 +1122,51 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface,
hr = IWICBitmapFrameDecode_CopyPixels(bitmapframe, &wicrect, pitch, hr = IWICBitmapFrameDecode_CopyPixels(bitmapframe, &wicrect, pitch,
pitch * wicrect.Height, buffer); pitch * wicrect.Height, buffer);
if (SUCCEEDED(hr) && (formatdesc->type == FORMAT_INDEX))
{
IWICPalette *wic_palette = NULL;
UINT nb_colors;
hr = IWICImagingFactory_CreatePalette(factory, &wic_palette);
if (SUCCEEDED(hr))
hr = IWICBitmapFrameDecode_CopyPalette(bitmapframe, wic_palette);
if (SUCCEEDED(hr))
hr = IWICPalette_GetColorCount(wic_palette, &nb_colors);
if (SUCCEEDED(hr))
{
colors = HeapAlloc(GetProcessHeap(), 0, nb_colors * sizeof(colors));
palette = HeapAlloc(GetProcessHeap(), 0, nb_colors * sizeof(palette));
if (!colors || !palette)
hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
hr = IWICPalette_GetColors(wic_palette, nb_colors, colors, &nb_colors);
if (SUCCEEDED(hr))
{
UINT i;
/* Convert colors from WICColor (ARGB) to PALETTEENTRY (ABGR) */
for (i = 0; i < nb_colors; i++)
{
palette[i].peRed = (colors[i] >> 16) & 0xff;
palette[i].peGreen = (colors[i] >> 8) & 0xff;
palette[i].peBlue = colors[i] & 0xff;
palette[i].peFlags = (colors[i] >> 24) & 0xff; /* peFlags is the alpha component in DX8 and higher */
}
}
if (wic_palette)
IWICPalette_Release(wic_palette);
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = D3DXLoadSurfaceFromMemory(pDestSurface, pDestPalette, pDestRect, hr = D3DXLoadSurfaceFromMemory(pDestSurface, pDestPalette, pDestRect,
buffer, imginfo.Format, pitch, buffer, imginfo.Format, pitch,
NULL, &rect, dwFilter, Colorkey); palette, &rect, dwFilter, Colorkey);
} }
HeapFree(GetProcessHeap(), 0, colors);
HeapFree(GetProcessHeap(), 0, palette);
HeapFree(GetProcessHeap(), 0, buffer); HeapFree(GetProcessHeap(), 0, buffer);
} }
...@@ -1136,6 +1176,9 @@ cleanup_bmp: ...@@ -1136,6 +1176,9 @@ cleanup_bmp:
IWICBitmapDecoder_Release(decoder); IWICBitmapDecoder_Release(decoder);
cleanup_err: cleanup_err:
if (factory)
IWICImagingFactory_Release(factory);
CoUninitialize(); CoUninitialize();
if (imginfo.ImageFileFormat == D3DXIFF_DIB) if (imginfo.ImageFileFormat == D3DXIFF_DIB)
...@@ -1466,7 +1509,8 @@ void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, ...@@ -1466,7 +1509,8 @@ void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
*/ */
void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size,
const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch,
const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key) const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key,
const PALETTEENTRY *palette)
{ {
struct argb_conversion_info conv_info, ck_conv_info; struct argb_conversion_info conv_info, ck_conv_info;
const struct pixel_format_desc *ck_format = NULL; const struct pixel_format_desc *ck_format = NULL;
...@@ -1520,7 +1564,7 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit ...@@ -1520,7 +1564,7 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit
format_to_vec4(src_format, &pixel, &color); format_to_vec4(src_format, &pixel, &color);
if (src_format->to_rgba) if (src_format->to_rgba)
src_format->to_rgba(&color, &tmp); src_format->to_rgba(&color, &tmp, palette);
else else
tmp = color; tmp = color;
...@@ -1565,7 +1609,8 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit ...@@ -1565,7 +1609,8 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit
*/ */
void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size,
const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch,
const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key) const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key,
const PALETTEENTRY *palette)
{ {
struct argb_conversion_info conv_info, ck_conv_info; struct argb_conversion_info conv_info, ck_conv_info;
const struct pixel_format_desc *ck_format = NULL; const struct pixel_format_desc *ck_format = NULL;
...@@ -1619,7 +1664,7 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic ...@@ -1619,7 +1664,7 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
format_to_vec4(src_format, &pixel, &color); format_to_vec4(src_format, &pixel, &color);
if (src_format->to_rgba) if (src_format->to_rgba)
src_format->to_rgba(&color, &tmp); src_format->to_rgba(&color, &tmp, palette);
else else
tmp = color; tmp = color;
...@@ -1767,7 +1812,8 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, ...@@ -1767,7 +1812,8 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
} }
else /* Stretching or format conversion. */ else /* Stretching or format conversion. */
{ {
if (srcformatdesc->type != FORMAT_ARGB || destformatdesc->type != FORMAT_ARGB) if (((srcformatdesc->type != FORMAT_ARGB) && (srcformatdesc->type != FORMAT_INDEX)) ||
(destformatdesc->type != FORMAT_ARGB))
{ {
FIXME("Format conversion missing %#x -> %#x\n", src_format, surfdesc.Format); FIXME("Format conversion missing %#x -> %#x\n", src_format, surfdesc.Format);
return E_NOTIMPL; return E_NOTIMPL;
...@@ -1779,7 +1825,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, ...@@ -1779,7 +1825,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
if ((filter & 0xf) == D3DX_FILTER_NONE) if ((filter & 0xf) == D3DX_FILTER_NONE)
{ {
convert_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc, convert_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc,
lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key); lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key, src_palette);
} }
else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */ else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */
{ {
...@@ -1789,7 +1835,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, ...@@ -1789,7 +1835,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
/* Always apply a point filter until D3DX_FILTER_LINEAR, /* Always apply a point filter until D3DX_FILTER_LINEAR,
* D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */ * D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */
point_filter_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc, point_filter_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc,
lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key); lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key, src_palette);
} }
IDirect3DSurface9_UnlockRect(dst_surface); IDirect3DSurface9_UnlockRect(dst_surface);
...@@ -2064,7 +2110,7 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE ...@@ -2064,7 +2110,7 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
convert_argb_pixels(locked_rect.pBits, locked_rect.Pitch, 0, &size, src_format_desc, convert_argb_pixels(locked_rect.pBits, locked_rect.Pitch, 0, &size, src_format_desc,
dst_data, dst_pitch, 0, &size, dst_format_desc, 0); dst_data, dst_pitch, 0, &size, dst_format_desc, 0, NULL);
IDirect3DSurface9_UnlockRect(src_surface); IDirect3DSurface9_UnlockRect(src_surface);
} }
......
...@@ -49,7 +49,7 @@ static const unsigned char bmp_1bpp[] = { ...@@ -49,7 +49,7 @@ static const unsigned char bmp_1bpp[] = {
0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x02,0x00,0x00,0x00,0xf1,0xf2,0xf3,0x80,0xf4,0xf5,0xf6,0x81,0x00,0x00,
0x00,0x00 0x00,0x00
}; };
...@@ -58,7 +58,7 @@ static const unsigned char bmp_2bpp[] = { ...@@ -58,7 +58,7 @@ static const unsigned char bmp_2bpp[] = {
0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00, 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,
0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x02,0x00,0x00,0x00,0xf1,0xf2,0xf3,0x80,0xf4,0xf5,0xf6,0x81,0x00,0x00,
0x00,0x00 0x00,0x00
}; };
...@@ -67,7 +67,7 @@ static const unsigned char bmp_4bpp[] = { ...@@ -67,7 +67,7 @@ static const unsigned char bmp_4bpp[] = {
0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00, 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00,
0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x02,0x00,0x00,0x00,0xf1,0xf2,0xf3,0x80,0xf4,0xf5,0xf6,0x81,0x00,0x00,
0x00,0x00 0x00,0x00
}; };
...@@ -76,7 +76,7 @@ static const unsigned char bmp_8bpp[] = { ...@@ -76,7 +76,7 @@ static const unsigned char bmp_8bpp[] = {
0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x00,0x00, 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x00,0x00,
0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x02,0x00,0x00,0x00,0xf1,0xf2,0xf3,0x80,0xf4,0xf5,0xf6,0x81,0x00,0x00,
0x00,0x00 0x00,0x00
}; };
...@@ -646,7 +646,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) ...@@ -646,7 +646,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
/* D3DXLoadSurfaceFromFile */ /* D3DXLoadSurfaceFromFile */
if(testbitmap_ok) { if(testbitmap_ok) {
hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL); hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL);
todo_wine ok(hr == D3D_OK, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3D_OK);
hr = D3DXLoadSurfaceFromFileA(NULL, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL); hr = D3DXLoadSurfaceFromFileA(NULL, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
...@@ -683,7 +683,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) ...@@ -683,7 +683,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
/* D3DXLoadSurfaceFromFileInMemory */ /* D3DXLoadSurfaceFromFileInMemory */
hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp_1bpp, sizeof(bmp_1bpp), NULL, D3DX_DEFAULT, 0, NULL); hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp_1bpp, sizeof(bmp_1bpp), NULL, D3DX_DEFAULT, 0, NULL);
todo_wine ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, noimage, sizeof(noimage), NULL, D3DX_DEFAULT, 0, NULL); hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, noimage, sizeof(noimage), NULL, D3DX_DEFAULT, 0, NULL);
ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
...@@ -800,6 +800,8 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) ...@@ -800,6 +800,8 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf, NULL); hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf, NULL);
if(FAILED(hr)) skip("Failed to create a surface (%#x)\n", hr); if(FAILED(hr)) skip("Failed to create a surface (%#x)\n", hr);
else { else {
PALETTEENTRY palette;
hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2, D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0); hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2, D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY); IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
...@@ -870,6 +872,28 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) ...@@ -870,6 +872,28 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
hr = IDirect3DSurface9_UnlockRect(surf); hr = IDirect3DSurface9_UnlockRect(surf);
ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
/* Test D3DXLoadSurfaceFromMemory with indexed color image */
palette.peRed = bmp_1bpp[56];
palette.peGreen = bmp_1bpp[55];
palette.peBlue = bmp_1bpp[54];
palette.peFlags = bmp_1bpp[57]; /* peFlags is the alpha component in DX8 and higher */
hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, &bmp_1bpp[62], D3DFMT_P8, 4, (const PALETTEENTRY*)&palette, &rect, D3DX_FILTER_NONE, 0);
ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x\n", hr);
ok(*(DWORD*)lockrect.pBits == 0x80f3f2f1, "Pixel color mismatch: got %#x, expected 0x80f3f2f1\n", *(DWORD*)lockrect.pBits);
hr = IDirect3DSurface9_UnlockRect(surf);
ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x\n", hr);
/* Test D3DXLoadSurfaceFromFileInMemory with indexed color image (alpha is not taken into account for bmp file) */
hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp_1bpp, sizeof(bmp_1bpp), NULL, D3DX_FILTER_NONE, 0, NULL);
ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x\n", hr);
ok(*(DWORD*)lockrect.pBits == 0xfff3f2f1, "Pixel color mismatch: got %#x, expected 0xfff3f2f1\n", *(DWORD*)lockrect.pBits);
hr = IDirect3DSurface9_UnlockRect(surf);
ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x\n", hr);
check_release((IUnknown*)surf, 0); check_release((IUnknown*)surf, 0);
} }
......
...@@ -28,7 +28,7 @@ static void la_from_rgba(const struct vec4 *rgba, struct vec4 *la) ...@@ -28,7 +28,7 @@ static void la_from_rgba(const struct vec4 *rgba, struct vec4 *la)
la->w = rgba->w; la->w = rgba->w;
} }
static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba) static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba, const PALETTEENTRY *palette)
{ {
rgba->x = la->x; rgba->x = la->x;
rgba->y = la->x; rgba->y = la->x;
...@@ -36,6 +36,16 @@ static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba) ...@@ -36,6 +36,16 @@ static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba)
rgba->w = la->w; rgba->w = la->w;
} }
static void index_to_rgba(const struct vec4 *index, struct vec4 *rgba, const PALETTEENTRY *palette)
{
ULONG idx = (ULONG)(index->x * 255.0f + 0.5f);
rgba->x = palette[idx].peRed / 255.0f;
rgba->y = palette[idx].peGreen / 255.0f;
rgba->z = palette[idx].peBlue / 255.0f;
rgba->w = palette[idx].peFlags / 255.0f; /* peFlags is the alpha component in DX8 and higher */
}
/************************************************************ /************************************************************
* pixel format table providing info about number of bytes per pixel, * pixel format table providing info about number of bytes per pixel,
* number of bits per channel and format type. * number of bits per channel and format type.
...@@ -73,7 +83,7 @@ static const struct pixel_format_desc formats[] = ...@@ -73,7 +83,7 @@ static const struct pixel_format_desc formats[] =
{D3DFMT_DXT5, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, FORMAT_DXT, NULL, NULL }, {D3DFMT_DXT5, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, FORMAT_DXT, NULL, NULL },
{D3DFMT_A16B16G16R16F, {16, 16, 16, 16}, {48, 0, 16, 32}, 8, 1, 1, 8, FORMAT_ARGBF16, NULL, NULL }, {D3DFMT_A16B16G16R16F, {16, 16, 16, 16}, {48, 0, 16, 32}, 8, 1, 1, 8, FORMAT_ARGBF16, NULL, NULL },
{D3DFMT_A32B32G32R32F, {32, 32, 32, 32}, {96, 0, 32, 64}, 16, 1, 1, 16, FORMAT_ARGBF, NULL, NULL }, {D3DFMT_A32B32G32R32F, {32, 32, 32, 32}, {96, 0, 32, 64}, 16, 1, 1, 16, FORMAT_ARGBF, NULL, NULL },
{D3DFMT_P8, { 8, 8, 8, 8}, { 0, 0, 0, 0}, 1, 1, 1, 1, FORMAT_UNKNOWN, NULL, NULL }, {D3DFMT_P8, { 8, 8, 8, 8}, { 0, 0, 0, 0}, 1, 1, 1, 1, FORMAT_INDEX, NULL, index_to_rgba},
/* marks last element */ /* marks last element */
{D3DFMT_UNKNOWN, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 0, 1, 1, 0, FORMAT_UNKNOWN, NULL, NULL }, {D3DFMT_UNKNOWN, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 0, 1, 1, 0, FORMAT_UNKNOWN, NULL, NULL },
}; };
......
...@@ -185,7 +185,9 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume, ...@@ -185,7 +185,9 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume,
{ {
const BYTE *src_addr; const BYTE *src_addr;
if (src_format_desc->type != FORMAT_ARGB || dst_format_desc->type != FORMAT_ARGB)
if (((src_format_desc->type != FORMAT_ARGB) && (src_format_desc->type != FORMAT_INDEX)) ||
(dst_format_desc->type != FORMAT_ARGB))
{ {
FIXME("Pixel format conversion not implemented %#x -> %#x\n", FIXME("Pixel format conversion not implemented %#x -> %#x\n",
src_format_desc->format, dst_format_desc->format); src_format_desc->format, dst_format_desc->format);
...@@ -203,7 +205,8 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume, ...@@ -203,7 +205,8 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume,
if ((filter & 0xf) == D3DX_FILTER_NONE) if ((filter & 0xf) == D3DX_FILTER_NONE)
{ {
convert_argb_pixels(src_memory, src_row_pitch, src_slice_pitch, &src_size, src_format_desc, convert_argb_pixels(src_memory, src_row_pitch, src_slice_pitch, &src_size, src_format_desc,
locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, &dst_size, dst_format_desc, color_key); locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, &dst_size, dst_format_desc, color_key,
src_palette);
} }
else else
{ {
...@@ -211,7 +214,8 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume, ...@@ -211,7 +214,8 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume,
FIXME("Unhandled filter %#x.\n", filter); FIXME("Unhandled filter %#x.\n", filter);
point_filter_argb_pixels(src_addr, src_row_pitch, src_slice_pitch, &src_size, src_format_desc, point_filter_argb_pixels(src_addr, src_row_pitch, src_slice_pitch, &src_size, src_format_desc,
locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, &dst_size, dst_format_desc, color_key); locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, &dst_size, dst_format_desc, color_key,
src_palette);
} }
IDirect3DVolume9_UnlockBox(dst_volume); IDirect3DVolume9_UnlockBox(dst_volume);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment