Browse Source

ImageRgba32

Former-commit-id: e8d174508130e99cb9152e3c6dad690232425075
Former-commit-id: 4191408f0e2678dfb6937918c46a0d588da073d7
Former-commit-id: 3dc34dfac9b7e02f3dca4e80b1d8cf41fe40ee35
af/merge-core
James Jackson-South 10 years ago
parent
commit
aa11973f2d
  1. 25
      GenericImage/ImageRgba32.cs
  2. 8
      GenericImage/PackedVectors/Rgba64.cs
  3. 148
      GenericImage/PixelAccessorRgba32.cs

25
GenericImage/ImageRgba32.cs

@ -0,0 +1,25 @@
namespace GenericImage
{
using GenericImage.PackedVectors;
public class ImageRgba32 : IImageBase<Rgba32>
{
public ImageRgba32(int width, int height)
{
this.Width = width;
this.Height = height;
this.Pixels = new Rgba32[width * height];
}
public Rgba32[] Pixels { get; }
public int Width { get; }
public int Height { get; }
public IPixelAccessor Lock()
{
return new PixelAccessorRgba32(this);
}
}
}

8
GenericImage/PackedVectors/Rgba64.cs

@ -84,9 +84,9 @@
public Vector4 ToVector4()
{
return new Vector4(
this.PackedValue & 0xFFFF,
(this.PackedValue >> 16) & 0xFFFF,
(this.PackedValue >> 32) & 0xFFFF,
(this.PackedValue >> 16) & 0xFFFF,
this.PackedValue & 0xFFFF,
(this.PackedValue >> 48) & 0xFFFF) / 65535f;
}
@ -140,9 +140,9 @@
/// </returns>
private static ulong Pack(ref Vector4 vector)
{
return (ulong)Math.Round(vector.X) |
return ((ulong)Math.Round(vector.Z) << 32) |
((ulong)Math.Round(vector.Y) << 16) |
((ulong)Math.Round(vector.Z) << 32) |
(ulong)Math.Round(vector.X) |
((ulong)Math.Round(vector.W) << 48);
}

148
GenericImage/PixelAccessorRgba32.cs

@ -0,0 +1,148 @@
namespace GenericImage
{
using System;
using System.Runtime.InteropServices;
using GenericImage.PackedVectors;
/// <summary>
/// Provides per-pixel access to an images pixels.
/// </summary>
public sealed unsafe class PixelAccessorRgba32 : IPixelAccessor
{
/// <summary>
/// The position of the first pixel in the bitmap.
/// </summary>
private Rgba32* pixelsBase;
/// <summary>
/// Provides a way to access the pixels from unmanaged memory.
/// </summary>
private GCHandle pixelsHandle;
/// <summary>
/// A value indicating whether this instance of the given entity has been disposed.
/// </summary>
/// <value><see langword="true"/> if this instance has been disposed; otherwise, <see langword="false"/>.</value>
/// <remarks>
/// If the entity is disposed, it must not be disposed a second
/// time. The isDisposed field is set the first time the entity
/// is disposed. If the isDisposed field is true, then the Dispose()
/// method will not dispose again. This help not to prolong the entity's
/// life in the Garbage Collector.
/// </remarks>
private bool isDisposed;
/// <summary>
/// Initializes a new instance of the <see cref="PixelAccessorRgba32"/> class.
/// </summary>
/// <param name="image">
/// The image to provide pixel access for.
/// </param>
public PixelAccessorRgba32(IImageBase<Rgba32> image)
{
//Guard.NotNull(image, nameof(image));
//Guard.MustBeGreaterThan(image.Width, 0, "image width");
//Guard.MustBeGreaterThan(image.Height, 0, "image height");
this.Width = image.Width;
this.Height = image.Height;
this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned);
this.pixelsBase = (Rgba32*)this.pixelsHandle.AddrOfPinnedObject().ToPointer();
}
/// <summary>
/// Finalizes an instance of the <see cref="PixelAccessorRgba32"/> class.
/// </summary>
~PixelAccessorRgba32()
{
this.Dispose();
}
/// <summary>
/// Gets the width of the image.
/// </summary>
public int Width { get; }
/// <summary>
/// Gets the height of the image.
/// </summary>
public int Height { get; }
/// <summary>
/// Gets or sets the color of a pixel at the specified position.
/// </summary>
/// <param name="x">
/// The x-coordinate of the pixel. Must be greater
/// than zero and smaller than the width of the pixel.
/// </param>
/// <param name="y">
/// The y-coordinate of the pixel. Must be greater
/// than zero and smaller than the width of the pixel.
/// </param>
/// <returns>The <see cref="IPackedVector"/> at the specified position.</returns>
public IPackedVector this[int x, int y]
{
get
{
#if DEBUG
if ((x < 0) || (x >= this.Width))
{
throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width.");
}
if ((y < 0) || (y >= this.Height))
{
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height.");
}
#endif
return *(this.pixelsBase + ((y * this.Width) + x));
}
set
{
#if DEBUG
if ((x < 0) || (x >= this.Width))
{
throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width.");
}
if ((y < 0) || (y >= this.Height))
{
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height.");
}
#endif
*(this.pixelsBase + ((y * this.Width) + x)) = (Rgba32)value;
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (this.isDisposed)
{
return;
}
if (this.pixelsHandle.IsAllocated)
{
this.pixelsHandle.Free();
}
this.pixelsBase = null;
// Note disposing is done.
this.isDisposed = true;
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SuppressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
}
}
Loading…
Cancel
Save