// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.ImageSharp.Tests
{
///
/// Tests the class.
///
public class PixelAccessorTests
{
public static Image CreateTestImage()
where TPixel : struct, IPixel
{
var image = new Image(10, 10);
using (PixelAccessor pixels = image.Lock())
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
var v = new Vector4(i, j, 0, 1);
v /= 10;
var color = default(TPixel);
color.PackFromVector4(v);
pixels[i, j] = color;
}
}
}
return image;
}
[Theory]
[WithMemberFactory(nameof(CreateTestImage), PixelTypes.All, ComponentOrder.Xyz)]
[WithMemberFactory(nameof(CreateTestImage), PixelTypes.All, ComponentOrder.Zyx)]
[WithMemberFactory(nameof(CreateTestImage), PixelTypes.All, ComponentOrder.Xyzw)]
[WithMemberFactory(nameof(CreateTestImage), PixelTypes.All, ComponentOrder.Zyxw)]
internal void CopyTo_Then_CopyFrom_OnFullImageRect(TestImageProvider provider, ComponentOrder order)
where TPixel : struct, IPixel
{
using (Image src = provider.GetImage())
{
using (Image dest = new Image(src.Width, src.Height))
{
using (PixelArea area = new PixelArea(src.Width, src.Height, order))
{
using (PixelAccessor srcPixels = src.Lock())
{
srcPixels.CopyTo(area, 0, 0);
}
using (PixelAccessor destPixels = dest.Lock())
{
destPixels.CopyFrom(area, 0, 0);
}
}
Assert.True(src.IsEquivalentTo(dest, false));
}
}
}
[Theory]
[WithBlankImages(16, 16, PixelTypes.All, ComponentOrder.Xyz)]
[WithBlankImages(16, 16, PixelTypes.All, ComponentOrder.Zyx)]
[WithBlankImages(16, 16, PixelTypes.All, ComponentOrder.Xyzw)]
[WithBlankImages(16, 16, PixelTypes.All, ComponentOrder.Zyxw)]
internal void CopyToThenCopyFromWithOffset(TestImageProvider provider, ComponentOrder order)
where TPixel : struct, IPixel
{
using (Image destImage = new Image(8, 8))
{
using (Image srcImage = provider.GetImage())
{
srcImage.Mutate(x => x.Fill(NamedColors.Red, new Rectangle(4, 4, 8, 8)));
using (PixelAccessor srcPixels = srcImage.Lock())
{
using (PixelArea area = new PixelArea(8, 8, order))
{
srcPixels.CopyTo(area, 4, 4);
using (PixelAccessor destPixels = destImage.Lock())
{
destPixels.CopyFrom(area, 0, 0);
}
}
}
}
provider.Utility.SourceFileOrDescription = order.ToString();
provider.Utility.SaveTestOutputFile(destImage, "bmp");
using (Image expectedImage = new Image(8, 8))
{
expectedImage.Mutate(x => x.Fill(NamedColors.Red));
Assert.True(destImage.IsEquivalentTo(expectedImage));
}
}
}
[Fact]
public void CopyFromZYX()
{
using (Image image = new Image(1, 1))
{
CopyFromZYXImpl(image);
}
}
[Fact]
public void CopyFromZYXW()
{
using (Image image = new Image(1, 1))
{
CopyFromZYXWImpl(image);
}
}
[Fact]
public void CopyToZYX()
{
using (Image image = new Image(1, 1))
{
CopyToZYXImpl(image);
}
}
[Fact]
public void CopyToZYXW()
{
using (Image image = new Image(1, 1))
{
CopyToZYXWImpl(image);
}
}
private static void CopyFromZYXImpl(Image image)
where TPixel : struct, IPixel
{
using (PixelAccessor pixels = image.Lock())
{
byte red = 1;
byte green = 2;
byte blue = 3;
byte alpha = 255;
using (PixelArea row = new PixelArea(1, ComponentOrder.Zyx))
{
row.Bytes[0] = blue;
row.Bytes[1] = green;
row.Bytes[2] = red;
pixels.CopyFrom(row, 0);
Rgba32 color = (Rgba32)(object)pixels[0, 0];
Assert.Equal(red, color.R);
Assert.Equal(green, color.G);
Assert.Equal(blue, color.B);
Assert.Equal(alpha, color.A);
}
}
}
private static void CopyFromZYXWImpl(Image image)
where TPixel : struct, IPixel
{
using (PixelAccessor pixels = image.Lock())
{
byte red = 1;
byte green = 2;
byte blue = 3;
byte alpha = 4;
using (PixelArea row = new PixelArea(1, ComponentOrder.Zyxw))
{
row.Bytes[0] = blue;
row.Bytes[1] = green;
row.Bytes[2] = red;
row.Bytes[3] = alpha;
pixels.CopyFrom(row, 0);
Rgba32 color = (Rgba32)(object)pixels[0, 0];
Assert.Equal(red, color.R);
Assert.Equal(green, color.G);
Assert.Equal(blue, color.B);
Assert.Equal(alpha, color.A);
}
}
}
private static void CopyToZYXImpl(Image image)
where TPixel : struct, IPixel
{
using (PixelAccessor pixels = image.Lock())
{
byte red = 1;
byte green = 2;
byte blue = 3;
using (PixelArea row = new PixelArea(1, ComponentOrder.Zyx))
{
pixels[0, 0] = (TPixel)(object)new Rgba32(red, green, blue);
pixels.CopyTo(row, 0);
Assert.Equal(blue, row.Bytes[0]);
Assert.Equal(green, row.Bytes[1]);
Assert.Equal(red, row.Bytes[2]);
}
}
}
private static void CopyToZYXWImpl(Image image)
where TPixel : struct, IPixel
{
using (PixelAccessor pixels = image.Lock())
{
byte red = 1;
byte green = 2;
byte blue = 3;
byte alpha = 4;
using (PixelArea row = new PixelArea(1, ComponentOrder.Zyxw))
{
pixels[0, 0] = (TPixel)(object)new Rgba32(red, green, blue, alpha);
pixels.CopyTo(row, 0);
Assert.Equal(blue, row.Bytes[0]);
Assert.Equal(green, row.Bytes[1]);
Assert.Equal(red, row.Bytes[2]);
Assert.Equal(alpha, row.Bytes[3]);
}
}
}
}
}