Skip to content

Commit

Permalink
No longer throws when DrawImage source does not overlap target
Browse files Browse the repository at this point in the history
Previously, when DrawImage was used to overlay an image, in cases where the source image did not overlap the target image, a very confusing error was reported: "System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: MaxDegreeOfParallelism"

Now, when this case happens, the DrawImage method will simply not affect the target image, which is the same way FillRegionProcessor handles such cases.

ParallelHelper.IterRows also now does more validation of the input rectangle so that any further cases of this kind of problem throw a more relvant exception. Note I switched from DebugGuard to Guard because IterRows is a public API and thus should always validate its inputs.

Fixes SixLabors#875
  • Loading branch information
atruskie committed Apr 7, 2019
1 parent 0dfa2f9 commit dd0b2a7
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ protected override void OnFrameApply(ImageFrame<TPixelDst> source, Rectangle sou

var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);

if (workingRect.Width < 0 || workingRect.Height < 0)
{
// no effect because rectangle does not overlap with this image.
return;
}

ParallelHelper.IterateRows(
workingRect,
configuration,
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public static void IterateRows(
in ParallelExecutionSettings parallelSettings,
Action<RowInterval> body)
{
DebugGuard.MustBeGreaterThan(rectangle.Width, 0, nameof(rectangle));
Guard.MustBeGreaterThan(rectangle.Width, 0, nameof(rectangle));
Guard.MustBeGreaterThan(rectangle.Height, 0, nameof(rectangle));

int maxSteps = DivideCeil(rectangle.Width * rectangle.Height, parallelSettings.MinimumPixelsProcessedPerTask);

Expand Down
20 changes: 20 additions & 0 deletions tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,26 @@ public void ImageShouldHandlePositiveLocation(TestImageProvider<Rgba32> provider
}
}

[Theory]
[WithSolidFilledImages(100, 100, 255, 255, 255, PixelTypes.Rgba32, -30, -30)]
[WithSolidFilledImages(100, 100, 255, 255, 255, PixelTypes.Rgba32, 130, -30)]
[WithSolidFilledImages(100, 100, 255, 255, 255, PixelTypes.Rgba32, 130, 130)]
[WithSolidFilledImages(100, 100, 255, 255, 255, PixelTypes.Rgba32, -30, 130)]
public void NonOverlappingImageHasNoEffect(TestImageProvider<Rgba32> provider, int x, int y)
{
using (Image<Rgba32> original = provider.GetImage())
using (Image<Rgba32> background = provider.GetImage())
using (var overlay = new Image<Rgba32>(Configuration.Default, 10, 10, Rgba32.Black))
{
background.Mutate(context => context.DrawImage(overlay, new Point(x, y), GraphicsOptions.Default));

// background image should be unmodified
ImageComparer.Exact.CompareImagesOrFrames(original, background);

background.DebugSave(provider, testOutputDetails: "NonOverlapping");
}
}

private static void VerifyImage<TPixel>(
TestImageProvider<TPixel> provider,
PixelColorBlendingMode mode,
Expand Down
15 changes: 15 additions & 0 deletions tests/ImageSharp.Tests/Helpers/ParallelHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,5 +334,20 @@ void FillRow(int y, Buffer2D<Point> buffer)
TestImageExtensions.CompareBuffers(expected.Span, actual.Span);
}
}

[Theory]
[InlineData(0, 10)]
[InlineData(10, 0)]
[InlineData(-10, 10)]
[InlineData(10, -10)]
public void IterateRowsRequiresValidRectangle(int width, int height)
{
var parallelSettings = new ParallelExecutionSettings();

var rect = new Rectangle(0, 0, width, height);

Assert.Throws<ArgumentOutOfRangeException>(
() => { ParallelHelper.IterateRows(rect, parallelSettings, (rows) => { }); });
}
}
}

0 comments on commit dd0b2a7

Please sign in to comment.