Browse Source

Fixes for Byte4

pull/33/head
James Jackson-South 9 years ago
parent
commit
b95a0eade1
  1. 6
      src/ImageSharp/Colors/PackedPixel/Byte4.cs
  2. 10
      src/ImageSharp/Colors/PackedPixel/HalfVector4.cs
  3. 139
      src/ImageSharp/Colors/PackedPixel/PackedPixelConverterHelper.cs
  4. 5
      tests/ImageSharp.Tests/Colors/PackedPixelTests.cs
  5. 17
      tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs

6
src/ImageSharp/Colors/PackedPixel/Byte4.cs

@ -91,13 +91,13 @@ namespace ImageSharp
/// <inheritdoc />
public void PackFromBytes(byte x, byte y, byte z, byte w)
{
this.PackFromVector4(new Vector4(x, y, z, w) / 255F);
this.PackFromVector4(new Vector4(x, y, z, w));
}
/// <inheritdoc />
public void ToBytes(byte[] bytes, int startIndex, ComponentOrder componentOrder)
{
Vector4 vector = this.ToVector4() * 255F;
Vector4 vector = this.ToVector4();
switch (componentOrder)
{
@ -174,4 +174,4 @@ namespace ImageSharp
return byte4 | byte3 | byte2 | byte1;
}
}
}
}

10
src/ImageSharp/Colors/PackedPixel/HalfVector4.cs

@ -32,8 +32,8 @@ namespace ImageSharp
/// <param name="w">The w-component.</param>
public HalfVector4(float x, float y, float z, float w)
{
var vector = new Vector4(x, y, z, w);
this.PackedValue = PackHelper(ref vector);
Vector4 vector = new Vector4(x, y, z, w);
this.PackedValue = Pack(ref vector);
}
/// <summary>
@ -42,7 +42,7 @@ namespace ImageSharp
/// <param name="vector">A vector containing the initial values for the components</param>
public HalfVector4(Vector4 vector)
{
this.PackedValue = PackHelper(ref vector);
this.PackedValue = Pack(ref vector);
}
/// <inheritdoc />
@ -85,7 +85,7 @@ namespace ImageSharp
/// <inheritdoc />
public void PackFromVector4(Vector4 vector)
{
this.PackedValue = PackHelper(ref vector);
this.PackedValue = Pack(ref vector);
}
/// <inheritdoc />
@ -170,7 +170,7 @@ namespace ImageSharp
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
/// <returns>The <see cref="ulong"/> containing the packed values.</returns>
private static ulong PackHelper(ref Vector4 vector)
private static ulong Pack(ref Vector4 vector)
{
ulong num4 = HalfTypeHelper.Pack(vector.X);
ulong num3 = (ulong)HalfTypeHelper.Pack(vector.Y) << 0x10;

139
src/ImageSharp/Colors/PackedPixel/PackedPixelConverterHelper.cs

@ -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.

5
tests/ImageSharp.Tests/Colors/PackedPixelTests.cs

@ -249,6 +249,11 @@ namespace ImageSharp.Tests.Colors
new Byte4(x, y, z, w).ToBytes(bgra, 0, ComponentOrder.ZYXW);
Assert.Equal(bgra, new byte[] { 0, 0, 128, 0 });
Byte4 r = new Byte4();
r.PackFromBytes(20, 38, 0, 255);
r.ToBytes(rgba, 0, ComponentOrder.XYZW);
Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 });
}
[Fact]

17
tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs

@ -54,6 +54,23 @@ namespace ImageSharp.Tests
{
Image image = file.CreateImage();
//var image = file.CreateImage()
// .To<Bgr565, ushort>()
// .To<Bgra4444, ushort>()
// .To<Bgra5551, ushort>()
// .To<Byte4, uint>()
// .To<HalfSingle, ushort>()
// .To<HalfVector2, uint>()
// .To<HalfVector4, ulong>()
// .To<Rg32, uint>()
// .To<Rgba1010102, uint>()
// .To<NormalizedByte2, ushort>()
// .To<NormalizedByte4, uint>()
// .To<NormalizedShort2, uint>()
// .To<NormalizedShort4, ulong>()
// .To<Short2, uint>()
// .To<Short4, ulong>();
// Image<Bgr565, ushort> image = file.CreateImage().To<Bgr565, ushort>();
// Image<Bgra4444, ushort> image = file.CreateImage().To<Bgra4444, ushort>();
// Image<Bgra5551, ushort> image = file.CreateImage().To<Bgra5551, ushort>();

Loading…
Cancel
Save