From f8d5742450cd0ecbf622a701f91b1e00cb54bd52 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 28 Dec 2016 04:25:45 +0100 Subject: [PATCH] CheckDimensions --- src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs | 45 +++++++++++++++---- src/ImageSharp/Image/PixelAccessor{TColor}.cs | 4 +- 2 files changed, 38 insertions(+), 11 deletions(-) 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: