using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.RemoteDesktop.Utils; namespace Tango.RemoteDesktop.Frames { /// /// Represents a vector frame encapsulating a set of . /// /// public class VectorFrame : Frame { private int _width; /// /// Gets the frame width. /// public override int Width { get { return _width; } } private int _height; /// /// Gets the frame height. /// public override int Height { get { return _height; } } /// /// Gets or sets the colors dictionary. /// public Dictionary Colors { get; set; } /// /// Gets the pixels. /// /// /// The pixels. /// public List Pixels { get; private set; } /// /// Initializes a new instance of the class. /// /// The frame width. /// The frame height. public VectorFrame(int width, int height) { _width = width; _height = height; Pixels = new List(); Colors = new Dictionary(); } /// /// Returns a GDI bitmap representing the frame. /// /// public override Bitmap ToBitmap() { DirectBitmap directBitmap = new DirectBitmap(Width, Height); foreach (var pixel in Pixels) { directBitmap.SetPixel((int)pixel.X, (int)pixel.Y, pixel.Color.ToColor()); } directBitmap.Dispose(); return directBitmap.Bitmap; } /// /// Applies this frame onto an existing bitmap. /// /// The bitmap. public override void Apply(Bitmap bitmap) { using (FastBitmap fast = bitmap.FastLock()) { foreach (var pixel in Pixels) { fast.SetPixel((int)pixel.X, (int)pixel.Y, pixel.Color.ToColor()); } } } /// /// Returns a byte array containing the binary serialized version of this frame. /// /// public byte[] Serialize() { using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(ms)) { writer.Write((UInt16)Width); writer.Write((UInt16)Height); writer.Write((UInt16)Colors.Count); if (Colors.Count > UInt16.MaxValue) { throw new InvalidOperationException("Number of color exceeded the maximum colors allowed."); } foreach (var color in Colors) { writer.Write(color.Value.R); writer.Write(color.Value.G); writer.Write(color.Value.B); } foreach (var pixel in Pixels) { writer.Write((UInt16)pixel.X); writer.Write((UInt16)pixel.ColorIndex); } ms.Position = 0; return ms.ToArray(); } } } /// /// Calculates the size of byte output. /// /// public int CalculateSize() { int size = 0; size += sizeof(int) * 3; //Width, Height, Count size += sizeof(ushort) * 2 * Pixels.Count; //X, Y size += sizeof(byte) * 3 * Pixels.Count; //RGB return size; } /// /// Creates a new instance of from the specified serialized byte array. /// /// The byte array. /// public static VectorFrame Deserialize(byte[] data) { using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader reader = new BinaryReader(ms)) { ms.Position = 0; var vector = new VectorFrame(reader.ReadUInt16(), reader.ReadUInt16()); int colorCount = reader.ReadUInt16(); //Number of colors in color table. for (int i = 0; i < colorCount; i++) { VectorFrameColor color = new VectorFrameColor() { R = reader.ReadByte(), G = reader.ReadByte(), B = reader.ReadByte(), Index = i, }; vector.Colors.Add(color.ToInt32(), color); } for (int i = 0; i < vector.Height; i++) { VectorFramePixel pixel = new VectorFramePixel(); pixel.X = reader.ReadUInt16(); pixel.Y = i; pixel.ColorIndex = reader.ReadUInt16(); pixel.Color = vector.Colors.ElementAt(pixel.ColorIndex).Value; vector.Pixels.Add(pixel); } return vector; } } } /// /// Releases unmanaged and - optionally - managed resources. /// public override void Dispose() { Pixels.Clear(); Pixels = null; } #region Color Helpers /// /// Converts the specified color to integer. /// /// The color. /// public static int ColorToInteger(byte r, byte g, byte b) { return (int)((255 << 24) | (r << 16) | (g << 8) | (b << 0)); } /// /// Converts the specified integer to color. /// /// The integer. /// public static Color IntegerToColor(int integer) { byte a = (byte)(integer >> 24); byte r = (byte)(integer >> 16); byte g = (byte)(integer >> 8); byte b = (byte)(integer >> 0); return Color.FromArgb(a, r, g, b); } #endregion } }