remove unnecessary classes to decrease stub size
This commit is contained in:
NYAN CAT 2019-05-07 00:41:52 -07:00
parent e0af8a63aa
commit 953140bbbf
58 changed files with 67 additions and 9370 deletions

View File

@ -147,35 +147,12 @@
<Compile Include="Settings.cs" /> <Compile Include="Settings.cs" />
<Compile Include="Socket\Clients.cs" /> <Compile Include="Socket\Clients.cs" />
<Compile Include="Socket\Listener.cs" /> <Compile Include="Socket\Listener.cs" />
<Compile Include="StreamLibrary\Codecs\DirectDriverCodec.cs" />
<Compile Include="StreamLibrary\Codecs\MJPGCodec.cs" />
<Compile Include="StreamLibrary\Codecs\QuickCachedStreamCodec.cs" />
<Compile Include="StreamLibrary\Codecs\QuickStreamCodec.cs" />
<Compile Include="StreamLibrary\Codecs\SmallCachedStreamCodec.cs" />
<Compile Include="StreamLibrary\Codecs\SmallStreamCodec.cs" />
<Compile Include="StreamLibrary\Encoders\GridCoder\GridBlock.cs" />
<Compile Include="StreamLibrary\Encoders\GridCoder\GridEncoder.cs" />
<Compile Include="StreamLibrary\Enums.cs" /> <Compile Include="StreamLibrary\Enums.cs" />
<Compile Include="StreamLibrary\IEncoder.cs" />
<Compile Include="StreamLibrary\IUnsafeCodec.cs" /> <Compile Include="StreamLibrary\IUnsafeCodec.cs" />
<Compile Include="StreamLibrary\IVideoCodec.cs" /> <Compile Include="StreamLibrary\IVideoCodec.cs" />
<Compile Include="StreamLibrary\src\CRC32.cs" />
<Compile Include="StreamLibrary\src\ExtensionAttribute.cs" />
<Compile Include="StreamLibrary\src\Extentions.cs" />
<Compile Include="StreamLibrary\src\FastBitmap.cs" />
<Compile Include="StreamLibrary\src\JpgCompression.cs" /> <Compile Include="StreamLibrary\src\JpgCompression.cs" />
<Compile Include="StreamLibrary\src\LzwCompression.cs" /> <Compile Include="StreamLibrary\src\LzwCompression.cs" />
<Compile Include="StreamLibrary\src\MurmurHash2Unsafe.cs" />
<Compile Include="StreamLibrary\src\NativeMethods.cs" /> <Compile Include="StreamLibrary\src\NativeMethods.cs" />
<Compile Include="StreamLibrary\src\PayloadWriter.cs" />
<Compile Include="StreamLibrary\src\PointerHelper.cs" />
<Compile Include="StreamLibrary\src\SafeQuickLZ.cs" />
<Compile Include="StreamLibrary\src\SimpleBitmap.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeCacheCodec.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeCachedStreamCodec.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeMiniCodec.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeOptimizedCodec.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeQuickStream.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeStreamCodec.cs" /> <Compile Include="StreamLibrary\UnsafeCodecs\UnsafeStreamCodec.cs" />
<EmbeddedResource Include="Forms\FormAbout.resx"> <EmbeddedResource Include="Forms\FormAbout.resx">
<DependentUpon>FormAbout.cs</DependentUpon> <DependentUpon>FormAbout.cs</DependentUpon>

View File

@ -41,7 +41,7 @@ namespace AsyncRAT_Sharp
{ {
if (!File.Exists(Path.Combine(Application.StartupPath, Path.GetFileName(Application.ExecutablePath) + ".config"))) if (!File.Exists(Path.Combine(Application.StartupPath, Path.GetFileName(Application.ExecutablePath) + ".config")))
{ {
File.WriteAllText(Path.Combine(Application.StartupPath, Path.GetFileName(Application.ExecutablePath) + ".config"), Properties.Resources.AsyncRAT_Sharp_exe); File.WriteAllText(Path.Combine(Application.StartupPath, Path.GetFileName(Application.ExecutablePath) + ".config"), Properties.Resources.AsyncRAT_Sharp_exe);
Process.Start(Application.ExecutablePath); Process.Start(Application.ExecutablePath);
Environment.Exit(0); Environment.Exit(0);
} }
@ -56,7 +56,7 @@ namespace AsyncRAT_Sharp
Directory.CreateDirectory(Path.Combine(Application.StartupPath, "Stub")); Directory.CreateDirectory(Path.Combine(Application.StartupPath, "Stub"));
if (!File.Exists(Path.Combine(Application.StartupPath, "Stub\\Stub.exe"))) if (!File.Exists(Path.Combine(Application.StartupPath, "Stub\\Stub.exe")))
File.WriteAllBytes(Path.Combine(Application.StartupPath, "Stub\\Stub.exe"), Properties.Resources.Stub); MessageBox.Show("Stub Not Found");
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -67,6 +67,11 @@ namespace AsyncRAT_Sharp
private async void Form1_Load(object sender, EventArgs e) private async void Form1_Load(object sender, EventArgs e)
{ {
Text = $"{Settings.Version}"; Text = $"{Settings.Version}";
#if DEBUG
Settings.Port = "6606";
Settings.Password = "NYAN CAT";
Settings.AES = new Aes256(Settings.Password);
#else
using (FormPorts portsFrm = new FormPorts()) using (FormPorts portsFrm = new FormPorts())
{ {
portsFrm.ShowDialog(); portsFrm.ShowDialog();
@ -74,6 +79,8 @@ namespace AsyncRAT_Sharp
Settings.Password = portsFrm.textPassword.Text; Settings.Password = portsFrm.textPassword.Text;
Settings.AES = new Aes256(Settings.Password); Settings.AES = new Aes256(Settings.Password);
} }
#endif
await Methods.FadeIn(this, 5); await Methods.FadeIn(this, 5);
trans = true; trans = true;

View File

@ -254,16 +254,6 @@ namespace AsyncRAT_Sharp.Properties {
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] Stub {
get {
object obj = ResourceManager.GetObject("Stub", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary> /// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap. /// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary> /// </summary>

View File

@ -136,9 +136,6 @@
<data name="cGeoIp" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="cGeoIp" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\cGeoIp.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>..\Resources\cGeoIp.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
<data name="AsyncRAT_Sharp_exe" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\AsyncRAT-Sharp.exe.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="botkiller" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="botkiller" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\botkiller.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\botkiller.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
@ -181,13 +178,13 @@
<data name="msgbox" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="msgbox" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\msgbox.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\msgbox.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="Stub" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Stub.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="visit" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="visit" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\visit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\visit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="settings" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="settings" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="AsyncRAT_Sharp_exe" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\AsyncRAT-Sharp.exe.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root> </root>

View File

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration>

View File

@ -184,21 +184,24 @@ namespace AsyncRAT_Sharp.Sockets
{ {
lock (SendSync) lock (SendSync)
{ {
try lock (EndSendSync)
{ {
MsgPack msgpack = new MsgPack(); try
msgpack.ForcePathObject("Packet").AsString = "Ping"; {
msgpack.ForcePathObject("Message").AsString = "This is a ping!"; MsgPack msgpack = new MsgPack();
byte[] buffer = Settings.AES.Encrypt(msgpack.Encode2Bytes()); msgpack.ForcePathObject("Packet").AsString = "Ping";
byte[] buffersize = BitConverter.GetBytes(buffer.Length); msgpack.ForcePathObject("Message").AsString = "This is a ping!";
ClientSocket.Poll(-1, SelectMode.SelectWrite); byte[] buffer = Settings.AES.Encrypt(msgpack.Encode2Bytes());
ClientSocket.Send(buffersize, 0, buffersize.Length, SocketFlags.None); byte[] buffersize = BitConverter.GetBytes(buffer.Length);
ClientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None); ClientSocket.Poll(-1, SelectMode.SelectWrite);
} ClientSocket.Send(buffersize, 0, buffersize.Length, SocketFlags.None);
catch ClientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None);
{ }
Disconnected(); catch
return; {
Disconnected();
return;
}
} }
} }

View File

@ -1,160 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class DirectDriverCodec
{
private Bitmap decodedBitmap;
private byte[] EncodeBuffer;
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private JpgCompression jpgCompression;
public DirectDriverCodec(int Quality)
{
jpgCompression = new JpgCompression(Quality);
}
public unsafe void CodeImage(IntPtr Scan0, Rectangle[] Changes, Size ImageSize, PixelFormat Format, Stream outStream)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
Stride = ImageSize.Width * PixelSize;
RawLength = Stride * ImageSize.Height;
if (EncodeBuffer == null)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
this.EncodeBuffer = new byte[RawLength];
fixed (byte* ptr = EncodeBuffer)
{
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
}
return;
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
for (int i = 0; i < Changes.Length; i++)
{
Rectangle rect = Changes[i];
int blockStride = PixelSize * rect.Width;
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
}
public Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
return decodedBitmap;
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
}
}

View File

@ -1,68 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
/// <summary>
/// The M-JPG codec is not very efficient for networking as it is just a very simple codec
/// </summary>
public class MJPGCodec : IVideoCodec
{
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override ulong CachedSize
{
get { return 0; }
internal set { }
}
public override int BufferCount
{
get { return 0; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.None; }
}
public MJPGCodec(int ImageQuality = 100)
: base(ImageQuality)
{
}
public override void CodeImage(Bitmap bitmap, Stream outStream)
{
lock (base.jpgCompression)
{
byte[] data = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(data.Length), 0, 4);
outStream.Write(data, 0, data.Length);
}
}
public override Bitmap DecodeData(Stream inStream)
{
lock (base.jpgCompression)
{
if (!inStream.CanRead)
throw new Exception("Must have access to Read in the Stream");
byte[] temp = new byte[4];
inStream.Read(temp, 0, temp.Length);
int DataLength = BitConverter.ToInt32(temp, 0);
temp = new byte[DataLength];
inStream.Read(temp, 0, temp.Length);
return (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
}
}
}
}

View File

@ -1,204 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class QuickCachedStreamCodec : IVideoCodec
{
private Bitmap CodeTempBitmap;
private Bitmap DecodeTempBitmap;
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override ulong CachedSize
{
get;
internal set;
}
public int MaxBuffers { get; private set; }
private SortedList<int, byte[]> EncodeCache;
private SortedList<int, byte[]> DecodeCache;
/// <summary>
/// Initialize a new object of QuickStreamCodec
/// </summary>
/// <param name="ImageQuality">The image quality 0-100%</param>
public QuickCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100)
: base(ImageQuality)
{
this.MaxBuffers = MaxBuffers;
this.EncodeCache = new SortedList<int, byte[]>();
this.DecodeCache = new SortedList<int, byte[]>();
}
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.RequireSameSize | CodecOption.AutoDispose; }
}
public override unsafe void CodeImage(Bitmap bitmap, Stream outStream)
{
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
if (CodeTempBitmap != null)
{
if (CodeTempBitmap.Width != bitmap.Width || CodeTempBitmap.Height != bitmap.Height)
throw new Exception("Bitmap width/height are not equal to previous bitmap");
if (bitmap.PixelFormat != CodeTempBitmap.PixelFormat)
throw new Exception("PixelFormat is not equal to previous Bitmap");
}
if (CodeTempBitmap == null)
{
byte[] temp = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
CodeTempBitmap = bitmap;
return;
}
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
BitmapData CodeBmpData = CodeTempBitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
int Stride = Math.Abs(bmpData.Stride);
List<Rectangle> Blocks = new List<Rectangle>();
for (int y = 0, i = 0; y < bitmap.Height; y++, i += Stride)
{
if (onCodeDebugScan != null)
onCodeDebugScan(new Rectangle(0, y, bitmap.Width, 1));
Rectangle ScanBlock = new Rectangle(0, y, bitmap.Width, 1);
if (NativeMethods.memcmp(new IntPtr(bmpData.Scan0.ToInt32() + i), new IntPtr(CodeBmpData.Scan0.ToInt32() + i), (uint)Stride) != 0)
{
byte[] temp = new byte[Stride];
fixed(byte* ptr = temp)
{
NativeMethods.memcpy(ptr, (void*)(bmpData.Scan0.ToInt32() + i), (uint)temp.Length);
}
CRC32 hasher = new CRC32();
int hash = BitConverter.ToInt32(hasher.ComputeHash(temp), 0);
if (EncodeCache.Count >= MaxBuffers)
EncodeCache.RemoveAt(0);
if (EncodeCache.ContainsKey(hash))
{
outStream.WriteByte(1);
outStream.Write(new byte[4], 0, 4);
outStream.Write(BitConverter.GetBytes(hash), 0, 4);
outStream.Write(BitConverter.GetBytes((ushort)y), 0, 2);
}
else
{
outStream.WriteByte(0);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(BitConverter.GetBytes(hash), 0, 4);
outStream.Write(BitConverter.GetBytes((ushort)y), 0, 2);
outStream.Write(temp, 0, temp.Length);
EncodeCache.Add(hash, temp);
}
Blocks.Add(ScanBlock);
}
}
for (int i = 0; i < Blocks.Count; i++)
{
Bitmap cloned = (Bitmap)bitmap.Clone(Blocks[i], bitmap.PixelFormat);
byte[] temp = base.jpgCompression.Compress(cloned);
cloned.Dispose();
}
bitmap.UnlockBits(bmpData);
CodeTempBitmap.UnlockBits(CodeBmpData);
if (onVideoStreamCoding != null)
onVideoStreamCoding(outStream, Blocks.ToArray());
if (CodeTempBitmap != null)
CodeTempBitmap.Dispose();
this.CodeTempBitmap = bitmap;
}
public override Bitmap DecodeData(Stream inStream)
{
if (!inStream.CanRead)
throw new Exception("Must have access to Read in the Stream");
if (DecodeTempBitmap == null)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
DecodeTempBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return DecodeTempBitmap;
}
//BitmapData BmpData = DecodeTempBitmap.LockBits(new Rectangle(0, 0, DecodeTempBitmap.Width, DecodeTempBitmap.Height), ImageLockMode.WriteOnly, DecodeTempBitmap.PixelFormat);
//int Stride = Math.Abs(BmpData.Stride);
while (inStream.Position < inStream.Length)
{
byte[] temp = new byte[11];
if (inStream.Read(temp, 0, temp.Length) != temp.Length)
break;
bool inCache = temp[0] == 1;
int DataSize = BitConverter.ToInt32(temp, 1);
int Hash = BitConverter.ToInt32(temp, 5);
ushort Y = BitConverter.ToUInt16(temp, 9);
temp = new byte[DataSize];
if (inStream.Read(temp, 0, temp.Length) != temp.Length)
break;
if (inCache)
{
if (DecodeCache.ContainsKey(Hash))
{
temp = DecodeCache[Hash];
}
else
{
}
}
//copy new data to cached bitmap
Bitmap tmpBmp = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
using (Graphics g = Graphics.FromImage(DecodeTempBitmap))
{
g.DrawImage(tmpBmp, new Point(0, Y));
}
/*BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.WriteOnly, tmpBmp.PixelFormat);
int Offset = Y * Stride;
NativeMethods.memcpy(new IntPtr(BmpData.Scan0.ToInt32() + Offset), tmpData.Scan0, (uint)(tmpBmp.Height * Stride));*/
//tmpBmp.UnlockBits(tmpData);
tmpBmp.Dispose();
}
//DecodeTempBitmap.UnlockBits(BmpData);
return DecodeTempBitmap;
}
}
}

View File

@ -1,179 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class QuickStreamCodec : IVideoCodec
{
private Bitmap CodeTempBitmap;
private Bitmap DecodeTempBitmap;
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override ulong CachedSize
{
get;
internal set;
}
/// <summary>
/// Initialize a new object of QuickStreamCodec
/// </summary>
/// <param name="ImageQuality">The image quality 0-100%</param>
public QuickStreamCodec(int ImageQuality = 100)
: base(ImageQuality)
{
}
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.RequireSameSize | CodecOption.AutoDispose; }
}
public override void CodeImage(Bitmap bitmap, Stream outStream)
{
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
if (CodeTempBitmap != null)
{
if (CodeTempBitmap.Width != bitmap.Width || CodeTempBitmap.Height != bitmap.Height)
throw new Exception("Bitmap width/height are not equal to previous bitmap");
if (bitmap.PixelFormat != CodeTempBitmap.PixelFormat)
throw new Exception("PixelFormat is not equal to previous Bitmap");
}
if (CodeTempBitmap == null)
{
byte[] temp = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
CodeTempBitmap = bitmap;
return;
}
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
BitmapData CodeBmpData = CodeTempBitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
int Stride = Math.Abs(bmpData.Stride);
List<Rectangle> Blocks = new List<Rectangle>();
for (int y = 0, i = 0; y < bitmap.Height; y++, i += Stride)
{
if(onCodeDebugScan != null)
onCodeDebugScan(new Rectangle(0, y, bitmap.Width, 1));
Rectangle ScanBlock = new Rectangle(0, y, bitmap.Width, 1);
if (NativeMethods.memcmp(new IntPtr(bmpData.Scan0.ToInt32() + i), new IntPtr(CodeBmpData.Scan0.ToInt32() + i), (uint)Stride) != 0)
{
int index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == ScanBlock.Y)
{
ScanBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + ScanBlock.Height);
Blocks[index] = ScanBlock;
}
else
{
Blocks.Add(ScanBlock);
}
}
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
for (int i = 0; i < Blocks.Count; i++)
{
Bitmap cloned = (Bitmap)bitmap.Clone(Blocks[i], bitmap.PixelFormat);
byte[] temp = base.jpgCompression.Compress(cloned);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(BitConverter.GetBytes((ushort)Blocks[i].Y), 0, 2);
outStream.Write(temp, 0, temp.Length);
cloned.Dispose();
TotalDataLength += 6 + temp.Length;
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
bitmap.UnlockBits(bmpData);
CodeTempBitmap.UnlockBits(CodeBmpData);
if (onVideoStreamCoding != null)
onVideoStreamCoding(outStream, Blocks.ToArray());
if (CodeTempBitmap != null)
CodeTempBitmap.Dispose();
this.CodeTempBitmap = bitmap;
}
public override Bitmap DecodeData(Stream inStream)
{
if (!inStream.CanRead)
throw new Exception("Must have access to Read in the Stream");
if (DecodeTempBitmap == null)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 4);
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
DecodeTempBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return DecodeTempBitmap;
}
byte[] LenTemp = new byte[4];
inStream.Read(LenTemp, 0, 4);
int DataLength = BitConverter.ToInt32(LenTemp, 0);
//BitmapData BmpData = DecodeTempBitmap.LockBits(new Rectangle(0, 0, DecodeTempBitmap.Width, DecodeTempBitmap.Height), ImageLockMode.WriteOnly, DecodeTempBitmap.PixelFormat);
//int Stride = Math.Abs(BmpData.Stride);
while (DataLength > 0)
{
byte[] temp = new byte[6];
if (inStream.Read(temp, 0, temp.Length) != temp.Length)
break;
int DataSize = BitConverter.ToInt32(temp, 0);
ushort Y = BitConverter.ToUInt16(temp, 4);
temp = new byte[DataSize];
if (inStream.Read(temp, 0, temp.Length) != temp.Length)
break;
//copy new data to cached bitmap
Bitmap tmpBmp = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
using (Graphics g = Graphics.FromImage(DecodeTempBitmap))
{
g.DrawImage(tmpBmp, new Point(0, Y));
}
/*BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.WriteOnly, tmpBmp.PixelFormat);
int Offset = Y * Stride;
NativeMethods.memcpy(new IntPtr(BmpData.Scan0.ToInt32() + Offset), tmpData.Scan0, (uint)(tmpBmp.Height * Stride));*/
//tmpBmp.UnlockBits(tmpData);
tmpBmp.Dispose();
DataLength -= 6 + temp.Length;
}
//DecodeTempBitmap.UnlockBits(BmpData);
return DecodeTempBitmap;
}
}
}

View File

@ -1,374 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class SmallCachedStreamCodec : IVideoCodec
{
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
SortedList<int, byte[]> codeCached;
SortedList<int, byte[]> decodeCached;
public override int BufferCount
{
get { return codeCached.Count; }
}
public override ulong CachedSize
{
get;
internal set;
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.HasBuffers | CodecOption.RequireSameSize; }
}
private Size CheckBlock { get; set; }
public SimpleBitmap LastFrame { get; set; }
private object ImageProcessLock = new object();
private Bitmap decodedBitmap;
private CRC32 hasher;
public int MaxBuffers { get; private set; }
/// <summary>
/// Initialize a new object of SmallCachedStreamCodec
/// </summary>
/// <param name="MaxBuffers">The maximum amount of buffers, higher value will decrease stream size but could decrease performance</param>
/// <param name="ImageQuality">The image quality 0-100%</param>
public SmallCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100)
: base(ImageQuality)
{
CheckBlock = new Size(20, 1);
codeCached = new SortedList<int, byte[]>();
decodeCached = new SortedList<int, byte[]>();
hasher = new CRC32();
this.MaxBuffers = MaxBuffers;
}
private void SetLastFrame(ref Bitmap bmp)
{
SetLastFrame(new SimpleBitmap(bmp));
}
private void SetLastFrame(SimpleBitmap bmp)
{
lock (ImageProcessLock)
{
if (LastFrame != null && LastFrame.Locked)
LastFrame.Dispose(true);
LastFrame = bmp;
}
}
public override unsafe void CodeImage(Bitmap bitmap, Stream outStream)
{
lock (ImageProcessLock)
{
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
if (LastFrame == null)
{
byte[] temp = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
SetLastFrame(ref bitmap);
return;
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<byte[]> updates = new List<byte[]>();
SimpleBitmap sbBmp = new SimpleBitmap(bitmap);
MemoryStream ms = new MemoryStream();
byte[] buffer = null;
if (!LastFrame.Locked)
LastFrame.Lock();
sbBmp.Lock();
if (sbBmp.Info.PixelSize != LastFrame.Info.PixelSize)
throw new Exception("PixelFormat is not equal to previous Bitmap");
if (LastFrame.Info.Width != sbBmp.Info.Width || LastFrame.Info.Height != sbBmp.Info.Height)
{
sbBmp.Unlock();
throw new Exception("Bitmap width/height are not equal to previous bitmap");
}
List<Rectangle> Blocks = new List<Rectangle>();
int index = 0;
int y = 0;
int x = 0;
Size s = new Size(bitmap.Width, CheckBlock.Height);
Size lastSize = new Size(bitmap.Width % CheckBlock.Width, bitmap.Height % CheckBlock.Height);
int lasty = bitmap.Height - lastSize.Height;
int lastx = bitmap.Width - lastSize.Width;
Rectangle cBlock = new Rectangle();
s = new Size(bitmap.Width, s.Height);
while (y != bitmap.Height)
{
if (y == lasty)
s = new Size(bitmap.Width, lastSize.Height);
cBlock = new Rectangle(0, y, bitmap.Width, s.Height);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (!SimpleBitmap.Compare(cBlock, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info))
//if (!SimpleBitmap.Compare(y, s.Height, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info))
{
index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
{
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
Blocks[index] = cBlock;
}
else
{
Blocks.Add(cBlock);
}
}
y += s.Height;
}
List<CacheInfo> finalUpdates = new List<CacheInfo>();
const int CheckHeight = 50;
for (int i = 0; i < Blocks.Count; i++)
{
s = new Size(CheckBlock.Width, Blocks[i].Height);
y = Blocks[i].Y;
lasty = (Blocks[i].Y + Blocks[i].Height);
while (y != lasty)
{
int ScanHeight = y + CheckHeight > lasty ? lasty - y : CheckHeight;
x = 0;
while (x != bitmap.Width)
{
if (x == lastx)
s = new Size(lastSize.Width, Blocks[i].Height);
cBlock = new Rectangle(x, y, s.Width, ScanHeight);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (!SimpleBitmap.Compare(cBlock, sbBmp.Scan0_int, LastFrame.Scan0_int, sbBmp.Info))
{
/*byte[] tempData = new byte[0];
LastFrame.CopyBlock(cBlock, ref tempData);
finalUpdates.Add(new CacheInfo(0, false, tempData, cBlock));*/
//hash it and see if exists in cache
hasher = new CRC32(); //re-initialize for seed
byte[] tempData = new byte[0];
LastFrame.CopyBlock(cBlock, ref tempData);
int hash = BitConverter.ToInt32(hasher.ComputeHash(tempData), 0);
if (codeCached.Count >= MaxBuffers)
codeCached.RemoveAt(0);
if (codeCached.ContainsKey(hash))
{
CachedSize += (ulong)tempData.Length;
finalUpdates.Add(new CacheInfo(hash, true, new byte[0], cBlock));
}
else
{
//nothing found in cache let's use the normal way
codeCached.Add(hash, tempData);
finalUpdates.Add(new CacheInfo(hash, false, tempData, cBlock));
}
}
x += s.Width;
}
y += ScanHeight;
}
}
for (int i = 0; i < finalUpdates.Count; i++)
{
buffer = new byte[0];
Rectangle rect = finalUpdates[i].Rect;
if (!finalUpdates[i].isCached)
{
fixed (byte* ptr = finalUpdates[i].Data)
{
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * LastFrame.Info.PixelSize, LastFrame.bitmapData.PixelFormat, new IntPtr(ptr)))
{
buffer = base.jpgCompression.Compress(TmpBmp);
}
}
}
outStream.WriteByte(finalUpdates[i].isCached ? (byte)1 : (byte)0);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Height), 0, 4);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Hash), 0, 4);
outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
outStream.Write(buffer, 0, buffer.Length);
TotalDataLength += buffer.Length + (4 * 6) + 1;
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
Blocks.Clear();
SetLastFrame(sbBmp);
ms.Close();
ms.Dispose();
}
}
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
List<CacheInfo> cacheInfo = new List<CacheInfo>();
byte[] HeaderData = new byte[(4 * 6) + 1];
while (DataSize > 0)
{
inStream.Read(HeaderData, 0, HeaderData.Length);
bool isCached = HeaderData[0] == 1;
rect = new Rectangle(BitConverter.ToInt32(HeaderData, 1), BitConverter.ToInt32(HeaderData, 5),
BitConverter.ToInt32(HeaderData, 9), BitConverter.ToInt32(HeaderData, 13));
int Hash = BitConverter.ToInt32(HeaderData, 17);
int UpdateLen = BitConverter.ToInt32(HeaderData, 21);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
//process update data
if (isCached)
{
//data is cached
if (decodeCached.ContainsKey(Hash))
buffer = decodeCached[Hash];
else
{
}
cacheInfo.Add(new CacheInfo(Hash, true, new byte[0], rect));
}
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
if (buffer.Length > 0)
{
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
}
if (decodeCached.Count >= MaxBuffers)
decodeCached.RemoveAt(0);
if(!decodeCached.ContainsKey(Hash))
this.decodeCached.Add(Hash, buffer);
DataSize -= UpdateLen + HeaderData.Length;
}
int CachedSize = 0;
foreach(CacheInfo inf in cacheInfo)
{
CachedSize += (inf.Rect.Width * 4) * inf.Rect.Height;
}
Console.WriteLine(cacheInfo.Count + ", " + CachedSize);
g.Dispose();
return decodedBitmap;
}
private class CacheInfo
{
public bool isCached = false;
public byte[] Data;
public int Hash;
public Rectangle Rect;
public CacheInfo(int Hash, bool isCached, byte[] Data, Rectangle Rect)
{
this.Hash = Hash;
this.isCached = isCached;
this.Data = Data;
this.Rect = Rect;
}
/*public unsafe void CreateHashList(SimpleBitmap sBmp, Size CheckBlock, SmallCachedStreamCodec codec)
{
if (ScanRects.Count > 0)
{
int scanX = ScanRects[0].X;
for (int i = 0; i < ScanRects.Count; i++)
{
int scanWidth = ScanRects[i].Width > CheckBlock.Width ? CheckBlock.Width : ScanRects[i].Width;
Rectangle rect = ScanRects[i];
rect.Width = scanWidth;
rect.X = scanX;
byte[] buffer = new byte[0];
sBmp.CopyBlock(rect, ref buffer);
int hash = BitConverter.ToInt32(new CRC32().ComputeHash(buffer), 0);
if (!HashList.ContainsKey(hash))
HashList.Add(hash, rect);
//fixed (byte* ptr = buffer)
//{
// using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * sBmp.Info.PixelSize, sBmp.bitmapData.PixelFormat, new IntPtr(ptr)))
// {
// buffer = codec.lzwCompression.Compress(TmpBmp);
//
// }
//}
scanX += scanWidth;
}
}
}*/
}
}
}

View File

@ -1,266 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class SmallStreamCodec : IVideoCodec
{
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 1; }
}
public override ulong CachedSize
{
get;
internal set;
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; }
}
public Size CheckBlock { get; set; }
public SimpleBitmap LastFrame { get; set; }
private object ImageProcessLock = new object();
private Bitmap decodedBitmap;
/// <summary>
/// Initialize a new object of SmallStreamCodec
/// </summary>
/// <param name="ImageQuality">The image quality 0-100%</param>
public SmallStreamCodec(int ImageQuality = 100)
: base(ImageQuality)
{
CheckBlock = new Size(20, 1);
}
private void SetLastFrame(ref Bitmap bmp)
{
SetLastFrame(new SimpleBitmap(bmp));
}
private void SetLastFrame(SimpleBitmap bmp)
{
lock (ImageProcessLock)
{
if (LastFrame != null && LastFrame.Locked)
LastFrame.Dispose(true);
LastFrame = bmp;
}
}
/// <summary>
/// Encode the image
/// </summary>
/// <param name="bitmap">The image you want to encode.</param>
/// <param name="outStream">The output stream</param>
public override unsafe void CodeImage(Bitmap bitmap, Stream outStream)
{
lock (ImageProcessLock)
{
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
if (LastFrame == null)
{
byte[] temp = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
SetLastFrame(ref bitmap);
return;
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<byte[]> updates = new List<byte[]>();
SimpleBitmap sbBmp = new SimpleBitmap(bitmap);
MemoryStream ms = new MemoryStream();
byte[] buffer = null;
if (!LastFrame.Locked)
LastFrame.Lock();
sbBmp.Lock();
if (sbBmp.Info.PixelSize != LastFrame.Info.PixelSize)
throw new Exception("PixelFormat is not equal to previous Bitmap");
if (LastFrame.Info.Width != sbBmp.Info.Width || LastFrame.Info.Height != sbBmp.Info.Height)
{
sbBmp.Unlock();
throw new Exception("Bitmap width/height are not equal to previous bitmap");
}
List<Rectangle> Blocks = new List<Rectangle>();
int index = 0;
int y = 0;
int x = 0;
Size s = new Size(bitmap.Width, CheckBlock.Height);
Size lastSize = new Size(bitmap.Width % CheckBlock.Width, bitmap.Height % CheckBlock.Height);
int lasty = bitmap.Height - lastSize.Height;
int lastx = bitmap.Width - lastSize.Width;
Rectangle cBlock = new Rectangle();
s = new Size(bitmap.Width, s.Height);
while (y != bitmap.Height)
{
if (y == lasty)
s = new Size(bitmap.Width, lastSize.Height);
cBlock = new Rectangle(0, y, bitmap.Width, s.Height);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (!SimpleBitmap.Compare(cBlock, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info))
//if (!SimpleBitmap.Compare(y, s.Height, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info))
{
index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
{
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
Blocks[index] = cBlock;
}
else
{
Blocks.Add(cBlock);
}
}
y += s.Height;
}
List<Rectangle> finalUpdates = new List<Rectangle>();
for (int i = 0; i < Blocks.Count; i++)
{
s = new Size(CheckBlock.Width, Blocks[i].Height);
x = 0;
while (x != bitmap.Width)
{
if (x == lastx)
s = new Size(lastSize.Width, Blocks[i].Height);
cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (!SimpleBitmap.Compare(cBlock, sbBmp.Scan0_int, LastFrame.Scan0_int, sbBmp.Info))
{
index = finalUpdates.Count - 1;
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
{
Rectangle rect = finalUpdates[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
finalUpdates[index] = cBlock;
}
else
{
finalUpdates.Add(cBlock);
}
}
x += s.Width;
}
}
for (int i = 0; i < finalUpdates.Count; i++)
{
Rectangle rect = finalUpdates[i];
sbBmp.CopyBlock(rect, ref buffer);
fixed (byte* ptr = buffer)
{
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * LastFrame.Info.PixelSize, LastFrame.bitmapData.PixelFormat, new IntPtr(ptr)))
{
buffer = base.jpgCompression.Compress(TmpBmp);
}
}
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
outStream.Write(buffer, 0, buffer.Length);
TotalDataLength += buffer.Length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
Blocks.Clear();
SetLastFrame(sbBmp);
ms.Close();
ms.Dispose();
}
}
/// <summary>
/// Decode the video stream
/// </summary>
/// <param name="inStream">The input stream</param>
/// <returns>The image that has been decoded</returns>
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= buffer.Length + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace StreamLibrary.Encoders.GridCoder
{
internal class GridBlock
{
public Rectangle Rect { get; private set; }
public ulong Hash { get; private set; }
private GridEncoder encoder;
public GridBlock(Rectangle Rect, GridEncoder encoder)
{
this.encoder = encoder;
this.Rect = Rect;
CalculateHash();
}
public void CalculateHash()
{
}
}
}

View File

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace StreamLibrary.Encoders.GridCoder
{
public class GridEncoder : IEncoder
{
public override ulong CachedSize
{
get;
internal set;
}
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; }
}
public override unsafe void CodeImage(IntPtr Scan0, System.Drawing.Rectangle ScanArea, System.Drawing.Size ImageSize, System.Drawing.Imaging.PixelFormat Format, System.IO.Stream outStream)
{
}
public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream)
{
return null;
}
public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
return null;
}
}
}

View File

@ -1,46 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary
{
public abstract class IEncoder
{
protected LzwCompression lzwCompression;
public abstract ulong CachedSize { get; internal set; }
protected object ImageProcessLock { get; private set; }
private int _imageQuality;
public int ImageQuality
{
get { return _imageQuality; }
set
{
_imageQuality = value;
lzwCompression = new LzwCompression(value);
}
}
public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public IEncoder(int ImageQuality = 100)
{
this.ImageQuality = ImageQuality;
this.ImageProcessLock = new object();
}
public abstract int BufferCount { get; }
public abstract CodecOption CodecOptions { get; }
public abstract unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream);
public abstract unsafe Bitmap DecodeData(Stream inStream);
public abstract unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length);
}
}

View File

@ -1,324 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeCacheCodec : IUnsafeCodec
{
private const int BlockCount = 5;
private const int HashBlockCount = 8192;
public override ulong CachedSize
{
get { return 0; }
internal set { }
}
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 0; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.HasBuffers | CodecOption.RequireSameSize; }
}
private Bitmap decodedBitmap;
private int EncodedWidth;
private int EncodedHeight;
private PixelFormat EncodedFormat;
private MurmurHash2Unsafe hasher;
private SortedList<int, SortedList<int, uint>> EncodeBuffer;
private Rectangle[] Offsets;
private BlockInfo[] EncodeHashBlocks;
private BlockInfo[] DecodeHashBlocks;
public ulong EncodedFrames { get; private set; }
public ulong DecodedFrames { get; private set; }
public UnsafeCacheCodec(int ImageQuality = 80)
: base(ImageQuality)
{
this.hasher = new MurmurHash2Unsafe();
this.Offsets = new Rectangle[BlockCount];
this.EncodeHashBlocks = new BlockInfo[HashBlockCount];
this.DecodeHashBlocks = new BlockInfo[HashBlockCount];
for (int i = 0; i < HashBlockCount; i++)
{
EncodeHashBlocks[i] = new BlockInfo();
DecodeHashBlocks[i] = new BlockInfo();
}
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
{
if (ImageSize.Width == 0 || ImageSize.Height == 0)
throw new ArgumentException("The width and height must be 1 or higher");
if (ImageSize.Width < BlockCount || ImageSize.Height < BlockCount)
throw new Exception("The Image size Width/Height must be bigger then the Block Count " + BlockCount + "x" + BlockCount);
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
int Stride = ImageSize.Width * PixelSize;
int RawLength = Stride * ImageSize.Height;
if (EncodedFrames == 0)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
double size = (double)ImageSize.Width / (double)BlockCount;
//fix floating point here
for (int i = 0, j = 0; i < BlockCount; i++, j += (int)size)
{
Offsets[i] = new Rectangle(j, 0, (int)size, 1);
}
EncodeBuffer = new SortedList<int, SortedList<int, uint>>();
for (int y = 0; y < ImageSize.Height; y++)
{
for(int i = 0; i < Offsets.Length; i++)
{
if (!EncodeBuffer.ContainsKey(y))
EncodeBuffer.Add(y, new SortedList<int, uint>());
if (!EncodeBuffer[y].ContainsKey(Offsets[i].X))
EncodeBuffer[y].Add(Offsets[i].X, 0); //0=hash
}
}
EncodedFrames++;
return;
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<HashBlock> ImageOffsets = new List<HashBlock>();
List<uint> ImageHashes = new List<uint>();
byte* pScan0 = (byte*)Scan0.ToInt32();
for (int i = 0; i < Offsets.Length; i++)
{
for (int y = 0; y < ImageSize.Height; y++)
{
Rectangle ScanRect = Offsets[i];
ScanRect.Y = y;
int offset = (y * Stride) + (ScanRect.X * PixelSize);
if (offset+Stride > Stride * ImageSize.Height)
break;
uint Hash = hasher.Hash(pScan0 + offset, (int)Stride);
uint BlockOffset = Hash % HashBlockCount;
BlockInfo blockInfo = EncodeHashBlocks[BlockOffset];
if (EncodeBuffer[y][ScanRect.X] != Hash)
{
if (!blockInfo.Hashes.ContainsKey(Hash))
{
int index = ImageOffsets.Count - 1;
if (ImageOffsets.Count > 0 && ImageOffsets[index].Location.Y + 1 == ScanRect.Y)
{
Rectangle rect = ImageOffsets[index].Location;
ImageOffsets[index].Location = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height + 1);
}
else
{
ImageOffsets.Add(new HashBlock(Hash, false, new Rectangle(ScanRect.X, y, ScanRect.Width, 1)));
}
blockInfo.Hashes.Add(Hash, new HashBlock(Hash, false, new Rectangle(ScanRect.X, y, ScanRect.Width, 1)));
ImageHashes.Add(Hash);
}
EncodeBuffer[y][ScanRect.X] = Hash;
}
}
}
if (ImageOffsets.Count > 0)
{
for (int i = 0; i < Offsets.Length; i++)
{
Rectangle TargetOffset = Offsets[i];
int Height = GetOffsetHeight(ImageOffsets, TargetOffset);
Bitmap TmpBmp = new Bitmap(TargetOffset.Width, Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
int blockStride = PixelSize * TargetOffset.Width;
List<HashBlock> UsedOffsets = new List<HashBlock>();
for (int j = 0; j < ImageOffsets.Count; j++)
{
Rectangle rect = ImageOffsets[j].Location;
if (rect.Width != TargetOffset.Width || rect.X != TargetOffset.X)
continue; //error in 1440p, did not tested futher
for (int o = 0, offset = 0; o < rect.Height; o++)
{
int blockOffset = (Stride * (rect.Y + o)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
UsedOffsets.Add(ImageOffsets[j]);
}
}
TmpBmp.UnlockBits(TmpData);
TmpBmp.Dispose();
outStream.Write(BitConverter.GetBytes((short)UsedOffsets.Count), 0, 2);
if (UsedOffsets.Count > 0)
{
outStream.Write(BitConverter.GetBytes((short)UsedOffsets[0].Location.X), 0, 2);
for (int j = 0; j < UsedOffsets.Count; j++)
{
outStream.Write(BitConverter.GetBytes((short)UsedOffsets[j].Location.Y), 0, 2);
outStream.Write(BitConverter.GetBytes((short)UsedOffsets[j].Location.Height), 0, 2);
outStream.Write(BitConverter.GetBytes(UsedOffsets[j].Hash), 0, 4);
}
byte[] CompressedImg = base.jpgCompression.Compress(TmpBmp);
outStream.Write(BitConverter.GetBytes(CompressedImg.Length), 0, 4);
outStream.Write(CompressedImg, 0, CompressedImg.Length);
}
//TotalDataLength += (int)length + (4 * 5);
}
}
EncodedFrames++;
}
private int GetOffsetHeight(List<HashBlock> ImageOffsets, Rectangle rect)
{
int height = 0;
for (int i = 0; i < ImageOffsets.Count; i++)
{
if (ImageOffsets[i].Location.Width == rect.Width && ImageOffsets[i].Location.X == rect.X)
height += ImageOffsets[i].Location.Height;
}
return height;
}
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
//return decodedBitmap;
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
return null;
}
private class BlockInfo
{
public SortedList<uint, HashBlock> Hashes { get; private set; }
public BlockInfo()
{
Hashes = new SortedList<uint, HashBlock>();
}
}
private class HashBlock
{
public bool Cached { get; set; }
public uint Hash { get; set; }
public Rectangle Location { get; set; }
public HashBlock(uint Hash, bool Cached, Rectangle Location)
{
this.Hash = Hash;
this.Cached = Cached;
this.Location = Location;
}
public HashBlock()
{
}
}
private class ImageOffset
{
public Rectangle Location { get; set; }
public List<uint> Hashes { get; set; }
public ImageOffset()
{
this.Hashes = new List<uint>();
}
}
}
}

View File

@ -1,308 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeCachedStreamCodec : IUnsafeCodec
{
public override ulong CachedSize
{
get;
internal set;
}
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 0; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.HasBuffers; }
}
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private static Size CheckBlock = new Size(50, 50);
private MurmurHash2Unsafe Hasher = new MurmurHash2Unsafe();
private List<Frame> Frames = new List<Frame>();
public const int MAX_FRAMES = 120;
private ulong[] DecodeBuffer;
private Bitmap DecodedBitmap;
private List<Bitmap> DecodedFrames = new List<Bitmap>();
public UnsafeCachedStreamCodec(int ImageQuality)
: base(ImageQuality)
{
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
Stride = ImageSize.Width * PixelSize;
RawLength = Stride * ImageSize.Height;
if (EncodedWidth == 0 && EncodedHeight == 0)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
return;
}
Frame frame = new Frame(ImageSize.Width, ImageSize.Height);
int Blocks = (ScanArea.Width / CheckBlock.Width) * (ScanArea.Height / CheckBlock.Height);
int RawSizeUsed = 0;
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<Rectangle> ChangedBlocks = new List<Rectangle>();
for(int y = ScanArea.Y; y < ScanArea.Height; )
{
int height = y + CheckBlock.Height < ScanArea.Height ? CheckBlock.Height : ScanArea.Height - y;
for (int x = ScanArea.X; x < ScanArea.Width; )
{
int width = x + CheckBlock.Width < ScanArea.Width ? CheckBlock.Width : ScanArea.Width - x;
int BlockStride = Format == PixelFormat.Format24bppRgb ? width * 3 : width * 4;
decimal FinalHash = 0;
for (int h = 0; h < height; h++)
{
int Offset = FastBitmap.CalcImageOffset(x, y+h, Format, ImageSize.Width);
FinalHash += Hasher.Hash(pScan0 + Offset, BlockStride);
}
if(onCodeDebugScan != null)
onCodeDebugScan(new Rectangle(x, y, width, height));
bool FoundBlock = false;
decimal FoundHash = 0;
int FrameIndex = 0;
for (int i = 0; i < Frames.Count; i++)
{
decimal hash = Frames[i].GetHashBlock(x, y);
if (hash == FinalHash)
{
FrameIndex = i;
FoundBlock = true;
FoundHash = hash;
break;
}
}
frame.AddHashBlock(x, y, FinalHash);
if (!FoundBlock)
{
int index = ChangedBlocks.Count - 1;
Rectangle cBlock = new Rectangle(x, y, width, height);
if (ChangedBlocks.Count > 0 && (ChangedBlocks[index].X + ChangedBlocks[index].Width) == cBlock.X)
{
Rectangle rect = ChangedBlocks[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
ChangedBlocks[index] = cBlock;
}
/*else if (ChangedBlocks.Count > 0 && (ChangedBlocks[index].Y + ChangedBlocks[index].Height) == cBlock.Y)
{
Rectangle rect = ChangedBlocks[index];
int newHeight = cBlock.Height + rect.Height;
cBlock = new Rectangle(rect.X, rect.Y, rect.Width, newHeight);
ChangedBlocks[index] = cBlock;
}*/
else
{
ChangedBlocks.Add(cBlock);
}
RawSizeUsed += BlockStride * height;
}
x += width;
}
y += height;
}
//write all the blocks
for (int i = 0; i < ChangedBlocks.Count; i++)
{
Rectangle rect = ChangedBlocks[i];
int blockStride = PixelSize * rect.Width;
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
base.jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
ChangedBlocks.Clear();
Frames.Add(frame);
if (Frames.Count > MAX_FRAMES)
Frames.RemoveAt(0);
}
public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (DecodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.DecodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
DecodedFrames.Add(DecodedBitmap);
return DecodedBitmap;
}
Rectangle rect;
Graphics g = Graphics.FromImage(DecodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return DecodedBitmap;
}
public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
return new Bitmap(10, 10);
}
private class HashedBlock
{
public int X { get; private set; }
public int Y { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public int FrameIndex { get; private set; }
public HashedBlock(int x, int y, int width, int height, int FrameIndex)
{
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
this.FrameIndex = FrameIndex;
}
public override string ToString()
{
return "X:" + X + ", Y:" + Y + ", Width:" + Width + ", Height:" + Height + ", FrameIndex:" + FrameIndex;
}
}
private class Frame
{
public decimal[,] HashBlocks { get; private set; }
public Frame(int ImageWidth, int ImageHeight)
{
this.HashBlocks = new decimal[(ImageWidth / UnsafeCachedStreamCodec.CheckBlock.Width) + 2, (ImageHeight / UnsafeCachedStreamCodec.CheckBlock.Height) + 2];
}
public void AddHashBlock(int x, int y, decimal Hash)
{
x = x / UnsafeCachedStreamCodec.CheckBlock.Width;
y = y / UnsafeCachedStreamCodec.CheckBlock.Height;
this.HashBlocks[x, y] = Hash;
}
public decimal GetHashBlock(int x, int y)
{
x = x / UnsafeCachedStreamCodec.CheckBlock.Width;
y = y / UnsafeCachedStreamCodec.CheckBlock.Height;
return this.HashBlocks[x, y];
}
}
}
}

View File

@ -1,365 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeMiniCodec : IUnsafeCodec
{
public override ulong CachedSize
{
get;
internal set;
}
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; }
}
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private byte[] EncodeBuffer;
private Bitmap decodedBitmap;
private Size CheckBlock { get { return new Size(50, 50); } }
public UnsafeMiniCodec(int ImageQuality = 100)
: base(ImageQuality)
{
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
{
lock (this.ImageProcessLock)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
FastBitmap.CalcImageOffset(0, 0, Format, ScanArea.Width); //check for FastBitmap Support
switch (Format)
{
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format + " is not supported.");
}
Stride = ImageSize.Width * PixelSize;
RawLength = Stride * ImageSize.Height;
//first frame
if (EncodeBuffer == null)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
this.EncodeBuffer = new byte[RawLength];
fixed (byte* ptr = EncodeBuffer)
{
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
}
return;
}
if (this.EncodedFormat != Format)
throw new Exception("PixelFormat is not equal to previous Bitmap");
if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height)
throw new Exception("Bitmap width/height are not equal to previous bitmap");
if (ScanArea.Width > ImageSize.Width || ImageSize.Height > this.EncodedHeight)
throw new Exception("Scan Area Width/Height cannot be greater then the encoded image");
List<Rectangle> Blocks = new List<Rectangle>(); //all the changes
fixed (byte* encBuffer = EncodeBuffer)
{
//1. Check for the changes in height
for (int y = ScanArea.Y; y < ScanArea.Height; y++)
{
Rectangle cBlock = new Rectangle(0, y, ImageSize.Width, 1);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
int Offset = FastBitmap.CalcImageOffset(0, y, Format, ImageSize.Width);
if (NativeMethods.memcmp(encBuffer + Offset, pScan0 + Offset, (uint)Stride) != 0)
{
int index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
{
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
Blocks[index] = cBlock;
}
else
{
Blocks.Add(cBlock);
}
}
}
//2. Capture all the changes using the CheckBlock
List<Rectangle> finalUpdates = new List<Rectangle>();
for (int i = 0; i < Blocks.Count; i++)
{
Rectangle scanBlock = Blocks[i];
//go through the Blocks
for (int y = scanBlock.Y; y < scanBlock.Height; y += CheckBlock.Height)
{
for (int x = scanBlock.X; x < scanBlock.Width; x += CheckBlock.Width)
{
int blockWidth = x + CheckBlock.Width < scanBlock.Width ? CheckBlock.Width : scanBlock.Width - x;
int blockHeight = y + CheckBlock.Height < scanBlock.Height ? CheckBlock.Height : scanBlock.Height - y;
Rectangle cBlock = new Rectangle(x, y, blockWidth, blockHeight);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
//scan the block from Top To Bottom and check for changes
bool FoundChanges = false;
for (int blockY = y; blockY < y + blockHeight; blockY++)
{
int Offset = FastBitmap.CalcImageOffset(x, blockY, Format, blockWidth);
if (NativeMethods.memcmp(encBuffer + Offset, pScan0 + Offset, (uint)Stride) != 0)
{
FoundChanges = true;
break;
}
}
if (FoundChanges)
{
int index = finalUpdates.Count - 1;
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
{
Rectangle rect = finalUpdates[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
finalUpdates[index] = cBlock;
}
else
{
finalUpdates.Add(cBlock);
}
}
}
}
}
//maybe a too hard algorithm but oh well
SortedList<int, SortedList<int, Rectangle>> Array = finalUpdates.ToArray().RectanglesTo2D().Rectangle2DToRows();
List<Rectangle> FinalTemp = new List<Rectangle>();
for (int i = 0; i < Array.Values.Count; i++)
{
FinalTemp.AddRange(Array.Values[i].Values);
}
//fixup the height
for (int i = 0; i < FinalTemp.Count; )
{
if (FinalTemp.Count == 1)
{
FinalTemp.Add(FinalTemp[i]);
break;
}
if (i + 1 < FinalTemp.Count)
{
Rectangle curRect = FinalTemp[i];
Rectangle nextRect = FinalTemp[i + 1];
if ((curRect.Y + curRect.Height) == nextRect.Y && curRect.Width == nextRect.Width)
{
FinalTemp[i] = new Rectangle(curRect.X, curRect.Y, curRect.Width, curRect.Height + curRect.Height);
FinalTemp.RemoveAt(i + 1);
}
else
{
i++;
}
}
else
{
break;
}
}
//copy changes to the EncodeBuffer and Process the Output
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
for (int i = 0; i < FinalTemp.Count; i++)
{
Rectangle rect = FinalTemp[i];
int blockStride = PixelSize * rect.Width;
//copy changes to EncodeBuffer
for (int y = rect.Y; y < rect.Y + rect.Height; y++)
{
int Offset = FastBitmap.CalcImageOffset(rect.X, y, Format, rect.Width);
NativeMethods.memcpy(encBuffer + Offset, pScan0 + Offset, (uint)blockStride); //copy-changes
}
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
base.jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
Blocks.Clear();
}
}
}
public override unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
if (Length < 4)
return decodedBitmap;
int DataSize = *(int*)(CodecBuffer);
if (decodedBitmap == null)
{
byte[] temp = new byte[DataSize];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize);
}
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
byte* bufferPtr = (byte*)CodecBuffer.ToInt32();
if (DataSize > 0)
{
Graphics g = Graphics.FromImage(decodedBitmap);
for (int i = 4; DataSize > 0; )
{
Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4),
*(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12));
int UpdateLen = *(int*)(bufferPtr + i + 16);
byte[] temp = new byte[UpdateLen];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen);
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr)))
{
g.DrawImage(TmpBmp, new Point(rect.X, rect.Y));
}
}
DataSize -= UpdateLen + (4 * 5);
i += UpdateLen + (4 * 5);
}
g.Dispose();
}
return decodedBitmap;
}
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
}
}

View File

@ -1,473 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeOptimizedCodec : IUnsafeCodec
{
private class PopulairPoint
{
public Rectangle Rect;
public int Score;
public Stopwatch LastUpdate;
public PopulairPoint(Rectangle rect)
{
this.Rect = rect;
this.Score = 0;
this.LastUpdate = Stopwatch.StartNew();
}
}
public override ulong CachedSize
{
get;
internal set;
}
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.RequireSameSize; }
}
public Size CheckBlock { get; private set; }
private object ImageProcessLock = new object();
private byte[] EncodeBuffer;
private Bitmap decodedBitmap;
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private List<PopulairPoint> populairPoints;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
private Stopwatch ScreenRefreshSW = Stopwatch.StartNew();
//options
/// <summary> If a part in the image is been changing for the last x milliseconds it will be seen as a video </summary>
public uint AliveTimeForBeingVideo = 5000;
/// <summary> This will check if the video went away or stopped playing so it will refresh the other parts in the image </summary>
public uint ScreenRefreshTimer = 2000;
/// <summary> The size for being a video, if bigger or equal to the VideoScreenSize it must be a video </summary>
public Size VideoScreenSize = new Size(100, 100);
/// <summary>
/// Initialize a new object of UnsafeOptimizedCodec
/// </summary>
/// <param name="ImageQuality">The quality to use between 0-100</param>
public UnsafeOptimizedCodec(int ImageQuality = 100)
: base(ImageQuality)
{
this.populairPoints = new List<PopulairPoint>();
this.CheckBlock = new Size(15, 1);
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
{
lock (ImageProcessLock)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
Stride = ImageSize.Width * PixelSize;
RawLength = Stride * ImageSize.Height;
if (EncodeBuffer == null)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
this.EncodeBuffer = new byte[RawLength];
fixed (byte* ptr = EncodeBuffer)
{
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
}
return;
}
if (ScreenRefreshSW.ElapsedMilliseconds > ScreenRefreshTimer)
{
for (int i = 0; i < populairPoints.Count; i++)
{
if (populairPoints[i].Score == 0 || populairPoints[i].LastUpdate.Elapsed.Seconds > 5)
{
populairPoints.RemoveAt(i);
}
}
ScreenRefreshSW = Stopwatch.StartNew();
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<byte[]> updates = new List<byte[]>();
MemoryStream ms = new MemoryStream();
byte[] buffer = null;
if (this.EncodedFormat != Format)
throw new Exception("PixelFormat is not equal to previous Bitmap");
if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height)
throw new Exception("Bitmap width/height are not equal to previous bitmap");
List<Rectangle> Blocks = new List<Rectangle>();
int index = 0;
Size s = new Size(ScanArea.Width, CheckBlock.Height);
Size lastSize = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height);
int lasty = ScanArea.Height - lastSize.Height;
int lastx = ScanArea.Width - lastSize.Width;
Rectangle cBlock = new Rectangle();
List<Rectangle> finalUpdates = new List<Rectangle>();
PopulairPoint[] points = GetPossibleVideos();
if (points.Length > 0)
{
ScanArea = new Rectangle(points[0].Rect.X, points[0].Rect.Y, points[0].Rect.Width + points[0].Rect.X, points[0].Rect.Height + points[0].Rect.Y);
}
s = new Size(ScanArea.Width, s.Height);
fixed (byte* encBuffer = EncodeBuffer)
{
if (points.Length == 0) //only scan if there is no video
{
for (int y = ScanArea.Y; y != ScanArea.Height; )
{
if (y == lasty)
s = new Size(ScanArea.Width, lastSize.Height);
cBlock = new Rectangle(ScanArea.X, y, ScanArea.Width, s.Height);
int offset = (y * Stride) + (ScanArea.X * PixelSize);
if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
{
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
{
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
Blocks[index] = cBlock;
}
else
{
Blocks.Add(cBlock);
}
}
y += s.Height;
}
for (int i = 0, x = ScanArea.X; i < Blocks.Count; i++)
{
s = new Size(CheckBlock.Width, Blocks[i].Height);
x = ScanArea.X;
while (x != ScanArea.Width)
{
if (x == lastx)
s = new Size(lastSize.Width, Blocks[i].Height);
cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height);
bool FoundChanges = false;
int blockStride = PixelSize * cBlock.Width;
for (int j = 0; j < cBlock.Height; j++)
{
int blockOffset = (Stride * (cBlock.Y + j)) + (PixelSize * cBlock.X);
if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride) != 0)
FoundChanges = true;
NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
}
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (FoundChanges)
{
index = finalUpdates.Count - 1;
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
{
Rectangle rect = finalUpdates[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
finalUpdates[index] = cBlock;
}
else
{
finalUpdates.Add(cBlock);
}
}
x += s.Width;
}
}
}
else
{
finalUpdates.Add(points[0].Rect);
}
}
for (int i = 0; i < finalUpdates.Count; i++)
{
Rectangle rect = finalUpdates[i];
int blockStride = PixelSize * rect.Width;
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
base.jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
if (rect.Width > VideoScreenSize.Width && rect.Height > VideoScreenSize.Height)
{
PopulairPoint point = null;
if (GetPopulairPoint(rect, ref point))
{
point.Score++;
point.LastUpdate = Stopwatch.StartNew();
//Console.WriteLine("[" + populairPoints.Count + "]Video spotted at x:" + rect.X + ", y:" + rect.Y + ", width:" + rect.Width + ", height:" + rect.Height);
}
else
{
populairPoints.Add(new PopulairPoint(rect));
}
}
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
/*for (int i = 0; i < finalUpdates.Count; i++)
{
Rectangle rect = finalUpdates[i];
int blockStride = PixelSize * rect.Width;
buffer = new byte[blockStride * rect.Height];
fixed (byte* ptr = buffer)
{
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy(ptr + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * PixelSize, Format, new IntPtr(ptr)))
{
buffer = base.jpgCompression.Compress(TmpBmp);
if (rect.Width > VideoScreenSize.Width && rect.Height > VideoScreenSize.Height)
{
PopulairPoint point = null;
if (GetPopulairPoint(rect, ref point))
{
point.Score++;
point.LastUpdate = Stopwatch.StartNew();
Console.WriteLine("[" + populairPoints.Count + "]Video spotted at x:" + rect.X + ", y:" + rect.Y + ", width:" + rect.Width + ", height:" + rect.Height);
}
else
{
populairPoints.Add(new PopulairPoint(rect));
}
}
}
}
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
outStream.Write(buffer, 0, buffer.Length);
TotalDataLength += buffer.Length + (4 * 5);
}*/
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
Blocks.Clear();
ms.Close();
ms.Dispose();
}
}
public override unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
if (Length < 4)
return decodedBitmap;
int DataSize = *(int*)(CodecBuffer);
if (decodedBitmap == null)
{
byte[] temp = new byte[DataSize];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize);
}
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
byte* bufferPtr = (byte*)CodecBuffer.ToInt32();
if (DataSize > 0)
{
Graphics g = Graphics.FromImage(decodedBitmap);
for (int i = 4; DataSize > 0; )
{
Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4),
*(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12));
int UpdateLen = *(int*)(bufferPtr + i + 16);
byte[] temp = new byte[UpdateLen];
fixed(byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen);
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr)))
{
g.DrawImage(TmpBmp, new Point(rect.X, rect.Y));
}
}
DataSize -= UpdateLen + (4 * 5);
i += UpdateLen + (4 * 5);
}
g.Dispose();
}
return decodedBitmap;
}
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
private bool GetPopulairPoint(Rectangle rect, ref PopulairPoint PopuPoint)
{
for (int i = 0; i < populairPoints.Count; i++)
{
PopulairPoint point = populairPoints[i];
if (point.Rect.Width == rect.Width &&
point.Rect.Height == rect.Height &&
point.Rect.X == rect.X &&
point.Rect.Y == rect.Y)
{
PopuPoint = populairPoints[i];
return true;
}
}
return false;
}
private PopulairPoint[] GetPossibleVideos()
{
List<PopulairPoint> points = new List<PopulairPoint>();
for (int i = 0; i < populairPoints.Count; i++)
{
if (populairPoints[i].Score > 30)
{
points.Add(populairPoints[i]);
}
}
return points.ToArray();
}
}
}

View File

@ -1,285 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeQuickStream : IUnsafeCodec
{
public override ulong CachedSize { get; internal set; }
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 0; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; }
}
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private ulong[] EncodeBuffer;
private int BlockWidth = 0;
private int BlockHeight = 0;
private Bitmap decodedBitmap;
public List<Rectangle> VerifyPoints = null;
public Size CheckBlock { get; private set; }
public UnsafeQuickStream(int ImageQuality = 100)
: base(ImageQuality)
{
this.CheckBlock = new Size(50, 50);//width must be bigger then 3
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle OutputRect, Size InputSize, PixelFormat Format, Stream outStream)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
Stride = InputSize.Width * PixelSize;
RawLength = Stride * InputSize.Height;
if (EncodedWidth == 0 && EncodedHeight == 0)
{
this.EncodedFormat = Format;
this.EncodedWidth = OutputRect.Width;
this.EncodedHeight = OutputRect.Height;
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(OutputRect.Width, OutputRect.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
return;
}
List<Rectangle> Points = ProcessChanges(Scan0, OutputRect, Format, InputSize.Width);
VerifyPoints = Points;
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
for (int i = 0; i < Points.Count; i++)
{
Rectangle rect = Points[i];
int blockStride = PixelSize * rect.Width;
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
base.jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
}
private unsafe List<Rectangle> ProcessChanges(IntPtr Scan0, Rectangle OutputRect, PixelFormat Format, int ImageWidth)
{
if (EncodeBuffer == null)
{
this.BlockWidth = (int)Math.Floor((float)(OutputRect.Width / CheckBlock.Width));
this.BlockHeight = (int)Math.Floor((double)(OutputRect.Height / CheckBlock.Height));
int TotalBlocks = (int)Math.Floor((float)(BlockHeight * BlockWidth));
this.EncodeBuffer = new ulong[TotalBlocks];
}
List<Rectangle> points = new List<Rectangle>();
int StartScan = Scan0.ToInt32();
for (int y = OutputRect.Y; y < OutputRect.Height + OutputRect.Y; y += CheckBlock.Height)
{
if (y + CheckBlock.Height > OutputRect.Height)
break;
for (int x = OutputRect.X; x < OutputRect.Width + OutputRect.X; x += CheckBlock.Width)
{
if (x + CheckBlock.Width > OutputRect.Width)
break;
int EncodeOffset = GetOffset(x, y);
long offset = FastBitmap.CalcImageOffset(x, y, Format, ImageWidth);
ulong* ScanPtr = (ulong*)(StartScan + offset);
if (EncodeBuffer[EncodeOffset] != *ScanPtr)
{
EncodeBuffer[EncodeOffset] = *ScanPtr;
Rectangle cBlock = new Rectangle(x, y, CheckBlock.Width, CheckBlock.Height);
int index = points.Count - 1;
if (points.Count > 0 && (points[index].X + points[index].Width) == cBlock.X)
{
Rectangle rect = points[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
points[index] = cBlock;
}
else
{
points.Add(cBlock);
}
}
}
}
return points;
}
private Point GetOffsetPoint(int x, int y)
{
return new Point((int)Math.Floor((float)(y / CheckBlock.Height)) * BlockWidth,
(int)Math.Floor((double)(x / CheckBlock.Width)));
}
private int GetOffset(int x, int y)
{
return (int)Math.Floor((float)(y / CheckBlock.Height)) * BlockWidth +
(int)Math.Floor((double)(x / CheckBlock.Width));
}
public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
if (Length < 4)
return decodedBitmap;
int DataSize = *(int*)(CodecBuffer);
if (decodedBitmap == null)
{
byte[] temp = new byte[DataSize];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize);
}
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
byte* bufferPtr = (byte*)CodecBuffer.ToInt32();
if (DataSize > 0)
{
Graphics g = Graphics.FromImage(decodedBitmap);
for (int i = 4; DataSize > 0; )
{
Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4),
*(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12));
int UpdateLen = *(int*)(bufferPtr + i + 16);
byte[] temp = new byte[UpdateLen];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen);
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr)))
{
g.DrawImage(TmpBmp, new Point(rect.X, rect.Y));
}
}
DataSize -= UpdateLen + (4 * 5);
i += UpdateLen + (4 * 5);
}
g.Dispose();
}
return decodedBitmap;
}
}
}

View File

@ -1,186 +0,0 @@
// Tamir Khason http://khason.net/
//
// Released under MS-PL : 6-Apr-09
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Collections;
using System.IO;
namespace StreamLibrary.src
{
/// <summary>Implements a 32-bits cyclic redundancy check (CRC) hash algorithm.</summary>
/// <remarks>This class is not intended to be used for security purposes. For security applications use MD5, SHA1, SHA256, SHA384,
/// or SHA512 in the System.Security.Cryptography namespace.</remarks>
public class CRC32 : HashAlgorithm
{
#region CONSTRUCTORS
/// <summary>Creates a CRC32 object using the <see cref="DefaultPolynomial"/>.</summary>
public CRC32()
: this(DefaultPolynomial)
{
}
/// <summary>Creates a CRC32 object using the specified polynomial.</summary>
/// <remarks>The polynomical should be supplied in its bit-reflected form. <see cref="DefaultPolynomial"/>.</remarks>
public CRC32(uint polynomial)
{
HashSizeValue = 32;
_crc32Table = (uint[])_crc32TablesCache[polynomial];
if (_crc32Table == null)
{
_crc32Table = CRC32._buildCRC32Table(polynomial);
_crc32TablesCache.Add(polynomial, _crc32Table);
}
Initialize();
}
// static constructor
static CRC32()
{
_crc32TablesCache = Hashtable.Synchronized(new Hashtable());
_defaultCRC = new CRC32();
}
#endregion
#region PROPERTIES
/// <summary>Gets the default polynomial (used in WinZip, Ethernet, etc.)</summary>
/// <remarks>The default polynomial is a bit-reflected version of the standard polynomial 0x04C11DB7 used by WinZip, Ethernet, etc.</remarks>
public static readonly uint DefaultPolynomial = 0xEDB88320; // Bitwise reflection of 0x04C11DB7;
#endregion
#region METHODS
/// <summary>Initializes an implementation of HashAlgorithm.</summary>
public override void Initialize()
{
_crc = _allOnes;
}
/// <summary>Routes data written to the object into the hash algorithm for computing the hash.</summary>
protected override void HashCore(byte[] buffer, int offset, int count)
{
for (int i = offset; i < count; i++)
{
ulong ptr = (_crc & 0xFF) ^ buffer[i];
_crc >>= 8;
_crc ^= _crc32Table[ptr];
}
}
/// <summary>Finalizes the hash computation after the last data is processed by the cryptographic stream object.</summary>
protected override byte[] HashFinal()
{
byte[] finalHash = new byte[4];
ulong finalCRC = _crc ^ _allOnes;
finalHash[0] = (byte)((finalCRC >> 0) & 0xFF);
finalHash[1] = (byte)((finalCRC >> 8) & 0xFF);
finalHash[2] = (byte)((finalCRC >> 16) & 0xFF);
finalHash[3] = (byte)((finalCRC >> 24) & 0xFF);
return finalHash;
}
/// <summary>Computes the CRC32 value for the given ASCII string using the <see cref="DefaultPolynomial"/>.</summary>
public static int Compute(string asciiString)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(asciiString));
}
/// <summary>Computes the CRC32 value for the given input stream using the <see cref="DefaultPolynomial"/>.</summary>
public static int Compute(Stream inputStream)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(inputStream));
}
/// <summary>Computes the CRC32 value for the input data using the <see cref="DefaultPolynomial"/>.</summary>
public static int Compute(byte[] buffer)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(buffer));
}
/// <summary>Computes the hash value for the input data using the <see cref="DefaultPolynomial"/>.</summary>
public static int Compute(byte[] buffer, int offset, int count)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(buffer, offset, count));
}
/// <summary>Computes the hash value for the given ASCII string.</summary>
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
public byte[] ComputeHash(string asciiString)
{
byte[] rawBytes = ASCIIEncoding.ASCII.GetBytes(asciiString);
return ComputeHash(rawBytes);
}
/// <summary>Computes the hash value for the given input stream.</summary>
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
new public byte[] ComputeHash(Stream inputStream)
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.Read(buffer, 0, 4096)) > 0)
{
HashCore(buffer, 0, bytesRead);
}
return HashFinal();
}
/// <summary>Computes the hash value for the input data.</summary>
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
new public byte[] ComputeHash(byte[] buffer)
{
return ComputeHash(buffer, 0, buffer.Length);
}
/// <summary>Computes the hash value for the input data.</summary>
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
new public byte[] ComputeHash(byte[] buffer, int offset, int count)
{
HashCore(buffer, offset, count);
return HashFinal();
}
#endregion
#region PRIVATE SECTION
private static uint _allOnes = 0xffffffff;
private static CRC32 _defaultCRC;
private static Hashtable _crc32TablesCache;
private uint[] _crc32Table;
private uint _crc;
// Builds a crc32 table given a polynomial
private static uint[] _buildCRC32Table(uint polynomial)
{
uint crc;
uint[] table = new uint[256];
// 256 values representing ASCII character codes.
for (int i = 0; i < 256; i++)
{
crc = (uint)i;
for (int j = 8; j > 0; j--)
{
if ((crc & 1) == 1)
crc = (crc >> 1) ^ polynomial;
else
crc >>= 1;
}
table[i] = crc;
}
return table;
}
private static int ToInt32(byte[] buffer)
{
return BitConverter.ToInt32(buffer, 0);
}
#endregion
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method)]
public sealed class ExtensionAttribute : Attribute
{
public ExtensionAttribute() { }
}
}

View File

@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace StreamLibrary.src
{
public static unsafe class Extensions
{
public static SortedList<int, SortedList<int, Rectangle>> RectanglesTo2D(this Rectangle[] rects)
{
SortedList<int, SortedList<int, Rectangle>> Rects = new SortedList<int, SortedList<int, Rectangle>>();
for (int i = 0; i < rects.Length; i++)
{
if (!Rects.ContainsKey(rects[i].Y))
Rects.Add(rects[i].Y, new SortedList<int, Rectangle>());
if (!Rects[rects[i].Y].ContainsKey(rects[i].X))
Rects[rects[i].Y].Add(rects[i].X, rects[i]);
}
return Rects;
}
public static SortedList<int, SortedList<int, Rectangle>> Rectangle2DToRows(this SortedList<int, SortedList<int, Rectangle>> Rects)
{
SortedList<int, SortedList<int, Rectangle>> RectRows = new SortedList<int, SortedList<int, Rectangle>>();
for (int i = 0; i < Rects.Values.Count; i++)
{
if (!RectRows.ContainsKey(Rects.Values[i].Values[0].Y))
{
RectRows.Add(Rects.Values[i].Values[0].Y, new SortedList<int, Rectangle>());
}
if (!RectRows[Rects.Values[i].Values[0].Y].ContainsKey(Rects.Values[i].Values[0].X))
{
RectRows[Rects.Values[i].Values[0].Y].Add(Rects.Values[i].Values[0].X, Rects.Values[i].Values[0]);
}
Rectangle EndRect = Rects.Values[i].Values[0];
for (int x = 1; x < Rects.Values[i].Values.Count; x++)
{
Rectangle CurRect = Rects.Values[i].Values[x];
Rectangle tmpRect = RectRows[EndRect.Y].Values[RectRows[EndRect.Y].Count - 1];
if (tmpRect.IntersectsWith(new Rectangle(CurRect.X - 1, CurRect.Y, CurRect.Width, CurRect.Height)))
{
RectRows[EndRect.Y][tmpRect.X] = new Rectangle(tmpRect.X, tmpRect.Y, tmpRect.Width + EndRect.Width, tmpRect.Height);
EndRect = Rects.Values[i].Values[x];
}
else
{
EndRect = Rects.Values[i].Values[x];
RectRows[Rects.Values[i].Values[0].Y].Add(EndRect.X, EndRect);
}
}
}
return RectRows;
}
}
}

View File

@ -1,353 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
namespace StreamLibrary.src
{
public unsafe class FastBitmap
{
public Bitmap bitmap { get; set; }
public BitmapData bitmapData { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public PixelFormat format { get; private set; }
public DateTime BitmapCreatedAt;
public bool IsLocked { get; private set; }
public int Stride
{
get { return bitmapData.Stride; }
}
public FastBitmap(Bitmap bitmap, PixelFormat format)
{
switch (format)
{
case PixelFormat.Format32bppArgb:
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
case PixelFormat.Format8bppIndexed:
case PixelFormat.Format4bppIndexed:
case PixelFormat.Format1bppIndexed:
break;
default:
throw new NotSupportedException(format + " is not supported.");
}
this.bitmap = bitmap;
this.Width = this.bitmap.Width;
this.Height = this.bitmap.Height;
this.format = format;
Lock();
BitmapCreatedAt = DateTime.Now;
}
public FastBitmap(Bitmap bitmap)
{
this.format = bitmap.PixelFormat;
switch (format)
{
case PixelFormat.Format32bppArgb:
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
case PixelFormat.Format8bppIndexed:
case PixelFormat.Format4bppIndexed:
case PixelFormat.Format1bppIndexed:
break;
default:
throw new NotSupportedException(format + " is not supported.");
}
this.bitmap = bitmap;
this.Width = this.bitmap.Width;
this.Height = this.bitmap.Height;
this.format = format;
Lock();
BitmapCreatedAt = DateTime.Now;
}
public Color GetPixel(int x, int y)
{
byte* position = (byte*)bitmapData.Scan0.ToPointer();
position += CalcOffset(x, y);
byte A = position[3];
byte R = position[2];
byte G = position[1];
byte B = position[0];
return Color.FromArgb(A, R, G, B);
}
public void SetPixel(int x, int y, Color color)
{
byte* position = (byte*)bitmapData.Scan0.ToPointer();
position += CalcOffset(x, y);
position[3] = color.A;
position[2] = color.R;
position[1] = color.G;
position[0] = color.B;
}
public Color GetPixel(int x, int y, byte[] ImgData)
{
long offset = CalcOffset(x, y) + 4;
if (offset + 4 < ImgData.Length)
{
byte R = ImgData[offset];
byte G = ImgData[offset + 1];
byte B = ImgData[offset + 2];
return Color.FromArgb(255, R, G, B);
}
return Color.FromArgb(255, 0, 0, 0);
}
public void SetPixel(int x, int y, Color color, byte[] ImgData)
{
long offset = CalcOffset(x, y) + 4;
if (offset + 4 < ImgData.Length)
{
ImgData[offset] = color.R;
ImgData[offset + 1] = color.G;
ImgData[offset + 2] = color.B;
ByteArrayToBitmap(ImgData);
}
}
public void DrawRectangle(Point begin, Point end, Color color)
{
for (int x = begin.X; x < end.X; x++)
{
for (int y = begin.Y; y < end.Y; y++)
{
SetPixel(x, y, color);
}
}
}
public Int64 CalcOffset(int x, int y)
{
switch (format)
{
case PixelFormat.Format32bppArgb:
return (y * bitmapData.Stride) + (x * 4);
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
return (y * bitmapData.Stride) + (x * 3);
case PixelFormat.Format8bppIndexed:
return (y * bitmapData.Stride) + x;
case PixelFormat.Format4bppIndexed:
return (y * bitmapData.Stride) + (x / 2);
case PixelFormat.Format1bppIndexed:
return (y * bitmapData.Stride) + (x * 8);
}
return 0;
}
public static int CalcImageOffset(int x, int y, PixelFormat format, int width)
{
switch (format)
{
case PixelFormat.Format32bppArgb:
return (y * (width * 4)) + (x * 4);
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
return (y * (width * 3)) + (x * 3);
case PixelFormat.Format8bppIndexed:
return (y * width) + x;
case PixelFormat.Format4bppIndexed:
return (y * (width / 2)) + (x / 2);
case PixelFormat.Format1bppIndexed:
return (y * (width * 8)) + (x * 8);
default:
throw new NotSupportedException(format + " is not supported.");
}
}
public void ScanPixelDuplicates(Point BeginPoint, ref Point EndPoint, ref Color RetColor)
{
Color curColor = GetPixel(BeginPoint.X, BeginPoint.Y);
for (int x = BeginPoint.X; x < this.Width; x++)
{
Color prevColor = GetPixel(x, BeginPoint.Y);
if (curColor.R != prevColor.R ||
curColor.G != prevColor.G ||
curColor.B != prevColor.B)
{
EndPoint = new Point(x, BeginPoint.Y);
RetColor = curColor;
return;
}
}
EndPoint = new Point(this.Width, BeginPoint.Y);
RetColor = curColor;
}
public void Unlock()
{
if (IsLocked)
{
bitmap.UnlockBits(bitmapData);
IsLocked = false;
}
}
public void Lock()
{
if (!IsLocked)
{
bitmapData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, format);
IsLocked = true;
}
}
public byte[] ToByteArray()
{
int bytes = Math.Abs(bitmapData.Stride) * Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(new IntPtr(bitmapData.Scan0.ToInt32()), rgbValues, 0, bytes);
return rgbValues;
}
public void ByteArrayToBitmap(byte[] data)
{
System.Runtime.InteropServices.Marshal.Copy(data, 0, bitmapData.Scan0, data.Length);
}
public void Dispose()
{
if (bitmap != null)
{
try { bitmap.UnlockBits(bitmapData); }
catch { }
try { bitmap.Dispose(); }
catch { }
try
{
bitmap = null;
bitmapData = null;
}
catch { }
}
}
/// <summary> Get the byte points where to read from in a byte array </summary>
/// <param name="beginPoint">The beginning of the X, Y</param>
/// <param name="endPoint">The end of the X, Y</param>
/// <param name="ImgSize">The size of the image</param>
/// <param name="SlicePieces">Slice the byte points into pieces to get the byte points faster</param>
public static ArrayOffset[] GetBytePoints(Point beginPoint, Point endPoint, Size ImgSize, PixelFormat format)
{
List<ArrayOffset> offsets = new List<ArrayOffset>();
for (int y = beginPoint.Y; y < endPoint.Y; y++)
{
int BeginOffset = (int)FastBitmap.CalcImageOffset(beginPoint.X, y, format, ImgSize.Width);//(y * ImgSize.Width * 4) + (beginPoint.X * 4);
int EndOffset = (int)FastBitmap.CalcImageOffset(endPoint.X, y, format, ImgSize.Width);//(y * ImgSize.Width * 4) + (endPoint.X * 4);
switch (format)
{
case PixelFormat.Format32bppArgb:
{
if (EndOffset + ((endPoint.X - beginPoint.X) * 4) >= (ImgSize.Width * ImgSize.Height) * 4)
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 4), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
{
if (EndOffset + ((endPoint.X - beginPoint.X) * 3) >= (ImgSize.Width * ImgSize.Height) * 3)
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 3), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
case PixelFormat.Format8bppIndexed:
{
if (EndOffset + ((endPoint.X - beginPoint.X)) >= (ImgSize.Width * ImgSize.Height))
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X)), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
case PixelFormat.Format4bppIndexed:
{
if (EndOffset + ((endPoint.X - beginPoint.X) / 2) >= (ImgSize.Width * ImgSize.Height) / 2)
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) / 2), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
case PixelFormat.Format1bppIndexed:
{
if (EndOffset + ((endPoint.X - beginPoint.X) * 8) >= (ImgSize.Width * ImgSize.Height) * 8)
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 8), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
default:
{
throw new NotSupportedException(format + " is not supported.");
}
}
}
return offsets.ToArray();
}
/// <summary> Get the byte points in 2D </summary>
/// <param name="beginPoint">The beginning of the X, Y</param>
/// <param name="endPoint">The end of the X, Y</param>
/// <param name="ImgSize">The size of the image</param>
/// <param name="SlicePieces">Slice the byte points into pieces to get the byte points faster</param>
public static ArrayOffset[,][] Get2DBytePoints(Point beginPoint, Point endPoint, Size ImgSize, int SlicePieces, PixelFormat format)
{
int Width = endPoint.X - beginPoint.X;
int Height = endPoint.Y - beginPoint.Y;
float Wsize = ((float)Width / (float)SlicePieces);
float Hsize = ((float)Height / (float)SlicePieces);
//+1 just to make sure we are not going outside the array
if (Wsize - (int)Wsize > 0.0F) Wsize += 1.0F;
if (Hsize - (int)Hsize > 0.0F) Hsize += 1.0F;
ArrayOffset[,][] ImageArrayOffsets = new ArrayOffset[(int)Hsize, (int)Wsize][];
Point tmp = new Point(0, 0);
for (int y = beginPoint.Y; y < Height; y += SlicePieces)
{
for (int x = beginPoint.X; x < Width; x += SlicePieces)
{
ImageArrayOffsets[tmp.Y, tmp.X] = FastBitmap.GetBytePoints(new Point(x, y), new Point(x + SlicePieces, y + SlicePieces), ImgSize, format);
tmp.X++;
}
tmp.X = 0;
tmp.Y++;
}
return ImageArrayOffsets;
}
}
public class ArrayOffset
{
public int BeginOffset { get; private set; }
public int EndOffset { get; private set; }
public int Stride { get; private set; }
public int X { get; private set; }
public int Y { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public ArrayOffset(int begin, int end, int Stride, int x, int y, int width, int height)
{
this.BeginOffset = begin;
this.EndOffset = end;
this.Stride = Stride;
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
}
}

View File

@ -1,62 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace StreamLibrary.src
{
public unsafe class MurmurHash2Unsafe
{
const UInt32 m = 0x5bd1e995;
const Int32 r = 24;
public unsafe UInt32 Hash(Byte* data, int length)
{
if (length == 0)
return 0;
UInt32 h = 0xc58f1a7b ^ (UInt32)length;
Int32 remainingBytes = length & 3; // mod 4
Int32 numberOfLoops = length >> 2; // div 4
UInt32* realData = (UInt32*)data;
while (numberOfLoops != 0)
{
UInt32 k = *realData;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
numberOfLoops--;
realData++;
}
switch (remainingBytes)
{
case 3:
h ^= (UInt16)(*realData);
h ^= ((UInt32)(*(((Byte*)(realData)) + 2))) << 16;
h *= m;
break;
case 2:
h ^= (UInt16)(*realData);
h *= m;
break;
case 1:
h ^= *((Byte*)realData);
h *= m;
break;
default:
break;
}
// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
}
}

View File

@ -1,113 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace StreamLibrary.src
{
public class PayloadWriter : IDisposable
{
public Stream vStream { get; set; }
public PayloadWriter()
{
vStream = new MemoryStream();
}
public PayloadWriter(Stream stream)
{
vStream = stream;
}
public void WriteBytes(byte[] value)
{
vStream.Write(value, 0, value.Length);
}
public void WriteBytes(byte[] value, int Offset, int Length)
{
vStream.Write(value, Offset, Length);
}
public void WriteInteger(int value)
{
WriteBytes(BitConverter.GetBytes(value));
}
/// <summary>
/// A integer with 3 bytes not 4
/// </summary>
public void WriteThreeByteInteger(int value)
{
WriteByte((byte)value);
WriteByte((byte)(value >> 8));
WriteByte((byte)(value >> 16));
}
public void WriteUInteger(uint value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteShort(short value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteUShort(ushort value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteULong(ulong value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteByte(byte value)
{
vStream.WriteByte(value);
}
public void WriteBool(bool value)
{
WriteByte(value ? (byte)1 : (byte)0);
}
public void WriteDouble(double value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteLong(long value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteFloat(float value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteDecimal(decimal value)
{
BinaryWriter writer = new BinaryWriter(vStream);
writer.Write(value);
}
public void WriteString(string value)
{
if (!(value == null))
WriteBytes(System.Text.Encoding.Unicode.GetBytes(value));
else
throw new NullReferenceException("value");
vStream.WriteByte(0);
vStream.WriteByte(0);
}
public int Length
{
get { return (int)vStream.Length; }
}
public void Dispose()
{
vStream.Close();
vStream.Dispose();
vStream = null;
}
}
}

View File

@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace StreamLibrary.src
{
/// <summary>
/// A helper class for pointers
/// </summary>
public class PointerHelper
{
private int _offset;
public IntPtr Pointer
{
get;
private set;
}
public int TotalLength { get; private set; }
public int Offset
{
get { return _offset; }
set
{
if (value < 0)
throw new Exception("Offset must be >= 1");
if (value >= TotalLength)
throw new Exception("Offset cannot go outside of the reserved buffer space");
_offset = value;
}
}
public PointerHelper(IntPtr pointer, int Length)
{
this.TotalLength = Length;
this.Pointer = pointer;
}
/// <summary>
/// Copies data from Source to the current Pointer Offset
/// </summary>
public void Copy(IntPtr Source, int SourceOffset, int SourceLength)
{
if (CheckBoundries(this.Offset, SourceLength))
throw new AccessViolationException("Cannot write outside of the buffer space");
NativeMethods.memcpy(new IntPtr(this.Pointer.ToInt64() + Offset), new IntPtr(Source.ToInt64() + SourceOffset), (uint)SourceLength);
}
private bool CheckBoundries(int offset, int length)
{
return offset + length > TotalLength;
}
}
}

View File

@ -1,487 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace StreamLibrary.src
{
// QuickLZ data compression library
// Copyright (C) 2006-2011 Lasse Mikkel Reinhold
// lar@quicklz.com
//
// QuickLZ can be used for free under the GPL 1, 2 or 3 license (where anything
// released into public must be open source) or under a commercial license if such
// has been acquired (see http://www.quicklz.com/order.html). The commercial license
// does not cover derived or ported versions created by third parties under GPL.
//
// Only a subset of the C library has been ported, namely level 1 and 3 not in
// streaming mode.
//
// Version: 1.5.0 final
public class SafeQuickLZ
{
public const int QLZ_VERSION_MAJOR = 1;
public const int QLZ_VERSION_MINOR = 5;
public const int QLZ_VERSION_REVISION = 0;
// Streaming mode not supported
public const int QLZ_STREAMING_BUFFER = 0;
// Bounds checking not supported Use try...catch instead
public const int QLZ_MEMORY_SAFE = 0;
// Decrease QLZ_POINTERS_3 to increase level 3 compression speed. Do not edit any other values!
private const int HASH_VALUES = 4096;
private const int MINOFFSET = 2;
private const int UNCONDITIONAL_MATCHLEN = 6;
private const int UNCOMPRESSED_END = 4;
private const int CWORD_LEN = 4;
private const int DEFAULT_HEADERLEN = 9;
private const int QLZ_POINTERS_1 = 1;
private const int QLZ_POINTERS_3 = 16;
private int headerLen(byte[] source, int offset)
{
return ((source[offset] & 2) == 2) ? 9 : 3;
}
public int sizeDecompressed(byte[] source, int offset)
{
if (headerLen(source, offset) == 9)
return source[offset + 5] | (source[offset + 6] << 8) | (source[offset + 7] << 16) | (source[offset + 8] << 24);
else
return source[offset + 2];
}
public int sizeCompressed(byte[] source, int offset)
{
if (headerLen(source, offset) == 9)
return source[offset + 1] | (source[offset + 2] << 8) | (source[offset + 3] << 16) | (source[offset + 4] << 24);
else
return source[offset + 1];
}
private void write_header(byte[] dst, int level, bool compressible, int size_compressed, int size_decompressed)
{
dst[0] = (byte)(2 | (compressible ? 1 : 0));
dst[0] |= (byte)(level << 2);
dst[0] |= (1 << 6);
dst[0] |= (0 << 4);
fast_write(dst, 1, size_decompressed, 4);
fast_write(dst, 5, size_compressed, 4);
}
public byte[] compress(byte[] source, int Offset, int Length, int level)
{
int src = Offset;
int dst = DEFAULT_HEADERLEN + CWORD_LEN;
uint cword_val = 0x80000000;
int cword_ptr = DEFAULT_HEADERLEN;
byte[] destination = new byte[Length + 400];
int[,] hashtable;
int[] cachetable = new int[HASH_VALUES];
byte[] hash_counter = new byte[HASH_VALUES];
byte[] d2;
int fetch = 0;
int last_matchstart = (Length - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END - 1);
int lits = 0;
if (level != 1 && level != 3)
throw new ArgumentException("C# version only supports level 1 and 3");
if (level == 1)
hashtable = new int[HASH_VALUES, QLZ_POINTERS_1];
else
hashtable = new int[HASH_VALUES, QLZ_POINTERS_3];
if (Length == 0)
return new byte[0];
if (src <= last_matchstart)
fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16);
while (src <= last_matchstart)
{
if ((cword_val & 1) == 1)
{
if (src > Length >> 1 && dst > src - (src >> 5))
{
d2 = new byte[Length + DEFAULT_HEADERLEN];
write_header(d2, level, false, Length, Length + DEFAULT_HEADERLEN);
System.Array.Copy(source, 0, d2, DEFAULT_HEADERLEN, Length);
return d2;
}
fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4);
cword_ptr = dst;
dst += CWORD_LEN;
cword_val = 0x80000000;
}
if (level == 1)
{
int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1);
int o = hashtable[hash, 0];
int cache = cachetable[hash] ^ fetch;
cachetable[hash] = fetch;
hashtable[hash, 0] = src;
if (cache == 0 && hash_counter[hash] != 0 && (src - o > MINOFFSET || (src == o + 1 && lits >= 3 && src > 3 && source[src] == source[src - 3] &&
source[src] == source[src - 2] && source[src] == source[src - 1] &&
source[src] == source[src + 1] && source[src] == source[src + 2])))
{
cword_val = ((cword_val >> 1) | 0x80000000);
if (source[o + 3] != source[src + 3])
{
int f = 3 - 2 | (hash << 4);
destination[dst + 0] = (byte)(f >> 0 * 8);
destination[dst + 1] = (byte)(f >> 1 * 8);
src += 3;
dst += 2;
}
else
{
int old_src = src;
int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1));
src += 4;
if (source[o + src - old_src] == source[src])
{
src++;
if (source[o + src - old_src] == source[src])
{
src++;
while (source[o + (src - old_src)] == source[src] && (src - old_src) < remaining)
src++;
}
}
int matchlen = src - old_src;
hash <<= 4;
if (matchlen < 18)
{
int f = (hash | (matchlen - 2));
destination[dst + 0] = (byte)(f >> 0 * 8);
destination[dst + 1] = (byte)(f >> 1 * 8);
dst += 2;
}
else
{
fast_write(destination, dst, hash | (matchlen << 16), 3);
dst += 3;
}
}
fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16);
lits = 0;
}
else
{
lits++;
hash_counter[hash] = 1;
destination[dst] = source[src];
cword_val = (cword_val >> 1);
src++;
dst++;
fetch = ((fetch >> 8) & 0xffff) | (source[src + 2] << 16);
}
}
else
{
fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16);
int o, offset2;
int matchlen, k, m, best_k = 0;
byte c;
int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1));
int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1);
c = hash_counter[hash];
matchlen = 0;
offset2 = 0;
for (k = 0; k < QLZ_POINTERS_3 && c > k; k++)
{
o = hashtable[hash, k];
if ((byte)fetch == source[o] && (byte)(fetch >> 8) == source[o + 1] && (byte)(fetch >> 16) == source[o + 2] && o < src - MINOFFSET)
{
m = 3;
while (source[o + m] == source[src + m] && m < remaining)
m++;
if ((m > matchlen) || (m == matchlen && o > offset2))
{
offset2 = o;
matchlen = m;
best_k = k;
}
}
}
o = offset2;
hashtable[hash, c & (QLZ_POINTERS_3 - 1)] = src;
c++;
hash_counter[hash] = c;
if (matchlen >= 3 && src - o < 131071)
{
int offset = src - o;
for (int u = 1; u < matchlen; u++)
{
fetch = source[src + u] | (source[src + u + 1] << 8) | (source[src + u + 2] << 16);
hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1);
c = hash_counter[hash]++;
hashtable[hash, c & (QLZ_POINTERS_3 - 1)] = src + u;
}
src += matchlen;
cword_val = ((cword_val >> 1) | 0x80000000);
if (matchlen == 3 && offset <= 63)
{
fast_write(destination, dst, offset << 2, 1);
dst++;
}
else if (matchlen == 3 && offset <= 16383)
{
fast_write(destination, dst, (offset << 2) | 1, 2);
dst += 2;
}
else if (matchlen <= 18 && offset <= 1023)
{
fast_write(destination, dst, ((matchlen - 3) << 2) | (offset << 6) | 2, 2);
dst += 2;
}
else if (matchlen <= 33)
{
fast_write(destination, dst, ((matchlen - 2) << 2) | (offset << 7) | 3, 3);
dst += 3;
}
else
{
fast_write(destination, dst, ((matchlen - 3) << 7) | (offset << 15) | 3, 4);
dst += 4;
}
lits = 0;
}
else
{
destination[dst] = source[src];
cword_val = (cword_val >> 1);
src++;
dst++;
}
}
}
while (src <= Length - 1)
{
if ((cword_val & 1) == 1)
{
fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4);
cword_ptr = dst;
dst += CWORD_LEN;
cword_val = 0x80000000;
}
destination[dst] = source[src];
src++;
dst++;
cword_val = (cword_val >> 1);
}
while ((cword_val & 1) != 1)
{
cword_val = (cword_val >> 1);
}
fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), CWORD_LEN);
write_header(destination, level, true, Length, dst);
d2 = new byte[dst];
System.Array.Copy(destination, d2, dst);
return d2;
}
private void fast_write(byte[] a, int i, int value, int numbytes)
{
for (int j = 0; j < numbytes; j++)
a[i + j] = (byte)(value >> (j * 8));
}
public byte[] decompress(byte[] source, int Offset, int Length)
{
int level;
int size = sizeDecompressed(source, Offset);
int src = headerLen(source, Offset) + Offset;
int dst = 0;
uint cword_val = 1;
byte[] destination = new byte[size];
int[] hashtable = new int[4096];
byte[] hash_counter = new byte[4096];
int last_matchstart = size - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END - 1;
int last_hashed = -1;
int hash;
uint fetch = 0;
level = (source[Offset] >> 2) & 0x3;
if (level != 1 && level != 3)
throw new ArgumentException("C# version only supports level 1 and 3");
if ((source[Offset] & 1) != 1)
{
byte[] d2 = new byte[size];
System.Array.Copy(source, headerLen(source, Offset), d2, Offset, size);
return d2;
}
for (; ; )
{
if (cword_val == 1)
{
cword_val = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
src += 4;
if (dst <= last_matchstart)
{
if (level == 1)
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16));
else
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
}
}
if ((cword_val & 1) == 1)
{
uint matchlen;
uint offset2;
cword_val = cword_val >> 1;
if (level == 1)
{
hash = ((int)fetch >> 4) & 0xfff;
offset2 = (uint)hashtable[hash];
if ((fetch & 0xf) != 0)
{
matchlen = (fetch & 0xf) + 2;
src += 2;
}
else
{
matchlen = source[src + 2];
src += 3;
}
}
else
{
uint offset;
if ((fetch & 3) == 0)
{
offset = (fetch & 0xff) >> 2;
matchlen = 3;
src++;
}
else if ((fetch & 2) == 0)
{
offset = (fetch & 0xffff) >> 2;
matchlen = 3;
src += 2;
}
else if ((fetch & 1) == 0)
{
offset = (fetch & 0xffff) >> 6;
matchlen = ((fetch >> 2) & 15) + 3;
src += 2;
}
else if ((fetch & 127) != 3)
{
offset = (fetch >> 7) & 0x1ffff;
matchlen = ((fetch >> 2) & 0x1f) + 2;
src += 3;
}
else
{
offset = (fetch >> 15);
matchlen = ((fetch >> 7) & 255) + 3;
src += 4;
}
offset2 = (uint)(dst - offset);
}
destination[dst + 0] = destination[offset2 + 0];
destination[dst + 1] = destination[offset2 + 1];
destination[dst + 2] = destination[offset2 + 2];
for (int i = 3; i < matchlen; i += 1)
{
destination[dst + i] = destination[offset2 + i];
}
dst += (int)matchlen;
if (level == 1)
{
fetch = (uint)(destination[last_hashed + 1] | (destination[last_hashed + 2] << 8) | (destination[last_hashed + 3] << 16));
while (last_hashed < dst - matchlen)
{
last_hashed++;
hash = (int)(((fetch >> 12) ^ fetch) & (HASH_VALUES - 1));
hashtable[hash] = last_hashed;
hash_counter[hash] = 1;
fetch = (uint)(fetch >> 8 & 0xffff | destination[last_hashed + 3] << 16);
}
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16));
}
else
{
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
}
last_hashed = dst - 1;
}
else
{
if (dst <= last_matchstart)
{
destination[dst] = source[src];
dst += 1;
src += 1;
cword_val = cword_val >> 1;
if (level == 1)
{
while (last_hashed < dst - 3)
{
last_hashed++;
int fetch2 = destination[last_hashed] | (destination[last_hashed + 1] << 8) | (destination[last_hashed + 2] << 16);
hash = ((fetch2 >> 12) ^ fetch2) & (HASH_VALUES - 1);
hashtable[hash] = last_hashed;
hash_counter[hash] = 1;
}
fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16);
}
else
{
fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16 | source[src + 3] << 24);
}
}
else
{
while (dst <= size - 1)
{
if (cword_val == 1)
{
src += CWORD_LEN;
cword_val = 0x80000000;
}
destination[dst] = source[src];
dst++;
src++;
cword_val = cword_val >> 1;
}
return destination;
}
}
}
}
}
}

View File

@ -1,177 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text;
namespace StreamLibrary.src
{
public unsafe class SimpleBitmap
{
private object ProcessingLock = new object();
public SimpleBitmapInfo Info { get; internal set; }
public bool Locked { get { return Scan0 == IntPtr.Zero ? false : true; } }
public IntPtr Scan0 { get; internal set; }
public int Scan0_int { get; internal set; }
public BitmapData bitmapData { get; internal set; }
public Bitmap bitMap { get; set; }
public class SimpleBitmapInfo
{
public SimpleBitmapInfo()
{
Clear();
}
public SimpleBitmapInfo(BitmapData data)
{
Load(data);
}
public int Stride { get; protected set; }
public int PixelSize { get; protected set; }
public int Width { get; protected set; }
public int Height { get; protected set; }
public int TotalSize { get; protected set; }
internal void Clear()
{
Stride = 0; PixelSize = 0; Width = 0; Height = 0; TotalSize = 0;
}
internal void Load(BitmapData data)
{
Width = data.Width; Height = data.Height; Stride = data.Stride;
PixelSize = Math.Abs(data.Stride) / data.Width;
TotalSize = data.Width * data.Height * PixelSize;
}
}
public static bool Compare(Rectangle block, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo)
{
int calc = 0;
int WidthSize = block.Width * sharedInfo.PixelSize;
calc = (block.Y) * sharedInfo.Stride + block.X * sharedInfo.PixelSize;
for (int i = 0; i < block.Height; i++)
{
if (NativeMethods.memcmp((byte*)(ptr1 + calc), (byte*)(ptr2 + calc), (uint)WidthSize) != 0)
return false;
calc += sharedInfo.Stride;
}
return true;
}
public static bool Compare(int y, int rowsize, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo)
{
int calc = 0;
int Size = sharedInfo.Width * sharedInfo.PixelSize * rowsize;
calc = y * sharedInfo.Stride;
if (NativeMethods.memcmp((byte*)(ptr1 + calc), (byte*)(ptr2 + calc), (uint)Size) != 0)
return false;
return true;
}
public static bool FastCompare(int offset, int size, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo)
{
if (NativeMethods.memcmp((byte*)(ptr1 + offset), (byte*)(ptr2 + offset), (uint)size) != 0)
return false;
return true;
}
public unsafe void CopyBlock(Rectangle block, ref byte[] dest)
{
int calc = 0;
int WidthSize = block.Width * Info.PixelSize;
int CopyOffset = 0;
int scan0 = Scan0.ToInt32();
int destSize = WidthSize * block.Height;
if (dest == null || dest.Length != destSize)
dest = new byte[destSize];
calc = (block.Y) * Info.Stride + block.X * Info.PixelSize;
fixed (byte* ptr = dest)
{
for (int i = 0; i < block.Height; i++)
{
NativeMethods.memcpy(new IntPtr(ptr + CopyOffset), new IntPtr(scan0 + calc), (uint)WidthSize);
calc += Info.Stride;
CopyOffset += WidthSize;
}
}
}
public SimpleBitmap()
{
Scan0 = IntPtr.Zero;
bitmapData = null;
bitMap = null;
Info = new SimpleBitmapInfo();
}
public SimpleBitmap(Bitmap bmp)
{
this.bitMap = bmp;
}
public void Lock()
{
if (Locked)
throw new Exception("Already locked");
lock (ProcessingLock)
{
bitmapData = bitMap.LockBits(new Rectangle(0, 0, bitMap.Width, bitMap.Height), ImageLockMode.ReadWrite, bitMap.PixelFormat);
Info = new SimpleBitmapInfo(bitmapData);
Scan0 = bitmapData.Scan0;
Scan0_int = Scan0.ToInt32();
}
}
public void Unlock()
{
if (!Locked)
throw new Exception("Nothing to unlock");
lock (ProcessingLock)
{
Scan0 = IntPtr.Zero;
Scan0_int = 0;
Info.Clear();
bitMap.UnlockBits(bitmapData);
bitmapData = null;
}
}
public unsafe void PlaceBlockAtRectange(byte[] block, Rectangle loc)
{
int CopySize = Info.PixelSize * loc.Width;
int OffsetX = loc.X * Info.PixelSize;
int TotalCopied = 0;
fixed (byte* ptr = block)
{
for (int i = 0; i < loc.Height; i++)
{
NativeMethods.memcpy(new IntPtr(Scan0_int + ((loc.Y + i) * Info.Stride + OffsetX)), new IntPtr(ptr + TotalCopied), (uint)CopySize);
TotalCopied += CopySize;
}
}
}
public void Dispose(bool disposeBitmap = false)
{
if (Locked)
Unlock();
if (disposeBitmap)
bitMap.Dispose();
bitMap = null;
}
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Costura.Fody.3.3.3\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.3.3.3\build\Costura.Fody.props')" /> <Import Project="..\packages\Costura.Fody.4.0.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.0.0\build\Costura.Fody.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -36,7 +36,7 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\AsyncRAT-Sharp\Resources\</OutputPath> <OutputPath>..\AsyncRAT-Sharp\bin\Debug\Stub\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@ -49,7 +49,7 @@
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>..\AsyncRAT-Sharp\Resources\</OutputPath> <OutputPath>..\AsyncRAT-Sharp\bin\Release\Stub\</OutputPath>
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@ -61,8 +61,11 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup /> <PropertyGroup />
<ItemGroup> <ItemGroup>
<Reference Include="Costura, Version=4.0.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.4.0.0\lib\net40\Costura.dll</HintPath>
</Reference>
<Reference Include="IconLib"> <Reference Include="IconLib">
<HintPath>..\packages\IconLib\IconLib.dll</HintPath> <HintPath>..\AsyncRAT-Sharp\Resources\IconLib.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.VisualBasic" /> <Reference Include="Microsoft.VisualBasic" />
<Reference Include="System" /> <Reference Include="System" />
@ -96,35 +99,12 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Settings.cs" /> <Compile Include="Settings.cs" />
<Compile Include="Sockets\ClientSocket.cs" /> <Compile Include="Sockets\ClientSocket.cs" />
<Compile Include="StreamLibrary\Codecs\DirectDriverCodec.cs" />
<Compile Include="StreamLibrary\Codecs\MJPGCodec.cs" />
<Compile Include="StreamLibrary\Codecs\QuickCachedStreamCodec.cs" />
<Compile Include="StreamLibrary\Codecs\QuickStreamCodec.cs" />
<Compile Include="StreamLibrary\Codecs\SmallCachedStreamCodec.cs" />
<Compile Include="StreamLibrary\Codecs\SmallStreamCodec.cs" />
<Compile Include="StreamLibrary\Encoders\GridCoder\GridBlock.cs" />
<Compile Include="StreamLibrary\Encoders\GridCoder\GridEncoder.cs" />
<Compile Include="StreamLibrary\Enums.cs" /> <Compile Include="StreamLibrary\Enums.cs" />
<Compile Include="StreamLibrary\IEncoder.cs" />
<Compile Include="StreamLibrary\IUnsafeCodec.cs" /> <Compile Include="StreamLibrary\IUnsafeCodec.cs" />
<Compile Include="StreamLibrary\IVideoCodec.cs" /> <Compile Include="StreamLibrary\IVideoCodec.cs" />
<Compile Include="StreamLibrary\src\CRC32.cs" />
<Compile Include="StreamLibrary\src\ExtensionAttribute.cs" />
<Compile Include="StreamLibrary\src\Extentions.cs" />
<Compile Include="StreamLibrary\src\FastBitmap.cs" />
<Compile Include="StreamLibrary\src\JpgCompression.cs" /> <Compile Include="StreamLibrary\src\JpgCompression.cs" />
<Compile Include="StreamLibrary\src\LzwCompression.cs" /> <Compile Include="StreamLibrary\src\LzwCompression.cs" />
<Compile Include="StreamLibrary\src\MurmurHash2Unsafe.cs" />
<Compile Include="StreamLibrary\src\NativeMethods.cs" /> <Compile Include="StreamLibrary\src\NativeMethods.cs" />
<Compile Include="StreamLibrary\src\PayloadWriter.cs" />
<Compile Include="StreamLibrary\src\PointerHelper.cs" />
<Compile Include="StreamLibrary\src\SafeQuickLZ.cs" />
<Compile Include="StreamLibrary\src\SimpleBitmap.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeCacheCodec.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeCachedStreamCodec.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeMiniCodec.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeOptimizedCodec.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeQuickStream.cs" />
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeStreamCodec.cs" /> <Compile Include="StreamLibrary\UnsafeCodecs\UnsafeStreamCodec.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -139,12 +119,12 @@
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Fody.4.0.2\build\Fody.targets" Condition="Exists('..\packages\Fody.4.0.2\build\Fody.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup> <PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('..\packages\Fody.4.0.2\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.4.0.2\build\Fody.targets'))" /> <Error Condition="!Exists('..\packages\Costura.Fody.4.0.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.4.0.0\build\Costura.Fody.props'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.3.3.3\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.3.3.3\build\Costura.Fody.props'))" /> <Error Condition="!Exists('..\packages\Fody.5.0.5\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.5.0.5\build\Fody.targets'))" />
</Target> </Target>
<Import Project="..\packages\Fody.5.0.5\build\Fody.targets" Condition="Exists('..\packages\Fody.5.0.5\build\Fody.targets')" />
</Project> </Project>

View File

@ -14,7 +14,11 @@ namespace Client
public static readonly string Password = "NYAN CAT"; public static readonly string Password = "NYAN CAT";
public static readonly Aes256 aes256 = new Aes256(Password); public static readonly Aes256 aes256 = new Aes256(Password);
public static readonly string MTX = "%MTX%"; public static readonly string MTX = "%MTX%";
public static readonly string Anti = "%Anti%"; #if DEBUG
//public static readonly string Anti = "false"; public static readonly string Anti = "false";
#else
public static readonly string Anti = "%Anti%";
#endif
} }
} }

View File

@ -199,23 +199,29 @@ namespace Client.Sockets
public static void CheckServer(object obj) public static void CheckServer(object obj)
{ {
try lock (SendSync)
{ {
MsgPack msgpack = new MsgPack(); lock (EndSendSync)
msgpack.ForcePathObject("Packet").AsString = "Ping"; {
msgpack.ForcePathObject("Message").AsString = $"CPU {(int)TheCPUCounter.NextValue()}% RAM {(int)TheMemCounter.NextValue()}%"; try
{
MsgPack msgpack = new MsgPack();
msgpack.ForcePathObject("Packet").AsString = "Ping";
msgpack.ForcePathObject("Message").AsString = $"CPU {(int)TheCPUCounter.NextValue()}% RAM {(int)TheMemCounter.NextValue()}%";
byte[] buffer = Settings.aes256.Encrypt(msgpack.Encode2Bytes()); byte[] buffer = Settings.aes256.Encrypt(msgpack.Encode2Bytes());
byte[] buffersize = BitConverter.GetBytes(buffer.Length); byte[] buffersize = BitConverter.GetBytes(buffer.Length);
Client.Poll(-1, SelectMode.SelectWrite); Client.Poll(-1, SelectMode.SelectWrite);
Client.Send(buffersize, 0, buffersize.Length, SocketFlags.None); Client.Send(buffersize, 0, buffersize.Length, SocketFlags.None);
Client.Send(buffer, 0, buffer.Length, SocketFlags.None); Client.Send(buffer, 0, buffer.Length, SocketFlags.None);
} }
catch catch
{ {
IsConnected = false; IsConnected = false;
return; return;
}
}
} }
} }
} }

View File

@ -1,160 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class DirectDriverCodec
{
private Bitmap decodedBitmap;
private byte[] EncodeBuffer;
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private JpgCompression jpgCompression;
public DirectDriverCodec(int Quality)
{
jpgCompression = new JpgCompression(Quality);
}
public unsafe void CodeImage(IntPtr Scan0, Rectangle[] Changes, Size ImageSize, PixelFormat Format, Stream outStream)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
Stride = ImageSize.Width * PixelSize;
RawLength = Stride * ImageSize.Height;
if (EncodeBuffer == null)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
this.EncodeBuffer = new byte[RawLength];
fixed (byte* ptr = EncodeBuffer)
{
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
}
return;
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
for (int i = 0; i < Changes.Length; i++)
{
Rectangle rect = Changes[i];
int blockStride = PixelSize * rect.Width;
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
}
public Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
return decodedBitmap;
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
}
}

View File

@ -1,68 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
/// <summary>
/// The M-JPG codec is not very efficient for networking as it is just a very simple codec
/// </summary>
public class MJPGCodec : IVideoCodec
{
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override ulong CachedSize
{
get { return 0; }
internal set { }
}
public override int BufferCount
{
get { return 0; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.None; }
}
public MJPGCodec(int ImageQuality = 100)
: base(ImageQuality)
{
}
public override void CodeImage(Bitmap bitmap, Stream outStream)
{
lock (base.jpgCompression)
{
byte[] data = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(data.Length), 0, 4);
outStream.Write(data, 0, data.Length);
}
}
public override Bitmap DecodeData(Stream inStream)
{
lock (base.jpgCompression)
{
if (!inStream.CanRead)
throw new Exception("Must have access to Read in the Stream");
byte[] temp = new byte[4];
inStream.Read(temp, 0, temp.Length);
int DataLength = BitConverter.ToInt32(temp, 0);
temp = new byte[DataLength];
inStream.Read(temp, 0, temp.Length);
return (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
}
}
}
}

View File

@ -1,204 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class QuickCachedStreamCodec : IVideoCodec
{
private Bitmap CodeTempBitmap;
private Bitmap DecodeTempBitmap;
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override ulong CachedSize
{
get;
internal set;
}
public int MaxBuffers { get; private set; }
private SortedList<int, byte[]> EncodeCache;
private SortedList<int, byte[]> DecodeCache;
/// <summary>
/// Initialize a new object of QuickStreamCodec
/// </summary>
/// <param name="ImageQuality">The image quality 0-100%</param>
public QuickCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100)
: base(ImageQuality)
{
this.MaxBuffers = MaxBuffers;
this.EncodeCache = new SortedList<int, byte[]>();
this.DecodeCache = new SortedList<int, byte[]>();
}
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.RequireSameSize | CodecOption.AutoDispose; }
}
public override unsafe void CodeImage(Bitmap bitmap, Stream outStream)
{
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
if (CodeTempBitmap != null)
{
if (CodeTempBitmap.Width != bitmap.Width || CodeTempBitmap.Height != bitmap.Height)
throw new Exception("Bitmap width/height are not equal to previous bitmap");
if (bitmap.PixelFormat != CodeTempBitmap.PixelFormat)
throw new Exception("PixelFormat is not equal to previous Bitmap");
}
if (CodeTempBitmap == null)
{
byte[] temp = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
CodeTempBitmap = bitmap;
return;
}
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
BitmapData CodeBmpData = CodeTempBitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
int Stride = Math.Abs(bmpData.Stride);
List<Rectangle> Blocks = new List<Rectangle>();
for (int y = 0, i = 0; y < bitmap.Height; y++, i += Stride)
{
if (onCodeDebugScan != null)
onCodeDebugScan(new Rectangle(0, y, bitmap.Width, 1));
Rectangle ScanBlock = new Rectangle(0, y, bitmap.Width, 1);
if (NativeMethods.memcmp(new IntPtr(bmpData.Scan0.ToInt32() + i), new IntPtr(CodeBmpData.Scan0.ToInt32() + i), (uint)Stride) != 0)
{
byte[] temp = new byte[Stride];
fixed(byte* ptr = temp)
{
NativeMethods.memcpy(ptr, (void*)(bmpData.Scan0.ToInt32() + i), (uint)temp.Length);
}
CRC32 hasher = new CRC32();
int hash = BitConverter.ToInt32(hasher.ComputeHash(temp), 0);
if (EncodeCache.Count >= MaxBuffers)
EncodeCache.RemoveAt(0);
if (EncodeCache.ContainsKey(hash))
{
outStream.WriteByte(1);
outStream.Write(new byte[4], 0, 4);
outStream.Write(BitConverter.GetBytes(hash), 0, 4);
outStream.Write(BitConverter.GetBytes((ushort)y), 0, 2);
}
else
{
outStream.WriteByte(0);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(BitConverter.GetBytes(hash), 0, 4);
outStream.Write(BitConverter.GetBytes((ushort)y), 0, 2);
outStream.Write(temp, 0, temp.Length);
EncodeCache.Add(hash, temp);
}
Blocks.Add(ScanBlock);
}
}
for (int i = 0; i < Blocks.Count; i++)
{
Bitmap cloned = (Bitmap)bitmap.Clone(Blocks[i], bitmap.PixelFormat);
byte[] temp = base.jpgCompression.Compress(cloned);
cloned.Dispose();
}
bitmap.UnlockBits(bmpData);
CodeTempBitmap.UnlockBits(CodeBmpData);
if (onVideoStreamCoding != null)
onVideoStreamCoding(outStream, Blocks.ToArray());
if (CodeTempBitmap != null)
CodeTempBitmap.Dispose();
this.CodeTempBitmap = bitmap;
}
public override Bitmap DecodeData(Stream inStream)
{
if (!inStream.CanRead)
throw new Exception("Must have access to Read in the Stream");
if (DecodeTempBitmap == null)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
DecodeTempBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return DecodeTempBitmap;
}
//BitmapData BmpData = DecodeTempBitmap.LockBits(new Rectangle(0, 0, DecodeTempBitmap.Width, DecodeTempBitmap.Height), ImageLockMode.WriteOnly, DecodeTempBitmap.PixelFormat);
//int Stride = Math.Abs(BmpData.Stride);
while (inStream.Position < inStream.Length)
{
byte[] temp = new byte[11];
if (inStream.Read(temp, 0, temp.Length) != temp.Length)
break;
bool inCache = temp[0] == 1;
int DataSize = BitConverter.ToInt32(temp, 1);
int Hash = BitConverter.ToInt32(temp, 5);
ushort Y = BitConverter.ToUInt16(temp, 9);
temp = new byte[DataSize];
if (inStream.Read(temp, 0, temp.Length) != temp.Length)
break;
if (inCache)
{
if (DecodeCache.ContainsKey(Hash))
{
temp = DecodeCache[Hash];
}
else
{
}
}
//copy new data to cached bitmap
Bitmap tmpBmp = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
using (Graphics g = Graphics.FromImage(DecodeTempBitmap))
{
g.DrawImage(tmpBmp, new Point(0, Y));
}
/*BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.WriteOnly, tmpBmp.PixelFormat);
int Offset = Y * Stride;
NativeMethods.memcpy(new IntPtr(BmpData.Scan0.ToInt32() + Offset), tmpData.Scan0, (uint)(tmpBmp.Height * Stride));*/
//tmpBmp.UnlockBits(tmpData);
tmpBmp.Dispose();
}
//DecodeTempBitmap.UnlockBits(BmpData);
return DecodeTempBitmap;
}
}
}

View File

@ -1,179 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class QuickStreamCodec : IVideoCodec
{
private Bitmap CodeTempBitmap;
private Bitmap DecodeTempBitmap;
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override ulong CachedSize
{
get;
internal set;
}
/// <summary>
/// Initialize a new object of QuickStreamCodec
/// </summary>
/// <param name="ImageQuality">The image quality 0-100%</param>
public QuickStreamCodec(int ImageQuality = 100)
: base(ImageQuality)
{
}
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.RequireSameSize | CodecOption.AutoDispose; }
}
public override void CodeImage(Bitmap bitmap, Stream outStream)
{
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
if (CodeTempBitmap != null)
{
if (CodeTempBitmap.Width != bitmap.Width || CodeTempBitmap.Height != bitmap.Height)
throw new Exception("Bitmap width/height are not equal to previous bitmap");
if (bitmap.PixelFormat != CodeTempBitmap.PixelFormat)
throw new Exception("PixelFormat is not equal to previous Bitmap");
}
if (CodeTempBitmap == null)
{
byte[] temp = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
CodeTempBitmap = bitmap;
return;
}
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
BitmapData CodeBmpData = CodeTempBitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
int Stride = Math.Abs(bmpData.Stride);
List<Rectangle> Blocks = new List<Rectangle>();
for (int y = 0, i = 0; y < bitmap.Height; y++, i += Stride)
{
if(onCodeDebugScan != null)
onCodeDebugScan(new Rectangle(0, y, bitmap.Width, 1));
Rectangle ScanBlock = new Rectangle(0, y, bitmap.Width, 1);
if (NativeMethods.memcmp(new IntPtr(bmpData.Scan0.ToInt32() + i), new IntPtr(CodeBmpData.Scan0.ToInt32() + i), (uint)Stride) != 0)
{
int index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == ScanBlock.Y)
{
ScanBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + ScanBlock.Height);
Blocks[index] = ScanBlock;
}
else
{
Blocks.Add(ScanBlock);
}
}
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
for (int i = 0; i < Blocks.Count; i++)
{
Bitmap cloned = (Bitmap)bitmap.Clone(Blocks[i], bitmap.PixelFormat);
byte[] temp = base.jpgCompression.Compress(cloned);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(BitConverter.GetBytes((ushort)Blocks[i].Y), 0, 2);
outStream.Write(temp, 0, temp.Length);
cloned.Dispose();
TotalDataLength += 6 + temp.Length;
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
bitmap.UnlockBits(bmpData);
CodeTempBitmap.UnlockBits(CodeBmpData);
if (onVideoStreamCoding != null)
onVideoStreamCoding(outStream, Blocks.ToArray());
if (CodeTempBitmap != null)
CodeTempBitmap.Dispose();
this.CodeTempBitmap = bitmap;
}
public override Bitmap DecodeData(Stream inStream)
{
if (!inStream.CanRead)
throw new Exception("Must have access to Read in the Stream");
if (DecodeTempBitmap == null)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 4);
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
DecodeTempBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return DecodeTempBitmap;
}
byte[] LenTemp = new byte[4];
inStream.Read(LenTemp, 0, 4);
int DataLength = BitConverter.ToInt32(LenTemp, 0);
//BitmapData BmpData = DecodeTempBitmap.LockBits(new Rectangle(0, 0, DecodeTempBitmap.Width, DecodeTempBitmap.Height), ImageLockMode.WriteOnly, DecodeTempBitmap.PixelFormat);
//int Stride = Math.Abs(BmpData.Stride);
while (DataLength > 0)
{
byte[] temp = new byte[6];
if (inStream.Read(temp, 0, temp.Length) != temp.Length)
break;
int DataSize = BitConverter.ToInt32(temp, 0);
ushort Y = BitConverter.ToUInt16(temp, 4);
temp = new byte[DataSize];
if (inStream.Read(temp, 0, temp.Length) != temp.Length)
break;
//copy new data to cached bitmap
Bitmap tmpBmp = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
using (Graphics g = Graphics.FromImage(DecodeTempBitmap))
{
g.DrawImage(tmpBmp, new Point(0, Y));
}
/*BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.WriteOnly, tmpBmp.PixelFormat);
int Offset = Y * Stride;
NativeMethods.memcpy(new IntPtr(BmpData.Scan0.ToInt32() + Offset), tmpData.Scan0, (uint)(tmpBmp.Height * Stride));*/
//tmpBmp.UnlockBits(tmpData);
tmpBmp.Dispose();
DataLength -= 6 + temp.Length;
}
//DecodeTempBitmap.UnlockBits(BmpData);
return DecodeTempBitmap;
}
}
}

View File

@ -1,374 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class SmallCachedStreamCodec : IVideoCodec
{
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
SortedList<int, byte[]> codeCached;
SortedList<int, byte[]> decodeCached;
public override int BufferCount
{
get { return codeCached.Count; }
}
public override ulong CachedSize
{
get;
internal set;
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.HasBuffers | CodecOption.RequireSameSize; }
}
private Size CheckBlock { get; set; }
public SimpleBitmap LastFrame { get; set; }
private object ImageProcessLock = new object();
private Bitmap decodedBitmap;
private CRC32 hasher;
public int MaxBuffers { get; private set; }
/// <summary>
/// Initialize a new object of SmallCachedStreamCodec
/// </summary>
/// <param name="MaxBuffers">The maximum amount of buffers, higher value will decrease stream size but could decrease performance</param>
/// <param name="ImageQuality">The image quality 0-100%</param>
public SmallCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100)
: base(ImageQuality)
{
CheckBlock = new Size(20, 1);
codeCached = new SortedList<int, byte[]>();
decodeCached = new SortedList<int, byte[]>();
hasher = new CRC32();
this.MaxBuffers = MaxBuffers;
}
private void SetLastFrame(ref Bitmap bmp)
{
SetLastFrame(new SimpleBitmap(bmp));
}
private void SetLastFrame(SimpleBitmap bmp)
{
lock (ImageProcessLock)
{
if (LastFrame != null && LastFrame.Locked)
LastFrame.Dispose(true);
LastFrame = bmp;
}
}
public override unsafe void CodeImage(Bitmap bitmap, Stream outStream)
{
lock (ImageProcessLock)
{
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
if (LastFrame == null)
{
byte[] temp = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
SetLastFrame(ref bitmap);
return;
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<byte[]> updates = new List<byte[]>();
SimpleBitmap sbBmp = new SimpleBitmap(bitmap);
MemoryStream ms = new MemoryStream();
byte[] buffer = null;
if (!LastFrame.Locked)
LastFrame.Lock();
sbBmp.Lock();
if (sbBmp.Info.PixelSize != LastFrame.Info.PixelSize)
throw new Exception("PixelFormat is not equal to previous Bitmap");
if (LastFrame.Info.Width != sbBmp.Info.Width || LastFrame.Info.Height != sbBmp.Info.Height)
{
sbBmp.Unlock();
throw new Exception("Bitmap width/height are not equal to previous bitmap");
}
List<Rectangle> Blocks = new List<Rectangle>();
int index = 0;
int y = 0;
int x = 0;
Size s = new Size(bitmap.Width, CheckBlock.Height);
Size lastSize = new Size(bitmap.Width % CheckBlock.Width, bitmap.Height % CheckBlock.Height);
int lasty = bitmap.Height - lastSize.Height;
int lastx = bitmap.Width - lastSize.Width;
Rectangle cBlock = new Rectangle();
s = new Size(bitmap.Width, s.Height);
while (y != bitmap.Height)
{
if (y == lasty)
s = new Size(bitmap.Width, lastSize.Height);
cBlock = new Rectangle(0, y, bitmap.Width, s.Height);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (!SimpleBitmap.Compare(cBlock, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info))
//if (!SimpleBitmap.Compare(y, s.Height, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info))
{
index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
{
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
Blocks[index] = cBlock;
}
else
{
Blocks.Add(cBlock);
}
}
y += s.Height;
}
List<CacheInfo> finalUpdates = new List<CacheInfo>();
const int CheckHeight = 50;
for (int i = 0; i < Blocks.Count; i++)
{
s = new Size(CheckBlock.Width, Blocks[i].Height);
y = Blocks[i].Y;
lasty = (Blocks[i].Y + Blocks[i].Height);
while (y != lasty)
{
int ScanHeight = y + CheckHeight > lasty ? lasty - y : CheckHeight;
x = 0;
while (x != bitmap.Width)
{
if (x == lastx)
s = new Size(lastSize.Width, Blocks[i].Height);
cBlock = new Rectangle(x, y, s.Width, ScanHeight);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (!SimpleBitmap.Compare(cBlock, sbBmp.Scan0_int, LastFrame.Scan0_int, sbBmp.Info))
{
/*byte[] tempData = new byte[0];
LastFrame.CopyBlock(cBlock, ref tempData);
finalUpdates.Add(new CacheInfo(0, false, tempData, cBlock));*/
//hash it and see if exists in cache
hasher = new CRC32(); //re-initialize for seed
byte[] tempData = new byte[0];
LastFrame.CopyBlock(cBlock, ref tempData);
int hash = BitConverter.ToInt32(hasher.ComputeHash(tempData), 0);
if (codeCached.Count >= MaxBuffers)
codeCached.RemoveAt(0);
if (codeCached.ContainsKey(hash))
{
CachedSize += (ulong)tempData.Length;
finalUpdates.Add(new CacheInfo(hash, true, new byte[0], cBlock));
}
else
{
//nothing found in cache let's use the normal way
codeCached.Add(hash, tempData);
finalUpdates.Add(new CacheInfo(hash, false, tempData, cBlock));
}
}
x += s.Width;
}
y += ScanHeight;
}
}
for (int i = 0; i < finalUpdates.Count; i++)
{
buffer = new byte[0];
Rectangle rect = finalUpdates[i].Rect;
if (!finalUpdates[i].isCached)
{
fixed (byte* ptr = finalUpdates[i].Data)
{
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * LastFrame.Info.PixelSize, LastFrame.bitmapData.PixelFormat, new IntPtr(ptr)))
{
buffer = base.jpgCompression.Compress(TmpBmp);
}
}
}
outStream.WriteByte(finalUpdates[i].isCached ? (byte)1 : (byte)0);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Height), 0, 4);
outStream.Write(BitConverter.GetBytes(finalUpdates[i].Hash), 0, 4);
outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
outStream.Write(buffer, 0, buffer.Length);
TotalDataLength += buffer.Length + (4 * 6) + 1;
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
Blocks.Clear();
SetLastFrame(sbBmp);
ms.Close();
ms.Dispose();
}
}
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
List<CacheInfo> cacheInfo = new List<CacheInfo>();
byte[] HeaderData = new byte[(4 * 6) + 1];
while (DataSize > 0)
{
inStream.Read(HeaderData, 0, HeaderData.Length);
bool isCached = HeaderData[0] == 1;
rect = new Rectangle(BitConverter.ToInt32(HeaderData, 1), BitConverter.ToInt32(HeaderData, 5),
BitConverter.ToInt32(HeaderData, 9), BitConverter.ToInt32(HeaderData, 13));
int Hash = BitConverter.ToInt32(HeaderData, 17);
int UpdateLen = BitConverter.ToInt32(HeaderData, 21);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
//process update data
if (isCached)
{
//data is cached
if (decodeCached.ContainsKey(Hash))
buffer = decodeCached[Hash];
else
{
}
cacheInfo.Add(new CacheInfo(Hash, true, new byte[0], rect));
}
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
if (buffer.Length > 0)
{
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
}
if (decodeCached.Count >= MaxBuffers)
decodeCached.RemoveAt(0);
if(!decodeCached.ContainsKey(Hash))
this.decodeCached.Add(Hash, buffer);
DataSize -= UpdateLen + HeaderData.Length;
}
int CachedSize = 0;
foreach(CacheInfo inf in cacheInfo)
{
CachedSize += (inf.Rect.Width * 4) * inf.Rect.Height;
}
Console.WriteLine(cacheInfo.Count + ", " + CachedSize);
g.Dispose();
return decodedBitmap;
}
private class CacheInfo
{
public bool isCached = false;
public byte[] Data;
public int Hash;
public Rectangle Rect;
public CacheInfo(int Hash, bool isCached, byte[] Data, Rectangle Rect)
{
this.Hash = Hash;
this.isCached = isCached;
this.Data = Data;
this.Rect = Rect;
}
/*public unsafe void CreateHashList(SimpleBitmap sBmp, Size CheckBlock, SmallCachedStreamCodec codec)
{
if (ScanRects.Count > 0)
{
int scanX = ScanRects[0].X;
for (int i = 0; i < ScanRects.Count; i++)
{
int scanWidth = ScanRects[i].Width > CheckBlock.Width ? CheckBlock.Width : ScanRects[i].Width;
Rectangle rect = ScanRects[i];
rect.Width = scanWidth;
rect.X = scanX;
byte[] buffer = new byte[0];
sBmp.CopyBlock(rect, ref buffer);
int hash = BitConverter.ToInt32(new CRC32().ComputeHash(buffer), 0);
if (!HashList.ContainsKey(hash))
HashList.Add(hash, rect);
//fixed (byte* ptr = buffer)
//{
// using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * sBmp.Info.PixelSize, sBmp.bitmapData.PixelFormat, new IntPtr(ptr)))
// {
// buffer = codec.lzwCompression.Compress(TmpBmp);
//
// }
//}
scanX += scanWidth;
}
}
}*/
}
}
}

View File

@ -1,266 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
namespace StreamLibrary.Codecs
{
public class SmallStreamCodec : IVideoCodec
{
public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding;
public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 1; }
}
public override ulong CachedSize
{
get;
internal set;
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; }
}
public Size CheckBlock { get; set; }
public SimpleBitmap LastFrame { get; set; }
private object ImageProcessLock = new object();
private Bitmap decodedBitmap;
/// <summary>
/// Initialize a new object of SmallStreamCodec
/// </summary>
/// <param name="ImageQuality">The image quality 0-100%</param>
public SmallStreamCodec(int ImageQuality = 100)
: base(ImageQuality)
{
CheckBlock = new Size(20, 1);
}
private void SetLastFrame(ref Bitmap bmp)
{
SetLastFrame(new SimpleBitmap(bmp));
}
private void SetLastFrame(SimpleBitmap bmp)
{
lock (ImageProcessLock)
{
if (LastFrame != null && LastFrame.Locked)
LastFrame.Dispose(true);
LastFrame = bmp;
}
}
/// <summary>
/// Encode the image
/// </summary>
/// <param name="bitmap">The image you want to encode.</param>
/// <param name="outStream">The output stream</param>
public override unsafe void CodeImage(Bitmap bitmap, Stream outStream)
{
lock (ImageProcessLock)
{
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
if (LastFrame == null)
{
byte[] temp = base.jpgCompression.Compress(bitmap);
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
SetLastFrame(ref bitmap);
return;
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<byte[]> updates = new List<byte[]>();
SimpleBitmap sbBmp = new SimpleBitmap(bitmap);
MemoryStream ms = new MemoryStream();
byte[] buffer = null;
if (!LastFrame.Locked)
LastFrame.Lock();
sbBmp.Lock();
if (sbBmp.Info.PixelSize != LastFrame.Info.PixelSize)
throw new Exception("PixelFormat is not equal to previous Bitmap");
if (LastFrame.Info.Width != sbBmp.Info.Width || LastFrame.Info.Height != sbBmp.Info.Height)
{
sbBmp.Unlock();
throw new Exception("Bitmap width/height are not equal to previous bitmap");
}
List<Rectangle> Blocks = new List<Rectangle>();
int index = 0;
int y = 0;
int x = 0;
Size s = new Size(bitmap.Width, CheckBlock.Height);
Size lastSize = new Size(bitmap.Width % CheckBlock.Width, bitmap.Height % CheckBlock.Height);
int lasty = bitmap.Height - lastSize.Height;
int lastx = bitmap.Width - lastSize.Width;
Rectangle cBlock = new Rectangle();
s = new Size(bitmap.Width, s.Height);
while (y != bitmap.Height)
{
if (y == lasty)
s = new Size(bitmap.Width, lastSize.Height);
cBlock = new Rectangle(0, y, bitmap.Width, s.Height);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (!SimpleBitmap.Compare(cBlock, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info))
//if (!SimpleBitmap.Compare(y, s.Height, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info))
{
index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
{
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
Blocks[index] = cBlock;
}
else
{
Blocks.Add(cBlock);
}
}
y += s.Height;
}
List<Rectangle> finalUpdates = new List<Rectangle>();
for (int i = 0; i < Blocks.Count; i++)
{
s = new Size(CheckBlock.Width, Blocks[i].Height);
x = 0;
while (x != bitmap.Width)
{
if (x == lastx)
s = new Size(lastSize.Width, Blocks[i].Height);
cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (!SimpleBitmap.Compare(cBlock, sbBmp.Scan0_int, LastFrame.Scan0_int, sbBmp.Info))
{
index = finalUpdates.Count - 1;
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
{
Rectangle rect = finalUpdates[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
finalUpdates[index] = cBlock;
}
else
{
finalUpdates.Add(cBlock);
}
}
x += s.Width;
}
}
for (int i = 0; i < finalUpdates.Count; i++)
{
Rectangle rect = finalUpdates[i];
sbBmp.CopyBlock(rect, ref buffer);
fixed (byte* ptr = buffer)
{
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * LastFrame.Info.PixelSize, LastFrame.bitmapData.PixelFormat, new IntPtr(ptr)))
{
buffer = base.jpgCompression.Compress(TmpBmp);
}
}
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
outStream.Write(buffer, 0, buffer.Length);
TotalDataLength += buffer.Length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
Blocks.Clear();
SetLastFrame(sbBmp);
ms.Close();
ms.Dispose();
}
}
/// <summary>
/// Decode the video stream
/// </summary>
/// <param name="inStream">The input stream</param>
/// <returns>The image that has been decoded</returns>
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= buffer.Length + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace StreamLibrary.Encoders.GridCoder
{
internal class GridBlock
{
public Rectangle Rect { get; private set; }
public ulong Hash { get; private set; }
private GridEncoder encoder;
public GridBlock(Rectangle Rect, GridEncoder encoder)
{
this.encoder = encoder;
this.Rect = Rect;
CalculateHash();
}
public void CalculateHash()
{
}
}
}

View File

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace StreamLibrary.Encoders.GridCoder
{
public class GridEncoder : IEncoder
{
public override ulong CachedSize
{
get;
internal set;
}
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; }
}
public override unsafe void CodeImage(IntPtr Scan0, System.Drawing.Rectangle ScanArea, System.Drawing.Size ImageSize, System.Drawing.Imaging.PixelFormat Format, System.IO.Stream outStream)
{
}
public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream)
{
return null;
}
public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
return null;
}
}
}

View File

@ -1,46 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary
{
public abstract class IEncoder
{
protected LzwCompression lzwCompression;
public abstract ulong CachedSize { get; internal set; }
protected object ImageProcessLock { get; private set; }
private int _imageQuality;
public int ImageQuality
{
get { return _imageQuality; }
set
{
_imageQuality = value;
lzwCompression = new LzwCompression(value);
}
}
public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public IEncoder(int ImageQuality = 100)
{
this.ImageQuality = ImageQuality;
this.ImageProcessLock = new object();
}
public abstract int BufferCount { get; }
public abstract CodecOption CodecOptions { get; }
public abstract unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream);
public abstract unsafe Bitmap DecodeData(Stream inStream);
public abstract unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length);
}
}

View File

@ -1,324 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeCacheCodec : IUnsafeCodec
{
private const int BlockCount = 5;
private const int HashBlockCount = 8192;
public override ulong CachedSize
{
get { return 0; }
internal set { }
}
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 0; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.HasBuffers | CodecOption.RequireSameSize; }
}
private Bitmap decodedBitmap;
private int EncodedWidth;
private int EncodedHeight;
private PixelFormat EncodedFormat;
private MurmurHash2Unsafe hasher;
private SortedList<int, SortedList<int, uint>> EncodeBuffer;
private Rectangle[] Offsets;
private BlockInfo[] EncodeHashBlocks;
private BlockInfo[] DecodeHashBlocks;
public ulong EncodedFrames { get; private set; }
public ulong DecodedFrames { get; private set; }
public UnsafeCacheCodec(int ImageQuality = 80)
: base(ImageQuality)
{
this.hasher = new MurmurHash2Unsafe();
this.Offsets = new Rectangle[BlockCount];
this.EncodeHashBlocks = new BlockInfo[HashBlockCount];
this.DecodeHashBlocks = new BlockInfo[HashBlockCount];
for (int i = 0; i < HashBlockCount; i++)
{
EncodeHashBlocks[i] = new BlockInfo();
DecodeHashBlocks[i] = new BlockInfo();
}
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
{
if (ImageSize.Width == 0 || ImageSize.Height == 0)
throw new ArgumentException("The width and height must be 1 or higher");
if (ImageSize.Width < BlockCount || ImageSize.Height < BlockCount)
throw new Exception("The Image size Width/Height must be bigger then the Block Count " + BlockCount + "x" + BlockCount);
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
int Stride = ImageSize.Width * PixelSize;
int RawLength = Stride * ImageSize.Height;
if (EncodedFrames == 0)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
double size = (double)ImageSize.Width / (double)BlockCount;
//fix floating point here
for (int i = 0, j = 0; i < BlockCount; i++, j += (int)size)
{
Offsets[i] = new Rectangle(j, 0, (int)size, 1);
}
EncodeBuffer = new SortedList<int, SortedList<int, uint>>();
for (int y = 0; y < ImageSize.Height; y++)
{
for(int i = 0; i < Offsets.Length; i++)
{
if (!EncodeBuffer.ContainsKey(y))
EncodeBuffer.Add(y, new SortedList<int, uint>());
if (!EncodeBuffer[y].ContainsKey(Offsets[i].X))
EncodeBuffer[y].Add(Offsets[i].X, 0); //0=hash
}
}
EncodedFrames++;
return;
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<HashBlock> ImageOffsets = new List<HashBlock>();
List<uint> ImageHashes = new List<uint>();
byte* pScan0 = (byte*)Scan0.ToInt32();
for (int i = 0; i < Offsets.Length; i++)
{
for (int y = 0; y < ImageSize.Height; y++)
{
Rectangle ScanRect = Offsets[i];
ScanRect.Y = y;
int offset = (y * Stride) + (ScanRect.X * PixelSize);
if (offset+Stride > Stride * ImageSize.Height)
break;
uint Hash = hasher.Hash(pScan0 + offset, (int)Stride);
uint BlockOffset = Hash % HashBlockCount;
BlockInfo blockInfo = EncodeHashBlocks[BlockOffset];
if (EncodeBuffer[y][ScanRect.X] != Hash)
{
if (!blockInfo.Hashes.ContainsKey(Hash))
{
int index = ImageOffsets.Count - 1;
if (ImageOffsets.Count > 0 && ImageOffsets[index].Location.Y + 1 == ScanRect.Y)
{
Rectangle rect = ImageOffsets[index].Location;
ImageOffsets[index].Location = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height + 1);
}
else
{
ImageOffsets.Add(new HashBlock(Hash, false, new Rectangle(ScanRect.X, y, ScanRect.Width, 1)));
}
blockInfo.Hashes.Add(Hash, new HashBlock(Hash, false, new Rectangle(ScanRect.X, y, ScanRect.Width, 1)));
ImageHashes.Add(Hash);
}
EncodeBuffer[y][ScanRect.X] = Hash;
}
}
}
if (ImageOffsets.Count > 0)
{
for (int i = 0; i < Offsets.Length; i++)
{
Rectangle TargetOffset = Offsets[i];
int Height = GetOffsetHeight(ImageOffsets, TargetOffset);
Bitmap TmpBmp = new Bitmap(TargetOffset.Width, Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
int blockStride = PixelSize * TargetOffset.Width;
List<HashBlock> UsedOffsets = new List<HashBlock>();
for (int j = 0; j < ImageOffsets.Count; j++)
{
Rectangle rect = ImageOffsets[j].Location;
if (rect.Width != TargetOffset.Width || rect.X != TargetOffset.X)
continue; //error in 1440p, did not tested futher
for (int o = 0, offset = 0; o < rect.Height; o++)
{
int blockOffset = (Stride * (rect.Y + o)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
UsedOffsets.Add(ImageOffsets[j]);
}
}
TmpBmp.UnlockBits(TmpData);
TmpBmp.Dispose();
outStream.Write(BitConverter.GetBytes((short)UsedOffsets.Count), 0, 2);
if (UsedOffsets.Count > 0)
{
outStream.Write(BitConverter.GetBytes((short)UsedOffsets[0].Location.X), 0, 2);
for (int j = 0; j < UsedOffsets.Count; j++)
{
outStream.Write(BitConverter.GetBytes((short)UsedOffsets[j].Location.Y), 0, 2);
outStream.Write(BitConverter.GetBytes((short)UsedOffsets[j].Location.Height), 0, 2);
outStream.Write(BitConverter.GetBytes(UsedOffsets[j].Hash), 0, 4);
}
byte[] CompressedImg = base.jpgCompression.Compress(TmpBmp);
outStream.Write(BitConverter.GetBytes(CompressedImg.Length), 0, 4);
outStream.Write(CompressedImg, 0, CompressedImg.Length);
}
//TotalDataLength += (int)length + (4 * 5);
}
}
EncodedFrames++;
}
private int GetOffsetHeight(List<HashBlock> ImageOffsets, Rectangle rect)
{
int height = 0;
for (int i = 0; i < ImageOffsets.Count; i++)
{
if (ImageOffsets[i].Location.Width == rect.Width && ImageOffsets[i].Location.X == rect.X)
height += ImageOffsets[i].Location.Height;
}
return height;
}
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
//return decodedBitmap;
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
return null;
}
private class BlockInfo
{
public SortedList<uint, HashBlock> Hashes { get; private set; }
public BlockInfo()
{
Hashes = new SortedList<uint, HashBlock>();
}
}
private class HashBlock
{
public bool Cached { get; set; }
public uint Hash { get; set; }
public Rectangle Location { get; set; }
public HashBlock(uint Hash, bool Cached, Rectangle Location)
{
this.Hash = Hash;
this.Cached = Cached;
this.Location = Location;
}
public HashBlock()
{
}
}
private class ImageOffset
{
public Rectangle Location { get; set; }
public List<uint> Hashes { get; set; }
public ImageOffset()
{
this.Hashes = new List<uint>();
}
}
}
}

View File

@ -1,308 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeCachedStreamCodec : IUnsafeCodec
{
public override ulong CachedSize
{
get;
internal set;
}
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 0; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.HasBuffers; }
}
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private static Size CheckBlock = new Size(50, 50);
private MurmurHash2Unsafe Hasher = new MurmurHash2Unsafe();
private List<Frame> Frames = new List<Frame>();
public const int MAX_FRAMES = 120;
private ulong[] DecodeBuffer;
private Bitmap DecodedBitmap;
private List<Bitmap> DecodedFrames = new List<Bitmap>();
public UnsafeCachedStreamCodec(int ImageQuality)
: base(ImageQuality)
{
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
Stride = ImageSize.Width * PixelSize;
RawLength = Stride * ImageSize.Height;
if (EncodedWidth == 0 && EncodedHeight == 0)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
return;
}
Frame frame = new Frame(ImageSize.Width, ImageSize.Height);
int Blocks = (ScanArea.Width / CheckBlock.Width) * (ScanArea.Height / CheckBlock.Height);
int RawSizeUsed = 0;
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<Rectangle> ChangedBlocks = new List<Rectangle>();
for(int y = ScanArea.Y; y < ScanArea.Height; )
{
int height = y + CheckBlock.Height < ScanArea.Height ? CheckBlock.Height : ScanArea.Height - y;
for (int x = ScanArea.X; x < ScanArea.Width; )
{
int width = x + CheckBlock.Width < ScanArea.Width ? CheckBlock.Width : ScanArea.Width - x;
int BlockStride = Format == PixelFormat.Format24bppRgb ? width * 3 : width * 4;
decimal FinalHash = 0;
for (int h = 0; h < height; h++)
{
int Offset = FastBitmap.CalcImageOffset(x, y+h, Format, ImageSize.Width);
FinalHash += Hasher.Hash(pScan0 + Offset, BlockStride);
}
if(onCodeDebugScan != null)
onCodeDebugScan(new Rectangle(x, y, width, height));
bool FoundBlock = false;
decimal FoundHash = 0;
int FrameIndex = 0;
for (int i = 0; i < Frames.Count; i++)
{
decimal hash = Frames[i].GetHashBlock(x, y);
if (hash == FinalHash)
{
FrameIndex = i;
FoundBlock = true;
FoundHash = hash;
break;
}
}
frame.AddHashBlock(x, y, FinalHash);
if (!FoundBlock)
{
int index = ChangedBlocks.Count - 1;
Rectangle cBlock = new Rectangle(x, y, width, height);
if (ChangedBlocks.Count > 0 && (ChangedBlocks[index].X + ChangedBlocks[index].Width) == cBlock.X)
{
Rectangle rect = ChangedBlocks[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
ChangedBlocks[index] = cBlock;
}
/*else if (ChangedBlocks.Count > 0 && (ChangedBlocks[index].Y + ChangedBlocks[index].Height) == cBlock.Y)
{
Rectangle rect = ChangedBlocks[index];
int newHeight = cBlock.Height + rect.Height;
cBlock = new Rectangle(rect.X, rect.Y, rect.Width, newHeight);
ChangedBlocks[index] = cBlock;
}*/
else
{
ChangedBlocks.Add(cBlock);
}
RawSizeUsed += BlockStride * height;
}
x += width;
}
y += height;
}
//write all the blocks
for (int i = 0; i < ChangedBlocks.Count; i++)
{
Rectangle rect = ChangedBlocks[i];
int blockStride = PixelSize * rect.Width;
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
base.jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
ChangedBlocks.Clear();
Frames.Add(frame);
if (Frames.Count > MAX_FRAMES)
Frames.RemoveAt(0);
}
public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (DecodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.DecodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
DecodedFrames.Add(DecodedBitmap);
return DecodedBitmap;
}
Rectangle rect;
Graphics g = Graphics.FromImage(DecodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return DecodedBitmap;
}
public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
return new Bitmap(10, 10);
}
private class HashedBlock
{
public int X { get; private set; }
public int Y { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public int FrameIndex { get; private set; }
public HashedBlock(int x, int y, int width, int height, int FrameIndex)
{
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
this.FrameIndex = FrameIndex;
}
public override string ToString()
{
return "X:" + X + ", Y:" + Y + ", Width:" + Width + ", Height:" + Height + ", FrameIndex:" + FrameIndex;
}
}
private class Frame
{
public decimal[,] HashBlocks { get; private set; }
public Frame(int ImageWidth, int ImageHeight)
{
this.HashBlocks = new decimal[(ImageWidth / UnsafeCachedStreamCodec.CheckBlock.Width) + 2, (ImageHeight / UnsafeCachedStreamCodec.CheckBlock.Height) + 2];
}
public void AddHashBlock(int x, int y, decimal Hash)
{
x = x / UnsafeCachedStreamCodec.CheckBlock.Width;
y = y / UnsafeCachedStreamCodec.CheckBlock.Height;
this.HashBlocks[x, y] = Hash;
}
public decimal GetHashBlock(int x, int y)
{
x = x / UnsafeCachedStreamCodec.CheckBlock.Width;
y = y / UnsafeCachedStreamCodec.CheckBlock.Height;
return this.HashBlocks[x, y];
}
}
}
}

View File

@ -1,365 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeMiniCodec : IUnsafeCodec
{
public override ulong CachedSize
{
get;
internal set;
}
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; }
}
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private byte[] EncodeBuffer;
private Bitmap decodedBitmap;
private Size CheckBlock { get { return new Size(50, 50); } }
public UnsafeMiniCodec(int ImageQuality = 100)
: base(ImageQuality)
{
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
{
lock (this.ImageProcessLock)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
FastBitmap.CalcImageOffset(0, 0, Format, ScanArea.Width); //check for FastBitmap Support
switch (Format)
{
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format + " is not supported.");
}
Stride = ImageSize.Width * PixelSize;
RawLength = Stride * ImageSize.Height;
//first frame
if (EncodeBuffer == null)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
this.EncodeBuffer = new byte[RawLength];
fixed (byte* ptr = EncodeBuffer)
{
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
}
return;
}
if (this.EncodedFormat != Format)
throw new Exception("PixelFormat is not equal to previous Bitmap");
if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height)
throw new Exception("Bitmap width/height are not equal to previous bitmap");
if (ScanArea.Width > ImageSize.Width || ImageSize.Height > this.EncodedHeight)
throw new Exception("Scan Area Width/Height cannot be greater then the encoded image");
List<Rectangle> Blocks = new List<Rectangle>(); //all the changes
fixed (byte* encBuffer = EncodeBuffer)
{
//1. Check for the changes in height
for (int y = ScanArea.Y; y < ScanArea.Height; y++)
{
Rectangle cBlock = new Rectangle(0, y, ImageSize.Width, 1);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
int Offset = FastBitmap.CalcImageOffset(0, y, Format, ImageSize.Width);
if (NativeMethods.memcmp(encBuffer + Offset, pScan0 + Offset, (uint)Stride) != 0)
{
int index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
{
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
Blocks[index] = cBlock;
}
else
{
Blocks.Add(cBlock);
}
}
}
//2. Capture all the changes using the CheckBlock
List<Rectangle> finalUpdates = new List<Rectangle>();
for (int i = 0; i < Blocks.Count; i++)
{
Rectangle scanBlock = Blocks[i];
//go through the Blocks
for (int y = scanBlock.Y; y < scanBlock.Height; y += CheckBlock.Height)
{
for (int x = scanBlock.X; x < scanBlock.Width; x += CheckBlock.Width)
{
int blockWidth = x + CheckBlock.Width < scanBlock.Width ? CheckBlock.Width : scanBlock.Width - x;
int blockHeight = y + CheckBlock.Height < scanBlock.Height ? CheckBlock.Height : scanBlock.Height - y;
Rectangle cBlock = new Rectangle(x, y, blockWidth, blockHeight);
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
//scan the block from Top To Bottom and check for changes
bool FoundChanges = false;
for (int blockY = y; blockY < y + blockHeight; blockY++)
{
int Offset = FastBitmap.CalcImageOffset(x, blockY, Format, blockWidth);
if (NativeMethods.memcmp(encBuffer + Offset, pScan0 + Offset, (uint)Stride) != 0)
{
FoundChanges = true;
break;
}
}
if (FoundChanges)
{
int index = finalUpdates.Count - 1;
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
{
Rectangle rect = finalUpdates[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
finalUpdates[index] = cBlock;
}
else
{
finalUpdates.Add(cBlock);
}
}
}
}
}
//maybe a too hard algorithm but oh well
SortedList<int, SortedList<int, Rectangle>> Array = finalUpdates.ToArray().RectanglesTo2D().Rectangle2DToRows();
List<Rectangle> FinalTemp = new List<Rectangle>();
for (int i = 0; i < Array.Values.Count; i++)
{
FinalTemp.AddRange(Array.Values[i].Values);
}
//fixup the height
for (int i = 0; i < FinalTemp.Count; )
{
if (FinalTemp.Count == 1)
{
FinalTemp.Add(FinalTemp[i]);
break;
}
if (i + 1 < FinalTemp.Count)
{
Rectangle curRect = FinalTemp[i];
Rectangle nextRect = FinalTemp[i + 1];
if ((curRect.Y + curRect.Height) == nextRect.Y && curRect.Width == nextRect.Width)
{
FinalTemp[i] = new Rectangle(curRect.X, curRect.Y, curRect.Width, curRect.Height + curRect.Height);
FinalTemp.RemoveAt(i + 1);
}
else
{
i++;
}
}
else
{
break;
}
}
//copy changes to the EncodeBuffer and Process the Output
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
for (int i = 0; i < FinalTemp.Count; i++)
{
Rectangle rect = FinalTemp[i];
int blockStride = PixelSize * rect.Width;
//copy changes to EncodeBuffer
for (int y = rect.Y; y < rect.Y + rect.Height; y++)
{
int Offset = FastBitmap.CalcImageOffset(rect.X, y, Format, rect.Width);
NativeMethods.memcpy(encBuffer + Offset, pScan0 + Offset, (uint)blockStride); //copy-changes
}
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
base.jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
Blocks.Clear();
}
}
}
public override unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
if (Length < 4)
return decodedBitmap;
int DataSize = *(int*)(CodecBuffer);
if (decodedBitmap == null)
{
byte[] temp = new byte[DataSize];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize);
}
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
byte* bufferPtr = (byte*)CodecBuffer.ToInt32();
if (DataSize > 0)
{
Graphics g = Graphics.FromImage(decodedBitmap);
for (int i = 4; DataSize > 0; )
{
Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4),
*(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12));
int UpdateLen = *(int*)(bufferPtr + i + 16);
byte[] temp = new byte[UpdateLen];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen);
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr)))
{
g.DrawImage(TmpBmp, new Point(rect.X, rect.Y));
}
}
DataSize -= UpdateLen + (4 * 5);
i += UpdateLen + (4 * 5);
}
g.Dispose();
}
return decodedBitmap;
}
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
}
}

View File

@ -1,473 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeOptimizedCodec : IUnsafeCodec
{
private class PopulairPoint
{
public Rectangle Rect;
public int Score;
public Stopwatch LastUpdate;
public PopulairPoint(Rectangle rect)
{
this.Rect = rect;
this.Score = 0;
this.LastUpdate = Stopwatch.StartNew();
}
}
public override ulong CachedSize
{
get;
internal set;
}
public override int BufferCount
{
get { return 1; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.RequireSameSize; }
}
public Size CheckBlock { get; private set; }
private object ImageProcessLock = new object();
private byte[] EncodeBuffer;
private Bitmap decodedBitmap;
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private List<PopulairPoint> populairPoints;
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
private Stopwatch ScreenRefreshSW = Stopwatch.StartNew();
//options
/// <summary> If a part in the image is been changing for the last x milliseconds it will be seen as a video </summary>
public uint AliveTimeForBeingVideo = 5000;
/// <summary> This will check if the video went away or stopped playing so it will refresh the other parts in the image </summary>
public uint ScreenRefreshTimer = 2000;
/// <summary> The size for being a video, if bigger or equal to the VideoScreenSize it must be a video </summary>
public Size VideoScreenSize = new Size(100, 100);
/// <summary>
/// Initialize a new object of UnsafeOptimizedCodec
/// </summary>
/// <param name="ImageQuality">The quality to use between 0-100</param>
public UnsafeOptimizedCodec(int ImageQuality = 100)
: base(ImageQuality)
{
this.populairPoints = new List<PopulairPoint>();
this.CheckBlock = new Size(15, 1);
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
{
lock (ImageProcessLock)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
Stride = ImageSize.Width * PixelSize;
RawLength = Stride * ImageSize.Height;
if (EncodeBuffer == null)
{
this.EncodedFormat = Format;
this.EncodedWidth = ImageSize.Width;
this.EncodedHeight = ImageSize.Height;
this.EncodeBuffer = new byte[RawLength];
fixed (byte* ptr = EncodeBuffer)
{
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
}
return;
}
if (ScreenRefreshSW.ElapsedMilliseconds > ScreenRefreshTimer)
{
for (int i = 0; i < populairPoints.Count; i++)
{
if (populairPoints[i].Score == 0 || populairPoints[i].LastUpdate.Elapsed.Seconds > 5)
{
populairPoints.RemoveAt(i);
}
}
ScreenRefreshSW = Stopwatch.StartNew();
}
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
List<byte[]> updates = new List<byte[]>();
MemoryStream ms = new MemoryStream();
byte[] buffer = null;
if (this.EncodedFormat != Format)
throw new Exception("PixelFormat is not equal to previous Bitmap");
if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height)
throw new Exception("Bitmap width/height are not equal to previous bitmap");
List<Rectangle> Blocks = new List<Rectangle>();
int index = 0;
Size s = new Size(ScanArea.Width, CheckBlock.Height);
Size lastSize = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height);
int lasty = ScanArea.Height - lastSize.Height;
int lastx = ScanArea.Width - lastSize.Width;
Rectangle cBlock = new Rectangle();
List<Rectangle> finalUpdates = new List<Rectangle>();
PopulairPoint[] points = GetPossibleVideos();
if (points.Length > 0)
{
ScanArea = new Rectangle(points[0].Rect.X, points[0].Rect.Y, points[0].Rect.Width + points[0].Rect.X, points[0].Rect.Height + points[0].Rect.Y);
}
s = new Size(ScanArea.Width, s.Height);
fixed (byte* encBuffer = EncodeBuffer)
{
if (points.Length == 0) //only scan if there is no video
{
for (int y = ScanArea.Y; y != ScanArea.Height; )
{
if (y == lasty)
s = new Size(ScanArea.Width, lastSize.Height);
cBlock = new Rectangle(ScanArea.X, y, ScanArea.Width, s.Height);
int offset = (y * Stride) + (ScanArea.X * PixelSize);
if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
{
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
index = Blocks.Count - 1;
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
{
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
Blocks[index] = cBlock;
}
else
{
Blocks.Add(cBlock);
}
}
y += s.Height;
}
for (int i = 0, x = ScanArea.X; i < Blocks.Count; i++)
{
s = new Size(CheckBlock.Width, Blocks[i].Height);
x = ScanArea.X;
while (x != ScanArea.Width)
{
if (x == lastx)
s = new Size(lastSize.Width, Blocks[i].Height);
cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height);
bool FoundChanges = false;
int blockStride = PixelSize * cBlock.Width;
for (int j = 0; j < cBlock.Height; j++)
{
int blockOffset = (Stride * (cBlock.Y + j)) + (PixelSize * cBlock.X);
if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride) != 0)
FoundChanges = true;
NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
}
if (onCodeDebugScan != null)
onCodeDebugScan(cBlock);
if (FoundChanges)
{
index = finalUpdates.Count - 1;
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
{
Rectangle rect = finalUpdates[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
finalUpdates[index] = cBlock;
}
else
{
finalUpdates.Add(cBlock);
}
}
x += s.Width;
}
}
}
else
{
finalUpdates.Add(points[0].Rect);
}
}
for (int i = 0; i < finalUpdates.Count; i++)
{
Rectangle rect = finalUpdates[i];
int blockStride = PixelSize * rect.Width;
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
base.jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
if (rect.Width > VideoScreenSize.Width && rect.Height > VideoScreenSize.Height)
{
PopulairPoint point = null;
if (GetPopulairPoint(rect, ref point))
{
point.Score++;
point.LastUpdate = Stopwatch.StartNew();
//Console.WriteLine("[" + populairPoints.Count + "]Video spotted at x:" + rect.X + ", y:" + rect.Y + ", width:" + rect.Width + ", height:" + rect.Height);
}
else
{
populairPoints.Add(new PopulairPoint(rect));
}
}
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
/*for (int i = 0; i < finalUpdates.Count; i++)
{
Rectangle rect = finalUpdates[i];
int blockStride = PixelSize * rect.Width;
buffer = new byte[blockStride * rect.Height];
fixed (byte* ptr = buffer)
{
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy(ptr + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * PixelSize, Format, new IntPtr(ptr)))
{
buffer = base.jpgCompression.Compress(TmpBmp);
if (rect.Width > VideoScreenSize.Width && rect.Height > VideoScreenSize.Height)
{
PopulairPoint point = null;
if (GetPopulairPoint(rect, ref point))
{
point.Score++;
point.LastUpdate = Stopwatch.StartNew();
Console.WriteLine("[" + populairPoints.Count + "]Video spotted at x:" + rect.X + ", y:" + rect.Y + ", width:" + rect.Width + ", height:" + rect.Height);
}
else
{
populairPoints.Add(new PopulairPoint(rect));
}
}
}
}
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
outStream.Write(buffer, 0, buffer.Length);
TotalDataLength += buffer.Length + (4 * 5);
}*/
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
Blocks.Clear();
ms.Close();
ms.Dispose();
}
}
public override unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
if (Length < 4)
return decodedBitmap;
int DataSize = *(int*)(CodecBuffer);
if (decodedBitmap == null)
{
byte[] temp = new byte[DataSize];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize);
}
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
byte* bufferPtr = (byte*)CodecBuffer.ToInt32();
if (DataSize > 0)
{
Graphics g = Graphics.FromImage(decodedBitmap);
for (int i = 4; DataSize > 0; )
{
Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4),
*(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12));
int UpdateLen = *(int*)(bufferPtr + i + 16);
byte[] temp = new byte[UpdateLen];
fixed(byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen);
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr)))
{
g.DrawImage(TmpBmp, new Point(rect.X, rect.Y));
}
}
DataSize -= UpdateLen + (4 * 5);
i += UpdateLen + (4 * 5);
}
g.Dispose();
}
return decodedBitmap;
}
public override Bitmap DecodeData(Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
private bool GetPopulairPoint(Rectangle rect, ref PopulairPoint PopuPoint)
{
for (int i = 0; i < populairPoints.Count; i++)
{
PopulairPoint point = populairPoints[i];
if (point.Rect.Width == rect.Width &&
point.Rect.Height == rect.Height &&
point.Rect.X == rect.X &&
point.Rect.Y == rect.Y)
{
PopuPoint = populairPoints[i];
return true;
}
}
return false;
}
private PopulairPoint[] GetPossibleVideos()
{
List<PopulairPoint> points = new List<PopulairPoint>();
for (int i = 0; i < populairPoints.Count; i++)
{
if (populairPoints[i].Score > 30)
{
points.Add(populairPoints[i]);
}
}
return points.ToArray();
}
}
}

View File

@ -1,285 +0,0 @@
using StreamLibrary.src;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace StreamLibrary.UnsafeCodecs
{
public class UnsafeQuickStream : IUnsafeCodec
{
public override ulong CachedSize { get; internal set; }
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
public override int BufferCount
{
get { return 0; }
}
public override CodecOption CodecOptions
{
get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; }
}
private PixelFormat EncodedFormat;
private int EncodedWidth;
private int EncodedHeight;
private ulong[] EncodeBuffer;
private int BlockWidth = 0;
private int BlockHeight = 0;
private Bitmap decodedBitmap;
public List<Rectangle> VerifyPoints = null;
public Size CheckBlock { get; private set; }
public UnsafeQuickStream(int ImageQuality = 100)
: base(ImageQuality)
{
this.CheckBlock = new Size(50, 50);//width must be bigger then 3
}
public override unsafe void CodeImage(IntPtr Scan0, Rectangle OutputRect, Size InputSize, PixelFormat Format, Stream outStream)
{
byte* pScan0 = (byte*)Scan0.ToInt32();
if (!outStream.CanWrite)
throw new Exception("Must have access to Write in the Stream");
int Stride = 0;
int RawLength = 0;
int PixelSize = 0;
switch (Format)
{
case PixelFormat.Format24bppRgb:
PixelSize = 3;
break;
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
PixelSize = 4;
break;
default:
throw new NotSupportedException(Format.ToString());
}
Stride = InputSize.Width * PixelSize;
RawLength = Stride * InputSize.Height;
if (EncodedWidth == 0 && EncodedHeight == 0)
{
this.EncodedFormat = Format;
this.EncodedWidth = OutputRect.Width;
this.EncodedHeight = OutputRect.Height;
byte[] temp = null;
using (Bitmap TmpBmp = new Bitmap(OutputRect.Width, OutputRect.Height, Stride, Format, Scan0))
{
temp = base.jpgCompression.Compress(TmpBmp);
}
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
outStream.Write(temp, 0, temp.Length);
return;
}
List<Rectangle> Points = ProcessChanges(Scan0, OutputRect, Format, InputSize.Width);
VerifyPoints = Points;
long oldPos = outStream.Position;
outStream.Write(new byte[4], 0, 4);
int TotalDataLength = 0;
for (int i = 0; i < Points.Count; i++)
{
Rectangle rect = Points[i];
int blockStride = PixelSize * rect.Width;
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
for (int j = 0, offset = 0; j < rect.Height; j++)
{
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
offset += blockStride;
}
TmpBmp.UnlockBits(TmpData);
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
outStream.Write(new byte[4], 0, 4);
long length = outStream.Position;
long OldPos = outStream.Position;
base.jpgCompression.Compress(TmpBmp, ref outStream);
length = outStream.Position - length;
outStream.Position = OldPos - 4;
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
outStream.Position += length;
TmpBmp.Dispose();
TotalDataLength += (int)length + (4 * 5);
}
outStream.Position = oldPos;
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
}
private unsafe List<Rectangle> ProcessChanges(IntPtr Scan0, Rectangle OutputRect, PixelFormat Format, int ImageWidth)
{
if (EncodeBuffer == null)
{
this.BlockWidth = (int)Math.Floor((float)(OutputRect.Width / CheckBlock.Width));
this.BlockHeight = (int)Math.Floor((double)(OutputRect.Height / CheckBlock.Height));
int TotalBlocks = (int)Math.Floor((float)(BlockHeight * BlockWidth));
this.EncodeBuffer = new ulong[TotalBlocks];
}
List<Rectangle> points = new List<Rectangle>();
int StartScan = Scan0.ToInt32();
for (int y = OutputRect.Y; y < OutputRect.Height + OutputRect.Y; y += CheckBlock.Height)
{
if (y + CheckBlock.Height > OutputRect.Height)
break;
for (int x = OutputRect.X; x < OutputRect.Width + OutputRect.X; x += CheckBlock.Width)
{
if (x + CheckBlock.Width > OutputRect.Width)
break;
int EncodeOffset = GetOffset(x, y);
long offset = FastBitmap.CalcImageOffset(x, y, Format, ImageWidth);
ulong* ScanPtr = (ulong*)(StartScan + offset);
if (EncodeBuffer[EncodeOffset] != *ScanPtr)
{
EncodeBuffer[EncodeOffset] = *ScanPtr;
Rectangle cBlock = new Rectangle(x, y, CheckBlock.Width, CheckBlock.Height);
int index = points.Count - 1;
if (points.Count > 0 && (points[index].X + points[index].Width) == cBlock.X)
{
Rectangle rect = points[index];
int newWidth = cBlock.Width + rect.Width;
cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
points[index] = cBlock;
}
else
{
points.Add(cBlock);
}
}
}
}
return points;
}
private Point GetOffsetPoint(int x, int y)
{
return new Point((int)Math.Floor((float)(y / CheckBlock.Height)) * BlockWidth,
(int)Math.Floor((double)(x / CheckBlock.Width)));
}
private int GetOffset(int x, int y)
{
return (int)Math.Floor((float)(y / CheckBlock.Height)) * BlockWidth +
(int)Math.Floor((double)(x / CheckBlock.Width));
}
public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream)
{
byte[] temp = new byte[4];
inStream.Read(temp, 0, 4);
int DataSize = BitConverter.ToInt32(temp, 0);
if (decodedBitmap == null)
{
temp = new byte[DataSize];
inStream.Read(temp, 0, temp.Length);
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
List<Rectangle> updates = new List<Rectangle>();
Rectangle rect;
Graphics g = Graphics.FromImage(decodedBitmap);
Bitmap tmp;
byte[] buffer = null;
MemoryStream m;
while (DataSize > 0)
{
byte[] tempData = new byte[4 * 5];
inStream.Read(tempData, 0, tempData.Length);
rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
int UpdateLen = BitConverter.ToInt32(tempData, 16);
buffer = new byte[UpdateLen];
inStream.Read(buffer, 0, buffer.Length);
if (onDecodeDebugScan != null)
onDecodeDebugScan(rect);
m = new MemoryStream(buffer);
tmp = (Bitmap)Image.FromStream(m);
g.DrawImage(tmp, rect.Location);
tmp.Dispose();
m.Close();
m.Dispose();
DataSize -= UpdateLen + (4 * 5);
}
g.Dispose();
return decodedBitmap;
}
public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
{
if (Length < 4)
return decodedBitmap;
int DataSize = *(int*)(CodecBuffer);
if (decodedBitmap == null)
{
byte[] temp = new byte[DataSize];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize);
}
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
return decodedBitmap;
}
byte* bufferPtr = (byte*)CodecBuffer.ToInt32();
if (DataSize > 0)
{
Graphics g = Graphics.FromImage(decodedBitmap);
for (int i = 4; DataSize > 0; )
{
Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4),
*(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12));
int UpdateLen = *(int*)(bufferPtr + i + 16);
byte[] temp = new byte[UpdateLen];
fixed (byte* tempPtr = temp)
{
NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen);
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr)))
{
g.DrawImage(TmpBmp, new Point(rect.X, rect.Y));
}
}
DataSize -= UpdateLen + (4 * 5);
i += UpdateLen + (4 * 5);
}
g.Dispose();
}
return decodedBitmap;
}
}
}

View File

@ -1,186 +0,0 @@
// Tamir Khason http://khason.net/
//
// Released under MS-PL : 6-Apr-09
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Collections;
using System.IO;
namespace StreamLibrary.src
{
/// <summary>Implements a 32-bits cyclic redundancy check (CRC) hash algorithm.</summary>
/// <remarks>This class is not intended to be used for security purposes. For security applications use MD5, SHA1, SHA256, SHA384,
/// or SHA512 in the System.Security.Cryptography namespace.</remarks>
public class CRC32 : HashAlgorithm
{
#region CONSTRUCTORS
/// <summary>Creates a CRC32 object using the <see cref="DefaultPolynomial"/>.</summary>
public CRC32()
: this(DefaultPolynomial)
{
}
/// <summary>Creates a CRC32 object using the specified polynomial.</summary>
/// <remarks>The polynomical should be supplied in its bit-reflected form. <see cref="DefaultPolynomial"/>.</remarks>
public CRC32(uint polynomial)
{
HashSizeValue = 32;
_crc32Table = (uint[])_crc32TablesCache[polynomial];
if (_crc32Table == null)
{
_crc32Table = CRC32._buildCRC32Table(polynomial);
_crc32TablesCache.Add(polynomial, _crc32Table);
}
Initialize();
}
// static constructor
static CRC32()
{
_crc32TablesCache = Hashtable.Synchronized(new Hashtable());
_defaultCRC = new CRC32();
}
#endregion
#region PROPERTIES
/// <summary>Gets the default polynomial (used in WinZip, Ethernet, etc.)</summary>
/// <remarks>The default polynomial is a bit-reflected version of the standard polynomial 0x04C11DB7 used by WinZip, Ethernet, etc.</remarks>
public static readonly uint DefaultPolynomial = 0xEDB88320; // Bitwise reflection of 0x04C11DB7;
#endregion
#region METHODS
/// <summary>Initializes an implementation of HashAlgorithm.</summary>
public override void Initialize()
{
_crc = _allOnes;
}
/// <summary>Routes data written to the object into the hash algorithm for computing the hash.</summary>
protected override void HashCore(byte[] buffer, int offset, int count)
{
for (int i = offset; i < count; i++)
{
ulong ptr = (_crc & 0xFF) ^ buffer[i];
_crc >>= 8;
_crc ^= _crc32Table[ptr];
}
}
/// <summary>Finalizes the hash computation after the last data is processed by the cryptographic stream object.</summary>
protected override byte[] HashFinal()
{
byte[] finalHash = new byte[4];
ulong finalCRC = _crc ^ _allOnes;
finalHash[0] = (byte)((finalCRC >> 0) & 0xFF);
finalHash[1] = (byte)((finalCRC >> 8) & 0xFF);
finalHash[2] = (byte)((finalCRC >> 16) & 0xFF);
finalHash[3] = (byte)((finalCRC >> 24) & 0xFF);
return finalHash;
}
/// <summary>Computes the CRC32 value for the given ASCII string using the <see cref="DefaultPolynomial"/>.</summary>
public static int Compute(string asciiString)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(asciiString));
}
/// <summary>Computes the CRC32 value for the given input stream using the <see cref="DefaultPolynomial"/>.</summary>
public static int Compute(Stream inputStream)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(inputStream));
}
/// <summary>Computes the CRC32 value for the input data using the <see cref="DefaultPolynomial"/>.</summary>
public static int Compute(byte[] buffer)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(buffer));
}
/// <summary>Computes the hash value for the input data using the <see cref="DefaultPolynomial"/>.</summary>
public static int Compute(byte[] buffer, int offset, int count)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(buffer, offset, count));
}
/// <summary>Computes the hash value for the given ASCII string.</summary>
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
public byte[] ComputeHash(string asciiString)
{
byte[] rawBytes = ASCIIEncoding.ASCII.GetBytes(asciiString);
return ComputeHash(rawBytes);
}
/// <summary>Computes the hash value for the given input stream.</summary>
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
new public byte[] ComputeHash(Stream inputStream)
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.Read(buffer, 0, 4096)) > 0)
{
HashCore(buffer, 0, bytesRead);
}
return HashFinal();
}
/// <summary>Computes the hash value for the input data.</summary>
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
new public byte[] ComputeHash(byte[] buffer)
{
return ComputeHash(buffer, 0, buffer.Length);
}
/// <summary>Computes the hash value for the input data.</summary>
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
new public byte[] ComputeHash(byte[] buffer, int offset, int count)
{
HashCore(buffer, offset, count);
return HashFinal();
}
#endregion
#region PRIVATE SECTION
private static uint _allOnes = 0xffffffff;
private static CRC32 _defaultCRC;
private static Hashtable _crc32TablesCache;
private uint[] _crc32Table;
private uint _crc;
// Builds a crc32 table given a polynomial
private static uint[] _buildCRC32Table(uint polynomial)
{
uint crc;
uint[] table = new uint[256];
// 256 values representing ASCII character codes.
for (int i = 0; i < 256; i++)
{
crc = (uint)i;
for (int j = 8; j > 0; j--)
{
if ((crc & 1) == 1)
crc = (crc >> 1) ^ polynomial;
else
crc >>= 1;
}
table[i] = crc;
}
return table;
}
private static int ToInt32(byte[] buffer)
{
return BitConverter.ToInt32(buffer, 0);
}
#endregion
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method)]
public sealed class ExtensionAttribute : Attribute
{
public ExtensionAttribute() { }
}
}

View File

@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace StreamLibrary.src
{
public static unsafe class Extensions
{
public static SortedList<int, SortedList<int, Rectangle>> RectanglesTo2D(this Rectangle[] rects)
{
SortedList<int, SortedList<int, Rectangle>> Rects = new SortedList<int, SortedList<int, Rectangle>>();
for (int i = 0; i < rects.Length; i++)
{
if (!Rects.ContainsKey(rects[i].Y))
Rects.Add(rects[i].Y, new SortedList<int, Rectangle>());
if (!Rects[rects[i].Y].ContainsKey(rects[i].X))
Rects[rects[i].Y].Add(rects[i].X, rects[i]);
}
return Rects;
}
public static SortedList<int, SortedList<int, Rectangle>> Rectangle2DToRows(this SortedList<int, SortedList<int, Rectangle>> Rects)
{
SortedList<int, SortedList<int, Rectangle>> RectRows = new SortedList<int, SortedList<int, Rectangle>>();
for (int i = 0; i < Rects.Values.Count; i++)
{
if (!RectRows.ContainsKey(Rects.Values[i].Values[0].Y))
{
RectRows.Add(Rects.Values[i].Values[0].Y, new SortedList<int, Rectangle>());
}
if (!RectRows[Rects.Values[i].Values[0].Y].ContainsKey(Rects.Values[i].Values[0].X))
{
RectRows[Rects.Values[i].Values[0].Y].Add(Rects.Values[i].Values[0].X, Rects.Values[i].Values[0]);
}
Rectangle EndRect = Rects.Values[i].Values[0];
for (int x = 1; x < Rects.Values[i].Values.Count; x++)
{
Rectangle CurRect = Rects.Values[i].Values[x];
Rectangle tmpRect = RectRows[EndRect.Y].Values[RectRows[EndRect.Y].Count - 1];
if (tmpRect.IntersectsWith(new Rectangle(CurRect.X - 1, CurRect.Y, CurRect.Width, CurRect.Height)))
{
RectRows[EndRect.Y][tmpRect.X] = new Rectangle(tmpRect.X, tmpRect.Y, tmpRect.Width + EndRect.Width, tmpRect.Height);
EndRect = Rects.Values[i].Values[x];
}
else
{
EndRect = Rects.Values[i].Values[x];
RectRows[Rects.Values[i].Values[0].Y].Add(EndRect.X, EndRect);
}
}
}
return RectRows;
}
}
}

View File

@ -1,353 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
namespace StreamLibrary.src
{
public unsafe class FastBitmap
{
public Bitmap bitmap { get; set; }
public BitmapData bitmapData { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public PixelFormat format { get; private set; }
public DateTime BitmapCreatedAt;
public bool IsLocked { get; private set; }
public int Stride
{
get { return bitmapData.Stride; }
}
public FastBitmap(Bitmap bitmap, PixelFormat format)
{
switch (format)
{
case PixelFormat.Format32bppArgb:
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
case PixelFormat.Format8bppIndexed:
case PixelFormat.Format4bppIndexed:
case PixelFormat.Format1bppIndexed:
break;
default:
throw new NotSupportedException(format + " is not supported.");
}
this.bitmap = bitmap;
this.Width = this.bitmap.Width;
this.Height = this.bitmap.Height;
this.format = format;
Lock();
BitmapCreatedAt = DateTime.Now;
}
public FastBitmap(Bitmap bitmap)
{
this.format = bitmap.PixelFormat;
switch (format)
{
case PixelFormat.Format32bppArgb:
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
case PixelFormat.Format8bppIndexed:
case PixelFormat.Format4bppIndexed:
case PixelFormat.Format1bppIndexed:
break;
default:
throw new NotSupportedException(format + " is not supported.");
}
this.bitmap = bitmap;
this.Width = this.bitmap.Width;
this.Height = this.bitmap.Height;
this.format = format;
Lock();
BitmapCreatedAt = DateTime.Now;
}
public Color GetPixel(int x, int y)
{
byte* position = (byte*)bitmapData.Scan0.ToPointer();
position += CalcOffset(x, y);
byte A = position[3];
byte R = position[2];
byte G = position[1];
byte B = position[0];
return Color.FromArgb(A, R, G, B);
}
public void SetPixel(int x, int y, Color color)
{
byte* position = (byte*)bitmapData.Scan0.ToPointer();
position += CalcOffset(x, y);
position[3] = color.A;
position[2] = color.R;
position[1] = color.G;
position[0] = color.B;
}
public Color GetPixel(int x, int y, byte[] ImgData)
{
long offset = CalcOffset(x, y) + 4;
if (offset + 4 < ImgData.Length)
{
byte R = ImgData[offset];
byte G = ImgData[offset + 1];
byte B = ImgData[offset + 2];
return Color.FromArgb(255, R, G, B);
}
return Color.FromArgb(255, 0, 0, 0);
}
public void SetPixel(int x, int y, Color color, byte[] ImgData)
{
long offset = CalcOffset(x, y) + 4;
if (offset + 4 < ImgData.Length)
{
ImgData[offset] = color.R;
ImgData[offset + 1] = color.G;
ImgData[offset + 2] = color.B;
ByteArrayToBitmap(ImgData);
}
}
public void DrawRectangle(Point begin, Point end, Color color)
{
for (int x = begin.X; x < end.X; x++)
{
for (int y = begin.Y; y < end.Y; y++)
{
SetPixel(x, y, color);
}
}
}
public Int64 CalcOffset(int x, int y)
{
switch (format)
{
case PixelFormat.Format32bppArgb:
return (y * bitmapData.Stride) + (x * 4);
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
return (y * bitmapData.Stride) + (x * 3);
case PixelFormat.Format8bppIndexed:
return (y * bitmapData.Stride) + x;
case PixelFormat.Format4bppIndexed:
return (y * bitmapData.Stride) + (x / 2);
case PixelFormat.Format1bppIndexed:
return (y * bitmapData.Stride) + (x * 8);
}
return 0;
}
public static int CalcImageOffset(int x, int y, PixelFormat format, int width)
{
switch (format)
{
case PixelFormat.Format32bppArgb:
return (y * (width * 4)) + (x * 4);
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
return (y * (width * 3)) + (x * 3);
case PixelFormat.Format8bppIndexed:
return (y * width) + x;
case PixelFormat.Format4bppIndexed:
return (y * (width / 2)) + (x / 2);
case PixelFormat.Format1bppIndexed:
return (y * (width * 8)) + (x * 8);
default:
throw new NotSupportedException(format + " is not supported.");
}
}
public void ScanPixelDuplicates(Point BeginPoint, ref Point EndPoint, ref Color RetColor)
{
Color curColor = GetPixel(BeginPoint.X, BeginPoint.Y);
for (int x = BeginPoint.X; x < this.Width; x++)
{
Color prevColor = GetPixel(x, BeginPoint.Y);
if (curColor.R != prevColor.R ||
curColor.G != prevColor.G ||
curColor.B != prevColor.B)
{
EndPoint = new Point(x, BeginPoint.Y);
RetColor = curColor;
return;
}
}
EndPoint = new Point(this.Width, BeginPoint.Y);
RetColor = curColor;
}
public void Unlock()
{
if (IsLocked)
{
bitmap.UnlockBits(bitmapData);
IsLocked = false;
}
}
public void Lock()
{
if (!IsLocked)
{
bitmapData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, format);
IsLocked = true;
}
}
public byte[] ToByteArray()
{
int bytes = Math.Abs(bitmapData.Stride) * Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(new IntPtr(bitmapData.Scan0.ToInt32()), rgbValues, 0, bytes);
return rgbValues;
}
public void ByteArrayToBitmap(byte[] data)
{
System.Runtime.InteropServices.Marshal.Copy(data, 0, bitmapData.Scan0, data.Length);
}
public void Dispose()
{
if (bitmap != null)
{
try { bitmap.UnlockBits(bitmapData); }
catch { }
try { bitmap.Dispose(); }
catch { }
try
{
bitmap = null;
bitmapData = null;
}
catch { }
}
}
/// <summary> Get the byte points where to read from in a byte array </summary>
/// <param name="beginPoint">The beginning of the X, Y</param>
/// <param name="endPoint">The end of the X, Y</param>
/// <param name="ImgSize">The size of the image</param>
/// <param name="SlicePieces">Slice the byte points into pieces to get the byte points faster</param>
public static ArrayOffset[] GetBytePoints(Point beginPoint, Point endPoint, Size ImgSize, PixelFormat format)
{
List<ArrayOffset> offsets = new List<ArrayOffset>();
for (int y = beginPoint.Y; y < endPoint.Y; y++)
{
int BeginOffset = (int)FastBitmap.CalcImageOffset(beginPoint.X, y, format, ImgSize.Width);//(y * ImgSize.Width * 4) + (beginPoint.X * 4);
int EndOffset = (int)FastBitmap.CalcImageOffset(endPoint.X, y, format, ImgSize.Width);//(y * ImgSize.Width * 4) + (endPoint.X * 4);
switch (format)
{
case PixelFormat.Format32bppArgb:
{
if (EndOffset + ((endPoint.X - beginPoint.X) * 4) >= (ImgSize.Width * ImgSize.Height) * 4)
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 4), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
{
if (EndOffset + ((endPoint.X - beginPoint.X) * 3) >= (ImgSize.Width * ImgSize.Height) * 3)
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 3), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
case PixelFormat.Format8bppIndexed:
{
if (EndOffset + ((endPoint.X - beginPoint.X)) >= (ImgSize.Width * ImgSize.Height))
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X)), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
case PixelFormat.Format4bppIndexed:
{
if (EndOffset + ((endPoint.X - beginPoint.X) / 2) >= (ImgSize.Width * ImgSize.Height) / 2)
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) / 2), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
case PixelFormat.Format1bppIndexed:
{
if (EndOffset + ((endPoint.X - beginPoint.X) * 8) >= (ImgSize.Width * ImgSize.Height) * 8)
break;
offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 8), beginPoint.X, y, (endPoint.X - beginPoint.X), 1));
break;
}
default:
{
throw new NotSupportedException(format + " is not supported.");
}
}
}
return offsets.ToArray();
}
/// <summary> Get the byte points in 2D </summary>
/// <param name="beginPoint">The beginning of the X, Y</param>
/// <param name="endPoint">The end of the X, Y</param>
/// <param name="ImgSize">The size of the image</param>
/// <param name="SlicePieces">Slice the byte points into pieces to get the byte points faster</param>
public static ArrayOffset[,][] Get2DBytePoints(Point beginPoint, Point endPoint, Size ImgSize, int SlicePieces, PixelFormat format)
{
int Width = endPoint.X - beginPoint.X;
int Height = endPoint.Y - beginPoint.Y;
float Wsize = ((float)Width / (float)SlicePieces);
float Hsize = ((float)Height / (float)SlicePieces);
//+1 just to make sure we are not going outside the array
if (Wsize - (int)Wsize > 0.0F) Wsize += 1.0F;
if (Hsize - (int)Hsize > 0.0F) Hsize += 1.0F;
ArrayOffset[,][] ImageArrayOffsets = new ArrayOffset[(int)Hsize, (int)Wsize][];
Point tmp = new Point(0, 0);
for (int y = beginPoint.Y; y < Height; y += SlicePieces)
{
for (int x = beginPoint.X; x < Width; x += SlicePieces)
{
ImageArrayOffsets[tmp.Y, tmp.X] = FastBitmap.GetBytePoints(new Point(x, y), new Point(x + SlicePieces, y + SlicePieces), ImgSize, format);
tmp.X++;
}
tmp.X = 0;
tmp.Y++;
}
return ImageArrayOffsets;
}
}
public class ArrayOffset
{
public int BeginOffset { get; private set; }
public int EndOffset { get; private set; }
public int Stride { get; private set; }
public int X { get; private set; }
public int Y { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public ArrayOffset(int begin, int end, int Stride, int x, int y, int width, int height)
{
this.BeginOffset = begin;
this.EndOffset = end;
this.Stride = Stride;
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
}
}

View File

@ -1,62 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace StreamLibrary.src
{
public unsafe class MurmurHash2Unsafe
{
const UInt32 m = 0x5bd1e995;
const Int32 r = 24;
public unsafe UInt32 Hash(Byte* data, int length)
{
if (length == 0)
return 0;
UInt32 h = 0xc58f1a7b ^ (UInt32)length;
Int32 remainingBytes = length & 3; // mod 4
Int32 numberOfLoops = length >> 2; // div 4
UInt32* realData = (UInt32*)data;
while (numberOfLoops != 0)
{
UInt32 k = *realData;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
numberOfLoops--;
realData++;
}
switch (remainingBytes)
{
case 3:
h ^= (UInt16)(*realData);
h ^= ((UInt32)(*(((Byte*)(realData)) + 2))) << 16;
h *= m;
break;
case 2:
h ^= (UInt16)(*realData);
h *= m;
break;
case 1:
h ^= *((Byte*)realData);
h *= m;
break;
default:
break;
}
// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
}
}

View File

@ -1,113 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace StreamLibrary.src
{
public class PayloadWriter : IDisposable
{
public Stream vStream { get; set; }
public PayloadWriter()
{
vStream = new MemoryStream();
}
public PayloadWriter(Stream stream)
{
vStream = stream;
}
public void WriteBytes(byte[] value)
{
vStream.Write(value, 0, value.Length);
}
public void WriteBytes(byte[] value, int Offset, int Length)
{
vStream.Write(value, Offset, Length);
}
public void WriteInteger(int value)
{
WriteBytes(BitConverter.GetBytes(value));
}
/// <summary>
/// A integer with 3 bytes not 4
/// </summary>
public void WriteThreeByteInteger(int value)
{
WriteByte((byte)value);
WriteByte((byte)(value >> 8));
WriteByte((byte)(value >> 16));
}
public void WriteUInteger(uint value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteShort(short value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteUShort(ushort value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteULong(ulong value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteByte(byte value)
{
vStream.WriteByte(value);
}
public void WriteBool(bool value)
{
WriteByte(value ? (byte)1 : (byte)0);
}
public void WriteDouble(double value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteLong(long value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteFloat(float value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public void WriteDecimal(decimal value)
{
BinaryWriter writer = new BinaryWriter(vStream);
writer.Write(value);
}
public void WriteString(string value)
{
if (!(value == null))
WriteBytes(System.Text.Encoding.Unicode.GetBytes(value));
else
throw new NullReferenceException("value");
vStream.WriteByte(0);
vStream.WriteByte(0);
}
public int Length
{
get { return (int)vStream.Length; }
}
public void Dispose()
{
vStream.Close();
vStream.Dispose();
vStream = null;
}
}
}

View File

@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace StreamLibrary.src
{
/// <summary>
/// A helper class for pointers
/// </summary>
public class PointerHelper
{
private int _offset;
public IntPtr Pointer
{
get;
private set;
}
public int TotalLength { get; private set; }
public int Offset
{
get { return _offset; }
set
{
if (value < 0)
throw new Exception("Offset must be >= 1");
if (value >= TotalLength)
throw new Exception("Offset cannot go outside of the reserved buffer space");
_offset = value;
}
}
public PointerHelper(IntPtr pointer, int Length)
{
this.TotalLength = Length;
this.Pointer = pointer;
}
/// <summary>
/// Copies data from Source to the current Pointer Offset
/// </summary>
public void Copy(IntPtr Source, int SourceOffset, int SourceLength)
{
if (CheckBoundries(this.Offset, SourceLength))
throw new AccessViolationException("Cannot write outside of the buffer space");
NativeMethods.memcpy(new IntPtr(this.Pointer.ToInt64() + Offset), new IntPtr(Source.ToInt64() + SourceOffset), (uint)SourceLength);
}
private bool CheckBoundries(int offset, int length)
{
return offset + length > TotalLength;
}
}
}

View File

@ -1,487 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace StreamLibrary.src
{
// QuickLZ data compression library
// Copyright (C) 2006-2011 Lasse Mikkel Reinhold
// lar@quicklz.com
//
// QuickLZ can be used for free under the GPL 1, 2 or 3 license (where anything
// released into public must be open source) or under a commercial license if such
// has been acquired (see http://www.quicklz.com/order.html). The commercial license
// does not cover derived or ported versions created by third parties under GPL.
//
// Only a subset of the C library has been ported, namely level 1 and 3 not in
// streaming mode.
//
// Version: 1.5.0 final
public class SafeQuickLZ
{
public const int QLZ_VERSION_MAJOR = 1;
public const int QLZ_VERSION_MINOR = 5;
public const int QLZ_VERSION_REVISION = 0;
// Streaming mode not supported
public const int QLZ_STREAMING_BUFFER = 0;
// Bounds checking not supported Use try...catch instead
public const int QLZ_MEMORY_SAFE = 0;
// Decrease QLZ_POINTERS_3 to increase level 3 compression speed. Do not edit any other values!
private const int HASH_VALUES = 4096;
private const int MINOFFSET = 2;
private const int UNCONDITIONAL_MATCHLEN = 6;
private const int UNCOMPRESSED_END = 4;
private const int CWORD_LEN = 4;
private const int DEFAULT_HEADERLEN = 9;
private const int QLZ_POINTERS_1 = 1;
private const int QLZ_POINTERS_3 = 16;
private int headerLen(byte[] source, int offset)
{
return ((source[offset] & 2) == 2) ? 9 : 3;
}
public int sizeDecompressed(byte[] source, int offset)
{
if (headerLen(source, offset) == 9)
return source[offset + 5] | (source[offset + 6] << 8) | (source[offset + 7] << 16) | (source[offset + 8] << 24);
else
return source[offset + 2];
}
public int sizeCompressed(byte[] source, int offset)
{
if (headerLen(source, offset) == 9)
return source[offset + 1] | (source[offset + 2] << 8) | (source[offset + 3] << 16) | (source[offset + 4] << 24);
else
return source[offset + 1];
}
private void write_header(byte[] dst, int level, bool compressible, int size_compressed, int size_decompressed)
{
dst[0] = (byte)(2 | (compressible ? 1 : 0));
dst[0] |= (byte)(level << 2);
dst[0] |= (1 << 6);
dst[0] |= (0 << 4);
fast_write(dst, 1, size_decompressed, 4);
fast_write(dst, 5, size_compressed, 4);
}
public byte[] compress(byte[] source, int Offset, int Length, int level)
{
int src = Offset;
int dst = DEFAULT_HEADERLEN + CWORD_LEN;
uint cword_val = 0x80000000;
int cword_ptr = DEFAULT_HEADERLEN;
byte[] destination = new byte[Length + 400];
int[,] hashtable;
int[] cachetable = new int[HASH_VALUES];
byte[] hash_counter = new byte[HASH_VALUES];
byte[] d2;
int fetch = 0;
int last_matchstart = (Length - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END - 1);
int lits = 0;
if (level != 1 && level != 3)
throw new ArgumentException("C# version only supports level 1 and 3");
if (level == 1)
hashtable = new int[HASH_VALUES, QLZ_POINTERS_1];
else
hashtable = new int[HASH_VALUES, QLZ_POINTERS_3];
if (Length == 0)
return new byte[0];
if (src <= last_matchstart)
fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16);
while (src <= last_matchstart)
{
if ((cword_val & 1) == 1)
{
if (src > Length >> 1 && dst > src - (src >> 5))
{
d2 = new byte[Length + DEFAULT_HEADERLEN];
write_header(d2, level, false, Length, Length + DEFAULT_HEADERLEN);
System.Array.Copy(source, 0, d2, DEFAULT_HEADERLEN, Length);
return d2;
}
fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4);
cword_ptr = dst;
dst += CWORD_LEN;
cword_val = 0x80000000;
}
if (level == 1)
{
int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1);
int o = hashtable[hash, 0];
int cache = cachetable[hash] ^ fetch;
cachetable[hash] = fetch;
hashtable[hash, 0] = src;
if (cache == 0 && hash_counter[hash] != 0 && (src - o > MINOFFSET || (src == o + 1 && lits >= 3 && src > 3 && source[src] == source[src - 3] &&
source[src] == source[src - 2] && source[src] == source[src - 1] &&
source[src] == source[src + 1] && source[src] == source[src + 2])))
{
cword_val = ((cword_val >> 1) | 0x80000000);
if (source[o + 3] != source[src + 3])
{
int f = 3 - 2 | (hash << 4);
destination[dst + 0] = (byte)(f >> 0 * 8);
destination[dst + 1] = (byte)(f >> 1 * 8);
src += 3;
dst += 2;
}
else
{
int old_src = src;
int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1));
src += 4;
if (source[o + src - old_src] == source[src])
{
src++;
if (source[o + src - old_src] == source[src])
{
src++;
while (source[o + (src - old_src)] == source[src] && (src - old_src) < remaining)
src++;
}
}
int matchlen = src - old_src;
hash <<= 4;
if (matchlen < 18)
{
int f = (hash | (matchlen - 2));
destination[dst + 0] = (byte)(f >> 0 * 8);
destination[dst + 1] = (byte)(f >> 1 * 8);
dst += 2;
}
else
{
fast_write(destination, dst, hash | (matchlen << 16), 3);
dst += 3;
}
}
fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16);
lits = 0;
}
else
{
lits++;
hash_counter[hash] = 1;
destination[dst] = source[src];
cword_val = (cword_val >> 1);
src++;
dst++;
fetch = ((fetch >> 8) & 0xffff) | (source[src + 2] << 16);
}
}
else
{
fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16);
int o, offset2;
int matchlen, k, m, best_k = 0;
byte c;
int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1));
int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1);
c = hash_counter[hash];
matchlen = 0;
offset2 = 0;
for (k = 0; k < QLZ_POINTERS_3 && c > k; k++)
{
o = hashtable[hash, k];
if ((byte)fetch == source[o] && (byte)(fetch >> 8) == source[o + 1] && (byte)(fetch >> 16) == source[o + 2] && o < src - MINOFFSET)
{
m = 3;
while (source[o + m] == source[src + m] && m < remaining)
m++;
if ((m > matchlen) || (m == matchlen && o > offset2))
{
offset2 = o;
matchlen = m;
best_k = k;
}
}
}
o = offset2;
hashtable[hash, c & (QLZ_POINTERS_3 - 1)] = src;
c++;
hash_counter[hash] = c;
if (matchlen >= 3 && src - o < 131071)
{
int offset = src - o;
for (int u = 1; u < matchlen; u++)
{
fetch = source[src + u] | (source[src + u + 1] << 8) | (source[src + u + 2] << 16);
hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1);
c = hash_counter[hash]++;
hashtable[hash, c & (QLZ_POINTERS_3 - 1)] = src + u;
}
src += matchlen;
cword_val = ((cword_val >> 1) | 0x80000000);
if (matchlen == 3 && offset <= 63)
{
fast_write(destination, dst, offset << 2, 1);
dst++;
}
else if (matchlen == 3 && offset <= 16383)
{
fast_write(destination, dst, (offset << 2) | 1, 2);
dst += 2;
}
else if (matchlen <= 18 && offset <= 1023)
{
fast_write(destination, dst, ((matchlen - 3) << 2) | (offset << 6) | 2, 2);
dst += 2;
}
else if (matchlen <= 33)
{
fast_write(destination, dst, ((matchlen - 2) << 2) | (offset << 7) | 3, 3);
dst += 3;
}
else
{
fast_write(destination, dst, ((matchlen - 3) << 7) | (offset << 15) | 3, 4);
dst += 4;
}
lits = 0;
}
else
{
destination[dst] = source[src];
cword_val = (cword_val >> 1);
src++;
dst++;
}
}
}
while (src <= Length - 1)
{
if ((cword_val & 1) == 1)
{
fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4);
cword_ptr = dst;
dst += CWORD_LEN;
cword_val = 0x80000000;
}
destination[dst] = source[src];
src++;
dst++;
cword_val = (cword_val >> 1);
}
while ((cword_val & 1) != 1)
{
cword_val = (cword_val >> 1);
}
fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), CWORD_LEN);
write_header(destination, level, true, Length, dst);
d2 = new byte[dst];
System.Array.Copy(destination, d2, dst);
return d2;
}
private void fast_write(byte[] a, int i, int value, int numbytes)
{
for (int j = 0; j < numbytes; j++)
a[i + j] = (byte)(value >> (j * 8));
}
public byte[] decompress(byte[] source, int Offset, int Length)
{
int level;
int size = sizeDecompressed(source, Offset);
int src = headerLen(source, Offset) + Offset;
int dst = 0;
uint cword_val = 1;
byte[] destination = new byte[size];
int[] hashtable = new int[4096];
byte[] hash_counter = new byte[4096];
int last_matchstart = size - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END - 1;
int last_hashed = -1;
int hash;
uint fetch = 0;
level = (source[Offset] >> 2) & 0x3;
if (level != 1 && level != 3)
throw new ArgumentException("C# version only supports level 1 and 3");
if ((source[Offset] & 1) != 1)
{
byte[] d2 = new byte[size];
System.Array.Copy(source, headerLen(source, Offset), d2, Offset, size);
return d2;
}
for (; ; )
{
if (cword_val == 1)
{
cword_val = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
src += 4;
if (dst <= last_matchstart)
{
if (level == 1)
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16));
else
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
}
}
if ((cword_val & 1) == 1)
{
uint matchlen;
uint offset2;
cword_val = cword_val >> 1;
if (level == 1)
{
hash = ((int)fetch >> 4) & 0xfff;
offset2 = (uint)hashtable[hash];
if ((fetch & 0xf) != 0)
{
matchlen = (fetch & 0xf) + 2;
src += 2;
}
else
{
matchlen = source[src + 2];
src += 3;
}
}
else
{
uint offset;
if ((fetch & 3) == 0)
{
offset = (fetch & 0xff) >> 2;
matchlen = 3;
src++;
}
else if ((fetch & 2) == 0)
{
offset = (fetch & 0xffff) >> 2;
matchlen = 3;
src += 2;
}
else if ((fetch & 1) == 0)
{
offset = (fetch & 0xffff) >> 6;
matchlen = ((fetch >> 2) & 15) + 3;
src += 2;
}
else if ((fetch & 127) != 3)
{
offset = (fetch >> 7) & 0x1ffff;
matchlen = ((fetch >> 2) & 0x1f) + 2;
src += 3;
}
else
{
offset = (fetch >> 15);
matchlen = ((fetch >> 7) & 255) + 3;
src += 4;
}
offset2 = (uint)(dst - offset);
}
destination[dst + 0] = destination[offset2 + 0];
destination[dst + 1] = destination[offset2 + 1];
destination[dst + 2] = destination[offset2 + 2];
for (int i = 3; i < matchlen; i += 1)
{
destination[dst + i] = destination[offset2 + i];
}
dst += (int)matchlen;
if (level == 1)
{
fetch = (uint)(destination[last_hashed + 1] | (destination[last_hashed + 2] << 8) | (destination[last_hashed + 3] << 16));
while (last_hashed < dst - matchlen)
{
last_hashed++;
hash = (int)(((fetch >> 12) ^ fetch) & (HASH_VALUES - 1));
hashtable[hash] = last_hashed;
hash_counter[hash] = 1;
fetch = (uint)(fetch >> 8 & 0xffff | destination[last_hashed + 3] << 16);
}
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16));
}
else
{
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
}
last_hashed = dst - 1;
}
else
{
if (dst <= last_matchstart)
{
destination[dst] = source[src];
dst += 1;
src += 1;
cword_val = cword_val >> 1;
if (level == 1)
{
while (last_hashed < dst - 3)
{
last_hashed++;
int fetch2 = destination[last_hashed] | (destination[last_hashed + 1] << 8) | (destination[last_hashed + 2] << 16);
hash = ((fetch2 >> 12) ^ fetch2) & (HASH_VALUES - 1);
hashtable[hash] = last_hashed;
hash_counter[hash] = 1;
}
fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16);
}
else
{
fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16 | source[src + 3] << 24);
}
}
else
{
while (dst <= size - 1)
{
if (cword_val == 1)
{
src += CWORD_LEN;
cword_val = 0x80000000;
}
destination[dst] = source[src];
dst++;
src++;
cword_val = cword_val >> 1;
}
return destination;
}
}
}
}
}
}

View File

@ -1,177 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text;
namespace StreamLibrary.src
{
public unsafe class SimpleBitmap
{
private object ProcessingLock = new object();
public SimpleBitmapInfo Info { get; internal set; }
public bool Locked { get { return Scan0 == IntPtr.Zero ? false : true; } }
public IntPtr Scan0 { get; internal set; }
public int Scan0_int { get; internal set; }
public BitmapData bitmapData { get; internal set; }
public Bitmap bitMap { get; set; }
public class SimpleBitmapInfo
{
public SimpleBitmapInfo()
{
Clear();
}
public SimpleBitmapInfo(BitmapData data)
{
Load(data);
}
public int Stride { get; protected set; }
public int PixelSize { get; protected set; }
public int Width { get; protected set; }
public int Height { get; protected set; }
public int TotalSize { get; protected set; }
internal void Clear()
{
Stride = 0; PixelSize = 0; Width = 0; Height = 0; TotalSize = 0;
}
internal void Load(BitmapData data)
{
Width = data.Width; Height = data.Height; Stride = data.Stride;
PixelSize = Math.Abs(data.Stride) / data.Width;
TotalSize = data.Width * data.Height * PixelSize;
}
}
public static bool Compare(Rectangle block, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo)
{
int calc = 0;
int WidthSize = block.Width * sharedInfo.PixelSize;
calc = (block.Y) * sharedInfo.Stride + block.X * sharedInfo.PixelSize;
for (int i = 0; i < block.Height; i++)
{
if (NativeMethods.memcmp((byte*)(ptr1 + calc), (byte*)(ptr2 + calc), (uint)WidthSize) != 0)
return false;
calc += sharedInfo.Stride;
}
return true;
}
public static bool Compare(int y, int rowsize, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo)
{
int calc = 0;
int Size = sharedInfo.Width * sharedInfo.PixelSize * rowsize;
calc = y * sharedInfo.Stride;
if (NativeMethods.memcmp((byte*)(ptr1 + calc), (byte*)(ptr2 + calc), (uint)Size) != 0)
return false;
return true;
}
public static bool FastCompare(int offset, int size, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo)
{
if (NativeMethods.memcmp((byte*)(ptr1 + offset), (byte*)(ptr2 + offset), (uint)size) != 0)
return false;
return true;
}
public unsafe void CopyBlock(Rectangle block, ref byte[] dest)
{
int calc = 0;
int WidthSize = block.Width * Info.PixelSize;
int CopyOffset = 0;
int scan0 = Scan0.ToInt32();
int destSize = WidthSize * block.Height;
if (dest == null || dest.Length != destSize)
dest = new byte[destSize];
calc = (block.Y) * Info.Stride + block.X * Info.PixelSize;
fixed (byte* ptr = dest)
{
for (int i = 0; i < block.Height; i++)
{
NativeMethods.memcpy(new IntPtr(ptr + CopyOffset), new IntPtr(scan0 + calc), (uint)WidthSize);
calc += Info.Stride;
CopyOffset += WidthSize;
}
}
}
public SimpleBitmap()
{
Scan0 = IntPtr.Zero;
bitmapData = null;
bitMap = null;
Info = new SimpleBitmapInfo();
}
public SimpleBitmap(Bitmap bmp)
{
this.bitMap = bmp;
}
public void Lock()
{
if (Locked)
throw new Exception("Already locked");
lock (ProcessingLock)
{
bitmapData = bitMap.LockBits(new Rectangle(0, 0, bitMap.Width, bitMap.Height), ImageLockMode.ReadWrite, bitMap.PixelFormat);
Info = new SimpleBitmapInfo(bitmapData);
Scan0 = bitmapData.Scan0;
Scan0_int = Scan0.ToInt32();
}
}
public void Unlock()
{
if (!Locked)
throw new Exception("Nothing to unlock");
lock (ProcessingLock)
{
Scan0 = IntPtr.Zero;
Scan0_int = 0;
Info.Clear();
bitMap.UnlockBits(bitmapData);
bitmapData = null;
}
}
public unsafe void PlaceBlockAtRectange(byte[] block, Rectangle loc)
{
int CopySize = Info.PixelSize * loc.Width;
int OffsetX = loc.X * Info.PixelSize;
int TotalCopied = 0;
fixed (byte* ptr = block)
{
for (int i = 0; i < loc.Height; i++)
{
NativeMethods.memcpy(new IntPtr(Scan0_int + ((loc.Y + i) * Info.Stride + OffsetX)), new IntPtr(ptr + TotalCopied), (uint)CopySize);
TotalCopied += CopySize;
}
}
}
public void Dispose(bool disposeBitmap = false)
{
if (Locked)
Unlock();
if (disposeBitmap)
bitMap.Dispose();
bitMap = null;
}
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Costura.Fody" version="3.3.3" targetFramework="net40-client" /> <package id="Costura.Fody" version="4.0.0" targetFramework="net40-client" />
<package id="Fody" version="4.0.2" targetFramework="net40-client" developmentDependency="true" /> <package id="Fody" version="5.0.5" targetFramework="net40-client" developmentDependency="true" />
</packages> </packages>