diff --git a/src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs b/src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs
index 7163af315..7608c70c6 100644
--- a/src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs
+++ b/src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs
@@ -13,12 +13,9 @@ namespace ImageSharp.Formats.Jpg
internal static unsafe class JpegUtils
{
///
- /// Copy a region of an image into dest. De "outlier" area will be stretched out with pixels on the right and bottom of
- /// the image.
+ /// Copy a region of an image into dest. De "outlier" area will be stretched out with pixels on the right and bottom of the image.
///
- ///
- /// The pixel type
- ///
+ /// The pixel type
/// The input pixel acessor
/// The destination
/// Starting Y coord
@@ -30,27 +27,57 @@ namespace ImageSharp.Formats.Jpg
int sourceX)
where TColor : struct, IPackedPixel, IEquatable
{
- pixels.CopyTo(dest, sourceY, sourceX);
+ pixels.UncheckedCopyTo(dest, sourceY, sourceX);
int stretchFromX = pixels.Width - sourceX;
int stretchFromY = pixels.Height - sourceY;
StretchPixels(dest, stretchFromX, stretchFromY);
}
+ ///
+ /// Copy a region of image into the image destination area. Does not throw when requesting a 0-size copy.
+ ///
+ /// The pixel type
+ /// The source
+ /// The destination area.
+ /// The source row index.
+ /// The source column index.
+ ///
+ /// Thrown when an unsupported component order value is passed.
+ ///
+ public static void UncheckedCopyTo(
+ this PixelAccessor sourcePixels,
+ PixelArea destinationArea,
+ int sourceY,
+ int sourceX)
+ where TColor : struct, IPackedPixel, IEquatable
+ {
+ // TODO: Code smell! This is exactly the same code PixelArea.CopyTo() starts with!
+ int width = Math.Min(destinationArea.Width, sourcePixels.Width - sourceX);
+ int height = Math.Min(destinationArea.Height, sourcePixels.Height - sourceY);
+ if (width < 1 || height < 1)
+ {
+ return;
+ }
+
+ sourcePixels.CopyTo(destinationArea, sourceY, sourceX);
+ }
+
///
/// Copy an RGB value
///
/// Source pointer
/// Destination pointer
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void CopyRgb(byte* source, byte* dest)
+ public static void CopyRgb(byte* source, byte* dest)
{
*dest++ = *source++; // R
*dest++ = *source++; // G
*dest = *source; // B
}
+ // Nothing to stretch if (fromX, fromY) is outside the area, or is at (0,0)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static bool IsInvalidStretchArea(PixelArea area, int fromX, int fromY)
+ private static bool IsInvalidStretchStartingPosition(PixelArea area, int fromX, int fromY)
where TColor : struct, IPackedPixel, IEquatable
{
return fromX <= 0 || fromY <= 0 || fromX >= area.Width || fromY >= area.Height;
@@ -59,7 +86,7 @@ namespace ImageSharp.Formats.Jpg
private static void StretchPixels(PixelArea area, int fromX, int fromY)
where TColor : struct, IPackedPixel, IEquatable
{
- if (IsInvalidStretchArea(area, fromX, fromY))
+ if (IsInvalidStretchStartingPosition(area, fromX, fromY))
{
return;
}
diff --git a/src/ImageSharp/Image/PixelAccessor{TColor}.cs b/src/ImageSharp/Image/PixelAccessor{TColor}.cs
index 1dd3edf94..178ea5274 100644
--- a/src/ImageSharp/Image/PixelAccessor{TColor}.cs
+++ b/src/ImageSharp/Image/PixelAccessor{TColor}.cs
@@ -186,7 +186,7 @@ namespace ImageSharp
int width = Math.Min(area.Width, this.Width - targetX);
int height = Math.Min(area.Height, this.Height - targetY);
- // this.CheckDimensions(width, height); TODO: Why was width == 0 or height == 0 considered a problem? Copy implementations do not fail on this (just do nothing)!
+ this.CheckDimensions(width, height);
switch (area.ComponentOrder)
{
case ComponentOrder.ZYX:
@@ -220,7 +220,7 @@ namespace ImageSharp
int width = Math.Min(area.Width, this.Width - sourceX);
int height = Math.Min(area.Height, this.Height - sourceY);
- // this.CheckDimensions(width, height); TODO: Why was width == 0 or height == 0 considered a problem? Copy implementations do not fail on this (just do nothing)!
+ this.CheckDimensions(width, height);
switch (area.ComponentOrder)
{
case ComponentOrder.ZYX: