Browse Source

We might be getting somewhere.

Fix ToBytes ulong


Former-commit-id: 26d591aac6b99819a036f9667bf28685dad8ef4b
Former-commit-id: 5ecd391866013328fab1bb81ff0e7c7b73fa8054
Former-commit-id: 1127739e8a52cf1d1f5a5826c483511029785791
af/merge-core
James Jackson-South 10 years ago
parent
commit
86bbe9cdbb
  1. 8
      GenericImage/IImageBase.cs
  2. 8
      GenericImage/ImageRgba64.cs
  3. 6
      GenericImage/PackedVectors/IPackedVector.cs
  4. 155
      GenericImage/PackedVectors/Rgba32.cs
  5. 6
      GenericImage/PackedVectors/Rgba64.cs
  6. 25
      GenericImage/PixelAccessorRgba64.cs

8
GenericImage/IImageBase.cs

@ -1,9 +1,11 @@
namespace GenericImage
{
public interface IImageBase<T>
where T : struct
using GenericImage.PackedVectors;
public interface IImageBase<TPacked>
where TPacked : IPackedVector
{
T[] Pixels { get; }
TPacked[] Pixels { get; }
int Width { get; }

8
GenericImage/ImageRgba64.cs

@ -1,15 +1,17 @@
namespace GenericImage
{
public class ImageRgba64 : IImageBase<ulong>
using GenericImage.PackedVectors;
public class ImageRgba64 : IImageBase<Rgba64>
{
public ImageRgba64(int width, int height)
{
this.Width = width;
this.Height = height;
this.Pixels = new ulong[width * height * 4];
this.Pixels = new Rgba64[width * height];
}
public ulong[] Pixels { get; }
public Rgba64[] Pixels { get; }
public int Width { get; }

6
GenericImage/PackedVectors/IPackedVector.cs

@ -34,5 +34,11 @@
/// </summary>
/// <returns>The <see cref="Vector4"/>.</returns>
Vector4 ToVector4();
/// <summary>
/// Expands the packed representation into a <see cref="T:byte[]"/>.
/// </summary>
/// <returns>The <see cref="Vector4"/>.</returns>
byte[] ToBytes();
}
}

155
GenericImage/PackedVectors/Rgba32.cs

@ -0,0 +1,155 @@
namespace GenericImage.PackedVectors
{
using System;
using System.Numerics;
/// <summary>
/// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 255.
/// </summary>
public struct Rgba32 : IPackedVector<uint>, IEquatable<Rgba32>
{
/// <summary>
/// Initializes a new instance of the <see cref="Rgba32"/> struct.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
public Rgba32(float r, float g, float b, float a)
{
this.PackedValue = Pack(r, g, b, a);
}
/// <summary>
/// Initializes a new instance of the <see cref="Rgba32"/> struct.
/// </summary>
/// <param name="vector">
/// Vector containing the components for the packed vector.
/// </param>
public Rgba32(Vector4 vector)
{
this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
}
/// <inheritdoc/>
public uint PackedValue { get; set; }
/// <summary>
/// Compares two <see cref="Rgba32"/> objects for equality.
/// </summary>
/// <param name="left">
/// The <see cref="Rgba32"/> on the left side of the operand.
/// </param>
/// <param name="right">
/// The <see cref="Rgba32"/> on the right side of the operand.
/// </param>
/// <returns>
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
public static bool operator ==(Rgba32 left, Rgba32 right)
{
return left.PackedValue == right.PackedValue;
}
/// <summary>
/// Compares two <see cref="Rgba32"/> objects for equality.
/// </summary>
/// <param name="left">The <see cref="Rgba32"/> on the left side of the operand.</param>
/// <param name="right">The <see cref="Rgba32"/> on the right side of the operand.</param>
/// <returns>
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
public static bool operator !=(Rgba32 left, Rgba32 right)
{
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc/>
public void PackVector(Vector4 vector)
{
Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One);
this.PackedValue = Pack(clamped.X, clamped.Y, clamped.Z, clamped.W);
}
/// <inheritdoc/>
public Vector4 ToVector4()
{
return new Vector4(
((this.PackedValue >> 16) & 0xFF) / 255f,
((this.PackedValue >> 8) & 0xFF) / 255f,
(this.PackedValue & 0xFF) / 255f,
((this.PackedValue >> 24) & 0xFF) / 255f);
}
/// <inheritdoc/>
public byte[] ToBytes()
{
return new[]
{
(byte)((this.PackedValue >> 16) & 0xFF),
(byte)((this.PackedValue >> 8) & 0xFF),
(byte)(this.PackedValue & 0xFF),
(byte)((this.PackedValue >> 24) & 0xFF)
};
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
return (obj is Rgba32) && this.Equals((Rgba32)obj);
}
/// <inheritdoc/>
public bool Equals(Rgba32 other)
{
return this.PackedValue == other.PackedValue;
}
/// <summary>
/// Gets a string representation of the packed vector.
/// </summary>
/// <returns>A string representation of the packed vector.</returns>
public override string ToString()
{
return this.ToVector4().ToString();
}
/// <inheritdoc/>
public override int GetHashCode()
{
return this.GetHashCode(this);
}
/// <summary>
/// Sets the packed representation from the given component values.
/// </summary>
/// <param name="x">The x component.</param>
/// <param name="y">The y component.</param>
/// <param name="z">The z component.</param>
/// <param name="w">The w component.</param>
/// <returns>
/// The <see cref="uint"/>.
/// </returns>
private static uint Pack(float x, float y, float z, float w)
{
return ((uint)Math.Round(x * 255f) << 16) |
((uint)Math.Round(y * 255f) << 8) |
(uint)Math.Round(z * 255f) |
((uint)Math.Round(w * 255f) << 24);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <param name="packed">
/// The instance of <see cref="Rgba32"/> to return the hash code for.
/// </param>
/// <returns>
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
private int GetHashCode(Rgba32 packed)
{
return packed.PackedValue.GetHashCode();
}
}
}

6
GenericImage/PackedVectors/Rgba64.cs

@ -80,6 +80,12 @@
((this.PackedValue >> 48) & 0xFFFF) / 65535f);
}
/// <inheritdoc/>
public byte[] ToBytes()
{
throw new NotImplementedException();
}
/// <inheritdoc/>
public override bool Equals(object obj)
{

25
GenericImage/PixelAccessorRgba64.cs

@ -13,7 +13,7 @@
/// <summary>
/// The position of the first pixel in the bitmap.
/// </summary>
private ulong* pixelsBase;
private Rgba64* pixelsBase;
/// <summary>
/// Provides a way to access the pixels from unmanaged memory.
@ -39,30 +39,17 @@
/// <param name="image">
/// The image to provide pixel access for.
/// </param>
public PixelAccessorRgba64(IImageBase<ulong> image)
public PixelAccessorRgba64(IImageBase<Rgba64> image)
{
//Guard.NotNull(image, nameof(image));
//Guard.MustBeGreaterThan(image.Width, 0, "image width");
//Guard.MustBeGreaterThan(image.Height, 0, "image height");
int size = image.Pixels.Length;
this.Width = image.Width;
this.Height = image.Height;
// Assign the pointer.
// If buffer is allocated on Large Object Heap i.e > 85Kb, then we are going to pin it instead of making a copy.
if (size > 87040)
{
this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned);
this.pixelsBase = (ulong*)this.pixelsHandle.AddrOfPinnedObject().ToPointer();
}
else
{
fixed (ulong* pbuffer = image.Pixels)
{
this.pixelsBase = pbuffer;
}
}
this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned);
this.pixelsBase = (Rgba64*)this.pixelsHandle.AddrOfPinnedObject().ToPointer();
}
/// <summary>
@ -110,7 +97,7 @@
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height.");
}
#endif
return *((Rgba64*)(this.pixelsBase + (((y * this.Width) + x) * 4)));
return *(this.pixelsBase + ((y * this.Width) + x));
}
set
@ -126,7 +113,7 @@
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height.");
}
#endif
*(Rgba64*)(this.pixelsBase + (((y * this.Width) + x) * 4)) = (Rgba64)value;
*(this.pixelsBase + ((y * this.Width) + x)) = (Rgba64)value;
}
}

Loading…
Cancel
Save