/// <inheritdoc/> public void ToBytes(byte[] bytes, int startIndex, ComponentOrder componentOrder) { switch (componentOrder) { case ComponentOrder.ZYX: bytes[startIndex] = this.B; bytes[startIndex + 1] = this.G; bytes[startIndex + 2] = this.R; break; case ComponentOrder.ZYXW: bytes[startIndex] = this.B; bytes[startIndex + 1] = this.G; bytes[startIndex + 2] = this.R; bytes[startIndex + 3] = this.A; break; case ComponentOrder.XYZ: bytes[startIndex] = this.R; bytes[startIndex + 1] = this.G; bytes[startIndex + 2] = this.B; break; case ComponentOrder.XYZW: bytes[startIndex] = this.R; bytes[startIndex + 1] = this.G; bytes[startIndex + 2] = this.B; bytes[startIndex + 3] = this.A; break; default: throw new NotSupportedException(); } }
public PixelRow(int width, ComponentOrder componentOrder, int padding) { this.Width = width; this.ComponentOrder = componentOrder; this.Data = new byte[(width * GetComponentCount(componentOrder)) + padding]; this.handle = GCHandle.Alloc(this.Data, GCHandleType.Pinned); this.DataPointer = (byte *)this.handle.AddrOfPinnedObject().ToPointer(); }
private void CheckBytesLength(int width, int height, byte[] bytes, ComponentOrder componentOrder) { int requiredLength = (width * GetComponentCount(componentOrder)) * height; if (bytes.Length != requiredLength) { throw new ArgumentOutOfRangeException(nameof(bytes), $"Invalid byte array length. Length {bytes.Length}; Should be {requiredLength}."); } }
/// <summary> /// Initializes a new instance of the <see cref="PixelArea{TColor}"/> class. /// </summary> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="componentOrder">The component order.</param> /// <param name="padding">The number of bytes to pad each row.</param> public PixelArea(int width, int height, ComponentOrder componentOrder, int padding) { this.Width = width; this.Height = height; this.ComponentOrder = componentOrder; this.RowStride = (width * GetComponentCount(componentOrder)) + padding; this.Length = this.RowStride * height; this.byteBuffer = new Buffer <byte>(this.Length); }
/// <summary> /// Initializes a new instance of the <see cref="PixelRow{TColor,TPacked}"/> class. /// </summary> /// <param name="width">The width. </param> /// <param name="componentOrder">The component order.</param> /// <param name="padding">The number of bytes to pad each row.</param> public PixelRow(int width, ComponentOrder componentOrder, int padding) { this.Width = width; this.ComponentOrder = componentOrder; this.Bytes = new byte[(width * GetComponentCount(componentOrder)) + padding]; this.pixelsHandle = GCHandle.Alloc(this.Bytes, GCHandleType.Pinned); // TODO: Why is Resharper warning us about an impure method call? this.dataPointer = this.pixelsHandle.AddrOfPinnedObject(); this.PixelBase = (byte *)this.dataPointer.ToPointer(); }
/// <summary> /// Initializes a new instance of the <see cref="PixelArea{TColor}"/> class. /// </summary> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="bytes">The bytes.</param> /// <param name="componentOrder">The component order.</param> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if <paramref name="bytes"></paramref> is the incorrect length. /// </exception> public PixelArea(int width, int height, byte[] bytes, ComponentOrder componentOrder) { this.CheckBytesLength(width, height, bytes, componentOrder); this.Width = width; this.Height = height; this.ComponentOrder = componentOrder; this.RowStride = width * GetComponentCount(componentOrder); this.Length = bytes.Length; // TODO: Is this the right value for Length? this.byteBuffer = new Buffer <byte>(bytes); }
/// <summary> /// Initializes a new instance of the <see cref="PixelArea{TColor}"/> class. /// </summary> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="componentOrder">The component order.</param> /// <param name="padding">The number of bytes to pad each row.</param> public PixelArea(int width, int height, ComponentOrder componentOrder, int padding) { this.Width = width; this.Height = height; this.ComponentOrder = componentOrder; this.RowStride = (width * GetComponentCount(componentOrder)) + padding; this.Length = this.RowStride * height; this.Bytes = BytesPool.Rent(this.Length); this.isBufferRented = true; this.pixelsHandle = GCHandle.Alloc(this.Bytes, GCHandleType.Pinned); // TODO: Why is Resharper warning us about an impure method call? this.dataPointer = this.pixelsHandle.AddrOfPinnedObject(); this.PixelBase = (byte *)this.dataPointer.ToPointer(); }
/// <summary> /// Gets component count for the given order. /// </summary> /// <param name="componentOrder">The component order.</param> /// <returns> /// The <see cref="int"/>. /// </returns> /// <exception cref="NotSupportedException"> /// Thrown if an invalid order is given. /// </exception> private static int GetComponentCount(ComponentOrder componentOrder) { switch (componentOrder) { case ComponentOrder.Zyx: case ComponentOrder.Xyz: return(3); case ComponentOrder.Zyxw: case ComponentOrder.Xyzw: return(4); } throw new NotSupportedException(); }
/// <summary> /// Gets component count for the given order. /// </summary> /// <param name="componentOrder">The component order.</param> /// <returns> /// The <see cref="int"/>. /// </returns> /// <exception cref="NotSupportedException"> /// Thrown if an invalid order is given. /// </exception> private static int GetComponentCount(ComponentOrder componentOrder) { switch (componentOrder) { case ComponentOrder.ZYX: case ComponentOrder.XYZ: return(3); case ComponentOrder.ZYXW: case ComponentOrder.XYZW: return(4); } throw new NotSupportedException(); }
/// <summary> /// Initializes a new instance of the <see cref="PixelArea{TColor,TPacked}"/> class. /// </summary> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="bytes">The bytes.</param> /// <param name="componentOrder">The component order.</param> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if <paramref name="bytes"></paramref> is the incorrect length. /// </exception> public PixelArea(int width, int height, byte[] bytes, ComponentOrder componentOrder) { this.CheckBytesLength(width, height, bytes, componentOrder); this.Width = width; this.Height = height; this.ComponentOrder = componentOrder; this.RowByteCount = width * GetComponentCount(componentOrder); this.Bytes = bytes; this.pixelsHandle = GCHandle.Alloc(this.Bytes, GCHandleType.Pinned); // TODO: Why is Resharper warning us about an impure method call? this.dataPointer = this.pixelsHandle.AddrOfPinnedObject(); this.PixelBase = (byte *)this.dataPointer.ToPointer(); }
private static int GetComponentCount(ComponentOrder componentOrder) { switch (componentOrder) { case ComponentOrder.BGR: case ComponentOrder.RGB: return(3); case ComponentOrder.BGRA: case ComponentOrder.RGBA: return(4); } throw new NotSupportedException(); }
/// <summary> /// Initializes a new instance of the <see cref="PixelRow{TColor,TPacked}"/> class. /// </summary> /// <param name="width">The width.</param> /// <param name="bytes">The bytes.</param> /// <param name="componentOrder">The component order.</param> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if <paramref name="bytes"></paramref> is the incorrect length. /// </exception> public PixelRow(int width, byte[] bytes, ComponentOrder componentOrder) { if (bytes.Length != width * GetComponentCount(componentOrder)) { throw new ArgumentOutOfRangeException($"Invalid byte array length. Length {bytes.Length}; Should be {width * GetComponentCount(componentOrder)}."); } this.Width = width; this.ComponentOrder = componentOrder; this.Bytes = bytes; this.pixelsHandle = GCHandle.Alloc(this.Bytes, GCHandleType.Pinned); // TODO: Why is Resharper warning us about an impure method call? this.dataPointer = this.pixelsHandle.AddrOfPinnedObject(); this.PixelBase = (byte *)this.dataPointer.ToPointer(); }
/// <inheritdoc /> public void ToBytes(byte[] bytes, int startIndex, ComponentOrder componentOrder) { Vector2 vector = this.ToVector2(); vector /= 65534; vector *= 255; vector += Half; vector += Round; vector = Vector2.Clamp(vector, Vector2.Zero, MaxBytes); switch (componentOrder) { case ComponentOrder.ZYX: bytes[startIndex] = 0; bytes[startIndex + 1] = (byte)(float)Math.Round(vector.Y); bytes[startIndex + 2] = (byte)(float)Math.Round(vector.X); break; case ComponentOrder.ZYXW: bytes[startIndex] = 0; bytes[startIndex + 1] = (byte)(float)Math.Round(vector.Y); bytes[startIndex + 2] = (byte)(float)Math.Round(vector.X); bytes[startIndex + 3] = 255; break; case ComponentOrder.XYZ: bytes[startIndex] = (byte)(float)Math.Round(vector.X); bytes[startIndex + 1] = (byte)(float)Math.Round(vector.Y); bytes[startIndex + 2] = 0; break; case ComponentOrder.XYZW: bytes[startIndex] = (byte)(float)Math.Round(vector.X); bytes[startIndex + 1] = (byte)(float)Math.Round(vector.Y); bytes[startIndex + 2] = 0; bytes[startIndex + 3] = 255; break; default: throw new NotSupportedException(); } }
/// <inheritdoc /> public void ToBytes(byte[] bytes, int startIndex, ComponentOrder componentOrder) { Vector4 vector = this.ToVector4(); vector *= Half; vector += Round; vector += Half; vector += Round; vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); switch (componentOrder) { case ComponentOrder.ZYX: bytes[startIndex] = (byte)vector.Z; bytes[startIndex + 1] = (byte)vector.Y; bytes[startIndex + 2] = (byte)vector.X; break; case ComponentOrder.ZYXW: bytes[startIndex] = (byte)vector.Z; bytes[startIndex + 1] = (byte)vector.Y; bytes[startIndex + 2] = (byte)vector.X; bytes[startIndex + 3] = (byte)vector.W; break; case ComponentOrder.XYZ: bytes[startIndex] = (byte)vector.X; bytes[startIndex + 1] = (byte)vector.Y; bytes[startIndex + 2] = (byte)vector.Z; break; case ComponentOrder.XYZW: bytes[startIndex] = (byte)vector.X; bytes[startIndex + 1] = (byte)vector.Y; bytes[startIndex + 2] = (byte)vector.Z; bytes[startIndex + 3] = (byte)vector.W; break; default: throw new NotSupportedException(); } }
/// <inheritdoc /> public void ToBytes(byte[] bytes, int startIndex, ComponentOrder componentOrder) { Vector4 vector = this.ToVector4() * 255F; switch (componentOrder) { case ComponentOrder.ZYX: bytes[startIndex] = (byte)(float)Math.Round(vector.Z); bytes[startIndex + 1] = (byte)(float)Math.Round(vector.Y); bytes[startIndex + 2] = (byte)(float)Math.Round(vector.X); break; case ComponentOrder.ZYXW: bytes[startIndex] = (byte)(float)Math.Round(vector.Z); bytes[startIndex + 1] = (byte)(float)Math.Round(vector.Y); bytes[startIndex + 2] = (byte)(float)Math.Round(vector.X); bytes[startIndex + 3] = (byte)(float)Math.Round(vector.W); break; case ComponentOrder.XYZ: bytes[startIndex] = (byte)(float)Math.Round(vector.X); bytes[startIndex + 1] = (byte)(float)Math.Round(vector.Y); bytes[startIndex + 2] = (byte)(float)Math.Round(vector.Z); break; case ComponentOrder.XYZW: bytes[startIndex] = (byte)(float)Math.Round(vector.X); bytes[startIndex + 1] = (byte)(float)Math.Round(vector.Y); bytes[startIndex + 2] = (byte)(float)Math.Round(vector.Z); bytes[startIndex + 3] = (byte)(float)Math.Round(vector.W); break; default: throw new NotSupportedException(); } }
/// <summary> /// Initializes a new instance of the <see cref="PixelRow{TColor,TPacked}"/> class. /// </summary> /// <param name="width">The width. </param> /// <param name="componentOrder">The component order.</param> public PixelRow(int width, ComponentOrder componentOrder) : this(width, componentOrder, 0) { }
public void CopyTo_Then_CopyFrom_OnFullImageRect <TColor, TPacked>(TestImageFactory <TColor, TPacked> factory, ComponentOrder order) where TColor : struct, IPackedPixel <TPacked> where TPacked : struct, IEquatable <TPacked> { var src = factory.Create(); var dest = new Image <TColor, TPacked>(src.Width, src.Height); using (PixelArea <TColor, TPacked> area = new PixelArea <TColor, TPacked>(src.Width, src.Height, order)) { using (var srcPixels = src.Lock()) { srcPixels.CopyTo(area, 0, 0); } using (var destPixels = dest.Lock()) { destPixels.CopyFrom(area, 0, 0); } } Assert.True(src.IsEquivalentTo(dest, false)); }
public void CopyTo_Then_CopyFrom_OnFullImageRect <TColor>(TestImageProvider <TColor> provider, ComponentOrder order) where TColor : struct, IPackedPixel, IEquatable <TColor> { var src = provider.GetImage(); var dest = new Image <TColor>(src.Width, src.Height); using (PixelArea <TColor> area = new PixelArea <TColor>(src.Width, src.Height, order)) { using (var srcPixels = src.Lock()) { srcPixels.CopyTo(area, 0, 0); } using (var destPixels = dest.Lock()) { destPixels.CopyFrom(area, 0, 0); } } Assert.True(src.IsEquivalentTo(dest, false)); }
public void CopyTo_Then_CopyFrom_WithOffset <TColor, TPacked>(TestImageFactory <TColor, TPacked> factory, ComponentOrder order) where TColor : struct, IPackedPixel <TPacked> where TPacked : struct, IEquatable <TPacked> { var srcImage = factory.Create(); var color = default(TColor); color.PackFromBytes(255, 0, 0, 255); Fill(srcImage, new Rectangle(4, 4, 8, 8), color); var destImage = new Image <TColor, TPacked>(8, 8); using (var srcPixels = srcImage.Lock()) { using (var area = new PixelArea <TColor, TPacked>(8, 8, order)) { srcPixels.CopyTo(area, 4, 4); using (var destPixels = destImage.Lock()) { destPixels.CopyFrom(area, 0, 0); } } } factory.Utility.SourceFileOrDescription = order.ToString(); factory.Utility.SaveTestOutputFile(destImage, "bmp"); var expectedImage = new Image <TColor, TPacked>(8, 8).Fill(color); Assert.True(destImage.IsEquivalentTo(expectedImage)); }
/// <summary> /// Initializes a new instance of the <see cref="PixelArea{TColor}"/> class. /// </summary> /// <param name="width">The width.</param> /// <param name="componentOrder">The component order.</param> public PixelArea(int width, ComponentOrder componentOrder) : this(width, 1, componentOrder, 0) { }
/// <summary> /// Initializes a new instance of the <see cref="PixelArea{TColor}"/> class. /// </summary> /// <param name="width">The width.</param> /// <param name="bytes">The bytes.</param> /// <param name="componentOrder">The component order.</param> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if <paramref name="bytes"></paramref> is the incorrect length. /// </exception> public PixelArea(int width, byte[] bytes, ComponentOrder componentOrder) : this(width, 1, bytes, componentOrder) { }
public void CopyToThenCopyFromWithOffset <TColor>(TestImageProvider <TColor> provider, ComponentOrder order) where TColor : struct, IPackedPixel, IEquatable <TColor> { using (Image <TColor> destImage = new Image <TColor>(8, 8)) { TColor color; using (Image <TColor> srcImage = provider.GetImage()) { color = default(TColor); color.PackFromBytes(255, 0, 0, 255); Fill(srcImage, new Rectangle(4, 4, 8, 8), color); using (PixelAccessor <TColor> srcPixels = srcImage.Lock()) { using (PixelArea <TColor> area = new PixelArea <TColor>(8, 8, order)) { srcPixels.CopyTo(area, 4, 4); using (PixelAccessor <TColor> destPixels = destImage.Lock()) { destPixels.CopyFrom(area, 0, 0); } } } } provider.Utility.SourceFileOrDescription = order.ToString(); provider.Utility.SaveTestOutputFile(destImage, "bmp"); using (Image <TColor> expectedImage = new Image <TColor>(8, 8).Fill(color)) { Assert.True(destImage.IsEquivalentTo(expectedImage)); } } }
public void CopyTo_Then_CopyFrom_OnFullImageRect <TPixel>(TestImageProvider <TPixel> provider, ComponentOrder order) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> src = provider.GetImage()) { using (Image <TPixel> dest = new Image <TPixel>(src.Width, src.Height)) { using (PixelArea <TPixel> area = new PixelArea <TPixel>(src.Width, src.Height, order)) { using (PixelAccessor <TPixel> srcPixels = src.Lock()) { srcPixels.CopyTo(area, 0, 0); } using (PixelAccessor <TPixel> destPixels = dest.Lock()) { destPixels.CopyFrom(area, 0, 0); } } Assert.True(src.IsEquivalentTo(dest, false)); } } }
/// <summary> /// Initializes a new instance of the <see cref="PixelArea{TColor}"/> class. /// </summary> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="componentOrder">The component order.</param> public PixelArea(int width, int height, ComponentOrder componentOrder) : this(width, height, componentOrder, 0) { }
public void CopyToThenCopyFromWithOffset <TPixel>(TestImageProvider <TPixel> provider, ComponentOrder order) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> destImage = new Image <TPixel>(8, 8)) { using (Image <TPixel> srcImage = provider.GetImage()) { Fill(srcImage, new Rectangle(4, 4, 8, 8), NamedColors <TPixel> .Red); using (PixelAccessor <TPixel> srcPixels = srcImage.Lock()) { using (PixelArea <TPixel> area = new PixelArea <TPixel>(8, 8, order)) { srcPixels.CopyTo(area, 4, 4); using (PixelAccessor <TPixel> destPixels = destImage.Lock()) { destPixels.CopyFrom(area, 0, 0); } } } } provider.Utility.SourceFileOrDescription = order.ToString(); provider.Utility.SaveTestOutputFile(destImage, "bmp"); using (Image <TPixel> expectedImage = new Image <TPixel>(8, 8).Fill(NamedColors <TPixel> .Red)) { Assert.True(destImage.IsEquivalentTo(expectedImage)); } } }
/// <summary> /// Initializes a new instance of the <see cref="PixelArea{TColor}"/> class. /// </summary> /// <param name="width">The width. </param> /// <param name="componentOrder">The component order.</param> /// <param name="padding">The number of bytes to pad each row.</param> public PixelArea(int width, ComponentOrder componentOrder, int padding) : this(width, 1, componentOrder, padding) { }