I've sent this last patch in the series mainly as request for comment. At the first place I am not sure if it should go during the code freeze, the problem it is supposed to fix is not a regression. Other than that, a complete fix would probably require a bit more than this.
My tests show that the full color images (24bpp) are downsampled using HALFTONE stretch mode, 1 bit images use BLACKONWHITE (as it works now in Wine), and anything between works like COLORONCOLOR mode. HALFTONE mode is not currently supported by gdi32 and falls back to COLORONCOLOR (STRECTH_DELETESCANS). This still makes more sense than using BLACKONWHITE for color images, but does not allow to fit the test for 24bpp bitmap. It could probably look more appropriate to set COLORONCOLOR mode for color images with less than 24bpp, but this way it won't fit any of my tests at all by now without changing gdi32 stretch code. If STRECTH_DELETESCANS mode is used, stretch_bitmapinfo() in gdi32/dibdrv/bitblt.c takes a bit different (optimized) path and drops wrong scans (not those dropped on Windows or when HALFTONE mode is used). This difference should not matter much in practice in most cases though. I see the following possible ways:
1. Use a more appropriate stretch mode in CopyImage() / LoadImage() for color images regardless of gdi32 stuff. It will eliminate major image colors distortions currently introduced when ANDing color values during stretch. 2. Leave CopyImage() / LoadImage() alone by now and start from transferring some StretchBlt tests to gdi32, fix COLORONCOLOR rows drop, maybe support HALFTONE interpolation, and come back to CopyImage / LoadImage after.
On 1/9/19 15:49, Paul Gofman wrote:
For bug https://bugs.winehq.org/show_bug.cgi?id=46375.
Signed-off-by: Paul Gofman gofmanp@gmail.com
dlls/user32/cursoricon.c | 4 ++++ dlls/user32/tests/cursoricon.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c index 539fc7ca54..3214746664 100644 --- a/dlls/user32/cursoricon.c +++ b/dlls/user32/cursoricon.c @@ -2976,6 +2976,8 @@ static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name, }
orig_bm = SelectObject(screen_mem_dc, hbitmap);
- if (info->bmiHeader.biBitCount > 1)
SetStretchBltMode(screen_mem_dc, HALFTONE); StretchDIBits(screen_mem_dc, 0, 0, new_width, new_height, 0, 0, width, height, bits, fix_info, DIB_RGB_COLORS, SRCCOPY); SelectObject(screen_mem_dc, orig_bm);
@@ -3217,6 +3219,8 @@ HANDLE WINAPI CopyImage( HANDLE hnd, UINT type, INT desiredx, void * bits;
dc = CreateCompatibleDC(NULL);
if (ds.dsBm.bmBitsPixel > 1)
SetStretchBltMode(dc, HALFTONE); bi->bmiHeader.biWidth = ds.dsBm.bmWidth; bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c index e5ff215b4f..bb88e2e196 100644 --- a/dlls/user32/tests/cursoricon.c +++ b/dlls/user32/tests/cursoricon.c @@ -2918,9 +2918,9 @@ static void test_Image_StretchMode(void) sizeof(colors_bits_1), FALSE}, {4, 4, 2, 2, 8, test_bits_8, expected_bits_8, sizeof(test_bits_8), sizeof(expected_bits_8), colors_bits_8,
sizeof(colors_bits_8), TRUE},
sizeof(colors_bits_8), FALSE}, {4, 4, 2, 2, 16, (const unsigned char *)test_bits_16, (const unsigned char *)expected_bits_16,
sizeof(test_bits_16), sizeof(expected_bits_16), NULL, 0, TRUE},
sizeof(test_bits_16), sizeof(expected_bits_16), NULL, 0, FALSE}, }; static const char filename[] = "test.bmp"; BITMAPINFO *bmi, *bmi_output;