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
}
}