|
|
|
@ -3,7 +3,9 @@ |
|
|
|
|
|
|
|
using System; |
|
|
|
using System.Buffers; |
|
|
|
using System.Runtime.CompilerServices; |
|
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
|
using SixLabors.ImageSharp.Memory; |
|
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
|
|
|
|
|
namespace SixLabors.ImageSharp.Processing.Processors.Transforms |
|
|
|
@ -53,20 +55,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms |
|
|
|
private void FlipX(ImageFrame<TPixel> source, Configuration configuration) |
|
|
|
{ |
|
|
|
int height = source.Height; |
|
|
|
using IMemoryOwner<TPixel> tempBuffer = configuration.MemoryAllocator.Allocate<TPixel>(source.Width); |
|
|
|
Span<TPixel> temp = tempBuffer.Memory.Span; |
|
|
|
|
|
|
|
using (IMemoryOwner<TPixel> tempBuffer = configuration.MemoryAllocator.Allocate<TPixel>(source.Width)) |
|
|
|
for (int yTop = 0; yTop < height / 2; yTop++) |
|
|
|
{ |
|
|
|
Span<TPixel> temp = tempBuffer.Memory.Span; |
|
|
|
|
|
|
|
for (int yTop = 0; yTop < height / 2; yTop++) |
|
|
|
{ |
|
|
|
int yBottom = height - yTop - 1; |
|
|
|
Span<TPixel> topRow = source.GetPixelRowSpan(yBottom); |
|
|
|
Span<TPixel> bottomRow = source.GetPixelRowSpan(yTop); |
|
|
|
topRow.CopyTo(temp); |
|
|
|
bottomRow.CopyTo(topRow); |
|
|
|
temp.CopyTo(bottomRow); |
|
|
|
} |
|
|
|
int yBottom = height - yTop - 1; |
|
|
|
Span<TPixel> topRow = source.GetPixelRowSpan(yBottom); |
|
|
|
Span<TPixel> bottomRow = source.GetPixelRowSpan(yTop); |
|
|
|
topRow.CopyTo(temp); |
|
|
|
bottomRow.CopyTo(topRow); |
|
|
|
temp.CopyTo(bottomRow); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -80,13 +79,24 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms |
|
|
|
ParallelRowIterator.IterateRows( |
|
|
|
source.Bounds(), |
|
|
|
configuration, |
|
|
|
rows => |
|
|
|
{ |
|
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
|
{ |
|
|
|
source.GetPixelRowSpan(y).Reverse(); |
|
|
|
} |
|
|
|
}); |
|
|
|
new RowIntervalAction(source)); |
|
|
|
} |
|
|
|
|
|
|
|
private readonly struct RowIntervalAction : IRowIntervalAction |
|
|
|
{ |
|
|
|
private readonly ImageFrame<TPixel> source; |
|
|
|
|
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
|
public RowIntervalAction(ImageFrame<TPixel> source) => this.source = source; |
|
|
|
|
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
|
public void Invoke(in RowInterval rows) |
|
|
|
{ |
|
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
|
{ |
|
|
|
this.source.GetPixelRowSpan(y).Reverse(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|