From 7ab7b226d93b3e06cd34e096f82101e8f91a15ad Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Fri, 8 Dec 2023 14:06:31 +0000 Subject: [PATCH 1/3] handle when foreground overhangs bottom of background --- .../DrawImageProcessor{TPixelBg,TPixelFg}.cs | 14 +++++++++++++ .../Drawing/DrawImageTests.cs | 21 +++++++++++++++++++ .../Drawing/DrawImageTests/Issue2603.png | 3 +++ 3 files changed, 38 insertions(+) create mode 100644 tests/Images/External/ReferenceOutput/Drawing/DrawImageTests/Issue2603.png diff --git a/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs b/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs index 378ea20fa8..c51df8af80 100644 --- a/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs +++ b/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs @@ -96,6 +96,20 @@ protected override void OnFrameApply(ImageFrame source) top = 0; } + if (left + foregroundRectangle.Width > source.Width) + { + // will overhange, lets trim it down + int diff = (left + foregroundRectangle.Width) - source.Width; + foregroundRectangle.Width -= diff; + } + + if (top + foregroundRectangle.Height > source.Height) + { + // will overhange, lets trim it down + int diff = (top + foregroundRectangle.Height) - source.Height; + foregroundRectangle.Height -= diff; + } + int width = foregroundRectangle.Width; int height = foregroundRectangle.Height; if (width <= 0 || height <= 0) diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs index 8b0db773ab..6cd6e15e25 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs @@ -251,4 +251,25 @@ public void Issue2447_C(TestImageProvider provider) appendPixelTypeToFileName: false, appendSourceFileOrDescription: false); } + + [Theory] + [WithFile(TestImages.Png.Issue2447, PixelTypes.Rgba32)] + public void Issue2603(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image foreground = provider.GetImage(); + using Image background = new(100, 100, new Rgba32(0, 255, 255)); + + background.Mutate(c => c.DrawImage(foreground, new Point(80, 80), new Rectangle(32, 32, 32, 32), 1F)); + + background.DebugSave( + provider, + appendPixelTypeToFileName: false, + appendSourceFileOrDescription: false); + + background.CompareToReferenceOutput( + provider, + appendPixelTypeToFileName: false, + appendSourceFileOrDescription: false); + } } diff --git a/tests/Images/External/ReferenceOutput/Drawing/DrawImageTests/Issue2603.png b/tests/Images/External/ReferenceOutput/Drawing/DrawImageTests/Issue2603.png new file mode 100644 index 0000000000..1940dbba04 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/Drawing/DrawImageTests/Issue2603.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:307ef8cea7999e615420740bb0a403a64b24f1fff5356c2ac45c1952f84c5e4c +size 508 From dd705eb0587f147f748aa0dec5032c2738f23327 Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Sat, 9 Dec 2023 10:32:00 +0000 Subject: [PATCH 2/3] prevent potential overflow --- .../Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs b/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs index c51df8af80..e2aca1d90a 100644 --- a/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs +++ b/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs @@ -96,14 +96,14 @@ protected override void OnFrameApply(ImageFrame source) top = 0; } - if (left + foregroundRectangle.Width > source.Width) + if (left > source.Width - foregroundRectangle.Width) { // will overhange, lets trim it down int diff = (left + foregroundRectangle.Width) - source.Width; foregroundRectangle.Width -= diff; } - if (top + foregroundRectangle.Height > source.Height) + if (top > source.Height - foregroundRectangle.Height) { // will overhange, lets trim it down int diff = (top + foregroundRectangle.Height) - source.Height; From 6c7b59fc06cf8da9af070cad8aebae059cb68e47 Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Sat, 9 Dec 2023 10:43:21 +0000 Subject: [PATCH 3/3] reduce to a single par of clamping operations --- .../DrawImageProcessor{TPixelBg,TPixelFg}.cs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs b/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs index e2aca1d90a..031bcbdf78 100644 --- a/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs +++ b/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs @@ -96,19 +96,9 @@ protected override void OnFrameApply(ImageFrame source) top = 0; } - if (left > source.Width - foregroundRectangle.Width) - { - // will overhange, lets trim it down - int diff = (left + foregroundRectangle.Width) - source.Width; - foregroundRectangle.Width -= diff; - } - - if (top > source.Height - foregroundRectangle.Height) - { - // will overhange, lets trim it down - int diff = (top + foregroundRectangle.Height) - source.Height; - foregroundRectangle.Height -= diff; - } + // clamp the height/width to the availible space left to prevent overflowing + foregroundRectangle.Width = Math.Min(source.Width - left, foregroundRectangle.Width); + foregroundRectangle.Height = Math.Min(source.Height - top, foregroundRectangle.Height); int width = foregroundRectangle.Width; int height = foregroundRectangle.Height;