//
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
//
namespace ImageSharp.Processing.Processors
{
using System;
using System.Threading.Tasks;
///
/// Provides methods that allow the flipping of an image around its center point.
///
/// The pixel format.
public class FlipProcessor : ImageProcessor
where TColor : struct, IPackedPixel, IEquatable
{
///
/// Initializes a new instance of the class.
///
/// The used to perform flipping.
public FlipProcessor(FlipType flipType)
{
this.FlipType = flipType;
}
///
/// Gets the used to perform flipping.
///
public FlipType FlipType { get; }
///
protected override void OnApply(ImageBase source, Rectangle sourceRectangle)
{
switch (this.FlipType)
{
// No default needed as we have already set the pixels.
case FlipType.Vertical:
this.FlipX(source);
break;
case FlipType.Horizontal:
this.FlipY(source);
break;
}
}
///
/// Swaps the image at the X-axis, which goes horizontally through the middle
/// at half the height of the image.
///
/// The source image to apply the process to.
private void FlipX(ImageBase source)
{
int width = source.Width;
int height = source.Height;
int halfHeight = (int)Math.Ceiling(source.Height * .5F);
using (PixelAccessor targetPixels = new PixelAccessor(width, height))
{
using (PixelAccessor sourcePixels = source.Lock())
{
Parallel.For(
0,
halfHeight,
this.ParallelOptions,
y =>
{
for (int x = 0; x < width; x++)
{
int newY = height - y - 1;
targetPixels[x, y] = sourcePixels[x, newY];
targetPixels[x, newY] = sourcePixels[x, y];
}
});
}
source.SwapPixelsBuffers(targetPixels);
}
}
///
/// Swaps the image at the Y-axis, which goes vertically through the middle
/// at half of the width of the image.
///
/// The source image to apply the process to.
private void FlipY(ImageBase source)
{
int width = source.Width;
int height = source.Height;
int halfWidth = (int)Math.Ceiling(width * .5F);
using (PixelAccessor targetPixels = new PixelAccessor(width, height))
{
using (PixelAccessor sourcePixels = source.Lock())
{
Parallel.For(
0,
height,
this.ParallelOptions,
y =>
{
for (int x = 0; x < halfWidth; x++)
{
int newX = width - x - 1;
targetPixels[x, y] = sourcePixels[newX, y];
targetPixels[newX, y] = sourcePixels[x, y];
}
});
}
source.SwapPixelsBuffers(targetPixels);
}
}
}
}