[PATCH 2/2] gdiplus: Fix resample offset for nearest neighbor interpolation.
Jan Havran
havran.jan at email.cz
Sun Mar 24 09:48:36 CDT 2019
While PixelOffsetModeHighSpeed starts resampling from top left corner,
the PixelOffsetModeHighQuality uses half of step as an offset.
Signed-off-by: Jan Havran <havran.jan at email.cz>
---
dlls/gdiplus/graphics.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 82f0cc79f5..ec4cb6c69b 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -959,7 +959,7 @@ static ARGB sample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT wi
static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT width,
UINT height, GpPointF *point, GDIPCONST GpImageAttributes *attributes,
- InterpolationMode interpolation, PixelOffsetMode offset_mode)
+ InterpolationMode interpolation, PixelOffsetMode offset_mode, REAL x_dx_half, REAL y_dy_half)
{
static int fixme;
@@ -1005,22 +1005,24 @@ static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT
}
case InterpolationModeNearestNeighbor:
{
- FLOAT pixel_offset;
+ FLOAT pixel_offset_x, pixel_offset_y;
switch (offset_mode)
{
default:
case PixelOffsetModeNone:
case PixelOffsetModeHighSpeed:
- pixel_offset = 0.5;
+ pixel_offset_x = 0.5;
+ pixel_offset_y = 0.5;
break;
case PixelOffsetModeHalf:
case PixelOffsetModeHighQuality:
- pixel_offset = 0.0;
+ pixel_offset_x = x_dx_half;
+ pixel_offset_y = y_dy_half;
break;
}
return sample_bitmap_pixel(src_rect, bits, width, height,
- floorf(point->X + pixel_offset), floorf(point->Y + pixel_offset), attributes);
+ floorf(point->X + pixel_offset_x), floorf(point->Y + pixel_offset_y), attributes);
}
}
@@ -1311,6 +1313,8 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush,
REAL x_dy = draw_points[1].Y - draw_points[0].Y;
REAL y_dx = draw_points[2].X - draw_points[0].X;
REAL y_dy = draw_points[2].Y - draw_points[0].Y;
+ REAL x_dx_half = x_dx / 2.0;
+ REAL y_dy_half = y_dx / 2.0;
for (y=0; y<fill_area->Height; y++)
{
@@ -1323,7 +1327,7 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush,
argb_pixels[x + y*cdwStride] = resample_bitmap_pixel(
&src_area, fill->bitmap_bits, bitmap->width, bitmap->height,
&point, fill->imageattributes, graphics->interpolation,
- graphics->pixeloffset);
+ graphics->pixeloffset, x_dx_half, y_dy_half);
}
}
}
@@ -3083,6 +3087,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
PixelOffsetMode offset_mode = graphics->pixeloffset;
GpPointF dst_to_src_points[3] = {{0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}};
REAL x_dx, x_dy, y_dx, y_dy;
+ REAL x_dx_half, y_dy_half;
static const GpImageAttributes defaultImageAttributes = {WrapModeClamp, 0, FALSE};
if (!imageAttributes)
@@ -3187,6 +3192,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
x_dy = dst_to_src_points[1].Y - dst_to_src_points[0].Y;
y_dx = dst_to_src_points[2].X - dst_to_src_points[0].X;
y_dy = dst_to_src_points[2].Y - dst_to_src_points[0].Y;
+ x_dx_half = x_dx / 2.0;
+ y_dy_half = y_dy / 2.0;
for (x=dst_area.left; x<dst_area.right; x++)
{
@@ -3202,7 +3209,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
if (src_pointf.X >= srcx && src_pointf.X < srcx + srcwidth && src_pointf.Y >= srcy && src_pointf.Y < srcy+srcheight)
*dst_color = resample_bitmap_pixel(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf,
- imageAttributes, interpolation, offset_mode);
+ imageAttributes, interpolation, offset_mode, x_dx_half, y_dy_half);
else
*dst_color = 0;
}
--
2.21.0
More information about the wine-devel
mailing list