[RFC PATCH v4 7/7] gdi32: calculate effective number of scan lines and truncate bitmap bits for EMR_SETDIBITSTODEVICE.

Jinoh Kang jinoh.kang.kr at gmail.com
Mon Oct 18 09:10:56 CDT 2021


On 10/17/21 13:39, Jinoh Kang wrote:
> Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
> ---
>  dlls/gdi32/emfdc.c          | 17 +++++++++++++++++
>  dlls/gdi32/tests/metafile.c |  7 -------
>  2 files changed, 17 insertions(+), 7 deletions(-)
> 
> diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c
> index 6495129e97e..bd73906f72d 100644
> --- a/dlls/gdi32/emfdc.c
> +++ b/dlls/gdi32/emfdc.c
> @@ -1808,6 +1808,7 @@ BOOL EMFDC_SetDIBitsToDevice( DC_ATTR *dc_attr, INT x_dst, INT y_dst, DWORD widt
>      EMRSETDIBITSTODEVICE *emr;
>      BOOL ret;
>      UINT bmi_size, img_size, payload_size, emr_size;
> +    UINT src_height, stride;
>      BITMAPINFOHEADER bih;
>      BITMAPINFO *bi;
>  
> @@ -1815,6 +1816,22 @@ BOOL EMFDC_SetDIBitsToDevice( DC_ATTR *dc_attr, INT x_dst, INT y_dst, DWORD widt
>      if (!emf_parse_user_bitmapinfo( &bih, &info->bmiHeader, usage, TRUE,
>                                      &bmi_size, &img_size )) return 0;
>  
> +    if (bih.biHeight >= 0)
> +    {
> +        src_height = (UINT)bih.biHeight;
> +        if (src_height > y_src + height) src_height = y_src + height;
> +        if (lines > src_height - startscan) lines = src_height - startscan;

Some discrepancies from nulldrv that I have discovered:

- nulldrv fails if `src_height < startscan`.
  - behaviour should be copied to EMFDC.
- nulldrv ignores startscan and lines if using BI_RLE4 and BI_RLE8.
  - likely a bug on nulldrv's part.

> +        if (!lines) return 0;
> +
> +        if (bih.biCompression == BI_RGB || bih.biCompression == BI_BITFIELDS)
> +        {
> +            /* truncate image and check for overflows */
> +            stride = get_dib_stride( bih.biWidth, bih.biBitCount );
> +            img_size = lines * stride;
> +            if (img_size / stride != lines) return 0;
> +        }
> +    }
> +
>      /* check for overflows */
>      payload_size = bmi_size + img_size;
>      if (payload_size < bmi_size) return 0;
> diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
> index 25c851e7384..2df38674c2f 100644
> --- a/dlls/gdi32/tests/metafile.c
> +++ b/dlls/gdi32/tests/metafile.c
> @@ -7764,13 +7764,6 @@ static void test_emf_SetDIBitsToDevice(void)
>      {
>          winetest_push_context("Test %d", test_idx);
>  
> -        if (tests[test_idx].height != bitmap_height && !strcmp(winetest_platform, "wine"))
> -        {
> -            skip("Wine does not adjust cLines appropriately\n");
> -            winetest_pop_context();
> -            continue;
> -        }
> -
>          memset(&bmi, 0, sizeof(bmi));
>          if (tests[test_idx].infomode < 2)
>          {
> 

-- 
Sincerely,
Jinoh Kang



More information about the wine-devel mailing list