|
|
|
@ -36,19 +36,16 @@ namespace ImageSharp |
|
|
|
Type source = typeof(TColor); |
|
|
|
Type target = typeof(TColor2); |
|
|
|
|
|
|
|
// Standard to offset
|
|
|
|
// Normalized standard
|
|
|
|
if (IsStandardNormalizedType(source)) |
|
|
|
{ |
|
|
|
if (IsOffsetNormalizedType(target) || IsOffsetTwoComponentNormalizedType(target)) |
|
|
|
{ |
|
|
|
// Expand the range then offset the center down.
|
|
|
|
return vector4 => (2F * vector4) - Vector4.One; |
|
|
|
} |
|
|
|
return FromStandardNormalizedType(target); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetType(target) || IsOffsetTwoComponentType(target)) |
|
|
|
{ |
|
|
|
return v => (65534 * v) - new Vector4(32767); |
|
|
|
} |
|
|
|
// Standard
|
|
|
|
if (IsStandardType(source)) |
|
|
|
{ |
|
|
|
return FromStandardType(target); |
|
|
|
} |
|
|
|
|
|
|
|
// Normalized offsets. All four components.
|
|
|
|
@ -78,6 +75,61 @@ namespace ImageSharp |
|
|
|
return Noop; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns the correct conversion function to convert from types having vector values representing all four components
|
|
|
|
/// ranging from 0 to 1.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="target">The target type</param>
|
|
|
|
/// <returns>The <see cref="Func{Vector4,Vector4}"/></returns>
|
|
|
|
private static Func<Vector4, Vector4> FromStandardNormalizedType(Type target) |
|
|
|
{ |
|
|
|
if (IsStandardType(target)) |
|
|
|
{ |
|
|
|
return vector4 => 255F * vector4; |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetNormalizedType(target) || IsOffsetTwoComponentNormalizedType(target)) |
|
|
|
{ |
|
|
|
// Expand the range then offset the center down.
|
|
|
|
return vector4 => (2F * vector4) - Vector4.One; |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetType(target) || IsOffsetTwoComponentType(target)) |
|
|
|
{ |
|
|
|
return vector4 => (65534F * vector4) - new Vector4(32767F); |
|
|
|
} |
|
|
|
|
|
|
|
return Noop; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns the correct conversion function to convert from types having vector values representing all four components
|
|
|
|
/// ranging from 0 to 255.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="target">The target type</param>
|
|
|
|
/// <returns>The <see cref="Func{Vector4,Vector4}"/></returns>
|
|
|
|
private static Func<Vector4, Vector4> FromStandardType(Type target) |
|
|
|
{ |
|
|
|
// Scale down
|
|
|
|
if (IsStandardNormalizedType(target)) |
|
|
|
{ |
|
|
|
return vector4 => vector4 / 255F; |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetNormalizedType(target) || IsOffsetTwoComponentNormalizedType(target)) |
|
|
|
{ |
|
|
|
// Expand the range, divide, then offset the center down.
|
|
|
|
return vector4 => ((2F * (vector4 / 255F)) - Vector4.One); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetType(target) || IsOffsetTwoComponentType(target)) |
|
|
|
{ |
|
|
|
return vector4 => (65534F * (vector4 / 255F)) - new Vector4(32767F); |
|
|
|
} |
|
|
|
|
|
|
|
return Noop; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns the correct conversion function to convert from types having vector values representing all four components
|
|
|
|
/// ranging from -1 to 1.
|
|
|
|
@ -92,6 +144,12 @@ namespace ImageSharp |
|
|
|
return vector4 => (vector4 / 2F) + new Vector4(.5F); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsStandardType(target)) |
|
|
|
{ |
|
|
|
// Compress the range, multiply, then offset the center up.
|
|
|
|
return vector4 => ((vector4 / 2F) * 255F) + new Vector4(127.5F); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetType(target) || IsOffsetTwoComponentType(target)) |
|
|
|
{ |
|
|
|
// Multiply out the range, two component won't read the last two values.
|
|
|
|
@ -112,13 +170,19 @@ namespace ImageSharp |
|
|
|
if (IsStandardNormalizedType(target)) |
|
|
|
{ |
|
|
|
// Compress the range then offset the center up.
|
|
|
|
return vector4 => (vector4 / 65534) + new Vector4(.5F); |
|
|
|
return vector4 => (vector4 / 65534F) + new Vector4(.5F); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsStandardType(target)) |
|
|
|
{ |
|
|
|
// Compress the range, multiply, then offset the center up.
|
|
|
|
return vector4 => ((vector4 / 65534F) * 255F) + new Vector4(127.5F); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetNormalizedType(target) || IsOffsetTwoComponentNormalizedType(target)) |
|
|
|
{ |
|
|
|
// Compress the range. Two component won't read the last two values.
|
|
|
|
return vector4 => (vector4 / 32767); |
|
|
|
return vector4 => (vector4 / 32767F); |
|
|
|
} |
|
|
|
|
|
|
|
return Noop; |
|
|
|
@ -138,20 +202,30 @@ namespace ImageSharp |
|
|
|
{ |
|
|
|
// Compress the range then offset the center up for first pair.
|
|
|
|
Vector4 v = (vector4 / 2F) + new Vector4(.5F); |
|
|
|
return new Vector4(v.X, v.Y, 0, 1); |
|
|
|
return new Vector4(v.X, v.Y, 0F, 1F); |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if (IsStandardType(target)) |
|
|
|
{ |
|
|
|
return vector4 => |
|
|
|
{ |
|
|
|
// Compress the range, multiply, then offset the center up for first pair.
|
|
|
|
Vector4 v = ((vector4 / 2F) * 255F) + new Vector4(127.5F); |
|
|
|
return new Vector4(v.X, v.Y, 0F, 255F); |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetNormalizedType(target)) |
|
|
|
{ |
|
|
|
// Copy the first two components and set second pair to 0 and 1 equivalent.
|
|
|
|
return vector4 => new Vector4(vector4.X, vector4.Y, -1, 1); |
|
|
|
return vector4 => new Vector4(vector4.X, vector4.Y, -1F, 1F); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetTwoComponentType(target)) |
|
|
|
{ |
|
|
|
// Multiply. Two component won't read the last two values.
|
|
|
|
return vector4 => (vector4 * 32767); |
|
|
|
return vector4 => (vector4 * 32767F); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetType(target)) |
|
|
|
@ -159,8 +233,8 @@ namespace ImageSharp |
|
|
|
return vector4 => |
|
|
|
{ |
|
|
|
// Multiply the first two components and set second pair to 0 and 1 equivalent.
|
|
|
|
Vector4 v = vector4 * 32767; |
|
|
|
return new Vector4(v.X, v.Y, -32767, 32767); |
|
|
|
Vector4 v = vector4 * 32767F; |
|
|
|
return new Vector4(v.X, v.Y, -32767F, 32767F); |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
@ -179,15 +253,24 @@ namespace ImageSharp |
|
|
|
{ |
|
|
|
return vector4 => |
|
|
|
{ |
|
|
|
Vector4 v = (vector4 / 65534) + new Vector4(.5F); |
|
|
|
Vector4 v = (vector4 / 65534F) + new Vector4(.5F); |
|
|
|
return new Vector4(v.X, v.Y, 0, 1); |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if (IsStandardType(target)) |
|
|
|
{ |
|
|
|
return vector4 => |
|
|
|
{ |
|
|
|
Vector4 v = ((vector4 / 65534F) * 255F) + new Vector4(127.5F); |
|
|
|
return new Vector4(v.X, v.Y, 0, 255F); |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetType(target)) |
|
|
|
{ |
|
|
|
// Copy the first two components and set second pair to 0 and 1 equivalent.
|
|
|
|
return vector4 => new Vector4(vector4.X, vector4.Y, -32767, 32767); |
|
|
|
return vector4 => new Vector4(vector4.X, vector4.Y, -32767F, 32767F); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetNormalizedType(target)) |
|
|
|
@ -195,15 +278,15 @@ namespace ImageSharp |
|
|
|
return vector4 => |
|
|
|
{ |
|
|
|
// Divide the first two components and set second pair to 0 and 1 equivalent.
|
|
|
|
Vector4 v = vector4 / 32767; |
|
|
|
return new Vector4(v.X, v.Y, -1, 1); |
|
|
|
Vector4 v = vector4 / 32767F; |
|
|
|
return new Vector4(v.X, v.Y, -1F, 1F); |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if (IsOffsetTwoComponentNormalizedType(target)) |
|
|
|
{ |
|
|
|
// Divide. Two component won't read the last two values.
|
|
|
|
return vector4 => (vector4 / 32767); |
|
|
|
return vector4 => (vector4 / 32767F); |
|
|
|
} |
|
|
|
|
|
|
|
return Noop; |
|
|
|
@ -217,10 +300,10 @@ namespace ImageSharp |
|
|
|
private static bool IsStandardNormalizedType(Type type) |
|
|
|
{ |
|
|
|
return type == typeof(Color) |
|
|
|
|| type == typeof(Alpha8) |
|
|
|
|| type == typeof(Bgr565) |
|
|
|
|| type == typeof(Bgra4444) |
|
|
|
|| type == typeof(Bgra5551) |
|
|
|
|| type == typeof(Byte4) |
|
|
|
|| type == typeof(HalfSingle) |
|
|
|
|| type == typeof(HalfVector2) |
|
|
|
|| type == typeof(HalfVector4) |
|
|
|
@ -229,6 +312,16 @@ namespace ImageSharp |
|
|
|
|| type == typeof(Rgba64); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Identifies the type as having vector component values ranging from 0 to 255.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="type">The type to test.</param>
|
|
|
|
/// <returns>The <see cref="bool"/></returns>
|
|
|
|
private static bool IsStandardType(Type type) |
|
|
|
{ |
|
|
|
return type == typeof(Byte4); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Identifies the type as having vector values representing the first component pair ranging from -1 to 1.
|
|
|
|
/// and the second component pair ranging from 0 to 1.
|
|
|
|
|