//
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
//
namespace ImageSharp.Tests
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using ImageSharp.PixelFormats;
///
/// Extension methods for TestUtilities
///
public static class TestUtilityExtensions
{
private static readonly Dictionary ClrTypes2PixelTypes = new Dictionary();
private static readonly Assembly ImageSharpAssembly = typeof(Rgba32).GetTypeInfo().Assembly;
private static readonly Dictionary PixelTypes2ClrTypes = new Dictionary();
private static readonly PixelTypes[] AllConcretePixelTypes = GetAllPixelTypes()
.Except(new[] { PixelTypes.Undefined, PixelTypes.All })
.ToArray();
static TestUtilityExtensions()
{
// Add Rgba32 Our default.
Type defaultPixelFormatType = typeof(Rgba32);
PixelTypes2ClrTypes[PixelTypes.Rgba32] = defaultPixelFormatType;
ClrTypes2PixelTypes[defaultPixelFormatType] = PixelTypes.Rgba32;
// Add PixelFormat types
string nameSpace = typeof(Alpha8).FullName;
nameSpace = nameSpace.Substring(0, nameSpace.Length - typeof(Alpha8).Name.Length - 1);
foreach (PixelTypes pt in AllConcretePixelTypes.Where(pt => pt != PixelTypes.Rgba32))
{
string typeName = $"{nameSpace}.{pt}";
Type t = ImageSharpAssembly.GetType(typeName);
PixelTypes2ClrTypes[pt] = t ?? throw new InvalidOperationException($"Could not find: {typeName}");
ClrTypes2PixelTypes[t] = pt;
}
}
public static bool HasFlag(this PixelTypes pixelTypes, PixelTypes flag) => (pixelTypes & flag) == flag;
public static bool IsEquivalentTo(this Image a, Image b, bool compareAlpha = true)
where TPixel : struct, IPixel
{
if (a.Width != b.Width || a.Height != b.Height)
{
return false;
}
byte[] bytesA = new byte[3];
byte[] bytesB = new byte[3];
using (PixelAccessor pixA = a.Lock())
{
using (PixelAccessor pixB = b.Lock())
{
for (int y = 0; y < a.Height; y++)
{
for (int x = 0; x < a.Width; x++)
{
TPixel ca = pixA[x, y];
TPixel cb = pixB[x, y];
if (compareAlpha)
{
if (!ca.Equals(cb))
{
return false;
}
}
else
{
ca.ToXyzBytes(bytesA, 0);
cb.ToXyzBytes(bytesB, 0);
if (bytesA[0] != bytesB[0] ||
bytesA[1] != bytesB[1] ||
bytesA[2] != bytesB[2])
{
return false;
}
}
}
}
}
}
return true;
}
public static string ToCsv(this IEnumerable items, string separator = ",")
{
return string.Join(separator, items.Select(o => string.Format(CultureInfo.InvariantCulture, "{0}", o)));
}
public static Type ToType(this PixelTypes pixelType) => PixelTypes2ClrTypes[pixelType];
///
/// Returns the enumerations for the given type.
///
///
///
public static PixelTypes GetPixelType(this Type colorStructClrType) => ClrTypes2PixelTypes[colorStructClrType];
public static IEnumerable> ExpandAllTypes(this PixelTypes pixelTypes)
{
if (pixelTypes == PixelTypes.Undefined)
{
return Enumerable.Empty>();
}
else if (pixelTypes == PixelTypes.All)
{
// TODO: Need to return unknown types here without forcing CLR to load all types in ImageSharp assembly
return PixelTypes2ClrTypes;
}
return AllConcretePixelTypes
.Where(pt => pixelTypes.HasFlag(pt))
.Select(pt => new KeyValuePair(pt, pt.ToType()));
}
///
/// Enumerate all available -s
///
/// The pixel types
internal static PixelTypes[] GetAllPixelTypes() => (PixelTypes[])Enum.GetValues(typeof(PixelTypes));
}
}