[PATCH 5/5] user32: Select more appropriate stretch mode for colored images interpolation.
Paul Gofman
gofmanp at gmail.com
Wed Jan 9 07:22:35 CST 2019
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 at 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;
More information about the wine-devel
mailing list